aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@suse.de>2018-06-18 10:29:31 +0200
committerAndreas Schwab <schwab@suse.de>2018-06-19 11:01:28 +0200
commit39e07931b1be69b13acb8322687f825bd00afe91 (patch)
treeea4be14522172189929dc3a319e61d6dd0226bc1 /binutils
parentf63b508a8709da08448ea68c9db7c5d9f168da0c (diff)
downloadbinutils-39e07931b1be69b13acb8322687f825bd00afe91.zip
binutils-39e07931b1be69b13acb8322687f825bd00afe91.tar.gz
binutils-39e07931b1be69b13acb8322687f825bd00afe91.tar.bz2
readelf: Handle more RISC-V relocations
* readelf.c (is_16bit_abs_reloc): Handle R_RISCV_SET16. (is_8bit_abs_reloc): New function. (is_6bit_abs_reloc): New function. (is_6bit_inplace_sub_reloc): New function. (apply_relocations): Use them. Handle 6-bit relocations.
Diffstat (limited to 'binutils')
-rw-r--r--binutils/readelf.c73
1 files changed, 72 insertions, 1 deletions
diff --git a/binutils/readelf.c b/binutils/readelf.c
index c713e7f..1b50ba7 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -12659,6 +12659,8 @@ is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
return reloc_type == 9; /* R_NIOS_16. */
case EM_OR1K:
return reloc_type == 2; /* R_OR1K_16. */
+ case EM_RISCV:
+ return reloc_type == 55; /* R_RISCV_SET16. */
case EM_TI_PRU:
return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
case EM_TI_C6000:
@@ -12676,6 +12678,36 @@ is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
}
/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
+ a 8-bit absolute RELA relocation used in DWARF debug sections. */
+
+static bfd_boolean
+is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
+{
+ switch (filedata->file_header.e_machine)
+ {
+ case EM_RISCV:
+ return reloc_type == 54; /* R_RISCV_SET8. */
+ default:
+ return FALSE;
+ }
+}
+
+/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
+ a 6-bit absolute RELA relocation used in DWARF debug sections. */
+
+static bfd_boolean
+is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
+{
+ switch (filedata->file_header.e_machine)
+ {
+ case EM_RISCV:
+ return reloc_type == 53; /* R_RISCV_SET6. */
+ default:
+ return FALSE;
+ }
+}
+
+/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
a 32-bit inplace add RELA relocation used in DWARF debug sections. */
static bfd_boolean
@@ -12803,6 +12835,21 @@ is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
}
}
+/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
+ a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
+
+static bfd_boolean
+is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
+{
+ switch (filedata->file_header.e_machine)
+ {
+ case EM_RISCV:
+ return reloc_type == 52; /* R_RISCV_SUB6. */
+ default:
+ return FALSE;
+ }
+}
+
/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
relocation entries (possibly formerly used for SHT_GROUP sections). */
@@ -13006,6 +13053,9 @@ apply_relocations (Filedata * filedata,
reloc_size = 3;
else if (is_16bit_abs_reloc (filedata, reloc_type))
reloc_size = 2;
+ else if (is_8bit_abs_reloc (filedata, reloc_type)
+ || is_6bit_abs_reloc (filedata, reloc_type))
+ reloc_size = 1;
else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
reloc_type))
|| is_32bit_inplace_add_reloc (filedata, reloc_type))
@@ -13034,6 +13084,12 @@ apply_relocations (Filedata * filedata,
reloc_size = 1;
reloc_inplace = TRUE;
}
+ else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
+ reloc_type)))
+ {
+ reloc_size = 1;
+ reloc_inplace = TRUE;
+ }
else
{
static unsigned int prev_reloc = 0;
@@ -13106,7 +13162,12 @@ apply_relocations (Filedata * filedata,
|| filedata->file_header.e_machine == EM_CYGNUS_D30V)
&& reloc_type == 12)
|| reloc_inplace)
- addend += byte_get (rloc, reloc_size);
+ {
+ if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
+ addend += byte_get (rloc, reloc_size) & 0x3f;
+ else
+ addend += byte_get (rloc, reloc_size);
+ }
if (is_32bit_pcrel_reloc (filedata, reloc_type)
|| is_64bit_pcrel_reloc (filedata, reloc_type))
@@ -13117,6 +13178,16 @@ apply_relocations (Filedata * filedata,
byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
reloc_size);
}
+ else if (is_6bit_abs_reloc (filedata, reloc_type)
+ || is_6bit_inplace_sub_reloc (filedata, reloc_type))
+ {
+ if (reloc_subtract)
+ addend -= sym->st_value;
+ else
+ addend += sym->st_value;
+ addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
+ byte_put (rloc, addend, reloc_size);
+ }
else if (reloc_subtract)
byte_put (rloc, addend - sym->st_value, reloc_size);
else