Alien-TinyCCx

 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);

    tcc_add_pragma_libs(s1);

    if (0 == s1->nostdlib) {
        static const char *libs[] = {
            "tcc1", "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 (tcc_add_library_err(s1, p) < 0) {
                break;
            }
        }
    }

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

    pe->type = pe_type;
}

static void pe_set_options(TCCState * s1, struct pe_info *pe)
{
    if (PE_DLL == pe->type) {
        /* 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;
    }

    if (s1->section_align != 0)
        pe->section_align = s1->section_align;
    if (s1->pe_file_align != 0)
        pe->file_align = s1->pe_file_align;

    if ((pe->subsystem >= 10) && (pe->subsystem <= 12))
        pe->imagebase = 0;

    if (s1->has_text_addr)
        pe->imagebase = s1->text_addr;
}

ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
{



( run in 0.525 second using v1.01-cache-2.11-cpan-5623c5533a1 )