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 )