X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=ld%2Fldlang.c;h=d40ff07a5b339dcd89422dada5e11e589f84d6f6;hb=4e277b380845ab7bb7090b7a71122e7efe1903e5;hp=10e41c247f872e74e3b692719879191bcd1f01ea;hpb=32edc927faea39b1f7be4654f6ffa03f3e6b16ce;p=deliverable%2Fbinutils-gdb.git diff --git a/ld/ldlang.c b/ld/ldlang.c index 10e41c247f..d40ff07a5b 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -682,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; @@ -2168,8 +2169,8 @@ print_input_section (in) { asection *i = in->section; bfd_size_type size = i->_cooked_size != 0 ? i->_cooked_size : i->_raw_size; - int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, - ldfile_output_machine); + unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, + ldfile_output_machine); if (size != 0) { print_space (); @@ -2235,8 +2236,8 @@ print_data_statement (data) bfd_vma addr; bfd_size_type size; const char *name; - int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, - ldfile_output_machine); + 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 (); @@ -2306,8 +2307,8 @@ print_reloc_statement (reloc) int i; bfd_vma addr; bfd_size_type size; - int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, - ldfile_output_machine); + 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 (); @@ -2338,8 +2339,8 @@ print_padding_statement (s) { int len; bfd_vma addr; - int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, - ldfile_output_machine); + unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, + ldfile_output_machine); minfo (" *fill*"); @@ -2555,8 +2556,8 @@ insert_pad (this_ptr, fill, power, output_section_statement, dot) inserting a magic 'padding' statement. */ - int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, - ldfile_output_machine); + 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) @@ -2598,8 +2599,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; - int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, - ldfile_output_machine); + unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, + ldfile_output_machine); if (is->ifile->just_syms_flag == false) { @@ -2642,7 +2643,7 @@ static void lang_check_section_addresses () { asection * s; - int opb = bfd_octets_per_byte (output_bfd); + 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) @@ -2672,8 +2673,8 @@ lang_check_section_addresses () 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; + 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)) @@ -2695,6 +2696,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 @@ -2706,8 +2744,8 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) bfd_vma dot; boolean relax; { - int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, - ldfile_output_machine); + 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) @@ -2853,37 +2891,35 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax) { 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; @@ -2906,6 +2942,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; @@ -3081,8 +3119,8 @@ lang_do_assignments (s, output_section_statement, fill, dot) fill_type fill; bfd_vma dot; { - int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, - ldfile_output_machine); + unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, + ldfile_output_machine); for (; s != (lang_statement_union_type *) NULL; s = s->next) { @@ -3147,9 +3185,11 @@ lang_do_assignments (s, output_section_statement, fill, dot) einfo (_("%F%P: invalid data statement\n")); } { - int size; + unsigned int size; switch (s->data_statement.type) { + default: + abort(); case QUAD: case SQUAD: size = QUAD_SIZE; @@ -3269,8 +3309,8 @@ lang_set_startof () h = bfd_link_hash_lookup (link_info.hash, buf, false, false, true); if (h != NULL && h->type == bfd_link_hash_undefined) { - int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, - ldfile_output_machine); + 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 / opb; @@ -3452,8 +3492,8 @@ lang_one_common (h, info) unsigned int power_of_two; bfd_vma size; asection *section; - int opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, - ldfile_output_machine); + unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, + ldfile_output_machine); if (h->type != bfd_link_hash_common) return true; @@ -4255,13 +4295,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; } @@ -4640,7 +4689,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. */ @@ -4670,12 +4720,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; @@ -4684,6 +4736,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; @@ -4695,6 +4752,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;