* ldlang.h (lang_output_section_statement_type): Add prev.
authorAlan Modra <amodra@gmail.com>
Sat, 24 Dec 2005 07:48:30 +0000 (07:48 +0000)
committerAlan Modra <amodra@gmail.com>
Sat, 24 Dec 2005 07:48:30 +0000 (07:48 +0000)
* ldlang.c (output_statement_newfunc): Set os.prev.
(lang_insert_orphan): Likewise.
(output_prev_sec_find): Use os.prev.

ld/ChangeLog
ld/ldlang.c
ld/ldlang.h

index c0c61d8e3de209d8f3137e871052f8923ca33f4d..dea1f295296552d3c9e7e2ca58fc16ea71a7baa2 100644 (file)
@@ -1,3 +1,10 @@
+2005-12-24  Alan Modra  <amodra@bigpond.net.au>
+
+       * ldlang.h (lang_output_section_statement_type): Add prev.
+       * ldlang.c (output_statement_newfunc): Set os.prev.
+       (lang_insert_orphan): Likewise.
+       (output_prev_sec_find): Use os.prev.
+
 2005-12-22  Santosh Raktawan <santoshr2@kpitcummins.com>
 
        * ld/emulparms/h8300helf.sh (TINY_READONLY_SECTION,
index 8ef48d13b9fb0e254f72c8dfdea7ba660380a07a..f51f68ef4b09054443d600bb8018f596dd2efb97 100644 (file)
@@ -912,6 +912,14 @@ output_statement_newfunc (struct bfd_hash_entry *entry,
                         (lang_statement_union_type *) &ret->os,
                         &ret->os.header.next);
 
+  /* For every output section statement added to the list, except the
+     first one, lang_output_section_statement.tail points to the "next"
+     field of the last element of the list.  */
+  if (lang_output_section_statement.head != NULL)
+    ret->os.prev = (lang_output_section_statement_type *)
+      ((char *) lang_output_section_statement.tail
+       - offsetof (lang_output_section_statement_type, next));
+
   /* GCC's strict aliasing rules prevent us from just casting the
      address, so we store the pointer in a variable and cast that
      instead.  */
@@ -1290,20 +1298,15 @@ lang_output_section_find_by_flags (const asection *sec,
 static asection *
 output_prev_sec_find (lang_output_section_statement_type *os)
 {
-  asection *s = (asection *) NULL;
   lang_output_section_statement_type *lookup;
 
-  for (lookup = &lang_output_section_statement.head->output_section_statement;
-       lookup != NULL;
-       lookup = lookup->next)
+  for (lookup = os->prev; lookup != NULL; lookup = lookup->prev)
     {
       if (lookup->constraint == -1)
        continue;
-      if (lookup == os)
-       return s;
 
       if (lookup->bfd_section != NULL && lookup->bfd_section->owner != NULL)
-       s = lookup->bfd_section;
+       return lookup->bfd_section;
     }
 
   return NULL;
@@ -1544,7 +1547,12 @@ lang_insert_orphan (asection *s,
          /* Do the same for the list of output section statements.  */
          newly_added_os = *os_tail;
          *os_tail = NULL;
+         newly_added_os->prev = (lang_output_section_statement_type *)
+           ((char *) place->os_tail
+            - offsetof (lang_output_section_statement_type, next));
          newly_added_os->next = *place->os_tail;
+         if (newly_added_os->next != NULL)
+           newly_added_os->next->prev = newly_added_os;
          *place->os_tail = newly_added_os;
          place->os_tail = &newly_added_os->next;
 
index 381bb0484cbf11bd3d76742909413ce0024d3cab..cf5b01ff3d08ae5cb068430d2951be80239507d2 100644 (file)
@@ -130,6 +130,7 @@ typedef struct lang_output_section_statement_struct
   lang_statement_header_type header;
   lang_statement_list_type children;
   struct lang_output_section_statement_struct *next;
+  struct lang_output_section_statement_struct *prev;
   const char *name;
   asection *bfd_section;
   lang_memory_region_type *region;