aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@mips.com>2018-09-14 20:22:56 +0100
committerMaciej W. Rozycki <macro@linux-mips.org>2018-09-14 20:22:56 +0100
commit6057dc97e4df5ca9692ddd948798eaa543c74cc7 (patch)
tree4ac5b59f61ba9a6cb89a0aca6b5a344e24de2550
parenta000f8817b32eadd4aeadf9185634350a59e6649 (diff)
downloadfsf-binutils-gdb-6057dc97e4df5ca9692ddd948798eaa543c74cc7.zip
fsf-binutils-gdb-6057dc97e4df5ca9692ddd948798eaa543c74cc7.tar.gz
fsf-binutils-gdb-6057dc97e4df5ca9692ddd948798eaa543c74cc7.tar.bz2
LD: Always make a SEGMENT_START expression section-relative
Fix an issue with the SEGMENT_START builtin function where its result is absolute when taken from the default supplied, and section-relative when taken from a `-T' command-line override. This is against documentation, inconsistent and unexpected, and with PIE executables gives an incorrect result with the `__executable_start' symbol. Make the result of SEGMENT_START always section-relative then. ld/ * ldexp.c (fold_binary): Always make the result of SEGMENT_START section-relative. * testsuite/ld-scripts/segment-start.d: New test. * testsuite/ld-scripts/segment-start.ld: New test linker script. * testsuite/ld-scripts/segment-start.s: New test source. * testsuite/ld-scripts/script.exp: Run the new test.
-rw-r--r--ld/ChangeLog10
-rw-r--r--ld/ldexp.c4
-rw-r--r--ld/testsuite/ld-scripts/script.exp4
-rw-r--r--ld/testsuite/ld-scripts/segment-start.d19
-rw-r--r--ld/testsuite/ld-scripts/segment-start.ld12
-rw-r--r--ld/testsuite/ld-scripts/segment-start.s2
6 files changed, 50 insertions, 1 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index bda269c..528ba3c 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,13 @@
+2018-09-14 Maciej W. Rozycki <macro@mips.com>
+ Maciej W. Rozycki <macro@linux-mips.org>
+
+ * ldexp.c (fold_binary): Always make the result of SEGMENT_START
+ section-relative.
+ * testsuite/ld-scripts/segment-start.d: New test.
+ * testsuite/ld-scripts/segment-start.ld: New test linker script.
+ * testsuite/ld-scripts/segment-start.s: New test source.
+ * testsuite/ld-scripts/script.exp: Run the new test.
+
2018-09-14 Maciej W. Rozycki <macro@linux-mips.org>
* ldexp.c (fold_binary): Check that `config.maxpagesize' is
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 4b9676e..f6446dc 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -534,6 +534,7 @@ fold_binary (etree_type *tree)
operand, binary.rhs is first operand. */
if (expld.result.valid_p && tree->type.node_code == SEGMENT_START)
{
+ bfd_vma value = expld.result.value;
const char *segment_name;
segment_type *seg;
@@ -551,9 +552,10 @@ fold_binary (etree_type *tree)
"isn't multiple of maximum page size\n"),
segment_name);
seg->used = TRUE;
- new_rel_from_abs (seg->value);
+ value = seg->value;
break;
}
+ new_rel_from_abs (value);
return;
}
diff --git a/ld/testsuite/ld-scripts/script.exp b/ld/testsuite/ld-scripts/script.exp
index 4b781d4..6663633 100644
--- a/ld/testsuite/ld-scripts/script.exp
+++ b/ld/testsuite/ld-scripts/script.exp
@@ -231,3 +231,7 @@ foreach test_script $test_script_list {
run_dump_test "align-with-input"
run_dump_test "pr20302"
+
+run_dump_test "segment-start" {{name (default)}}
+run_dump_test "segment-start" {{name (overridden)} \
+ {ld -Ttext-segment=0x10000000}}
diff --git a/ld/testsuite/ld-scripts/segment-start.d b/ld/testsuite/ld-scripts/segment-start.d
new file mode 100644
index 0000000..fcbcfb3
--- /dev/null
+++ b/ld/testsuite/ld-scripts/segment-start.d
@@ -0,0 +1,19 @@
+#PROG: nm
+#name: SEGMENT_START expression not absolute
+#source: segment-start.s
+#ld: -e 0 -u __executable_start -T segment-start.ld
+#xfail: mmix-*-* pdp11-*-* powerpc-*-aix* powerpc-*-beos* rs6000-*-* sh-*-pe
+#xfail: c30-*-*aout* tic30-*-*aout* c54x*-*-*coff* tic54x-*-*coff*
+# XFAIL targets that are not expected to handle SEGMENT_START correctly.
+
+# Make sure `__executable_start' is regular:
+#
+# 10000000 T __executable_start
+#
+# not absolute:
+#
+# 10000000 A __executable_start
+
+#...
+0*10000000 T __executable_start
+#pass
diff --git a/ld/testsuite/ld-scripts/segment-start.ld b/ld/testsuite/ld-scripts/segment-start.ld
new file mode 100644
index 0000000..6202d19
--- /dev/null
+++ b/ld/testsuite/ld-scripts/segment-start.ld
@@ -0,0 +1,12 @@
+SECTIONS
+{
+ PROVIDE (__executable_start = SEGMENT_START ("text-segment", 0x10000000));
+ .text : { *(.text) }
+ .data : { *(.data) }
+ .bss : { *(.bss) }
+ .loader : { *(.loader) }
+ .symtab : { *(.symtab) }
+ .strtab : { *(.strtab) }
+ .shstrtab : { *(.shstrtab) }
+ /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-scripts/segment-start.s b/ld/testsuite/ld-scripts/segment-start.s
new file mode 100644
index 0000000..5d785b4
--- /dev/null
+++ b/ld/testsuite/ld-scripts/segment-start.s
@@ -0,0 +1,2 @@
+ .text
+ .space 16