* ld.h (lang_phase_type): Move to..

* ldexp.h: ..here.  Add lang_mark_phase_enum.
	(node_type): Remove etree_undef and etree_unspec.
	(exp_data_seg): Delete.
	(struct ldexp_control, expld): New.
	(invalid, exp_mark_used_section): Delete.
	(exp_fold_tree, exp_get_vma, exp_get_value_int, exp_get_fill,
	exp_get_abs_int): Update prototypes.
	* ldexp.c (assigning_to_dot): Delete.
	(expld): Define.
	(make_abs): Operate directly on expld.result.  Update all callers.
	(new_abs): Likewise.  Return void.
	(new_rel_from_abs): Rename from new_rel_from_section.
	(new_rel, new_rel_from_abs): Operate on expld.result and return void.
	Update all callers.
	(fold_unary): Operate on expld.result and return void.  Remove
	"current_section", "allocation_done", "dot", "dotp" and "mark_used"
	params.  Update all callers.
	(fold_binary, fold_trinary, fold_name, exp_fold_tree_1): Likewise.
	(fold_unary <ALIGN_K>): Ensure alignment is absolute.
	(fold_unary <ABSOLUTE>): Use make_abs.
	(fold_unary <DATA_SEGMENT_END>): Evaluate mark_phase as for
	allocating_phase.
	(fold_binary <DATA_SEGMENT_ALIGN, DATA_SEGMENT_RELRO_END, >): Ditto.
	(fold_binary <'%','/'>): Don't error if marking.
	(fold_name <SIZEOF_HEADERS>): Don't call bfd_sizeof_headers when
	marking.
	(fold_name <NAME>): Remove FIXME; -R is handled correctly.  Don't
	error when marking.
	(fold_name <ADDR, LOADADDR, SIZEOF>): Don't set SEC_KEEP.
	(exp_fold_tree_1): Don't error when marking.
	(exp_fold_tree_1 <etree_rel>): Evaluate in all phases except first.
	(exp_fold_tree_1 <etree_assign to dot>): Don't check for NULL
	current section, instead check for NULL dotp.
	(exp_fold_tree_1 <etree_provide>): Don't evaluate the assignment
	source unless the symbol is referenced and undefined.
	(exp_fold_tree): Remove "allocation_done" and "dot" params.  Save
	params to expld.
	(exp_fold_tree_no_dot): Remove "current_section", "allocation_done
	and "mark_used" params.  Save params to expld.  Update all callers.
	(exp_assop): Do without temp var.
	(exp_print_tree <etree_undef>): Delete code.
	(exp_get_vma): Remove "allocation_done" param.  Correct error return.
	(exp_get_fill, exp_get_abs_int): Likewise.
	(exp_get_value_int): Remove "allocation_done" param.
	(exp_mark_used_section): Delete.
	* ldgram.y (fill_exp): Update exp_get_fill call.
	(origin_spec, length_spec): Update exp_get_vma call.
	* ldlang.c (lang_init): Don't bother clearing lang_statement_iteration.
	(lang_mark_used_section_1, lang_mark_used_section): Delete.
	(strip_excluded_output_sections): Call one_lang_size_sections_pass in
	marking mode.  Merge old lang_mark_used_section code.  Correct handling
	of output sections with excluded input sections and data statements.
	Don't drop non-zero sized sections.  Don't zap os->bfd_section.
	Do set SEC_EXCLUDE when appropriate.
	(print_output_section_statement): Update for changed ldexp.c
	interface.
	(print_assignment, lang_size_sections_1): Likewise.
	(lang_do_assignments_1, lang_enter_output_section_statement): Likewise.
	(lang_new_phdr, lang_record_phdrs): Likewise.
	(lang_size_sections): Likewise.
	(insert_pad): Use following statement if it is a pad, rather than
	creating a new one.
	(lang_size_sections_1 <lang_output_section_statement_enum>): Do
	process ignored output section to set vma and lma, but don't
	update dot for these sections.  Don't error if marking.
	(lang_size_sections_1 <lang_assignment_statement_enum>): Don't
	update dot for ignored sections.
	(lang_size_sections_1 <lang_data_statement_enum>): Don't mark absolute
	section with SEC_ALLOC.
	(one_lang_size_sections_pass): New function.
	(lang_size_sections): Remove first five params.  Set expld.phase on
	entry and exit.   Use one_lang_size_sections_pass.
	(lang_do_assignments): Remove all params.  Update all callers.
	(lang_reset_memory_regions): Clear os->processed for all output
	section statements.
	* ldlang.h (lang_do_assignments): Update prototype.
	(lang_size_sections): Likewise.
	(one_lang_size_sections_pass): Declare.
	* pe-dll.c (pe_dll_fill_sections, pe_exe_fill_sections): Update
	lang_size_sections and lang_do_assignments calls.
	* emultempl/elf32.em (layout_sections_again): Likewise.
	* emultempl/ppc64elf.em (ppc_before_allocation): Use
	one_lang_size_sections_pass.
This commit is contained in:
Alan Modra 2005-06-09 02:05:47 +00:00
parent 0e58fcf315
commit e9ee469ad1
10 changed files with 693 additions and 909 deletions

View File

