one line fix by Gregory Lielens <Gregory.Lielens@fft.be> to fix a problem
[deliverable/binutils-gdb.git] / ld / ldlang.c
index 33dc573c0d7ea26043b5a7c73b424f9960291a12..d43140f06b2fa4970b3833e848110fb1dd2df06f 100644 (file)
@@ -1,5 +1,5 @@
 /* Linker command language support.
-   Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 1999
+   Copyright (C) 1991, 92, 93, 94, 95, 96, 97, 98, 99, 2000
    Free Software Foundation, Inc.
 
 This file is part of GLD, the Gnu Linker.
@@ -58,7 +58,6 @@ static lang_output_section_statement_type *default_common_section;
 static boolean map_option_f;
 static bfd_vma print_dot;
 static lang_input_statement_type *first_file;
-static lang_statement_list_type lang_output_section_statement;
 static CONST char *current_target;
 static CONST char *output_target;
 static lang_statement_list_type statement_list;
@@ -166,6 +165,7 @@ static char * get_first_input_target PARAMS ((void));
                                        
 /* EXPORTS */
 lang_output_section_statement_type *abs_output_section;
+lang_statement_list_type lang_output_section_statement;
 lang_statement_list_type *stat_ptr = &statement_list;
 lang_statement_list_type file_chain = { NULL, NULL };
 const char *entry_symbol = NULL;
@@ -213,17 +213,21 @@ walk_wild_section (ptr, section, file, callback, data)
      void *data;
 {
   /* Don't process sections from files which were excluded. */
-  if (ptr->exclude_filename != NULL)
+  if (ptr->exclude_filename_list != NULL)
     {
-      boolean match;
+      struct name_list *list_tmp;
+      for (list_tmp = ptr->exclude_filename_list; list_tmp; list_tmp = list_tmp->next)
+        {
+         boolean match;
 
-      if (wildcardp (ptr->exclude_filename))
-         match = fnmatch (ptr->exclude_filename, file->filename, 0) == 0 ? true : false;
-      else
-         match = strcmp (ptr->exclude_filename, file->filename) == 0 ? true : false;
+         if (wildcardp (list_tmp->name))
+           match = fnmatch (list_tmp->name, file->filename, 0) == 0 ? true : false;
+         else
+           match = strcmp (list_tmp->name, file->filename) == 0 ? true : false;
 
-      if (match)
-        return;
+         if (match)
+           return;
+       }
     }
 
   if (file->just_syms_flag == false)
@@ -678,6 +682,7 @@ lang_output_section_statement_lookup (name)
       lookup = (lang_output_section_statement_type *)
        new_stat (lang_output_section_statement, stat_ptr);
       lookup->region = (lang_memory_region_type *) NULL;
+      lookup->lma_region = (lang_memory_region_type *) NULL;
       lookup->fill = 0;
       lookup->block_value = 1;
       lookup->name = name;
@@ -1859,8 +1864,10 @@ open_input_bfds (s, force)
 
              /* If we are being called from within a group, and this
                  is an archive which has already been searched, then
-                 force it to be researched.  */
+                 force it to be researched unless the whole archive
+                has been loaded already.  */
              if (force
+                 && !s->input_statement.whole_archive
                  && s->input_statement.loaded
                  && bfd_check_format (s->input_statement.the_bfd,
                                       bfd_archive))
@@ -2164,7 +2171,8 @@ print_input_section (in)
 {
   asection *i = in->section;
   bfd_size_type size = i->_cooked_size != 0 ? i->_cooked_size : i->_raw_size;
-
+  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, 
+                                               ldfile_output_machine);
   if (size != 0)
     {
       print_space ();
@@ -2188,7 +2196,7 @@ print_input_section (in)
            }
 
          minfo ("0x%V %W %B\n",
-                i->output_section->vma + i->output_offset, size,
+                i->output_section->vma + i->output_offset, size / opb,
                 i->owner);
 
          if (i->_cooked_size != 0 && i->_cooked_size != i->_raw_size)
@@ -2210,7 +2218,7 @@ print_input_section (in)
 
          bfd_link_hash_traverse (link_info.hash, print_one_symbol, (PTR) i);
 
-         print_dot = i->output_section->vma + i->output_offset + size;
+         print_dot = i->output_section->vma + i->output_offset + size / opb;
        }
     }
 }
