OSDN Git Service

PR ld/12380
authoramodra <amodra>
Wed, 12 Jan 2011 21:07:19 +0000 (21:07 +0000)
committeramodra <amodra>
Wed, 12 Jan 2011 21:07:19 +0000 (21:07 +0000)
* ldexp.h (enum phase_enum): Comment.  Add exp_dataseg_done.
* ldexp.c (fold_unary <DATA_SEGMENT_END>): Rearrange code.  Test
for exp_dataseg_done rather than expld.phase == lang_final_phase_enum
to detect when we've finished sizing sections.
(fold_binary <DATA_SEGMENT_ALIGN>): Likewise.
(fold_binary <DATA_SEGMENT_RELRO_END>): Likewise.  Also test
that we are not inside an output section statement.
* ldlang.c (lang_size_sections): Set exp_dataseg_done on exit if
not exp_dataseg_relro_adjust or exp_dataseg_adjust.  Don't set
lang_final_phase_enum here.
(lang_process): Set lang_final_phase_enum here.

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

index 6f835c9..457e380 100644 (file)
@@ -1,3 +1,18 @@
+2011-01-12  Alan Modra  <amodra@gmail.com>
+
+       PR ld/12380
+       * ldexp.h (enum phase_enum): Comment.  Add exp_dataseg_done.
+       * ldexp.c (fold_unary <DATA_SEGMENT_END>): Rearrange code.  Test
+       for exp_dataseg_done rather than expld.phase == lang_final_phase_enum
+       to detect when we've finished sizing sections.
+       (fold_binary <DATA_SEGMENT_ALIGN>): Likewise.
+       (fold_binary <DATA_SEGMENT_RELRO_END>): Likewise.  Also test
+       that we are not inside an output section statement.
+       * ldlang.c (lang_size_sections): Set exp_dataseg_done on exit if
+       not exp_dataseg_relro_adjust or exp_dataseg_adjust.  Don't set
+       lang_final_phase_enum here.
+       (lang_process): Set lang_final_phase_enum here.
+
 2011-01-10  Nick Clifton  <nickc@redhat.com>
 
        * po/da.po: Updated Danish translation.
index 3261884..9aad092 100644 (file)
@@ -1,6 +1,6 @@
 /* This module handles expression trees.
    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
    Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
 
@@ -259,20 +259,22 @@ fold_unary (etree_type *tree)
          break;
 
        case DATA_SEGMENT_END:
-         if (expld.phase != lang_first_phase_enum
-             && expld.section == bfd_abs_section_ptr
-             && (expld.dataseg.phase == exp_dataseg_align_seen
-                 || expld.dataseg.phase == exp_dataseg_relro_seen
-                 || expld.dataseg.phase == exp_dataseg_adjust
-                 || expld.dataseg.phase == exp_dataseg_relro_adjust
-                 || expld.phase == lang_final_phase_enum))
+         if (expld.phase == lang_first_phase_enum
+             || expld.section != bfd_abs_section_ptr)
            {
-             if (expld.dataseg.phase == exp_dataseg_align_seen
-                 || expld.dataseg.phase == exp_dataseg_relro_seen)
-               {
-                 expld.dataseg.phase = exp_dataseg_end_seen;
-                 expld.dataseg.end = expld.result.value;
-               }
+             expld.result.valid_p = FALSE;
+           }
+         else if (expld.dataseg.phase == exp_dataseg_align_seen
+                  || expld.dataseg.phase == exp_dataseg_relro_seen)
+           {
+             expld.dataseg.phase = exp_dataseg_end_seen;
+             expld.dataseg.end = expld.result.value;
+           }
+         else if (expld.dataseg.phase == exp_dataseg_done
+                  || expld.dataseg.phase == exp_dataseg_adjust
+                  || expld.dataseg.phase == exp_dataseg_relro_adjust)
+           {
+             /* OK.  */
            }
          else
            expld.result.valid_p = FALSE;
@@ -402,12 +404,10 @@ fold_binary (etree_type *tree)
 
        case DATA_SEGMENT_ALIGN:
          expld.dataseg.relro = exp_dataseg_relro_start;
