mirror of
git://repo.or.cz/tinycc.git
synced 2026-11-04 21:26:36 +08:00
TLS bits
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-arm64-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
build and test / test-i386-linux (push) Has been cancelled
Some checks failed
build and test / test-x86_64-linux (push) Has been cancelled
build and test / test-x86_64-osx (push) Has been cancelled
build and test / test-aarch64-osx (push) Has been cancelled
build and test / test-x86_64-win32 (push) Has been cancelled
build and test / test-i386-win32 (push) Has been cancelled
build and test / test-arm64-win32 (push) Has been cancelled
build and test / test-armv7-linux (push) Has been cancelled
build and test / test-aarch64-linux (push) Has been cancelled
build and test / test-riscv64-linux (push) Has been cancelled
build and test / test-i386-linux (push) Has been cancelled
tccelf.c:
- set_elf_sym()
check NOBITS instead of just .bss
- sort_sections()
must have common alignment for tls sections
fix BSD relro
tccpe.c:
- sort .tbss after .tdata
tccrun.c:
- TLS not supported with -run
- arm64: FlushInstructionCache on win32 too
lib/bt-exe.c:
- use less unused bss memory (from global vars in tcc.h)
arm64-gen.c:
- arm64_sym():
direct access (no GOT) for 'static' vars
relocate with 'addend' unless GOT
- reserve X16/x17 for internal usage (specifically to avoid
their usage as value register passed to store())
This commit is contained in:
parent
2ba12e83b3
commit
1bcec040d0
111
arm64-gen.c
111
arm64-gen.c
@ -77,14 +77,10 @@ ST_DATA const int reg_classes[NB_REGS] = {
|
|||||||
RC_INT | RC_R(13),
|
RC_INT | RC_R(13),
|
||||||
RC_INT | RC_R(14),
|
RC_INT | RC_R(14),
|
||||||
RC_INT | RC_R(15),
|
RC_INT | RC_R(15),
|
||||||
RC_INT | RC_R(16),
|
RC_R(16), /* reserved for generator (arm64_sym()) */
|
||||||
RC_INT | RC_R(17),
|
RC_R(17), /* reserved for generator (arm64_sym()) */
|
||||||
#ifdef TCC_TARGET_PE
|
RC_R(18), /* reserved on Windows/OSX */
|
||||||
RC_R(18), /* (x18 reserved on Windows) */
|
RC_R30, /* not in RC_INT as we make special use of x30 */
|
||||||
#else
|
|
||||||
RC_INT | RC_R(18),
|
|
||||||
#endif
|
|
||||||
RC_R30, // not in RC_INT as we make special use of x30
|
|
||||||
RC_FLOAT | RC_F(0),
|
RC_FLOAT | RC_F(0),
|
||||||
RC_FLOAT | RC_F(1),
|
RC_FLOAT | RC_F(1),
|
||||||
RC_FLOAT | RC_F(2),
|
RC_FLOAT | RC_F(2),
|
||||||
@ -298,6 +294,7 @@ static void arm64_spoff(int reg, uint64_t off)
|
|||||||
|
|
||||||
static uint64_t arm64_check_offset(int sz_, uint64_t off)
|
static uint64_t arm64_check_offset(int sz_, uint64_t off)
|
||||||
{
|
{
|
||||||
|
#ifndef TCC_TARGET_PE
|
||||||
uint32_t sz = sz_;
|
uint32_t sz = sz_;
|
||||||
uint64_t scaled_mask = 0xffful << sz;
|
uint64_t scaled_mask = 0xffful << sz;
|
||||||
if (!(off & ~scaled_mask) || (off < 256 || -off <= 256))
|
if (!(off & ~scaled_mask) || (off < 256 || -off <= 256))
|
||||||
@ -306,6 +303,7 @@ static uint64_t arm64_check_offset(int sz_, uint64_t off)
|
|||||||
return scaled_mask;
|
return scaled_mask;
|
||||||
if (off & 0x1fful)
|
if (off & 0x1fful)
|
||||||
return 0x1fful;
|
return 0x1fful;
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,12 +461,17 @@ static void arm64_strv(int sz_, int dst, int bas, uint64_t off)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void arm64_reloca(Sym *sym, int reloc_type, uint64_t addend)
|
||||||
|
{
|
||||||
|
greloca(cur_text_section, sym, ind, reloc_type, addend);
|
||||||
|
}
|
||||||
|
|
||||||
static void arm64_sym(int r, Sym *sym, addr_t addend)
|
static void arm64_sym(int r, Sym *sym, addr_t addend)
|
||||||
{
|
{
|
||||||
if (sym->type.t & VT_TLS) {
|
if (sym->type.t & VT_TLS) {
|
||||||
#if TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
Sym *s2 = external_global_sym(TOK___tls_index, &int_type);
|
Sym *s2 = external_global_sym(TOK___tls_index, &int_type);
|
||||||
int r2 = get_reg(RC_INT);
|
int r2 = get_reg(RC_R(16));
|
||||||
arm64_sym(30, s2, 0);
|
arm64_sym(30, s2, 0);
|
||||||
o(0xb94003de); // ldr w30, [x30]
|
o(0xb94003de); // ldr w30, [x30]
|
||||||
o(0xf9402e40 | r2); // ldr r2, [x18, #88]
|
o(0xf9402e40 | r2); // ldr r2, [x18, #88]
|
||||||
@ -477,46 +480,35 @@ static void arm64_sym(int r, Sym *sym, addr_t addend)
|
|||||||
#else
|
#else
|
||||||
o(0xd53bd040 | r); /* mrs xr, tpidr_el0 */
|
o(0xd53bd040 | r); /* mrs xr, tpidr_el0 */
|
||||||
#endif
|
#endif
|
||||||
greloca(cur_text_section, sym, ind, R_AARCH64_TLSLE_ADD_TPREL_HI12, 0);
|
arm64_reloca(sym, R_AARCH64_TLSLE_ADD_TPREL_HI12, addend);
|
||||||
/* add xr, xr, #0, lsl #12 */
|
o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_SH(1) | ARM64_RN(r) | ARM64_RD(r)); /* add xr, xr, #0, lsl #12 */
|
||||||
o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_SH(1) | ARM64_RN(r) | ARM64_RD(r));
|
arm64_reloca(sym, R_AARCH64_TLSLE_ADD_TPREL_LO12, addend);
|
||||||
greloca(cur_text_section, sym, ind, R_AARCH64_TLSLE_ADD_TPREL_LO12, 0);
|
o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RN(r) | ARM64_RD(r)); /* add xr, xr, #0 */
|
||||||
/* add xr, xr, #0 */
|
#ifndef TCC_TARGET_PE /* no elf-style GOT on Windows */
|
||||||
o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RN(r) | ARM64_RD(r));
|
} else if (!(sym->type.t & VT_STATIC)) {
|
||||||
goto add_addend;
|
arm64_reloca(sym, R_AARCH64_ADR_GOT_PAGE, 0);
|
||||||
}
|
o(ARM64_ADRP | r); /* adrp xr, #sym */
|
||||||
#ifdef TCC_TARGET_PE
|
arm64_reloca(sym, R_AARCH64_LD64_GOT_LO12_NC, 0);
|
||||||
/* PE links symbol addresses directly; there is no ELF-style GOT here. */
|
o(ARM64_LDR_X | ARM64_RN(r) | r); /* ld xr,[xr, #sym] */
|
||||||
greloca(cur_text_section, sym, ind, R_AARCH64_ADR_PREL_PG_HI21, 0);
|
if (addend > 0xffffff) {
|
||||||
o(ARM64_ADRP | r); // adrp xr, #sym
|
int t = get_reg(RC_R(16));
|
||||||
greloca(cur_text_section, sym, ind, R_AARCH64_ADD_ABS_LO12_NC, 0);
|
arm64_movimm(t, addend); // use xt for addent
|
||||||
o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RN(r) | r); // add xr, xr, #sym
|
|
||||||
#else
|
|
||||||
greloca(cur_text_section, sym, ind, R_AARCH64_ADR_GOT_PAGE, 0);
|
|
||||||
o(ARM64_ADRP | r); // adrp xr, #sym
|
|
||||||
greloca(cur_text_section, sym, ind, R_AARCH64_LD64_GOT_LO12_NC, 0);
|
|
||||||
o(ARM64_LDR_X | ARM64_RN(r) | r); // ld xr,[xr, #sym]
|
|
||||||
#endif
|
|
||||||
add_addend:
|
|
||||||
if (addend) {
|
|
||||||
// add xr, xr, #addend
|
|
||||||
if (addend & 0xffful)
|
|
||||||
o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RN(r) | r |
|
|
||||||
(addend & 0xfff) << 10);
|
|
||||||
if (addend > 0xffful) {
|
|
||||||
// add xr, xr, #addend, lsl #12
|
|
||||||
if (addend & 0xfff000ul)
|
|
||||||
o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_SH(1) |
|
|
||||||
ARM64_RN(r) | r | ((addend >> 12) & 0xfff) << 10);
|
|
||||||
if (addend > 0xfffffful) {
|
|
||||||
/* very unlikely */
|
|
||||||
int t = r ? 0 : 1;
|
|
||||||
o(ARM64_STR_X_PRE | 0x001F0FE0U | t); /* str xt, [sp, #-16]! */
|
|
||||||
arm64_movimm(t, addend & ~0xffffffull); // use xt for addent
|
|
||||||
o(ARM64_ADD_REG | ARM64_SF(1) | ARM64_RM(t) | ARM64_RN(r) | r); /* add xr, xr, xt */
|
o(ARM64_ADD_REG | ARM64_SF(1) | ARM64_RM(t) | ARM64_RN(r) | r); /* add xr, xr, xt */
|
||||||
o(ARM64_LDR_X_POST | 0x000107E0U | t); /* ldr xt, [sp], #16 */
|
} else {
|
||||||
}
|
if (addend & 0xfff) /* add xr, xr, #addend */
|
||||||
|
o(ARM64_ADD_IMM | ARM64_SF(1)
|
||||||
|
| ARM64_RN(r) | r | (addend & 0xfff) << 10);
|
||||||
|
addend >>= 12;
|
||||||
|
if (addend & 0xfff) /* add xr, xr, #addend, lsl #12 */
|
||||||
|
o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_SH(1)
|
||||||
|
| ARM64_RN(r) | r | (addend & 0xfff) << 10);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
arm64_reloca(sym, R_AARCH64_ADR_PREL_PG_HI21, addend);
|
||||||
|
o(ARM64_ADRP | r); /* adrp xr, #sym */
|
||||||
|
arm64_reloca(sym, R_AARCH64_ADD_ABS_LO12_NC, addend);
|
||||||
|
o(ARM64_ADD_IMM | ARM64_SF(1) | ARM64_RN(r) | r); /* add xr, xr, #sym */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -678,8 +670,8 @@ ST_FUNC void store(int r, SValue *sv)
|
|||||||
|
|
||||||
static void arm64_gen_bl_or_b(int b)
|
static void arm64_gen_bl_or_b(int b)
|
||||||
{
|
{
|
||||||
if ((vtop->r & (VT_VALMASK | VT_LVAL)) == VT_CONST && (vtop->r & VT_SYM)) {
|
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == (VT_CONST | VT_SYM)) {
|
||||||
greloca(cur_text_section, vtop->sym, ind,
|
arm64_reloca(vtop->sym,
|
||||||
b ? R_AARCH64_JUMP26 : R_AARCH64_CALL26, 0);
|
b ? R_AARCH64_JUMP26 : R_AARCH64_CALL26, 0);
|
||||||
o(b ? ARM64_B : ARM64_BL); // b/bl .
|
o(b ? ARM64_B : ARM64_BL); // b/bl .
|
||||||
}
|
}
|
||||||
@ -691,16 +683,16 @@ static void arm64_gen_bl_or_b(int b)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_TCC_BCHECK)
|
#if defined CONFIG_TCC_BCHECK || defined TCC_TARGET_PE
|
||||||
|
static void gen_static_call(int v)
|
||||||
static void gen_bounds_call(int v)
|
|
||||||
{
|
{
|
||||||
Sym *sym = external_helper_sym(v);
|
Sym *sym = external_helper_sym(v);
|
||||||
|
arm64_reloca(sym, R_AARCH64_CALL26, 0);
|
||||||
greloca(cur_text_section, sym, ind, R_AARCH64_CALL26, 0);
|
|
||||||
o(ARM64_BL); // bl
|
o(ARM64_BL); // bl
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_TCC_BCHECK)
|
||||||
static void gen_bounds_prolog(void)
|
static void gen_bounds_prolog(void)
|
||||||
{
|
{
|
||||||
/* leave some room for bound checking code */
|
/* leave some room for bound checking code */
|
||||||
@ -735,7 +727,7 @@ static void gen_bounds_epilog(void)
|
|||||||
saved_ind = ind;
|
saved_ind = ind;
|
||||||
ind = func_bound_ind;
|
ind = func_bound_ind;
|
||||||
arm64_sym(0, sym_data, 0);
|
arm64_sym(0, sym_data, 0);
|
||||||
gen_bounds_call(TOK___bound_local_new);
|
gen_static_call(TOK___bound_local_new);
|
||||||
ind = saved_ind;
|
ind = saved_ind;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -743,7 +735,7 @@ static void gen_bounds_epilog(void)
|
|||||||
o(0xa9bf07e0); /* stp x0, x1, [sp, #-16]! */
|
o(0xa9bf07e0); /* stp x0, x1, [sp, #-16]! */
|
||||||
o(0x3c9f0fe0); /* str q0, [sp, #-16]! */
|
o(0x3c9f0fe0); /* str q0, [sp, #-16]! */
|
||||||
arm64_sym(0, sym_data, 0);
|
arm64_sym(0, sym_data, 0);
|
||||||
gen_bounds_call(TOK___bound_local_delete);
|
gen_static_call(TOK___bound_local_delete);
|
||||||
o(0x3cc107e0); /* ldr q0, [sp], #16 */
|
o(0x3cc107e0); /* ldr q0, [sp], #16 */
|
||||||
o(0xa8c107e0); /* ldp x0, x1, [sp], #16 */
|
o(0xa8c107e0); /* ldp x0, x1, [sp], #16 */
|
||||||
}
|
}
|
||||||
@ -1004,11 +996,8 @@ static void arm64_sub_sp(uint64_t diff)
|
|||||||
return;
|
return;
|
||||||
#ifdef TCC_TARGET_PE
|
#ifdef TCC_TARGET_PE
|
||||||
if (diff >= 4096) {
|
if (diff >= 4096) {
|
||||||
Sym *sym = external_helper_sym(TOK___chkstk);
|
|
||||||
|
|
||||||
arm64_movimm(15, diff >> 4);
|
arm64_movimm(15, diff >> 4);
|
||||||
greloca(cur_text_section, sym, ind, R_AARCH64_CALL26, 0);
|
gen_static_call(TOK___chkstk);
|
||||||
o(ARM64_BL); // bl __chkstk
|
|
||||||
o(0xcb2f73ff); // sub sp,sp,x15,lsl #4
|
o(0xcb2f73ff); // sub sp,sp,x15,lsl #4
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
from tccrun.c into executables. */
|
from tccrun.c into executables. */
|
||||||
|
|
||||||
#define CONFIG_TCC_BACKTRACE_ONLY
|
#define CONFIG_TCC_BACKTRACE_ONLY
|
||||||
#define ONE_SOURCE 1
|
#define ONE_SOURCE 0
|
||||||
#define pstrcpy tcc_pstrcpy
|
#define pstrcpy tcc_pstrcpy
|
||||||
#include "../tccrun.c"
|
#include "../tccrun.c"
|
||||||
|
|
||||||
|
|||||||
39
tccelf.c
39
tccelf.c
@ -693,6 +693,14 @@ version_add (TCCState *s1)
|
|||||||
}
|
}
|
||||||
#endif /* ndef ELF_OBJ_ONLY */
|
#endif /* ndef ELF_OBJ_ONLY */
|
||||||
|
|
||||||
|
/* catch .tbss also */
|
||||||
|
static int IS_BSS(TCCState *s1, int ndx)
|
||||||
|
{
|
||||||
|
return ndx == SHN_COMMON
|
||||||
|
|| (ndx < s1->nb_sections
|
||||||
|
&& s1->sections[ndx]->sh_type == SHT_NOBITS);
|
||||||
|
}
|
||||||
|
|
||||||
/* add an elf symbol : check if it is already defined and patch
|
/* add an elf symbol : check if it is already defined and patch
|
||||||
it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
|
it. Return symbol index. NOTE that sh_num can be SHN_UNDEF. */
|
||||||
ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
|
ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
|
||||||
@ -744,13 +752,10 @@ ST_FUNC int set_elf_sym(Section *s, addr_t value, unsigned long size,
|
|||||||
/* ignore hidden symbols after */
|
/* ignore hidden symbols after */
|
||||||
} else if (s->sh_flags & SHF_DYNSYM) {
|
} else if (s->sh_flags & SHF_DYNSYM) {
|
||||||
/* we accept that two DLL define the same symbol */
|
/* we accept that two DLL define the same symbol */
|
||||||
} else if ((esym->st_shndx == SHN_COMMON
|
} else if (!IS_BSS(s1, shndx) && IS_BSS(s1, esym->st_shndx)) {
|
||||||
|| esym->st_shndx == bss_section->sh_num)
|
|
||||||
&& (shndx < SHN_LORESERVE
|
|
||||||
&& shndx != bss_section->sh_num)) {
|
|
||||||
/* data symbol gets precedence over common/bss */
|
/* data symbol gets precedence over common/bss */
|
||||||
goto do_patch;
|
goto do_patch;
|
||||||
} else if (shndx == SHN_COMMON || shndx == bss_section->sh_num) {
|
} else if (IS_BSS(s1, shndx)) {
|
||||||
/* data symbol keeps precedence over common/bss */
|
/* data symbol keeps precedence over common/bss */
|
||||||
} else if (esym->st_other & ST_ASM_SET) {
|
} else if (esym->st_other & ST_ASM_SET) {
|
||||||
/* If the existing symbol came from an asm .set
|
/* If the existing symbol came from an asm .set
|
||||||
@ -2259,6 +2264,7 @@ static int sort_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
|
|||||||
int i, j, k, f, f0, n;
|
int i, j, k, f, f0, n;
|
||||||
int nb_sections = s1->nb_sections;
|
int nb_sections = s1->nb_sections;
|
||||||
int *sec_cls = sec_order + nb_sections;
|
int *sec_cls = sec_order + nb_sections;
|
||||||
|
int tls_align = 0; /* need common alignment for all tls sections */
|
||||||
|
|
||||||
for (i = 1; i < nb_sections; i++) {
|
for (i = 1; i < nb_sections; i++) {
|
||||||
s = s1->sections[i];
|
s = s1->sections[i];
|
||||||
@ -2294,6 +2300,8 @@ static int sort_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
|
|||||||
k = 0x60;
|
k = 0x60;
|
||||||
/* RELRO sections --> */
|
/* RELRO sections --> */
|
||||||
} else if (s->sh_flags & SHF_TLS) {
|
} else if (s->sh_flags & SHF_TLS) {
|
||||||
|
if (s->sh_addralign > tls_align)
|
||||||
|
tls_align = s->sh_addralign;
|
||||||
k = 0x40 + (s->sh_type == SHT_NOBITS);
|
k = 0x40 + (s->sh_type == SHT_NOBITS);
|
||||||
} else if (s->sh_type == SHT_PREINIT_ARRAY) {
|
} else if (s->sh_type == SHT_PREINIT_ARRAY) {
|
||||||
k = 0x42;
|
k = 0x42;
|
||||||
@ -2302,11 +2310,11 @@ static int sort_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
|
|||||||
} else if (s->sh_type == SHT_FINI_ARRAY) {
|
} else if (s->sh_type == SHT_FINI_ARRAY) {
|
||||||
k = 0x44;
|
k = 0x44;
|
||||||
} else if (s->sh_type == SHT_DYNAMIC) {
|
} else if (s->sh_type == SHT_DYNAMIC) {
|
||||||
k = 0x46;
|
k = 0x48;
|
||||||
} else if (s == s1->got) {
|
} else if (s == s1->got) {
|
||||||
k = 0x47; /* .got as RELRO needs BIND_NOW in DT_FLAGS */
|
k = 0x49; /* .got as RELRO needs BIND_NOW in DT_FLAGS */
|
||||||
} else if (s->reloc && (s->reloc->sh_flags & SHF_ALLOC) && j == 0x100) {
|
} else if (s->reloc && (s->reloc->sh_flags & SHF_ALLOC) && j == 0x100) {
|
||||||
k = 0x45;
|
k = 0x45; /* +1 for data.ro */
|
||||||
/* <-- */
|
/* <-- */
|
||||||
} else if (s->sh_type == SHT_NOTE) {
|
} else if (s->sh_type == SHT_NOTE) {
|
||||||
k = 0x08, d->notes = 1;
|
k = 0x08, d->notes = 1;
|
||||||
@ -2349,15 +2357,18 @@ static int sort_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
|
|||||||
/* NetBSD only supports 2 PT_LOAD sections.
|
/* NetBSD only supports 2 PT_LOAD sections.
|
||||||
See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
|
See: https://blog.netbsd.org/tnf/entry/the_first_report_on_lld */
|
||||||
if ((f & SHF_WRITE) == 0)
|
if ((f & SHF_WRITE) == 0)
|
||||||
f |= SHF_EXECINSTR, k = 0; /* no relro */
|
f |= SHF_EXECINSTR;
|
||||||
|
k = 0; /* no relro */
|
||||||
#endif
|
#endif
|
||||||
|
if ((k & 0xfff0) == 0x240) /* RELRO sections */
|
||||||
|
d->relro = 1, f |= SHFX_RELRO;
|
||||||
/* start new header when flags changed, but avoid zero memsz */
|
/* start new header when flags changed, but avoid zero memsz */
|
||||||
if (f != f0 && s->sh_size)
|
if (f != f0 && s->sh_size)
|
||||||
f0 = f, ++n, f |= SHFX_NEWPH;
|
f0 = f, ++n, f |= SHFX_NEWPH;
|
||||||
if ((s->sh_flags & SHF_TLS) && s->sh_size)
|
if ((s->sh_flags & SHF_TLS) && s->sh_size) {
|
||||||
|
s->sh_addralign = tls_align;
|
||||||
d->tls = 1, f |= SHF_TLS;
|
d->tls = 1, f |= SHF_TLS;
|
||||||
if ((k & 0xfff0) == 0x240) /* RELRO sections */
|
}
|
||||||
d->relro = 1, f |= SHFX_RELRO;
|
|
||||||
}
|
}
|
||||||
sec_cls[i] = f;
|
sec_cls[i] = f;
|
||||||
//printf("ph %d sec %02d : %3X %3X %8.2X %04X %s\n", (f>0) * n, i, f, k, s->sh_type, (int)s->sh_size, s->name);
|
//printf("ph %d sec %02d : %3X %3X %8.2X %04X %s\n", (f>0) * n, i, f, k, s->sh_type, (int)s->sh_size, s->name);
|
||||||
@ -2484,7 +2495,7 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
|
|||||||
s->sh_offset = file_offset;
|
s->sh_offset = file_offset;
|
||||||
s->sh_addr = addr;
|
s->sh_addr = addr;
|
||||||
|
|
||||||
//printf("%d : %08x %08x %04x %03x %s\n", (int)(ph - d->phdr), (int)file_offset, (int)addr, (int)s->sh_size, s->sh_type, s->name);
|
//printf("%d : %08x %08x %04x %03x %s %d\n", n, (int)file_offset, (int)addr, (int)s->sh_size, s->sh_type, s->name, align + 1);
|
||||||
addr += s->sh_size;
|
addr += s->sh_size;
|
||||||
if (s->sh_type != SHT_NOBITS)
|
if (s->sh_type != SHT_NOBITS)
|
||||||
file_offset += s->sh_size;
|
file_offset += s->sh_size;
|
||||||
@ -2516,8 +2527,6 @@ static int layout_sections(TCCState *s1, int *sec_order, struct dyn_inf *d)
|
|||||||
}
|
}
|
||||||
if (f & SHF_TLS) {
|
if (f & SHF_TLS) {
|
||||||
ph2 = update_phdr(&d->phdr[d->tls], PT_TLS, s, addr, file_offset);
|
ph2 = update_phdr(&d->phdr[d->tls], PT_TLS, s, addr, file_offset);
|
||||||
if (s->sh_addralign > ph2->p_align)
|
|
||||||
ph2->p_align = s->sh_addralign;
|
|
||||||
if (s->sh_type == SHT_NOBITS)
|
if (s->sh_type == SHT_NOBITS)
|
||||||
addr -= s->sh_size;
|
addr -= s->sh_size;
|
||||||
/* for xxx-link.c:relocate() */
|
/* for xxx-link.c:relocate() */
|
||||||
|
|||||||
26
tccpe.c
26
tccpe.c
@ -351,7 +351,8 @@ enum {
|
|||||||
sec_bss ,
|
sec_bss ,
|
||||||
sec_idata ,
|
sec_idata ,
|
||||||
sec_pdata ,
|
sec_pdata ,
|
||||||
sec_tls ,
|
sec_tdata ,
|
||||||
|
sec_tbss ,
|
||||||
sec_other ,
|
sec_other ,
|
||||||
sec_rsrc ,
|
sec_rsrc ,
|
||||||
sec_debug ,
|
sec_debug ,
|
||||||
@ -1197,6 +1198,7 @@ static void pe_build_tls(struct pe_info *pe, Section *s)
|
|||||||
int c, n;
|
int c, n;
|
||||||
|
|
||||||
if (0 == s) {
|
if (0 == s) {
|
||||||
|
pe->tls_size = sizeof (IMAGE_TLS_DIRECTORY);
|
||||||
pe->tls_dir = section_add(pe->thunk, pe->tls_size, 16);
|
pe->tls_dir = section_add(pe->thunk, pe->tls_size, 16);
|
||||||
pe->tls_data = section_add(data_section, PTR_SIZE * (1+3), 16);
|
pe->tls_data = section_add(data_section, PTR_SIZE * (1+3), 16);
|
||||||
/* put relocations on entries */
|
/* put relocations on entries */
|
||||||
@ -1209,6 +1211,7 @@ static void pe_build_tls(struct pe_info *pe, Section *s)
|
|||||||
0, data_section->sh_num, "__tls_index");
|
0, data_section->sh_num, "__tls_index");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == s1->tls_start)
|
if (0 == s1->tls_start)
|
||||||
s1->tls_start = s->sh_addr;
|
s1->tls_start = s->sh_addr;
|
||||||
d = (void*)(pe->thunk->data + pe->tls_dir);
|
d = (void*)(pe->thunk->data + pe->tls_dir);
|
||||||
@ -1235,7 +1238,7 @@ static int pe_section_class(Section *s)
|
|||||||
return sec_debug;
|
return sec_debug;
|
||||||
} else if (flags & SHF_ALLOC) {
|
} else if (flags & SHF_ALLOC) {
|
||||||
if (flags & SHF_TLS)
|
if (flags & SHF_TLS)
|
||||||
return sec_tls;
|
return sec_tdata + (type == SHT_NOBITS);
|
||||||
if (type == SHT_PROGBITS
|
if (type == SHT_PROGBITS
|
||||||
|| type == SHT_INIT_ARRAY
|
|| type == SHT_INIT_ARRAY
|
||||||
|| type == SHT_FINI_ARRAY) {
|
|| type == SHT_FINI_ARRAY) {
|
||||||
@ -1273,6 +1276,7 @@ static int pe_assign_addresses (struct pe_info *pe)
|
|||||||
if (PE_DLL == pe->type
|
if (PE_DLL == pe->type
|
||||||
|| (s1->pe_dll_characteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE))
|
|| (s1->pe_dll_characteristics & IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE))
|
||||||
pe->reloc = new_section(s1, ".reloc", SHT_PROGBITS, 0);
|
pe->reloc = new_section(s1, ".reloc", SHT_PROGBITS, 0);
|
||||||
|
pe->thunk = rodata_section;
|
||||||
//pe->thunk = new_section(s1, ".iedat", SHT_PROGBITS, SHF_ALLOC);
|
//pe->thunk = new_section(s1, ".iedat", SHT_PROGBITS, SHF_ALLOC);
|
||||||
|
|
||||||
nbs = s1->nb_sections;
|
nbs = s1->nb_sections;
|
||||||
@ -1284,35 +1288,30 @@ static int pe_assign_addresses (struct pe_info *pe)
|
|||||||
for (n = i; n > 1 && k < (c = sec_cls[n - 1]); --n)
|
for (n = i; n > 1 && k < (c = sec_cls[n - 1]); --n)
|
||||||
sec_cls[n] = c, sec_order[n] = sec_order[n - 1];
|
sec_cls[n] = c, sec_order[n] = sec_order[n - 1];
|
||||||
sec_cls[n] = k, sec_order[n] = i;
|
sec_cls[n] = k, sec_order[n] = i;
|
||||||
if (k == sec_tls)
|
if ((s->sh_flags & SHF_TLS) && 0 == pe->tls_size)
|
||||||
pe->tls_size = sizeof (IMAGE_TLS_DIRECTORY);
|
pe_build_tls(pe, NULL);
|
||||||
}
|
}
|
||||||
si = NULL;
|
si = NULL;
|
||||||
addr = pe->imagebase + 1;
|
addr = pe->imagebase + 1;
|
||||||
|
|
||||||
for (i = 1; (c = sec_cls[i]) < sec_last; ++i) {
|
for (i = 1; (c = sec_cls[i]) < sec_last; ++i) {
|
||||||
s = s1->sections[sec_order[i]];
|
s = s1->sections[sec_order[i]];
|
||||||
|
|
||||||
if (PE_MERGE_DATA && c == sec_bss)
|
if (PE_MERGE_DATA && c == sec_bss)
|
||||||
c = sec_data;
|
c = sec_data;
|
||||||
|
if (c == sec_tbss)
|
||||||
|
c = sec_tdata;
|
||||||
|
|
||||||
if (si && c == si->cls && c != sec_debug) {
|
if (si && c == si->cls && c != sec_debug) {
|
||||||
/* merge with previous section */
|
/* merge with previous section */
|
||||||
s->sh_addr = addr = ((addr - 1) | (16 - 1)) + 1;
|
s->sh_addr = addr = ((addr - 1) | (s->sh_addralign - 1)) + 1;
|
||||||
} else {
|
} else {
|
||||||
si = NULL;
|
si = NULL;
|
||||||
s->sh_addr = addr = pe_virtual_align(pe, addr);
|
s->sh_addr = addr = pe_virtual_align(pe, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL == pe->thunk
|
|
||||||
&& c == (data_section == rodata_section ? sec_data : sec_rdata))
|
|
||||||
pe->thunk = s;
|
|
||||||
|
|
||||||
if (s == pe->thunk) {
|
if (s == pe->thunk) {
|
||||||
pe_build_imports(pe);
|
pe_build_imports(pe);
|
||||||
pe_build_exports(pe);
|
pe_build_exports(pe);
|
||||||
if (pe->tls_size)
|
|
||||||
pe_build_tls(pe, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s == pe->reloc)
|
if (s == pe->reloc)
|
||||||
@ -1367,7 +1366,7 @@ add_section:
|
|||||||
Section *s = s1->sections[sec_order[i]];
|
Section *s = s1->sections[sec_order[i]];
|
||||||
int type = s->sh_type;
|
int type = s->sh_type;
|
||||||
int flags = s->sh_flags;
|
int flags = s->sh_flags;
|
||||||
printf("section %-16s %-10s %p %04x %s,%s,%s\n",
|
printf("section %-16s %-10s %p %04x %2d %s,%s,%s\n",
|
||||||
s->name,
|
s->name,
|
||||||
type == SHT_PROGBITS ? "progbits" :
|
type == SHT_PROGBITS ? "progbits" :
|
||||||
type == SHT_INIT_ARRAY ? "initarr" :
|
type == SHT_INIT_ARRAY ? "initarr" :
|
||||||
@ -1378,6 +1377,7 @@ add_section:
|
|||||||
type == SHT_RELX ? "rel" : "???",
|
type == SHT_RELX ? "rel" : "???",
|
||||||
s->sh_addr,
|
s->sh_addr,
|
||||||
(unsigned)s->data_offset,
|
(unsigned)s->data_offset,
|
||||||
|
s->sh_addralign,
|
||||||
flags & SHF_ALLOC ? "alloc" : "",
|
flags & SHF_ALLOC ? "alloc" : "",
|
||||||
flags & SHF_WRITE ? "write" : "",
|
flags & SHF_WRITE ? "write" : "",
|
||||||
flags & SHF_EXECINSTR ? "exec" : ""
|
flags & SHF_EXECINSTR ? "exec" : ""
|
||||||
|
|||||||
12
tccrun.c
12
tccrun.c
@ -385,6 +385,9 @@ redo:
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((s->sh_flags & SHF_TLS) && length)
|
||||||
|
return tcc_error_noabort("thread-local storage not supported with -run");
|
||||||
|
|
||||||
align = s->sh_addralign;
|
align = s->sh_addralign;
|
||||||
if (++n == 1) {
|
if (++n == 1) {
|
||||||
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
|
#if defined TCC_TARGET_I386 || defined TCC_TARGET_X86_64
|
||||||
@ -486,13 +489,18 @@ static int protect_pages(void *ptr, unsigned long length, int mode)
|
|||||||
};
|
};
|
||||||
if (mprotect(ptr, length, protect[mode]))
|
if (mprotect(ptr, length, protect[mode]))
|
||||||
return -1;
|
return -1;
|
||||||
|
#endif
|
||||||
/* XXX: BSD sometimes dump core with bad system call */
|
/* XXX: BSD sometimes dump core with bad system call */
|
||||||
# if (defined TCC_TARGET_ARM && !TARGETOS_BSD) || defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
|
#if (defined TCC_TARGET_ARM && !TARGETOS_BSD) \
|
||||||
|
|| defined TCC_TARGET_ARM64 || defined TCC_TARGET_RISCV64
|
||||||
if (mode == 0 || mode == 3) {
|
if (mode == 0 || mode == 3) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
FlushInstructionCache(GetCurrentProcess(), ptr, length);
|
||||||
|
#else
|
||||||
void __clear_cache(void *beginning, void *end);
|
void __clear_cache(void *beginning, void *end);
|
||||||
__clear_cache(ptr, (char *)ptr + length);
|
__clear_cache(ptr, (char *)ptr + length);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
# endif
|
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user