diff options
author | Nick Clifton <nickc@redhat.com> | 1999-05-26 08:27:38 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 1999-05-26 08:27:38 +0000 |
commit | 780a67af1ecdbc56543f7029709609f49f010cac (patch) | |
tree | 002ac27df6c0c63ed3172222303b42e31a2d5ad7 | |
parent | 392a587b0562bfd8561bc15ad2625a4f49f461f0 (diff) | |
download | gdb-780a67af1ecdbc56543f7029709609f49f010cac.zip gdb-780a67af1ecdbc56543f7029709609f49f010cac.tar.gz gdb-780a67af1ecdbc56543f7029709609f49f010cac.tar.bz2 |
Applied patches from Philip Blundell <pb@nexus.co.uk>, to improve PIC support.
-rw-r--r-- | bfd/ChangeLog | 13 | ||||
-rw-r--r-- | bfd/elf32-arm.h | 75 |
2 files changed, 69 insertions, 19 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 48cea47..1613261 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,16 @@ +1999-05-25 Philip Blundell <pb@nexus.co.uk> + + * bfd/elf32-arm.h (elf32_arm_link_hash_newfunc): New function. + (elf32_arm_link_hash_table_create): Use above function as the + constructor for hash table entries. + (elf32_arm_relocate_section): Avoid crash when there is no output + section. + (elf32_arm_final_link_relocate): New parameter h. + (elf32_arm_relocate_section): Pass symbol hash entry to above + routine. + (elf32_arm_gc_sweep_hook, elf32_arm_check relocs): Correct + comments. + 1999-05-25 Catherine Moore <clm@cygnus.com> * coff-arm.c (coff_arm_relocate_section): Don't emit diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h index c73f1ae..120b387 100644 --- a/bfd/elf32-arm.h +++ b/bfd/elf32-arm.h @@ -34,7 +34,9 @@ static int elf32_arm_get_symbol_type static struct bfd_link_hash_table *elf32_arm_link_hash_table_create PARAMS ((bfd *)); static bfd_reloc_status_type elf32_arm_final_link_relocate - PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, bfd_vma, struct bfd_link_info *, asection *, const char *, unsigned char)); + PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *, + Elf_Internal_Rela *, bfd_vma, struct bfd_link_info *, asection *, + const char *, unsigned char, struct elf_link_hash_entry *)); static insn32 insert_thumb_branch PARAMS ((insn32, int)); @@ -157,6 +159,36 @@ struct elf32_arm_link_hash_table }; +/* Create an entry in an ARM ELF linker hash table. */ + +static struct bfd_hash_entry * +elf32_arm_link_hash_newfunc (entry, table, string) + struct bfd_hash_entry * entry; + struct bfd_hash_table * table; + const char * string; +{ + struct elf32_arm_link_hash_entry * ret = + (struct elf32_arm_link_hash_entry *) entry; + + /* Allocate the structure if it has not already been allocated by a + subclass. */ + if (ret == (struct elf32_arm_link_hash_entry *) NULL) + ret = ((struct elf32_arm_link_hash_entry *) + bfd_hash_allocate (table, + sizeof (struct elf32_arm_link_hash_entry))); + if (ret == (struct elf32_arm_link_hash_entry *) NULL) + return (struct bfd_hash_entry *) ret; + + /* Call the allocation method of the superclass. */ + ret = ((struct elf32_arm_link_hash_entry *) + _bfd_elf_link_hash_newfunc ((struct bfd_hash_entry *) ret, + table, string)); + if (ret != (struct elf32_arm_link_hash_entry *) NULL) + ret->pcrel_relocs_copied = NULL; + + return (struct bfd_hash_entry *) ret; +} + /* Create an ARM elf linker hash table */ static struct bfd_link_hash_table * @@ -171,7 +203,7 @@ elf32_arm_link_hash_table_create (abfd) return NULL; if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, - _bfd_elf_link_hash_newfunc)) + elf32_arm_link_hash_newfunc)) { bfd_release (abfd, ret); return NULL; @@ -943,7 +975,7 @@ elf32_arm_to_thumb_stub (info, name, input_bfd, output_bfd, input_section, static bfd_reloc_status_type elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, input_section, contents, rel, value, - info, sym_sec, sym_name, sym_flags) + info, sym_sec, sym_name, sym_flags, h) reloc_howto_type * howto; bfd * input_bfd; bfd * output_bfd; @@ -955,6 +987,7 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, asection * sym_sec; const char * sym_name; unsigned char sym_flags; + struct elf_link_hash_entry * h; { unsigned long r_type = howto->type; unsigned long r_symndx; @@ -966,7 +999,6 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, asection * sgot = NULL; asection * splt = NULL; asection * sreloc = NULL; - struct elf_link_hash_entry * h = NULL; bfd_vma addend; dynobj = elf_hash_table (info)->dynobj; @@ -1553,11 +1585,9 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section, if (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) { - sec = h->root.u.def.section; + int relocation_needed = 1; - relocation = (h->root.u.def.value - + sec->output_section->vma - + sec->output_offset); + sec = h->root.u.def.section; /* In these cases, we don't need the relocation value. We check specially because in some obscure cases @@ -1573,11 +1603,11 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section, ) && ((input_section->flags & SEC_ALLOC) != 0) ) - relocation = 0; + relocation_needed = 0; break; case R_ARM_GOTPC: - relocation = 0; + relocation_needed = 0; break; case R_ARM_GOT32: @@ -1587,12 +1617,12 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section, || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 ) ) - relocation = 0; + relocation_needed = 0; break; case R_ARM_PLT32: if (h->plt.offset != (bfd_vma)-1) - relocation = 0; + relocation_needed = 0; break; default: @@ -1602,9 +1632,16 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section, (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"), bfd_get_filename (input_bfd), h->root.root.string, bfd_get_section_name (input_bfd, input_section)); - relocation = 0; + relocation_needed = 0; } } + + if (relocation_needed) + relocation = h->root.u.def.value + + sec->output_section->vma + + sec->output_offset; + else + relocation = 0; } else if (h->root.type == bfd_link_hash_undefweak) relocation = 0; @@ -1632,7 +1669,7 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section, input_section, contents, rel, relocation, info, sec, name, (h ? ELF_ST_TYPE (h->type) : - ELF_ST_TYPE (sym->st_info))); + ELF_ST_TYPE (sym->st_info)), h); if (r != bfd_reloc_ok) { @@ -1957,6 +1994,8 @@ elf32_arm_gc_mark_hook (abfd, info, rel, h, sym) return NULL; } +/* Update the got entry reference counts for the section being removed. */ + static boolean elf32_arm_gc_sweep_hook (abfd, info, sec, relocs) bfd *abfd; @@ -1964,14 +2003,12 @@ elf32_arm_gc_sweep_hook (abfd, info, sec, relocs) asection *sec; const Elf_Internal_Rela *relocs; { - /* we don't use got and plt entries for armelf */ + /* We don't support garbage collection of GOT and PLT relocs yet. */ return true; } -/* Look through the relocs for a section during the first phase. - Since we don't do .gots or .plts, we just need to consider the - virtual table relocs for gc. */ - +/* Look through the relocs for a section during the first phase. */ + static boolean elf32_arm_check_relocs (abfd, info, sec, relocs) bfd * abfd; |