diff options
-rw-r--r-- | ld/ChangeLog | 13 | ||||
-rw-r--r-- | ld/ldexp.c | 88 | ||||
-rw-r--r-- | ld/ldlang.c | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/provide-6.d | 9 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/provide-6.t | 11 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/provide-7.d | 8 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/provide-7.t | 11 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/provide-8.d | 8 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/provide-8.t | 14 |
9 files changed, 121 insertions, 42 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index f96517e..956a856 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,5 +1,18 @@ 2018-01-11 Andrew Burgess <andrew.burgess@embecosm.com> + * 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. + +2018-01-11 Andrew Burgess <andrew.burgess@embecosm.com> + * testsuite/ld-scripts/provide-3.d: Add xfail directive. * testsuite/ld-scripts/provide-4.d: Use new map file name. * testsuite/ld-scripts/provide-5.d: Use new map file name. @@ -1153,13 +1153,12 @@ exp_fold_tree_1 (etree_type *tree) 2) Section relative symbol values cannot be correctly converted to absolute values, as is required by many expressions, until final section sizing is complete. */ - if ((expld.result.valid_p - && (expld.phase == lang_final_phase_enum - || expld.assign_name != NULL)) - || (expld.phase <= lang_mark_phase_enum - && tree->type.node_class == etree_assign - && tree->assign.defsym)) + if (expld.phase == lang_final_phase_enum + || expld.assign_name != NULL) { + if (tree->type.node_class == etree_provide) + tree->type.node_class = etree_provided; + if (h == NULL) { h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst, @@ -1169,44 +1168,49 @@ exp_fold_tree_1 (etree_type *tree) tree->assign.dst); } - if (expld.result.section == NULL) - expld.result.section = expld.section; - if (!update_definedness (tree->assign.dst, h) && 0) + /* If the expression is not valid then fake a zero value. In + the final phase any errors will already have been raised, + in earlier phases we want to create this definition so + that it can be seen by other expressions. */ + if (!expld.result.valid_p + && h->type == bfd_link_hash_new) + { + expld.result.value = 0; + expld.result.section = NULL; + expld.result.valid_p = TRUE; + } + + if (expld.result.valid_p) { - /* Symbol was already defined. For now this error - is disabled because it causes failures in the ld - testsuite: ld-elf/var1, ld-scripts/defined5, and - ld-scripts/pr14962. Some of these no doubt - reflect scripts used in the wild. */ - (*link_info.callbacks->multiple_definition) - (&link_info, h, link_info.output_bfd, - expld.result.section, expld.result.value); + if (expld.result.section == NULL) + expld.result.section = expld.section; + if (!update_definedness (tree->assign.dst, h) && 0) + { + /* Symbol was already defined. For now this error + is disabled because it causes failures in the ld + testsuite: ld-elf/var1, ld-scripts/defined5, and + ld-scripts/pr14962. Some of these no doubt + reflect scripts used in the wild. */ + (*link_info.callbacks->multiple_definition) + (&link_info, h, link_info.output_bfd, + expld.result.section, expld.result.value); + } + h->type = bfd_link_hash_defined; + h->u.def.value = expld.result.value; + h->u.def.section = expld.result.section; + h->linker_def = ! tree->assign.type.lineno; + h->ldscript_def = 1; + + /* Copy the symbol type if this is an expression only + referencing a single symbol. (If the expression + contains ternary conditions, ignoring symbols on + false branches.) */ + if (expld.assign_src != NULL + && (expld.assign_src + != (struct bfd_link_hash_entry *) 0 - 1)) + bfd_copy_link_hash_symbol_type (link_info.output_bfd, h, + expld.assign_src); } - h->type = bfd_link_hash_defined; - h->u.def.value = expld.result.value; - h->u.def.section = expld.result.section; - h->linker_def = ! tree->assign.type.lineno; - h->ldscript_def = 1; - if (tree->type.node_class == etree_provide) - tree->type.node_class = etree_provided; - - /* Copy the symbol type if this is an expression only - referencing a single symbol. (If the expression - contains ternary conditions, ignoring symbols on - false branches.) */ - if (expld.result.valid_p - && expld.assign_src != NULL - && expld.assign_src != (struct bfd_link_hash_entry *) 0 - 1) - bfd_copy_link_hash_symbol_type (link_info.output_bfd, h, - expld.assign_src); - } - else if (expld.phase == lang_final_phase_enum) - { - h = bfd_link_hash_lookup (link_info.hash, tree->assign.dst, - FALSE, FALSE, TRUE); - if (h != NULL - && h->type == bfd_link_hash_new) - h->type = bfd_link_hash_undefined; } expld.assign_name = NULL; } 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; diff --git a/ld/testsuite/ld-scripts/provide-6.d b/ld/testsuite/ld-scripts/provide-6.d new file mode 100644 index 0000000..dd40515 --- /dev/null +++ b/ld/testsuite/ld-scripts/provide-6.d @@ -0,0 +1,9 @@ +#source: provide-5.s +#ld: -T provide-6.t +#PROG: nm +#xfail: x86_64-*-cygwin + +#... +0+1000 D foo +0+1000 D foo_2 +#... diff --git a/ld/testsuite/ld-scripts/provide-6.t b/ld/testsuite/ld-scripts/provide-6.t new file mode 100644 index 0000000..6b5d11c --- /dev/null +++ b/ld/testsuite/ld-scripts/provide-6.t @@ -0,0 +1,11 @@ +SECTIONS +{ + .data 0x1000 : + { + *(.data) + } + + foo = ADDR (.data); + foo_2 = foo; + PROVIDE (foo = 0x20); +} diff --git a/ld/testsuite/ld-scripts/provide-7.d b/ld/testsuite/ld-scripts/provide-7.d new file mode 100644 index 0000000..c524fe4 --- /dev/null +++ b/ld/testsuite/ld-scripts/provide-7.d @@ -0,0 +1,8 @@ +#source: provide-5.s +#ld: -T provide-7.t +#PROG: nm + +#... +0+10 A foo +0+10 A foo_2 +#... diff --git a/ld/testsuite/ld-scripts/provide-7.t b/ld/testsuite/ld-scripts/provide-7.t new file mode 100644 index 0000000..882883e --- /dev/null +++ b/ld/testsuite/ld-scripts/provide-7.t @@ -0,0 +1,11 @@ +SECTIONS +{ + .data 0x1000 : + { + *(.data) + } + + foo = 0x10; + foo_2 = foo; + PROVIDE (foo = 0x20); +} diff --git a/ld/testsuite/ld-scripts/provide-8.d b/ld/testsuite/ld-scripts/provide-8.d new file mode 100644 index 0000000..a402937 --- /dev/null +++ b/ld/testsuite/ld-scripts/provide-8.d @@ -0,0 +1,8 @@ +#source: provide-5.s +#ld: -T provide-8.t +#PROG: nm +#xfail: x86_64-*-cygwin mmix-*-* sh-*-pe spu-*-* + +#... +0+4000 D __FOO +#... diff --git a/ld/testsuite/ld-scripts/provide-8.t b/ld/testsuite/ld-scripts/provide-8.t new file mode 100644 index 0000000..ffc3467 --- /dev/null +++ b/ld/testsuite/ld-scripts/provide-8.t @@ -0,0 +1,14 @@ +SECTIONS +{ + .data 0x1000 : + { + *(.data) + QUAD (__FOO); + } + + .foo 0x4000 : + { + PROVIDE (__FOO = .); + *(.foo) + } +} |