* ldlang.h: add new field "loadable" to output_section_statement.

* ldlang.c (lang_output_section_statement_lookup): initilize new
	field. (wild_doit): if new field is not set, then stop output
	section from being loadable.
	(lang_enter_output_section_statement): set the field from the
	NOLOAD keyword
	* ldgram.y: new synax for NOLOAD. Removes a shift/reduce too.
	* h8300hms.sc-sh, h8300hms.em: get -r right.
This commit is contained in:
Steve Chamberlain
1992-08-07 19:34:59 +00:00
parent f6492282df
commit ae475b39b2
5 changed files with 339 additions and 264 deletions

View File

@ -1,3 +1,14 @@
Fri Aug 7 12:31:10 1992 Steve Chamberlain (sac@thepub.cygnus.com)
* ldlang.h: add new field "loadable" to output_section_statement.
* ldlang.c (lang_output_section_statement_lookup): initilize new
field. (wild_doit): if new field is not set, then stop output
section from being loadable.
(lang_enter_output_section_statement): set the field from the
NOLOAD keyword
* ldgram.y: new synax for NOLOAD. Removes a shift/reduce too.
* h8300hms.sc-sh, h8300hms.em: get -r right.
Thu Aug 6 18:35:21 1992 Per Bothner (bothner@rtl.cygnus.com) Thu Aug 6 18:35:21 1992 Per Bothner (bothner@rtl.cygnus.com)
* ldint.texinfo: New internals manual (beginnings thereof). * ldint.texinfo: New internals manual (beginnings thereof).

View File

@ -53,10 +53,10 @@ static char *h8300hms_script =
#include "h8300hms.x" #include "h8300hms.x"
; ;
static char *h8300hms_script_option_Ur = static char *h8300hms_script_option_Ur =
#include "h8300hms.x" #include "h8300hms.xu"
; ;
static char *h8300hms_script_option_r = static char *h8300hms_script_option_r =
#include "h8300hms.x" #include "h8300hms.xr"
; ;
static char *h8300hms_get_script() static char *h8300hms_get_script()

View File

@ -16,23 +16,23 @@ SECTIONS
{ {
*(.text) *(.text)
*(.strings) *(.strings)
_etext = .; ${RELOCATING+ _etext = . ; }
} ${RELOCATING+ > ram} } ${RELOCATING+ > ram}
.data : .data :
{ {
*(.data) *(.data)
_edata = .; ${RELOCATING+ _edata = . ; }
} ${RELOCATING+ > ram} } ${RELOCATING+ > ram}
.bss : .bss :
{ {
${RELOCATING+ _bss_start = .}; ${RELOCATING+ _bss_start = . ;}
*(.bss) *(.bss)
*(COMMON) *(COMMON)
${RELOCATING+ _end = .}; ${RELOCATING+ _end = . ; }
} ${RELOCATING+ >ram} } ${RELOCATING+ >ram}
.stack : .stack :
{ {
_stack = .; ${RELOCATING+ _stack = . ; }
*(.stack) *(.stack)
} ${RELOCATING+ > topram} } ${RELOCATING+ > topram}
} }

View File

