From 2ec0dd123c40b3ee8217696c1db228553d266f1e Mon Sep 17 00:00:00 2001
From: Jeff Law <law@redhat.com>
Date: Tue, 14 Sep 1999 03:44:43 +0000
Subject:         * 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.

---
 bfd/ChangeLog  |  5 +++++
 bfd/elf-hppa.h | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 66 insertions(+), 8 deletions(-)

(limited to 'bfd')

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 597bd5d00ce..964c7b60cd2 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/elf-hppa.h b/bfd/elf-hppa.h
index 65c009167c3..95d972411fd 100644
--- a/bfd/elf-hppa.h
+++ b/bfd/elf-hppa.h
@@ -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:
-- 
cgit v1.2.1