mirror of
https://github.com/mirror/tinycc.git
synced 2024-12-26 03:50:07 +08:00
Use RELA relocations properly for R_DATA_PTR on x86_64.
libtcc.c: Add greloca, a generalisation of greloc that takes an addend. tcc.h: Add greloca and put_elf_reloca. tccelf.c: Add put_elf_reloca, a generalisation of put_elf_reloc. tccgen.c: On x86_64, use greloca instead of greloc in init_putv.
This commit is contained in:
parent
86c850fc58
commit
738606dbd5
10
libtcc.c
10
libtcc.c
@ -536,7 +536,8 @@ ST_FUNC void put_extern_sym(Sym *sym, Section *section,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* add a new relocation entry to symbol 'sym' in section 's' */
|
/* add a new relocation entry to symbol 'sym' in section 's' */
|
||||||
ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
|
ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type,
|
||||||
|
unsigned long addend)
|
||||||
{
|
{
|
||||||
int c = 0;
|
int c = 0;
|
||||||
if (sym) {
|
if (sym) {
|
||||||
@ -545,7 +546,12 @@ ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
|
|||||||
c = sym->c;
|
c = sym->c;
|
||||||
}
|
}
|
||||||
/* now we can add ELF relocation info */
|
/* now we can add ELF relocation info */
|
||||||
put_elf_reloc(symtab_section, s, offset, type, c);
|
put_elf_reloca(symtab_section, s, offset, type, c, addend);
|
||||||
|
}
|
||||||
|
|
||||||
|
ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
|
||||||
|
{
|
||||||
|
greloca(s, sym, offset, type, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************************************/
|
/********************************************************/
|
||||||
|
2
tcc.h
2
tcc.h
@ -1074,6 +1074,7 @@ ST_FUNC Section *find_section(TCCState *s1, const char *name);
|
|||||||
ST_FUNC void put_extern_sym2(Sym *sym, Section *section, addr_t value, unsigned long size, int can_add_underscore);
|
ST_FUNC void put_extern_sym2(Sym *sym, Section *section, addr_t value, unsigned long size, int can_add_underscore);
|
||||||
ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size);
|
ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size);
|
||||||
ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);
|
ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);
|
||||||
|
ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, unsigned long addend);
|
||||||
|
|
||||||
ST_INLN void sym_free(Sym *sym);
|
ST_INLN void sym_free(Sym *sym);
|
||||||
ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c);
|
ST_FUNC Sym *sym_push2(Sym **ps, int v, int t, long c);
|
||||||
@ -1261,6 +1262,7 @@ ST_FUNC int put_elf_sym(Section *s, addr_t value, unsigned long size, int info,
|
|||||||
ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int sh_num, const char *name);
|
ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int sh_num, const char *name);
|
||||||
ST_FUNC int find_elf_sym(Section *s, const char *name);
|
ST_FUNC int find_elf_sym(Section *s, const char *name);
|
||||||
ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);
|
ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);
|
||||||
|
ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, int type, int symbol, unsigned long addend);
|
||||||
|
|
||||||
ST_FUNC void put_stabs(const char *str, int type, int other, int desc, unsigned long value);
|
ST_FUNC void put_stabs(const char *str, int type, int other, int desc, unsigned long value);
|
||||||
ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index);
|
ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index);
|
||||||
|
15
tccelf.c
15
tccelf.c
@ -269,8 +269,8 @@ ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* put relocation */
|
/* put relocation */
|
||||||
ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
|
ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
|
||||||
int type, int symbol)
|
int type, int symbol, unsigned long addend)
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
Section *sr;
|
Section *sr;
|
||||||
@ -292,10 +292,19 @@ ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
|
|||||||
rel->r_offset = offset;
|
rel->r_offset = offset;
|
||||||
rel->r_info = ELFW(R_INFO)(symbol, type);
|
rel->r_info = ELFW(R_INFO)(symbol, type);
|
||||||
#ifdef TCC_TARGET_X86_64
|
#ifdef TCC_TARGET_X86_64
|
||||||
rel->r_addend = 0;
|
rel->r_addend = addend;
|
||||||
|
#else
|
||||||
|
if (addend)
|
||||||
|
tcc_error("non-zero addend on REL architecture");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
|
||||||
|
int type, int symbol)
|
||||||
|
{
|
||||||
|
put_elf_reloca(symtab, s, offset, type, symbol, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* put stab debug information */
|
/* put stab debug information */
|
||||||
|
|
||||||
ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
|
ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
|
||||||
|
32
tccgen.c
32
tccgen.c
@ -5201,19 +5201,35 @@ static void init_putv(CType *type, Section *sec, unsigned long c,
|
|||||||
case VT_LLONG:
|
case VT_LLONG:
|
||||||
*(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
|
*(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
|
||||||
break;
|
break;
|
||||||
case VT_PTR:
|
case VT_PTR: {
|
||||||
if (vtop->r & VT_SYM) {
|
addr_t val = (vtop->c.ptr_offset & bit_mask) << bit_pos;
|
||||||
|
#ifdef TCC_TARGET_X86_64
|
||||||
|
if (vtop->r & VT_SYM)
|
||||||
|
greloca(sec, vtop->sym, c, R_DATA_PTR, val);
|
||||||
|
else
|
||||||
|
*(addr_t *)ptr |= val;
|
||||||
|
#else
|
||||||
|
if (vtop->r & VT_SYM)
|
||||||
greloc(sec, vtop->sym, c, R_DATA_PTR);
|
greloc(sec, vtop->sym, c, R_DATA_PTR);
|
||||||
}
|
*(addr_t *)ptr |= val;
|
||||||
*(addr_t *)ptr |= (vtop->c.ptr_offset & bit_mask) << bit_pos;
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
}
|
||||||
if (vtop->r & VT_SYM) {
|
default: {
|
||||||
|
int val = (vtop->c.i & bit_mask) << bit_pos;
|
||||||
|
#ifdef TCC_TARGET_X86_64
|
||||||
|
if (vtop->r & VT_SYM)
|
||||||
|
greloca(sec, vtop->sym, c, R_DATA_PTR, val);
|
||||||
|
else
|
||||||
|
*(int *)ptr |= val;
|
||||||
|
#else
|
||||||
|
if (vtop->r & VT_SYM)
|
||||||
greloc(sec, vtop->sym, c, R_DATA_PTR);
|
greloc(sec, vtop->sym, c, R_DATA_PTR);
|
||||||
}
|
*(int *)ptr |= val;
|
||||||
*(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
vtop--;
|
vtop--;
|
||||||
} else {
|
} else {
|
||||||
vset(&dtype, VT_LOCAL|VT_LVAL, c);
|
vset(&dtype, VT_LOCAL|VT_LVAL, c);
|
||||||
|
Loading…
Reference in New Issue
Block a user