sparc: fix the extraction of relocation IDs from r_type fields.
authorJose E. Marchesi <jose.marchesi@oracle.com>
Mon, 5 Oct 2015 15:36:33 +0000 (17:36 +0200)
committerMark Wielaard <mjw@redhat.com>
Mon, 5 Oct 2015 22:03:07 +0000 (00:03 +0200)
This patch adds support for a RELOC_TYPE_ID transform macros that
backends can use before including common-reloc.c.  The sparc backend
uses this in order to extract the relocation IDs from r_type fields.
In this target the most significative 24 bits of r_type are used to
store an additional addend in some relocation types.

Signed-off-by: Jose E. Marchesi <jose.marchesi@oracle.com>
backends/ChangeLog
backends/common-reloc.c
backends/sparc_init.c

index 719fb23..60c6b72 100644 (file)
@@ -1,5 +1,13 @@
 2015-10-02  Jose E. Marchesi  <jose.marchesi@oracle.com>
 
+       * sparc_init.c (RELOC_TYPE_ID): Defined.
+       * common-reloc.c (reloc_type_name): Apply target-specific
+       relocation ID extractors if defined.
+       (reloc_type_check): Likewise.
+       (reloc_valid_use): Likewise.
+
+2015-10-02  Jose E. Marchesi  <jose.marchesi@oracle.com>
+
        * sparc_reloc.def: Added relocation types WDISP10, JMP_IREL and
        IRELATIVE.
 
index 2667ec4..3317b6c 100644 (file)
@@ -87,6 +87,10 @@ EBLHOOK(reloc_type_name) (int reloc,
                          char *buf __attribute__ ((unused)),
                          size_t len __attribute__ ((unused)))
 {
+#ifdef RELOC_TYPE_ID
+  reloc = RELOC_TYPE_ID (reloc);
+#endif
+
   if (reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0)
     return &reloc_namestr[EBLHOOK(reloc_nameidx)[reloc]];
   return NULL;
@@ -95,19 +99,28 @@ EBLHOOK(reloc_type_name) (int reloc,
 bool
 EBLHOOK(reloc_type_check) (int reloc)
 {
+#ifdef RELOC_TYPE_ID
+  reloc = RELOC_TYPE_ID (reloc);
+#endif
+
   return reloc >= 0 && reloc < nreloc && EBLHOOK(reloc_nameidx)[reloc] != 0;
 }
 
 bool
 EBLHOOK(reloc_valid_use) (Elf *elf, int reloc)
 {
-  uint8_t uses = EBLHOOK(reloc_valid)[reloc];
+  uint8_t uses;
 
   GElf_Ehdr ehdr_mem;
   GElf_Ehdr *ehdr = gelf_getehdr (elf, &ehdr_mem);
   assert (ehdr != NULL);
   uint8_t type = ehdr->e_type;
 
+#ifdef RELOC_TYPE_ID
+  reloc = RELOC_TYPE_ID (reloc);
+#endif
+
+  uses = EBLHOOK(reloc_valid)[reloc];
   return type > ET_NONE && type < ET_CORE && (uses & (1 << (type - 1)));
 }
 
index 18d7349..229a9b0 100644 (file)
 #define RELOC_PREFIX   R_SPARC_
 #include "libebl_CPU.h"
 
+/* In SPARC some relocations use the most significative 24 bits of the
+   r_type field to encode a secondary addend.  Make sure the routines
+   in common-reloc.c acknowledge this.  */
+#define RELOC_TYPE_ID(type) ((type) & 0xff)
+
 /* This defines the common reloc hooks based on sparc_reloc.def.  */
 #include "common-reloc.c"