From a6cbf936e3dce68114d28cdf60d510a3f78a6d40 Mon Sep 17 00:00:00 2001 From: Kuan-Lin Chen Date: Thu, 8 Jun 2017 11:54:14 -0700 Subject: [PATCH] RISC-V: Use pc-relative relocation for FDE initial location The symbol address in .eh_frame may be adjusted in _bfd_elf_discard_section_eh_frame, and the content of .eh_frame will be adjusted in _bfd_elf_write_section_eh_frame. Therefore, we cannot insert a relocation whose addend symbol is in .eh_frame. Othrewise, the value may be adjusted twice. bfd/ChangeLog 2017-06-26 Kuan-Lin Chen * elfnn-riscv.c (perform_relocation): Support the new R_RISCV_32_PCREL relocation. (riscv_elf_relocate_section): Likewise. * elfxx-riscv.c (howto_table): Likewise. (riscv_reloc_map): Likewise. * bfd-in2.h (BFD_RELOC_RISCV_32_PCREL): New relocation. * libbfd.h: Regenerate. gas/ChangeLog 2017-06-26 Kuan-Lin Chen * config/tc-riscv.c (md_apply_fix) [BFD_RELOC_32]: Convert to a R_RISCV_32_PCREL relocation. include/ChangeLog 2017-06-26 Kuan-Lin Chen * elf/riscv.h (R_RISCV_32_PCREL): New. --- bfd/ChangeLog | 10 ++++++++++ bfd/bfd-in2.h | 1 + bfd/elfnn-riscv.c | 2 ++ bfd/elfxx-riscv.c | 16 ++++++++++++++++ bfd/libbfd.h | 1 + bfd/reloc.c | 2 ++ gas/ChangeLog | 5 +++++ gas/config/tc-riscv.c | 20 +++++++++++++++++++- include/ChangeLog | 4 ++++ include/elf/riscv.h | 1 + 10 files changed, 61 insertions(+), 1 deletion(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f440f8f5725..3cab920a60a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2017-06-26 Kuan-Lin Chen + + * elfnn-riscv.c (perform_relocation): Support the new + R_RISCV_32_PCREL relocation. + (riscv_elf_relocate_section): Likewise. + * elfxx-riscv.c (howto_table): Likewise. + (riscv_reloc_map): Likewise. + * bfd-in2.h (BFD_RELOC_RISCV_32_PCREL): New relocation. + * libbfd.h: Regenerate. + 2017-06-27 Alan Modra PR binutils/21665 diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 45f665b57fc..8c312e3f9ef 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -4771,6 +4771,7 @@ number for the SBIC, SBIS, SBI and CBI instructions */ BFD_RELOC_RISCV_SET8, BFD_RELOC_RISCV_SET16, BFD_RELOC_RISCV_SET32, + BFD_RELOC_RISCV_32_PCREL, /* Renesas RL78 Relocations. */ BFD_RELOC_RL78_NEG8, diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index 4e3cf552b1a..455f2ff2922 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -1566,6 +1566,7 @@ perform_relocation (const reloc_howto_type *howto, case R_RISCV_SET8: case R_RISCV_SET16: case R_RISCV_SET32: + case R_RISCV_32_PCREL: case R_RISCV_TLS_DTPREL32: case R_RISCV_TLS_DTPREL64: break; @@ -1849,6 +1850,7 @@ riscv_elf_relocate_section (bfd *output_bfd, case R_RISCV_SET8: case R_RISCV_SET16: case R_RISCV_SET32: + case R_RISCV_32_PCREL: /* These require no special handling beyond perform_relocation. */ break; diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c index 6936722f9d5..5fa98f37e98 100644 --- a/bfd/elfxx-riscv.c +++ b/bfd/elfxx-riscv.c @@ -833,6 +833,21 @@ static reloc_howto_type howto_table[] = 0, /* src_mask */ MINUS_ONE, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* 32-bit PC relative. */ + HOWTO (R_RISCV_32_PCREL, /* type */ + 0, /* rightshift */ + 2, /* size */ + 32, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_RISCV_32_PCREL", /* name */ + FALSE, /* partial_inplace */ + 0, /* src_mask */ + MINUS_ONE, /* dst_mask */ + FALSE), /* pcrel_offset */ }; /* A mapping from BFD reloc types to RISC-V ELF reloc types. */ @@ -894,6 +909,7 @@ static const struct elf_reloc_map riscv_reloc_map[] = { BFD_RELOC_RISCV_SET8, R_RISCV_SET8 }, { BFD_RELOC_RISCV_SET16, R_RISCV_SET16 }, { BFD_RELOC_RISCV_SET32, R_RISCV_SET32 }, + { BFD_RELOC_RISCV_32_PCREL, R_RISCV_32_PCREL }, }; /* Given a BFD reloc type, return a howto structure. */ diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 09df3b2e050..ae9bf768144 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -2215,6 +2215,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_RISCV_SET8", "BFD_RELOC_RISCV_SET16", "BFD_RELOC_RISCV_SET32", + "BFD_RELOC_RISCV_32_PCREL", "BFD_RELOC_RL78_NEG8", "BFD_RELOC_RL78_NEG16", "BFD_RELOC_RL78_NEG24", diff --git a/bfd/reloc.c b/bfd/reloc.c index 024056f1181..aa70fa58740 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -5155,6 +5155,8 @@ ENUMX BFD_RELOC_RISCV_SET16 ENUMX BFD_RELOC_RISCV_SET32 +ENUMX + BFD_RELOC_RISCV_32_PCREL ENUMDOC RISC-V relocations. diff --git a/gas/ChangeLog b/gas/ChangeLog index 6d3281d4f2a..a4b99155fba 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +2017-06-26 Kuan-Lin Chen + + * config/tc-riscv.c (md_apply_fix) [BFD_RELOC_32]: Convert to a + R_RISCV_32_PCREL relocation. + 2017-06-26 H.J. Lu PR gas/21661 diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index afda6c51248..55c41c5db3c 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -1871,6 +1871,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) bfd_byte *buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where); bfd_boolean relaxable = FALSE; offsetT loc; + segT sub_segment; /* Remember value for tc_gen_reloc. */ fixP->fx_addnumber = *valP; @@ -1919,8 +1920,25 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) _("TLS relocation against a constant")); break; - case BFD_RELOC_64: case BFD_RELOC_32: + /* Use pc-relative relocation for FDE initial location. + The symbol address in .eh_frame may be adjusted in + _bfd_elf_discard_section_eh_frame, and the content of + .eh_frame will be adjusted in _bfd_elf_write_section_eh_frame. + Therefore, we cannot insert a relocation whose addend symbol is + in .eh_frame. Othrewise, the value may be adjusted twice.*/ + if (fixP->fx_addsy && fixP->fx_subsy + && (sub_segment = S_GET_SEGMENT (fixP->fx_subsy)) + && strcmp (sub_segment->name, ".eh_frame") == 0 + && S_GET_VALUE (fixP->fx_subsy) + == fixP->fx_frag->fr_address + fixP->fx_where) + { + fixP->fx_r_type = BFD_RELOC_RISCV_32_PCREL; + fixP->fx_subsy = NULL; + break; + } + /* Fall through. */ + case BFD_RELOC_64: case BFD_RELOC_16: case BFD_RELOC_8: case BFD_RELOC_RISCV_CFA: diff --git a/include/ChangeLog b/include/ChangeLog index 91cb91fb861..243c7303cd6 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2017-06-26 Kuan-Lin Chen + + * elf/riscv.h (R_RISCV_32_PCREL): New. + 2017-06-24 Thomas Preud'homme * elf/arm.h (TAG_CPU_ARCH_V8R): New macro. diff --git a/include/elf/riscv.h b/include/elf/riscv.h index daa44639263..eecacf89c7e 100644 --- a/include/elf/riscv.h +++ b/include/elf/riscv.h @@ -87,6 +87,7 @@ START_RELOC_NUMBERS (elf_riscv_reloc_type) RELOC_NUMBER (R_RISCV_SET8, 54) RELOC_NUMBER (R_RISCV_SET16, 55) RELOC_NUMBER (R_RISCV_SET32, 56) + RELOC_NUMBER (R_RISCV_32_PCREL, 57) END_RELOC_NUMBERS (R_RISCV_max) /* Processor specific flags for the ELF header e_flags field. */ -- 2.30.2