From: Jose E. Marchesi Date: Mon, 5 Oct 2015 15:36:33 +0000 (+0200) Subject: sparc: fix the extraction of relocation IDs from r_type fields. X-Git-Tag: elfutils-0.164~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=22843755fa0b6870162660105c6fbbd1ba078390;p=thirdparty%2Felfutils.git sparc: fix the extraction of relocation IDs from r_type fields. 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 --- diff --git a/backends/ChangeLog b/backends/ChangeLog index 719fb231e..60c6b72ff 100644 --- a/backends/ChangeLog +++ b/backends/ChangeLog @@ -1,3 +1,11 @@ +2015-10-02 Jose E. Marchesi + + * 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 * sparc_reloc.def: Added relocation types WDISP10, JMP_IREL and diff --git a/backends/common-reloc.c b/backends/common-reloc.c index 2667ec4a9..3317b6c99 100644 --- a/backends/common-reloc.c +++ b/backends/common-reloc.c @@ -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))); } diff --git a/backends/sparc_init.c b/backends/sparc_init.c index 18d734949..229a9b086 100644 --- a/backends/sparc_init.c +++ b/backends/sparc_init.c @@ -34,6 +34,11 @@ #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"