X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=ld%2Fldlang.c;h=d43140f06b2fa4970b3833e848110fb1dd2df06f;hb=9af9729377dcf027c06e1bf21f958df2c8907c3c;hp=33dc573c0d7ea26043b5a7c73b424f9960291a12;hpb=9503fd8735ec438fcb2fca34afa276e3e6ca94f5;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/ldlang.c b/ld/ldlang.c index 33dc573c0d..d43140f06b 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1,5 +1,5 @@ /* Linker command language support. - Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999 + Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000 Free Software Foundation, Inc. This file is part of GLD, the Gnu Linker. @@ -58,7 +58,6 @@ static lang_output_section_statement_type *default_common_section; static boolean map_option_f; static bfd_vma print_dot; static lang_input_statement_type *first_file; -static lang_statement_list_type lang_output_section_statement; static CONST char *current_target; static CONST char *output_target; static lang_statement_list_type statement_list; @@ -166,6 +165,7 @@ static char * get_first_input_target PARAMS ((void)); /* EXPORTS */ lang_output_section_statement_type *abs_output_section; +lang_statement_list_type lang_output_section_statement; lang_statement_list_type *stat_ptr = &statement_list; lang_statement_list_type file_chain = { NULL, NULL }; const char *entry_symbol = NULL; @@ -213,17 +213,21 @@ walk_wild_section (ptr, section, file, callback, data) void *data; { /* Don't process sections from files which were excluded. */ - if (ptr->exclude_filename != NULL) + if (ptr->exclude_filename_list != NULL) { - boolean match; + struct name_list *list_tmp; + for (list_tmp = ptr->exclude_filename_list; list_tmp; list_tmp = list_tmp->next) + { + boolean match; - if (wildcardp (ptr->exclude_filename)) - match = fnmatch (ptr->exclude_filename, file->filename, 0) == 0 ? true : false; - else - match = strcmp (ptr->exclude_filename, file->filename) == 0 ? true : false; + if (wildcardp (list_tmp->name)) + match = fnmatch (list_tmp->name, file->filename, 0) == 0 ? true : false; + else + match = strcmp (list_tmp->name, file->filename) == 0 ? true : false; - if (match) - return; + if (match) + return; + } } if (file->just_syms_flag == false) @@ -678,6 +682,7 @@ lang_output_section_statement_lookup (name) lookup = (lang_output_section_statement_type *) new_stat (lang_output_section_statement, stat_ptr); lookup->region = (lang_memory_region_type *) NULL; + lookup->lma_region = (lang_memory_region_type *) NULL; lookup->fill = 0; lookup->block_value = 1; lookup->name = name; @@ -1859,8 +1864,10 @@ open_input_bfds (s, force) /* If we are being called from within a group, and this is an archive which has already been searched, then - force it to be researched. */ + force it to be researched unless the whole archive + has been loaded already. */ if (force + && !s->input_statement.whole_archive && s->input_statement.loaded && bfd_check_format (s->input_statement.the_bfd, bfd_archive)) @@ -2164,7 +2171,8 @@ print_input_section (in) { asection *i = in->section; bfd_size_type size = i->_cooked_size != 0 ? i->_cooked_size : i->_raw_size; - + unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, + ldfile_output_machine); if (size != 0) { print_space (); @@ -2188,7 +2196,7 @@ print_input_section (in) } minfo ("0x%V %W %B\n", - i->output_section->vma + i->output_offset, size, + i->output_section->vma + i->output_offset, size / opb, i->owner); if (i->_cooked_size != 0 && i->_cooked_size != i->_raw_size) @@ -2210,7 +2218,7 @@ print_input_section (in) bfd_link_hash_traverse (link_info.hash, print_one_symbol, (PTR) i); - print_dot = i->output_section->vma + i->output_offset + size; + print_dot = i->output_section->vma + i->output_offset + size / opb; } } } @@ -2230,6 +2238,8 @@ print_data_statement (data) bfd_vma addr; bfd_size_type size; const char *name; + unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, + ldfile_output_machine); for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) print_space (); @@ -2274,7 +2284,8 @@ print_data_statement (data) print_nl (); - print_dot = addr + size; + print_dot = addr + size / opb; + } /* Print an address statement. These are generated by options like @@ -2298,6 +2309,8 @@ print_reloc_statement (reloc) int i; bfd_vma addr; bfd_size_type size; + unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, + ldfile_output_machine); for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) print_space (); @@ -2319,7 +2332,7 @@ print_reloc_statement (reloc) print_nl (); - print_dot = addr + size; + print_dot = addr + size / opb; } static void @@ -2328,6 +2341,8 @@ print_padding_statement (s) { int len; bfd_vma addr; + unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, + ldfile_output_machine); minfo (" *fill*"); @@ -2348,7 +2363,7 @@ print_padding_statement (s) print_nl (); - print_dot = addr + s->size; + print_dot = addr + s->size / opb; } static void @@ -2360,9 +2375,15 @@ print_wild_statement (w, os) if (w->filenames_sorted) minfo ("SORT("); - if (w->exclude_filename != NULL) - minfo ("EXCLUDE_FILE ( %s )", w->exclude_filename); - if (w->filename != NULL) + if (w->exclude_filename_list != NULL) + { + name_list *tmp; + minfo ("EXCLUDE_FILE ( %s", w->exclude_filename_list->name); + for (tmp=w->exclude_filename_list->next; tmp; tmp = tmp->next) + minfo (", %s", tmp->name); + minfo (")"); + } + if (w->filename != NULL) minfo ("%s", w->filename); else minfo ("*"); @@ -2537,6 +2558,8 @@ insert_pad (this_ptr, fill, power, output_section_statement, dot) inserting a magic 'padding' statement. */ + unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, + ldfile_output_machine); unsigned int alignment_needed = align_power (dot, power) - dot; if (alignment_needed != 0) @@ -2553,7 +2576,7 @@ insert_pad (this_ptr, fill, power, output_section_statement, dot) new->padding_statement.output_offset = dot - output_section_statement->vma; new->padding_statement.fill = fill; - new->padding_statement.size = alignment_needed; + new->padding_statement.size = alignment_needed * opb; } @@ -2562,9 +2585,9 @@ insert_pad (this_ptr, fill, power, output_section_statement, dot) { output_section_statement->alignment_power = power; } - output_section_statement->_raw_size += alignment_needed; - return alignment_needed + dot; + output_section_statement->_raw_size += alignment_needed * opb; + return dot + alignment_needed; } /* Work out how much this section will move the dot point */ @@ -2578,6 +2601,8 @@ size_input_section (this_ptr, output_section_statement, fill, dot, relax) { lang_input_section_type *is = &((*this_ptr)->input_section); asection *i = is->section; + unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, + ldfile_output_machine); if (is->ifile->just_syms_flag == false) { @@ -2595,10 +2620,11 @@ size_input_section (this_ptr, output_section_statement, fill, dot, relax) /* Mark how big the output section must be to contain this now */ if (i->_cooked_size != 0) - dot += i->_cooked_size; + dot += i->_cooked_size / opb; else - dot += i->_raw_size; - output_section_statement->bfd_section->_raw_size = dot - output_section_statement->bfd_section->vma; + dot += i->_raw_size / opb; + output_section_statement->bfd_section->_raw_size = + (dot - output_section_statement->bfd_section->vma) * opb; } else { @@ -2608,6 +2634,10 @@ size_input_section (this_ptr, output_section_statement, fill, dot, relax) return dot; } +#define IGNORE_SECTION(bfd, s) \ + (((bfd_get_section_flags (bfd, s) & (SEC_ALLOC | SEC_LOAD)) != (SEC_ALLOC | SEC_LOAD)) \ + || bfd_section_size (bfd, s) == 0) + /* Check to see if any allocated sections overlap with other allocated sections. This can happen when the linker script specifically specifies the output section addresses of the two sections. */ @@ -2615,52 +2645,52 @@ static void lang_check_section_addresses () { asection * s; + unsigned opb = bfd_octets_per_byte (output_bfd); /* Scan all sections in the output list. */ for (s = output_bfd->sections; s != NULL; s = s->next) - /* Ignore sections which are not loaded or which have no contents. */ - if ((bfd_get_section_flags (output_bfd, s) & (SEC_ALLOC | SEC_LOAD)) - && bfd_section_size (output_bfd, s) != 0) - { - asection * os; + { + asection * os; + + /* Ignore sections which are not loaded or which have no contents. */ + if (IGNORE_SECTION (output_bfd, s)) + continue; + + /* Once we reach section 's' stop our seach. This prevents two + warning messages from being produced, one for 'section A overlaps + section B' and one for 'section B overlaps section A'. */ + for (os = output_bfd->sections; os != s; os = os->next) + { + bfd_vma s_start; + bfd_vma s_end; + bfd_vma os_start; + bfd_vma os_end; + + /* Only consider loadable sections with real contents. */ + if (IGNORE_SECTION (output_bfd, os)) + continue; - /* Once we reach section 's' stop our seach. This prevents two - warning messages from being produced, one for 'section A overlaps - section B' and one for 'section B overlaps section A'. */ - for (os = output_bfd->sections; os != s; os = os->next) - { - bfd_vma s_start; - bfd_vma s_end; - bfd_vma os_start; - bfd_vma os_end; - - /* Only consider loadable sections with real contents. */ - if (((bfd_get_section_flags (output_bfd, os) - & (SEC_ALLOC | SEC_LOAD)) == 0) - || bfd_section_size (output_bfd, os) == 0) - continue; - - /* We must check the sections' LMA addresses not their - VMA addresses because overlay sections can have - overlapping VMAs but they must have distinct LMAs. */ - s_start = bfd_section_lma (output_bfd, s); - os_start = bfd_section_lma (output_bfd, os); - s_end = s_start + bfd_section_size (output_bfd, s) - 1; - os_end = os_start + bfd_section_size (output_bfd, os) - 1; - - /* Look for an overlap. */ - if ((s_end < os_start) || (s_start > os_end)) - continue; - - einfo ( + /* We must check the sections' LMA addresses not their + VMA addresses because overlay sections can have + overlapping VMAs but they must have distinct LMAs. */ + s_start = bfd_section_lma (output_bfd, s); + os_start = bfd_section_lma (output_bfd, os); + s_end = s_start + bfd_section_size (output_bfd, s) / opb - 1; + os_end = os_start + bfd_section_size (output_bfd, os) / opb - 1; + + /* Look for an overlap. */ + if ((s_end < os_start) || (s_start > os_end)) + continue; + + einfo ( _("%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"), - s->name, s_start, s_end, os->name, os_start, os_end); - - /* Once we have found one overlap for this section, - stop looking for others. */ - break; - } - } + s->name, s_start, s_end, os->name, os_start, os_end); + + /* Once we have found one overlap for this section, + stop looking for others. */ + break; + } + } } /* This variable indicates whether bfd_relax_section should be called @@ -2668,6 +2698,43 @@ _("%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"), static boolean relax_again; +/* Make sure the new address is within the region. We explicitly permit the + current address to be at the exact end of the region when the address is + non-zero, in case the region is at the end of addressable memory and the + calculation wraps around. */ + +static void +os_region_check (os, region, tree, base) + lang_output_section_statement_type *os; + struct memory_region_struct *region; + etree_type *tree; + bfd_vma base; +{ + if ((region->current < region->origin + || (region->current - region->origin > region->length)) + && ((region->current != region->origin + region->length) + || base == 0)) + { + if (tree != (etree_type *) NULL) + { + 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); + } + else + { + einfo (_("%X%P: region %s is full (%B section %s)\n"), + region->name, + os->bfd_section->owner, + os->bfd_section->name); + } + /* Reset the region pointer. */ + region->current = region->origin; + } +} + /* Set the sizes for all the output sections. */ bfd_vma @@ -2679,6 +2746,9 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) bfd_vma dot; boolean relax; { + unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, + ldfile_output_machine); + /* Size up the sections from their constituent parts. */ for (; s != (lang_statement_union_type *) NULL; s = s->next) { @@ -2792,62 +2862,66 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) (void) lang_size_sections (os->children.head, os, &os->children.head, os->fill, dot, relax); - /* Ignore the size of the input sections, use the vma and size to - align against. */ - - after = ALIGN_N (os->bfd_section->vma + - os->bfd_section->_raw_size, + /* put the section within the requested block size, or align at + the block boundary */ + after = ALIGN_N (os->bfd_section->vma + + os->bfd_section->_raw_size / opb, /* The coercion here is important, see ld.h. */ (bfd_vma) os->block_value); if (bfd_is_abs_section (os->bfd_section)) ASSERT (after == os->bfd_section->vma); else - os->bfd_section->_raw_size = after - os->bfd_section->vma; - dot = os->bfd_section->vma + os->bfd_section->_raw_size; + os->bfd_section->_raw_size = + (after - os->bfd_section->vma) * opb; + dot = os->bfd_section->vma + os->bfd_section->_raw_size / opb; os->processed = true; /* Update dot in the region ? We only do this if the section is going to be allocated, since unallocated sections do not contribute to the region's - overall size in memory. */ + overall size in memory. + + If the SEC_NEVER_LOAD bit is not set, it will affect the + addresses of sections after it. We have to update + dot. */ if (os->region != (lang_memory_region_type *) NULL - && (bfd_get_section_flags (output_bfd, os->bfd_section) - & (SEC_ALLOC | SEC_LOAD))) + && ((bfd_get_section_flags (output_bfd, os->bfd_section) + & SEC_NEVER_LOAD) == 0 + || (bfd_get_section_flags (output_bfd, os->bfd_section) + & (SEC_ALLOC | SEC_LOAD)))) { os->region->current = dot; - /* Make sure the new address is within the region. We - explicitly permit the current address to be at the - exact end of the region when the VMA is non-zero, - in case the region is at the end of addressable - memory and the calculation wraps around. */ - if ((os->region->current < os->region->origin - || (os->region->current - os->region->origin - > os->region->length)) - && ((os->region->current - != os->region->origin + os->region->length) - || os->bfd_section->vma == 0)) - - { - if (os->addr_tree != (etree_type *) NULL) - { - einfo (_("%X%P: address 0x%v of %B section %s is not within region %s\n"), - os->region->current, - os->bfd_section->owner, - os->bfd_section->name, - os->region->name); - } - else - { - einfo (_("%X%P: region %s is full (%B section %s)\n"), - os->region->name, - os->bfd_section->owner, - os->bfd_section->name); - } - /* Reset the region pointer. */ - os->region->current = os->region->origin; - } + /* Make sure the new address is within the region. */ + os_region_check (os, os->region, os->addr_tree, + os->bfd_section->vma); + + /* if there's no load address specified, use the run region as + the load region */ + if (os->lma_region == NULL && os->load_base == NULL) + os->lma_region = os->region; + + if (os->lma_region != NULL) + { + if (os->load_base != NULL) + { + einfo (_("%X%P: use an absolute load address or a load memory region, not both\n")); + } + else + { + /* don't allocate twice */ + if (os->lma_region != os->region) + { + /* set load_base, which will be handled later */ + os->load_base = exp_intop (os->lma_region->current); + os->lma_region->current += + os->bfd_section->_raw_size / opb; + os_region_check (os, os->lma_region, NULL, + os->bfd_section->lma); + } + } + } } } break; @@ -2870,6 +2944,8 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) switch (s->data_statement.type) { + default: + abort(); case QUAD: case SQUAD: size = QUAD_SIZE; @@ -2884,8 +2960,9 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) size = BYTE_SIZE; break; } - - dot += size; + if (size < opb) + size = opb; + dot += size / opb; output_section_statement->bfd_section->_raw_size += size; /* The output section gets contents, and then we inspect for any flags set in the input script which override any ALLOC. */ @@ -2905,7 +2982,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) s->reloc_statement.output_section = output_section_statement->bfd_section; size = bfd_get_reloc_size (s->reloc_statement.howto); - dot += size; + dot += size / opb; output_section_statement->bfd_section->_raw_size += size; } break; @@ -2993,7 +3070,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) new->padding_statement.output_offset = dot - output_section_statement->bfd_section->vma; new->padding_statement.fill = fill; - new->padding_statement.size = newdot - dot; + new->padding_statement.size = (newdot - dot) * opb; output_section_statement->bfd_section->_raw_size += new->padding_statement.size; } @@ -3011,7 +3088,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) pass than it did at this point in the previous pass. */ s->padding_statement.output_offset = dot - output_section_statement->bfd_section->vma; - dot += s->padding_statement.size; + dot += s->padding_statement.size / opb; output_section_statement->bfd_section->_raw_size += s->padding_statement.size; break; @@ -3044,6 +3121,9 @@ lang_do_assignments (s, output_section_statement, fill, dot) fill_type fill; bfd_vma dot; { + unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, + ldfile_output_machine); + for (; s != (lang_statement_union_type *) NULL; s = s->next) { switch (s->header.type) @@ -3065,7 +3145,8 @@ lang_do_assignments (s, output_section_statement, fill, dot) dot = os->bfd_section->vma; (void) lang_do_assignments (os->children.head, os, os->fill, dot); - dot = os->bfd_section->vma + os->bfd_section->_raw_size; + dot = os->bfd_section->vma + os->bfd_section->_raw_size / opb; + } if (os->load_base) { @@ -3105,22 +3186,30 @@ lang_do_assignments (s, output_section_statement, fill, dot) if (value.valid_p == false) einfo (_("%F%P: invalid data statement\n")); } - switch (s->data_statement.type) - { - case QUAD: - case SQUAD: - dot += QUAD_SIZE; - break; - case LONG: - dot += LONG_SIZE; - break; - case SHORT: - dot += SHORT_SIZE; - break; - case BYTE: - dot += BYTE_SIZE; - break; - } + { + unsigned int size; + switch (s->data_statement.type) + { + default: + abort(); + case QUAD: + case SQUAD: + size = QUAD_SIZE; + break; + case LONG: + size = LONG_SIZE; + break; + case SHORT: + size = SHORT_SIZE; + break; + case BYTE: + size = BYTE_SIZE; + break; + } + if (size < opb) + size = opb; + dot += size / opb; + } break; case lang_reloc_statement_enum: @@ -3134,7 +3223,7 @@ lang_do_assignments (s, output_section_statement, fill, dot) if (value.valid_p == false) einfo (_("%F%P: invalid reloc statement\n")); } - dot += bfd_get_reloc_size (s->reloc_statement.howto); + dot += bfd_get_reloc_size (s->reloc_statement.howto) / opb; break; case lang_input_section_enum: @@ -3142,9 +3231,9 @@ lang_do_assignments (s, output_section_statement, fill, dot) asection *in = s->input_section.section; if (in->_cooked_size != 0) - dot += in->_cooked_size; + dot += in->_cooked_size / opb; else - dot += in->_raw_size; + dot += in->_raw_size / opb; } break; @@ -3164,7 +3253,7 @@ lang_do_assignments (s, output_section_statement, fill, dot) break; case lang_padding_statement_enum: - dot += s->padding_statement.size; + dot += s->padding_statement.size / opb; break; case lang_group_statement_enum: @@ -3222,11 +3311,13 @@ lang_set_startof () h = bfd_link_hash_lookup (link_info.hash, buf, false, false, true); if (h != NULL && h->type == bfd_link_hash_undefined) { + unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, + ldfile_output_machine); h->type = bfd_link_hash_defined; if (s->_cooked_size != 0) - h->u.def.value = s->_cooked_size; + h->u.def.value = s->_cooked_size / opb; else - h->u.def.value = s->_raw_size; + h->u.def.value = s->_raw_size / opb; h->u.def.section = bfd_abs_section_ptr; } @@ -3403,6 +3494,8 @@ lang_one_common (h, info) unsigned int power_of_two; bfd_vma size; asection *section; + unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, + ldfile_output_machine); if (h->type != bfd_link_hash_common) return true; @@ -3417,8 +3510,8 @@ lang_one_common (h, info) section = h->u.c.p->section; /* Increase the size of the section. */ - section->_cooked_size = ALIGN_N (section->_cooked_size, - (bfd_size_type) (1 << power_of_two)); + section->_cooked_size = ALIGN_N ((section->_cooked_size + opb - 1) / opb, + (bfd_size_type) (1 << power_of_two)) * opb; /* Adjust the alignment if necessary. */ if (power_of_two > section->alignment_power) @@ -3722,7 +3815,7 @@ topower (x) return 0; } -void +lang_output_section_statement_type * lang_enter_output_section_statement (output_section_statement_name, address_exp, sectype, block_value, align, subalign, ebase) @@ -3770,6 +3863,7 @@ lang_enter_output_section_statement (output_section_statement_name, "section alignment", 0)); os->load_base = ebase; + return os; } @@ -4026,13 +4120,13 @@ lang_process () void lang_add_wild (section_name, sections_sorted, filename, filenames_sorted, - keep_sections, exclude_filename) + keep_sections, exclude_filename_list) const char *const section_name; boolean sections_sorted; const char *const filename; boolean filenames_sorted; boolean keep_sections; - const char *exclude_filename; + struct name_list *exclude_filename_list; { lang_wild_statement_type *new = new_stat (lang_wild_statement, stat_ptr); @@ -4050,7 +4144,7 @@ lang_add_wild (section_name, sections_sorted, filename, filenames_sorted, new->filename = filename; new->filenames_sorted = filenames_sorted; new->keep_sections = keep_sections; - new->exclude_filename = exclude_filename; + new->exclude_filename_list = exclude_filename_list; lang_list_init (&new->children); } @@ -4204,13 +4298,22 @@ lang_float (maybe) } void -lang_leave_output_section_statement (fill, memspec, phdrs) +lang_leave_output_section_statement (fill, memspec, phdrs, lma_memspec) bfd_vma fill; const char *memspec; struct lang_output_section_phdr_list *phdrs; + const char *lma_memspec; { current_section->fill = fill; current_section->region = lang_memory_region_lookup (memspec); + if (strcmp (lma_memspec, "*default*") != 0) + { + current_section->lma_region = lang_memory_region_lookup (lma_memspec); + /* if no runtime region has been given, but the load region has been, + use the load region */ + if (strcmp (memspec, "*default*") == 0) + current_section->region = lang_memory_region_lookup (lma_memspec); + } current_section->phdrs = phdrs; stat_ptr = &statement_list; } @@ -4278,7 +4381,8 @@ lang_abs_symbol_at_end_of (secname, name) h->u.def.value = 0; else h->u.def.value = (bfd_get_section_vma (output_bfd, sec) - + bfd_section_size (output_bfd, sec)); + + bfd_section_size (output_bfd, sec) / + bfd_octets_per_byte (output_bfd)); h->u.def.section = bfd_abs_section_ptr; } @@ -4588,7 +4692,8 @@ lang_leave_overlay_section (fill, phdrs) name = current_section->name; - lang_leave_output_section_statement (fill, "*default*", phdrs); + lang_leave_output_section_statement (fill, "*default*", + phdrs, "*default*"); /* Define the magic symbols. */ @@ -4618,12 +4723,14 @@ lang_leave_overlay_section (fill, phdrs) looks through all the sections in the overlay and sets them. */ void -lang_leave_overlay (fill, memspec, phdrs) +lang_leave_overlay (fill, memspec, phdrs, lma_memspec) bfd_vma fill; const char *memspec; struct lang_output_section_phdr_list *phdrs; + const char *lma_memspec; { lang_memory_region_type *region; + lang_memory_region_type *lma_region; struct overlay_list *l; struct lang_nocrossref *nocrossref; @@ -4632,6 +4739,11 @@ lang_leave_overlay (fill, memspec, phdrs) else region = lang_memory_region_lookup (memspec); + if (lma_memspec == NULL) + lma_region = NULL; + else + lma_region = lang_memory_region_lookup (lma_memspec); + nocrossref = NULL; l = overlay_list; @@ -4643,6 +4755,8 @@ lang_leave_overlay (fill, memspec, phdrs) l->os->fill = fill; if (region != NULL && l->os->region == NULL) l->os->region = region; + if (lma_region != NULL && l->os->lma_region == NULL) + l->os->lma_region = lma_region; if (phdrs != NULL && l->os->phdrs == NULL) l->os->phdrs = phdrs;