@ -1,3 +1,90 @@
2005-06-09 Alan Modra <amodra@bigpond.net.au>
* ld.h (lang_phase_type): Move to..
* ldexp.h: ..here. Add lang_mark_phase_enum.
(node_type): Remove etree_undef and etree_unspec.
(exp_data_seg): Delete.
(struct ldexp_control, expld): New.
(invalid, exp_mark_used_section): Delete.
(exp_fold_tree, exp_get_vma, exp_get_value_int, exp_get_fill,
exp_get_abs_int): Update prototypes.
* ldexp.c (assigning_to_dot): Delete.
(expld): Define.
(make_abs): Operate directly on expld.result. Update all callers.
(new_abs): Likewise. Return void.
(new_rel_from_abs): Rename from new_rel_from_section.
(new_rel, new_rel_from_abs): Operate on expld.result and return void.
Update all callers.
(fold_unary): Operate on expld.result and return void. Remove
"current_section", "allocation_done", "dot", "dotp" and "mark_used"
params. Update all callers.
(fold_binary, fold_trinary, fold_name, exp_fold_tree_1): Likewise.
(fold_unary <ALIGN_K>): Ensure alignment is absolute.
(fold_unary <ABSOLUTE>): Use make_abs.
(fold_unary <DATA_SEGMENT_END>): Evaluate mark_phase as for
allocating_phase.
(fold_binary <DATA_SEGMENT_ALIGN, DATA_SEGMENT_RELRO_END, >): Ditto.
(fold_binary <'%','/'>): Don't error if marking.
(fold_name <SIZEOF_HEADERS>): Don't call bfd_sizeof_headers when
marking.
(fold_name <NAME>): Remove FIXME; -R is handled correctly. Don't
error when marking.
(fold_name <ADDR, LOADADDR, SIZEOF>): Don't set SEC_KEEP.
(exp_fold_tree_1): Don't error when marking.
(exp_fold_tree_1 <etree_rel>): Evaluate in all phases except first.
(exp_fold_tree_1 <etree_assign to dot>): Don't check for NULL
current section, instead check for NULL dotp.
(exp_fold_tree_1 <etree_provide>): Don't evaluate the assignment
source unless the symbol is referenced and undefined.
(exp_fold_tree): Remove "allocation_done" and "dot" params. Save
params to expld.
(exp_fold_tree_no_dot): Remove "current_section", "allocation_done
and "mark_used" params. Save params to expld. Update all callers.
(exp_assop): Do without temp var.
(exp_print_tree <etree_undef>): Delete code.
(exp_get_vma): Remove "allocation_done" param. Correct error return.
(exp_get_fill, exp_get_abs_int): Likewise.
(exp_get_value_int): Remove "allocation_done" param.
(exp_mark_used_section): Delete.
* ldgram.y (fill_exp): Update exp_get_fill call.
(origin_spec, length_spec): Update exp_get_vma call.
* ldlang.c (lang_init): Don't bother clearing lang_statement_iteration.
(lang_mark_used_section_1, lang_mark_used_section): Delete.
(strip_excluded_output_sections): Call one_lang_size_sections_pass in
marking mode. Merge old lang_mark_used_section code. Correct handling
of output sections with excluded input sections and data statements.
Don't drop non-zero sized sections. Don't zap os->bfd_section.
Do set SEC_EXCLUDE when appropriate.
(print_output_section_statement): Update for changed ldexp.c
interface.
(print_assignment, lang_size_sections_1): Likewise.
(lang_do_assignments_1, lang_enter_output_section_statement): Likewise.
(lang_new_phdr, lang_record_phdrs): Likewise.
(lang_size_sections): Likewise.
(insert_pad): Use following statement if it is a pad, rather than
creating a new one.
(lang_size_sections_1 <lang_output_section_statement_enum>): Do
process ignored output section to set vma and lma, but don't
update dot for these sections. Don't error if marking.
(lang_size_sections_1 <lang_assignment_statement_enum>): Don't
update dot for ignored sections.
(lang_size_sections_1 <lang_data_statement_enum>): Don't mark absolute
section with SEC_ALLOC.
(one_lang_size_sections_pass): New function.
(lang_size_sections): Remove first five params. Set expld.phase on
entry and exit. Use one_lang_size_sections_pass.
(lang_do_assignments): Remove all params. Update all callers.
(lang_reset_memory_regions): Clear os->processed for all output
section statements.
* ldlang.h (lang_do_assignments): Update prototype.
(lang_size_sections): Likewise.
(one_lang_size_sections_pass): Declare.
* pe-dll.c (pe_dll_fill_sections, pe_exe_fill_sections): Update
lang_size_sections and lang_do_assignments calls.
* emultempl/elf32.em (layout_sections_again): Likewise.
* emultempl/ppc64elf.em (ppc_before_allocation): Use
one_lang_size_sections_pass.
2005-06-08 Aldy Hernandez <aldyh@redhat.com> 2005-06-08 Aldy Hernandez <aldyh@redhat.com>
* emulparams/elf32ms1.sh: New. * emulparams/elf32ms1.sh: New.

View File

@ -1497,15 +1497,13 @@ gld${EMULATION_NAME}_layout_sections_again (void)
lang_reset_memory_regions (); lang_reset_memory_regions ();
/* Resize the sections. */ /* Resize the sections. */
lang_size_sections (stat_ptr->head, abs_output_section, lang_size_sections (NULL, TRUE);
&stat_ptr->head, 0, (bfd_vma) 0, NULL, TRUE);
/* Redo special stuff. */ /* Redo special stuff. */
ldemul_after_allocation (); ldemul_after_allocation ();
/* Do the assignments again. */ /* Do the assignments again. */
lang_do_assignments (stat_ptr->head, abs_output_section, lang_do_assignments ();
(fill_type *) 0, (bfd_vma) 0);
} }
static void static void

View File

@ -110,14 +110,14 @@ ppc_before_allocation (void)
{ {
/* Size the sections. This is premature, but we want to know the /* Size the sections. This is premature, but we want to know the
TLS segment layout so that certain optimizations can be done. */ TLS segment layout so that certain optimizations can be done. */
lang_size_sections (stat_ptr->head, abs_output_section, expld.phase = lang_mark_phase_enum;
&stat_ptr->head, 0, 0, NULL, TRUE); expld.dataseg.phase = exp_dataseg_none;
one_lang_size_sections_pass (NULL, TRUE);
if (!ppc64_elf_tls_optimize (output_bfd, &link_info)) if (!ppc64_elf_tls_optimize (output_bfd, &link_info))
einfo ("%X%P: TLS problem %E\n"); einfo ("%X%P: TLS problem %E\n");
/* We must not cache anything from the preliminary sizing. */ /* We must not cache anything from the preliminary sizing. */
elf_tdata (output_bfd)->program_header_size = 0;
lang_reset_memory_regions (); lang_reset_memory_regions ();
} }

View File