@ -299,7 +299,7 @@ command_line_option:
{ lang_add_input_file($1,lang_input_file_is_file_enum, { lang_add_input_file($1,lang_input_file_is_file_enum,
(char *)NULL); } (char *)NULL); }
| OPTION_c filename | OPTION_c filename
{ ldfile_open_command_file($2); } mri_script_file END { ldlex_command()}; { ldfile_open_command_file($2); } mri_script_file END { ldlex_command();}
| OPTION_Tfile | OPTION_Tfile
{ ldfile_open_command_file($1); } script_file { ldfile_open_command_file($1); } script_file
@ -327,7 +327,7 @@ END { ldlex_command();}
lang_add_assignment(exp_assop($4,$3,$5)); lang_add_assignment(exp_assop($4,$3,$5));
} }
| '-' NAME | '-' NAME
{ info("%P%F Unrecognised option -%s\n", $2); } { info("%P%F Unrecognized option -%s\n", $2); }
| '{' script_file '}' | '{' script_file '}'
; ;
@ -747,6 +747,8 @@ exp :
{ $$ = exp_nameop(SIZEOF,$3); } { $$ = exp_nameop(SIZEOF,$3); }
| ADDR '(' NAME ')' | ADDR '(' NAME ')'
{ $$ = exp_nameop(ADDR,$3); } { $$ = exp_nameop(ADDR,$3); }
| ABSOLUTE '(' exp ')'
{ $$ = exp_unop(ABSOLUTE, $3); }
| ALIGN_K '(' exp ')' | ALIGN_K '(' exp ')'
{ $$ = exp_unop(ALIGN_K,$3); } { $$ = exp_unop(ALIGN_K,$3); }
| NAME | NAME
@ -772,11 +774,11 @@ opt_comma
; ;
opt_type: opt_type:
'(' NOLOAD ')' { $$ = SEC_NO_FLAGS; } NOLOAD { $$ = SEC_NEVER_LOAD; }
| '(' DSECT ')' { $$ = 0; } | DSECT { $$ = 0; }
| '(' COPY ')' { $$ = 0; } | COPY { $$ = 0; }
| '(' INFO ')' { $$ = 0; } | INFO { $$ = 0; }
| '(' OVERLAY ')' { $$ = 0; } | OVERLAY { $$ = 0; }
| { $$ = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; } | { $$ = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS; }
; ;

View File

