*** empty log message ***
[deliverable/binutils-gdb.git] / ld / ldlang.c
index cba7179699e94c4776dd593b828cdae1dfa58ca9..0e72ab851e56d8a7c907d8bc13b7091bfcdcb957 100644 (file)
@@ -1147,7 +1147,8 @@ lang_output_section_statement_lookup (const char *const name)
 
 lang_output_section_statement_type *
 lang_output_section_find_by_flags (const asection *sec,
-                                  lang_output_section_statement_type **exact)
+                                  lang_output_section_statement_type **exact,
+                                  lang_match_sec_type_func match_type)
 {
   lang_output_section_statement_type *first, *look, *found;
   flagword flags;
@@ -1165,9 +1166,8 @@ lang_output_section_find_by_flags (const asection *sec,
       if (look->bfd_section != NULL)
        {
          flags = look->bfd_section->flags;
-         if (!bfd_match_sections_by_type (output_bfd,
-                                          look->bfd_section,
-                                          sec->owner, sec))
+         if (match_type && !match_type (output_bfd, look->bfd_section,
+                                        sec->owner, sec))
            continue;
        }
       flags ^= sec->flags;
@@ -1177,7 +1177,8 @@ lang_output_section_find_by_flags (const asection *sec,
     }
   if (found != NULL)
     {
-      *exact = found;
+      if (exact != NULL)
+       *exact = found;
       return found;
     }
 
@@ -1190,9 +1191,8 @@ lang_output_section_find_by_flags (const asection *sec,
          if (look->bfd_section != NULL)
            {
              flags = look->bfd_section->flags;
-             if (!bfd_match_sections_by_type (output_bfd,
-                                              look->bfd_section,
-                                              sec->owner, sec))
+             if (match_type && !match_type (output_bfd, look->bfd_section,
+                                            sec->owner, sec))
                continue;
            }
          flags ^= sec->flags;
@@ -1200,10 +1200,8 @@ lang_output_section_find_by_flags (const asection *sec,
                         | SEC_CODE | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
            found = look;
        }
-      return found;
     }
-
-  if (sec->flags & (SEC_READONLY | SEC_THREAD_LOCAL))
+  else if (sec->flags & (SEC_READONLY | SEC_THREAD_LOCAL))
     {
       /* .rodata can go after .text, .sdata2 after .rodata.  */
       for (look = first; look; look = look->next)
@@ -1212,9 +1210,8 @@ lang_output_section_find_by_flags (const asection *sec,
          if (look->bfd_section != NULL)
            {
              flags = look->bfd_section->flags;
-             if (!bfd_match_sections_by_type (output_bfd,
-                                              look->bfd_section,
-                                              sec->owner, sec))
+             if (match_type && !match_type (output_bfd, look->bfd_section,
+                                            sec->owner, sec))
                continue;
            }
          flags ^= sec->flags;
@@ -1223,10 +1220,8 @@ lang_output_section_find_by_flags (const asection *sec,
              && !(look->flags & (SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
            found = look;
        }
-      return found;
     }
-
-  if (sec->flags & SEC_SMALL_DATA)
+  else if (sec->flags & SEC_SMALL_DATA)
     {
       /* .sdata goes after .data, .sbss after .sdata.  */
       for (look = first; look; look = look->next)
@@ -1235,9 +1230,8 @@ lang_output_section_find_by_flags (const asection *sec,
          if (look->bfd_section != NULL)
            {
              flags = look->bfd_section->flags;
-             if (!bfd_match_sections_by_type (output_bfd,
-                                              look->bfd_section,
-                                              sec->owner, sec))
+             if (match_type && !match_type (output_bfd, look->bfd_section,
+                                            sec->owner, sec))
                continue;
            }
          flags ^= sec->flags;
@@ -1247,10 +1241,8 @@ lang_output_section_find_by_flags (const asection *sec,
                  && !(sec->flags & SEC_HAS_CONTENTS)))
            found = look;
        }
-      return found;
     }
-
-  if (sec->flags & SEC_HAS_CONTENTS)
+  else if (sec->flags & SEC_HAS_CONTENTS)
     {
       /* .data goes after .rodata.  */
       for (look = first; look; look = look->next)
@@ -1259,9 +1251,8 @@ lang_output_section_find_by_flags (const asection *sec,
          if (look->bfd_section != NULL)
            {
              flags = look->bfd_section->flags;
-             if (!bfd_match_sections_by_type (output_bfd,
-                                              look->bfd_section,
-                                              sec->owner, sec))
+             if (match_type && !match_type (output_bfd, look->bfd_section,
+                                            sec->owner, sec))
                continue;
            }
          flags ^= sec->flags;
@@ -1269,27 +1260,30 @@ lang_output_section_find_by_flags (const asection *sec,
                         | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
            found = look;
        }
-      return found;
     }
-
-  /* .bss goes last.  */
-  for (look = first; look; look = look->next)
+  else
     {
-      flags = look->flags;
-      if (look->bfd_section != NULL)
+      /* .bss goes last.  */
+      for (look = first; look; look = look->next)
        {
-         flags = look->bfd_section->flags;
-         if (!bfd_match_sections_by_type (output_bfd,
-                                          look->bfd_section,
-                                          sec->owner, sec))
-           continue;
+         flags = look->flags;
+         if (look->bfd_section != NULL)
+           {
+             flags = look->bfd_section->flags;
+             if (match_type && !match_type (output_bfd, look->bfd_section,
+                                            sec->owner, sec))
+               continue;
+           }
+         flags ^= sec->flags;
+         if (!(flags & SEC_ALLOC))
+           found = look;
        }
-      flags ^= sec->flags;
-      if (!(flags & SEC_ALLOC))
-       found = look;
     }
 
-  return found;
+  if (found || !match_type)
+    return found;
+
+  return lang_output_section_find_by_flags (sec, NULL, NULL);
 }
 
 /* Find the last output section before given output statement.
@@ -1467,13 +1461,20 @@ lang_insert_orphan (asection *s,
            {
              lang_statement_union_type **where;
              lang_statement_union_type **assign = NULL;
+             bfd_boolean ignore_first;
 
              /* Look for a suitable place for the new statement list.
                 The idea is to skip over anything that might be inside
                 a SECTIONS {} statement in a script, before we find
                 another output_section_statement.  Assignments to "dot"
                 before an output section statement are assumed to
-                belong to it.  */
+                belong to it.  An exception to this rule is made for
+                the first assignment to dot, otherwise we might put an
+                orphan before . = . + SIZEOF_HEADERS or similar
+                assignments that set the initial address.  */
+
+             ignore_first = after == (&lang_output_section_statement.head
+                                      ->output_section_statement);
              for (where = &after->header.next;
                   *where != NULL;
                   where = &(*where)->header.next)
@@ -1487,9 +1488,11 @@ lang_insert_orphan (asection *s,
                          ass = &(*where)->assignment_statement;
                          if (ass->exp->type.node_class != etree_assert
                              && ass->exp->assign.dst[0] == '.'
-                             && ass->exp->assign.dst[1] == 0)
+                             && ass->exp->assign.dst[1] == 0
+                             && !ignore_first)
                            assign = where;
                        }
+                     ignore_first = FALSE;
                      continue;
                    case lang_wild_statement_enum:
                    case lang_input_section_enum:
This page took 0.026127 seconds and 4 git commands to generate.