aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog13
-rw-r--r--bfd/elfnn-riscv.c20
-rw-r--r--bfd/elfxx-riscv.h6
-rw-r--r--ld/ChangeLog12
-rw-r--r--ld/emultempl/riscvelf.em14
-rw-r--r--ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp3
-rw-r--r--ld/testsuite/ld-riscv-elf/relro-relax-lui.d12
-rw-r--r--ld/testsuite/ld-riscv-elf/relro-relax-lui.s15
-rw-r--r--ld/testsuite/ld-riscv-elf/relro-relax-pcrel.d12
-rw-r--r--ld/testsuite/ld-riscv-elf/relro-relax-pcrel.s14
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