@ -238,12 +238,6 @@ typedef struct {
extern ld_config_type config; extern ld_config_type config;
typedef enum {
lang_first_phase_enum,
lang_allocating_phase_enum,
lang_final_phase_enum
} lang_phase_type;
extern FILE * saved_script_handle; extern FILE * saved_script_handle;
extern bfd_boolean force_make_executable; extern bfd_boolean force_make_executable;

File diff suppressed because it is too large Load Diff

View File

@ -40,8 +40,6 @@ typedef struct {
etree_assign, etree_assign,
etree_provide, etree_provide,
etree_provided, etree_provided,
etree_undef,
etree_unspec,
etree_value, etree_value,
etree_assert, etree_assert,
etree_rel etree_rel
@ -91,7 +89,30 @@ typedef union etree_union {
} assert_s; } assert_s;
} etree_type; } etree_type;
extern struct exp_data_seg { typedef enum {
lang_first_phase_enum,
lang_mark_phase_enum,
lang_allocating_phase_enum,
lang_final_phase_enum
} lang_phase_type;
struct ldexp_control {
/* Modify expression evaluation depending on this. */
lang_phase_type phase;
/* Principally used for diagnostics. */
bfd_boolean assigning_to_dot;
/* Working results. */
etree_value_type result;
bfd_vma dot;
/* Current dot and section passed to ldexp folder. */
bfd_vma *dotp;
asection *section;
/* State machine and results for DATASEG. */
struct {
enum { enum {
exp_dataseg_none, exp_dataseg_none,
exp_dataseg_align_seen, exp_dataseg_align_seen,
@ -100,8 +121,12 @@ extern struct exp_data_seg {
exp_dataseg_relro_adjust, exp_dataseg_relro_adjust,
exp_dataseg_adjust exp_dataseg_adjust
} phase; } phase;
bfd_vma base, min_base, relro_end, end, pagesize, maxpagesize; bfd_vma base, min_base, relro_end, end, pagesize, maxpagesize;
} exp_data_seg; } dataseg;
};
extern struct ldexp_control expld;
/* A maps from a segment name to a base address. */ /* A maps from a segment name to a base address. */
typedef struct segment_struct { typedef struct segment_struct {
@ -127,10 +152,8 @@ etree_type *exp_bigintop
(bfd_vma, char *); (bfd_vma, char *);
etree_type *exp_relop etree_type *exp_relop
(asection *, bfd_vma); (asection *, bfd_vma);
etree_value_type invalid void exp_fold_tree
(void); (etree_type *, asection *, bfd_vma *);
etree_value_type exp_fold_tree
(etree_type *, asection *, lang_phase_type, bfd_vma, bfd_vma *);
etree_type *exp_binop etree_type *exp_binop
(int, etree_type *, etree_type *); (int, etree_type *, etree_type *);
etree_type *exp_trinop etree_type *exp_trinop
@ -148,14 +171,12 @@ etree_type *exp_assert
void exp_print_tree void exp_print_tree
(etree_type *); (etree_type *);
bfd_vma exp_get_vma bfd_vma exp_get_vma
(etree_type *, bfd_vma, char *, lang_phase_type); (etree_type *, bfd_vma, char *);
int exp_get_value_int int exp_get_value_int
(etree_type *, int, char *, lang_phase_type); (etree_type *, int, char *);
fill_type *exp_get_fill fill_type *exp_get_fill
(etree_type *, fill_type *, char *, lang_phase_type); (etree_type *, fill_type *, char *);
bfd_vma exp_get_abs_int bfd_vma exp_get_abs_int
(etree_type *, int, char *, lang_phase_type); (etree_type *, int, char *);
void exp_mark_used_section
(etree_type *, asection *);
#endif #endif

View File

@ -600,10 +600,7 @@ length:
fill_exp: fill_exp:
mustbe_exp mustbe_exp
{ {
$$ = exp_get_fill ($1, $$ = exp_get_fill ($1, 0, "fill value");
0,
"fill value",
lang_first_phase_enum);
} }
; ;
@ -681,18 +678,16 @@ memory_spec: NAME
origin_spec: origin_spec:
ORIGIN '=' mustbe_exp ORIGIN '=' mustbe_exp
{ region->current = {
region->origin = region->origin = exp_get_vma ($3, 0, "origin");
exp_get_vma($3, 0L,"origin", lang_first_phase_enum); region->current = region->origin;
} }
; ;
length_spec: length_spec:
LENGTH '=' mustbe_exp LENGTH '=' mustbe_exp
{ region->length = exp_get_vma($3, {
~((bfd_vma)0), region->length = exp_get_vma ($3, -1, "length");
"length",
lang_first_phase_enum);
} }
; ;

View File

@ -101,6 +101,9 @@ bfd_boolean delete_output_file_on_failure = FALSE;
struct lang_nocrossrefs *nocrossref_list; struct lang_nocrossrefs *nocrossref_list;
static struct unique_sections *unique_section_list; static struct unique_sections *unique_section_list;
static bfd_boolean ldlang_sysrooted_script = FALSE; static bfd_boolean ldlang_sysrooted_script = FALSE;
/* Functions that traverse the linker script and might evaluate
DEFINED() need to increment this. */
int lang_statement_iteration = 0; int lang_statement_iteration = 0;
etree_type *base; /* Relocation base - or null */ etree_type *base; /* Relocation base - or null */
@ -895,9 +898,6 @@ lang_init (void)
if (!bfd_hash_table_init_n (&lang_definedness_table, if (!bfd_hash_table_init_n (&lang_definedness_table,
lang_definedness_newfunc, 3)) lang_definedness_newfunc, 3))
einfo (_("%P%F: out of memory during initialization")); einfo (_("%P%F: out of memory during initialization"));
/* Callers of exp_fold_tree need to increment this. */
lang_statement_iteration = 0;
} }
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
@ -3044,95 +3044,6 @@ map_input_to_output_sections
} }
} }
/* Worker function for lang_mark_used_section. Recursiveness goes
here. */
static void
lang_mark_used_section_1
(lang_statement_union_type *s,
lang_output_section_statement_type *output_section_statement)
{
for (; s != NULL; s = s->header.next)
{
switch (s->header.type)
{
case lang_constructors_statement_enum:
break;
case lang_output_section_statement_enum:
{
lang_output_section_statement_type *os;
os = &(s->output_section_statement);
if (os->bfd_section != NULL)
{
lang_mark_used_section_1 (os->children.head, os);
if (os->load_base)
exp_mark_used_section (os->load_base,
bfd_abs_section_ptr);
}
}
break;
case lang_wild_statement_enum:
lang_mark_used_section_1 (s->wild_statement.children.head,
output_section_statement);
break;
case lang_object_symbols_statement_enum:
case lang_output_statement_enum:
case lang_target_statement_enum:
break;
case lang_data_statement_enum:
exp_mark_used_section (s->data_statement.exp,
bfd_abs_section_ptr);
break;
case lang_reloc_statement_enum:
break;
case lang_input_section_enum:
break;
case lang_input_statement_enum:
break;
case lang_fill_statement_enum:
break;
case lang_assignment_statement_enum:
exp_mark_used_section (s->assignment_statement.exp,
output_section_statement->bfd_section);
break;
case lang_padding_statement_enum:
break;
case lang_group_statement_enum:
lang_mark_used_section_1 (s->group_statement.children.head,
output_section_statement);
break;
default:
FAIL ();
break;
case lang_address_statement_enum:
break;
}
}
}
static void
lang_mark_used_section (void)
{
unsigned int gc_sections = link_info.gc_sections;
/* Callers of exp_fold_tree need to increment this. */
lang_statement_iteration++;
lang_mark_used_section_1 (statement_list.head, abs_output_section);
link_info.gc_sections = 0;
bfd_gc_sections (output_bfd, &link_info);
link_info.gc_sections = gc_sections;
}
/* An output section might have been removed after its statement was /* An output section might have been removed after its statement was
added. For example, ldemul_before_allocation can remove dynamic added. For example, ldemul_before_allocation can remove dynamic
sections if they turn out to be not needed. Clean them up here. */ sections if they turn out to be not needed. Clean them up here. */
@ -3141,8 +3052,25 @@ void
strip_excluded_output_sections (void) strip_excluded_output_sections (void)
{ {
lang_output_section_statement_type *os; lang_output_section_statement_type *os;
unsigned int gc_sections;
lang_mark_used_section (); /* Run lang_size_sections (if not already done) to ensure that all
symbols defined in the linker script are put in the bfd hash
table. */
if (expld.phase != lang_mark_phase_enum)
{
expld.phase = lang_mark_phase_enum;
expld.dataseg.phase = exp_dataseg_none;
one_lang_size_sections_pass (NULL, FALSE);
lang_reset_memory_regions ();
}
/* Now call into bfd_gc_sections to mark all sections defining global
symbols with SEC_KEEP. */
gc_sections = link_info.gc_sections;
link_info.gc_sections = 0;
bfd_gc_sections (output_bfd, &link_info);
link_info.gc_sections = gc_sections;
for (os = &lang_output_section_statement.head->output_section_statement; for (os = &lang_output_section_statement.head->output_section_statement;
os != NULL; os != NULL;
@ -3158,7 +3086,7 @@ strip_excluded_output_sections (void)
if (output_section == NULL) if (output_section == NULL)
continue; continue;
exclude = FALSE; exclude = TRUE;
if (output_section->map_head.s != NULL) if (output_section->map_head.s != NULL)
{ {
asection *s; asection *s;
@ -3166,26 +3094,25 @@ strip_excluded_output_sections (void)
for (s = output_section->map_head.s; s != NULL; for (s = output_section->map_head.s; s != NULL;
s = s->map_head.s) s = s->map_head.s)
if ((s->flags & SEC_EXCLUDE) == 0) if ((s->flags & SEC_EXCLUDE) == 0)
{
exclude = FALSE;
break; break;
}
output_section->map_head.link_order = NULL; output_section->map_head.link_order = NULL;
output_section->map_tail.link_order = NULL; output_section->map_tail.link_order = NULL;
if (s == NULL)
exclude = TRUE;
} }
if (exclude if (exclude
|| (output_section->linker_has_input == 0 && (output_section->flags & SEC_KEEP) == 0
&& ((output_section->flags && output_section->rawsize == 0
& (SEC_KEEP | SEC_HAS_CONTENTS)) == 0))) && !bfd_is_abs_section (output_section))
{ {
if (exclude)
os->bfd_section = NULL;
else
/* We don't set bfd_section to NULL since bfd_section of the /* We don't set bfd_section to NULL since bfd_section of the
* removed output section statement may still be used. */ removed output section statement may still be used. */
os->ignored = TRUE; os->ignored = TRUE;
output_section->flags |= SEC_EXCLUDE;
if (!bfd_section_removed_from_list (output_bfd, if (!bfd_section_removed_from_list (output_bfd,
output_section)) output_section))
{ {
@ -3234,7 +3161,7 @@ print_output_section_statement
bfd_vma addr; bfd_vma addr;
addr = exp_get_abs_int (output_section_statement->load_base, 0, addr = exp_get_abs_int (output_section_statement->load_base, 0,
"load base", lang_final_phase_enum); "load base");
minfo (_(" load address 0x%V"), addr); minfo (_(" load address 0x%V"), addr);
} }
} }
@ -3304,7 +3231,6 @@ print_assignment (lang_assignment_statement_type *assignment,
bfd_boolean is_dot; bfd_boolean is_dot;
bfd_boolean computation_is_valid = TRUE; bfd_boolean computation_is_valid = TRUE;
etree_type *tree; etree_type *tree;
etree_value_type result;
for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
print_space (); print_space ();
@ -3324,18 +3250,17 @@ print_assignment (lang_assignment_statement_type *assignment,
computation_is_valid = is_dot || (scan_for_self_assignment (dst, tree) == FALSE); computation_is_valid = is_dot || (scan_for_self_assignment (dst, tree) == FALSE);
} }
result = exp_fold_tree (tree, output_section->bfd_section, exp_fold_tree (tree, output_section->bfd_section, &print_dot);
lang_final_phase_enum, print_dot, &print_dot); if (expld.result.valid_p)
if (result.valid_p)
{ {
bfd_vma value; bfd_vma value;
if (computation_is_valid) if (computation_is_valid)
{ {
value = result.value; value = expld.result.value;
if (result.section) if (expld.result.section)
value += result.section->vma; value += expld.result.section->vma;
minfo ("0x%V", value); minfo ("0x%V", value);
if (is_dot) if (is_dot)
@ -3351,8 +3276,8 @@ print_assignment (lang_assignment_statement_type *assignment,
{ {
value = h->u.def.value; value = h->u.def.value;
if (result.section) if (expld.result.section)
value += result.section->vma; value += expld.result.section->vma;
minfo ("[0x%V]", value); minfo ("[0x%V]", value);
} }
@ -3821,16 +3746,22 @@ insert_pad (lang_statement_union_type **ptr,
bfd_vma dot) bfd_vma dot)
{ {
static fill_type zero_fill = { 1, { 0 } }; static fill_type zero_fill = { 1, { 0 } };
lang_statement_union_type *pad; lang_statement_union_type *pad = NULL;
if (ptr != &statement_list.head)
pad = ((lang_statement_union_type *) pad = ((lang_statement_union_type *)
((char *) ptr - offsetof (lang_statement_union_type, header.next))); ((char *) ptr - offsetof (lang_statement_union_type, header.next)));
if (ptr != &statement_list.head if (pad != NULL
&& pad->header.type == lang_padding_statement_enum && pad->header.type == lang_padding_statement_enum
&& pad->padding_statement.output_section == output_section) && pad->padding_statement.output_section == output_section)
{ {
/* Use the existing pad statement. The above test on output /* Use the existing pad statement. */
section is probably redundant, but it doesn't hurt to check. */ }
else if ((pad = *ptr) != NULL
&& pad->header.type == lang_padding_statement_enum
&& pad->padding_statement.output_section == output_section)
{
/* Use the existing pad statement. */
} }
else else
{ {
@ -4045,11 +3976,11 @@ lang_size_sections_1
{ {
case lang_output_section_statement_enum: case lang_output_section_statement_enum:
{ {
bfd_vma after; bfd_vma newdot, after;
lang_output_section_statement_type *os; lang_output_section_statement_type *os;
os = &s->output_section_statement; os = &s->output_section_statement;
if (os->bfd_section == NULL || os->ignored) if (os->bfd_section == NULL)
/* This section was removed or never actually created. */ /* This section was removed or never actually created. */
break; break;
@ -4109,7 +4040,8 @@ lang_size_sections_1
&& lang_memory_region_list != NULL && lang_memory_region_list != NULL
&& (strcmp (lang_memory_region_list->name, && (strcmp (lang_memory_region_list->name,
DEFAULT_MEMORY_REGION) != 0 DEFAULT_MEMORY_REGION) != 0
|| lang_memory_region_list->next != NULL)) || lang_memory_region_list->next != NULL)
&& expld.phase != lang_mark_phase_enum)
{ {
/* By default this is an error rather than just a /* By default this is an error rather than just a
warning because if we allocate the section to the warning because if we allocate the section to the
@ -4132,80 +4064,80 @@ lang_size_sections_1
os->bfd_section)); os->bfd_section));
} }
dot = os->region->current; newdot = os->region->current;
if (os->section_alignment == -1) if (os->section_alignment == -1)
{ {
bfd_vma olddot; bfd_vma savedot = newdot;
newdot = align_power (newdot,
olddot = dot;
dot = align_power (dot,
os->bfd_section->alignment_power); os->bfd_section->alignment_power);
if (dot != olddot && config.warn_section_align) if (newdot != savedot
&& config.warn_section_align
&& expld.phase != lang_mark_phase_enum)
einfo (_("%P: warning: changing start of section" einfo (_("%P: warning: changing start of section"
" %s by %u bytes\n"), " %s by %lu bytes\n"),
os->name, (unsigned int) (dot - olddot)); os->name, (unsigned long) (newdot - savedot));
} }
} }
else else
{ {
etree_value_type r; newdot = dot;
os->processed = -1; os->processed = -1;
r = exp_fold_tree (os->addr_tree, exp_fold_tree (os->addr_tree, bfd_abs_section_ptr,
bfd_abs_section_ptr, &newdot);
lang_allocating_phase_enum,
dot, &dot);
os->processed = 0; os->processed = 0;
if (!r.valid_p) if (!expld.result.valid_p
&& expld.phase != lang_mark_phase_enum)
einfo (_("%F%S: non constant or forward reference" einfo (_("%F%S: non constant or forward reference"
" address expression for section %s\n"), " address expression for section %s\n"),
os->name); os->name);
dot = r.value + r.section->vma; newdot = expld.result.value + expld.result.section->vma;
} }
/* The section starts here. /* The section starts here.
First, align to what the section needs. */ First, align to what the section needs. */
if (os->section_alignment != -1) if (os->section_alignment != -1)
dot = align_power (dot, os->section_alignment); newdot = align_power (newdot, os->section_alignment);
bfd_set_section_vma (0, os->bfd_section, dot); bfd_set_section_vma (0, os->bfd_section, newdot);
os->bfd_section->output_offset = 0; os->bfd_section->output_offset = 0;
} }
lang_size_sections_1 (os->children.head, os, &os->children.head, lang_size_sections_1 (os->children.head, os, &os->children.head,
os->fill, dot, relax, check_regions); os->fill, newdot, relax, check_regions);
os->processed = 1;
if (bfd_is_abs_section (os->bfd_section) || os->ignored)
{
ASSERT (os->bfd_section->size == 0);
break;
}
dot = os->bfd_section->vma;
/* Put the section within the requested block size, or /* Put the section within the requested block size, or
align at the block boundary. */ align at the block boundary. */
after = ((os->bfd_section->vma after = ((dot
+ TO_ADDR (os->bfd_section->size) + TO_ADDR (os->bfd_section->size)
+ os->block_value - 1) + os->block_value - 1)
& - (bfd_vma) os->block_value); & - (bfd_vma) os->block_value);
if (bfd_is_abs_section (os->bfd_section)) os->bfd_section->size = TO_SIZE (after - os->bfd_section->vma);
ASSERT (after == os->bfd_section->vma);
else
os->bfd_section->size
= TO_SIZE (after - os->bfd_section->vma);
dot = os->bfd_section->vma;
/* .tbss sections effectively have zero size. */ /* .tbss sections effectively have zero size. */
if ((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0 if ((os->bfd_section->flags & SEC_HAS_CONTENTS) != 0
|| (os->bfd_section->flags & SEC_THREAD_LOCAL) == 0 || (os->bfd_section->flags & SEC_THREAD_LOCAL) == 0
|| link_info.relocatable) || link_info.relocatable)
dot += TO_ADDR (os->bfd_section->size); dot += TO_ADDR (os->bfd_section->size);
os->processed = 1;
if (os->update_dot_tree != 0) if (os->update_dot_tree != 0)
exp_fold_tree (os->update_dot_tree, bfd_abs_section_ptr, exp_fold_tree (os->update_dot_tree, bfd_abs_section_ptr, &dot);
lang_allocating_phase_enum, dot, &dot);
/* Update dot in the region ? /* Update dot in the region ?
We only do this if the section is going to be allocated, We only do this if the section is going to be allocated,
@ -4263,8 +4195,7 @@ lang_size_sections_1
/* We might refer to provided symbols in the expression, and /* We might refer to provided symbols in the expression, and
need to mark them as needed. */ need to mark them as needed. */
exp_fold_tree (s->data_statement.exp, bfd_abs_section_ptr, exp_fold_tree (s->data_statement.exp, bfd_abs_section_ptr, &dot);
lang_allocating_phase_enum, dot, &dot);
switch (s->data_statement.type) switch (s->data_statement.type)
{ {
@ -4306,21 +4237,21 @@ lang_size_sections_1
break; break;
case lang_wild_statement_enum: case lang_wild_statement_enum:
dot = lang_size_sections_1 (s->wild_statement.children.head, dot = lang_size_sections_1 (s->wild_statement.children.head,
output_section_statement, output_section_statement,
&s->wild_statement.children.head, &s->wild_statement.children.head,
fill, dot, relax, check_regions); fill, dot, relax, check_regions);
break; break;
case lang_object_symbols_statement_enum: case lang_object_symbols_statement_enum:
link_info.create_object_symbols_section = link_info.create_object_symbols_section =
output_section_statement->bfd_section; output_section_statement->bfd_section;
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:
{ {
asection *i; asection *i;
@ -4339,25 +4270,26 @@ lang_size_sections_1
output_section_statement->fill, dot); output_section_statement->fill, dot);
} }
break; break;
case lang_input_statement_enum: case lang_input_statement_enum:
break; break;
case lang_fill_statement_enum: case lang_fill_statement_enum:
s->fill_statement.output_section = s->fill_statement.output_section =
output_section_statement->bfd_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->bfd_section, output_section_statement->bfd_section,
lang_allocating_phase_enum,
dot,
&newdot); &newdot);
if (newdot != dot) if (newdot != dot && !output_section_statement->ignored)
{ {
if (output_section_statement == abs_output_section) if (output_section_statement == abs_output_section)
{ {
@ -4376,15 +4308,15 @@ lang_size_sections_1
/* Don't neuter the pad below when relaxing. */ /* Don't neuter the pad below when relaxing. */
s = s->header.next; s = s->header.next;
}
/* If dot is advanced, this implies that the section should /* If dot is advanced, this implies that the section
have space allocated to it, unless the user has explicitly should have space allocated to it, unless the
stated that the section should never be loaded. */ user has explicitly stated that the section
should never be loaded. */
if (!(output_section_statement->flags if (!(output_section_statement->flags
& (SEC_NEVER_LOAD | SEC_ALLOC))) & (SEC_NEVER_LOAD | SEC_ALLOC)))
output_section_statement->bfd_section->flags |= SEC_ALLOC; output_section_statement->bfd_section->flags |= SEC_ALLOC;
}
dot = newdot; dot = newdot;
} }
} }
@ -4427,47 +4359,43 @@ lang_size_sections_1
return dot; return dot;
} }
bfd_vma void
lang_size_sections one_lang_size_sections_pass (bfd_boolean *relax, bfd_boolean check_regions)
(lang_statement_union_type *s,
lang_output_section_statement_type *output_section_statement,
lang_statement_union_type **prev,
fill_type *fill,
bfd_vma dot,
bfd_boolean *relax,
bfd_boolean check_regions)
{ {
bfd_vma result;
/* Callers of exp_fold_tree need to increment this. */
lang_statement_iteration++; lang_statement_iteration++;
lang_size_sections_1 (statement_list.head, abs_output_section,
&statement_list.head, 0, 0, relax, check_regions);
}
exp_data_seg.phase = exp_dataseg_none; void
result = lang_size_sections_1 (s, output_section_statement, prev, fill, lang_size_sections (bfd_boolean *relax, bfd_boolean check_regions)
dot, relax, check_regions); {
if (exp_data_seg.phase == exp_dataseg_end_seen expld.phase = lang_allocating_phase_enum;
&& link_info.relro && exp_data_seg.relro_end) expld.dataseg.phase = exp_dataseg_none;
one_lang_size_sections_pass (relax, check_regions);
if (expld.dataseg.phase == exp_dataseg_end_seen
&& link_info.relro && expld.dataseg.relro_end)
{ {
/* If DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END pair was seen, try /* If DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END pair was seen, try
to put exp_data_seg.relro on a (common) page boundary. */ to put expld.dataseg.relro on a (common) page boundary. */
bfd_vma old_min_base, relro_end, maxpage; bfd_vma old_min_base, relro_end, maxpage;
exp_data_seg.phase = exp_dataseg_relro_adjust; expld.dataseg.phase = exp_dataseg_relro_adjust;
old_min_base = exp_data_seg.min_base; old_min_base = expld.dataseg.min_base;
maxpage = exp_data_seg.maxpagesize; maxpage = expld.dataseg.maxpagesize;
exp_data_seg.base += (-exp_data_seg.relro_end expld.dataseg.base += (-expld.dataseg.relro_end
& (exp_data_seg.pagesize - 1)); & (expld.dataseg.pagesize - 1));
/* Compute the expected PT_GNU_RELRO segment end. */ /* Compute the expected PT_GNU_RELRO segment end. */
relro_end = (exp_data_seg.relro_end + exp_data_seg.pagesize - 1) relro_end = (expld.dataseg.relro_end + expld.dataseg.pagesize - 1)
& ~(exp_data_seg.pagesize - 1); & ~(expld.dataseg.pagesize - 1);
if (old_min_base + maxpage < exp_data_seg.base) if (old_min_base + maxpage < expld.dataseg.base)
{ {
exp_data_seg.base -= maxpage; expld.dataseg.base -= maxpage;
relro_end -= maxpage; relro_end -= maxpage;
} }
result = lang_size_sections_1 (s, output_section_statement, prev, fill, one_lang_size_sections_pass (relax, check_regions);
dot, relax, check_regions); if (expld.dataseg.relro_end > relro_end)
if (exp_data_seg.relro_end > relro_end)
{ {
/* The alignment of sections between DATA_SEGMENT_ALIGN /* The alignment of sections between DATA_SEGMENT_ALIGN
and DATA_SEGMENT_RELRO_END caused huge padding to be and DATA_SEGMENT_RELRO_END caused huge padding to be
@ -4478,46 +4406,42 @@ lang_size_sections
/* Find maximum alignment power of sections between /* Find maximum alignment power of sections between
DATA_SEGMENT_ALIGN and DATA_SEGMENT_RELRO_END. */ DATA_SEGMENT_ALIGN and DATA_SEGMENT_RELRO_END. */
for (sec = output_bfd->sections; sec; sec = sec->next) for (sec = output_bfd->sections; sec; sec = sec->next)
if (sec->vma >= exp_data_seg.base if (sec->vma >= expld.dataseg.base
&& sec->vma < exp_data_seg.relro_end && sec->vma < expld.dataseg.relro_end
&& sec->alignment_power > max_alignment_power) && sec->alignment_power > max_alignment_power)
max_alignment_power = sec->alignment_power; max_alignment_power = sec->alignment_power;
if (((bfd_vma) 1 << max_alignment_power) < exp_data_seg.pagesize) if (((bfd_vma) 1 << max_alignment_power) < expld.dataseg.pagesize)
{ {
if (exp_data_seg.base - (1 << max_alignment_power) if (expld.dataseg.base - (1 << max_alignment_power)
< old_min_base) < old_min_base)
exp_data_seg.base += exp_data_seg.pagesize; expld.dataseg.base += expld.dataseg.pagesize;
exp_data_seg.base -= (1 << max_alignment_power); expld.dataseg.base -= (1 << max_alignment_power);
result = lang_size_sections_1 (s, output_section_statement, one_lang_size_sections_pass (relax, check_regions);
prev, fill, dot, relax,
check_regions);
} }
} }
link_info.relro_start = exp_data_seg.base; link_info.relro_start = expld.dataseg.base;
link_info.relro_end = exp_data_seg.relro_end; link_info.relro_end = expld.dataseg.relro_end;
} }
else if (exp_data_seg.phase == exp_dataseg_end_seen) else if (expld.dataseg.phase == exp_dataseg_end_seen)
{ {
/* If DATA_SEGMENT_ALIGN DATA_SEGMENT_END pair was seen, check whether /* If DATA_SEGMENT_ALIGN DATA_SEGMENT_END pair was seen, check whether
a page could be saved in the data segment. */ a page could be saved in the data segment. */
bfd_vma first, last; bfd_vma first, last;
first = -exp_data_seg.base & (exp_data_seg.pagesize - 1); first = -expld.dataseg.base & (expld.dataseg.pagesize - 1);
last = exp_data_seg.end & (exp_data_seg.pagesize - 1); last = expld.dataseg.end & (expld.dataseg.pagesize - 1);
if (first && last if (first && last
&& ((exp_data_seg.base & ~(exp_data_seg.pagesize - 1)) && ((expld.dataseg.base & ~(expld.dataseg.pagesize - 1))
!= (exp_data_seg.end & ~(exp_data_seg.pagesize - 1))) != (expld.dataseg.end & ~(expld.dataseg.pagesize - 1)))
&& first + last <= exp_data_seg.pagesize) && first + last <= expld.dataseg.pagesize)
{ {
exp_data_seg.phase = exp_dataseg_adjust; expld.dataseg.phase = exp_dataseg_adjust;
lang_statement_iteration++; one_lang_size_sections_pass (relax, check_regions);
result = lang_size_sections_1 (s, output_section_statement, prev,
fill, dot, relax, check_regions);
} }
} }
return result; expld.phase = lang_final_phase_enum;
} }
/* Worker function for lang_do_assignments. Recursiveness goes here. */ /* Worker function for lang_do_assignments. Recursiveness goes here. */
@ -4562,36 +4486,31 @@ lang_do_assignments_1
if (os->bfd_section && !os->ignored) if (os->bfd_section && !os->ignored)
{ {
os->bfd_section->lma os->bfd_section->lma
= exp_get_abs_int (os->load_base, 0, "load base", = exp_get_abs_int (os->load_base, 0, "load base");
lang_final_phase_enum);
} }
} }
} }
break; break;
case lang_wild_statement_enum: case lang_wild_statement_enum:
dot = lang_do_assignments_1 (s->wild_statement.children.head, dot = lang_do_assignments_1 (s->wild_statement.children.head,
output_section_statement, output_section_statement,
fill, dot); fill, dot);
break; break;
case lang_object_symbols_statement_enum: case lang_object_symbols_statement_enum:
case lang_output_statement_enum: case lang_output_statement_enum:
case lang_target_statement_enum: case lang_target_statement_enum:
break; break;
case lang_data_statement_enum:
{
etree_value_type value;
value = exp_fold_tree (s->data_statement.exp, case lang_data_statement_enum:
bfd_abs_section_ptr, exp_fold_tree (s->data_statement.exp, bfd_abs_section_ptr, &dot);
lang_final_phase_enum, dot, &dot); if (expld.result.valid_p)
if (!value.valid_p) s->data_statement.value = (expld.result.value
+ expld.result.section->vma);
else
einfo (_("%F%P: invalid data statement\n")); einfo (_("%F%P: invalid data statement\n"));
s->data_statement.value
= value.value + value.section->vma;
}
{ {
unsigned int size; unsigned int size;
switch (s->data_statement.type) switch (s->data_statement.type)
@ -4619,16 +4538,12 @@ lang_do_assignments_1
break; break;
case lang_reloc_statement_enum: case lang_reloc_statement_enum:
{ exp_fold_tree (s->reloc_statement.addend_exp,
etree_value_type value; bfd_abs_section_ptr, &dot);
if (expld.result.valid_p)
value = exp_fold_tree (s->reloc_statement.addend_exp, s->reloc_statement.addend_value = expld.result.value;
bfd_abs_section_ptr, else
lang_final_phase_enum, dot, &dot);
s->reloc_statement.addend_value = value.value;
if (!value.valid_p)
einfo (_("%F%P: invalid reloc statement\n")); einfo (_("%F%P: invalid reloc statement\n"));
}
dot += TO_ADDR (bfd_get_reloc_size (s->reloc_statement.howto)); dot += TO_ADDR (bfd_get_reloc_size (s->reloc_statement.howto));
break; break;
@ -4643,19 +4558,17 @@ lang_do_assignments_1
case lang_input_statement_enum: case lang_input_statement_enum:
break; break;
case lang_fill_statement_enum: case lang_fill_statement_enum:
fill = s->fill_statement.fill; fill = s->fill_statement.fill;
break; break;
case lang_assignment_statement_enum: case lang_assignment_statement_enum:
{
exp_fold_tree (s->assignment_statement.exp, exp_fold_tree (s->assignment_statement.exp,
output_section_statement->bfd_section, output_section_statement->bfd_section,
lang_final_phase_enum,
dot,
&dot); &dot);
}
break; break;
case lang_padding_statement_enum: case lang_padding_statement_enum:
dot += TO_ADDR (s->padding_statement.size); dot += TO_ADDR (s->padding_statement.size);
break; break;
@ -4664,30 +4577,24 @@ lang_do_assignments_1
dot = lang_do_assignments_1 (s->group_statement.children.head, dot = lang_do_assignments_1 (s->group_statement.children.head,
output_section_statement, output_section_statement,
fill, dot); fill, dot);
break; break;
default: default:
FAIL (); FAIL ();
break; break;
case lang_address_statement_enum: case lang_address_statement_enum:
break; break;
} }
} }
return dot; return dot;
} }
void void
lang_do_assignments lang_do_assignments (void)
(lang_statement_union_type *s,
lang_output_section_statement_type *output_section_statement,
fill_type *fill,
bfd_vma dot)
{ {
/* Callers of exp_fold_tree need to increment this. */
lang_statement_iteration++; lang_statement_iteration++;
lang_do_assignments_1 (s, output_section_statement, fill, dot); lang_do_assignments_1 (statement_list.head, abs_output_section, NULL, 0);
} }
/* Fix any .startof. or .sizeof. symbols. When the assemblers see the /* Fix any .startof. or .sizeof. symbols. When the assemblers see the
@ -5227,9 +5134,9 @@ lang_enter_output_section_statement (const char *output_section_statement_name,
stat_ptr = &os->children; stat_ptr = &os->children;
os->subsection_alignment = os->subsection_alignment =
topower (exp_get_value_int (subalign, -1, "subsection alignment", 0)); topower (exp_get_value_int (subalign, -1, "subsection alignment"));
os->section_alignment = os->section_alignment =
topower (exp_get_value_int (align, -1, "section alignment", 0)); topower (exp_get_value_int (align, -1, "section alignment"));
os->load_base = ebase; os->load_base = ebase;
return os; return os;
@ -5251,6 +5158,7 @@ lang_reset_memory_regions (void)
{ {
lang_memory_region_type *p = lang_memory_region_list; lang_memory_region_type *p = lang_memory_region_list;
asection *o; asection *o;
lang_output_section_statement_type *os;
for (p = lang_memory_region_list; p != NULL; p = p->next) for (p = lang_memory_region_list; p != NULL; p = p->next)
{ {
@ -5258,6 +5166,11 @@ lang_reset_memory_regions (void)
p->current = p->origin; p->current = p->origin;
} }
for (os = &lang_output_section_statement.head->output_section_statement;
os != NULL;
os = os->next)
os->processed = 0;
for (o = output_bfd->sections; o != NULL; o = o->next) for (o = output_bfd->sections; o != NULL; o = o->next)
{ {
/* Save the last size for possible use by bfd_relax_section. */ /* Save the last size for possible use by bfd_relax_section. */
@ -5444,9 +5357,7 @@ lang_process (void)
lang_record_phdrs (); lang_record_phdrs ();
/* Size up the sections. */ /* Size up the sections. */
lang_size_sections (statement_list.head, abs_output_section, lang_size_sections (NULL, !command_line.relax);
&statement_list.head, 0, 0, NULL,
command_line.relax ? FALSE : TRUE);
/* Now run around and relax if we can. */ /* Now run around and relax if we can. */
if (command_line.relax) if (command_line.relax)
@ -5464,8 +5375,7 @@ lang_process (void)
/* Do all the assignments with our current guesses as to /* Do all the assignments with our current guesses as to
section sizes. */ section sizes. */
lang_do_assignments (statement_list.head, abs_output_section, lang_do_assignments ();
NULL, 0);
/* We must do this after lang_do_assignments, because it uses /* We must do this after lang_do_assignments, because it uses
size. */ size. */
@ -5473,8 +5383,7 @@ lang_process (void)
/* Perform another relax pass - this time we know where the /* Perform another relax pass - this time we know where the
globals are, so can make a better guess. */ globals are, so can make a better guess. */
lang_size_sections (statement_list.head, abs_output_section, lang_size_sections (&relax_again, FALSE);
&statement_list.head, 0, 0, &relax_again, FALSE);
/* If the normal relax is done and the relax finalize pass /* If the normal relax is done and the relax finalize pass
is not performed yet, we perform another relax pass. */ is not performed yet, we perform another relax pass. */
@ -5487,10 +5396,9 @@ lang_process (void)
while (relax_again); while (relax_again);
/* Final extra sizing to report errors. */ /* Final extra sizing to report errors. */
lang_do_assignments (statement_list.head, abs_output_section, NULL, 0); lang_do_assignments ();
lang_reset_memory_regions (); lang_reset_memory_regions ();
lang_size_sections (statement_list.head, abs_output_section, lang_size_sections (NULL, TRUE);
&statement_list.head, 0, 0, NULL, TRUE);
} }
/* See if anything special should be done now we know how big /* See if anything special should be done now we know how big
@ -5503,7 +5411,7 @@ lang_process (void)
/* Do all the assignments, now that we know the final resting places /* Do all the assignments, now that we know the final resting places
of all the symbols. */ of all the symbols. */
lang_do_assignments (statement_list.head, abs_output_section, NULL, 0); lang_do_assignments ();
/* Make sure that the section addresses make sense. */ /* Make sure that the section addresses make sense. */
if (! link_info.relocatable if (! link_info.relocatable
@ -5891,8 +5799,7 @@ lang_new_phdr (const char *name,
n = stat_alloc (sizeof (struct lang_phdr)); n = stat_alloc (sizeof (struct lang_phdr));
n->next = NULL; n->next = NULL;
n->name = name; n->name = name;
n->type = exp_get_value_int (type, 0, "program header type", n->type = exp_get_value_int (type, 0, "program header type");
lang_final_phase_enum);
n->filehdr = filehdr; n->filehdr = filehdr;
n->phdrs = phdrs; n->phdrs = phdrs;
n->at = at; n->at = at;
@ -5968,14 +5875,12 @@ lang_record_phdrs (void)
if (l->flags == NULL) if (l->flags == NULL)
flags = 0; flags = 0;
else else
flags = exp_get_vma (l->flags, 0, "phdr flags", flags = exp_get_vma (l->flags, 0, "phdr flags");
lang_final_phase_enum);
if (l->at == NULL) if (l->at == NULL)
at = 0; at = 0;
else else
at = exp_get_vma (l->at, 0, "phdr load address", at = exp_get_vma (l->at, 0, "phdr load address");
lang_final_phase_enum);
if (! bfd_record_phdr (output_bfd, l->type, if (! bfd_record_phdr (output_bfd, l->type,
l->flags != NULL, flags, l->at != NULL, l->flags != NULL, flags, l->at != NULL,

View File

@ -509,8 +509,7 @@ extern void lang_for_each_file
extern void lang_reset_memory_regions extern void lang_reset_memory_regions
(void); (void);
extern void lang_do_assignments extern void lang_do_assignments
(lang_statement_union_type *, lang_output_section_statement_type *, (void);
fill_type *, bfd_vma);
#define LANG_FOR_EACH_INPUT_STATEMENT(statement) \ #define LANG_FOR_EACH_INPUT_STATEMENT(statement) \
lang_input_statement_type *statement; \ lang_input_statement_type *statement; \
@ -556,10 +555,10 @@ extern void strip_excluded_output_sections
(void); (void);
extern void dprint_statement extern void dprint_statement
(lang_statement_union_type *, int); (lang_statement_union_type *, int);
extern bfd_vma lang_size_sections extern void lang_size_sections
(lang_statement_union_type *, lang_output_section_statement_type *, (bfd_boolean *, bfd_boolean);
lang_statement_union_type **, fill_type *, bfd_vma, bfd_boolean *, extern void one_lang_size_sections_pass
bfd_boolean); (bfd_boolean *, bfd_boolean);
extern void lang_enter_group extern void lang_enter_group
(void); (void);
extern void lang_leave_group extern void lang_leave_group

View File

@ -2636,14 +2636,13 @@ pe_dll_fill_sections (bfd *abfd, struct bfd_link_info *info)
bfd_set_section_size (filler_bfd, reloc_s, reloc_sz); bfd_set_section_size (filler_bfd, reloc_s, reloc_sz);
/* Resize the sections. */ /* Resize the sections. */
lang_size_sections (stat_ptr->head, abs_output_section, lang_size_sections (NULL, TRUE);
&stat_ptr->head, 0, 0, NULL, TRUE);
/* Redo special stuff. */ /* Redo special stuff. */
ldemul_after_allocation (); ldemul_after_allocation ();
/* Do the assignments again. */ /* Do the assignments again. */
lang_do_assignments (stat_ptr->head, abs_output_section, NULL, 0); lang_do_assignments ();
} }
fill_edata (abfd, info); fill_edata (abfd, info);
@ -2667,14 +2666,13 @@ pe_exe_fill_sections (bfd *abfd, struct bfd_link_info *info)
bfd_set_section_size (filler_bfd, reloc_s, reloc_sz); bfd_set_section_size (filler_bfd, reloc_s, reloc_sz);
/* Resize the sections. */ /* Resize the sections. */
lang_size_sections (stat_ptr->head, abs_output_section, lang_size_sections (NULL, TRUE);
&stat_ptr->head, 0, 0, NULL, TRUE);
/* Redo special stuff. */ /* Redo special stuff. */
ldemul_after_allocation (); ldemul_after_allocation ();
/* Do the assignments again. */ /* Do the assignments again. */
lang_do_assignments (stat_ptr->head, abs_output_section, NULL, 0); lang_do_assignments ();
} }
reloc_s->contents = reloc_d; reloc_s->contents = reloc_d;
} }