diff options
-rw-r--r-- | ld/ChangeLog | 13 | ||||
-rw-r--r-- | ld/ldexp.c | 55 | ||||
-rw-r--r-- | ld/ldexp.h | 9 | ||||
-rw-r--r-- | ld/ldlang.c | 3 | ||||
-rw-r--r-- | ld/testsuite/ChangeLog | 13 | ||||
-rw-r--r-- | ld/testsuite/ld-elf/provide-hidden-2.ld | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-mips-elf/gp-hidden.sd | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-mips-elf/no-shared-1-n32.d | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-mips-elf/no-shared-1-n64.d | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-mips-elf/no-shared-1-o32.d | 2 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/expr.exp | 7 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/pr18963.d | 15 | ||||
-rw-r--r-- | ld/testsuite/ld-scripts/pr18963.t | 25 |
13 files changed, 142 insertions, 8 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog index 6369d99..96359f5 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,16 @@ +2015-09-18 Alan Modra <amodra@gmail.com> + + PR ld/18963 + * ldexp.h (struct ldexp_control): Add rel_from_abs. + (ldexp_finalize_syms): Declare. + * ldexp.c (new_rel_from_abs): Keep absolute for expressions + outside of output section statements. Set rel_from_abs. + (make_abs, exp_fold_tree, exp_fold_tree_no_dot): Clear rel_from_abs. + (struct definedness_hash_entry): Add final_sec, and comment. + (update_definedness): Set final_sec. + (set_sym_sections, ldexp_finalize_syms): New functions. + * ldlang.c (lang_process): Call ldexp_finalize_syms. + 2015-09-10 Nick Clifton <nickc@redhat.com> * po/zh_CN.po: Updated simplified Chinese translation. @@ -49,13 +49,25 @@ segment_type *segments; struct ldexp_control expld; /* This structure records symbols for which we need to keep track of - definedness for use in the DEFINED () test. */ + definedness for use in the DEFINED () test. It is also used in + making absolute symbols section relative late in the link. */ struct definedness_hash_entry { struct bfd_hash_entry root; + + /* If this symbol was assigned from "dot" outside of an output + section statement, the section we'd like it relative to. */ + asection *final_sec; + + /* Symbol was defined by an object file. */ unsigned int by_object : 1; + + /* Symbols was defined by a script. */ unsigned int by_script : 1; + + /* Low bit of iteration count. Symbols with matching iteration have + been defined in this pass over the script. */ unsigned int iteration : 1; }; @@ -174,6 +186,7 @@ make_abs (void) if (expld.result.section != NULL) expld.result.value += expld.result.section->vma; expld.result.section = bfd_abs_section_ptr; + expld.rel_from_abs = FALSE; } static void @@ -249,8 +262,7 @@ new_rel_from_abs (bfd_vma value) { asection *s = expld.section; - if (s == bfd_abs_section_ptr && expld.phase == lang_final_phase_enum) - s = section_for_dot (); + expld.rel_from_abs = TRUE; expld.result.valid_p = TRUE; expld.result.value = value - s->vma; expld.result.str = NULL; @@ -322,6 +334,11 @@ update_definedness (const char *name, struct bfd_link_hash_entry *h) defentry->by_script = 1; defentry->iteration = lang_statement_iteration; + defentry->final_sec = bfd_abs_section_ptr; + if (expld.phase == lang_final_phase_enum + && expld.rel_from_abs + && expld.result.section == bfd_abs_section_ptr) + defentry->final_sec = section_for_dot (); return ret; } @@ -1189,6 +1206,7 @@ exp_fold_tree_1 (etree_type *tree) void exp_fold_tree (etree_type *tree, asection *current_section, bfd_vma *dotp) { + expld.rel_from_abs = FALSE; expld.dot = *dotp; expld.dotp = dotp; expld.section = current_section; @@ -1198,6 +1216,7 @@ exp_fold_tree (etree_type *tree, asection *current_section, bfd_vma *dotp) void exp_fold_tree_no_dot (etree_type *tree) { + expld.rel_from_abs = FALSE; expld.dot = 0; expld.dotp = NULL; expld.section = bfd_abs_section_ptr; @@ -1581,6 +1600,36 @@ ldexp_init (void) einfo (_("%P%F: can not create hash table: %E\n")); } +/* Convert absolute symbols defined by a script from "dot" (also + SEGMENT_START or ORIGIN) outside of an output section statement, + to section relative. */ + +static bfd_boolean +set_sym_sections (struct bfd_hash_entry *bh, void *inf ATTRIBUTE_UNUSED) +{ + struct definedness_hash_entry *def = (struct definedness_hash_entry *) bh; + if (def->final_sec != bfd_abs_section_ptr) + { + struct bfd_link_hash_entry *h; + h = bfd_link_hash_lookup (link_info.hash, bh->string, + FALSE, FALSE, TRUE); + if (h != NULL + && h->type == bfd_link_hash_defined + && h->u.def.section == bfd_abs_section_ptr) + { + h->u.def.value -= def->final_sec->vma; + h->u.def.section = def->final_sec; + } + } + return TRUE; +} + +void +ldexp_finalize_syms (void) +{ + bfd_hash_traverse (&definedness_table, set_sym_sections, NULL); +} + void ldexp_finish (void) { @@ -138,6 +138,14 @@ struct ldexp_control { /* Principally used for diagnostics. */ bfd_boolean assigning_to_dot; + + /* Set if the current expression used "dot", SEGMENT_START or + ORIGIN, but not ABSOLUTE or combined symbols in a way that forces + an absolute result. Used in tracking symbols assigned from dot + outside of output section statements, in order to later convert + them from absolute. */ + bfd_boolean rel_from_abs; + /* If evaluating an assignment, the destination. Cleared if an etree_name NAME matches this, to signal a self-assignment. Note that an etree_name DEFINED does not clear this field, nor @@ -222,6 +230,7 @@ fill_type *exp_get_fill bfd_vma exp_get_abs_int (etree_type *, int, char *); void ldexp_init (void); +void ldexp_finalize_syms (void); void ldexp_finish (void); #endif diff --git a/ld/ldlang.c b/ld/ldlang.c index 3d2cc99..2986981 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -6882,6 +6882,9 @@ lang_process (void) ldemul_finish (); + /* Convert absolute symbols to section relative. */ + ldexp_finalize_syms (); + /* Make sure that the section addresses make sense. */ if (command_line.check_section_addresses) lang_check_section_addresses (); diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 9629dda..575d048 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,16 @@ +2015-09-18 Alan Modra <amodra@gmail.com> + + PR ld/18963 + * ld-scripts/pr18963.d, + * ld-scripts/pr18963.t: New test. + * ld-scripts/expr.exp: Run it. + * ld-elf/provide-hidden-2.ld: Explicitly make "dot" absolute. + * ld-mips-elf/gp-hidden.sd: Don't care about _gp section. + * ld-mips-elf/no-shared-1-n32.d: Don't care about symbol shown at + start of .data section. + * ld-mips-elf/no-shared-1-n64.d: Likewise. + * ld-mips-elf/no-shared-1-o32.d: Likewise. + 2015-09-11 H.J. Lu <hongjiu.lu@intel.com> * ld-plugin/lto.exp (lto_link_tests): Add a "ld -r" test for diff --git a/ld/testsuite/ld-elf/provide-hidden-2.ld b/ld/testsuite/ld-elf/provide-hidden-2.ld index 0b04c49..17e526b 100644 --- a/ld/testsuite/ld-elf/provide-hidden-2.ld +++ b/ld/testsuite/ld-elf/provide-hidden-2.ld @@ -1,7 +1,7 @@ SECTIONS { . = 0x12300000; - PROVIDE_HIDDEN (foo = . + 0x11100000); + PROVIDE_HIDDEN (foo = ABSOLUTE (.) + 0x11100000); .data : { *(.data) } .got : { *(.got) } .interp : { *(.interp) } diff --git a/ld/testsuite/ld-mips-elf/gp-hidden.sd b/ld/testsuite/ld-mips-elf/gp-hidden.sd index 2e9cfbf..620eb9a 100644 --- a/ld/testsuite/ld-mips-elf/gp-hidden.sd +++ b/ld/testsuite/ld-mips-elf/gp-hidden.sd @@ -5,5 +5,5 @@ Symbol table '.dynsym' contains [0-9]+ entries: Symbol table '.symtab' contains [0-9]+ entries: * Num: * Value * Size * Type * Bind * Vis * Ndx * Name #... - * [0-9a-f]+: * [0-9a-f]+ * 0 * NOTYPE * LOCAL * DEFAULT * ABS * _gp + * [0-9a-f]+: * [0-9a-f]+ * 0 * NOTYPE * LOCAL * DEFAULT .* _gp #pass diff --git a/ld/testsuite/ld-mips-elf/no-shared-1-n32.d b/ld/testsuite/ld-mips-elf/no-shared-1-n32.d index 04c466e..6a55008 100644 --- a/ld/testsuite/ld-mips-elf/no-shared-1-n32.d +++ b/ld/testsuite/ld-mips-elf/no-shared-1-n32.d @@ -16,7 +16,7 @@ Disassembly of section \.text: #... Disassembly of section \.data: -00060000 <\.data>: +00060000 .*: 60000: 00068000 .* #... Disassembly of section \.got: diff --git a/ld/testsuite/ld-mips-elf/no-shared-1-n64.d b/ld/testsuite/ld-mips-elf/no-shared-1-n64.d index 0c91921..5813b30 100644 --- a/ld/testsuite/ld-mips-elf/no-shared-1-n64.d +++ b/ld/testsuite/ld-mips-elf/no-shared-1-n64.d @@ -15,7 +15,7 @@ Disassembly of section \.text: #... Disassembly of section \.data: -0000000000060000 <\.data>: +0000000000060000 .*: 60000: 00000000 .* 60004: 00068000 .* #... diff --git a/ld/testsuite/ld-mips-elf/no-shared-1-o32.d b/ld/testsuite/ld-mips-elf/no-shared-1-o32.d index b67737f..53bac9e 100644 --- a/ld/testsuite/ld-mips-elf/no-shared-1-o32.d +++ b/ld/testsuite/ld-mips-elf/no-shared-1-o32.d @@ -15,7 +15,7 @@ Disassembly of section \.text: #... Disassembly of section \.data: -00060000 <\.data>: +00060000 .*: 60000: 00068000 .* #... Disassembly of section \.got: diff --git a/ld/testsuite/ld-scripts/expr.exp b/ld/testsuite/ld-scripts/expr.exp index 85242ed..babbf43 100644 --- a/ld/testsuite/ld-scripts/expr.exp +++ b/ld/testsuite/ld-scripts/expr.exp @@ -25,3 +25,10 @@ run_dump_test sane1 run_dump_test assign-loc run_dump_test pr14962 run_dump_test pr14962-2 + +set old_ldflags $LDFLAGS +if { [istarget spu*-*-*] } { + set LDFLAGS "$LDFLAGS --no-overlays --local-store 0:0" +} +run_dump_test pr18963 +set LDFLAGS $old_ldflags diff --git a/ld/testsuite/ld-scripts/pr18963.d b/ld/testsuite/ld-scripts/pr18963.d new file mode 100644 index 0000000..699db59 --- /dev/null +++ b/ld/testsuite/ld-scripts/pr18963.d @@ -0,0 +1,15 @@ +# source: data.s +# ld: -T pr18963.t +# nm: -B -n + +#... +0+70000 A D +#... +0+70000 A E +#... +0+80000 T A +#... +0+90000 T B +#... +0+a0000 D C +#pass diff --git a/ld/testsuite/ld-scripts/pr18963.t b/ld/testsuite/ld-scripts/pr18963.t new file mode 100644 index 0000000..b0cd742 --- /dev/null +++ b/ld/testsuite/ld-scripts/pr18963.t @@ -0,0 +1,25 @@ +SECTIONS +{ + . = 0x80000; + A = .; + .text : + { + _start = .; + . = 0x10000; + } + B = .; + .data : + { + . = 0x10000; + } + C = .; + .bss : + { + . = 0x10000; + } + D = A - C + B; + E = A + B - C; + /DISCARD/ : {*(*)} +} + +ASSERT(D == E, "Addition is not commutative"); |