* ld.texinfo (Simple Example): Add missing punctuation.
[deliverable/binutils-gdb.git] / ld / ldlang.c
index ac7ab332876d97c298755960b1cc22aee905d2b4..6460c32ab6de24826358b29a92e28f50f7a90c7d 100644 (file)
@@ -445,6 +445,7 @@ new_afile (const char *name,
   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,
@@ -622,7 +623,7 @@ lang_output_section_statement_lookup (const char *const name)
 
       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);
@@ -775,6 +776,10 @@ exp_init_os (etree_type *exp)
       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;
@@ -1097,10 +1102,6 @@ lang_add_section (lang_statement_list_type *ptr,
          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)
@@ -1842,7 +1843,7 @@ open_input_bfds (lang_statement_union_type *s, bfd_boolean force)
          /* 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:
@@ -2094,10 +2095,14 @@ map_input_to_output_sections
                                        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:
@@ -2762,8 +2767,11 @@ size_input_section (lang_statement_union_type **this_ptr,
 }
 
 #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
@@ -2828,7 +2836,7 @@ _("%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"),
 
 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)
 {
@@ -2976,12 +2984,15 @@ lang_size_sections_1
                  {
                    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;
@@ -3010,16 +3021,18 @@ lang_size_sections_1
 
            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,
@@ -3081,6 +3094,11 @@ lang_size_sections_1
            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:
@@ -3286,6 +3304,7 @@ lang_size_sections
          && 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);
        }
@@ -3330,11 +3349,12 @@ lang_do_assignments_1
            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)
              {
@@ -3371,9 +3391,10 @@ lang_do_assignments_1
            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;
@@ -3668,7 +3689,7 @@ lang_check (void)
          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)
@@ -3919,24 +3940,6 @@ lang_for_each_file (void (*func) (lang_input_statement_type *))
     }
 }
 
-#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)
 {
@@ -4503,34 +4506,38 @@ lang_float (bfd_boolean maybe)
    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 (&current_section->region,
                    &current_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;
@@ -4689,7 +4696,7 @@ lang_record_phdrs (void)
 {
   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;
 
@@ -4708,7 +4715,7 @@ lang_record_phdrs (void)
           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;
 
@@ -4768,7 +4775,7 @@ lang_record_phdrs (void)
        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;
@@ -4785,7 +4792,7 @@ lang_record_phdrs (void)
 /* 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;
 
@@ -4870,7 +4877,7 @@ lang_enter_overlay_section (const char *name)
 
 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;
@@ -4917,17 +4924,17 @@ lang_leave_overlay (etree_type *lma_expr,
                    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 (&region, &lma_region,
                    memspec, lma_memspec,
-                   lma_expr != 0);
+                   lma_expr != NULL, FALSE);
 
   nocrossref = NULL;
 
@@ -4964,7 +4971,7 @@ lang_leave_overlay (etree_type *lma_expr,
 
       if (nocrossrefs)
        {
-         struct lang_nocrossref *nc;
+         lang_nocrossref_type *nc;
 
          nc = xmalloc (sizeof *nc);
          nc->name = l->os->name;
This page took 0.027497 seconds and 4 git commands to generate.