Alien-TinyCC

 view release on metacpan or  search on metacpan

src/tccpe.c  view on Meta::CPAN

            0x05, // UBYTE: 4 Frame Register (rbp), UBYTE: 4 Frame Register offset (scaled)
            // USHORT * n Unwind codes array
            // 0x0b, 0x01, 0xff, 0xff, // stack size
            0x04, 0x03, // set frame ptr (mov rsp -> rbp)
            0x01, 0x50  // push reg (rbp)
        };

        Section *s = text_section;
        unsigned char *p;

        section_ptr_add(s, -s->data_offset & 3); /* align */
        s1->uw_offs = s->data_offset;
        p = section_ptr_add(s, sizeof uw_info);
        memcpy(p, uw_info, sizeof uw_info);
    }

    return s1->uw_offs;
}

ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack)
{
    TCCState *s1 = tcc_state;
    Section *pd;
    unsigned o, n, d;
    struct /* _RUNTIME_FUNCTION */ {
      DWORD BeginAddress;
      DWORD EndAddress;
      DWORD UnwindData;
    } *p;

    d = pe_add_uwwind_info(s1);
    pd = s1->uw_pdata;
    o = pd->data_offset;
    p = section_ptr_add(pd, sizeof *p);

    /* record this function */
    p->BeginAddress = start;
    p->EndAddress = end;
    p->UnwindData = d;

    /* put relocations on it */
    for (n = o + sizeof *p; o < n; o += sizeof p->BeginAddress)
        put_elf_reloc(symtab_section, pd, o,  R_X86_64_RELATIVE, s1->uw_sym);
}
#endif
/* ------------------------------------------------------------- */
#ifdef TCC_TARGET_X86_64
#define PE_STDSYM(n,s) n
#else
#define PE_STDSYM(n,s) "_" n s
#endif

static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
{
    const char *start_symbol;
    int pe_type = 0;

    if (find_elf_sym(symtab_section, PE_STDSYM("WinMain","@16")))
        pe_type = PE_GUI;
    else
    if (TCC_OUTPUT_DLL == s1->output_type) {
        pe_type = PE_DLL;
        /* need this for 'tccelf.c:relocate_section()' */
        s1->output_type = TCC_OUTPUT_EXE;
    }
    else
        pe_type = PE_EXE;

    start_symbol =
        TCC_OUTPUT_MEMORY == s1->output_type
        ? PE_GUI == pe_type ? "__runwinmain" : "_main"
        : PE_DLL == pe_type ? PE_STDSYM("__dllstart","@12")
        : PE_GUI == pe_type ? "__winstart" : "__start"
        ;

    if (!s1->leading_underscore || strchr(start_symbol, '@'))
        ++start_symbol;

    /* grab the startup code from libtcc1 */
    if (TCC_OUTPUT_MEMORY != s1->output_type || PE_GUI == pe_type)
        add_elf_sym(symtab_section,
            0, 0,
            ELFW(ST_INFO)(STB_GLOBAL, STT_NOTYPE), 0,
            SHN_UNDEF, start_symbol);

    if (0 == s1->nostdlib) {
        static const char *libs[] = {
            "libtcc1.a", "msvcrt", "kernel32", "", "user32", "gdi32", NULL
        };
        const char **pp, *p;
        for (pp = libs; 0 != (p = *pp); ++pp) {
            if (0 == *p) {
                if (PE_DLL != pe_type && PE_GUI != pe_type)
                    break;
            } else if (pp == libs ? tcc_add_dll(s1, p, 0) : tcc_add_library(s1, p)) {
                tcc_error_noabort("cannot find library: %s", p);
                break;
            }
        }
    }

    if (TCC_OUTPUT_MEMORY == s1->output_type) {
        pe_type = PE_RUN;
        s1->runtime_main = start_symbol;
    } else {
        pe->start_addr = (DWORD)tcc_get_symbol_err(s1, start_symbol);
    }

    pe->type = pe_type;
}

ST_FUNC int pe_output_file(TCCState * s1, const char *filename)
{
    int ret;
    struct pe_info pe;
    int i;

    memset(&pe, 0, sizeof pe);
    pe.filename = filename;
    pe.s1 = s1;

    tcc_add_bcheck(s1);
    pe_add_runtime(s1, &pe);
    relocate_common_syms(); /* assign bss adresses */
    tcc_add_linker_symbols(s1);

    ret = pe_check_symbols(&pe);
    if (ret)
        ;
    else if (filename) {
        if (PE_DLL == pe.type) {
            pe.reloc = new_section(pe.s1, ".reloc", SHT_PROGBITS, 0);
            /* XXX: check if is correct for arm-pe target */
            pe.imagebase = 0x10000000;
        } else {
#if defined(TCC_TARGET_ARM)
            pe.imagebase = 0x00010000;
#else
            pe.imagebase = 0x00400000;
#endif
        }

#if defined(TCC_TARGET_ARM)
        /* we use "console" subsystem by default */
        pe.subsystem = 9;
#else
        if (PE_DLL == pe.type || PE_GUI == pe.type)
            pe.subsystem = 2;
        else
            pe.subsystem = 3;
#endif
        /* Allow override via -Wl,-subsystem=... option */
        if (s1->pe_subsystem != 0)
            pe.subsystem = s1->pe_subsystem;

        /* set default file/section alignment */
	if (pe.subsystem == 1) {
	    pe.section_align = 0x20;
	    pe.file_align = 0x20;
	} else {
	    pe.section_align = 0x1000;
	    pe.file_align = 0x200;



( run in 0.503 second using v1.01-cache-2.11-cpan-62a16548d74 )