public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [Gold, patch RFC] Fix for PR16321
@ 2014-04-25  9:38 Alexander Ivchenko
  0 siblings, 0 replies; only message in thread
From: Alexander Ivchenko @ 2014-04-25  9:38 UTC (permalink / raw)
  To: binutils, Cary Coutant, Ian Lance Taylor, H.J. Lu

Hi,


I'm trying to fix the problem with changed .bss file offset when
stripping the gold-linked binary.
Gold has the right to adjust file offset for .bss the way it does,
because file offset is irrelevant for .bss. However, this leads to
certain problems for gdb. Let's say you want to remotely debug a
stripped executable that is running on a target, you then load symbols
from unstripped executable that you have on the host, but at this
point gdb will compare all the segments and everything in them. Since
file offset for one of the sections differs, gdb will fail to load the
symbols.


Plus, I think it would be beneficial to have a little bit more
identical behavior between gold and ld, since ld does not insert any
padding for .bss section file offset.



Here is my attempt to fix the PR:


diff --git a/gold/output.cc b/gold/output.cc
index c078fbb..8b52f78 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -4402,6 +4402,8 @@ Output_segment::set_section_addresses(const
Target* target,

   off_t off = 0;
   uint64_t ret;
+  uint64_t prev_addr = addr;
+
   for (int i = 0; i < static_cast<int>(ORDER_MAX); ++i)
     {
       if (i == static_cast<int>(ORDER_RELRO_LAST))
@@ -4437,7 +4439,7 @@ Output_segment::set_section_addresses(const
Target* target,
       *poff = align_address(*poff, segment_align);
     }

-  this->memsz_ = *poff - orig_off;
+  this->memsz_ = addr - prev_addr;

   // Ignore the file offset adjustments made by the BSS Output_data
   // objects.
@@ -4497,6 +4499,8 @@
Output_segment::set_section_list_addresses(Layout* layout, bool reset,
   off_t maxoff = startoff;

   off_t off = startoff;
+
+  uint64_t max_address = addr;
   for (Output_data_list::iterator p = pdl->begin();
        p != pdl->end();
        ++p)
@@ -4545,8 +4549,17 @@
Output_segment::set_section_list_addresses(Layout* layout, bool reset,

          if (!parameters->incremental_update())
            {
-             off = align_address(off, align);
-             (*p)->set_address_and_file_offset(addr + (off - startoff), off);
+             if (!(*p)->is_section_type(elfcpp::SHT_NOBITS))
+               {
+                 off = align_address(off, align);
+                 (*p)->set_address_and_file_offset(addr + (off -
startoff), off);
+               }
+             else
+               {
+                 uint64_t bss_address = align_address(addr + (off -
startoff), align);
+
+                 (*p)->set_address_and_file_offset(bss_address, off);
+               }
            }
          else
            {
@@ -4561,7 +4574,19 @@
Output_segment::set_section_list_addresses(Layout* layout, bool reset,
                                  "relink with --incremental-full"),
                                (*p)->output_section()->name());
                }
-             (*p)->set_address_and_file_offset(addr + (off - startoff), off);
+
+             if (!(*p)->is_section_type(elfcpp::SHT_NOBITS))
+               {
+                 off = align_address(off, align);
+                 (*p)->set_address_and_file_offset(addr + (off -
startoff), off);
+               }
+             else
+               {
+                 uint64_t bss_address = align_address(addr + (off -
startoff), align);
+
+                 (*p)->set_address_and_file_offset(bss_address, off);
+               }
+
              if ((*p)->data_size() > current_size)
                {
                  gold_assert((*p)->output_section() != NULL);
@@ -4623,7 +4648,13 @@
Output_segment::set_section_list_addresses(Layout* layout, bool reset,
       // PT_LOAD segment.
       if (!(*p)->is_section_flag_set(elfcpp::SHF_TLS)
          || !(*p)->is_section_type(elfcpp::SHT_NOBITS))
-       off += (*p)->data_size();
+       {
+
+         if ((*p)->address() + (*p)->data_size() > max_address)
+           max_address = (*p)->address() + (*p)->data_size();
+
+         off += (*p)->data_size();
+       }

       if (off > maxoff)
        maxoff = off;
@@ -4636,7 +4667,7 @@
Output_segment::set_section_list_addresses(Layout* layout, bool reset,
     }

   *poff = maxoff;
-  return addr + (maxoff - startoff);
+  return max_address;
 }

 // For a non-PT_LOAD segment, set the offset from the sections, if



So far for "make check-gold" only tls_phdrs_script_test fails, but I
don't know yet why.

Anyways, I would really appreciate any comments on the patch.

--Alexander

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2014-04-25  9:38 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-25  9:38 [Gold, patch RFC] Fix for PR16321 Alexander Ivchenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).