aboutsummaryrefslogtreecommitdiff
path: root/ld/ldlang.c
diff options
context:
space:
mode:
authorAndrew Burgess <andrew.burgess@embecosm.com>2017-04-27 18:05:08 +0100
committerAndrew Burgess <andrew.burgess@embecosm.com>2018-01-11 17:35:35 +0000
commiteab62f2f018417121e2520acb0623985b1708b02 (patch)
tree162184cd8ed4f0cf0b634a60d943ecc400818a30 /ld/ldlang.c
parent8be965c5f058f79554ec3376afac994e6e3ad1b7 (diff)
downloadgdb-eab62f2f018417121e2520acb0623985b1708b02.zip
gdb-eab62f2f018417121e2520acb0623985b1708b02.tar.gz
gdb-eab62f2f018417121e2520acb0623985b1708b02.tar.bz2
ld: Fix issue where PROVIDE overrides defined symbol
In a linker script, a sequence like this: foo = ADDR (.some_section); bar = foo; PROVIDE (foo = 0); will result in 'bar = ADDR (.some_section)' and 'foo = 0', which seems like incorrect behaviour, foo is clearly defined elsewhere, and so the PROVIDE should not trigger. The problem is that an expression like this: foo = ADDR (.some_section); can't be evaluated until a late phase of the linker, due to the need for the section '.some_section' to have been placed, then the PROVIDE was being marked as being used during an earlier phase. At the end of the link, both lines: foo = ADDR (.some_section); PROVIDE (foo = 0); are active, and this causes the final value of 'foo' to be 0. The solution proposed in this commit is that, during earlier phases of the linker, when we see the expression 'foo = ADDR (.some_section);', instead of ignoring the expression, we create a "fake" definition of 'foo'. The existence of this "fake" definition prevents the PROVIDE from being marked used, and during the final phase the real definition of 'foo' will replace the "fake" definition. The new test provide-6 covers the exact case described above. The provide-7 test is similar to the above, but using constant expressions, this was never broken, but is added here to increase coverage. The provide-8 case also didn't fail before this commit, but I did manage to break this case during development of this patch. This case was only covered by a mmix test before, so I've added this here to increase coverage. ld/ChangeLog: * ldexp.c (exp_fold_tree_1): Rework condition underwhich provide nodes are ignored in the tree walk, and move the location at which we change provide nodes into provided nodes. (exp_init_os): Add etree_provided. * testsuite/ld-scripts/provide-6.d: New file. * testsuite/ld-scripts/provide-6.t: New file. * testsuite/ld-scripts/provide-7.d: New file. * testsuite/ld-scripts/provide-7.t: New file. * testsuite/ld-scripts/provide-8.d: New file. * testsuite/ld-scripts/provide-8.t: New file.
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r--ld/ldlang.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 294e632..1526d7b 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -2207,6 +2207,7 @@ exp_init_os (etree_type *exp)
{
case etree_assign:
case etree_provide:
+ case etree_provided:
exp_init_os (exp->assign.src);
break;