This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Gold, patch RFC] Fix for PR16321


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]