@ -16,10 +16,6 @@ You should have received a copy of the GNU General Public License
along with GLD; see the file COPYING. If not, write to along with GLD; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* $Id$
*
*/
#include "bfd.h" #include "bfd.h"
#include "sysdep.h" #include "sysdep.h"
@ -459,6 +455,7 @@ DEFUN (lang_output_section_statement_lookup, (name),
lookup->next = (lang_statement_union_type *) NULL; lookup->next = (lang_statement_union_type *) NULL;
lookup->bfd_section = (asection *) NULL; lookup->bfd_section = (asection *) NULL;
lookup->processed = false; lookup->processed = false;
lookup->loadable = 1;
lookup->addr_tree = (etree_type *) NULL; lookup->addr_tree = (etree_type *) NULL;
lang_list_init (&lookup->children); lang_list_init (&lookup->children);
@ -485,7 +482,7 @@ DEFUN (print_flags, (ignore_flags),
if (flags->flag_loadable) if (flags->flag_loadable)
fprintf (outfile, "L"); fprintf (outfile, "L");
#endif #endif
fprintf (config.map_file, ")"); fprintf (config.map_file, ")");
} }
void void
@ -497,7 +494,9 @@ DEFUN_VOID (lang_map)
#ifdef HOST_64_BIT #ifdef HOST_64_BIT
fprintf (config.map_file, "name\t\torigin\t\tlength\t\tattributes\n"); fprintf (config.map_file, "name\t\torigin\t\tlength\t\tattributes\n");
#else #else
fprintf (config.map_file, "name\t\torigin length\t\tattributes\n"); fprintf (config.map_file,
"name\t\torigin length r_size c_size is attributes\n");
#endif #endif
for (m = lang_memory_region_list; for (m = lang_memory_region_list;
m != (lang_memory_region_type *) NULL; m != (lang_memory_region_type *) NULL;
@ -508,6 +507,12 @@ DEFUN_VOID (lang_map)
print_space (); print_space ();
print_address (m->length); print_address (m->length);
print_space (); print_space ();
print_address (m->old_length);
print_space();
print_address (m->current - m->origin);
print_space();
if (m->old_length)
fprintf(config.map_file," %2d%% ", ( m->current - m->origin) * 100 / m->old_length);
print_flags (&m->flags); print_flags (&m->flags);
fprintf (config.map_file, "\n"); fprintf (config.map_file, "\n");
} }
@ -540,7 +545,7 @@ DEFUN (init_os, (s),
output_bfd->xvec->name, s->name); output_bfd->xvec->name, s->name);
} }
s->bfd_section->output_section = s->bfd_section; s->bfd_section->output_section = s->bfd_section;
/* s->bfd_section->flags = s->flags;*/ /* s->bfd_section->flags = s->flags;*/
/* We initialize an output sections output offset to minus its own */ /* We initialize an output sections output offset to minus its own */
/* vma to allow us to output a section through itself */ /* vma to allow us to output a section through itself */
@ -571,25 +576,30 @@ DEFUN (wild_doit, (ptr, section, output, file),
lang_input_statement_type * file) lang_input_statement_type * file)
{ {
if (output->bfd_section == (asection *) NULL) if (output->bfd_section == (asection *) NULL)
{ {
init_os (output); init_os (output);
} }
if (section != (asection *) NULL if (section != (asection *) NULL
&& section->output_section == (asection *) NULL) && section->output_section == (asection *) NULL)
{ {
/* Add a section reference to the list */ /* Add a section reference to the list */
lang_input_section_type *new = new_stat (lang_input_section, ptr); lang_input_section_type *new = new_stat (lang_input_section, ptr);
new->section = section; new->section = section;
new->ifile = file; new->ifile = file;
section->output_section = output->bfd_section; section->output_section = output->bfd_section;
section->output_section->flags |= section->flags; section->output_section->flags |= section->flags;
if (section->alignment_power > output->bfd_section->alignment_power) if (!output->loadable)
{ {
output->bfd_section->alignment_power = section->alignment_power; /* Turn of load flag */
} output->bfd_section->flags &= ~SEC_LOAD;
} }
if (section->alignment_power > output->bfd_section->alignment_power)
{
output->bfd_section->alignment_power = section->alignment_power;
}
}
} }
static asection * static asection *
@ -721,30 +731,30 @@ DEFUN (open_output, (name),
bfd *output; bfd *output;
if (output_target == (char *) NULL) if (output_target == (char *) NULL)
{ {
if (current_target != (char *) NULL) if (current_target != (char *) NULL)
output_target = current_target; output_target = current_target;
else else
output_target = default_target; output_target = default_target;
} }
output = bfd_openw (name, output_target); output = bfd_openw (name, output_target);
output_filename = name; output_filename = name;
if (output == (bfd *) NULL) if (output == (bfd *) NULL)
{
if (bfd_error == invalid_target)
{ {
einfo ("%P%F target %s not found\n", output_target); if (bfd_error == invalid_target)
{
einfo ("%P%F target %s not found\n", output_target);
}
einfo ("%P%F problem opening output file %s, %E", name);
} }
einfo ("%P%F problem opening output file %s, %E", name);
}
/* output->flags |= D_PAGED;*/ /* output->flags |= D_PAGED;*/
bfd_set_format (output, bfd_object); bfd_set_format (output, bfd_object);
bfd_set_arch_mach(output, bfd_set_arch_mach (output,
ldfile_output_architecture, ldfile_output_architecture,
ldfile_output_machine); ldfile_output_machine);
return output; return output;
} }
@ -1009,7 +1019,9 @@ DEFUN (print_output_section_statement, (output_section_statement),
print_space (); print_space ();
print_address (section->vma); print_address (section->vma);
print_space (); print_space ();
print_size (bfd_get_section_size_before_reloc (section)); print_size (section->_raw_size);
print_space();
print_size(section->_cooked_size);
print_space (); print_space ();
print_alignment (section->alignment_power); print_alignment (section->alignment_power);
print_space (); print_space ();
@ -1112,7 +1124,9 @@ DEFUN (print_input_section, (in),
{ {
print_address (i->output_section->vma + i->output_offset); print_address (i->output_section->vma + i->output_offset);
fprintf (config.map_file, " "); fprintf (config.map_file, " ");
print_size (size); print_size (i->_raw_size);
fprintf (config.map_file, " ");
print_size(i->_cooked_size);
fprintf (config.map_file, " "); fprintf (config.map_file, " ");
print_alignment (i->alignment_power); print_alignment (i->alignment_power);
fprintf (config.map_file, " "); fprintf (config.map_file, " ");
@ -1141,20 +1155,20 @@ DEFUN (print_input_section, (in),
/* Find all the symbols in this file defined in this section */ /* Find all the symbols in this file defined in this section */
if (in->ifile->symbol_count) if (in->ifile->symbol_count)
{ {
asymbol **p; asymbol **p;
for (p = in->ifile->asymbols; *p; p++) for (p = in->ifile->asymbols; *p; p++)
{ {
asymbol *q = *p; asymbol *q = *p;
if (bfd_get_section (q) == i && q->flags & BSF_GLOBAL) if (bfd_get_section (q) == i && q->flags & BSF_GLOBAL)
{ {
print_symbol (q); print_symbol (q);
} }
} }
} }
} }
else else
{ {
@ -1382,11 +1396,13 @@ DEFUN (insert_pad, (this_ptr, fill, power, output_section_statement, dot),
/* Work out how much this section will move the dot point */ /* Work out how much this section will move the dot point */
static bfd_vma static bfd_vma
DEFUN (size_input_section, (this_ptr, output_section_statement, fill, dot), DEFUN (size_input_section, (this_ptr, output_section_statement, fill,
dot, relax),
lang_statement_union_type ** this_ptr AND lang_statement_union_type ** this_ptr AND
lang_output_section_statement_type * output_section_statement AND lang_output_section_statement_type * output_section_statement AND
unsigned short fill AND unsigned short fill AND
bfd_vma dot) bfd_vma dot AND
boolean relax)
{ {
lang_input_section_type *is = &((*this_ptr)->input_section); lang_input_section_type *is = &((*this_ptr)->input_section);
asection *i = is->section; asection *i = is->section;
@ -1410,10 +1426,17 @@ DEFUN (size_input_section, (this_ptr, output_section_statement, fill, dot),
i->output_offset = dot - output_section_statement->bfd_section->vma; i->output_offset = dot - output_section_statement->bfd_section->vma;
/* Mark how big the output section must be to contain this now */ /* Mark how big the output section must be to contain this now
dot += bfd_get_section_size_before_reloc (i); */
output_section_statement->bfd_section->_raw_size = if (relax)
dot - output_section_statement->bfd_section->vma; {
dot += i->_cooked_size;
}
else
{
dot += i->_raw_size;
}
output_section_statement->bfd_section->_raw_size = dot - output_section_statement->bfd_section->vma;
} }
else else
{ {
@ -1441,213 +1464,219 @@ DEFUN (lang_size_sections, (s, output_section_statement, prev, fill,
{ {
/* Size up the sections from their constituent parts */ /* Size up the sections from their constituent parts */
for (; s != (lang_statement_union_type *) NULL; s = s->next) for (; s != (lang_statement_union_type *) NULL; s = s->next)
{
switch (s->header.type)
{ {
switch (s->header.type)
{
case lang_output_section_statement_enum: case lang_output_section_statement_enum:
{ {
bfd_vma after; bfd_vma after;
lang_output_section_statement_type *os = &s->output_section_statement; lang_output_section_statement_type *os = &s->output_section_statement;
if (os->bfd_section == &bfd_abs_section) if (os->bfd_section == &bfd_abs_section)
{ {
/* No matter what happens, an abs section starts at zero */ /* No matter what happens, an abs section starts at zero */
bfd_set_section_vma (0, os->bfd_section, 0); bfd_set_section_vma (0, os->bfd_section, 0);
} }
else else
{ {
if (os->addr_tree == (etree_type *) NULL) if (os->addr_tree == (etree_type *) NULL)
{ {
/* No address specified for this section, get one /* No address specified for this section, get one
from the region specification from the region specification
*/ */
if (os->region == (lang_memory_region_type *) NULL) if (os->region == (lang_memory_region_type *) NULL)
{ {
os->region = lang_memory_region_lookup ("*default*"); os->region = lang_memory_region_lookup ("*default*");
} }
dot = os->region->current; dot = os->region->current;
} }
else else
{ {
etree_value_type r; etree_value_type r;
r = exp_fold_tree (os->addr_tree, r = exp_fold_tree (os->addr_tree,
abs_output_section, abs_output_section,
lang_allocating_phase_enum, lang_allocating_phase_enum,
dot, &dot); dot, &dot);
if (r.valid == false) if (r.valid == false)
{ {
einfo ("%F%S: non constant address expression for section %s\n", einfo ("%F%S: non constant address expression for section %s\n",
os->name); os->name);
} }
dot = r.value; dot = r.value;
} }
/* The section starts here */ /* The section starts here */
/* First, align to what the section needs */ /* First, align to what the section needs */
dot = align_power (dot, os->bfd_section->alignment_power); dot = align_power (dot, os->bfd_section->alignment_power);
bfd_set_section_vma (0, os->bfd_section, dot); bfd_set_section_vma (0, os->bfd_section, dot);
} }
os->bfd_section->output_offset = 0; os->bfd_section->output_offset = 0;
(void) lang_size_sections (os->children.head, os, &os->children.head, (void) lang_size_sections (os->children.head, os, &os->children.head,
os->fill, dot, relax); os->fill, dot, relax);
/* Ignore the size of the input sections, use the vma and size to */ /* Ignore the size of the input sections, use the vma and size to */
/* align against */ /* align against */
after = ALIGN (os->bfd_section->vma + after = ALIGN (os->bfd_section->vma +
os->bfd_section->_raw_size, os->bfd_section->_raw_size,
os->block_value); os->block_value);
os->bfd_section->_raw_size = after - os->bfd_section->vma; os->bfd_section->_raw_size = after - os->bfd_section->vma;
dot = os->bfd_section->vma + os->bfd_section->_raw_size; dot = os->bfd_section->vma + os->bfd_section->_raw_size;
os->processed = true; os->processed = true;
/* Replace into region ? */ /* Replace into region ? */
if (os->addr_tree == (etree_type *) NULL if (os->addr_tree == (etree_type *) NULL
&& os->region != (lang_memory_region_type *) NULL) && os->region != (lang_memory_region_type *) NULL)
{ {
os->region->current = dot; os->region->current = dot;
/* Make sure this isn't silly */ /* Make sure this isn't silly */
if (os->region->current > if (os->region->current >
os->region->origin + os->region->origin +
os->region->length) os->region->length)
{ {
einfo ("%X%P: Region %s is full (%B section %s)\n", einfo ("%X%P: Region %s is full (%B section %s)\n",
os->region->name, os->region->name,
os->bfd_section->owner, os->bfd_section->owner,
os->bfd_section->name); os->bfd_section->name);
/* Reset the region pointer */ /* Reset the region pointer */
os->region->current = 0; os->region->current = 0;
} }
} }
} }
break; break;
case lang_constructors_statement_enum: case lang_constructors_statement_enum:
dot = lang_size_sections (constructor_list.head, dot = lang_size_sections (constructor_list.head,
output_section_statement, output_section_statement,
&s->wild_statement.children.head, &s->wild_statement.children.head,
fill, fill,
dot, relax); dot, relax);
break; break;
case lang_data_statement_enum: case lang_data_statement_enum:
{ {
unsigned int size = 0; unsigned int size = 0;
s->data_statement.output_vma = dot - output_section_statement->bfd_section->vma; s->data_statement.output_vma = dot - output_section_statement->bfd_section->vma;
s->data_statement.output_section = s->data_statement.output_section =
output_section_statement->bfd_section; output_section_statement->bfd_section;
switch (s->data_statement.type) switch (s->data_statement.type)
{ {
case LONG: case LONG:
size = LONG_SIZE; size = LONG_SIZE;
break; break;
case SHORT: case SHORT:
size = SHORT_SIZE; size = SHORT_SIZE;
break; break;
case BYTE: case BYTE:
size = BYTE_SIZE; size = BYTE_SIZE;
break; break;
} }
dot += size; dot += size;
output_section_statement->bfd_section->_raw_size += size; output_section_statement->bfd_section->_raw_size += size;
} }
break; break;
case lang_wild_statement_enum: case lang_wild_statement_enum:
dot = lang_size_sections (s->wild_statement.children.head, dot = lang_size_sections (s->wild_statement.children.head,
output_section_statement, output_section_statement,
&s->wild_statement.children.head, &s->wild_statement.children.head,
fill, dot, relax); fill, dot, relax);
break; break;
case lang_object_symbols_statement_enum: case lang_object_symbols_statement_enum:
create_object_symbols = output_section_statement; create_object_symbols = output_section_statement;
break; break;
case lang_output_statement_enum: case lang_output_statement_enum:
case lang_target_statement_enum: case lang_target_statement_enum:
break; break;
case lang_input_section_enum: case lang_input_section_enum:
if (relax) if (relax)
{ {
relaxing = true; relaxing = true;
had_relax = had_relax || relax_section (prev); if( relax_section (prev))
relaxing = false; had_relax = true;
relaxing = false;
} }
else {
(*prev)->input_section.section->_cooked_size =
(*prev)->input_section.section->_raw_size ;
dot = size_input_section (prev, }
output_section_statement, dot = size_input_section (prev,
output_section_statement->fill, dot); output_section_statement,
break; output_section_statement->fill,
case lang_input_statement_enum: dot, relax);
break; break;
case lang_fill_statement_enum: case lang_input_statement_enum:
s->fill_statement.output_section = output_section_statement->bfd_section; break;
case lang_fill_statement_enum:
s->fill_statement.output_section = output_section_statement->bfd_section;
fill = s->fill_statement.fill; fill = s->fill_statement.fill;
break; break;
case lang_assignment_statement_enum: case lang_assignment_statement_enum:
{ {
bfd_vma newdot = dot; bfd_vma newdot = dot;
exp_fold_tree (s->assignment_statement.exp, exp_fold_tree (s->assignment_statement.exp,
output_section_statement, output_section_statement,
lang_allocating_phase_enum, lang_allocating_phase_enum,
dot, dot,
&newdot); &newdot);
if (newdot != dot && !relax) if (newdot != dot && !relax)
/* We've been moved ! so insert a pad */ /* We've been moved ! so insert a pad */
{ {
lang_statement_union_type *new = lang_statement_union_type *new =
(lang_statement_union_type *) (lang_statement_union_type *)
stat_alloc ((bfd_size_type) (sizeof (lang_padding_statement_type))); stat_alloc ((bfd_size_type) (sizeof (lang_padding_statement_type)));
/* Link into existing chain */ /* Link into existing chain */
new->header.next = *prev; new->header.next = *prev;
*prev = new; *prev = new;
new->header.type = lang_padding_statement_enum; new->header.type = lang_padding_statement_enum;
new->padding_statement.output_section = new->padding_statement.output_section =
output_section_statement->bfd_section; output_section_statement->bfd_section;
new->padding_statement.output_offset = new->padding_statement.output_offset =
dot - output_section_statement->bfd_section->vma; dot - output_section_statement->bfd_section->vma;
new->padding_statement.fill = fill; new->padding_statement.fill = fill;
new->padding_statement.size = newdot - dot; new->padding_statement.size = newdot - dot;
output_section_statement->bfd_section->_raw_size += output_section_statement->bfd_section->_raw_size +=
new->padding_statement.size; new->padding_statement.size;
dot = newdot; dot = newdot;
} }
} }
break; break;
default: default:
FAIL (); FAIL ();
break; break;
/* This can only get here when relaxing is turned on */ /* This can only get here when relaxing is turned on */
case lang_padding_statement_enum: case lang_padding_statement_enum:
case lang_address_statement_enum: case lang_address_statement_enum:
break; break;
}
prev = &s->header.next;
} }
prev = &s->header.next;
}
return dot; return dot;
} }
@ -2202,6 +2231,10 @@ DEFUN (lang_enter_output_section_statement,
address_exp; address_exp;
} }
os->flags = flags; os->flags = flags;
if (flags & SEC_NEVER_LOAD)
os->loadable = 0;
else
os->loadable = 1;
os->block_value = block_value; os->block_value = block_value;
stat_ptr = &os->children; stat_ptr = &os->children;
@ -2228,11 +2261,13 @@ DEFUN_VOID (reset_memory_regions)
p != (lang_memory_region_type *) NULL; p != (lang_memory_region_type *) NULL;
p = p->next) p = p->next)
{ {
p->old_length = p->current - p->origin;
p->current = p->origin; p->current = p->origin;
} }
} }
asymbol * asymbol *
DEFUN (create_symbol, (name, flags, section), DEFUN (create_symbol, (name, flags, section),
CONST char *name AND CONST char *name AND
@ -2301,38 +2336,65 @@ DEFUN_VOID (lang_process)
ldemul_before_allocation (); ldemul_before_allocation ();
/* Size up the sections */ #if 0
lang_size_sections (statement_list.head, had_relax = true;
abs_output_section, while (had_relax)
&(statement_list.head), 0, (bfd_vma) 0, false); {
had_relax = false;
lang_size_sections (statement_list.head,
(lang_output_section_statement_type *) NULL,
&(statement_list.head), 0, (bfd_vma) 0, true);
/* FIXME. Until the code in relax is fixed so that it only reads in
stuff once, we cant iterate since there is no way for the linker to
know what has been patched and what hasn't */
break;
}
#endif
/* Now run around and relax if we can */ /* Now run around and relax if we can */
if (command_line.relax) if (command_line.relax)
{ {
reset_memory_regions (); /* First time round is a trial run to get the 'worst case' addresses of the
objects if there was no relaxing */
/* Move the global symbols around */ lang_size_sections (statement_list.head,
lang_relocate_globals (); (lang_output_section_statement_type *) NULL,
&(statement_list.head), 0, (bfd_vma) 0, false);
had_relax = true;
while (had_relax)
{
had_relax = false;
lang_size_sections (statement_list.head,
(lang_output_section_statement_type *) NULL,
&(statement_list.head), 0, (bfd_vma) 0, true);
/* FIXME. Until the code in relax is fixed so that it only reads in
stuff once, we cant iterate since there is no way for the linker to
know what has been patched and what hasn't */
break;
}
/* Move the global symbols around so the second pass of relaxing can
see them */
lang_relocate_globals ();
reset_memory_regions ();
/* Do all the assignments, now that we know the final restingplaces
of all the symbols */
lang_do_assignments (statement_list.head,
abs_output_section,
0, (bfd_vma) 0);
/* Perform another relax pass - this time we know where the
globals are, so can make better guess */
lang_size_sections (statement_list.head,
(lang_output_section_statement_type *) NULL,
&(statement_list.head), 0, (bfd_vma) 0, true);
}
else
{
/* Size up the sections */
lang_size_sections (statement_list.head,
abs_output_section,
&(statement_list.head), 0, (bfd_vma) 0, false);
} }