diff options
author | Andreas Schwab <schwab@suse.de> | 2018-06-18 10:29:31 +0200 |
---|---|---|
committer | Andreas Schwab <schwab@suse.de> | 2018-06-19 11:01:28 +0200 |
commit | 39e07931b1be69b13acb8322687f825bd00afe91 (patch) | |
tree | ea4be14522172189929dc3a319e61d6dd0226bc1 /binutils | |
parent | f63b508a8709da08448ea68c9db7c5d9f168da0c (diff) | |
download | binutils-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.c | 73 |
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 |