@@ -2230,6 +2238,8 @@ print_data_statement (data)
   bfd_vma addr;
   bfd_size_type size;
   const char *name;
+  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, 
+                                               ldfile_output_machine);
 
   for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
     print_space ();
@@ -2274,7 +2284,8 @@ print_data_statement (data)
 
   print_nl ();
 
-  print_dot = addr + size;
+  print_dot = addr + size / opb;
+
 }
 
 /* Print an address statement.  These are generated by options like
@@ -2298,6 +2309,8 @@ print_reloc_statement (reloc)
   int i;
   bfd_vma addr;
   bfd_size_type size;
+  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, 
+                                               ldfile_output_machine); 
 
   for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
     print_space ();
@@ -2319,7 +2332,7 @@ print_reloc_statement (reloc)
 
   print_nl ();
 
-  print_dot = addr + size;
+  print_dot = addr + size / opb;
 }  
 
 static void
@@ -2328,6 +2341,8 @@ print_padding_statement (s)
 {
   int len;
   bfd_vma addr;
+  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, 
+                                               ldfile_output_machine); 
 
   minfo (" *fill*");
 
@@ -2348,7 +2363,7 @@ print_padding_statement (s)
 
   print_nl ();
 
-  print_dot = addr + s->size;
+  print_dot = addr + s->size / opb;
 }
 
 static void
@@ -2360,9 +2375,15 @@ print_wild_statement (w, os)
 
   if (w->filenames_sorted)
     minfo ("SORT(");
-  if (w->exclude_filename != NULL)
-    minfo ("EXCLUDE_FILE ( %s )", w->exclude_filename);
-  if (w->filename != NULL)
+  if (w->exclude_filename_list != NULL)
+    {
+      name_list *tmp;
+      minfo ("EXCLUDE_FILE ( %s", w->exclude_filename_list->name);
+      for (tmp=w->exclude_filename_list->next; tmp; tmp = tmp->next)
+        minfo (", %s", tmp->name);
+      minfo (")");
+     }
+   if (w->filename != NULL)
     minfo ("%s", w->filename);
   else
     minfo ("*");
@@ -2537,6 +2558,8 @@ insert_pad (this_ptr, fill, power, output_section_statement, dot)
      inserting a magic 'padding' statement.
      */
 
+  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, 
+                                               ldfile_output_machine); 
   unsigned int alignment_needed = align_power (dot, power) - dot;
 
   if (alignment_needed != 0)
@@ -2553,7 +2576,7 @@ insert_pad (this_ptr, fill, power, output_section_statement, dot)
       new->padding_statement.output_offset =
        dot - output_section_statement->vma;
       new->padding_statement.fill = fill;
-      new->padding_statement.size = alignment_needed;
+      new->padding_statement.size = alignment_needed * opb;
     }
 
 
@@ -2562,9 +2585,9 @@ insert_pad (this_ptr, fill, power, output_section_statement, dot)
     {
       output_section_statement->alignment_power = power;
     }
-  output_section_statement->_raw_size += alignment_needed;
-  return alignment_needed + dot;
+  output_section_statement->_raw_size += alignment_needed * opb;
 
+  return dot + alignment_needed;
 }
 
 /* Work out how much this section will move the dot point */
@@ -2578,6 +2601,8 @@ size_input_section (this_ptr, output_section_statement, fill, dot, relax)
 {
   lang_input_section_type *is = &((*this_ptr)->input_section);
   asection *i = is->section;
+  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, 
+                                               ldfile_output_machine); 
 
   if (is->ifile->just_syms_flag == false)
     {
@@ -2595,10 +2620,11 @@ size_input_section (this_ptr, output_section_statement, fill, dot, relax)
       /* Mark how big the output section must be to contain this now
         */
       if (i->_cooked_size != 0)
-       dot += i->_cooked_size;
+       dot += i->_cooked_size / opb;
       else
-       dot += i->_raw_size;
-      output_section_statement->bfd_section->_raw_size = dot - output_section_statement->bfd_section->vma;
+       dot += i->_raw_size / opb;
+      output_section_statement->bfd_section->_raw_size = 
+        (dot - output_section_statement->bfd_section->vma) * opb;
     }
   else
     {
@@ -2608,6 +2634,10 @@ size_input_section (this_ptr, output_section_statement, fill, dot, relax)
   return dot;
 }
 
