+2015-01-28 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
+
+ PR 4643
+ * ldexp.c (fold_name): Fold LENGTH only after
+ lang_first_phase_enum.
+ * ldgram.y (memory_spec): Don't evaluate ORIGIN and LENGTH
+ rightaway.
+ * ldlang.h (struct memory_region_struct): Add origin_exp and
+ length_exp fields.
+ * ldlang.c (lang_do_memory_regions): New.
+ (lang_memory_region_lookup): Initialize origin_exp and
+ length_exp fields.
+ (lang_process): Call lang_do_memory_regions.
+
2015-01-20 Andrew Burgess <andrew.burgess@embecosm.com>
* ldlang.c (print_assignment): Only evaluate the expression for a
case LENGTH:
{
- lang_memory_region_type *mem;
-
- mem = lang_memory_region_lookup (tree->name.name, FALSE);
- if (mem != NULL)
- new_number (mem->length);
- else
- einfo (_("%F%S: undefined MEMORY region `%s'"
- " referenced in expression\n"),
- tree, tree->name.name);
+ if (expld.phase != lang_first_phase_enum)
+ {
+ lang_memory_region_type *mem;
+
+ mem = lang_memory_region_lookup (tree->name.name, FALSE);
+ if (mem != NULL)
+ new_number (mem->length);
+ else
+ einfo (_("%F%S: undefined MEMORY region `%s'"
+ " referenced in expression\n"),
+ tree, tree->name.name);
+ }
}
break;
origin_spec:
ORIGIN '=' mustbe_exp
{
- region->origin = exp_get_vma ($3, 0, "origin");
+ region->origin_exp = $3;
region->current = region->origin;
}
;
length_spec:
LENGTH '=' mustbe_exp
{
- region->length = exp_get_vma ($3, -1, "length");
+ region->length_exp = $3;
}
;
static void lang_do_version_exports_section (void);
static void lang_finalize_version_expr_head
(struct bfd_elf_version_expr_head *);
+static void lang_do_memory_regions (void);
/* Exported variables. */
const char *output_target;
new_region->name_list.name = xstrdup (name);
new_region->name_list.next = NULL;
new_region->next = NULL;
+ new_region->origin_exp = NULL;
new_region->origin = 0;
+ new_region->length_exp = NULL;
new_region->length = ~(bfd_size_type) 0;
new_region->current = 0;
new_region->last_os = NULL;
/* PR 13683: We must rerun the assignments prior to running garbage
collection in order to make sure that all symbol aliases are resolved. */
lang_do_assignments (lang_mark_phase_enum);
+
+ lang_do_memory_regions();
expld.phase = lang_first_phase_enum;
/* Size up the common data. */
lang_new_vers_node (greg, lreg), NULL);
}
+/* Evaluate LENGTH and ORIGIN parts of MEMORY spec */
+
+static void
+lang_do_memory_regions (void)
+{
+ lang_memory_region_type *r = lang_memory_region_list;
+
+ for (; r != NULL; r = r->next)
+ {
+ if (r->origin_exp)
+ {
+ exp_fold_tree_no_dot (r->origin_exp);
+ if (expld.result.valid_p)
+ {
+ r->origin = expld.result.value;
+ r->current = r->origin;
+ }
+ else
+ einfo (_("%F%P: invalid origin for memory region %s\n"), r->name_list.name);
+ }
+ if (r->length_exp)
+ {
+ exp_fold_tree_no_dot (r->length_exp);
+ if (expld.result.valid_p)
+ r->length = expld.result.value;
+ else
+ einfo (_("%F%P: invalid length for memory region %s\n"), r->name_list.name);
+ }
+ }
+}
+
void
lang_add_unique (const char *name)
{
{
lang_memory_region_name name_list;
struct memory_region_struct *next;
+ union etree_union *origin_exp;
bfd_vma origin;
bfd_size_type length;
+ union etree_union *length_exp;
bfd_vma current;
union lang_statement_union *last_os;
flagword flags;
+2015-01-28 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
+
+ * ld-scripts/memory.t: Define new symbol tred.
+ * ld-scripts/memory_sym.t: New.
+ * ld-scripts/script.exp: Perform MEMORY with symbols test, and
+ conditionally check values of linker symbols.
+
2015-01-20 Andrew Burgess <andrew.burgess@embecosm.com>
* ld-scripts/provide-4-map.d: Update expected output.
data_end = .;
} >DATAMEM
- fred = ORIGIN(DATAMEM) + LENGTH(DATAMEM);
+ fred = ORIGIN(DATAMEM) + LENGTH(DATAMEM);
+ tred = ORIGIN(TEXTMEM) + LENGTH(TEXTMEM);
}
--- /dev/null
+TXT_ORIGIN = 0x100;
+TXT_LENGTH = 32K;
+MEMORY
+{
+ R_TEXTMEM (ARX) : ORIGIN = TXT_ORIGIN, LENGTH = TXT_LENGTH
+ R_DATAMEM (AW) : org = DATA_ORIGIN, l = DATA_LENGTH
+}
+
+REGION_ALIAS ("A_TEXTMEM", R_TEXTMEM);
+REGION_ALIAS ("A_DATAMEM", R_DATAMEM);
+
+REGION_ALIAS ("TEXTMEM", A_TEXTMEM);
+REGION_ALIAS ("DATAMEM", A_DATAMEM);
+
+SECTIONS
+{
+ . = 0;
+ .text :
+ {
+ text_start = ORIGIN (TEXTMEM);
+ *(.text)
+ *(.pr)
+ text_end = .;
+ } > TEXTMEM
+
+ data_start = ORIGIN (DATAMEM);
+ .data :
+ {
+ *(.data)
+ *(.rw)
+ data_end = .;
+ } >DATAMEM
+
+ fred = ORIGIN(DATAMEM) + LENGTH(DATAMEM);
+ tred = ORIGIN(TEXTMEM) + LENGTH(TEXTMEM);
+}
set passes 0
}
+ if {[info exists nm_output(tred)] \
+ && $nm_output(tred) != (0x100 + 0x8000)} {
+ send_log "tred == $nm_output(tred)\n"
+ verbose "tred == $nm_output(tred)"
+ set passes 0
+ }
+
if {$nm_output(text_end) < $text_end \
|| $nm_output(text_end) > 0x110} {
send_log "text_end == $nm_output(text_end)\n"
set passes 0
}
+ if {[info exists nm_output(fred)] \
+ && $nm_output(fred) != (0x1000 + 0x10000)} {
+ send_log "fred == $nm_output(fred)\n"
+ verbose "fred == $nm_output(fred)"
+ set passes 0
+ }
+
if {$nm_output(data_end) < $data_end \
|| $nm_output(data_end) > 0x1010} {
send_log "data_end == $nm_output(data_end)\n"
check_script
}
+set testname "MEMORY with symbols"
+if ![ld_simple_link $ld tmpdir/script "$flags -defsym DATA_ORIGIN=0x1000 -defsym DATA_LENGTH=0x10000 -T $srcdir/$subdir/memory_sym.t tmpdir/script.o"] {
+ fail $testname
+} else {
+ check_script
+}
+
set test_script_list [lsort [glob $srcdir/$subdir/region-alias-*.t]]
foreach test_script $test_script_list {