* elf-hppa.h (elf_hppa_fake_sections): Compute section indices
[deliverable/binutils-gdb.git] / bfd / elf-hppa.h
index e692c0f2e28622892976554463b62d0daf6521f2..f3099b8f8c26ff7936a84c9d0c778e7a6d6b95e3 100644 (file)
@@ -292,6 +292,9 @@ static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] =
   {R_PARISC_LTOFF_TP16DF, 0, 0, 0, false, 0, complain_overflow_bitfield, bfd_elf_generic_reloc, "R_PARISC_LTOFF_TP16DF", false, 0, 0, false},
 };
 
+#define OFFSET_14R_FROM_21L 4
+#define OFFSET_14F_FROM_21L 5
+
 /* Return one (or more) BFD relocations which implement the base
    relocation with modifications based on format and field.  */
 
@@ -346,6 +349,9 @@ _bfd_elf_hppa_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
            case e_rtsel:
              final_type = R_PARISC_DLTIND14R;
              break;
+           case e_rtpsel:
+             final_type = R_PARISC_LTOFF_FPTR14DR;
+             break;
            case e_tsel:
              final_type = R_PARISC_DLTIND14F;
              break;
@@ -382,6 +388,9 @@ _bfd_elf_hppa_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
            case e_ltsel:
              final_type = R_PARISC_DLTIND21L;
              break;
+           case e_ltpsel:
+             final_type = R_PARISC_LTOFF_FPTR21L;
+             break;
            case e_lpsel:
              final_type = R_PARISC_PLABEL21L;
              break;
@@ -395,6 +404,11 @@ _bfd_elf_hppa_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
            {
            case e_fsel:
              final_type = R_PARISC_DIR32;
+             /* When in 64bit mode, a 32bit relocation is supposed to
+                be a section relative relocation.  Dwarf2 (for example)
+                uses 32bit section relative relocations.  */
+             if (bfd_get_arch_info (abfd)->bits_per_address != 32)
+               final_type = R_PARISC_SECREL32;
              break;
            case e_psel:
              final_type = R_PARISC_PLABEL32;
@@ -404,6 +418,20 @@ _bfd_elf_hppa_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
            }
          break;
 
+       case 64:
+         switch (field)
+           {
+           case e_fsel:
+             final_type = R_PARISC_DIR64;
+             break;
+           case e_psel:
+             final_type = R_PARISC_FPTR64;
+             break;
+           default:
+             return NULL;
+           }
+         break;
+
        default:
          return NULL;
        }
@@ -418,10 +446,10 @@ _bfd_elf_hppa_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
            {
            case e_rsel:
            case e_rrsel:
-             final_type = R_PARISC_DPREL14R;
+             final_type = base_type + OFFSET_14R_FROM_21L;
              break;
            case e_fsel:
-             final_type = R_PARISC_DPREL14F;
+             final_type = base_type + OFFSET_14F_FROM_21L;
              break;
            default:
              return NULL;
@@ -433,7 +461,7 @@ _bfd_elf_hppa_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
            {
            case e_lrsel:
            case e_lsel:
-             final_type = R_PARISC_DPREL21L;
+             final_type = base_type;
              break;
            default:
              return NULL;
@@ -507,6 +535,11 @@ _bfd_elf_hppa_gen_reloc_type (abfd, base_type, format, field, ignore, sym)
        }
       break;
 
+    case R_PARISC_SEGREL32:
+    case R_PARISC_SEGBASE:
+      /* The defaults are fine for these cases.  */
+      break;
+
     default:
       return NULL;
     }
@@ -573,11 +606,60 @@ elf_hppa_final_write_processing (abfd, linker)
   else if (mach == 11)
     elf_elfheader (abfd)->e_flags |= EFA_PARISC_1_1;
   else if (mach == 20)
+    elf_elfheader (abfd)->e_flags |= EFA_PARISC_2_0;
+  else if (mach == 25)
+    elf_elfheader (abfd)->e_flags |= EF_PARISC_WIDE | EFA_PARISC_2_0;
+}
+
+/* Return true if SYM represents a local label symbol.  */
+
+static boolean
+elf_hppa_is_local_label_name (abfd, name)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     const char *name;
+{
+  return (name[0] == 'L' && name[1] == '$');
+}
+
+/* Set the correct type for an ELF section.  We do this by the
+   section name, which is a hack, but ought to work.  */
+
+static boolean
+elf_hppa_fake_sections (abfd, hdr, sec)
+     bfd *abfd;
+     Elf64_Internal_Shdr *hdr;
+     asection *sec;
+{
+  register const char *name;
+
+  name = bfd_get_section_name (abfd, sec);
+
+  if (strcmp (name, ".PARISC.unwind") == 0)
     {
-      elf_elfheader (abfd)->e_flags |= EFA_PARISC_2_0;
-#if ARCH_SIZE == 64
-      elf_elfheader (abfd)->e_flags |= EF_PARISC_WIDE;
-#endif
+      int indx;
+      asection *sec;
+      hdr->sh_type = SHT_LOPROC + 1;
+      /* ?!? How are unwinds supposed to work for symbols in arbitrary
+        sections?  Or what if we have multiple .text sections in a single
+        .o file?  HP really messed up on this one. 
+
+        Ugh.  We can not use elf_section_data (sec)->this_idx at this
+        point because it is not initialized yet.
+
+        So we (gasp) recompute it here.  Hopefully nobody ever changes the
+        way sections are numbered in elf.c!  */
+      for (sec = abfd->sections, indx = 1; sec; sec = sec->next, indx++)
+       {
+         if (sec->name && strcmp (sec->name, ".text") == 0)
+           {
+             hdr->sh_info = indx;
+             break;
+           }
+       }
+      
+      /* I have no idea if this is really necessary or what it means.  */
+      hdr->sh_entsize = 4;
     }
-
+  return true;
 }
+
This page took 0.025565 seconds and 4 git commands to generate.