* libecoff.h (struct ecoff_backend_data): Add adjust_headers
[deliverable/binutils-gdb.git] / bfd / elf32-hppa.c
index b8c4e71789b3a216b55c4970d7888cb80f4dbbc4..0e92f4e69b03b12dc5772f25ab746423ea6cc94e 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD back-end for HP PA-RISC ELF files.
-   Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
+   Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
 
    Written by
 
@@ -209,7 +209,7 @@ static unsigned long hppa_elf_relocate_insn
 static bfd_reloc_status_type hppa_elf_reloc
   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd*, char **));
 
-static CONST reloc_howto_type * elf_hppa_reloc_type_lookup
+static reloc_howto_type * elf_hppa_reloc_type_lookup
   PARAMS ((bfd *, bfd_reloc_code_real_type));
 
 static boolean elf32_hppa_set_section_contents
@@ -241,7 +241,7 @@ static boolean elf32_hppa_add_symbol_hook
           const char **, flagword *, asection **, bfd_vma *));
 
 static bfd_reloc_status_type elf32_hppa_bfd_final_link_relocate
-  PARAMS ((const reloc_howto_type *, bfd *, bfd *, asection *,
+  PARAMS ((reloc_howto_type *, bfd *, bfd *, asection *,
           bfd_byte *, bfd_vma, bfd_vma, bfd_vma, struct bfd_link_info *,
           asection *, const char *, int));
 
@@ -784,7 +784,7 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
   for (; rel < relend; rel++)
     {
       int r_type;
-      const reloc_howto_type *howto;
+      reloc_howto_type *howto;
       long r_symndx;
       struct elf_link_hash_entry *h;
       Elf_Internal_Sym *sym;
@@ -841,14 +841,15 @@ 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];
-         if (h->root.type == bfd_link_hash_defined)
+         if (h->root.type == bfd_link_hash_defined
+             || h->root.type == bfd_link_hash_defweak)
            {
              sym_sec = h->root.u.def.section;
              relocation = (h->root.u.def.value
                            + sym_sec->output_offset
                            + sym_sec->output_section->vma);
            }
-         else if (h->root.type == bfd_link_hash_weak)
+         else if (h->root.type == bfd_link_hash_undefweak)
            relocation = 0;
          else
            {
@@ -856,7 +857,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;
            }
        }
 
@@ -864,9 +865,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')
@@ -890,6 +891,16 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
        {
          switch (r)
            {
+           /* This can happen for DP relative relocs if $global$ is
+              undefined.  This is a panic situation so we don't try
+              to continue.  */
+           case bfd_reloc_undefined:
+           case bfd_reloc_notsupported:
+             if (!((*info->callbacks->undefined_symbol)
+                   (info, "$global$", input_bfd,
+                    input_section, rel->r_offset)))
+               return false;
+             return false;
            case bfd_reloc_dangerous:
              {
                /* We use this return value to indicate that we performed
@@ -1156,8 +1167,8 @@ 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.  */
@@ -1215,7 +1226,7 @@ static bfd_reloc_status_type
 elf32_hppa_bfd_final_link_relocate (howto, input_bfd, output_bfd,
                                    input_section, contents, offset, value,
                                    addend, info, sym_sec, sym_name, is_local)
-     const reloc_howto_type *howto;
+     reloc_howto_type *howto;
      bfd *input_bfd;
      bfd *output_bfd;
      asection *input_section;
@@ -1252,6 +1263,11 @@ elf32_hppa_bfd_final_link_relocate (howto, input_bfd, output_bfd,
       if (h == NULL)
        return bfd_reloc_notsupported;
 
+      /* If $global$ isn't a defined symbol, then we're still in deep
+        trouble.  */
+      if (h->root.type != bfd_link_hash_defined)
+       return bfd_reloc_undefined;
+
       sec = h->root.u.def.section;
       elf32_hppa_hash_table (info)->global_value = (h->root.u.def.value
                                                    + sec->output_section->vma
@@ -1288,7 +1304,11 @@ elf32_hppa_bfd_final_link_relocate (howto, input_bfd, output_bfd,
     case R_PARISC_DPREL21L:
       r_field = e_lrsel;
       if (sym_sec->flags & SEC_CODE)
-       insn &= ~0x03e00000;
+       {
+         if ((insn & 0xfc000000) >> 26 == 0xa
+              && (insn & 0x03e00000) >> 21 == 0x1b)
+           insn &= ~0x03e00000;
+       }
       else
        value -= elf32_hppa_hash_table (info)->global_value;
       goto do_basic_type_1;
@@ -1525,7 +1545,7 @@ do_basic_type_1:
 /* Return the address of the howto table entry to perform the CODE
    relocation for an ARCH machine.  */
 
-static CONST reloc_howto_type *
+static reloc_howto_type *
 elf_hppa_reloc_type_lookup (abfd, code)
      bfd *abfd;
      bfd_reloc_code_real_type code;
@@ -1987,7 +2007,7 @@ 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;
@@ -2509,7 +2529,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;
@@ -2783,9 +2803,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
@@ -2815,7 +2835,8 @@ elf32_hppa_size_stubs (stub_bfd, output_bfd, link_info)
 
                  index = r_index - symtab_hdr->sh_info;
                  hash = elf_sym_hashes (input_bfd)[index];
-                 if (hash->root.type == bfd_link_hash_defined)
+                 if (hash->root.type == bfd_link_hash_defined
+                     || hash->root.type == bfd_link_hash_defweak)
                    {
                      sym_sec = hash->root.u.def.section;
                      sym_name = hash->root.root.string;
@@ -2968,6 +2989,10 @@ 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;
 }
 
This page took 0.033137 seconds and 4 git commands to generate.