-         if (expld.phase != lang_first_phase_enum
-             && expld.section == bfd_abs_section_ptr
-             && (expld.dataseg.phase == exp_dataseg_none
-                 || expld.dataseg.phase == exp_dataseg_adjust
-                 || expld.dataseg.phase == exp_dataseg_relro_adjust
-                 || expld.phase == lang_final_phase_enum))
+         if (expld.phase == lang_first_phase_enum
+             || expld.section != bfd_abs_section_ptr)
+           expld.result.valid_p = FALSE;
+         else
            {
              bfd_vma maxpage = lhs.value;
              bfd_vma commonpage = expld.result.value;
@@ -415,10 +415,20 @@ fold_binary (etree_type *tree)
              expld.result.value = align_n (expld.dot, maxpage);
              if (expld.dataseg.phase == exp_dataseg_relro_adjust)
                expld.result.value = expld.dataseg.base;
-             else if (expld.dataseg.phase != exp_dataseg_adjust)
+             else if (expld.dataseg.phase == exp_dataseg_adjust)
+               {
+                 if (commonpage < maxpage)
+                   expld.result.value += ((expld.dot + commonpage - 1)
+                                          & (maxpage - commonpage));
+               }
+             else
                {
                  expld.result.value += expld.dot & (maxpage - 1);
-                 if (expld.phase == lang_allocating_phase_enum)
+                 if (expld.dataseg.phase == exp_dataseg_done)
+                   {
+                     /* OK.  */
+                   }
+                 else if (expld.dataseg.phase == exp_dataseg_none)
                    {
                      expld.dataseg.phase = exp_dataseg_align_seen;
                      expld.dataseg.min_base = expld.dot;
@@ -427,22 +437,21 @@ fold_binary (etree_type *tree)
                      expld.dataseg.maxpagesize = maxpage;
                      expld.dataseg.relro_end = 0;
                    }
+                 else
+                   expld.result.valid_p = FALSE;
                }
-             else if (commonpage < maxpage)
-               expld.result.value += ((expld.dot + commonpage - 1)
-                                      & (maxpage - commonpage));
            }
-         else
-           expld.result.valid_p = FALSE;
          break;
 
        case DATA_SEGMENT_RELRO_END:
          expld.dataseg.relro = exp_dataseg_relro_end;
-         if (expld.phase != lang_first_phase_enum
-             && (expld.dataseg.phase == exp_dataseg_align_seen
-                 || expld.dataseg.phase == exp_dataseg_adjust
-                 || expld.dataseg.phase == exp_dataseg_relro_adjust
-                 || expld.phase == lang_final_phase_enum))
+         if (expld.phase == lang_first_phase_enum
+             || expld.section != bfd_abs_section_ptr)
+           expld.result.valid_p = FALSE;
+         else if (expld.dataseg.phase == exp_dataseg_align_seen
+                  || expld.dataseg.phase == exp_dataseg_adjust
+                  || expld.dataseg.phase == exp_dataseg_relro_adjust
+                  || expld.dataseg.phase == exp_dataseg_done)
            {
              if (expld.dataseg.phase == exp_dataseg_align_seen
                  || expld.dataseg.phase == exp_dataseg_relro_adjust)
index 31a06ac..6c94be2 100644 (file)
@@ -1,6 +1,6 @@
 /* ldexp.h -
    Copyright 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000, 2001, 2002,
-   2003, 2004, 2005, 2007 Free Software Foundation, Inc.
+   2003, 2004, 2005, 2007, 2011 Free Software Foundation, Inc.
 
    This file is part of the GNU Binutils.
 
@@ -103,12 +103,17 @@ typedef enum {
 union lang_statement_union;
 
 enum phase_enum {
+  /* We step through the first four states here as we see the
+     associated linker script tokens.  */
   exp_dataseg_none,
   exp_dataseg_align_seen,
   exp_dataseg_relro_seen,
   exp_dataseg_end_seen,
+  /* The last three states are final, and affect the value returned
+     by DATA_SEGMENT_ALIGN.  */
   exp_dataseg_relro_adjust,
-  exp_dataseg_adjust
+  exp_dataseg_adjust,
+  exp_dataseg_done
 };
 
 enum relro_enum {
index 5251804..4fe80a8 100644 (file)
@@ -1,6 +1,6 @@
 /* Linker command language support.
    Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
    This file is part of the GNU Binutils.
@@ -5425,9 +5425,11 @@ lang_size_sections (bfd_boolean *relax, bfd_boolean check_regions)
          lang_reset_memory_regions ();
          one_lang_size_sections_pass (relax, check_regions);
        }
+      else
+       expld.dataseg.phase = exp_dataseg_done;
     }
-
-  expld.phase = lang_final_phase_enum;
+  else
+    expld.dataseg.phase = exp_dataseg_done;
 }
 
 /* Worker function for lang_do_assignments.  Recursiveness goes here.  */
@@ -6520,7 +6522,7 @@ lang_process (void)
 
   /* Do all the assignments, now that we know the final resting places
      of all the symbols.  */
-
+  expld.phase = lang_final_phase_enum;
   lang_do_assignments ();
 
   ldemul_finish ();