diff options
-rw-r--r-- | bfd/ChangeLog | 13 | ||||
-rw-r--r-- | bfd/elfnn-riscv.c | 20 | ||||
-rw-r--r-- | bfd/elfxx-riscv.h | 6 | ||||
-rw-r--r-- | ld/ChangeLog | 12 | ||||
-rw-r--r-- | ld/emultempl/riscvelf.em | 14 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 3 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/relro-relax-lui.d | 12 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/relro-relax-lui.s | 15 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/relro-relax-pcrel.d | 12 | ||||
-rw-r--r-- | ld/testsuite/ld-riscv-elf/relro-relax-pcrel.s | 14 |
10 files changed, 119 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 6242f3c..fd9721e 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,16 @@ +2021-05-31 Nelson Chu <nelson.chu@sifive.com> + Lifang Xia <lifang_xia@c-sky.com> + + PR 27566 + * elfnn-riscv.c (struct riscv_elf_link_hash_table): New integer pointer + to monitor the data segment phase. + (bfd_elfNN_riscv_set_data_segment_info): New function called by + after_allocation, to set the data_segment_phase from expld.dataseg. + (_bfd_riscv_relax_section): Don't relax when data_segment_phase is + exp_seg_relro_adjust (0x4). + * elfxx-riscv.h (bfd_elf32_riscv_set_data_segment_info): New extern. + (bfd_elf64_riscv_set_data_segment_info): Likewise + 2021-05-28 H.J. Lu <hongjiu.lu@intel.com> PR ld/27905 diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c index d2781f3..eef1e80 100644 --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -132,6 +132,10 @@ struct riscv_elf_link_hash_table /* Re-run the relaxations from relax pass 0 if TRUE. */ bool restart_relax; + + /* The data segment phase, don't relax the section + when it is exp_seg_relro_adjust. */ + int *data_segment_phase; }; /* Instruction access functions. */ @@ -4620,6 +4624,17 @@ _bfd_riscv_relax_delete (bfd *abfd, return true; } +/* Called by after_allocation to set the information of data segment + before relaxing. */ + +void +bfd_elfNN_riscv_set_data_segment_info (struct bfd_link_info *info, + int *data_segment_phase) +{ + struct riscv_elf_link_hash_table *htab = riscv_elf_hash_table (info); + htab->data_segment_phase = data_segment_phase; +} + /* Called by after_allocation to check if we need to run the whole relaxations again. */ @@ -4672,7 +4687,10 @@ _bfd_riscv_relax_section (bfd *abfd, asection *sec, || (info->disable_target_specific_optimizations && info->relax_pass < 2) || (htab->restart_relax - && info->relax_pass == 3)) + && info->relax_pass == 3) + /* The exp_seg_relro_adjust is enum phase_enum (0x4), + and defined in ld/ldexp.h. */ + || *(htab->data_segment_phase) == 4) return true; riscv_init_pcgp_relocs (&pcgp_relocs); diff --git a/bfd/elfxx-riscv.h b/bfd/elfxx-riscv.h index c2fff92..6a2501b 100644 --- a/bfd/elfxx-riscv.h +++ b/bfd/elfxx-riscv.h @@ -98,6 +98,10 @@ riscv_compare_subsets (const char *, const char *); extern bool bfd_elf32_riscv_restart_relax_sections (struct bfd_link_info *); - extern bool bfd_elf64_riscv_restart_relax_sections (struct bfd_link_info *); + +extern void +bfd_elf32_riscv_set_data_segment_info (struct bfd_link_info *, int *); +extern void +bfd_elf64_riscv_set_data_segment_info (struct bfd_link_info *, int *); diff --git a/ld/ChangeLog b/ld/ChangeLog index 263dee0..2c6615d 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,15 @@ +2021-05-31 Nelson Chu <nelson.chu@sifive.com> + Lifang Xia <lifang_xia@c-sky.com> + + PR 27566 + * emultempl/riscvelf.em (after_allocation): Call + riscv_set_data_segment_info to set data segment phase before relaxing. + * testsuite/ld-riscv-elf/ld-riscv-elf.exp: Updated. + * testsuite/ld-riscv-elf/relro-relax-lui.d: New testcase. + * testsuite/ld-riscv-elf/relro-relax-lui.s: Likewise. + * testsuite/ld-riscv-elf/relro-relax-pcrel.d: Likewise. + * testsuite/ld-riscv-elf/relro-relax-pcrel.s: Likewise. + 2021-05-28 H.J. Lu <hongjiu.lu@intel.com> PR ld/27905 diff --git a/ld/emultempl/riscvelf.em b/ld/emultempl/riscvelf.em index 5fa7c77..c625a63 100644 --- a/ld/emultempl/riscvelf.em +++ b/ld/emultempl/riscvelf.em @@ -62,6 +62,20 @@ gld${EMULATION_NAME}_after_allocation (void) } } + /* PR 27566, if the phase of data segment is exp_seg_relro_adjust, + that means we are still adjusting the relro, and shouldn't do the + relaxations at this stage. Otherwise, we will get the symbol + values beofore handling the relro, and may cause truncated fails + when the relax range crossing the data segment. One of the solution + is to monitor the data segment phase while relaxing, to know whether + the relro has been handled or not. + + I think we probably need to record more information about data + segment or alignments in the future, to make sure it is safe + to doing relaxations. */ + enum phase_enum *phase = &(expld.dataseg.phase); + bfd_elf${ELFSIZE}_riscv_set_data_segment_info (&link_info, (int *) phase); + do { ldelf_map_segments (need_layout); diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp index 319ac7e..0b49ddc 100644 --- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp +++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp @@ -122,6 +122,9 @@ if [istarget "riscv*-*-*"] { return } + run_dump_test "relro-relax-lui" + run_dump_test "relro-relax-pcrel" + set abis [list rv32gc ilp32 [riscv_choose_ilp32_emul] rv64gc lp64 [riscv_choose_lp64_emul]] foreach { arch abi emul } $abis { # This checks whether our linker scripts handle __global_pointer$ diff --git a/ld/testsuite/ld-riscv-elf/relro-relax-lui.d b/ld/testsuite/ld-riscv-elf/relro-relax-lui.d new file mode 100644 index 0000000..d29aa9d --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/relro-relax-lui.d @@ -0,0 +1,12 @@ +#source: relro-relax-lui.s +#ld: -zrelro --relax +#objdump: -d -Mno-aliases + +.*:[ ]+file format .* + + +Disassembly of section .text: + +0+[0-9a-f]+ <_start>: +.*:[ ]+[0-9a-f]+[ ]+lui[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+addi[ ]+.*<SymbolRodata> diff --git a/ld/testsuite/ld-riscv-elf/relro-relax-lui.s b/ld/testsuite/ld-riscv-elf/relro-relax-lui.s new file mode 100644 index 0000000..f284187 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/relro-relax-lui.s @@ -0,0 +1,15 @@ + .section .rodata + .align 10 + .globl SymbolRodata + .set SymbolRodata, . + 0x1800 + .word 0x0 + + + .section .init_array + .word 0x0 + + .text + .globl _start +_start: + lui a0, %hi (SymbolRodata) + addi a0, a0, %lo (SymbolRodata) diff --git a/ld/testsuite/ld-riscv-elf/relro-relax-pcrel.d b/ld/testsuite/ld-riscv-elf/relro-relax-pcrel.d new file mode 100644 index 0000000..28e11b3 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/relro-relax-pcrel.d @@ -0,0 +1,12 @@ +#source: relro-relax-pcrel.s +#ld: -zrelro --relax +#objdump: -d -Mno-aliases + +.*:[ ]+file format .* + + +Disassembly of section .text: + +0+[0-9a-f]+ <_start>: +.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+.* +.*:[ ]+[0-9a-f]+[ ]+addi[ ]+.*<SymbolRodata> diff --git a/ld/testsuite/ld-riscv-elf/relro-relax-pcrel.s b/ld/testsuite/ld-riscv-elf/relro-relax-pcrel.s new file mode 100644 index 0000000..4a88287 --- /dev/null +++ b/ld/testsuite/ld-riscv-elf/relro-relax-pcrel.s @@ -0,0 +1,14 @@ + .section .rodata + .align 10 + .globl SymbolRodata + .set SymbolRodata, . + 0x1800 + .word 0x0 + + + .section .init_array + .word 0x0 + + .text + .globl _start +_start: + lla a0, SymbolRodata |