+#define IGNORE_SECTION(bfd, s) \
+  (((bfd_get_section_flags (bfd, s) & (SEC_ALLOC | SEC_LOAD)) != (SEC_ALLOC | SEC_LOAD)) \
+   || bfd_section_size (bfd, s) == 0)
+
 /* Check to see if any allocated sections overlap with other allocated
    sections.  This can happen when the linker script specifically specifies
    the output section addresses of the two sections.  */
@@ -2615,52 +2645,52 @@ static void
 lang_check_section_addresses ()
 {
   asection * s;
+  unsigned opb = bfd_octets_per_byte (output_bfd);
 
   /* Scan all sections in the output list.  */
   for (s = output_bfd->sections; s != NULL; s = s->next)
-    /* Ignore sections which are not loaded or which have no contents.  */
-    if ((bfd_get_section_flags (output_bfd, s) & (SEC_ALLOC | SEC_LOAD))
-       && bfd_section_size (output_bfd, s) != 0)
-      {
-       asection * os;
+    {
+      asection * os;
+      
+      /* Ignore sections which are not loaded or which have no contents.  */
+      if (IGNORE_SECTION (output_bfd, s))
+       continue;
+      
+      /* Once we reach section 's' stop our seach.  This prevents two
+        warning messages from being produced, one for 'section A overlaps
+        section B' and one for 'section B overlaps section A'.  */
+      for (os = output_bfd->sections; os != s; os = os->next)
+       {
+         bfd_vma s_start;
+         bfd_vma s_end;
+         bfd_vma os_start;
+         bfd_vma os_end;
+         
+         /* Only consider loadable sections with real contents.  */
+         if (IGNORE_SECTION (output_bfd, os))
+           continue;
 
-       /* Once we reach section 's' stop our seach.  This prevents two
-          warning messages from being produced, one for 'section A overlaps
-          section B' and one for 'section B overlaps section A'.  */
-       for (os = output_bfd->sections; os != s; os = os->next)
-         {
-           bfd_vma s_start;
-           bfd_vma s_end;
-           bfd_vma os_start;
-           bfd_vma os_end;
-
-           /* Only consider loadable sections with real contents.  */
-           if (((bfd_get_section_flags (output_bfd, os)
-                 & (SEC_ALLOC | SEC_LOAD)) == 0)
-               || bfd_section_size (output_bfd, os) == 0)
-             continue;
-
-           /* We must check the sections' LMA addresses not their
-              VMA addresses because overlay sections can have
-              overlapping VMAs but they must have distinct LMAs.  */
-           s_start  = bfd_section_lma (output_bfd, s);
-           os_start = bfd_section_lma (output_bfd, os);
-           s_end    = s_start  + bfd_section_size (output_bfd, s) - 1;
-           os_end   = os_start + bfd_section_size (output_bfd, os) - 1;
-
-           /* Look for an overlap.  */
-           if ((s_end < os_start) || (s_start > os_end))
-             continue;
-           
-           einfo (
+         /* We must check the sections' LMA addresses not their
+            VMA addresses because overlay sections can have
+            overlapping VMAs but they must have distinct LMAs.  */
+         s_start  = bfd_section_lma (output_bfd, s);
+         os_start = bfd_section_lma (output_bfd, os);
+         s_end    = s_start  + bfd_section_size (output_bfd, s) / opb - 1;
+         os_end   = os_start + bfd_section_size (output_bfd, os) / opb - 1;
+         
+         /* Look for an overlap.  */
+         if ((s_end < os_start) || (s_start > os_end))
+           continue;
+         
+         einfo (
 _("%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"),
-                  s->name, s_start, s_end, os->name, os_start, os_end);
-
-           /* Once we have found one overlap for this section,
-              stop looking for others.  */
-           break;
-         }
-      }
+                s->name, s_start, s_end, os->name, os_start, os_end);
+         
+         /* Once we have found one overlap for this section,
+            stop looking for others.  */
+         break;
+       }
+    }
 }
 
 /* This variable indicates whether bfd_relax_section should be called
@@ -2668,6 +2698,43 @@ _("%X%P: section %s [%V -> %V] overlaps section %s [%V -> %V]\n"),
 
 static boolean relax_again;
 
+/* Make sure the new address is within the region.  We explicitly permit the
+   current address to be at the exact end of the region when the address is
+   non-zero, in case the region is at the end of addressable memory and the
+   calculation wraps around.  */ 
+
+static void
+os_region_check (os, region, tree, base)
+  lang_output_section_statement_type *os;
+  struct memory_region_struct *region;
+  etree_type *tree;
+  bfd_vma base;
+{
+  if ((region->current < region->origin
+       || (region->current - region->origin > region->length))
+      && ((region->current != region->origin + region->length)
+           || base == 0))
+    {
+      if (tree != (etree_type *) NULL)
+        {
+          einfo (_("%X%P: address 0x%v of %B section %s is not within region %s\n"),
+                 region->current,
+                 os->bfd_section->owner,
+                 os->bfd_section->name,
+                 region->name);
+        }
+      else
+        {
+          einfo (_("%X%P: region %s is full (%B section %s)\n"),
+                 region->name,
+                 os->bfd_section->owner,
+                 os->bfd_section->name);
+        }
+      /* Reset the region pointer.  */
+      region->current = region->origin;
+    }
+}
+
 /* Set the sizes for all the output sections.  */
 
 bfd_vma
@@ -2679,6 +2746,9 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
      bfd_vma dot;
      boolean relax;
 {
+  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, 
+                                               ldfile_output_machine);
+
   /* Size up the sections from their constituent parts.  */
   for (; s != (lang_statement_union_type *) NULL; s = s->next)
     {
@@ -2792,62 +2862,66 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
            (void) lang_size_sections (os->children.head, os, &os->children.head,
                                       os->fill, dot, relax);
            
-           /* Ignore the size of the input sections, use the vma and size to
-              align against.  */
-
-           after = ALIGN_N (os->bfd_section->vma +
-                            os->bfd_section->_raw_size,
+            /* put the section within the requested block size, or align at
+               the block boundary */
+           after = ALIGN_N (os->bfd_section->vma
+                            + os->bfd_section->_raw_size / opb,
                             /* The coercion here is important, see ld.h.  */
                             (bfd_vma) os->block_value);
 
            if (bfd_is_abs_section (os->bfd_section))
              ASSERT (after == os->bfd_section->vma);
            else
-             os->bfd_section->_raw_size = after - os->bfd_section->vma;
-           dot = os->bfd_section->vma + os->bfd_section->_raw_size;
+             os->bfd_section->_raw_size = 
+                (after - os->bfd_section->vma) * opb;
+           dot = os->bfd_section->vma + os->bfd_section->_raw_size / opb;
            os->processed = true;
 
            /* Update dot in the region ?
               We only do this if the section is going to be allocated,
               since unallocated sections do not contribute to the region's
-              overall size in memory.  */
+              overall size in memory.
+              
+              If the SEC_NEVER_LOAD bit is not set, it will affect the
+              addresses of sections after it. We have to update
+              dot.  */
            if (os->region != (lang_memory_region_type *) NULL
-               && (bfd_get_section_flags (output_bfd, os->bfd_section)
-                   & (SEC_ALLOC | SEC_LOAD)))
+               && ((bfd_get_section_flags (output_bfd, os->bfd_section)
+                    & SEC_NEVER_LOAD) == 0
+                   || (bfd_get_section_flags (output_bfd, os->bfd_section)
+                       & (SEC_ALLOC | SEC_LOAD))))
              {
                os->region->current = dot;
                
-               /* Make sure the new address is within the region.  We
-                   explicitly permit the current address to be at the
-                   exact end of the region when the VMA is non-zero,
-                   in case the region is at the end of addressable
-                   memory and the calculation wraps around.  */
-               if ((os->region->current < os->region->origin
-                    || (os->region->current - os->region->origin
-                        > os->region->length))
-                   && ((os->region->current
-                        != os->region->origin + os->region->length)
-                       || os->bfd_section->vma == 0))
-
-                 {
-                   if (os->addr_tree != (etree_type *) NULL)
-                     {
-                       einfo (_("%X%P: address 0x%v of %B section %s is not within region %s\n"),
-                              os->region->current,
-                              os->bfd_section->owner,
-                              os->bfd_section->name,
-                              os->region->name);
-                     }
-                   else
-                     {
-                       einfo (_("%X%P: region %s is full (%B section %s)\n"),
-                              os->region->name,
-                              os->bfd_section->owner,
-                              os->bfd_section->name);
-                     }
-                   /* Reset the region pointer.  */
-                   os->region->current = os->region->origin;
-                 }
+               /* Make sure the new address is within the region.  */
+                os_region_check (os, os->region, os->addr_tree, 
+                                 os->bfd_section->vma);
+
+                /* if there's no load address specified, use the run region as
+                   the load region */
+                if (os->lma_region == NULL && os->load_base == NULL)
+                    os->lma_region = os->region;
+
+                if (os->lma_region != NULL)
+                  {
+                    if (os->load_base != NULL)
+                      {
+                        einfo (_("%X%P: use an absolute load address or a load memory region, not both\n"));
+                      }
+                    else
+                      {
+                        /* don't allocate twice */
+                        if (os->lma_region != os->region)
+                          {
+                            /* set load_base, which will be handled later */
+                            os->load_base = exp_intop (os->lma_region->current);
+                            os->lma_region->current += 
+                              os->bfd_section->_raw_size / opb;
+                            os_region_check (os, os->lma_region, NULL,
+                                             os->bfd_section->lma);
+                          }
+                      }
+                  }
              }
          }
          break;
@@ -2870,6 +2944,8 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
 
            switch (s->data_statement.type)
              {
+              default:
+                abort();
              case QUAD:
              case SQUAD:
                size = QUAD_SIZE;
@@ -2884,8 +2960,9 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
                size = BYTE_SIZE;
                break;
              }
-
-           dot += size;
+            if (size < opb)
+              size = opb;
+           dot += size / opb;
            output_section_statement->bfd_section->_raw_size += size;
            /* The output section gets contents, and then we inspect for
               any flags set in the input script which override any ALLOC.  */
@@ -2905,7 +2982,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
            s->reloc_statement.output_section =
              output_section_statement->bfd_section;
            size = bfd_get_reloc_size (s->reloc_statement.howto);
-           dot += size;
+           dot += size / opb;
            output_section_statement->bfd_section->_raw_size += size;
          }
          break;
@@ -2993,7 +3070,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
                    new->padding_statement.output_offset =
                      dot - output_section_statement->bfd_section->vma;
                    new->padding_statement.fill = fill;
-                   new->padding_statement.size = newdot - dot;
+                   new->padding_statement.size = (newdot - dot) * opb;
                    output_section_statement->bfd_section->_raw_size +=
                      new->padding_statement.size;
                  }
@@ -3011,7 +3088,7 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
             pass than it did at this point in the previous pass.  */
          s->padding_statement.output_offset =
            dot - output_section_statement->bfd_section->vma;
-         dot += s->padding_statement.size;
+         dot += s->padding_statement.size / opb;
          output_section_statement->bfd_section->_raw_size +=
            s->padding_statement.size;
          break;
@@ -3044,6 +3121,9 @@ lang_do_assignments (s, output_section_statement, fill, dot)
      fill_type fill;
      bfd_vma dot;
 {
+  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, 
+                                               ldfile_output_machine); 
+
   for (; s != (lang_statement_union_type *) NULL; s = s->next)
     {
       switch (s->header.type)
@@ -3065,7 +3145,8 @@ lang_do_assignments (s, output_section_statement, fill, dot)
                dot = os->bfd_section->vma;
                (void) lang_do_assignments (os->children.head, os,
                                            os->fill, dot);
-               dot = os->bfd_section->vma + os->bfd_section->_raw_size;
+               dot = os->bfd_section->vma + os->bfd_section->_raw_size / opb;
+
              }
            if (os->load_base) 
              {
@@ -3105,22 +3186,30 @@ lang_do_assignments (s, output_section_statement, fill, dot)
            if (value.valid_p == false)
              einfo (_("%F%P: invalid data statement\n"));
          }
