X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felf32-hppa.c;h=784c699971b79d8774526b6f4787e7d7b731fb74;hb=bc6b39f5f5186513c2ed28da36c14746b145d26d;hp=d66679f5e95b3e66976d1e31db774e99b140c4ae;hpb=9a6880571c8a7f48a01b0502574712e75864dd49;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index d66679f5e9..784c699971 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -1,5 +1,6 @@ /* BFD back-end for HP PA-RISC ELF files. - Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc. + Copyright (C) 1990, 91, 92, 93, 94, 95, 96, 1997 + Free Software Foundation, Inc. Written by @@ -21,14 +22,14 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "bfd.h" #include "sysdep.h" #include "bfdlink.h" #include "libbfd.h" #include "obstack.h" -#include "libelf.h" +#include "elf-bfd.h" /* The internal type of a symbol table extension entry. */ typedef unsigned long symext_entryS; @@ -215,11 +216,11 @@ static reloc_howto_type * elf_hppa_reloc_type_lookup static boolean elf32_hppa_set_section_contents PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type)); -static void elf_info_to_howto +static void elf32_hppa_info_to_howto PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *)); static boolean elf32_hppa_backend_symbol_table_processing - PARAMS ((bfd *, elf_symbol_type *, int)); + PARAMS ((bfd *, elf_symbol_type *, unsigned int)); static void elf32_hppa_backend_begin_write_processing PARAMS ((bfd *, struct bfd_link_info *)); @@ -234,7 +235,7 @@ static void add_entry_to_symext_chain static void elf_hppa_tc_make_sections PARAMS ((bfd *, symext_chainS *)); -static boolean hppa_elf_is_local_label PARAMS ((bfd *, asymbol *)); +static boolean hppa_elf_is_local_label_name PARAMS ((bfd *, const char *)); static boolean elf32_hppa_add_symbol_hook PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, @@ -296,7 +297,9 @@ static boolean elf32_hppa_link_output_symbol_hook static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] = { {R_PARISC_NONE, 0, 0, 0, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_NONE"}, - {R_PARISC_DIR32, 0, 0, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR32"}, + /* The values in DIR32 are to placate the check in + _bfd_stab_section_find_nearest_line. */ + {R_PARISC_DIR32, 0, 2, 32, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR32", false, 0, 0xffffffff, false}, {R_PARISC_DIR21L, 0, 0, 21, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR21L"}, {R_PARISC_DIR17R, 0, 0, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR17R"}, {R_PARISC_DIR17F, 0, 0, 17, false, 0, complain_overflow_bitfield, hppa_elf_reloc, "R_PARISC_DIR17F"}, @@ -575,10 +578,7 @@ elf32_hppa_stub_hash_newfunc (entry, table, string) bfd_hash_allocate (table, sizeof (struct elf32_hppa_stub_hash_entry))); if (ret == NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } + return NULL; /* Call the allocation method of the superclass. */ ret = ((struct elf32_hppa_stub_hash_entry *) @@ -630,10 +630,7 @@ elf32_hppa_args_hash_newfunc (entry, table, string) bfd_hash_allocate (table, sizeof (struct elf32_hppa_args_hash_entry))); if (ret == NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } + return NULL; /* Call the allocation method of the superclass. */ ret = ((struct elf32_hppa_args_hash_entry *) @@ -659,10 +656,7 @@ elf32_hppa_link_hash_table_create (abfd) ret = ((struct elf32_hppa_link_hash_table *) bfd_alloc (abfd, sizeof (struct elf32_hppa_link_hash_table))); if (ret == NULL) - { - bfd_set_error (bfd_error_no_memory); - return NULL; - } + return NULL; if (!_bfd_elf_link_hash_table_init (&ret->root, abfd, _bfd_elf_link_hash_newfunc)) { @@ -785,7 +779,7 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section, { int r_type; reloc_howto_type *howto; - long r_symndx; + unsigned long r_symndx; struct elf_link_hash_entry *h; Elf_Internal_Sym *sym; asection *sym_sec; @@ -841,6 +835,9 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section, indx = r_symndx - symtab_hdr->sh_info; h = elf_sym_hashes (input_bfd)[indx]; + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; if (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) { @@ -857,7 +854,7 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section, (info, h->root.root.string, input_bfd, input_section, rel->r_offset))) return false; - relocation = 0; + break; } } @@ -865,9 +862,9 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section, sym_name = h->root.root.string; else { - sym_name = elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); + sym_name = bfd_elf_string_from_elf_section (input_bfd, + symtab_hdr->sh_link, + sym->st_name); if (sym_name == NULL) return false; if (*sym_name == '\0') @@ -945,24 +942,26 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section, relocation with modifications based on format and field. */ elf32_hppa_reloc_type ** -hppa_elf_gen_reloc_type (abfd, base_type, format, field) +hppa_elf_gen_reloc_type (abfd, base_type, format, field, ignore, sym) bfd *abfd; elf32_hppa_reloc_type base_type; int format; int field; + int ignore; + asymbol *sym; { elf32_hppa_reloc_type *finaltype; elf32_hppa_reloc_type **final_types; /* Allocate slots for the BFD relocation. */ - final_types = (elf32_hppa_reloc_type **) - bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type *) * 2); + final_types = ((elf32_hppa_reloc_type **) + bfd_alloc (abfd, sizeof (elf32_hppa_reloc_type *) * 2)); if (final_types == NULL) return NULL; /* Allocate space for the relocation itself. */ - finaltype = (elf32_hppa_reloc_type *) - bfd_alloc_by_size_t (abfd, sizeof (elf32_hppa_reloc_type)); + finaltype = ((elf32_hppa_reloc_type *) + bfd_alloc (abfd, sizeof (elf32_hppa_reloc_type))); if (finaltype == NULL) return NULL; @@ -1167,14 +1166,14 @@ elf32_hppa_set_section_contents (abfd, section, location, offset, count) if (!strcmp (section->name, ".PARISC.symextn") && !symext_chain_size) return true; else - return bfd_elf32_set_section_contents (abfd, section, location, - offset, count); + return _bfd_elf_set_section_contents (abfd, section, location, + offset, count); } /* Translate from an elf into field into a howto relocation pointer. */ static void -elf_info_to_howto (abfd, cache_ptr, dst) +elf32_hppa_info_to_howto (abfd, cache_ptr, dst) bfd *abfd; arelent *cache_ptr; Elf32_Internal_Rela *dst; @@ -1300,12 +1299,12 @@ elf32_hppa_bfd_final_link_relocate (howto, input_bfd, output_bfd, section. If it's a code section, then "data pointer relative" makes no sense. In that case we don't adjust the "value", and for 21 bit addil instructions, we change the source addend register from %dp to - %r0. + %r0. */ case R_PARISC_DPREL21L: r_field = e_lrsel; if (sym_sec->flags & SEC_CODE) { - if ((insn & 0xfc) >> 26 == 0xa + if ((insn & 0xfc000000) >> 26 == 0xa && (insn & 0x03e00000) >> 21 == 0x1b) insn &= ~0x03e00000; } @@ -1356,12 +1355,9 @@ elf32_hppa_bfd_final_link_relocate (howto, input_bfd, output_bfd, len = strlen (sym_name) + 1; if (is_local) len += 9; - new_name = malloc (len); + new_name = bfd_malloc (len); if (!new_name) - { - bfd_set_error (bfd_error_no_memory); - return bfd_reloc_notsupported; - } + return bfd_reloc_notsupported; strcpy (new_name, sym_name); /* Local symbols have unique IDs. */ @@ -1403,12 +1399,9 @@ elf32_hppa_bfd_final_link_relocate (howto, input_bfd, output_bfd, len = strlen (new_name); len += 23; - stub_name = malloc (len); + stub_name = bfd_malloc (len); if (!stub_name) - { - bfd_set_error (bfd_error_no_memory); - return bfd_reloc_notsupported; - } + return bfd_reloc_notsupported; elf32_hppa_name_of_stub (caller_args, callee_args, location, value, stub_name); strcat (stub_name, new_name); @@ -1561,11 +1554,11 @@ elf_hppa_reloc_type_lookup (abfd, code) /* Return true if SYM represents a local label symbol. */ static boolean -hppa_elf_is_local_label (abfd, sym) +hppa_elf_is_local_label_name (abfd, name) bfd *abfd; - asymbol *sym; + const char *name; { - return (sym->name[0] == 'L' && sym->name[1] == '$'); + return (name[0] == 'L' && name[1] == '$'); } /* Do any backend specific processing when beginning to write an object @@ -1687,12 +1680,9 @@ elf32_hppa_link_output_symbol_hook (abfd, info, name, sym, section) if (ELF_ST_BIND (sym->st_info) == STB_LOCAL) len += 9; - new_name = malloc (len); + new_name = bfd_malloc (len); if (new_name == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } + return false; strcpy (new_name, name); if (ELF_ST_BIND (sym->st_info) == STB_LOCAL) @@ -1786,10 +1776,7 @@ add_entry_to_symext_chain (abfd, arg_reloc, sym_idx, symext_root, symext_last) /* Allocate memory and initialize this entry. */ symextP = (symext_chainS *) bfd_alloc (abfd, sizeof (symext_chainS) * 2); if (!symextP) - { - bfd_set_error (bfd_error_no_memory); - abort(); /* FIXME */ - } + abort(); /* FIXME */ symextP[0].entry = ELF32_PARISC_SX_WORD (PARISC_SXT_SYMNDX, sym_idx); symextP[0].next = &symextP[1]; @@ -1829,10 +1816,7 @@ elf_hppa_tc_make_sections (abfd, symext_root) symextn_contents = (bfd_byte *) bfd_zalloc (abfd, symextn_sec->_raw_size); if (!symextn_contents) - { - bfd_set_error (bfd_error_no_memory); - abort(); /* FIXME */ - } + abort(); /* FIXME */ /* Fill in the contents of the symbol extension chain. */ for (i = 0, symextP = symext_root; symextP; symextP = symextP->next, ++i) @@ -1850,7 +1834,7 @@ static boolean elf32_hppa_backend_symbol_table_processing (abfd, esyms,symcnt) bfd *abfd; elf_symbol_type *esyms; - int symcnt; + unsigned int symcnt; { Elf32_Internal_Shdr *symextn_hdr = bfd_elf_find_section (abfd, SYMEXTN_SECTION_NAME); @@ -1870,10 +1854,7 @@ elf32_hppa_backend_symbol_table_processing (abfd, esyms,symcnt) /* Allocate a buffer of the appropriate size for the symextn section. */ symextn_hdr->contents = bfd_zalloc(abfd,symextn_hdr->sh_size); if (!symextn_hdr->contents) - { - bfd_set_error (bfd_error_no_memory); - return false; - } + return false; /* Read in the symextn section. */ if (bfd_seek (abfd, symextn_hdr->sh_offset, SEEK_SET) == -1) @@ -1888,7 +1869,7 @@ elf32_hppa_backend_symbol_table_processing (abfd, esyms,symcnt) { symext_entryS se = ELF32_PARISC_SX_GET (abfd, - (symextn_hdr->contents + ((unsigned char *)symextn_hdr->contents + i * ELF32_PARISC_SX_SIZE)); unsigned int se_value = ELF32_PARISC_SX_VAL (se); unsigned int se_type = ELF32_PARISC_SX_TYPE (se); @@ -1948,12 +1929,9 @@ elf32_hppa_read_symext_info (input_bfd, symtab_hdr, args_hash_table, local_syms) return true; } - contents = (bfd_byte *) malloc (symextn_sec->_raw_size); + contents = (bfd_byte *) bfd_malloc ((size_t) symextn_sec->_raw_size); if (contents == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } + return false; /* How gross. We turn off SEC_HAS_CONTENTS for the input symbol extension sections to keep the generic ELF/BFD code from trying to do anything @@ -2007,14 +1985,13 @@ elf32_hppa_read_symext_info (input_bfd, symtab_hdr, args_hash_table, local_syms) hdr = elf_elfsections (input_bfd)[local_syms[current_index].st_shndx]; sym_sec = hdr->bfd_section; - sym_name = elf_string_from_elf_section (input_bfd, + sym_name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, local_syms[current_index].st_name); len = strlen (sym_name) + 10; - new_name = malloc (len); + new_name = bfd_malloc (len); if (new_name == NULL) { - bfd_set_error (bfd_error_no_memory); free (contents); return false; } @@ -2502,10 +2479,7 @@ elf32_hppa_build_stubs (stub_bfd, info) size = bfd_section_size (stub_bfd, stub_sec); stub_sec->contents = (unsigned char *) bfd_zalloc (stub_bfd, size); if (stub_sec->contents == NULL) - { - bfd_set_error (bfd_error_no_memory); - return false; - } + return false; table = elf32_hppa_hash_table(info)->stub_hash_table; table->location = stub_sec->contents; @@ -2529,7 +2503,7 @@ elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info) struct bfd_link_info *link_info; { bfd *input_bfd; - asection *section, *stub_sec; + asection *section, *stub_sec = 0; Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Sym *local_syms, *isym, **all_local_syms; Elf32_External_Sym *ext_syms, *esym; @@ -2539,12 +2513,9 @@ elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info) /* Create and initialize the stub hash table. */ stub_hash_table = ((struct elf32_hppa_stub_hash_table *) - malloc (sizeof (struct elf32_hppa_stub_hash_table))); + bfd_malloc (sizeof (struct elf32_hppa_stub_hash_table))); if (!stub_hash_table) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } + goto error_return; if (!elf32_hppa_stub_hash_table_init (stub_hash_table, stub_bfd, elf32_hppa_stub_hash_newfunc)) @@ -2552,12 +2523,9 @@ elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info) /* Likewise for the argument location hash table. */ args_hash_table = ((struct elf32_hppa_args_hash_table *) - malloc (sizeof (struct elf32_hppa_args_hash_table))); + bfd_malloc (sizeof (struct elf32_hppa_args_hash_table))); if (!args_hash_table) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } + goto error_return; if (!elf32_hppa_args_hash_table_init (args_hash_table, elf32_hppa_args_hash_newfunc)) @@ -2577,12 +2545,10 @@ elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info) we need to read in the local symbols in parallel and save them for later use; so hold pointers to the local symbols in an array. */ all_local_syms - = (Elf_Internal_Sym **) malloc (sizeof (Elf_Internal_Sym *) * bfd_count); + = (Elf_Internal_Sym **) bfd_malloc (sizeof (Elf_Internal_Sym *) + * bfd_count); if (all_local_syms == NULL) - { - bfd_set_error (bfd_error_no_memory); - goto error_return; - } + goto error_return; memset (all_local_syms, 0, sizeof (Elf_Internal_Sym *) * bfd_count); /* Walk over all the input BFDs adding entries to the args hash table @@ -2599,11 +2565,10 @@ elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info) /* We need an array of the local symbols attached to the input bfd. Unfortunately, we're going to have to read & swap them in. */ local_syms - = (Elf_Internal_Sym *)malloc (symtab_hdr->sh_info - * sizeof (Elf_Internal_Sym)); + = (Elf_Internal_Sym *) bfd_malloc (symtab_hdr->sh_info + * sizeof (Elf_Internal_Sym)); if (local_syms == NULL) { - bfd_set_error (bfd_error_no_memory); for (i = 0; i < bfd_count; i++) if (all_local_syms[i]) free (all_local_syms[i]); @@ -2613,11 +2578,10 @@ elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info) all_local_syms[index] = local_syms; ext_syms - = (Elf32_External_Sym *)malloc (symtab_hdr->sh_info - * sizeof (Elf32_External_Sym)); + = (Elf32_External_Sym *) bfd_malloc (symtab_hdr->sh_info + * sizeof (Elf32_External_Sym)); if (ext_syms == NULL) { - bfd_set_error (bfd_error_no_memory); for (i = 0; i < bfd_count; i++) if (all_local_syms[i]) free (all_local_syms[i]); @@ -2702,10 +2666,11 @@ elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info) /* Allocate space for the external relocations. */ external_relocs - = (Elf32_External_Rela *) malloc (section->reloc_count * sizeof (Elf32_External_Rela)); + = ((Elf32_External_Rela *) + bfd_malloc (section->reloc_count + * sizeof (Elf32_External_Rela))); if (external_relocs == NULL) { - bfd_set_error (bfd_error_no_memory); for (i = 0; i < bfd_count; i++) if (all_local_syms[i]) free (all_local_syms[i]); @@ -2715,10 +2680,10 @@ elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info) /* Likewise for the internal relocations. */ internal_relocs - = (Elf_Internal_Rela *) malloc (section->reloc_count * sizeof (Elf_Internal_Rela)); + = ((Elf_Internal_Rela *) + bfd_malloc (section->reloc_count * sizeof (Elf_Internal_Rela))); if (internal_relocs == NULL) { - bfd_set_error (bfd_error_no_memory); free (external_relocs); for (i = 0; i < bfd_count; i++) if (all_local_syms[i]) @@ -2757,7 +2722,8 @@ elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info) irelaend = irela + section->reloc_count; for (; irela < irelaend; irela++) { - long r_type, callee_args, caller_args, r_index, size_of_stub; + long r_type, callee_args, caller_args, size_of_stub; + unsigned long r_index; struct elf_link_hash_entry *hash; struct elf32_hppa_stub_hash_entry *stub_hash; struct elf32_hppa_args_hash_entry *args_hash; @@ -2803,9 +2769,9 @@ elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info) sym = local_syms + r_index; hdr = elf_elfsections (input_bfd)[sym->st_shndx]; sym_sec = hdr->bfd_section; - sym_name = elf_string_from_elf_section (input_bfd, - symtab_hdr->sh_link, - sym->st_name); + sym_name = bfd_elf_string_from_elf_section (input_bfd, + symtab_hdr->sh_link, + sym->st_name); sym_value = (ELF_ST_TYPE (sym->st_info) == STT_SECTION ? 0 : sym->st_value); destination = (sym_value @@ -2814,10 +2780,9 @@ elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info) /* Tack on an ID so we can uniquely identify this local symbol in the stub or arg info hash tables. */ - new_name = malloc (strlen (sym_name) + 10); + new_name = bfd_malloc (strlen (sym_name) + 10); if (new_name == 0) { - bfd_set_error (bfd_error_bad_value); free (internal_relocs); for (i = 0; i < bfd_count; i++) if (all_local_syms[i]) @@ -2901,11 +2866,9 @@ elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info) len = strlen (sym_name); len += 23; - stub_name = malloc (len); + stub_name = bfd_malloc (len); if (!stub_name) { - bfd_set_error (bfd_error_no_memory); - /* Because sym_name was mallocd above for local symbols. */ if (r_index < symtab_hdr->sh_info) @@ -2948,7 +2911,6 @@ elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info) stub_name, true, true); if (stub_hash == NULL) { - bfd_set_error (bfd_error_no_memory); free (stub_name); free (internal_relocs); for (i = 0; i < bfd_count; i++) @@ -2989,15 +2951,20 @@ error_return: elf32_hppa_hash_table(link_info)->args_hash_table = NULL; free (args_hash_table); } + /* Set the size of the stub section to zero since we're never going + to create them. Avoids losing when we try to get its contents + too. */ + bfd_set_section_size (stub_bfd, stub_sec, 0); return false; } /* Misc BFD support code. */ #define bfd_elf32_bfd_reloc_type_lookup elf_hppa_reloc_type_lookup -#define bfd_elf32_bfd_is_local_label hppa_elf_is_local_label +#define bfd_elf32_bfd_is_local_label_name hppa_elf_is_local_label_name /* Symbol extension stuff. */ #define bfd_elf32_set_section_contents elf32_hppa_set_section_contents +#define elf_info_to_howto elf32_hppa_info_to_howto #define elf_backend_symbol_table_processing \ elf32_hppa_backend_symbol_table_processing #define elf_backend_begin_write_processing \