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.
 /* 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.
    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 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;
 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;
                                        
 /* 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;
 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. */
      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)
     }
 
   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 = (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;
       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
 
              /* 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
              if (force
+                 && !s->input_statement.whole_archive
                  && s->input_statement.loaded
                  && bfd_check_format (s->input_statement.the_bfd,
                                       bfd_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;
 {
   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 ();
   if (size != 0)
     {
       print_space ();
@@ -2188,7 +2196,7 @@ print_input_section (in)
            }
 
          minfo ("0x%V %W %B\n",
            }
 
          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)
                 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);
 
 
          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;
   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 ();
 
   for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
     print_space ();
@@ -2274,7 +2284,8 @@ print_data_statement (data)
 
   print_nl ();
 
 
   print_nl ();
 
-  print_dot = addr + size;
+  print_dot = addr + size / opb;
+
 }
 
 /* Print an address statement.  These are generated by options like
 }
 
 /* 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;
   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 ();
 
   for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++)
     print_space ();
@@ -2319,7 +2332,7 @@ print_reloc_statement (reloc)
 
   print_nl ();
 
 
   print_nl ();
 
-  print_dot = addr + size;
+  print_dot = addr + size / opb;
 }  
 
 static void
 }  
 
 static void
@@ -2328,6 +2341,8 @@ print_padding_statement (s)
 {
   int len;
   bfd_vma addr;
 {
   int len;
   bfd_vma addr;
+  unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, 
+                                               ldfile_output_machine); 
 
   minfo (" *fill*");
 
 
   minfo (" *fill*");
 
@@ -2348,7 +2363,7 @@ print_padding_statement (s)
 
   print_nl ();
 
 
   print_nl ();
 
-  print_dot = addr + s->size;
+  print_dot = addr + s->size / opb;
 }
 
 static void
 }
 
 static void
@@ -2360,9 +2375,15 @@ print_wild_statement (w, os)
 
   if (w->filenames_sorted)
     minfo ("SORT(");
 
   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 ("*");
     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.
      */
 
      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)
   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.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->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 */
 }
 
 /* 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;
 {
   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)
     {
 
   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)
       /* 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
       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
     {
     }
   else
     {
@@ -2608,6 +2634,10 @@ size_input_section (this_ptr, output_section_statement, fill, dot, relax)
   return dot;
 }
 
   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.  */
 /* 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;
 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)
 
   /* 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"),
 _("%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
 }
 
 /* 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;
 
 
 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
 /* 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;
 {
      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)
     {
   /* 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);
            
            (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
                             /* 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
            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
            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;
                
              {
                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;
              }
          }
          break;
@@ -2870,6 +2944,8 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
 
            switch (s->data_statement.type)
              {
 
            switch (s->data_statement.type)
              {
+              default:
+                abort();
              case QUAD:
              case SQUAD:
                size = QUAD_SIZE;
              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;
              }
                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.  */
            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);
            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;
            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.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;
                  }
                    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;
             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;
          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;
 {
      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)
   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;
                (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) 
              {
              }
            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"));
          }
            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:
          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"));
          }
            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:
          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)
            asection *in = s->input_section.section;
 
            if (in->_cooked_size != 0)
-             dot += in->_cooked_size;
+             dot += in->_cooked_size / opb;
            else
            else
-             dot += in->_raw_size;
+             dot += in->_raw_size / opb;
          }
          break;
 
          }
          break;
 
@@ -3164,7 +3253,7 @@ lang_do_assignments (s, output_section_statement, fill, dot)
 
          break;
        case lang_padding_statement_enum:
 
          break;
        case lang_padding_statement_enum:
-         dot += s->padding_statement.size;
+         dot += s->padding_statement.size / opb;
          break;
 
        case lang_group_statement_enum:
          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)
        {
       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->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
          else
-           h->u.def.value = s->_raw_size;
+           h->u.def.value = s->_raw_size / opb;
          h->u.def.section = bfd_abs_section_ptr;
        }
 
          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 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;
 
   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 = 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)
 
   /* Adjust the alignment if necessary.  */
   if (power_of_two > section->alignment_power)
@@ -3722,7 +3815,7 @@ topower (x)
   return 0;
 }
 
   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)
 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;
                     "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,
 
 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 *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);
 {
   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->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);
 }
 
   lang_list_init (&new->children);
 }
 
@@ -4204,13 +4298,22 @@ lang_float (maybe)
 }
 
 void
 }
 
 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;
      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);
 {
   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;
 }
   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)
        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;
     }
 
       h->u.def.section = bfd_abs_section_ptr;
     }
@@ -4588,7 +4692,8 @@ lang_leave_overlay_section (fill, phdrs)
 
   name = current_section->name;
 
 
   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.  */
 
 
   /* 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
    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;
      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 *region;
+  lang_memory_region_type *lma_region;
   struct overlay_list *l;
   struct lang_nocrossref *nocrossref;
 
   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);
 
   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;
   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;
        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;
 
       if (phdrs != NULL && l->os->phdrs == NULL)
        l->os->phdrs = phdrs;
 
This page took 0.036178 seconds and 4 git commands to generate.