-         switch (s->data_statement.type)
-           {
-           case QUAD:
-           case SQUAD:
-             dot += QUAD_SIZE;
-             break;
-           case LONG:
-             dot += LONG_SIZE;
-             break;
-           case SHORT:
-             dot += SHORT_SIZE;
-             break;
-           case BYTE:
-             dot += BYTE_SIZE;
-             break;
-           }
+          {
+            unsigned int size;
+            switch (s->data_statement.type)
+              {
+              default:
+                abort();
+              case QUAD:
+              case SQUAD:
+                size = QUAD_SIZE;
+                break;
+              case LONG:
+                size = LONG_SIZE;
+                break;
+              case SHORT:
+                size = SHORT_SIZE;
+                break;
+              case BYTE:
+                size = BYTE_SIZE;
+                break;
+              }
+            if (size < opb)
+              size = opb;
+            dot += size / opb;
+          }
          break;
 
        case lang_reloc_statement_enum:
@@ -3134,7 +3223,7 @@ lang_do_assignments (s, output_section_statement, fill, dot)
            if (value.valid_p == false)
              einfo (_("%F%P: invalid reloc statement\n"));
          }
-         dot += bfd_get_reloc_size (s->reloc_statement.howto);
+         dot += bfd_get_reloc_size (s->reloc_statement.howto) / opb;
          break;
 
        case lang_input_section_enum:
@@ -3142,9 +3231,9 @@ lang_do_assignments (s, output_section_statement, fill, dot)
            asection *in = s->input_section.section;
 
            if (in->_cooked_size != 0)
-             dot += in->_cooked_size;
+             dot += in->_cooked_size / opb;
            else
-             dot += in->_raw_size;
+             dot += in->_raw_size / opb;
          }
          break;
 
@@ -3164,7 +3253,7 @@ lang_do_assignments (s, output_section_statement, fill, dot)
 
          break;
        case lang_padding_statement_enum:
-         dot += s->padding_statement.size;
+         dot += s->padding_statement.size / opb;
          break;
 
        case lang_group_statement_enum:
@@ -3222,11 +3311,13 @@ lang_set_startof ()
       h = bfd_link_hash_lookup (link_info.hash, buf, false, false, true);
       if (h != NULL && h->type == bfd_link_hash_undefined)
        {
+          unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, 
+                                                       ldfile_output_machine);
          h->type = bfd_link_hash_defined;
          if (s->_cooked_size != 0)
-           h->u.def.value = s->_cooked_size;
+           h->u.def.value = s->_cooked_size / opb;
          else
-           h->u.def.value = s->_raw_size;
+           h->u.def.value = s->_raw_size / opb;
          h->u.def.section = bfd_abs_section_ptr;
        }
 
@@ -3403,6 +3494,8 @@ lang_one_common (h, info)
   unsigned int power_of_two;
   bfd_vma size;
   asection *section;
+  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, 
+                                               ldfile_output_machine); 
 
   if (h->type != bfd_link_hash_common)
     return true;
@@ -3417,8 +3510,8 @@ lang_one_common (h, info)
   section = h->u.c.p->section;
 
   /* Increase the size of the section.  */
-  section->_cooked_size = ALIGN_N (section->_cooked_size,
-                                  (bfd_size_type) (1 << power_of_two));
+  section->_cooked_size = ALIGN_N ((section->_cooked_size + opb - 1) / opb,
+                                  (bfd_size_type) (1 << power_of_two)) * opb;
 
   /* Adjust the alignment if necessary.  */
   if (power_of_two > section->alignment_power)
@@ -3722,7 +3815,7 @@ topower (x)
   return 0;
 }
 
-void
+lang_output_section_statement_type *
 lang_enter_output_section_statement (output_section_statement_name,
                                     address_exp, sectype, block_value,
                                     align, subalign, ebase)
