text relocation for netbsd
netbsd does not allow text relocations in text segment. tcc.h: - Add data_ro_section - Fix typo rela.plt tccelf.c: - Add data_ro_section - Make bounds_section/lbounds_section rw - Add GNU_RELRO section for data_ro_section/bounds_section/lbounds_section - Fix relocation for __dso_handle in atexit() tccgen.c: - Use data_ro_section x86_64-gen.c: - Use R_X86_64_PC32 instead of R_X86_64_64 for bounds checking tests/Makefile, tests/tests2/Makefile - Enable dll tests for netbsd
This commit is contained in:
parent
c13c434383
commit
0821940e26
6 changed files with 101 additions and 44 deletions
5
tcc.h
5
tcc.h
|
@ -409,7 +409,7 @@ extern long double strtold (const char *__nptr, char **__endptr);
|
||||||
# define ElfW_Rel ElfW(Rela)
|
# define ElfW_Rel ElfW(Rela)
|
||||||
# define SHT_RELX SHT_RELA
|
# define SHT_RELX SHT_RELA
|
||||||
# define REL_SECTION_FMT ".rela%s"
|
# define REL_SECTION_FMT ".rela%s"
|
||||||
# define RELPLT_SECTION_FMT ".rel.plt"
|
# define RELPLT_SECTION_FMT ".rela.plt"
|
||||||
#else
|
#else
|
||||||
# define ELFCLASSW ELFCLASS32
|
# define ELFCLASSW ELFCLASS32
|
||||||
# define ElfW(type) Elf##32##_##type
|
# define ElfW(type) Elf##32##_##type
|
||||||
|
@ -872,7 +872,7 @@ struct TCCState {
|
||||||
Section *plt;
|
Section *plt;
|
||||||
|
|
||||||
/* predefined sections */
|
/* predefined sections */
|
||||||
Section *text_section, *data_section, *bss_section;
|
Section *text_section, *data_section, *data_ro_section, *bss_section;
|
||||||
Section *common_section;
|
Section *common_section;
|
||||||
Section *cur_text_section; /* current section where function code is generated */
|
Section *cur_text_section; /* current section where function code is generated */
|
||||||
#ifdef CONFIG_TCC_BCHECK
|
#ifdef CONFIG_TCC_BCHECK
|
||||||
|
@ -1817,6 +1817,7 @@ ST_FUNC void gen_makedeps(TCCState *s, const char *target, const char *filename)
|
||||||
|
|
||||||
#define text_section TCC_STATE_VAR(text_section)
|
#define text_section TCC_STATE_VAR(text_section)
|
||||||
#define data_section TCC_STATE_VAR(data_section)
|
#define data_section TCC_STATE_VAR(data_section)
|
||||||
|
#define data_ro_section TCC_STATE_VAR(data_ro_section)
|
||||||
#define bss_section TCC_STATE_VAR(bss_section)
|
#define bss_section TCC_STATE_VAR(bss_section)
|
||||||
#define common_section TCC_STATE_VAR(common_section)
|
#define common_section TCC_STATE_VAR(common_section)
|
||||||
#define cur_text_section TCC_STATE_VAR(cur_text_section)
|
#define cur_text_section TCC_STATE_VAR(cur_text_section)
|
||||||
|
|
107
tccelf.c
107
tccelf.c
|
@ -58,6 +58,8 @@ ST_FUNC void tccelf_new(TCCState *s)
|
||||||
/* create standard sections */
|
/* create standard sections */
|
||||||
text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
|
text_section = new_section(s, ".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR);
|
||||||
data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
|
data_section = new_section(s, ".data", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
|
||||||
|
/* create ro data section (make ro after relocation done with GNU_RELRO) */
|
||||||
|
data_ro_section = new_section(s, ".data.ro", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
|
||||||
bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
|
bss_section = new_section(s, ".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
|
||||||
common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
|
common_section = new_section(s, ".common", SHT_NOBITS, SHF_PRIVATE);
|
||||||
common_section->sh_num = SHN_COMMON;
|
common_section->sh_num = SHN_COMMON;
|
||||||
|
@ -79,11 +81,11 @@ ST_FUNC void tccelf_new(TCCState *s)
|
||||||
ST_FUNC void tccelf_bounds_new(TCCState *s)
|
ST_FUNC void tccelf_bounds_new(TCCState *s)
|
||||||
{
|
{
|
||||||
TCCState *s1 = s;
|
TCCState *s1 = s;
|
||||||
/* create bounds sections */
|
/* create bounds sections (make ro after relocation done with GNU_RELRO) */
|
||||||
bounds_section = new_section(s, ".bounds",
|
bounds_section = new_section(s, ".bounds",
|
||||||
SHT_PROGBITS, SHF_ALLOC);
|
SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
|
||||||
lbounds_section = new_section(s, ".lbounds",
|
lbounds_section = new_section(s, ".lbounds",
|
||||||
SHT_PROGBITS, SHF_ALLOC);
|
SHT_PROGBITS, SHF_ALLOC | SHF_WRITE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1043,6 +1045,16 @@ static int prepare_dynamic_rel(TCCState *s1, Section *sr)
|
||||||
case R_386_PC32:
|
case R_386_PC32:
|
||||||
#elif defined(TCC_TARGET_X86_64)
|
#elif defined(TCC_TARGET_X86_64)
|
||||||
case R_X86_64_PC32:
|
case R_X86_64_PC32:
|
||||||
|
{
|
||||||
|
ElfW(Sym) *sym = &((ElfW(Sym) *)symtab_section->data)[sym_index];
|
||||||
|
|
||||||
|
/* support __dso_handle in atexit() */
|
||||||
|
if (sym->st_shndx != SHN_UNDEF &&
|
||||||
|
ELFW(ST_VISIBILITY)(sym->st_other) == STV_HIDDEN) {
|
||||||
|
rel->r_info = ELFW(R_INFO)(sym_index, R_X86_64_PLT32);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
#elif defined(TCC_TARGET_ARM64)
|
#elif defined(TCC_TARGET_ARM64)
|
||||||
case R_AARCH64_PREL32:
|
case R_AARCH64_PREL32:
|
||||||
#endif
|
#endif
|
||||||
|
@ -1828,11 +1840,20 @@ struct dyn_inf {
|
||||||
addr_t rel_size;
|
addr_t rel_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Info for GNU_RELRO */
|
||||||
|
struct ro_inf {
|
||||||
|
addr_t sh_offset;
|
||||||
|
addr_t sh_addr;
|
||||||
|
addr_t sh_size;
|
||||||
|
};
|
||||||
|
|
||||||
/* Assign sections to segments and decide how are sections laid out when loaded
|
/* Assign sections to segments and decide how are sections laid out when loaded
|
||||||
in memory. This function also fills corresponding program headers. */
|
in memory. This function also fills corresponding program headers. */
|
||||||
static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
|
static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr,
|
||||||
|
int phnum, int phfill,
|
||||||
Section *interp, Section* strsec,
|
Section *interp, Section* strsec,
|
||||||
struct dyn_inf *dyninf, int *sec_order)
|
struct dyn_inf *dyninf, struct ro_inf *roinf,
|
||||||
|
int *sec_order)
|
||||||
{
|
{
|
||||||
int i, sh_order_index, file_offset;
|
int i, sh_order_index, file_offset;
|
||||||
Section *s;
|
Section *s;
|
||||||
|
@ -1883,7 +1904,10 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
|
||||||
/* dynamic relocation table information, for .dynamic section */
|
/* dynamic relocation table information, for .dynamic section */
|
||||||
dyninf->rel_addr = dyninf->rel_size = 0;
|
dyninf->rel_addr = dyninf->rel_size = 0;
|
||||||
|
|
||||||
for(j = 0; j < (phnum == 6 ? 3 : 2); j++) {
|
/* read only segment mapping for GNU_RELRO */
|
||||||
|
roinf->sh_offset = roinf->sh_addr = roinf->sh_size = 0;
|
||||||
|
|
||||||
|
for(j = 0; j < phfill; j++) {
|
||||||
Section *relocplt = s1->got ? s1->got->relocplt : NULL;
|
Section *relocplt = s1->got ? s1->got->relocplt : NULL;
|
||||||
|
|
||||||
ph->p_type = j == 2 ? PT_TLS : PT_LOAD;
|
ph->p_type = j == 2 ? PT_TLS : PT_LOAD;
|
||||||
|
@ -1898,7 +1922,7 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
|
||||||
info about the layout. We do the following ordering: interp,
|
info about the layout. We do the following ordering: interp,
|
||||||
symbol tables, relocations, progbits, nobits */
|
symbol tables, relocations, progbits, nobits */
|
||||||
/* XXX: do faster and simpler sorting */
|
/* XXX: do faster and simpler sorting */
|
||||||
for(k = 0; k < 6; k++) {
|
for(k = 0; k < 7; k++) {
|
||||||
for(i = 1; i < s1->nb_sections; i++) {
|
for(i = 1; i < s1->nb_sections; i++) {
|
||||||
s = s1->sections[i];
|
s = s1->sections[i];
|
||||||
/* compute if section should be included */
|
/* compute if section should be included */
|
||||||
|
@ -1930,10 +1954,15 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
|
||||||
else if (k != 3 && s == relocplt)
|
else if (k != 3 && s == relocplt)
|
||||||
continue;
|
continue;
|
||||||
} else if (s->sh_type == SHT_NOBITS) {
|
} else if (s->sh_type == SHT_NOBITS) {
|
||||||
if (k != 5)
|
if (k != 6)
|
||||||
|
continue;
|
||||||
|
} else if (s == data_ro_section ||
|
||||||
|
s == bounds_section ||
|
||||||
|
s == lbounds_section) {
|
||||||
|
if (k != 4)
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if (k != 4)
|
if (k != 5)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
sec_order[sh_order_index++] = i;
|
sec_order[sh_order_index++] = i;
|
||||||
|
@ -1956,7 +1985,16 @@ static int layout_sections(TCCState *s1, ElfW(Phdr) *phdr, int phnum,
|
||||||
if (s->sh_type == SHT_RELX && s != relocplt) {
|
if (s->sh_type == SHT_RELX && s != relocplt) {
|
||||||
if (dyninf->rel_size == 0)
|
if (dyninf->rel_size == 0)
|
||||||
dyninf->rel_addr = addr;
|
dyninf->rel_addr = addr;
|
||||||
dyninf->rel_size += s->sh_size;
|
dyninf->rel_size = (addr - dyninf->rel_addr) + s->sh_size;
|
||||||
|
}
|
||||||
|
if (s == data_ro_section ||
|
||||||
|
s == bounds_section ||
|
||||||
|
s == lbounds_section) {
|
||||||
|
if (roinf->sh_size == 0) {
|
||||||
|
roinf->sh_offset = s->sh_offset;
|
||||||
|
roinf->sh_addr = s->sh_addr;
|
||||||
|
}
|
||||||
|
roinf->sh_size = (addr - roinf->sh_addr) + s->sh_size;
|
||||||
}
|
}
|
||||||
addr += s->sh_size;
|
addr += s->sh_size;
|
||||||
if (s->sh_type != SHT_NOBITS)
|
if (s->sh_type != SHT_NOBITS)
|
||||||
|
@ -2018,7 +2056,7 @@ static void put_dt(Section *dynamic, int dt, addr_t val)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
|
static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
|
||||||
Section *dynamic, Section *note)
|
Section *dynamic, Section *note, struct ro_inf *roinf)
|
||||||
{
|
{
|
||||||
ElfW(Phdr) *ph;
|
ElfW(Phdr) *ph;
|
||||||
|
|
||||||
|
@ -2046,7 +2084,7 @@ static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (note) {
|
if (note) {
|
||||||
ph = &phdr[phnum - 2];
|
ph = &phdr[phnum - 2 - (roinf != NULL)];
|
||||||
|
|
||||||
ph->p_type = PT_NOTE;
|
ph->p_type = PT_NOTE;
|
||||||
ph->p_offset = note->sh_offset;
|
ph->p_offset = note->sh_offset;
|
||||||
|
@ -2060,7 +2098,7 @@ static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
|
||||||
|
|
||||||
/* if dynamic section, then add corresponding program header */
|
/* if dynamic section, then add corresponding program header */
|
||||||
if (dynamic) {
|
if (dynamic) {
|
||||||
ph = &phdr[phnum - 1];
|
ph = &phdr[phnum - 1 - (roinf != NULL)];
|
||||||
|
|
||||||
ph->p_type = PT_DYNAMIC;
|
ph->p_type = PT_DYNAMIC;
|
||||||
ph->p_offset = dynamic->sh_offset;
|
ph->p_offset = dynamic->sh_offset;
|
||||||
|
@ -2071,6 +2109,19 @@ static void fill_unloadable_phdr(ElfW(Phdr) *phdr, int phnum, Section *interp,
|
||||||
ph->p_flags = PF_R | PF_W;
|
ph->p_flags = PF_R | PF_W;
|
||||||
ph->p_align = dynamic->sh_addralign;
|
ph->p_align = dynamic->sh_addralign;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (roinf) {
|
||||||
|
ph = &phdr[phnum - 1];
|
||||||
|
|
||||||
|
ph->p_type = PT_GNU_RELRO;
|
||||||
|
ph->p_offset = roinf->sh_offset;
|
||||||
|
ph->p_vaddr = roinf->sh_addr;
|
||||||
|
ph->p_paddr = ph->p_vaddr;
|
||||||
|
ph->p_filesz = roinf->sh_size;
|
||||||
|
ph->p_memsz = roinf->sh_size;
|
||||||
|
ph->p_flags = PF_R;
|
||||||
|
ph->p_align = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fill the dynamic section with tags describing the address and size of
|
/* Fill the dynamic section with tags describing the address and size of
|
||||||
|
@ -2440,8 +2491,9 @@ static Section *create_bsd_note_section(TCCState *s1,
|
||||||
/* XXX: suppress unneeded sections */
|
/* XXX: suppress unneeded sections */
|
||||||
static int elf_output_file(TCCState *s1, const char *filename)
|
static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
{
|
{
|
||||||
int ret, phnum, shnum, file_type, file_offset, *sec_order;
|
int i, ret, phnum, phfill, shnum, file_type, file_offset, *sec_order;
|
||||||
struct dyn_inf dyninf = {0};
|
struct dyn_inf dyninf = {0};
|
||||||
|
struct ro_inf roinf, *roinf_use = NULL;
|
||||||
ElfW(Phdr) *phdr;
|
ElfW(Phdr) *phdr;
|
||||||
Section *strsec, *interp, *dynamic, *dynstr, *note = NULL;
|
Section *strsec, *interp, *dynamic, *dynstr, *note = NULL;
|
||||||
|
|
||||||
|
@ -2489,6 +2541,8 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
|
s1->dynsym = new_symtab(s1, ".dynsym", SHT_DYNSYM, SHF_ALLOC,
|
||||||
".dynstr",
|
".dynstr",
|
||||||
".hash", SHF_ALLOC);
|
".hash", SHF_ALLOC);
|
||||||
|
/* Number of local symbols (readelf complains if not set) */
|
||||||
|
s1->dynsym->sh_info = 1;
|
||||||
dynstr = s1->dynsym->link;
|
dynstr = s1->dynsym->link;
|
||||||
/* add dynamic section */
|
/* add dynamic section */
|
||||||
dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
|
dynamic = new_section(s1, ".dynamic", SHT_DYNAMIC,
|
||||||
|
@ -2556,22 +2610,31 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
for (i = 1; i < s1->nb_sections &&
|
||||||
|
!(s1->sections[i]->sh_flags & SHF_TLS); i++);
|
||||||
|
phfill = 2 + (i < s1->nb_sections);
|
||||||
|
|
||||||
/* compute number of program headers */
|
/* compute number of program headers */
|
||||||
if (file_type == TCC_OUTPUT_OBJ)
|
if (file_type == TCC_OUTPUT_OBJ)
|
||||||
phnum = 0;
|
phnum = phfill = 0;
|
||||||
else if (file_type == TCC_OUTPUT_DLL)
|
else if (file_type == TCC_OUTPUT_DLL)
|
||||||
phnum = 3;
|
phnum = 3;
|
||||||
else if (s1->static_link)
|
else if (s1->static_link)
|
||||||
phnum = 2;
|
phnum = 2;
|
||||||
else {
|
else {
|
||||||
int i;
|
phnum = 5 + (i < s1->nb_sections);
|
||||||
for (i = 1; i < s1->nb_sections &&
|
|
||||||
!(s1->sections[i]->sh_flags & SHF_TLS); i++);
|
|
||||||
phnum = i < s1->nb_sections ? 6 : 5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
phnum += note != NULL;
|
phnum += note != NULL;
|
||||||
|
|
||||||
|
#if !TARGETOS_FreeBSD && !TARGETOS_NetBSD && !defined(__APPLE__) && !defined(_WIN32)
|
||||||
|
/* GNU_RELRO */
|
||||||
|
if (file_type != TCC_OUTPUT_OBJ) {
|
||||||
|
phnum++;
|
||||||
|
roinf_use = &roinf;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* allocate program segment headers */
|
/* allocate program segment headers */
|
||||||
phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
|
phdr = tcc_mallocz(phnum * sizeof(ElfW(Phdr)));
|
||||||
|
|
||||||
|
@ -2583,14 +2646,14 @@ static int elf_output_file(TCCState *s1, const char *filename)
|
||||||
sec_order[0] = 0;
|
sec_order[0] = 0;
|
||||||
|
|
||||||
/* compute section to program header mapping */
|
/* compute section to program header mapping */
|
||||||
file_offset = layout_sections(s1, phdr, phnum, interp, strsec, &dyninf,
|
file_offset = layout_sections(s1, phdr, phnum, phfill, interp, strsec,
|
||||||
sec_order);
|
&dyninf, &roinf, sec_order);
|
||||||
|
|
||||||
#ifndef ELF_OBJ_ONLY
|
#ifndef ELF_OBJ_ONLY
|
||||||
/* Fill remaining program header and finalize relocation related to dynamic
|
/* Fill remaining program header and finalize relocation related to dynamic
|
||||||
linking. */
|
linking. */
|
||||||
if (file_type != TCC_OUTPUT_OBJ) {
|
if (file_type != TCC_OUTPUT_OBJ) {
|
||||||
fill_unloadable_phdr(phdr, phnum, interp, dynamic, note);
|
fill_unloadable_phdr(phdr, phnum, interp, dynamic, note, roinf_use);
|
||||||
if (dynamic) {
|
if (dynamic) {
|
||||||
ElfW(Sym) *sym;
|
ElfW(Sym) *sym;
|
||||||
dynamic->data_offset = dyninf.data_offset;
|
dynamic->data_offset = dyninf.data_offset;
|
||||||
|
|
4
tccgen.c
4
tccgen.c
|
@ -8120,7 +8120,9 @@ static void decl_initializer_alloc(CType *type, AttributeDef *ad, int r,
|
||||||
/* allocate symbol in corresponding section */
|
/* allocate symbol in corresponding section */
|
||||||
sec = ad->section;
|
sec = ad->section;
|
||||||
if (!sec) {
|
if (!sec) {
|
||||||
if (has_init)
|
if (type->t & VT_CONSTANT)
|
||||||
|
sec = data_ro_section;
|
||||||
|
else if (has_init)
|
||||||
sec = data_section;
|
sec = data_section;
|
||||||
else if (tcc_state->nocommon)
|
else if (tcc_state->nocommon)
|
||||||
sec = bss_section;
|
sec = bss_section;
|
||||||
|
|
|
@ -64,17 +64,11 @@ endif
|
||||||
ifeq ($(TARGETOS),OpenBSD)
|
ifeq ($(TARGETOS),OpenBSD)
|
||||||
dlltest: CFLAGS+=-fno-stack-protector
|
dlltest: CFLAGS+=-fno-stack-protector
|
||||||
endif
|
endif
|
||||||
ifeq ($(TARGETOS),FreeBSD)
|
ifneq (,$(filter FreeBSD NetBSD,$(TARGETOS)))
|
||||||
# test3 has dlsym problems
|
# test3 has dlsym problems
|
||||||
TESTS := $(filter-out test3,$(TESTS))
|
TESTS := $(filter-out test3,$(TESTS))
|
||||||
TESTS += test1
|
TESTS += test1
|
||||||
endif
|
endif
|
||||||
ifeq ($(TARGETOS),NetBSD)
|
|
||||||
# test3 has dlsym problems
|
|
||||||
# dlltest does not allow text relocations
|
|
||||||
TESTS := $(filter-out test3 dlltest,$(TESTS))
|
|
||||||
TESTS += test1
|
|
||||||
endif
|
|
||||||
|
|
||||||
RUN_TCC = $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS)
|
RUN_TCC = $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS)
|
||||||
DISAS = objdump -d
|
DISAS = objdump -d
|
||||||
|
|
|
@ -53,9 +53,6 @@ ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS)))
|
||||||
SKIP += 114_bound_signal.test # libc problem signal/fork
|
SKIP += 114_bound_signal.test # libc problem signal/fork
|
||||||
SKIP += 116_bound_setjmp2.test # No TLS_FUNC/TLS_VAR in bcheck.c
|
SKIP += 116_bound_setjmp2.test # No TLS_FUNC/TLS_VAR in bcheck.c
|
||||||
endif
|
endif
|
||||||
ifeq ($(TARGETOS),NetBSD)
|
|
||||||
SKIP += 113_btdll.test # text relocations
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Some tests might need arguments
|
# Some tests might need arguments
|
||||||
ARGS =
|
ARGS =
|
||||||
|
|
14
x86_64-gen.c
14
x86_64-gen.c
|
@ -674,8 +674,8 @@ static void gen_bounds_prolog(void)
|
||||||
func_bound_offset = lbounds_section->data_offset;
|
func_bound_offset = lbounds_section->data_offset;
|
||||||
func_bound_ind = ind;
|
func_bound_ind = ind;
|
||||||
func_bound_add_epilog = 0;
|
func_bound_add_epilog = 0;
|
||||||
o(0xb848 + TREG_FASTCALL_1 * 0x100); /*lbound section pointer */
|
o(0x0d8d48 + ((TREG_FASTCALL_1 == TREG_RDI) * 0x300000)); /*lbound section pointer */
|
||||||
gen_le64 (0);
|
gen_le32 (0);
|
||||||
oad(0xb8, 0); /* call to function */
|
oad(0xb8, 0); /* call to function */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -700,17 +700,17 @@ static void gen_bounds_epilog(void)
|
||||||
if (offset_modified) {
|
if (offset_modified) {
|
||||||
saved_ind = ind;
|
saved_ind = ind;
|
||||||
ind = func_bound_ind;
|
ind = func_bound_ind;
|
||||||
greloca(cur_text_section, sym_data, ind + 2, R_X86_64_64, 0);
|
greloca(cur_text_section, sym_data, ind + 3, R_X86_64_PC32, -4);
|
||||||
ind = ind + 10;
|
ind = ind + 7;
|
||||||
gen_bounds_call(TOK___bound_local_new);
|
gen_bounds_call(TOK___bound_local_new);
|
||||||
ind = saved_ind;
|
ind = saved_ind;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* generate bound check local freeing */
|
/* generate bound check local freeing */
|
||||||
o(0x5250); /* save returned value, if any */
|
o(0x5250); /* save returned value, if any */
|
||||||
greloca(cur_text_section, sym_data, ind + 2, R_X86_64_64, 0);
|
greloca(cur_text_section, sym_data, ind + 3, R_X86_64_PC32, -4);
|
||||||
o(0xb848 + TREG_FASTCALL_1 * 0x100); /* mov xxx, %rcx/di */
|
o(0x0d8d48 + ((TREG_FASTCALL_1 == TREG_RDI) * 0x300000)); /* lea xxx(%rip), %rcx/rdi */
|
||||||
gen_le64 (0);
|
gen_le32 (0);
|
||||||
gen_bounds_call(TOK___bound_local_delete);
|
gen_bounds_call(TOK___bound_local_delete);
|
||||||
o(0x585a); /* restore returned value, if any */
|
o(0x585a); /* restore returned value, if any */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue