Index: third_party/yasm/patched-yasm/modules/objfmts/elf/elf-objfmt.c |
=================================================================== |
--- third_party/yasm/patched-yasm/modules/objfmts/elf/elf-objfmt.c (revision 71129) |
+++ third_party/yasm/patched-yasm/modules/objfmts/elf/elf-objfmt.c (working copy) |
@@ -25,7 +25,7 @@ |
* POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <util.h> |
-/*@unused@*/ RCSID("$Id: elf-objfmt.c 2166 2009-01-02 08:33:21Z peter $"); |
+/*@unused@*/ RCSID("$Id: elf-objfmt.c 2310 2010-03-28 19:28:54Z peter $"); |
/* Notes |
* |
@@ -68,6 +68,7 @@ |
yasm_section *sect; |
yasm_object *object; |
unsigned long sindex; |
+ yasm_symrec *GOT_sym; |
} elf_objfmt_output_info; |
typedef struct { |
@@ -454,7 +455,7 @@ |
int retval; |
reloc = elf_reloc_entry_create(sym, NULL, |
- yasm_intnum_create_uint(bc->offset), 0, valsize); |
+ yasm_intnum_create_uint(bc->offset), 0, valsize, 0); |
if (reloc == NULL) { |
yasm_error_set(YASM_ERROR_TYPE, N_("elf: invalid relocation size")); |
return 1; |
@@ -463,7 +464,7 @@ |
elf_secthead_append_reloc(info->sect, info->shead, reloc); |
zero = yasm_intnum_create_uint(0); |
- elf_handle_reloc_addend(zero, reloc); |
+ elf_handle_reloc_addend(zero, reloc, 0); |
retval = yasm_arch_intnum_tobytes(info->object->arch, zero, buf, destsize, |
valsize, 0, bc, warn); |
yasm_intnum_destroy(zero); |
@@ -546,9 +547,10 @@ |
if (value->curpos_rel) |
intn_val += offset; |
+ /* Check for _GLOBAL_OFFSET_TABLE_ symbol reference */ |
reloc = elf_reloc_entry_create(sym, wrt, |
yasm_intnum_create_uint(bc->offset + offset), value->curpos_rel, |
- valsize); |
+ valsize, sym == info->GOT_sym); |
if (reloc == NULL) { |
yasm_error_set(YASM_ERROR_TYPE, |
N_("elf: invalid relocation (WRT or size)")); |
@@ -572,7 +574,7 @@ |
} |
if (reloc) |
- elf_handle_reloc_addend(intn, reloc); |
+ elf_handle_reloc_addend(intn, reloc, offset); |
retval = yasm_arch_intnum_tobytes(info->object->arch, intn, buf, destsize, |
valsize, 0, bc, warn); |
yasm_intnum_destroy(intn); |
@@ -632,45 +634,6 @@ |
} |
static int |
-elf_objfmt_create_dbg_secthead(yasm_section *sect, /*@null@*/ void *d) |
-{ |
- /*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d; |
- elf_secthead *shead; |
- elf_section_type type=SHT_PROGBITS; |
- elf_size entsize=0; |
- const char *sectname; |
- /*@dependent@*/ yasm_symrec *sym; |
- elf_strtab_entry *name; |
- |
- shead = yasm_section_get_data(sect, &elf_section_data); |
- if (shead) |
- return 0; /* only create new secthead if missing */ |
- |
- sectname = yasm_section_get_name(sect); |
- name = elf_strtab_append_str(info->objfmt_elf->shstrtab, sectname); |
- |
- if (yasm__strcasecmp(sectname, ".stab")==0) { |
- entsize = 12; |
- } else if (yasm__strcasecmp(sectname, ".stabstr")==0) { |
- type = SHT_STRTAB; |
- } else if (yasm__strncasecmp(sectname, ".debug_", 7)==0) { |
- ; |
- } else |
- yasm_internal_error(N_("Unrecognized section without data")); |
- |
- shead = elf_secthead_create(name, type, 0, 0, 0); |
- elf_secthead_set_entsize(shead, entsize); |
- |
- sym = yasm_symtab_define_label(info->object->symtab, sectname, |
- yasm_section_bcs_first(sect), 1, 0); |
- elf_secthead_set_sym(shead, sym); |
- |
- yasm_section_add_data(sect, &elf_section_data, shead); |
- |
- return 0; |
-} |
- |
-static int |
elf_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d) |
{ |
/*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d; |
@@ -780,6 +743,7 @@ |
info.objfmt_elf = objfmt_elf; |
info.errwarns = errwarns; |
info.f = f; |
+ info.GOT_sym = yasm_symtab_get(object->symtab, "_GLOBAL_OFFSET_TABLE_"); |
/* Update filename strtab */ |
elf_strtab_entry_set_str(objfmt_elf->file_strtab_entry, |
@@ -792,11 +756,6 @@ |
return; |
} |
- /* Create missing section headers */ |
- if (yasm_object_sections_traverse(object, &info, |
- elf_objfmt_create_dbg_secthead)) |
- return; |
- |
/* add all (local) syms to symtab because relocation needs a symtab index |
* if all_syms, register them by name. if not, use strtab entry 0 */ |
buildsym_info.object = object; |
@@ -922,25 +881,33 @@ |
yasm_xfree(objfmt); |
} |
-static elf_secthead * |
-elf_objfmt_init_new_section(yasm_object *object, yasm_section *sect, |
- const char *sectname, unsigned long type, |
- unsigned long flags, unsigned long line) |
+static void |
+elf_objfmt_init_new_section(yasm_section *sect, unsigned long line) |
{ |
+ yasm_object *object = yasm_section_get_object(sect); |
+ const char *sectname = yasm_section_get_name(sect); |
yasm_objfmt_elf *objfmt_elf = (yasm_objfmt_elf *)object->objfmt; |
elf_secthead *esd; |
yasm_symrec *sym; |
elf_strtab_entry *name = elf_strtab_append_str(objfmt_elf->shstrtab, |
sectname); |
- esd = elf_secthead_create(name, type, flags, 0, 0); |
+ elf_section_type type=SHT_PROGBITS; |
+ elf_size entsize=0; |
+ |
+ if (yasm__strcasecmp(sectname, ".stab")==0) { |
+ entsize = 12; |
+ } else if (yasm__strcasecmp(sectname, ".stabstr")==0) { |
+ type = SHT_STRTAB; |
+ } |
+ |
+ esd = elf_secthead_create(name, type, 0, 0, 0); |
+ elf_secthead_set_entsize(esd, entsize); |
yasm_section_add_data(sect, &elf_section_data, esd); |
sym = yasm_symtab_define_label(object->symtab, sectname, |
yasm_section_bcs_first(sect), 1, line); |
elf_secthead_set_sym(esd, sym); |
- |
- return esd; |
} |
static yasm_section * |
@@ -948,12 +915,15 @@ |
{ |
yasm_section *retval; |
int isnew; |
- elf_secthead *esd; |
retval = yasm_object_get_general(object, ".text", 16, 1, 0, &isnew, 0); |
- esd = elf_objfmt_init_new_section(object, retval, ".text", SHT_PROGBITS, |
- SHF_ALLOC + SHF_EXECINSTR, 0); |
- yasm_section_set_default(retval, 1); |
+ if (isnew) |
+ { |
+ elf_secthead *esd = yasm_section_get_data(retval, &elf_section_data); |
+ elf_secthead_set_typeflags(esd, SHT_PROGBITS, |
+ SHF_ALLOC + SHF_EXECINSTR); |
+ yasm_section_set_default(retval, 1); |
+ } |
return retval; |
} |
@@ -1142,11 +1112,7 @@ |
(data.flags & SHF_EXECINSTR) != 0, |
resonly, &isnew, line); |
- if (isnew) |
- esd = elf_objfmt_init_new_section(object, retval, sectname, data.type, |
- data.flags, line); |
- else |
- esd = yasm_section_get_data(retval, &elf_section_data); |
+ esd = yasm_section_get_data(retval, &elf_section_data); |
if (isnew || yasm_section_is_default(retval)) { |
yasm_section_set_default(retval, 0); |
@@ -1356,6 +1322,7 @@ |
elf_objfmt_output, |
elf_objfmt_destroy, |
elf_objfmt_add_default_section, |
+ elf_objfmt_init_new_section, |
elf_objfmt_section_switch, |
elf_objfmt_get_special_sym |
}; |
@@ -1374,6 +1341,7 @@ |
elf_objfmt_output, |
elf_objfmt_destroy, |
elf_objfmt_add_default_section, |
+ elf_objfmt_init_new_section, |
elf_objfmt_section_switch, |
elf_objfmt_get_special_sym |
}; |
@@ -1392,6 +1360,7 @@ |
elf_objfmt_output, |
elf_objfmt_destroy, |
elf_objfmt_add_default_section, |
+ elf_objfmt_init_new_section, |
elf_objfmt_section_switch, |
elf_objfmt_get_special_sym |
}; |