p->next = NULL;
p->symbol_count = 0;
p->dynamic = config.dynamic_link;
+ p->as_needed = as_needed;
p->whole_archive = whole_archive;
p->loaded = FALSE;
lang_statement_append (&input_file_chain,
lookup->next = NULL;
lookup->bfd_section = NULL;
- lookup->processed = FALSE;
+ lookup->processed = 0;
lookup->sectype = normal_section;
lookup->addr_tree = NULL;
lang_list_init (&lookup->children);
exp_init_os (exp->trinary.rhs);
break;
+ case etree_assert:
+ exp_init_os (exp->assert_s.child);
+ break;
+
case etree_unary:
exp_init_os (exp->unary.child);
break;
flags &= ~ (SEC_MERGE | SEC_STRINGS);
}
- /* For now make .tbss normal section. */
- if ((flags & SEC_THREAD_LOCAL) && ! link_info.relocatable)
- flags |= SEC_LOAD;
-
section->output_section->flags |= flags;
if (flags & SEC_MERGE)
/* Maybe we should load the file's symbols. */
if (s->wild_statement.filename
&& ! wildcardp (s->wild_statement.filename))
- (void) lookup_name (s->wild_statement.filename);
+ lookup_name (s->wild_statement.filename);
open_input_bfds (s->wild_statement.children.head, force);
break;
case lang_group_statement_enum:
target,
output_section_statement);
break;
+ case lang_data_statement_enum:
+ /* Make sure that any sections mentioned in the expression
+ are initialized. */
+ exp_init_os (s->data_statement.exp);
+ /* FALLTHROUGH */
case lang_fill_statement_enum:
case lang_input_section_enum:
case lang_object_symbols_statement_enum:
- case lang_data_statement_enum:
case lang_reloc_statement_enum:
case lang_padding_statement_enum:
case lang_input_statement_enum:
}
#define IGNORE_SECTION(bfd, s) \
- (((bfd_get_section_flags (bfd, s) & (SEC_ALLOC | SEC_NEVER_LOAD)) \
- != SEC_ALLOC) \
+ (((bfd_get_section_flags (bfd, s) & SEC_THREAD_LOCAL) \
+ ? ((bfd_get_section_flags (bfd, s) & (SEC_LOAD | SEC_NEVER_LOAD)) \
+ != SEC_LOAD) \
+ : ((bfd_get_section_flags (bfd, s) & (SEC_ALLOC | SEC_NEVER_LOAD)) \
+ != SEC_ALLOC)) \
|| bfd_section_size (bfd, s) == 0)
/* Check to see if any allocated sections overlap with other allocated
static void
os_region_check (lang_output_section_statement_type *os,
- struct memory_region_struct *region,
+ lang_memory_region_type *region,
etree_type *tree,
bfd_vma base)
{
{
etree_value_type r;
+ os->processed = -1;
r = exp_fold_tree (os->addr_tree,
abs_output_section,
lang_allocating_phase_enum,
dot, &dot);
+ os->processed = 0;
+
if (!r.valid_p)
- einfo (_("%F%S: non constant address expression for section %s\n"),
+ einfo (_("%F%S: non constant or forward reference address expression for section %s\n"),
os->name);
dot = r.value + r.section->bfd_section->vma;
if (bfd_is_abs_section (os->bfd_section))
ASSERT (after == os->bfd_section->vma);
- else if ((os->bfd_section->flags & SEC_HAS_CONTENTS) == 0
- && (os->bfd_section->flags & SEC_THREAD_LOCAL)
- && ! link_info.relocatable)
- os->bfd_section->_raw_size = 0;
else
os->bfd_section->_raw_size
= TO_SIZE (after - os->bfd_section->vma);
- dot = os->bfd_section->vma + TO_ADDR (os->bfd_section->_raw_size);
- os->processed = TRUE;
+ dot = os->bfd_section->vma;
+ /* .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->_raw_size);
+
+ os->processed = 1;
if (os->update_dot_tree != 0)
exp_fold_tree (os->update_dot_tree, abs_output_section,
s->data_statement.output_section =
output_section_statement->bfd_section;
+ /* We might refer to provided symbols in the expression, and
+ need to mark them as needed. */
+ exp_fold_tree (s->data_statement.exp, abs_output_section,
+ lang_allocating_phase_enum, dot, &dot);
+
switch (s->data_statement.type)
{
default:
&& first + last <= exp_data_seg.pagesize)
{
exp_data_seg.phase = exp_dataseg_adjust;
+ lang_statement_iteration++;
result = lang_size_sections_1 (s, output_section_statement, prev,
fill, dot, relax, check_regions);
}
if (os->bfd_section != NULL)
{
dot = os->bfd_section->vma;
- (void) lang_do_assignments_1 (os->children.head, os,
- os->fill, dot);
- dot = (os->bfd_section->vma
- + TO_ADDR (os->bfd_section->_raw_size));
-
+ 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->_raw_size);
}
if (os->load_base)
{
value = exp_fold_tree (s->data_statement.exp,
abs_output_section,
lang_final_phase_enum, dot, &dot);
- s->data_statement.value = value.value;
if (!value.valid_p)
einfo (_("%F%P: invalid data statement\n"));
+ s->data_statement.value
+ = value.value + value.section->bfd_section->vma;
}
{
unsigned int size;
if (! bfd_merge_private_bfd_data (input_bfd, output_bfd))
{
if (command_line.warn_mismatch)
- einfo (_("%E%X: failed to merge target specific data of file %B\n"),
+ einfo (_("%P%X: failed to merge target specific data of file %B\n"),
input_bfd);
}
if (! command_line.warn_mismatch)
}
}
-#if 0
-
-/* Not used. */
-
-void
-lang_for_each_input_section (void (*func) (bfd *ab, asection *as))
-{
- LANG_FOR_EACH_INPUT_STATEMENT (f)
- {
- asection *s;
-
- for (s = f->the_bfd->sections; s != NULL; s = s->next)
- func (f->the_bfd, s);
- }
-}
-
-#endif
-
void
ldlang_add_file (lang_input_statement_type *entry)
{
It is an error to specify both a load region and a load address. */
static void
-lang_get_regions (struct memory_region_struct **region,
- struct memory_region_struct **lma_region,
+lang_get_regions (lang_memory_region_type **region,
+ lang_memory_region_type **lma_region,
const char *memspec,
const char *lma_memspec,
- int have_lma_p)
+ bfd_boolean have_lma,
+ bfd_boolean have_vma)
{
*lma_region = lang_memory_region_lookup (lma_memspec, FALSE);
- /* If no runtime region has been given, but the load region has
- been, use the load region. */
- if (lma_memspec != 0 && strcmp (memspec, DEFAULT_MEMORY_REGION) == 0)
+ /* If no runtime region or VMA has been specified, but the load region has
+ been specified, then use the load region for the runtime region as well. */
+ if (lma_memspec != NULL
+ && ! have_vma
+ && strcmp (memspec, DEFAULT_MEMORY_REGION) == 0)
*region = *lma_region;
else
*region = lang_memory_region_lookup (memspec, FALSE);
- if (have_lma_p && lma_memspec != 0)
+ if (have_lma && lma_memspec != 0)
einfo (_("%X%P:%S: section has both a load address and a load region\n"));
}
void
-lang_leave_output_section_statement
- (fill_type *fill, const char *memspec,
- struct lang_output_section_phdr_list *phdrs, const char *lma_memspec)
+lang_leave_output_section_statement (fill_type *fill, const char *memspec,
+ lang_output_section_phdr_list *phdrs,
+ const char *lma_memspec)
{
lang_get_regions (¤t_section->region,
¤t_section->lma_region,
memspec, lma_memspec,
- current_section->load_base != 0);
+ current_section->load_base != NULL,
+ current_section->addr_tree != NULL);
current_section->fill = fill;
current_section->phdrs = phdrs;
stat_ptr = &statement_list;
{
unsigned int alc;
asection **secs;
- struct lang_output_section_phdr_list *last;
+ lang_output_section_phdr_list *last;
struct lang_phdr *l;
lang_statement_union_type *u;
u = u->output_section_statement.next)
{
lang_output_section_statement_type *os;
- struct lang_output_section_phdr_list *pl;
+ lang_output_section_phdr_list *pl;
os = &u->output_section_statement;
u != NULL;
u = u->output_section_statement.next)
{
- struct lang_output_section_phdr_list *pl;
+ lang_output_section_phdr_list *pl;
if (u->output_section_statement.bfd_section == NULL)
continue;
/* Record a list of sections which may not be cross referenced. */
void
-lang_add_nocrossref (struct lang_nocrossref *l)
+lang_add_nocrossref (lang_nocrossref_type *l)
{
struct lang_nocrossrefs *n;
void
lang_leave_overlay_section (fill_type *fill,
- struct lang_output_section_phdr_list *phdrs)
+ lang_output_section_phdr_list *phdrs)
{
const char *name;
char *clean, *s2;
int nocrossrefs,
fill_type *fill,
const char *memspec,
- struct lang_output_section_phdr_list *phdrs,
+ lang_output_section_phdr_list *phdrs,
const char *lma_memspec)
{
lang_memory_region_type *region;
lang_memory_region_type *lma_region;
struct overlay_list *l;
- struct lang_nocrossref *nocrossref;
+ lang_nocrossref_type *nocrossref;
lang_get_regions (®ion, &lma_region,
memspec, lma_memspec,
- lma_expr != 0);
+ lma_expr != NULL, FALSE);
nocrossref = NULL;
if (nocrossrefs)
{
- struct lang_nocrossref *nc;
+ lang_nocrossref_type *nc;
nc = xmalloc (sizeof *nc);
nc->name = l->os->name;