* ldlang.h (lang_output_section_statement_type): Add update_dot_tree.

(lang_enter_overlay): Remove the last two parameters.
	(lang_leave_overlay): Take them here instead.
	* ldgram.y (memspec_at_opt): Set $$ to null if no region is given.
	(section): Pass LMA and crossref flag to lang_leave_overlay rather
	than lang_enter_overlay.
	* ldlang.c (lang_memory_region_lookup): Return null for null names.
	(lang_output_section_statement_lookup): Initialize update_dot_tree.
	(lang_size_sections_1): Evaluate it.
	(lang_leave_output_section_statement): Rework LMA lookup.
	(overlay_lma, overlay_nocrossrefs): Remove.
	(lang_enter_overlay): Remove LMA and corssref arguments.
	(lang_enter_overlay_section): Don't set the LMA here.
	(lang_leave_overlay): Take LMA and crossref arguments.  Move the '.'
	assignment to the last section's update_dot_tree.  Unconditionally
	use the load and run-time regions specified in the OVERLAY statement.
	Likewise the first section's LMA.  Only set the other sections' LMAs
	when no load region is given.
This commit is contained in:
Richard Sandiford 2002-05-07 11:04:54 +00:00
parent 010f3b2f35
commit 9f88b410a0
4 changed files with 86 additions and 77 deletions

View file

@ -1,3 +1,24 @@
2002-05-07 Richard Sandiford <rsandifo@redhat.com>
* ldlang.h (lang_output_section_statement_type): Add update_dot_tree.
(lang_enter_overlay): Remove the last two parameters.
(lang_leave_overlay): Take them here instead.
* ldgram.y (memspec_at_opt): Set $$ to null if no region is given.
(section): Pass LMA and crossref flag to lang_leave_overlay rather
than lang_enter_overlay.
* ldlang.c (lang_memory_region_lookup): Return null for null names.
(lang_output_section_statement_lookup): Initialize update_dot_tree.
(lang_size_sections_1): Evaluate it.
(lang_leave_output_section_statement): Rework LMA lookup.
(overlay_lma, overlay_nocrossrefs): Remove.
(lang_enter_overlay): Remove LMA and corssref arguments.
(lang_enter_overlay_section): Don't set the LMA here.
(lang_leave_overlay): Take LMA and crossref arguments. Move the '.'
assignment to the last section's update_dot_tree. Unconditionally
use the load and run-time regions specified in the OVERLAY statement.
Likewise the first section's LMA. Only set the other sections' LMAs
when no load region is given.
2002-05-06 Nick Clifton <nickc@redhat.com>
* po/sv.po: New translation.

View file