@@ -3770,6 +3863,7 @@ lang_enter_output_section_statement (output_section_statement_name,
                     "section alignment", 0));
 
   os->load_base = ebase;
+  return os;
 }
 
 
@@ -4026,13 +4120,13 @@ lang_process ()
 
 void
 lang_add_wild (section_name, sections_sorted, filename, filenames_sorted,
-              keep_sections, exclude_filename)
+              keep_sections, exclude_filename_list)
      const char *const section_name;
      boolean sections_sorted;
      const char *const filename;
      boolean filenames_sorted;
      boolean keep_sections;
-     const char *exclude_filename;
+     struct name_list *exclude_filename_list;
 {
   lang_wild_statement_type *new = new_stat (lang_wild_statement,
                                            stat_ptr);
@@ -4050,7 +4144,7 @@ lang_add_wild (section_name, sections_sorted, filename, filenames_sorted,
   new->filename = filename;
   new->filenames_sorted = filenames_sorted;
   new->keep_sections = keep_sections;
-  new->exclude_filename = exclude_filename;
+  new->exclude_filename_list = exclude_filename_list;
   lang_list_init (&new->children);
 }
 
@@ -4204,13 +4298,22 @@ lang_float (maybe)
 }
 
 void
-lang_leave_output_section_statement (fill, memspec, phdrs)
+lang_leave_output_section_statement (fill, memspec, phdrs, lma_memspec)
      bfd_vma fill;
      const char *memspec;
      struct lang_output_section_phdr_list *phdrs;
+     const char *lma_memspec;
 {
   current_section->fill = fill;
   current_section->region = lang_memory_region_lookup (memspec);
+  if (strcmp (lma_memspec, "*default*") != 0)
+    {
+      current_section->lma_region = lang_memory_region_lookup (lma_memspec);
+      /* if no runtime region has been given, but the load region has been,
+         use the load region */
+      if (strcmp (memspec, "*default*") == 0)
+        current_section->region = lang_memory_region_lookup (lma_memspec);
+    }
   current_section->phdrs = phdrs;
   stat_ptr = &statement_list;
 }
@@ -4278,7 +4381,8 @@ lang_abs_symbol_at_end_of (secname, name)
        h->u.def.value = 0;
       else
        h->u.def.value = (bfd_get_section_vma (output_bfd, sec)
-                         + bfd_section_size (output_bfd, sec));
+                         + bfd_section_size (output_bfd, sec) /
+                          bfd_octets_per_byte (output_bfd));
 
       h->u.def.section = bfd_abs_section_ptr;
     }
@@ -4588,7 +4692,8 @@ lang_leave_overlay_section (fill, phdrs)
 
   name = current_section->name;
 
-  lang_leave_output_section_statement (fill, "*default*", phdrs);
+  lang_leave_output_section_statement (fill, "*default*", 
+                                       phdrs, "*default*");
 
   /* Define the magic symbols.  */
 
@@ -4618,12 +4723,14 @@ lang_leave_overlay_section (fill, phdrs)
    looks through all the sections in the overlay and sets them.  */
 
 void
-lang_leave_overlay (fill, memspec, phdrs)
+lang_leave_overlay (fill, memspec, phdrs, lma_memspec)
      bfd_vma fill;
      const char *memspec;
      struct 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;
 
@@ -4632,6 +4739,11 @@ lang_leave_overlay (fill, memspec, phdrs)
   else
     region = lang_memory_region_lookup (memspec);
 
+  if (lma_memspec == NULL)
+    lma_region = NULL;
+  else
+    lma_region = lang_memory_region_lookup (lma_memspec);
+
   nocrossref = NULL;
 
   l = overlay_list;
@@ -4643,6 +4755,8 @@ lang_leave_overlay (fill, memspec, phdrs)
        l->os->fill = fill;
       if (region != NULL && l->os->region == NULL)
        l->os->region = region;
+      if (lma_region != NULL && l->os->lma_region == NULL)
+        l->os->lma_region = lma_region;
       if (phdrs != NULL && l->os->phdrs == NULL)
        l->os->phdrs = phdrs;
 
This page took 0.032719 seconds and 4 git commands to generate.