diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2013-01-16 21:34:46 +0000 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2013-01-16 21:34:46 +0000 |
commit | 1788fc08f7a091f246a41cd14d2b612d4253e55b (patch) | |
tree | a37e3ac15f14e718ac1248bc5eb66a5ade07d527 /bfd/elf32-i386.c | |
parent | e1ec603fec5191034dd56f4e417c89054b5f61b9 (diff) | |
download | gdb-1788fc08f7a091f246a41cd14d2b612d4253e55b.zip gdb-1788fc08f7a091f246a41cd14d2b612d4253e55b.tar.gz gdb-1788fc08f7a091f246a41cd14d2b612d4253e55b.tar.bz2 |
Add x86 size relocation support to bfd
* bfd-in2.h: Regenerated.
* libbfd.h: Likewise.
* elf32-i386.c (elf_howto_table): Fill R_386_SIZE32 entry.
(elf_i386_reloc_type_lookup): Support BFD_RELOC_SIZE32.
(elf_i386_check_relocs): Handle R_386_SIZE32.
(elf_i386_gc_sweep_hook): Likewise.
(elf_i386_relocate_section): Likewise.
* elf64-x86-64.c (x86_64_elf_howto_table): Fill R_X86_64_SIZE32
and R_X86_64_SIZE64 entries.
(x86_64_reloc_map): Add BFD_RELOC_SIZE32 and BFD_RELOC_SIZE64,
(elf_x86_64_rtype_to_howto): Handle R_X86_64_SIZE32 for x32.
(elf_x86_64_reloc_name_lookup): Likewise.
(elf_x86_64_check_relocs): Handle R_X86_64_SIZE32 and
R_X86_64_SIZE64.
(elf_x86_64_gc_sweep_hook): Likewise.
(elf_x86_64_relocate_section): Likewise.
* reloc.c (bfd_reloc_code_type): Add BFD_RELOC_SIZE32 and
BFD_RELOC_SIZE64.
Diffstat (limited to 'bfd/elf32-i386.c')
-rw-r--r-- | bfd/elf32-i386.c | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 99e8f45..368c8d5 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -133,7 +133,9 @@ static reloc_howto_type elf_howto_table[]= HOWTO(R_386_TLS_TPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_386_TLS_TPOFF32", TRUE, 0xffffffff, 0xffffffff, FALSE), - EMPTY_HOWTO (38), + HOWTO(R_386_SIZE32, 0, 2, 32, FALSE, 0, complain_overflow_unsigned, + bfd_elf_generic_reloc, "R_386_SIZE32", + TRUE, 0xffffffff, 0xffffffff, FALSE), HOWTO(R_386_TLS_GOTDESC, 0, 2, 32, FALSE, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_386_TLS_GOTDESC", TRUE, 0xffffffff, 0xffffffff, FALSE), @@ -312,6 +314,10 @@ elf_i386_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, TRACE ("BFD_RELOC_386_TLS_TPOFF32"); return &elf_howto_table[R_386_TLS_TPOFF32 - R_386_tls_offset]; + case BFD_RELOC_SIZE32: + TRACE ("BFD_RELOC_SIZE32"); + return &elf_howto_table[R_386_SIZE32 - R_386_tls_offset]; + case BFD_RELOC_386_TLS_GOTDESC: TRACE ("BFD_RELOC_386_TLS_GOTDESC"); return &elf_howto_table[R_386_TLS_GOTDESC - R_386_tls_offset]; @@ -1680,6 +1686,7 @@ elf_i386_check_relocs (bfd *abfd, case R_386_32: case R_386_PC32: + case R_386_SIZE32: if (h != NULL && info->executable) { /* If this reloc is in a read-only section, we might @@ -1959,6 +1966,7 @@ elf_i386_gc_sweep_hook (bfd *abfd, case R_386_32: case R_386_PC32: + case R_386_SIZE32: if (info->shared && (h == NULL || h->type != STT_GNU_IFUNC)) break; @@ -3185,6 +3193,7 @@ elf_i386_relocate_section (bfd *output_bfd, bfd_reloc_status_type r; unsigned int indx; int tls_type; + bfd_vma st_size; r_type = ELF32_R_TYPE (rel->r_info); if (r_type == R_386_GNU_VTINHERIT @@ -3217,6 +3226,7 @@ elf_i386_relocate_section (bfd *output_bfd, relocation = (sec->output_section->vma + sec->output_offset + sym->st_value); + st_size = sym->st_size; if (ELF_ST_TYPE (sym->st_info) == STT_SECTION && ((sec->flags & SEC_MERGE) != 0 @@ -3309,6 +3319,7 @@ elf_i386_relocate_section (bfd *output_bfd, r_symndx, symtab_hdr, sym_hashes, h, sec, relocation, unresolved_reloc, warned); + st_size = h->size; } if (sec != NULL && discarded_section (sec)) @@ -3670,6 +3681,25 @@ elf_i386_relocate_section (bfd *output_bfd, unresolved_reloc = FALSE; break; + case R_386_SIZE32: + if (h + && h->type == STT_TLS + && (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + && h->root.u.def.section->output_section != NULL + && htab->elf.tls_sec == NULL) + { + (*_bfd_error_handler) + (_("%B: `%s' accessed both as normal and thread local symbol"), + input_bfd, h->root.root.string); + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + + /* Set to symbol size. */ + relocation = st_size; + /* Fall through. */ + case R_386_32: case R_386_PC32: if ((input_section->flags & SEC_ALLOC) == 0 @@ -3680,7 +3710,7 @@ elf_i386_relocate_section (bfd *output_bfd, && (h == NULL || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT || h->root.type != bfd_link_hash_undefweak) - && (r_type != R_386_PC32 + && ((r_type != R_386_PC32 && r_type != R_386_SIZE32) || !SYMBOL_CALLS_LOCAL (info, h))) || (ELIMINATE_COPY_RELOCS && !info->shared |