@ -820,7 +820,7 @@ exp :
memspec_at_opt:
AT '>' NAME { $$ = $3; }
| { $$ = "*default*"; }
| { $$ = 0; }
;
opt_at:
@ -851,7 +851,7 @@ section: NAME { ldlex_expression(); }
{ ldlex_popstate (); ldlex_script (); }
'{'
{
lang_enter_overlay ($3, $5, (int) $4);
lang_enter_overlay ($3);
}
overlay_section
'}'
@ -859,7 +859,8 @@ section: NAME { ldlex_expression(); }
memspec_opt memspec_at_opt phdr_opt fill_opt
{
ldlex_popstate ();
lang_leave_overlay ($15, $12, $14, $13);
lang_leave_overlay ($5, (int) $4,
$15, $12, $14, $13);
}
opt_comma
| /* The GROUP case is just enough to support the gcc

View file

@ -617,6 +617,10 @@ lang_memory_region_lookup (name)
{
lang_memory_region_type *p;
/* NAME is NULL for LMA memspecs if no region was specified. */
if (name == NULL)
return NULL;
for (p = lang_memory_region_list;
p != (lang_memory_region_type *) NULL;
p = p->next)
@ -738,6 +742,7 @@ lang_output_section_statement_lookup (name)
lookup->subsection_alignment = -1;
lookup->section_alignment = -1;
lookup->load_base = (union etree_union *) NULL;
lookup->update_dot_tree = NULL;
lookup->phdrs = NULL;
lang_statement_append (&lang_output_section_statement,
@ -3009,9 +3014,14 @@ lang_size_sections_1 (s, output_section_statement, prev, fill, dot, relax)
else
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;
if (os->update_dot_tree != 0)
exp_fold_tree (os->update_dot_tree, abs_output_section,
lang_allocating_phase_enum, dot, &dot);
/* 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
@ -4514,14 +4524,13 @@ lang_leave_output_section_statement (fill, memspec, phdrs, 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->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 (current_section->lma_region != 0 && strcmp (memspec, "*default*") == 0)
current_section->region = current_section->lma_region;
current_section->phdrs = phdrs;
stat_ptr = &statement_list;
}
@ -4803,12 +4812,6 @@ lang_add_nocrossref (l)
/* The overlay virtual address. */
static etree_type *overlay_vma;
/* The overlay load address. */
static etree_type *overlay_lma;
/* Whether nocrossrefs is set for this overlay. */
static int overlay_nocrossrefs;
/* An expression for the maximum section size seen so far. */
static etree_type *overlay_max;
@ -4824,24 +4827,18 @@ static struct overlay_list *overlay_list;
/* Start handling an overlay. */
void
lang_enter_overlay (vma_expr, lma_expr, nocrossrefs)
lang_enter_overlay (vma_expr)
etree_type *vma_expr;
etree_type *lma_expr;
int nocrossrefs;
{
/* The grammar should prevent nested overlays from occurring. */
ASSERT (overlay_vma == NULL
&& overlay_lma == NULL
&& overlay_list == NULL
&& overlay_max == NULL);
ASSERT (overlay_vma == NULL && overlay_max == NULL);
overlay_vma = vma_expr;
overlay_lma = lma_expr;
overlay_nocrossrefs = nocrossrefs;
}
/* Start a section in an overlay. We handle this by calling
lang_enter_output_section_statement with the correct VMA and LMA. */
lang_enter_output_section_statement with the correct VMA.
lang_leave_overlay sets up the LMA and memory regions. */
void
lang_enter_overlay_section (name)
@ -4851,16 +4848,13 @@ lang_enter_overlay_section (name)
etree_type *size;
lang_enter_output_section_statement (name, overlay_vma, normal_section,
0, 0, 0, overlay_lma);
0, 0, 0, 0);
/* If this is the first section, then base the VMA and LMA of future
/* If this is the first section, then base the VMA of future
sections on this one. This will work correctly even if `.' is
used in the addresses. */
if (overlay_list == NULL)
{
overlay_vma = exp_nameop (ADDR, name);
overlay_lma = exp_nameop (LOADADDR, name);
}
overlay_vma = exp_nameop (ADDR, name);
/* Remember the section. */
n = (struct overlay_list *) xmalloc (sizeof *n);
@ -4870,9 +4864,6 @@ lang_enter_overlay_section (name)
size = exp_nameop (SIZEOF, name);
/* Adjust the LMA for the next section. */
overlay_lma = exp_binop ('+', overlay_lma, size);
/* Arrange to work out the maximum section end address. */
if (overlay_max == NULL)
overlay_max = size;
@ -4895,8 +4886,10 @@ lang_leave_overlay_section (fill, phdrs)
name = current_section->name;
lang_leave_output_section_statement (fill, "*default*",
phdrs, "*default*");
/* For now, assume that "*default*" is the run-time memory region and
that no load-time region has been specified. It doesn't really
matter what we say here, since lang_leave_overlay will override it. */
lang_leave_output_section_statement (fill, "*default*", phdrs, 0);
/* Define the magic symbols. */
@ -4926,32 +4919,30 @@ lang_leave_overlay_section (fill, phdrs)
looks through all the sections in the overlay and sets them. */
void
lang_leave_overlay (fill, memspec, phdrs, lma_memspec)
lang_leave_overlay (lma_expr, nocrossrefs, fill, memspec, phdrs, lma_memspec)
etree_type *lma_expr;
int nocrossrefs;
fill_type *fill;
const char *memspec;
struct lang_output_section_phdr_list *phdrs;
const char *lma_memspec;
{
lang_memory_region_type *region;
lang_memory_region_type *default_region;
lang_memory_region_type *lma_region;
struct overlay_list *l;
struct lang_nocrossref *nocrossref;
default_region = lang_memory_region_lookup ("*default*");
if (memspec == NULL)
region = NULL;
else
region = lang_memory_region_lookup (memspec);
if (lma_memspec == NULL)
lma_region = NULL;
else
lma_region = lang_memory_region_lookup (lma_memspec);
region = lang_memory_region_lookup (memspec);
lma_region = lang_memory_region_lookup (lma_memspec);
nocrossref = NULL;
/* After setting the size of the last section, set '.' to end of the
overlay region. */
if (overlay_list != NULL)
overlay_list->os->update_dot_tree
= exp_assop ('=', ".", exp_binop ('+', overlay_vma, overlay_max));
l = overlay_list;
while (l != NULL)
{
@ -4960,28 +4951,24 @@ lang_leave_overlay (fill, memspec, phdrs, lma_memspec)
if (fill != (fill_type *) 0 && l->os->fill == (fill_type *) 0)
l->os->fill = fill;
/* Assign a region to the sections, if one has been specified.
Override the assignment of the default section, but not
other sections. */
if (region != NULL &&
(l->os->region == NULL ||
l->os->region == default_region))
l->os->region = region;
l->os->region = region;
l->os->lma_region = lma_region;
/* We only set lma_region for the first overlay section, as
subsequent overlay sections will have load_base set relative
to the first section. Also, don't set lma_region if
load_base is specified. FIXME: There should really be a test
that `AT ( LDADDR )' doesn't conflict with `AT >LMA_REGION'
rather than letting LDADDR simply override LMA_REGION. */
if (lma_region != NULL && l->os->lma_region == NULL
&& l->next == NULL && l->os->load_base == NULL)
l->os->lma_region = lma_region;
/* The first section has the load address specified in the
OVERLAY statement. The rest are worked out from that.
The base address is not needed (and should be null) if
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;
if (overlay_nocrossrefs)
if (nocrossrefs)
{
struct lang_nocrossref *nc;
@ -4999,13 +4986,7 @@ lang_leave_overlay (fill, memspec, phdrs, lma_memspec)
if (nocrossref != NULL)
lang_add_nocrossref (nocrossref);
/* Update . for the end of the overlay. */
lang_add_assignment (exp_assop ('=', ".",
exp_binop ('+', overlay_vma, overlay_max)));
overlay_vma = NULL;
overlay_lma = NULL;
overlay_nocrossrefs = 0;
overlay_list = NULL;
overlay_max = NULL;
}

View file

@ -135,6 +135,12 @@ typedef struct lang_output_section_statement_struct {
union etree_union *load_base;
/* If non-null, an expression to evaluate after setting the section's
size. The expression is evaluated inside REGION (above) with '.'
set to the end of the section. Used in the last overlay section
to move '.' past all the overlaid sections. */
union etree_union *update_dot_tree;
struct lang_output_section_phdr_list *phdrs;
} lang_output_section_statement_type;
@ -456,13 +462,13 @@ extern void lang_new_phdr
PARAMS ((const char *, etree_type *, boolean, boolean, etree_type *,
etree_type *));
extern void lang_add_nocrossref PARAMS ((struct lang_nocrossref *));
extern void lang_enter_overlay PARAMS ((etree_type *, etree_type *, int));
extern void lang_enter_overlay PARAMS ((etree_type *));
extern void lang_enter_overlay_section PARAMS ((const char *));
extern void lang_leave_overlay_section
PARAMS ((fill_type *, struct lang_output_section_phdr_list *));
extern void lang_leave_overlay
PARAMS ((fill_type *, const char *, struct lang_output_section_phdr_list *,
const char *));
PARAMS ((etree_type *, int, fill_type *, const char *,
struct lang_output_section_phdr_list *, const char *));
extern struct bfd_elf_version_tree *lang_elf_version_info;