This adds support for ADD and SUB relocations as seen on RISC-V.
Signed-off-by: Andreas Schwab <schwab@suse.de>
+2018-10-02 Andreas Schwab <schwab@suse.de>
+
+ * riscv_symbol.c (riscv_reloc_simple_type): Add parameter addsub.
+ Set it for ADD and SUB relocations.
+ * aarch64_symbol.c (aarch64_reloc_simple_type): Add and ignore
+ third parameter.
+ * alpha_symbol.c (alpha_reloc_simple_type): Likewise.
+ * arm_symbol.c (arm_reloc_simple_type): Likewise.
+ * bpf_symbol.c (bpf_reloc_simple_type): Likewise.
+ * i386_symbol.c (i386_reloc_simple_type): Likewise.
+ * ia64_symbol.c (ia64_reloc_simple_type): Likewise.
+ * m68k_symbol.c (m68k_reloc_simple_type): Likewise.
+ * ppc64_symbol.c (ppc64_reloc_simple_type): Likewise.
+ * ppc_symbol.c (ppc_reloc_simple_type): Likewise.
+ * s390_symbol.c (s390_reloc_simple_type): Likewise.
+ * sh_symbol.c (sh_reloc_simple_type): Likewise.
+ * sparc_symbol.c (sparc_reloc_simple_type): Likewise.
+ * tilegx_symbol.c (tilegx_reloc_simple_type): Likewise.
+ * x86_64_symbol.c (x86_64_reloc_simple_type): Likewise.
+
2018-09-12 Mark Wielaard <mark@klomp.org>
* ppc64_init.c (ppc64_init): Use elf_getshdrstrndx.
/* Check for the simple reloc types. */
Elf_Type
-aarch64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+aarch64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+ int *addsub __attribute__ ((unused)))
{
switch (type)
{
/* Check for the simple reloc types. */
Elf_Type
-alpha_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+alpha_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+ int *addsub __attribute__ ((unused)))
{
switch (type)
{
/* Check for the simple reloc types. */
Elf_Type
-arm_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+arm_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+ int *addsub __attribute__ ((unused)))
{
switch (type)
{
/* Check for the simple reloc types. */
Elf_Type
-bpf_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+bpf_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+ int *addsub __attribute__ ((unused)))
{
switch (type)
{
/* Check for the simple reloc types. */
Elf_Type
-i386_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+i386_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+ int *addsub __attribute__ ((unused)))
{
switch (type)
{
/* Check for the simple reloc types. */
Elf_Type
-ia64_reloc_simple_type (Ebl *ebl, int type)
+ia64_reloc_simple_type (Ebl *ebl, int type,
+ int *addsub __attribute__ ((unused)))
{
switch (type)
{
/* Check for the simple reloc types. */
Elf_Type
-m68k_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+m68k_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+ int *addsub __attribute__ ((unused)))
{
switch (type)
{
/* Check for the simple reloc types. */
Elf_Type
-ppc64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+ppc64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+ int *addsub __attribute__ ((unused)))
{
switch (type)
{
/* Check for the simple reloc types. */
Elf_Type
-ppc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+ppc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+ int *addsub __attribute__ ((unused)))
{
switch (type)
{
/* Check for the simple reloc types. */
Elf_Type
-riscv_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+riscv_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+ int *addsub)
{
switch (type)
{
+ case R_RISCV_SET8:
+ return ELF_T_BYTE;
+ case R_RISCV_SET16:
+ return ELF_T_HALF;
case R_RISCV_32:
+ case R_RISCV_SET32:
return ELF_T_WORD;
case R_RISCV_64:
return ELF_T_XWORD;
+ case R_RISCV_ADD16:
+ *addsub = 1;
+ return ELF_T_HALF;
+ case R_RISCV_SUB16:
+ *addsub = -1;
+ return ELF_T_HALF;
+ case R_RISCV_ADD32:
+ *addsub = 1;
+ return ELF_T_WORD;
+ case R_RISCV_SUB32:
+ *addsub = -1;
+ return ELF_T_WORD;
+ case R_RISCV_ADD64:
+ *addsub = 1;
+ return ELF_T_XWORD;
+ case R_RISCV_SUB64:
+ *addsub = -1;
+ return ELF_T_XWORD;
default:
return ELF_T_NUM;
}
/* Check for the simple reloc types. */
Elf_Type
-s390_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+s390_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+ int *addsub __attribute__ ((unused)))
{
switch (type)
{
/* Check for the simple reloc types. */
Elf_Type
-sh_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+sh_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+ int *addsub __attribute__ ((unused)))
{
switch (type)
{
/* Check for the simple reloc types. */
Elf_Type
-sparc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+sparc_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+ int *addsub __attribute__ ((unused)))
{
switch (type)
{
/* Check for the simple reloc types. */
Elf_Type
-tilegx_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+tilegx_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+ int *addsub __attribute__ ((unused)))
{
switch (type)
{
/* Check for the simple reloc types. */
Elf_Type
-x86_64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type)
+x86_64_reloc_simple_type (Ebl *ebl __attribute__ ((unused)), int type,
+ int *addsub __attribute__ ((unused)))
{
switch (type)
{
+2018-10-02 Andreas Schwab <schwab@suse.de>
+
+ * relocate.c (relocate): Handle ADD/SUB relocations.
+
2018-09-13 Mark Wielaard <mark@klomp.org>
* dwfl_segment_report_module.c (dwfl_segment_report_module):
So we just pretend it's OK without further relocation. */
return DWFL_E_NOERROR;
- Elf_Type type = ebl_reloc_simple_type (mod->ebl, rtype);
+ int addsub = 0;
+ Elf_Type type = ebl_reloc_simple_type (mod->ebl, rtype, &addsub);
if (unlikely (type == ELF_T_NUM))
return DWFL_E_BADRELTYPE;
{
#define DO_TYPE(NAME, Name) \
case ELF_T_##NAME: \
+ if (addsub != 0 && addend == NULL) \
+ /* These do not make sense with SHT_REL. */ \
+ return DWFL_E_BADRELTYPE; \
size = sizeof (GElf_##Name); \
break
TYPES;
{
/* For the addend form, we have the value already. */
value += *addend;
+ /* For ADD/SUB relocations we need to fetch the section
+ contents. */
+ if (addsub != 0)
+ {
+ Elf_Data *d = gelf_xlatetom (relocated, &tmpdata, &rdata,
+ ehdr->e_ident[EI_DATA]);
+ if (d == NULL)
+ return DWFL_E_LIBELF;
+ assert (d == &tmpdata);
+ }
switch (type)
{
#define DO_TYPE(NAME, Name) \
case ELF_T_##NAME: \
- tmpbuf.Name = value; \
+ if (addsub != 0) \
+ tmpbuf.Name += value * addsub; \
+ else \
+ tmpbuf.Name = value; \
break
TYPES;
#undef DO_TYPE
+2018-10-02 Andreas Schwab <schwab@suse.de>
+
+ * ebl-hooks.h (EBLHOOK(reloc_simple_type)): Add third parameter.
+ * libebl.h (ebl_reloc_simple_type): Likewise.
+ * eblopenbackend.c (default_reloc_simple_type): Likewise.
+ * eblrelocsimpletype.c (ebl_reloc_simple_type): Pass it down.
+
2018-09-12 Mark Wielaard <mark@klomp.org>
* eblsectionstripp.c (ebl_section_strip_p): Drop ehdr argument.
bool EBLHOOK(reloc_type_check) (int);
/* Check if relocation type is for simple absolute relocations. */
-Elf_Type EBLHOOK(reloc_simple_type) (Ebl *, int);
+Elf_Type EBLHOOK(reloc_simple_type) (Ebl *, int, int *);
/* Check relocation type use. */
bool EBLHOOK(reloc_valid_use) (Elf *, int);
static const char *default_reloc_type_name (int ignore, char *buf, size_t len);
static bool default_reloc_type_check (int ignore);
static bool default_reloc_valid_use (Elf *elf, int ignore);
-static Elf_Type default_reloc_simple_type (Ebl *ebl, int ignore);
+static Elf_Type default_reloc_simple_type (Ebl *ebl, int ignore, int *addsub);
static bool default_gotpc_reloc_check (Elf *elf, int ignore);
static const char *default_segment_type_name (int ignore, char *buf,
size_t len);
static Elf_Type
default_reloc_simple_type (Ebl *eh __attribute__ ((unused)),
- int ignore __attribute__ ((unused)))
+ int ignore __attribute__ ((unused)),
+ int *addsub __attribute__ ((unused)))
{
return ELF_T_NUM;
}
Elf_Type
-ebl_reloc_simple_type (Ebl *ebl, int reloc)
+ebl_reloc_simple_type (Ebl *ebl, int reloc, int *addsub)
{
- return ebl != NULL ? ebl->reloc_simple_type (ebl, reloc) : ELF_T_NUM;
+ return ebl != NULL ? ebl->reloc_simple_type (ebl, reloc, addsub) : ELF_T_NUM;
}
extern bool ebl_reloc_valid_use (Ebl *ebl, int reloc);
/* Check if relocation type is for simple absolute relocations.
- Return ELF_T_{BYTE,HALF,SWORD,SXWORD} for a simple type, else ELF_T_NUM. */
-extern Elf_Type ebl_reloc_simple_type (Ebl *ebl, int reloc);
+ Return ELF_T_{BYTE,HALF,SWORD,SXWORD} for a simple type, else ELF_T_NUM.
+ If the relocation type is an ADD or SUB relocation, set *ADDSUB to 1 or -1,
+ resp. */
+extern Elf_Type ebl_reloc_simple_type (Ebl *ebl, int reloc, int *addsub);
/* Return true if the symbol type is that referencing the GOT. E.g.,
R_386_GOTPC. */
+2018-10-02 Andreas Schwab <schwab@suse.de>
+
+ * strip.c (handle_elf): Handle ADD/SUB relocation.
+
2018-09-13 Mark Wielaard <mark@klomp.org>
* readelf.c (print_shdr): Get number of section with elf_getshdrnum.
return true;
/* We only do simple absolute relocations. */
- Elf_Type type = ebl_reloc_simple_type (ebl, rtype);
+ int addsub = 0;
+ Elf_Type type = ebl_reloc_simple_type (ebl, rtype, &addsub);
if (type == ELF_T_NUM)
return false;
/* For SHT_RELA sections we just take the
given addend and add it to the value. */
value += addend;
+ /* For ADD/SUB relocations we need to fetch the
+ current section contents. */
+ if (addsub != 0)
+ {
+ Elf_Data *d = gelf_xlatetom (debugelf, &tmpdata,
+ &rdata,
+ ehdr->e_ident[EI_DATA]);
+ if (d == NULL)
+ INTERNAL_ERROR (fname);
+ assert (d == &tmpdata);
+ }
}
else
{
switch (type)
{
-#define DO_TYPE(NAME, Name) \
- case ELF_T_##NAME: \
- tmpbuf.Name += (GElf_##Name) value; \
+#define DO_TYPE(NAME, Name) \
+ case ELF_T_##NAME: \
+ if (addsub < 0) \
+ tmpbuf.Name -= (GElf_##Name) value; \
+ else \
+ tmpbuf.Name += (GElf_##Name) value; \
break;
TYPES;
#undef DO_TYPE