History

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.

Edmund Grimley Evans committed 11 years ago

Commit 738606d1 parent 86c850f4 files · +46 −13Browse files

Unified · Split

4 files
  1. libtcc.c +8 −2
  2. tcc.h +2 −0
  3. tccelf.c +12 −3
  4. tccgen.c +24 −8
libtcc.c+8−2
@@ -536,7 +536,8 @@ ST_FUNC void put_extern_sym(Sym *sym, Section *section, · 535 unmodified lines
536536 }
537537
538538 /* add a new relocation entry to symbol 'sym' in section 's' */
539−ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
539+ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type,
540+ unsigned long addend)
540541 {
541542 int c = 0;
542543 if (sym) {
@@ -545,7 +546,12 @@ ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type) · 2 unmodified lines
545546 c = sym->c;
546547 }
547548 /* now we can add ELF relocation info */
548− put_elf_reloc(symtab_section, s, offset, type, c);
549+ put_elf_reloca(symtab_section, s, offset, type, c, addend);
550+}
551+
552+ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type)
553+{
554+ greloca(s, sym, offset, type, 0);
549555 }
550556
551557 /********************************************************/
tcc.h+2−0
@@ -1074,6 +1074,7 @@ ST_FUNC Section *find_section(TCCState *s1, const char *name); · 1073 unmodified lines
10741074 ST_FUNC void put_extern_sym2(Sym *sym, Section *section, addr_t value, unsigned long size, int can_add_underscore);
10751075 ST_FUNC void put_extern_sym(Sym *sym, Section *section, addr_t value, unsigned long size);
10761076 ST_FUNC void greloc(Section *s, Sym *sym, unsigned long offset, int type);
1077+ST_FUNC void greloca(Section *s, Sym *sym, unsigned long offset, int type, unsigned long addend);
10771078
10781079 ST_INLN void sym_free(Sym *sym);
10791080 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, · 181 unmodified lines
12611262 ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size, int info, int other, int sh_num, const char *name);
12621263 ST_FUNC int find_elf_sym(Section *s, const char *name);
12631264 ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, int type, int symbol);
1265+ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset, int type, int symbol, unsigned long addend);
12641266
12651267 ST_FUNC void put_stabs(const char *str, int type, int other, int desc, unsigned long value);
12661268 ST_FUNC void put_stabs_r(const char *str, int type, int other, int desc, unsigned long value, Section *sec, int sym_index);
tccelf.c+12−3
@@ -269,8 +269,8 @@ ST_FUNC int add_elf_sym(Section *s, addr_t value, unsigned long size, · 268 unmodified lines
269269 }
270270
271271 /* put relocation */
272−ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
273− int type, int symbol)
272+ST_FUNC void put_elf_reloca(Section *symtab, Section *s, unsigned long offset,
273+ int type, int symbol, unsigned long addend)
274274 {
275275 char buf[256];
276276 Section *sr;
@@ -292,10 +292,19 @@ ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset, · 15 unmodified lines
292292 rel->r_offset = offset;
293293 rel->r_info = ELFW(R_INFO)(symbol, type);
294294 #ifdef TCC_TARGET_X86_64
295− rel->r_addend = 0;
295+ rel->r_addend = addend;
296+#else
297+ if (addend)
298+ tcc_error("non-zero addend on REL architecture");
296299 #endif
297300 }
298301
302+ST_FUNC void put_elf_reloc(Section *symtab, Section *s, unsigned long offset,
303+ int type, int symbol)
304+{
305+ put_elf_reloca(symtab, s, offset, type, symbol, 0);
306+}
307+
299308 /* put stab debug information */
300309
301310 ST_FUNC void put_stabs(const char *str, int type, int other, int desc,
tccgen.c+24−8
@@ -5201,19 +5201,35 @@ static void init_putv(CType *type, Section *sec, unsigned long c, · 5200 unmodified lines
52015201 case VT_LLONG:
52025202 *(long long *)ptr |= (vtop->c.ll & bit_mask) << bit_pos;
52035203 break;
5204− case VT_PTR:
5205− if (vtop->r & VT_SYM) {
5204+ case VT_PTR: {
5205+ addr_t val = (vtop->c.ptr_offset & bit_mask) << bit_pos;
5206+#ifdef TCC_TARGET_X86_64
5207+ if (vtop->r & VT_SYM)
5208+ greloca(sec, vtop->sym, c, R_DATA_PTR, val);
5209+ else
5210+ *(addr_t *)ptr |= val;
5211+#else
5212+ if (vtop->r & VT_SYM)
52065213 greloc(sec, vtop->sym, c, R_DATA_PTR);
5207− }
5208− *(addr_t *)ptr |= (vtop->c.ptr_offset & bit_mask) << bit_pos;
5214+ *(addr_t *)ptr |= val;
5215+#endif
52095216 break;
5210− default:
5211− if (vtop->r & VT_SYM) {
5217+ }
5218+ default: {
5219+ int val = (vtop->c.i & bit_mask) << bit_pos;
5220+#ifdef TCC_TARGET_X86_64
5221+ if (vtop->r & VT_SYM)
5222+ greloca(sec, vtop->sym, c, R_DATA_PTR, val);
5223+ else
5224+ *(int *)ptr |= val;
5225+#else
5226+ if (vtop->r & VT_SYM)
52125227 greloc(sec, vtop->sym, c, R_DATA_PTR);
5213− }
5214− *(int *)ptr |= (vtop->c.i & bit_mask) << bit_pos;
5228+ *(int *)ptr |= val;
5229+#endif
52155230 break;
52165231 }
5232+ }
52175233 vtop--;
52185234 } else {
52195235 vset(&dtype, VT_LOCAL|VT_LVAL, c);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t