btrace, gdbserver: read branch trace incrementally
[deliverable/binutils-gdb.git] / ld / ldlang.c
index ba7f493bee108515df539f3ba8c007d89ae54c99..2a6c4c5e2ab550bd2aa48f46add1bcfeac396cc3 100644 (file)
@@ -70,7 +70,6 @@ static struct unique_sections *unique_section_list;
 
 /* Forward declarations.  */
 static void exp_init_os (etree_type *);
-static void init_map_userdata (bfd *, asection *, void *);
 static lang_input_statement_type *lookup_name (const char *);
 static struct bfd_hash_entry *lang_definedness_newfunc
  (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
@@ -1974,7 +1973,6 @@ lang_map (void)
 {
   lang_memory_region_type *m;
   bfd_boolean dis_header_printed = FALSE;
-  bfd *p;
 
   LANG_FOR_EACH_INPUT_STATEMENT (file)
     {
@@ -2046,50 +2044,34 @@ lang_map (void)
   if (! link_info.reduce_memory_overheads)
     {
       obstack_begin (&map_obstack, 1000);
-      for (p = link_info.input_bfds; p != (bfd *) NULL; p = p->link_next)
-       bfd_map_over_sections (p, init_map_userdata, 0);
       bfd_link_hash_traverse (link_info.hash, sort_def_symbol, 0);
     }
   lang_statement_iteration ++;
   print_statements ();
 }
 
-static void
-init_map_userdata (bfd *abfd ATTRIBUTE_UNUSED,
-                  asection *sec,
-                  void *data ATTRIBUTE_UNUSED)
-{
-  fat_section_userdata_type *new_data
-    = ((fat_section_userdata_type *) (stat_alloc
-                                     (sizeof (fat_section_userdata_type))));
-
-  ASSERT (get_userdata (sec) == NULL);
-  get_userdata (sec) = new_data;
-  new_data->map_symbol_def_tail = &new_data->map_symbol_def_head;
-  new_data->map_symbol_def_count = 0;
-}
-
 static bfd_boolean
 sort_def_symbol (struct bfd_link_hash_entry *hash_entry,
                 void *info ATTRIBUTE_UNUSED)
 {
-  if (hash_entry->type == bfd_link_hash_defined
-      || hash_entry->type == bfd_link_hash_defweak)
+  if ((hash_entry->type == bfd_link_hash_defined
+       || hash_entry->type == bfd_link_hash_defweak)
+      && hash_entry->u.def.section->owner != link_info.output_bfd
+      && hash_entry->u.def.section->owner != NULL)
     {
-      struct fat_user_section_struct *ud;
+      input_section_userdata_type *ud;
       struct map_symbol_def *def;
 
-      ud = (struct fat_user_section_struct *)
-         get_userdata (hash_entry->u.def.section);
-      if  (! ud)
+      ud = ((input_section_userdata_type *)
+           get_userdata (hash_entry->u.def.section));
+      if (!ud)
        {
-         /* ??? What do we have to do to initialize this beforehand?  */
-         /* The first time we get here is bfd_abs_section...  */
-         init_map_userdata (0, hash_entry->u.def.section, 0);
-         ud = (struct fat_user_section_struct *)
-             get_userdata (hash_entry->u.def.section);
+         ud = (input_section_userdata_type *) stat_alloc (sizeof (*ud));
+         get_userdata (hash_entry->u.def.section) = ud;
+         ud->map_symbol_def_tail = &ud->map_symbol_def_head;
+         ud->map_symbol_def_count = 0;
        }
-      else if  (!ud->map_symbol_def_tail)
+      else if (!ud->map_symbol_def_tail)
        ud->map_symbol_def_tail = &ud->map_symbol_def_head;
 
       def = (struct map_symbol_def *) obstack_alloc (&map_obstack, sizeof *def);
@@ -2122,14 +2104,6 @@ init_os (lang_output_section_statement_type *s, flagword flags)
   s->bfd_section->output_section = s->bfd_section;
   s->bfd_section->output_offset = 0;
 
-  if (!link_info.reduce_memory_overheads)
-    {
-      fat_section_userdata_type *new_userdata = (fat_section_userdata_type *)
-       stat_alloc (sizeof (fat_section_userdata_type));
-      memset (new_userdata, 0, sizeof (fat_section_userdata_type));
-      get_userdata (s->bfd_section) = new_userdata;
-    }
-
   /* If there is a base address, make sure that any sections it might
      mention are initialized.  */
   if (s->addr_tree != NULL)
@@ -4083,8 +4057,8 @@ hash_entry_addr_cmp (const void *a, const void *b)
 static void
 print_all_symbols (asection *sec)
 {
-  struct fat_user_section_struct *ud =
-      (struct fat_user_section_struct *) get_userdata (sec);
+  input_section_userdata_type *ud
+    = (input_section_userdata_type *) get_userdata (sec);
   struct map_symbol_def *def;
   struct bfd_link_hash_entry **entries;
   unsigned int i;
@@ -5362,18 +5336,14 @@ lang_size_sections (bfd_boolean *relax, bfd_boolean check_regions)
       && link_info.relro && expld.dataseg.relro_end)
     {
       /* If DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END pair was seen, try
-        to put expld.dataseg.relro on a (common) page boundary.  */
-      bfd_vma min_base, old_base, relro_end, maxpage;
+        to put expld.dataseg.relro_end on a (common) page boundary.  */
+      bfd_vma min_base, relro_end, maxpage;
 
       expld.dataseg.phase = exp_dataseg_relro_adjust;
       maxpage = expld.dataseg.maxpagesize;
       /* MIN_BASE is the absolute minimum address we are allowed to start the
         read-write segment (byte before will be mapped read-only).  */
       min_base = (expld.dataseg.min_base + maxpage - 1) & ~(maxpage - 1);
-      /* OLD_BASE is the address for a feasible minimum address which will
-        still not cause a data overlap inside MAXPAGE causing file offset skip
-        by MAXPAGE.  */
-      old_base = expld.dataseg.base;
       expld.dataseg.base += (-expld.dataseg.relro_end
                             & (expld.dataseg.pagesize - 1));
       /* Compute the expected PT_GNU_RELRO segment end.  */
@@ -5389,9 +5359,9 @@ lang_size_sections (bfd_boolean *relax, bfd_boolean check_regions)
       if (expld.dataseg.relro_end > relro_end)
        {
          /* The alignment of sections between DATA_SEGMENT_ALIGN
-            and DATA_SEGMENT_RELRO_END caused huge padding to be
-            inserted at DATA_SEGMENT_RELRO_END.  Try to start a bit lower so
-            that the section alignments will fit in.  */
+            and DATA_SEGMENT_RELRO_END can cause excessive padding to
+            be inserted at DATA_SEGMENT_RELRO_END.  Try to start a
+            bit lower so that the section alignments will fit in.  */
          asection *sec;
          unsigned int max_alignment_power = 0;
 
@@ -5405,9 +5375,11 @@ lang_size_sections (bfd_boolean *relax, bfd_boolean check_regions)
 
          if (((bfd_vma) 1 << max_alignment_power) < expld.dataseg.pagesize)
            {
-             if (expld.dataseg.base - (1 << max_alignment_power) < old_base)
-               expld.dataseg.base += expld.dataseg.pagesize;
-             expld.dataseg.base -= (1 << max_alignment_power);
+             /* Aligning the adjusted base guarantees the padding
+                between sections won't change.  This is better than
+                simply subtracting 1 << max_alignment_power which is
+                what we used to do here.  */
+             expld.dataseg.base &= ~((1 << max_alignment_power) - 1);
              lang_reset_memory_regions ();
              one_lang_size_sections_pass (relax, check_regions);
            }
This page took 0.025099 seconds and 4 git commands to generate.