aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ld/ChangeLog13
-rw-r--r--ld/ldexp.c55
-rw-r--r--ld/ldexp.h9
-rw-r--r--ld/ldlang.c3
-rw-r--r--ld/testsuite/ChangeLog13
-rw-r--r--ld/testsuite/ld-elf/provide-hidden-2.ld2
-rw-r--r--ld/testsuite/ld-mips-elf/gp-hidden.sd2
-rw-r--r--ld/testsuite/ld-mips-elf/no-shared-1-n32.d2
-rw-r--r--ld/testsuite/ld-mips-elf/no-shared-1-n64.d2
-rw-r--r--ld/testsuite/ld-mips-elf/no-shared-1-o32.d2
-rw-r--r--ld/testsuite/ld-scripts/expr.exp7
-rw-r--r--ld/testsuite/ld-scripts/pr18963.d15
-rw-r--r--ld/testsuite/ld-scripts/pr18963.t25
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.
diff --git a/ld/ldexp.c b/ld/ldexp.c
index 1140881..b7b6e6c 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -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)
{
diff --git a/ld/ldexp.h b/ld/ldexp.h
index f61df6b..bea8045 100644
--- a/ld/ldexp.h
+++ b/ld/ldexp.h
@@ -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");