* ldexp.h (exp_data_seg): Add min_base and maxpagesize fields.
authorJakub Jelinek <jakub@redhat.com>
Fri, 17 Dec 2004 15:50:02 +0000 (15:50 +0000)
committerJakub Jelinek <jakub@redhat.com>
Fri, 17 Dec 2004 15:50:02 +0000 (15:50 +0000)
* ldexp.c (fold_binary) <case DATA_SEGMENT_ALIGN>: Initialize them.
* ldlang.c (lang_size_sections): Use them to avoid wasting virtual
address space at DATA_SEGMENT_ALIGN.  Fix computation of expected
PT_GNU_RELRO segment end.

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

index 0844e9a69c3536afa57cbd303c6c8a1dc3b22955..f5ef3a7a026abfa673079337166b94f268503416 100644 (file)
@@ -1,3 +1,11 @@
+2004-12-17  Jakub Jelinek  <jakub@redhat.com>
+
+       * ldexp.h (exp_data_seg): Add min_base and maxpagesize fields.
+       * ldexp.c (fold_binary) <case DATA_SEGMENT_ALIGN>: Initialize them.
+       * ldlang.c (lang_size_sections): Use them to avoid wasting virtual
+       address space at DATA_SEGMENT_ALIGN.  Fix computation of expected
+       PT_GNU_RELRO segment end.
+
 2004-12-14  P.J. Darcy  <darcypj@us.ibm.com>
 
        * configure.tgt: Add s390x-ibm-tpf support.
index cd6068cc47834ec4d559997e728c0ce70bc76b3f..f971ecfaeb288b3bfdb7ec59f11431dd18230475 100644 (file)
@@ -435,8 +435,10 @@ fold_binary (etree_type *tree,
                      if (allocation_done == lang_allocating_phase_enum)
                        {
                          exp_data_seg.phase = exp_dataseg_align_seen;
+                         exp_data_seg.min_base = align_n (dot, maxpage);
                          exp_data_seg.base = result.value;
                          exp_data_seg.pagesize = other.value;
+                         exp_data_seg.maxpagesize = maxpage;
                          exp_data_seg.relro_end = 0;
                        }
                    }
index addf83424a274dbc95ca6d8edef7d7e634888b85..59a5627508636d2926e74bd25580197bc437ea1a 100644 (file)
@@ -100,7 +100,7 @@ extern struct exp_data_seg {
     exp_dataseg_relro_adjust,
     exp_dataseg_adjust
   } phase;
-  bfd_vma base, relro_end, end, pagesize;
+  bfd_vma base, min_base, relro_end, end, pagesize, maxpagesize;
 } exp_data_seg;
 
 /* A maps from a segment name to a base address.  */
index c3a49344af0b492712fc460b39ea2abbae7bef7e..ab34090e412d8ede8bef78dec9a1068da9cc1c97 100644 (file)
@@ -3858,15 +3858,21 @@ lang_size_sections
     {
       /* If DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END pair was seen, try
         to put exp_data_seg.relro on a (common) page boundary.  */
-      bfd_vma old_base, relro_end;
+      bfd_vma old_min_base, relro_end, maxpage;
 
       exp_data_seg.phase = exp_dataseg_relro_adjust;
-      old_base = exp_data_seg.base;
+      old_min_base = exp_data_seg.min_base;
+      maxpage = exp_data_seg.maxpagesize;
       exp_data_seg.base += (-exp_data_seg.relro_end
                            & (exp_data_seg.pagesize - 1));
       /* Compute the expected PT_GNU_RELRO segment end.  */
       relro_end = (exp_data_seg.relro_end + exp_data_seg.pagesize - 1)
-                 & (exp_data_seg.pagesize - 1);
+                 & ~(exp_data_seg.pagesize - 1);
+      if (old_min_base + maxpage < exp_data_seg.base)
+       {
+         exp_data_seg.base -= maxpage;
+         relro_end -= maxpage;
+       }
       result = lang_size_sections_1 (s, output_section_statement, prev, fill,
                                     dot, relax, check_regions);
       if (exp_data_seg.relro_end > relro_end)
@@ -3888,7 +3894,7 @@ lang_size_sections
          if (((bfd_vma) 1 << max_alignment_power) < exp_data_seg.pagesize)
            {
              if (exp_data_seg.base - (1 << max_alignment_power)
-                 < old_base)
+                 < old_min_base)
                exp_data_seg.base += exp_data_seg.pagesize;
              exp_data_seg.base -= (1 << max_alignment_power);
              result = lang_size_sections_1 (s, output_section_statement,