* elf-hppa.h (elf_hppa_record_segment_addrs): New function.
authorJeff Law <law@redhat.com>
Tue, 14 Sep 1999 03:44:43 +0000 (03:44 +0000)
committerJeff Law <law@redhat.com>
Tue, 14 Sep 1999 03:44:43 +0000 (03:44 +0000)
        (elf_hppa_final_link): Initialize text_segment_base and
        data_segment_base.
        (elf_hppa_final_link_relocate): Handle SEGREL relocations.

bfd/ChangeLog
bfd/elf-hppa.h

index 597bd5d00ceecf73640527ae83c30a9819b6debc..964c7b60cd2f167b122f2c9fbfbd884d663ac2b9 100644 (file)
@@ -1,5 +1,10 @@
 Mon Sep 13 20:01:47 1999  Jeffrey A Law  (law@cygnus.com)
 
+       * elf-hppa.h (elf_hppa_record_segment_addrs): New function.
+       (elf_hppa_final_link): Initialize text_segment_base and
+       data_segment_base.
+       (elf_hppa_final_link_relocate): Handle SEGREL relocations.
+
        * elf-hppa.h (elf_hppa_final_link): Remove unused variables.
        (elf_hppa_final_link_relocate): Likewise.
        (elf_hppa_relocate_insn): Likewise.
index 65c009167c34dfd6a56c07daa2022d776fcb491b..95d972411fd4db2c0f8dc55245989762ba219e1d 100644 (file)
@@ -69,6 +69,9 @@ static boolean elf_hppa_unmark_useless_dynamic_symbols
 static boolean elf_hppa_remark_useless_dynamic_symbols
   PARAMS ((struct elf_link_hash_entry *, PTR));
 
+static void elf_hppa_record_segment_addrs
+  PARAMS ((bfd *, asection *, PTR));
+
 /* ELF/PA relocation howto entries.  */
 
 static reloc_howto_type elf_hppa_howto_table[ELF_HOWTO_TABLE_SIZE] =
@@ -810,6 +813,30 @@ elf_hppa_remark_useless_dynamic_symbols (h, data)
   return true;
 }
 
+/* Record the lowest address for the data and text segments.  */
+static void
+elf_hppa_record_segment_addrs (abfd, section, data)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     asection *section;
+     PTR data;
+{
+  struct elf64_hppa_link_hash_table *hppa_info;
+  bfd_vma value;
+  hppa_info = (struct elf64_hppa_link_hash_table *)data;
+
+  value = section->vma - section->filepos;
+
+  if ((section->flags & (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
+       == (SEC_ALLOC | SEC_LOAD | SEC_READONLY))
+      && value < hppa_info->text_segment_base)
+    hppa_info->text_segment_base = value;
+  else if ((section->flags & (SEC_ALLOC | SEC_LOAD | SEC_READONLY)
+       == (SEC_ALLOC | SEC_LOAD))
+      && value < hppa_info->data_segment_base)
+    hppa_info->data_segment_base = value;
+}
+
 /* Called after we have seen all the input files/sections, but before
    final symbol resolution and section placement has been determined.
 
@@ -852,6 +879,12 @@ elf_hppa_final_link (abfd, info)
       _bfd_set_gp_value (abfd, gp_val);
     }
 
+  /* We need to know the base of the text and data segments so that we
+     can perform SEGREL relocations.  We will recore the base addresses
+     when we encounter the first SEGREL relocation.  */
+  elf64_hppa_hash_table (info)->text_segment_base = (bfd_vma)-1;
+  elf64_hppa_hash_table (info)->data_segment_base = (bfd_vma)-1;
+
   /* HP's shared libraries have references to symbols that are not
      defined anywhere.  The generic ELF BFD linker code will complaim
      about such symbols.
@@ -1097,13 +1130,6 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd,
 
   insn = bfd_get_32 (input_bfd, hit_data);
 
-/* For reference here a quick summary of the relocations found in the
-   HPUX 11.00 PA64 .o and .a files, but not yet implemented.  This is mostly
-   a guide to help prioritize what relocation support is worked on first.
-   The list will be deleted eventually.
-
-   27210 R_PARISC_SEGREL32  */
-
   switch (r_type)
     {
     case R_PARISC_NONE:
@@ -1534,7 +1560,34 @@ elf_hppa_final_link_relocate (rel, input_bfd, output_bfd,
       return bfd_reloc_ok;
 
     case R_PARISC_SEGREL32:
-      return bfd_reloc_ok;
+    case R_PARISC_SEGREL64:
+      {
+       /* If this is the first SEGREL relocation, then initialize
+          the segment base values.  */
+       if (hppa_info->text_segment_base == (bfd_vma) -1)
+         bfd_map_over_sections (output_bfd, elf_hppa_record_segment_addrs,
+                                elf64_hppa_hash_table (info));
+
+       /* VALUE holds the absolute address.  We want to include the
+          addend, then turn it into a segment relative address.
+
+          The segment is derived from SYM_SEC.  We assume that there are
+          only two segments of note in the resulting executable/shlib.
+          A readonly segment (.text) and a readwrite segment (.data).  */
+       value += addend;
+
+       if (sym_sec->flags & SEC_CODE)
+         value -= hppa_info->text_segment_base;
+       else
+         value -= hppa_info->data_segment_base;
+
+       if (r_type == R_PARISC_SEGREL32)
+         bfd_put_32 (input_bfd, value, hit_data);
+       else
+         bfd_put_64 (input_bfd, value, hit_data);
+        return bfd_reloc_ok;
+      }
+      
 
     /* Something we don't know how to handle.  */
     default: