mirror of
git://repo.or.cz/tinycc.git
synced 2026-06-17 15:44:18 +08:00
arm64-win32 support : linker & -run
This commit is contained in:
parent
f459aff5f6
commit
41bcb4a78f
62
arm64-link.c
62
arm64-link.c
@ -50,6 +50,8 @@ ST_FUNC int code_reloc (int reloc_type)
|
||||
case R_AARCH64_JUMP26:
|
||||
case R_AARCH64_CALL26:
|
||||
case R_AARCH64_JUMP_SLOT:
|
||||
case R_AARCH64_CONDBR19:
|
||||
case R_AARCH64_TSTBR14:
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
@ -76,6 +78,8 @@ ST_FUNC int gotplt_entry_type (int reloc_type)
|
||||
case R_AARCH64_GLOB_DAT:
|
||||
case R_AARCH64_JUMP_SLOT:
|
||||
case R_AARCH64_COPY:
|
||||
case R_AARCH64_CONDBR19:
|
||||
case R_AARCH64_TSTBR14:
|
||||
return NO_GOTPLT_ENTRY;
|
||||
|
||||
case R_AARCH64_ABS32:
|
||||
@ -238,8 +242,23 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
|
||||
return;
|
||||
case R_AARCH64_ADR_PREL_PG_HI21: {
|
||||
uint64_t off = (val >> 12) - (addr >> 12);
|
||||
#ifdef TCC_TARGET_PE
|
||||
/* Weak undefined symbols resolve to address 0 on PE. ADRP cannot
|
||||
encode that from the default 64-bit image base, so materialize
|
||||
zero directly and let the paired ADD handle any low addend. */
|
||||
if ((off + ((uint64_t)1 << 20)) >> 21) {
|
||||
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||
if (sym->st_shndx == SHN_UNDEF
|
||||
&& ELFW(ST_BIND)(sym->st_info) == STB_WEAK) {
|
||||
write32le(ptr, 0xd2800000 | (read32le(ptr) & 0x1f));
|
||||
return;
|
||||
}
|
||||
tcc_error_noabort("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
|
||||
}
|
||||
#else
|
||||
if ((off + ((uint64_t)1 << 20)) >> 21)
|
||||
tcc_error_noabort("R_AARCH64_ADR_PREL_PG_HI21 relocation failed");
|
||||
#endif
|
||||
write32le(ptr, ((read32le(ptr) & 0x9f00001f) |
|
||||
(off & 0x1ffffc) << 3 | (off & 3) << 29));
|
||||
return;
|
||||
@ -265,19 +284,58 @@ ST_FUNC void relocate(TCCState *s1, ElfW_Rel *rel, int type, unsigned char *ptr,
|
||||
write32le(ptr, ((read32le(ptr) & 0xffc003ff) |
|
||||
(val & 0xff0) << 6));
|
||||
return;
|
||||
case R_AARCH64_CONDBR19:
|
||||
/* Conditional branch: 19-bit signed offset, bits 23:5 */
|
||||
#ifdef DEBUG_RELOC
|
||||
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
|
||||
(char *) symtab_section->link->data + sym->st_name);
|
||||
#endif
|
||||
if (((val - addr) + ((uint64_t)1 << 20)) & ~(uint64_t)0x1ffffc)
|
||||
tcc_error_noabort("R_AARCH64_CONDBR19 relocation failed"
|
||||
" (val=%lx, addr=%lx)", (long)val, (long)addr);
|
||||
write32le(ptr, ((read32le(ptr) & 0xff00001f) |
|
||||
(((val - addr) >> 2 & 0x7ffff) << 5)));
|
||||
return;
|
||||
case R_AARCH64_TSTBR14:
|
||||
/* Test and branch: 14-bit signed offset, bits 20:5 */
|
||||
#ifdef DEBUG_RELOC
|
||||
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
|
||||
(char *) symtab_section->link->data + sym->st_name);
|
||||
#endif
|
||||
if (((val - addr) + ((uint64_t)1 << 15)) & ~(uint64_t)0xfffc)
|
||||
tcc_error_noabort("R_AARCH64_TSTBR14 relocation failed"
|
||||
" (val=%lx, addr=%lx)", (long)val, (long)addr);
|
||||
write32le(ptr, ((read32le(ptr) & 0xfff8001f) |
|
||||
(((val - addr) >> 2 & 0x3fff) << 5)));
|
||||
return;
|
||||
case R_AARCH64_JUMP26:
|
||||
case R_AARCH64_CALL26:
|
||||
{
|
||||
const char *name;
|
||||
#ifdef DEBUG_RELOC
|
||||
printf ("reloc %d @ 0x%lx: val=0x%lx name=%s\n", type, addr, val,
|
||||
(char *) symtab_section->link->data + sym->st_name);
|
||||
#endif
|
||||
if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc)
|
||||
if (((val - addr) + ((uint64_t)1 << 27)) & ~(uint64_t)0xffffffc) {
|
||||
#ifdef TCC_TARGET_PE
|
||||
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||
if (sym->st_shndx == SHN_UNDEF
|
||||
&& ELFW(ST_BIND)(sym->st_info) == STB_WEAK) {
|
||||
write32le(ptr, ARM64_NOP); /* nop */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
name = (char *)symtab_section->link->data +
|
||||
((ElfW(Sym) *)symtab_section->data)[sym_index].st_name;
|
||||
tcc_error_noabort("R_AARCH64_(JUMP|CALL)26 relocation failed"
|
||||
" (val=%lx, addr=%lx)", (long)val, (long)addr);
|
||||
" for '%s' (val=%lx, addr=%lx)",
|
||||
name, (long)val, (long)addr);
|
||||
}
|
||||
write32le(ptr, (0x14000000 |
|
||||
(uint32_t)(type == R_AARCH64_CALL26) << 31 |
|
||||
((val - addr) >> 2 & 0x3ffffff)));
|
||||
return;
|
||||
}
|
||||
case R_AARCH64_ADR_GOT_PAGE: {
|
||||
uint64_t off =
|
||||
(((s1->got->sh_addr +
|
||||
|
||||
5
tcc.h
5
tcc.h
@ -949,9 +949,10 @@ struct TCCState {
|
||||
unsigned pe_file_align;
|
||||
unsigned pe_stack_size;
|
||||
addr_t pe_imagebase;
|
||||
# ifdef TCC_TARGET_X86_64
|
||||
# if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
|
||||
Section *uw_pdata;
|
||||
int uw_sym;
|
||||
int uw_xsym;
|
||||
unsigned uw_offs;
|
||||
# endif
|
||||
#endif
|
||||
@ -1762,7 +1763,7 @@ ST_FUNC int pe_putimport(TCCState *s1, int dllindex, const char *name, addr_t va
|
||||
ST_FUNC int pe_setsubsy(TCCState *s1, const char *arg);
|
||||
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
|
||||
#endif
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
#if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
|
||||
ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack);
|
||||
#endif
|
||||
PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp);
|
||||
|
||||
196
tccpe.c
196
tccpe.c
@ -50,6 +50,16 @@
|
||||
# define IMAGE_FILE_MACHINE 0x01C0
|
||||
# define RSRC_RELTYPE 7 /* ??? (not tested) */
|
||||
|
||||
#elif defined TCC_TARGET_ARM64
|
||||
# define ADDR3264 ULONGLONG
|
||||
# define PE_IMAGE_REL IMAGE_REL_BASED_DIR64
|
||||
# define REL_TYPE_DIRECT R_AARCH64_ABS64
|
||||
# define R_XXX_THUNKFIX R_AARCH64_ABS64
|
||||
# define R_XXX_RELATIVE R_AARCH64_RELATIVE
|
||||
# define R_XXX_FUNCCALL R_AARCH64_CALL26
|
||||
# define IMAGE_FILE_MACHINE 0xAA64
|
||||
# define RSRC_RELTYPE 3
|
||||
|
||||
#elif defined TCC_TARGET_I386
|
||||
# define ADDR3264 DWORD
|
||||
# define PE_IMAGE_REL IMAGE_REL_BASED_HIGHLOW
|
||||
@ -126,7 +136,7 @@ typedef struct _IMAGE_OPTIONAL_HEADER {
|
||||
DWORD SizeOfUninitializedData;
|
||||
DWORD AddressOfEntryPoint;
|
||||
DWORD BaseOfCode;
|
||||
#ifndef TCC_TARGET_X86_64
|
||||
#if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM64)
|
||||
DWORD BaseOfData;
|
||||
#endif
|
||||
/* NT additional fields. */
|
||||
@ -225,6 +235,19 @@ typedef struct _IMAGE_BASE_RELOCATION {
|
||||
|
||||
#define IMAGE_SIZEOF_BASE_RELOCATION 8
|
||||
|
||||
#ifndef IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA
|
||||
#define IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA 0x0020
|
||||
#endif
|
||||
#ifndef IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE
|
||||
#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040
|
||||
#endif
|
||||
#ifndef IMAGE_DLLCHARACTERISTICS_NX_COMPAT
|
||||
#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100
|
||||
#endif
|
||||
#ifndef IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE
|
||||
#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
|
||||
#endif
|
||||
|
||||
#define IMAGE_REL_BASED_ABSOLUTE 0
|
||||
#define IMAGE_REL_BASED_HIGH 1
|
||||
#define IMAGE_REL_BASED_LOW 2
|
||||
@ -250,6 +273,9 @@ typedef struct _IMAGE_BASE_RELOCATION {
|
||||
#endif /* ndef IMAGE_NT_SIGNATURE */
|
||||
/* ----------------------------------------------------------- */
|
||||
|
||||
#ifndef IMAGE_FILE_MACHINE_ARM64
|
||||
#define IMAGE_FILE_MACHINE_ARM64 0xAA64
|
||||
#endif
|
||||
#ifndef IMAGE_REL_BASED_DIR64
|
||||
# define IMAGE_REL_BASED_DIR64 10
|
||||
#endif
|
||||
@ -261,7 +287,7 @@ struct pe_header
|
||||
BYTE dosstub[0x40];
|
||||
DWORD nt_sig;
|
||||
IMAGE_FILE_HEADER filehdr;
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
#if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
|
||||
IMAGE_OPTIONAL_HEADER64 opthdr;
|
||||
#else
|
||||
#ifdef _WIN64
|
||||
@ -605,11 +631,15 @@ static int pe_write(struct pe_info *pe)
|
||||
0x00E0, /*WORD SizeOfOptionalHeader; */
|
||||
0x010F, /*WORD Characteristics; */
|
||||
#define CHARACTERISTICS_DLL 0x230F
|
||||
#elif defined(TCC_TARGET_ARM64)
|
||||
0x00F0, /*WORD SizeOfOptionalHeader; */
|
||||
0x0022 /*WORD Characteristics; */
|
||||
#define CHARACTERISTICS_DLL 0x2022
|
||||
#endif
|
||||
},{
|
||||
/* IMAGE_OPTIONAL_HEADER opthdr */
|
||||
/* Standard fields. */
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
#if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
|
||||
0x020B, /*WORD Magic; */
|
||||
#else
|
||||
0x010B, /*WORD Magic; */
|
||||
@ -621,29 +651,48 @@ static int pe_write(struct pe_info *pe)
|
||||
0x00000000, /*DWORD SizeOfUninitializedData; */
|
||||
0x00000000, /*DWORD AddressOfEntryPoint; */
|
||||
0x00000000, /*DWORD BaseOfCode; */
|
||||
#ifndef TCC_TARGET_X86_64
|
||||
#if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM64)
|
||||
0x00000000, /*DWORD BaseOfData; */
|
||||
#endif
|
||||
/* NT additional fields. */
|
||||
#if defined(TCC_TARGET_ARM)
|
||||
0x00100000, /*DWORD ImageBase; */
|
||||
#elif defined(TCC_TARGET_ARM64)
|
||||
0x140000000ULL, /*ULONGLONG ImageBase; */
|
||||
#else
|
||||
0x00400000, /*DWORD ImageBase; */
|
||||
#endif
|
||||
0x00001000, /*DWORD SectionAlignment; */
|
||||
0x00000200, /*DWORD FileAlignment; */
|
||||
#if defined(TCC_TARGET_ARM64)
|
||||
0x0006, /*WORD MajorOperatingSystemVersion; */
|
||||
0x0002, /*WORD MinorOperatingSystemVersion; */
|
||||
#else
|
||||
0x0004, /*WORD MajorOperatingSystemVersion; */
|
||||
0x0000, /*WORD MinorOperatingSystemVersion; */
|
||||
#endif
|
||||
0x0000, /*WORD MajorImageVersion; */
|
||||
0x0000, /*WORD MinorImageVersion; */
|
||||
#if defined(TCC_TARGET_ARM64)
|
||||
0x0006, /*WORD MajorSubsystemVersion; */
|
||||
0x0002, /*WORD MinorSubsystemVersion; */
|
||||
#else
|
||||
0x0004, /*WORD MajorSubsystemVersion; */
|
||||
0x0000, /*WORD MinorSubsystemVersion; */
|
||||
#endif
|
||||
0x00000000, /*DWORD Win32VersionValue; */
|
||||
0x00000000, /*DWORD SizeOfImage; */
|
||||
0x00000200, /*DWORD SizeOfHeaders; */
|
||||
0x00000000, /*DWORD CheckSum; */
|
||||
0x0002, /*WORD Subsystem; */
|
||||
#if defined(TCC_TARGET_ARM64)
|
||||
IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA |
|
||||
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE |
|
||||
IMAGE_DLLCHARACTERISTICS_NX_COMPAT |
|
||||
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE,
|
||||
#else
|
||||
0x0000, /*WORD DllCharacteristics; */
|
||||
#endif
|
||||
0x00100000, /*DWORD SizeOfStackReserve; */
|
||||
0x00001000, /*DWORD SizeOfStackCommit; */
|
||||
0x00100000, /*DWORD SizeOfHeapReserve; */
|
||||
@ -702,7 +751,7 @@ static int pe_write(struct pe_info *pe)
|
||||
break;
|
||||
|
||||
case sec_data:
|
||||
#ifndef TCC_TARGET_X86_64
|
||||
#if !defined(TCC_TARGET_X86_64) && !defined(TCC_TARGET_ARM64)
|
||||
if (!pe_header.opthdr.BaseOfData)
|
||||
pe_header.opthdr.BaseOfData = addr;
|
||||
#endif
|
||||
@ -1191,7 +1240,11 @@ static int pe_assign_addresses (struct pe_info *pe)
|
||||
Section *s;
|
||||
TCCState *s1 = pe->s1;
|
||||
|
||||
if (PE_DLL == pe->type)
|
||||
if (PE_DLL == pe->type
|
||||
#ifdef TCC_TARGET_ARM64
|
||||
|| PE_EXE == pe->type || PE_GUI == pe->type
|
||||
#endif
|
||||
)
|
||||
pe->reloc = new_section(s1, ".reloc", SHT_PROGBITS, 0);
|
||||
//pe->thunk = new_section(s1, ".iedat", SHT_PROGBITS, SHF_ALLOC);
|
||||
|
||||
@ -1380,6 +1433,18 @@ static int pe_check_symbols(struct pe_info *pe)
|
||||
write32le(p + 4, 0xE59CF000); // arm code ldr pc, [ip]
|
||||
put_elf_reloc(symtab_section, text_section,
|
||||
offset + 8, R_XXX_THUNKFIX, is->iat_index); // offset to IAT position
|
||||
#elif defined(TCC_TARGET_ARM64)
|
||||
p = section_ptr_add(text_section, 24);
|
||||
/* ldr x16, [pc, #16] */
|
||||
write32le(p + 0, 0x58000090);
|
||||
/* ldr x16, [x16] */
|
||||
write32le(p + 4, 0xf9400210);
|
||||
/* br x16 */
|
||||
write32le(p + 8, 0xd61f0200);
|
||||
/* nop for 8-byte literal alignment */
|
||||
write32le(p + 12, 0xd503201f);
|
||||
put_elf_reloc(symtab_section, text_section,
|
||||
offset + 16, R_XXX_THUNKFIX, is->iat_index);
|
||||
#else
|
||||
p = section_ptr_add(text_section, 8);
|
||||
write16le(p, 0x25FF);
|
||||
@ -1611,7 +1676,7 @@ static int get_dllexports(int fd, char **pp)
|
||||
if (IMAGE_DIRECTORY_ENTRY_EXPORT >= oh.NumberOfRvaAndSizes)
|
||||
goto the_end_0;
|
||||
addr = oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
||||
} else if (ih.Machine == 0x8664) {
|
||||
} else if (ih.Machine == 0x8664 || ih.Machine == IMAGE_FILE_MACHINE_ARM64) {
|
||||
IMAGE_OPTIONAL_HEADER64 oh;
|
||||
sec_hdroffset = opt_hdroffset + sizeof oh;
|
||||
if (!read_mem(fd, opt_hdroffset, &oh, sizeof oh))
|
||||
@ -1834,7 +1899,7 @@ PUB_FUNC int tcc_get_dllexports(const char *filename, char **pp)
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
static unsigned pe_add_uwwind_info(TCCState *s1)
|
||||
static unsigned pe_add_unwind_info(TCCState *s1)
|
||||
{
|
||||
if (NULL == s1->uw_pdata) {
|
||||
s1->uw_pdata = find_section(s1, ".pdata");
|
||||
@ -1879,7 +1944,7 @@ ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack)
|
||||
DWORD UnwindData;
|
||||
} *p;
|
||||
|
||||
d = pe_add_uwwind_info(s1);
|
||||
d = pe_add_unwind_info(s1);
|
||||
pd = s1->uw_pdata;
|
||||
o = pd->data_offset;
|
||||
p = section_ptr_add(pd, sizeof *p);
|
||||
@ -1893,9 +1958,110 @@ ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack)
|
||||
for (n = o + sizeof *p; o < n; o += sizeof p->BeginAddress)
|
||||
put_elf_reloc(symtab_section, pd, o, R_XXX_RELATIVE, s1->uw_sym);
|
||||
}
|
||||
#elif defined(TCC_TARGET_ARM64)
|
||||
/* ARM64 unwind codes:
|
||||
save_fplr_x: 10iiiiii - stp x29,lr,[sp,#-(i+1)*8]!
|
||||
set_fp: 11100001 - mov x29,sp
|
||||
alloc_s: 000iiiii - sub sp,sp,#i*16 (up to 496 bytes)
|
||||
alloc_m: 11000iii xxxxxxxx - sub sp,sp,#X*16 (up to 32KB)
|
||||
end: 11100100 - end of unwind codes
|
||||
*/
|
||||
static Section *pe_add_unwind_info(TCCState *s1)
|
||||
{
|
||||
Section *s;
|
||||
|
||||
if (NULL == s1->uw_pdata) {
|
||||
s1->uw_pdata = find_section(s1, ".pdata");
|
||||
s1->uw_pdata->sh_addralign = 4;
|
||||
}
|
||||
s = find_section(s1, ".xdata");
|
||||
if (NULL == s) {
|
||||
s = new_section(s1, ".xdata", SHT_PROGBITS, SHF_ALLOC);
|
||||
s->sh_addralign = 4;
|
||||
}
|
||||
if (0 == s1->uw_sym)
|
||||
s1->uw_sym = put_elf_sym(symtab_section, 0, 0, 0, 0,
|
||||
text_section->sh_num, ".uw_text_base");
|
||||
if (0 == s1->uw_xsym)
|
||||
s1->uw_xsym = put_elf_sym(symtab_section, 0, 0, 0, 0,
|
||||
s->sh_num, ".uw_base");
|
||||
return s;
|
||||
}
|
||||
|
||||
ST_FUNC void pe_add_unwind_data(unsigned start, unsigned end, unsigned stack)
|
||||
{
|
||||
TCCState *s1 = tcc_state;
|
||||
Section *pd, *xd;
|
||||
unsigned o, n, d, code_bytes, func_len, stack_slots;
|
||||
unsigned char *q;
|
||||
uint32_t header;
|
||||
struct {
|
||||
DWORD BeginAddress;
|
||||
DWORD EndAddress;
|
||||
DWORD UnwindData;
|
||||
} *p;
|
||||
|
||||
xd = pe_add_unwind_info(s1);
|
||||
pd = s1->uw_pdata;
|
||||
|
||||
stack = (stack + 15) & ~15;
|
||||
stack_slots = stack >> 4;
|
||||
func_len = (end - start) >> 2;
|
||||
code_bytes = 0;
|
||||
if (stack_slots) {
|
||||
if (stack_slots <= 31) {
|
||||
code_bytes += 1;
|
||||
} else if (stack_slots <= 0x7ff) {
|
||||
code_bytes += 2;
|
||||
} else {
|
||||
code_bytes += 4;
|
||||
}
|
||||
}
|
||||
code_bytes += 3; /* set_fp, save_fplr_x, end */
|
||||
code_bytes = (code_bytes + 3) & ~3;
|
||||
|
||||
section_ptr_add(xd, -xd->data_offset & 3);
|
||||
d = xd->data_offset;
|
||||
q = section_ptr_add(xd, 4 + code_bytes);
|
||||
|
||||
/* Full ARM64 xdata header: E=1 with one epilog and no exception handler. */
|
||||
header = (func_len & 0x3ffff) | (1u << 21) | ((code_bytes >> 2) << 27);
|
||||
write32le(q, header);
|
||||
q += 4;
|
||||
|
||||
if (stack_slots) {
|
||||
if (stack_slots <= 31) {
|
||||
*q++ = stack_slots; /* alloc_s */
|
||||
} else if (stack_slots <= 0x7ff) {
|
||||
*q++ = 0xC0 | (stack_slots >> 8); /* alloc_m */
|
||||
*q++ = stack_slots & 0xff;
|
||||
} else {
|
||||
*q++ = 0xE0; /* alloc_l */
|
||||
*q++ = (stack_slots >> 16) & 0xff;
|
||||
*q++ = (stack_slots >> 8) & 0xff;
|
||||
*q++ = stack_slots & 0xff;
|
||||
}
|
||||
}
|
||||
*q++ = 0xE1; /* set_fp */
|
||||
*q++ = 0x9B; /* save_fplr_x: stp x29,lr,[sp,#-224]! */
|
||||
*q++ = 0xE4; /* end */
|
||||
while ((unsigned)(q - (xd->data + d + 4)) < code_bytes)
|
||||
*q++ = 0xE3; /* nop padding */
|
||||
|
||||
o = pd->data_offset;
|
||||
p = section_ptr_add(pd, sizeof *p);
|
||||
|
||||
p->BeginAddress = start;
|
||||
p->EndAddress = end;
|
||||
p->UnwindData = d;
|
||||
|
||||
for (n = o + 2 * sizeof p->BeginAddress; o < n; o += sizeof p->BeginAddress)
|
||||
put_elf_reloc(symtab_section, pd, o, R_XXX_RELATIVE, s1->uw_sym);
|
||||
put_elf_reloc(symtab_section, pd, n, R_XXX_RELATIVE, s1->uw_xsym);
|
||||
}
|
||||
#endif
|
||||
/* ------------------------------------------------------------- */
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
#if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
|
||||
#define PE_STDSYM(n,s) n
|
||||
#else
|
||||
#define PE_STDSYM(n,s) "_" n s
|
||||
@ -1991,7 +2157,7 @@ static void pe_add_runtime(TCCState *s1, struct pe_info *pe)
|
||||
ST_FUNC int pe_setsubsy(TCCState *s1, const char *arg)
|
||||
{
|
||||
static const struct subsy { const char* p; int v; } x[] = {
|
||||
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64)
|
||||
#if defined(TCC_TARGET_I386) || defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
|
||||
{ "native", 1 },
|
||||
{ "gui", 2 },
|
||||
{ "windows", 2 },
|
||||
@ -2020,10 +2186,16 @@ 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 */
|
||||
#if defined(TCC_TARGET_ARM64)
|
||||
pe->imagebase = 0x180000000ULL;
|
||||
#else
|
||||
pe->imagebase = 0x10000000;
|
||||
#endif
|
||||
} else {
|
||||
#if defined(TCC_TARGET_ARM)
|
||||
pe->imagebase = 0x00010000;
|
||||
#elif defined(TCC_TARGET_ARM64)
|
||||
pe->imagebase = 0x140000000ULL;
|
||||
#else
|
||||
pe->imagebase = 0x00400000;
|
||||
#endif
|
||||
@ -2098,7 +2270,7 @@ ST_FUNC int pe_output_file(TCCState *s1, const char *filename)
|
||||
pe.thunk = data_section;
|
||||
pe_build_imports(&pe);
|
||||
s1->run_main = pe.start_symbol;
|
||||
#ifdef TCC_TARGET_X86_64
|
||||
#if defined(TCC_TARGET_X86_64) || defined(TCC_TARGET_ARM64)
|
||||
s1->uw_pdata = find_section(s1, ".pdata");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
10
tccrun.c
10
tccrun.c
@ -1199,7 +1199,11 @@ static int rt_error(rt_frame *f, const char *fmt, ...)
|
||||
/* translate from ucontext_t* to internal rt_context * */
|
||||
static void rt_getcontext(ucontext_t *uc, rt_frame *rc)
|
||||
{
|
||||
#if defined _WIN64
|
||||
#if defined _WIN64 && defined __aarch64__
|
||||
rc->ip = uc->Pc; /* Program Counter */
|
||||
rc->fp = uc->Fp; /* Frame Pointer (X29) */
|
||||
rc->sp = uc->Sp; /* Stack Pointer (X30 is LR, but SP is separate) */
|
||||
#elif defined _WIN64
|
||||
rc->ip = uc->Rip;
|
||||
rc->fp = uc->Rbp;
|
||||
rc->sp = uc->Rsp;
|
||||
@ -1398,7 +1402,11 @@ static long __stdcall cpu_exception_handler(EXCEPTION_POINTERS *ex_info)
|
||||
/* Generate a stack backtrace when a CPU exception occurs. */
|
||||
static void set_exception_handler(void)
|
||||
{
|
||||
#ifdef _WIN64
|
||||
AddVectoredExceptionHandler(1, cpu_exception_handler);
|
||||
#else
|
||||
SetUnhandledExceptionFilter(cpu_exception_handler);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user