diff options
author | Nick Clifton <nickc@redhat.com> | 2009-03-02 17:27:36 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2009-03-02 17:27:36 +0000 |
commit | 4a93e18003bc8a90c03a26a27c368fbc5a4e0e84 (patch) | |
tree | 1ade88f5dc05ea6287a283b4e323fc773922b789 /ld/ldlang.c | |
parent | 220df88bffbd9b2acf1d86a744ffae70c9fff248 (diff) | |
download | gdb-4a93e18003bc8a90c03a26a27c368fbc5a4e0e84.zip gdb-4a93e18003bc8a90c03a26a27c368fbc5a4e0e84.tar.gz gdb-4a93e18003bc8a90c03a26a27c368fbc5a4e0e84.tar.bz2 |
* ldgram.y: Add support for REGION_ALIAS operator.
* ldlang.c: Likewise.
* ldlang.h: Likewise.
* ldlex.l: Likewise.
* NEWS: Mention the new feature.
* ld.texinfo: Document the new feature.
* ld-scripts/regions-alias-1.t: New file.
* ld-scripts/regions-alias-2.t: New file.
* ld-scripts/regions-alias-3.t: New file.
* ld-scripts/regions-alias-4.t: New file.
* ld-scripts/script.exp: Run region alias tests.
Diffstat (limited to 'ld/ldlang.c')
-rw-r--r-- | ld/ldlang.c | 101 |
1 files changed, 76 insertions, 25 deletions
diff --git a/ld/ldlang.c b/ld/ldlang.c index cc390b0..9f62e9f 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1205,7 +1205,13 @@ lang_finish (void) In this case it is probably an error to create a region that has already been created. If we are not inside a MEMORY block it is dubious to use an undeclared region name (except DEFAULT_MEMORY_REGION) - and so we issue a warning. */ + and so we issue a warning. + + Each region has at least one name. The first name is either + DEFAULT_MEMORY_REGION or the name given in the MEMORY block. You can add + alias names to an existing region within a script with + REGION_ALIAS (alias, region_name). Each name corresponds to at most one + region. */ static lang_memory_region_type *lang_memory_region_list; static lang_memory_region_type **lang_memory_region_list_tail @@ -1214,28 +1220,31 @@ static lang_memory_region_type **lang_memory_region_list_tail lang_memory_region_type * lang_memory_region_lookup (const char *const name, bfd_boolean create) { - lang_memory_region_type *p; + lang_memory_region_name *n; + lang_memory_region_type *r; lang_memory_region_type *new; /* NAME is NULL for LMA memspecs if no region was specified. */ if (name == NULL) return NULL; - for (p = lang_memory_region_list; p != NULL; p = p->next) - if (strcmp (p->name, name) == 0) - { - if (create) - einfo (_("%P:%S: warning: redeclaration of memory region '%s'\n"), - name); - return p; - } + for (r = lang_memory_region_list; r != NULL; r = r->next) + for (n = &r->name_list; n != NULL; n = n->next) + if (strcmp (n->name, name) == 0) + { + if (create) + einfo (_("%P:%S: warning: redeclaration of memory region `%s'\n"), + name); + return r; + } if (!create && strcmp (name, DEFAULT_MEMORY_REGION)) - einfo (_("%P:%S: warning: memory region %s not declared\n"), name); + einfo (_("%P:%S: warning: memory region `%s' not declared\n"), name); new = stat_alloc (sizeof (lang_memory_region_type)); - new->name = xstrdup (name); + new->name_list.name = xstrdup (name); + new->name_list.next = NULL; new->next = NULL; new->origin = 0; new->length = ~(bfd_size_type) 0; @@ -1251,8 +1260,50 @@ lang_memory_region_lookup (const char *const name, bfd_boolean create) return new; } +void +lang_memory_region_alias (const char * alias, const char * region_name) +{ + lang_memory_region_name * n; + lang_memory_region_type * r; + lang_memory_region_type * region; + + /* The default region must be unique. This ensures that it is not necessary + to iterate through the name list if someone wants the check if a region is + the default memory region. */ + if (strcmp (region_name, DEFAULT_MEMORY_REGION) == 0 + || strcmp (alias, DEFAULT_MEMORY_REGION) == 0) + einfo (_("%F%P:%S: error: alias for default memory region\n")); + + /* Look for the target region and check if the alias is not already + in use. */ + region = NULL; + for (r = lang_memory_region_list; r != NULL; r = r->next) + for (n = &r->name_list; n != NULL; n = n->next) + { + if (region == NULL && strcmp (n->name, region_name) == 0) + region = r; + if (strcmp (n->name, alias) == 0) + einfo (_("%F%P:%S: error: redefinition of memory region " + "alias `%s'\n"), + alias); + } + + /* Check if the target region exists. */ + if (region == NULL) + einfo (_("%F%P:%S: error: memory region `%s' " + "for alias `%s' does not exist\n"), + region_name, + alias); + + /* Add alias to region name list. */ + n = stat_alloc (sizeof (lang_memory_region_name)); + n->name = xstrdup (alias); + n->next = region->name_list.next; + region->name_list.next = n; +} + static lang_memory_region_type * -lang_memory_default (asection *section) +lang_memory_default (asection * section) { lang_memory_region_type *p; @@ -1847,7 +1898,7 @@ lang_map (void) char buf[100]; int len; - fprintf (config.map_file, "%-16s ", m->name); + fprintf (config.map_file, "%-16s ", m->name_list.name); sprintf_vma (buf, m->origin); minfo ("0x%s ", buf); @@ -4462,8 +4513,8 @@ lang_check_section_addresses (void) a bfd_vma quantity in decimal. */ for (m = lang_memory_region_list; m; m = m->next) if (m->had_full_message) - einfo (_("%X%P: region %s overflowed by %ld bytes\n"), - m->name, (long)(m->current - (m->origin + m->length))); + einfo (_("%X%P: region `%s' overflowed by %ld bytes\n"), + m->name_list.name, (long)(m->current - (m->origin + m->length))); } @@ -4485,21 +4536,21 @@ os_region_check (lang_output_section_statement_type *os, { if (tree != NULL) { - einfo (_("%X%P: address 0x%v of %B section %s" - " is not within region %s\n"), + einfo (_("%X%P: address 0x%v of %B section `%s'" + " is not within region `%s'\n"), region->current, os->bfd_section->owner, os->bfd_section->name, - region->name); + region->name_list.name); } else if (!region->had_full_message) { region->had_full_message = TRUE; - einfo (_("%X%P: %B section %s will not fit in region %s\n"), + einfo (_("%X%P: %B section `%s' will not fit in region `%s'\n"), os->bfd_section->owner, os->bfd_section->name, - region->name); + region->name_list.name); } } } @@ -4588,8 +4639,8 @@ lang_size_sections_1 from the region specification. */ if (os->region == NULL || ((os->bfd_section->flags & (SEC_ALLOC | SEC_LOAD)) - && os->region->name[0] == '*' - && strcmp (os->region->name, + && os->region->name_list.name[0] == '*' + && strcmp (os->region->name_list.name, DEFAULT_MEMORY_REGION) == 0)) { os->region = lang_memory_default (os->bfd_section); @@ -4602,10 +4653,10 @@ lang_size_sections_1 && !IGNORE_SECTION (os->bfd_section) && ! link_info.relocatable && check_regions - && strcmp (os->region->name, + && strcmp (os->region->name_list.name, DEFAULT_MEMORY_REGION) == 0 && lang_memory_region_list != NULL - && (strcmp (lang_memory_region_list->name, + && (strcmp (lang_memory_region_list->name_list.name, DEFAULT_MEMORY_REGION) != 0 || lang_memory_region_list->next != NULL) && expld.phase != lang_mark_phase_enum) |