public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [GOLD][PATCH] Arm_input_section class.
@ 2009-10-21 21:39 Doug Kwan (關振德)
  2009-10-22  0:48 ` Ian Lance Taylor
  0 siblings, 1 reply; 3+ messages in thread
From: Doug Kwan (關振德) @ 2009-10-21 21:39 UTC (permalink / raw)
  To: Ian Lance Taylor, binutils

[-- Attachment #1: Type: text/plain, Size: 500 bytes --]

Hi,

   This patch adds Arm_input_section class, which is a sub-class of
Output_relaxed_input_section.  It is used to wrap an input section so
that we can append a stub table to it.

-Doug

2009-10-21  Doug Kwan  <dougkwan@google.com>

        * arm.cc (Arm_input_section): New class definition.
        (Arm_input_section::init, Arm_input_section:do_write,
        Arm_input_section::set_final_data_size,
        Arm_input_section::do_reset_address_and_file_offset): New method
        definitions.

[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 5881 bytes --]

Index: gold/arm.cc
===================================================================
RCS file: /cvs/src/src/gold/arm.cc,v
retrieving revision 1.18
diff -u -p -r1.18 arm.cc
--- gold/arm.cc	21 Oct 2009 18:33:18 -0000	1.18
+++ gold/arm.cc	21 Oct 2009 21:13:29 -0000
@@ -745,6 +745,95 @@ class Stub_table : public Output_data
   Reloc_stub_map reloc_stubs_;
 };
 
+// A class to wrap an ordinary input section containing executable code.
+
+template<bool big_endian>
+class Arm_input_section : public Output_relaxed_input_section
+{
+ public:
+  Arm_input_section(Relobj* relobj, unsigned int shndx)
+    : Output_relaxed_input_section(relobj, shndx, 1),
+      original_addralign_(1), original_size_(0), stub_table_(NULL)
+  { }
+
+  ~Arm_input_section()
+  { }
+
+  // Initialize.
+  void
+  init();
+  
+  // Whether this is a stub table owner.
+  bool
+  is_stub_table_owner() const
+  { return this->stub_table_ != NULL && this->stub_table_->owner() == this; }
+
+  // Return the stub table.
+  Stub_table<big_endian>*
+  stub_table() const
+  { return this->stub_table_; }
+
+  // Set the stub_table.
+  void
+  set_stub_table(Stub_table<big_endian>* stub_table)
+  { this->stub_table_ = stub_table; }
+
+ protected:
+  // Write data to output file.
+  void
+  do_write(Output_file*);
+
+  // Return required alignment of this.
+  uint64_t
+  do_addralign() const
+  {
+    if (this->is_stub_table_owner())
+      return std::max(this->stub_table_->addralign(),
+		      this->original_addralign_);
+    else
+      return this->original_addralign_;
+  }
+
+  // Finalize data size.
+  void
+  set_final_data_size();
+
+  // Reset address and file offset.
+  void
+  do_reset_address_and_file_offset();
+
+  // Output offset.
+  bool
+  do_output_offset(const Relobj* object, unsigned int shndx,
+		   section_offset_type offset,
+                   section_offset_type* poutput) const
+  {
+    if ((object == this->relobj())
+	&& (shndx == this->shndx())
+	&& (offset >= 0)
+	&& (convert_types<uint64_t, section_offset_type>(offset)
+	    <= this->original_size_))
+      {
+	*poutput = offset;
+	return true;
+      }
+    else
+      return false;
+  }
+
+ private:
+  // Copying is not allowed.
+  Arm_input_section(const Arm_input_section&);
+  Arm_input_section& operator=(const Arm_input_section&);
+
+  // Address alignment of the original input section.
+  uint64_t original_addralign_;
+  // Section size of the original input section.
+  uint64_t original_size_;
+  // Stub table.
+  Stub_table<big_endian>* stub_table_;
+};
+
 // Utilities for manipulating integers of up to 32-bits
 
 namespace utils
@@ -2470,6 +2559,96 @@ Stub_table<big_endian>::do_write(Output_
   of->write_output_view(this->offset(), oview_size, oview);
 }
 
+// Arm_input_section methods.
+
+// Initialize an Arm_input_section.
+
+template<bool big_endian>
+void
+Arm_input_section<big_endian>::init()
+{
+  Relobj* relobj = this->relobj();
+  unsigned int shndx = this->shndx();
+
+  // Cache these to speed up size and alignment queries.  It is too slow
+  // to call section_addraglin and section_size every time.
+  this->original_addralign_ = relobj->section_addralign(shndx);
+  this->original_size_ = relobj->section_size(shndx);
+
+  // We want to make this look like the original input section after
+  // output sections are finalized.
+  Output_section* os = relobj->output_section(shndx);
+  off_t offset = relobj->output_section_offset(shndx);
+  gold_assert(os != NULL && !relobj->is_output_section_offset_invalid(shndx));
+  this->set_address(os->address() + offset);
+  this->set_file_offset(os->offset() + offset);
+
+  this->set_current_data_size(this->original_size_);
+  this->finalize_data_size();
+}
+
+template<bool big_endian>
+void
+Arm_input_section<big_endian>::do_write(Output_file* of)
+{
+  // We have to write out the original section content.
+  section_size_type section_size;
+  const unsigned char* section_contents =
+    this->relobj()->section_contents(this->shndx(), &section_size, false); 
+  of->write(this->offset(), section_contents, section_size); 
+
+  // If this onws a stub table and it is not empty, write it.
+  if (this->is_stub_table_owner() && !this->stub_table_->empty())
+    this->stub_table_->write(of);
+}
+
+// Finalize data size.
+
+template<bool big_endian>
+void
+Arm_input_section<big_endian>::set_final_data_size()
+{
+  // If this owns a stub table, finalize its data size as well.
+  if (this->is_stub_table_owner())
+    {
+      uint64_t address = this->address();
+
+      // The stub table comes after the original section contents.
+      address += this->original_size_;
+      address = align_address(address, this->stub_table_->addralign());
+      off_t offset = this->offset() + (address - this->address());
+      this->stub_table_->set_address_and_file_offset(address, offset);
+      address += this->stub_table_->data_size();
+      gold_assert(address == this->address() + this->current_data_size());
+    }
+
+  this->set_data_size(this->current_data_size());
+}
+
+// Reset address and file offset.
+
+template<bool big_endian>
+void
+Arm_input_section<big_endian>::do_reset_address_and_file_offset()
+{
+  // Size of the original input section contents.
+  off_t off = convert_types<off_t, uint64_t>(this->original_size_);
+
+  // If this is a stub table owner, account for the stub table size.
+  if (this->is_stub_table_owner())
+    {
+      Stub_table<big_endian>* stub_table = this->stub_table_;
+
+      // Reset the stub table's address and file offset.  The
+      // current data size for child will be updated after that.
+      stub_table_->reset_address_and_file_offset();
+      off = align_address(off, stub_table_->addralign());
+      off += stub_table->current_data_size();
+    }
+
+  this->set_current_data_size(off);
+}
+
 // A class to handle the PLT data.
 
 template<bool big_endian>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-10-22  1:17 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-21 21:39 [GOLD][PATCH] Arm_input_section class Doug Kwan (關振德)
2009-10-22  0:48 ` Ian Lance Taylor
2009-10-22  1:17   ` Doug Kwan (關振德)

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).