forked from Imagelibrary/binutils-gdb
* ldexp.c (fold_name <LOADADDR>): Use the lma.
* ldlang.h (lang_memory_region_type): Delete old_length. Add last_os. * ldlang.c (lang_memory_region_lookup): Init new field. (lang_reset_memory_regions): Reset new field. (lang_insert_orphan): Don't set load_base. (lang_leave_overlay): Likewise. (lang_size_sections_1): Delete unnecessary code setting lma_region to region. Correct lma region check. (lang_do_assignments_1): Rename output_section_statement parm to current_os. Set lma from previous section in region.
This commit is contained in:
120
ld/ldlang.c
120
ld/ldlang.c
@@ -1164,15 +1164,16 @@ lang_memory_region_lookup (const char *const name, bfd_boolean create)
|
||||
|
||||
new->name = xstrdup (name);
|
||||
new->next = NULL;
|
||||
new->origin = 0;
|
||||
new->length = ~(bfd_size_type) 0;
|
||||
new->current = 0;
|
||||
new->last_os = NULL;
|
||||
new->flags = 0;
|
||||
new->not_flags = 0;
|
||||
new->had_full_message = FALSE;
|
||||
|
||||
*lang_memory_region_list_tail = new;
|
||||
lang_memory_region_list_tail = &new->next;
|
||||
new->origin = 0;
|
||||
new->flags = 0;
|
||||
new->not_flags = 0;
|
||||
new->length = ~(bfd_size_type) 0;
|
||||
new->current = 0;
|
||||
new->had_full_message = FALSE;
|
||||
|
||||
return new;
|
||||
}
|
||||
@@ -1462,7 +1463,6 @@ lang_insert_orphan (asection *s,
|
||||
lang_statement_list_type *old;
|
||||
lang_statement_list_type add;
|
||||
const char *ps;
|
||||
etree_type *load_base;
|
||||
lang_output_section_statement_type *os;
|
||||
lang_output_section_statement_type **os_tail;
|
||||
|
||||
@@ -1506,20 +1506,10 @@ lang_insert_orphan (asection *s,
|
||||
if (link_info.relocatable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
|
||||
address = exp_intop (0);
|
||||
|
||||
load_base = NULL;
|
||||
if (after != NULL && after->load_base != NULL)
|
||||
{
|
||||
etree_type *lma_from_vma;
|
||||
lma_from_vma = exp_binop ('-', after->load_base,
|
||||
exp_nameop (ADDR, after->name));
|
||||
load_base = exp_binop ('+', lma_from_vma,
|
||||
exp_nameop (ADDR, secname));
|
||||
}
|
||||
|
||||
os_tail = ((lang_output_section_statement_type **)
|
||||
lang_output_section_statement.tail);
|
||||
os = lang_enter_output_section_statement (secname, address, 0, NULL, NULL,
|
||||
load_base, 0);
|
||||
NULL, 0);
|
||||
|
||||
if (add_child == NULL)
|
||||
add_child = &os->children;
|
||||
@@ -4417,20 +4407,16 @@ lang_size_sections_1
|
||||
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 && 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 +=
|
||||
TO_ADDR (os->bfd_section->size);
|
||||
|
||||
if (check_regions)
|
||||
os_region_check (os, os->lma_region, NULL,
|
||||
os->bfd_section->lma);
|
||||
os->lma_region->current);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4709,11 +4695,10 @@ lang_size_sections (bfd_boolean *relax, bfd_boolean check_regions)
|
||||
/* Worker function for lang_do_assignments. Recursiveness goes here. */
|
||||
|
||||
static bfd_vma
|
||||
lang_do_assignments_1
|
||||
(lang_statement_union_type *s,
|
||||
lang_output_section_statement_type *output_section_statement,
|
||||
fill_type *fill,
|
||||
bfd_vma dot)
|
||||
lang_do_assignments_1 (lang_statement_union_type *s,
|
||||
lang_output_section_statement_type *current_os,
|
||||
fill_type *fill,
|
||||
bfd_vma dot)
|
||||
{
|
||||
for (; s != NULL; s = s->header.next)
|
||||
{
|
||||
@@ -4721,9 +4706,7 @@ lang_do_assignments_1
|
||||
{
|
||||
case lang_constructors_statement_enum:
|
||||
dot = lang_do_assignments_1 (constructor_list.head,
|
||||
output_section_statement,
|
||||
fill,
|
||||
dot);
|
||||
current_os, fill, dot);
|
||||
break;
|
||||
|
||||
case lang_output_section_statement_enum:
|
||||
@@ -4733,22 +4716,61 @@ lang_do_assignments_1
|
||||
os = &(s->output_section_statement);
|
||||
if (os->bfd_section != NULL && !os->ignored)
|
||||
{
|
||||
lang_memory_region_type *r;
|
||||
|
||||
dot = os->bfd_section->vma;
|
||||
lang_do_assignments_1 (os->children.head, os, os->fill, dot);
|
||||
r = os->region;
|
||||
if (r == NULL)
|
||||
r = lang_memory_region_lookup (DEFAULT_MEMORY_REGION, FALSE);
|
||||
|
||||
if (os->load_base)
|
||||
os->bfd_section->lma
|
||||
= exp_get_abs_int (os->load_base, 0, "load base");
|
||||
else if (r->last_os != NULL)
|
||||
{
|
||||
asection *last;
|
||||
bfd_vma lma;
|
||||
|
||||
last = r->last_os->output_section_statement.bfd_section;
|
||||
|
||||
/* If the current vma overlaps the previous section,
|
||||
then set the current lma to that at the end of
|
||||
the previous section. The previous section was
|
||||
probably an overlay. */
|
||||
if ((dot >= last->vma
|
||||
&& dot < last->vma + last->size)
|
||||
|| (last->vma >= dot
|
||||
&& last->vma < dot + os->bfd_section->size))
|
||||
lma = last->lma + last->size;
|
||||
|
||||
/* Otherwise, keep the same lma to vma relationship
|
||||
as the previous section. */
|
||||
else
|
||||
lma = dot + last->lma - last->vma;
|
||||
|
||||
if (os->section_alignment != -1)
|
||||
lma = align_power (lma, os->section_alignment);
|
||||
os->bfd_section->lma = lma;
|
||||
}
|
||||
|
||||
lang_do_assignments_1 (os->children.head,
|
||||
os, os->fill, dot);
|
||||
|
||||
/* .tbss sections effectively have zero size. */
|
||||
if ((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0
|
||||
|| (os->bfd_section->flags & SEC_THREAD_LOCAL) == 0
|
||||
|| link_info.relocatable)
|
||||
dot += TO_ADDR (os->bfd_section->size);
|
||||
}
|
||||
if (os->load_base)
|
||||
{
|
||||
/* If nothing has been placed into the output section then
|
||||
it won't have a bfd_section. */
|
||||
if (os->bfd_section && !os->ignored)
|
||||
{
|
||||
os->bfd_section->lma
|
||||
= exp_get_abs_int (os->load_base, 0, "load base");
|
||||
dot += TO_ADDR (os->bfd_section->size);
|
||||
|
||||
/* Keep track of normal sections using the default
|
||||
lma region. We use this to set the lma for
|
||||
following sections. Overlays or other linker
|
||||
script assignment to lma might mean that the
|
||||
default lma == vma is incorrect. */
|
||||
if (!link_info.relocatable
|
||||
&& os->lma_region == NULL)
|
||||
r->last_os = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4757,8 +4779,7 @@ lang_do_assignments_1
|
||||
case lang_wild_statement_enum:
|
||||
|
||||
dot = lang_do_assignments_1 (s->wild_statement.children.head,
|
||||
output_section_statement,
|
||||
fill, dot);
|
||||
current_os, fill, dot);
|
||||
break;
|
||||
|
||||
case lang_object_symbols_statement_enum:
|
||||
@@ -4827,7 +4848,7 @@ lang_do_assignments_1
|
||||
|
||||
case lang_assignment_statement_enum:
|
||||
exp_fold_tree (s->assignment_statement.exp,
|
||||
output_section_statement->bfd_section,
|
||||
current_os->bfd_section,
|
||||
&dot);
|
||||
break;
|
||||
|
||||
@@ -4837,8 +4858,7 @@ lang_do_assignments_1
|
||||
|
||||
case lang_group_statement_enum:
|
||||
dot = lang_do_assignments_1 (s->group_statement.children.head,
|
||||
output_section_statement,
|
||||
fill, dot);
|
||||
current_os, fill, dot);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -5423,8 +5443,8 @@ lang_reset_memory_regions (void)
|
||||
|
||||
for (p = lang_memory_region_list; p != NULL; p = p->next)
|
||||
{
|
||||
p->old_length = (bfd_size_type) (p->current - p->origin);
|
||||
p->current = p->origin;
|
||||
p->last_os = NULL;
|
||||
}
|
||||
|
||||
for (os = &lang_output_section_statement.head->output_section_statement;
|
||||
@@ -6350,10 +6370,6 @@ lang_leave_overlay (etree_type *lma_expr,
|
||||
an LMA region was specified. */
|
||||
if (l->next == 0)
|
||||
l->os->load_base = lma_expr;
|
||||
else if (lma_region == 0)
|
||||
l->os->load_base = exp_binop ('+',
|
||||
exp_nameop (LOADADDR, l->next->os->name),
|
||||
exp_nameop (SIZEOF, l->next->os->name));
|
||||
|
||||
if (phdrs != NULL && l->os->phdrs == NULL)
|
||||
l->os->phdrs = phdrs;
|
||||
|
||||
Reference in New Issue
Block a user