diff options
author | Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com> | 2015-01-28 15:01:50 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2015-01-28 15:06:48 +1030 |
commit | cc9ad334a71b0c032f711e86885fb73821f3be16 (patch) | |
tree | e721067748cda338595b230ab0557039b65d94f4 /ld/ldlang.c | |
parent | e5fe4957b4513015b40472086f22cf8723b95773 (diff) | |
download | gdb-cc9ad334a71b0c032f711e86885fb73821f3be16.zip gdb-cc9ad334a71b0c032f711e86885fb73821f3be16.tar.gz gdb-cc9ad334a71b0c032f711e86885fb73821f3be16.tar.bz2 |
Allow symbols in MEMORY region specification
This patch fixes PR 4643 by allowing symbols in the LENGTH and ORIGIN
fields of MEMORY regions. Previously, only constants and constant
expressions are allowed.
For the AVR target, this helps define memory constraints more
accurately (per device), without having to create a ton of device
specific linker scripts.
ld/
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.
ld/testsuite/
* 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.
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r-- | ld/ldlang.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c index 3ea22c2..5344e5e 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -85,6 +85,7 @@ static void lang_record_phdrs (void); 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; @@ -1305,7 +1306,9 @@ lang_memory_region_lookup (const char *const name, bfd_boolean create) 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; @@ -6707,6 +6710,8 @@ lang_process (void) /* 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. */ @@ -7970,6 +7975,37 @@ lang_do_version_exports_section (void) 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) { |