From 6057dc97e4df5ca9692ddd948798eaa543c74cc7 Mon Sep 17 00:00:00 2001 From: "Maciej W. Rozycki" Date: Fri, 14 Sep 2018 20:22:56 +0100 Subject: [PATCH] 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. --- ld/ChangeLog | 10 ++++++++++ ld/ldexp.c | 4 +++- ld/testsuite/ld-scripts/script.exp | 4 ++++ ld/testsuite/ld-scripts/segment-start.d | 19 +++++++++++++++++++ ld/testsuite/ld-scripts/segment-start.ld | 12 ++++++++++++ ld/testsuite/ld-scripts/segment-start.s | 2 ++ 6 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 ld/testsuite/ld-scripts/segment-start.d create mode 100644 ld/testsuite/ld-scripts/segment-start.ld create mode 100644 ld/testsuite/ld-scripts/segment-start.s diff --git a/ld/ChangeLog b/ld/ChangeLog index bda269c5a84..528ba3c255c 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,13 @@ +2018-09-14 Maciej W. Rozycki + Maciej W. Rozycki + + * 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 * ldexp.c (fold_binary): Check that `config.maxpagesize' is diff --git a/ld/ldexp.c b/ld/ldexp.c index 4b9676ecbab..f6446dcd202 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 4b781d4d386..6663633627f 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 00000000000..fcbcfb3ab98 --- /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 00000000000..6202d1950ec --- /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 00000000000..5d785b4fb28 --- /dev/null +++ b/ld/testsuite/ld-scripts/segment-start.s @@ -0,0 +1,2 @@ + .text + .space 16 -- 2.30.2