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]

Re: sparc gold support...


David Miller <davem@davemloft.net> writes:

> Ok, next problem is archive handling on systems that
> trap on unaligned accesses.
>
> Offsets within and archive into members can have all kinds of odd
> offsets.  The object file reader infrastructure in gold assumes it can
> just reference views via mmap().
>
> But if the offset is odd, this doesn't work and results on SIGBUS
> errors on platforms like Sparc.  This occurs as the ELF bits larger
> than a byte in size get dereferenced.
>
> It looks like a buffered version of the file view reader will need to
> be implemented, and used instead of mmap() if the offset is not a
> multiple of the largest core type size on the host (for sparc this
> would need to be something like sizeof(double), but generically I
> suppose something like sizeof(unsigned long long) could be used).

Thanks for the analysis.  I really should have thought of that, but it
never occurred to me.

I just committed the appended patch which should fix this.  I added an
aligned parameter to the get_view and get_lasting_view functions which
indicates whether the caller needs aligned data.  The initial file
offset is also passed down separately from the offset within the file;
this is used to see whether any alignment is required.  We then record
for each View how much the data has been shifted.  Let me know what
happens--you should be able to test it with a cross-linker running on
a SPARC host.

While testing the performance I noticed that we waste a lot of time
clearing views in an archive during a static link--or, rather, not
clearing views, as in general they are marked to be cached.  It was
actually wasting 18% of CPU time doing a static link of hello, world.
This patch includes a couple of conceptually unrelated changes to not
waste so much time doing that.

Ian


2008-04-02  Ian Lance Taylor  <iant@google.com>

	* fileread.cc (File_read::find_view): Add byteshift and vshifted
	parameters.  Update for new key type to views_.  Change all
	callers.
	(File_read::read): Adjust for byteshift in returned view.
	(File_read::add_view): New function, broken out of
	find_and_make_view.
	(File_read::make_view): New function, broken out of
	find_and_make_view.
	(File_read::find_or_make_view): Add offset and aligned
	parameters.  Rewrite accordingly.  Change all callers.
	(File_read::get_view): Add offset and aligned parameters.  Adjust
	for byteshift in return value.
	(File_read::get_lasting_view): Likewise.
	* fileread.h (class File_read): Update declarations.
	(class File_read::View): Add byteshift_ field.  Add byteshift to
	constructor.  Add byteshift method.
	* archive.h (Archive::clear_uncached_views): New function.
	(Archive::get_view): Add aligned parameter.  Change all callers.
	* object.h (Object::get_view): Add aligned parameter.  Change all
	callers.
	(Object::get_lasting_view): Likewise.

	* fileread.cc (File_read::release): Don't call clear_views if
	there are multiple objects.
	* fileread.h (File_read::clear_uncached_views): New function.
	* archive.cc (Add_archive_symbols::run): Call clear_uncached_views
	on the archive.


Index: archive.cc
===================================================================
RCS file: /cvs/src/src/gold/archive.cc,v
retrieving revision 1.27
diff -p -u -r1.27 archive.cc
--- archive.cc	1 Apr 2008 20:57:36 -0000	1.27
+++ archive.cc	2 Apr 2008 19:06:53 -0000
@@ -112,7 +112,7 @@ Archive::setup()
   if (xname == "/")
     {
       const unsigned char* p = this->get_view(off + sizeof(Archive_header),
-                                              extended_size, true);
+                                              extended_size, false, true);
       const char* px = reinterpret_cast<const char*>(p);
       this->extended_names_.assign(px, extended_size);
     }
@@ -137,7 +137,7 @@ void
 Archive::read_armap(off_t start, section_size_type size)
 {
   // Read in the entire armap.
-  const unsigned char* p = this->get_view(start, size, false);
+  const unsigned char* p = this->get_view(start, size, true, false);
 
   // Numbers in the armap are always big-endian.
   const elfcpp::Elf_Word* pword = reinterpret_cast<const elfcpp::Elf_Word*>(p);
@@ -178,7 +178,8 @@ off_t
 Archive::read_header(off_t off, bool cache, std::string* pname,
                      off_t* nested_off)
 {
-  const unsigned char* p = this->get_view(off, sizeof(Archive_header), cache);
+  const unsigned char* p = this->get_view(off, sizeof(Archive_header), true,
+					  cache);
   const Archive_header* hdr = reinterpret_cast<const Archive_header*>(p);
   return this->interpret_header(hdr, off,  pname, nested_off);
 }
@@ -554,6 +555,7 @@ Add_archive_symbols::run(Workqueue*)
   this->archive_->unlock_nested_archives();
 
   this->archive_->release();
+  this->archive_->clear_uncached_views();
 
   if (this->input_group_ != NULL)
     this->input_group_->add_archive(this->archive_);
Index: archive.h
===================================================================
RCS file: /cvs/src/src/gold/archive.h,v
retrieving revision 1.18
diff -p -u -r1.18 archive.h
--- archive.h	1 Apr 2008 20:57:36 -0000	1.18
+++ archive.h	2 Apr 2008 19:06:53 -0000
@@ -100,6 +100,11 @@ class Archive
   release()
   { this->input_file_->file().release(); }
 
+  // Clear uncached views in the underlying file.
+  void
+  clear_uncached_views()
+  { this->input_file_->file().clear_uncached_views(); }
+
   // Unlock any nested archives.
   void
   unlock_nested_archives();
@@ -117,8 +122,8 @@ class Archive
 
   // Get a view into the underlying file.
   const unsigned char*
-  get_view(off_t start, section_size_type size, bool cache)
-  { return this->input_file_->file().get_view(start, size, cache); }
+  get_view(off_t start, section_size_type size, bool aligned, bool cache)
+  { return this->input_file_->file().get_view(0, start, size, aligned, cache); }
 
   // Read the archive symbol map.
   void
Index: binary.cc
===================================================================
RCS file: /cvs/src/src/gold/binary.cc,v
retrieving revision 1.1
diff -p -u -r1.1 binary.cc
--- binary.cc	8 Feb 2008 07:06:57 -0000	1.1
+++ binary.cc	2 Apr 2008 19:06:53 -0000
@@ -132,7 +132,7 @@ Binary_to_elf::sized_convert(const Task*
     }
 
   section_size_type filesize = convert_to_section_size_type(f.filesize());
-  const unsigned char* fileview = f.get_view(0, filesize, false);
+  const unsigned char* fileview = f.get_view(0, 0, filesize, false, false);
 
   unsigned int align;
   if (size == 32)
Index: dynobj.cc
===================================================================
RCS file: /cvs/src/src/gold/dynobj.cc,v
retrieving revision 1.36
diff -p -u -r1.36 dynobj.cc
--- dynobj.cc	7 Mar 2008 16:30:59 -0000	1.36
+++ dynobj.cc	2 Apr 2008 19:06:53 -0000
@@ -183,7 +183,7 @@ Sized_dynobj<size, big_endian>::read_dyn
 	        shndx, shdr.get_sh_link(), link);
 
   *view = this->get_lasting_view(shdr.get_sh_offset(), shdr.get_sh_size(),
-				 false);
+				 true, false);
   *view_size = convert_to_section_size_type(shdr.get_sh_size());
   *view_info = shdr.get_sh_info();
 }
@@ -208,7 +208,7 @@ Sized_dynobj<size, big_endian>::read_dyn
 
   const off_t dynamic_size = dynamicshdr.get_sh_size();
   const unsigned char* pdynamic = this->get_view(dynamicshdr.get_sh_offset(),
-						 dynamic_size, false);
+						 dynamic_size, true, false);
 
   const unsigned int link = dynamicshdr.get_sh_link();
   if (link != strtab_shndx)
@@ -229,7 +229,8 @@ Sized_dynobj<size, big_endian>::read_dyn
 	}
 
       strtab_size = strtabshdr.get_sh_size();
-      strtabu = this->get_view(strtabshdr.get_sh_offset(), strtab_size, false);
+      strtabu = this->get_view(strtabshdr.get_sh_offset(), strtab_size, false,
+			       false);
     }
 
   const char* const strtab = reinterpret_cast<const char*>(strtabu);
@@ -313,7 +314,8 @@ Sized_dynobj<size, big_endian>::do_read_
       gold_assert(dynsymshdr.get_sh_type() == elfcpp::SHT_DYNSYM);
 
       sd->symbols = this->get_lasting_view(dynsymshdr.get_sh_offset(),
-					   dynsymshdr.get_sh_size(), false);
+					   dynsymshdr.get_sh_size(), true,
+					   false);
       sd->symbols_size =
 	convert_to_section_size_type(dynsymshdr.get_sh_size());
 
@@ -336,7 +338,7 @@ Sized_dynobj<size, big_endian>::do_read_
 
       sd->symbol_names = this->get_lasting_view(strtabshdr.get_sh_offset(),
 						strtabshdr.get_sh_size(),
-						false);
+						false, false);
       sd->symbol_names_size =
 	convert_to_section_size_type(strtabshdr.get_sh_size());
 
Index: fileread.cc
===================================================================
RCS file: /cvs/src/src/gold/fileread.cc,v
retrieving revision 1.39
diff -p -u -r1.39 fileread.cc
--- fileread.cc	13 Mar 2008 21:04:21 -0000	1.39
+++ fileread.cc	2 Apr 2008 19:06:53 -0000
@@ -158,7 +158,10 @@ File_read::release()
   if (File_read::current_mapped_bytes > File_read::maximum_mapped_bytes)
     File_read::maximum_mapped_bytes = File_read::current_mapped_bytes;
 
-  this->clear_views(false);
+  // Only clear views if there is only one attached object.  Otherwise
+  // we waste time trying to clear cached archive views.
+  if (this->object_count_ <= 1)
+    this->clear_views(false);
 
   this->released_ = true;
 }
@@ -196,27 +199,44 @@ File_read::is_locked() const
 
 // See if we have a view which covers the file starting at START for
 // SIZE bytes.  Return a pointer to the View if found, NULL if not.
+// If BYTESHIFT is not -1U, the returned View must have the specified
+// byte shift; otherwise, it may have any byte shift.  If VSHIFTED is
+// not NULL, this sets *VSHIFTED to a view which would have worked if
+// not for the requested BYTESHIFT.
 
 inline File_read::View*
-File_read::find_view(off_t start, section_size_type size) const
+File_read::find_view(off_t start, section_size_type size,
+		     unsigned int byteshift, File_read::View** vshifted) const
 {
+  if (vshifted != NULL)
+    *vshifted = NULL;
+
   off_t page = File_read::page_offset(start);
 
-  Views::const_iterator p = this->views_.lower_bound(page);
-  if (p == this->views_.end() || p->first > page)
+  unsigned int bszero = 0;
+  Views::const_iterator p = this->views_.upper_bound(std::make_pair(page - 1,
+								    bszero));
+
+  while (p != this->views_.end() && p->first.first <= page)
     {
-      if (p == this->views_.begin())
-	return NULL;
-      --p;
-    }
+      if (p->second->start() <= start
+	  && (p->second->start() + static_cast<off_t>(p->second->size())
+	      >= start + static_cast<off_t>(size)))
+	{
+	  if (byteshift == -1U || byteshift == p->second->byteshift())
+	    {
+	      p->second->set_accessed();
+	      return p->second;
+	    }
 
-  if (p->second->start() + static_cast<off_t>(p->second->size())
-      < start + static_cast<off_t>(size))
-    return NULL;
+	  if (vshifted != NULL && *vshifted == NULL)
+	    *vshifted = p->second;
+	}
 
-  p->second->set_accessed();
+      ++p;
+    }
 
-  return p->second;
+  return NULL;
 }
 
 // Read SIZE bytes from the file starting at offset START.  Read into
@@ -261,53 +281,53 @@ File_read::do_read(off_t start, section_
 void
 File_read::read(off_t start, section_size_type size, void* p) const
 {
-  const File_read::View* pv = this->find_view(start, size);
+  const File_read::View* pv = this->find_view(start, size, -1U, NULL);
   if (pv != NULL)
     {
-      memcpy(p, pv->data() + (start - pv->start()), size);
+      memcpy(p, pv->data() + (start - pv->start() + pv->byteshift()), size);
       return;
     }
 
   this->do_read(start, size, p);
 }
 
-// Find an existing view or make a new one.
+// Add a new view.  There may already be an existing view at this
+// offset.  If there is, the new view will be larger, and should
+// replace the old view.
 
-File_read::View*
-File_read::find_or_make_view(off_t start, section_size_type size, bool cache)
+void
+File_read::add_view(File_read::View* v)
 {
-  gold_assert(!this->token_.is_writable());
-  this->released_ = false;
+  std::pair<Views::iterator, bool> ins =
+    this->views_.insert(std::make_pair(std::make_pair(v->start(),
+						      v->byteshift()),
+				       v));
+  if (ins.second)
+    return;
 
-  File_read::View* v = this->find_view(start, size);
-  if (v != NULL)
+  // There was an existing view at this offset.  It must not be large
+  // enough.  We can't delete it here, since something might be using
+  // it; we put it on a list to be deleted when the file is unlocked.
+  File_read::View* vold = ins.first->second;
+  gold_assert(vold->size() < v->size());
+  if (vold->should_cache())
     {
-      if (cache)
-	v->set_cache();
-      return v;
+      v->set_cache();
+      vold->clear_cache();
     }
+  this->saved_views_.push_back(vold);
 
-  off_t poff = File_read::page_offset(start);
-
-  File_read::View* const vnull = NULL;
-  std::pair<Views::iterator, bool> ins =
-    this->views_.insert(std::make_pair(poff, vnull));
+  ins.first->second = v;
+}
 
-  if (!ins.second)
-    {
-      // There was an existing view at this offset.  It must not be
-      // large enough.  We can't delete it here, since something might
-      // be using it; put it on a list to be deleted when the file is
-      // unlocked.
-      v = ins.first->second;
-      gold_assert(v->size() - (start - v->start()) < size);
-      if (v->should_cache())
-	cache = true;
-      v->clear_cache();
-      this->saved_views_.push_back(v);
-    }
+// Make a new view with a specified byteshift, reading the data from
+// the file.
 
-  // We need to map data from the file.
+File_read::View*
+File_read::make_view(off_t start, section_size_type size,
+		     unsigned int byteshift, bool cache)
+{
+  off_t poff = File_read::page_offset(start);
 
   section_size_type psize = File_read::pages(size + (start - poff));
 
@@ -317,11 +337,13 @@ File_read::find_or_make_view(off_t start
       gold_assert(psize >= size);
     }
 
-  if (this->contents_ != NULL)
+  File_read::View* v;
+  if (this->contents_ != NULL || byteshift != 0)
     {
-      unsigned char* p = new unsigned char[psize];
-      this->do_read(poff, psize, p);
-      v = new File_read::View(poff, psize, p, cache, false);
+      unsigned char* p = new unsigned char[psize + byteshift];
+      memset(p, 0, byteshift);
+      this->do_read(poff, psize, p + byteshift);
+      v = new File_read::View(poff, psize, p, byteshift, cache, false);
     }
   else
     {
@@ -337,28 +359,97 @@ File_read::find_or_make_view(off_t start
       this->mapped_bytes_ += psize;
 
       const unsigned char* pbytes = static_cast<const unsigned char*>(p);
-      v = new File_read::View(poff, psize, pbytes, cache, true);
+      v = new File_read::View(poff, psize, pbytes, 0, cache, true);
     }
 
-  ins.first->second = v;
+  this->add_view(v);
+
   return v;
 }
 
+// Find a View or make a new one, shifted as required by the file
+// offset OFFSET and ALIGNED.
+
+File_read::View*
+File_read::find_or_make_view(off_t offset, off_t start,
+			     section_size_type size, bool aligned, bool cache)
+{
+  unsigned int byteshift;
+  if (offset == 0)
+    byteshift = 0;
+  else
+    {
+      unsigned int target_size = (!parameters->target_valid()
+				  ? 64
+				  : parameters->target().get_size());
+      byteshift = offset & ((target_size / 8) - 1);
+
+      // Set BYTESHIFT to the number of dummy bytes which must be
+      // inserted before the data in order for this data to be
+      // aligned.
+      if (byteshift != 0)
+	byteshift = (target_size / 8) - byteshift;
+    }
+
+  // Try to find a View with the required BYTESHIFT.
+  File_read::View* vshifted;
+  File_read::View* v = this->find_view(offset + start, size,
+				       aligned ? byteshift : -1U,
+				       &vshifted);
+  if (v != NULL)
+    {
+      if (cache)
+	v->set_cache();
+      return v;
+    }
+
+  // If VSHIFTED is not NULL, then it has the data we need, but with
+  // the wrong byteshift.
+  v = vshifted;
+  if (v != NULL)
+    {
+      gold_assert(aligned);
+
+      unsigned char* pbytes = new unsigned char[v->size() + byteshift];
+      memset(pbytes, 0, byteshift);
+      memcpy(pbytes + byteshift, v->data() + v->byteshift(), v->size());
+
+      File_read::View* shifted_view = new File_read::View(v->start(), v->size(),
+							  pbytes, byteshift,
+							  cache, false);
+
+      this->add_view(shifted_view);
+      return shifted_view;
+    }
+
+  // Make a new view.  If we don't need an aligned view, use a
+  // byteshift of 0, so that we can use mmap.
+  return this->make_view(offset + start, size,
+			 aligned ? byteshift : 0,
+			 cache);
+}
+
 // Get a view into the file.
 
 const unsigned char*
-File_read::get_view(off_t start, section_size_type size, bool cache)
+File_read::get_view(off_t offset, off_t start, section_size_type size,
+		    bool aligned, bool cache)
 {
-  File_read::View* pv = this->find_or_make_view(start, size, cache);
-  return pv->data() + (start - pv->start());
+  File_read::View* pv = this->find_or_make_view(offset, start, size,
+						aligned, cache);
+  return pv->data() + (offset + start - pv->start() + pv->byteshift());
 }
 
 File_view*
-File_read::get_lasting_view(off_t start, section_size_type size, bool cache)
+File_read::get_lasting_view(off_t offset, off_t start, section_size_type size,
+			    bool aligned, bool cache)
 {
-  File_read::View* pv = this->find_or_make_view(start, size, cache);
+  File_read::View* pv = this->find_or_make_view(offset, start, size,
+						aligned, cache);
   pv->lock();
-  return new File_view(*this, pv, pv->data() + (start - pv->start()));
+  return new File_view(*this, pv,
+		       (pv->data()
+			+ (offset + start - pv->start() + pv->byteshift())));
 }
 
 // Use readv to read COUNT entries from RM starting at START.  BASE
@@ -450,13 +541,15 @@ File_read::read_multiple(off_t base, con
       else
 	{
 	  File_read::View* view = this->find_view(base + i_off,
-						  end_off - i_off);
+						  end_off - i_off,
+						  -1U, NULL);
 	  if (view == NULL)
 	    this->do_readv(base, rm, i, j - i);
 	  else
 	    {
 	      const unsigned char* v = (view->data()
-					+ (base + i_off - view->start()));
+					+ (base + i_off - view->start()
+					   + view->byteshift()));
 	      for (size_t k = i; k < j; ++k)
 		{
 		  const Read_multiple_entry& k_entry(rm[k]);
Index: fileread.h
===================================================================
RCS file: /cvs/src/src/gold/fileread.h,v
retrieving revision 1.28
diff -p -u -r1.28 fileread.h
--- fileread.h	13 Mar 2008 21:04:21 -0000	1.28
+++ fileread.h	2 Apr 2008 19:06:53 -0000
@@ -116,14 +116,19 @@ class File_read
   { return this->size_; }
 
   // Return a view into the file starting at file offset START for
-  // SIZE bytes.  The pointer will remain valid until the File_read is
-  // unlocked.  It is an error if we can not read enough data from the
-  // file.  The CACHE parameter is a hint as to whether it will be
+  // SIZE bytes.  OFFSET is the offset into the input file for the
+  // file we are reading; this is zero for a normal object file,
+  // non-zero for an object file in an archive.  ALIGNED is true if
+  // the data must be naturally aligned; this only matters when OFFSET
+  // is not zero.  The pointer will remain valid until the File_read
+  // is unlocked.  It is an error if we can not read enough data from
+  // the file.  The CACHE parameter is a hint as to whether it will be
   // useful to cache this data for later accesses--i.e., later calls
   // to get_view, read, or get_lasting_view which retrieve the same
   // data.
   const unsigned char*
-  get_view(off_t start, section_size_type size, bool cache);
+  get_view(off_t offset, off_t start, section_size_type size, bool aligned,
+	   bool cache);
 
   // Read data from the file into the buffer P starting at file offset
   // START for SIZE bytes.
@@ -134,15 +139,23 @@ class File_read
   // for SIZE bytes.  This is allocated with new, and the caller is
   // responsible for deleting it when done.  The data associated with
   // this view will remain valid until the view is deleted.  It is an
-  // error if we can not read enough data from the file.  The CACHE
-  // parameter is as in get_view.
+  // error if we can not read enough data from the file.  The OFFSET,
+  // ALIGNED and CACHE parameters are as in get_view.
   File_view*
-  get_lasting_view(off_t start, section_size_type size, bool cache);
+  get_lasting_view(off_t offset, off_t start, section_size_type size,
+		   bool aligned, bool cache);
 
   // Mark all views as no longer cached.
   void
   clear_view_cache_marks();
 
+  // Discard all uncached views.  This is normally done by release(),
+  // but not for objects in archives.  FIXME: This is a complicated
+  // interface, and it would be nice to have something more automatic.
+  void
+  clear_uncached_views()
+  { this->clear_views(false); }
+
   // A struct used to do a multiple read.
   struct Read_multiple_entry
   {
@@ -193,9 +206,9 @@ class File_read
   {
    public:
     View(off_t start, section_size_type size, const unsigned char* data,
-	 bool cache, bool mapped)
+	 unsigned int byteshift, bool cache, bool mapped)
       : start_(start), size_(size), data_(data), lock_count_(0),
-	cache_(cache), mapped_(mapped), accessed_(true)
+	byteshift_(byteshift), cache_(cache), mapped_(mapped), accessed_(true)
     { }
 
     ~View();
@@ -221,6 +234,10 @@ class File_read
     bool
     is_locked();
 
+    unsigned int
+    byteshift() const
+    { return this->byteshift_; }
+
     void
     set_cache()
     { this->cache_ = true; }
@@ -249,29 +266,58 @@ class File_read
     View(const View&);
     View& operator=(const View&);
 
+    // The file offset of the start of the view.
     off_t start_;
+    // The size of the view.
     section_size_type size_;
+    // A pointer to the actual bytes.
     const unsigned char* data_;
+    // The number of locks on this view.
     int lock_count_;
+    // The number of bytes that the view is shifted relative to the
+    // underlying file.  This is used to align data.  This is normally
+    // zero, except possibly for an object in an archive.
+    unsigned int byteshift_;
+    // Whether the view is cached.
     bool cache_;
+    // Whether the view is mapped into memory.  If not, data_ points
+    // to memory allocated using new[].
     bool mapped_;
+    // Whether the view has been accessed recently.
     bool accessed_;
   };
 
   friend class View;
   friend class File_view;
 
+  // The type of a mapping from page start and byte shift to views.
+  typedef std::map<std::pair<off_t, unsigned int>, View*> Views;
+
+  // A simple list of Views.
+  typedef std::list<View*> Saved_views;
+
   // Find a view into the file.
   View*
-  find_view(off_t start, section_size_type size) const;
+  find_view(off_t start, section_size_type size, unsigned int byteshift,
+	    View** vshifted) const;
 
   // Read data from the file into a buffer.
   void
   do_read(off_t start, section_size_type size, void* p) const;
 
+  // Add a view.
+  void
+  add_view(View*);
+
+  // Make a view into the file.
+  View*
+  make_view(off_t start, section_size_type size, unsigned int byteshift,
+	    bool cache);
+
   // Find or make a view into the file.
   View*
-  find_or_make_view(off_t start, section_size_type size, bool cache);
+  find_or_make_view(off_t offset, off_t start, section_size_type size,
+		    bool aligned, bool cache);
 
   // Clear the file views.
   void
@@ -290,12 +336,6 @@ class File_read
   pages(off_t file_size)
   { return (file_size + (page_size - 1)) & ~ (page_size - 1); }
 
-  // The type of a mapping from page start to views.
-  typedef std::map<off_t, View*> Views;
-
-  // A simple list of Views.
-  typedef std::list<View*> Saved_views;
-
   // The maximum number of entries we will pass to ::readv.
   static const size_t max_readv_entries = 128;
 
Index: object.cc
===================================================================
RCS file: /cvs/src/src/gold/object.cc,v
retrieving revision 1.65
diff -p -u -r1.65 object.cc
--- object.cc	26 Mar 2008 23:36:46 -0000	1.65
+++ object.cc	2 Apr 2008 19:06:53 -0000
@@ -80,7 +80,7 @@ Object::section_contents(unsigned int sh
 {
   Location loc(this->do_section_contents(shndx));
   *plen = convert_to_section_size_type(loc.data_size);
-  return this->get_view(loc.file_offset, *plen, cache);
+  return this->get_view(loc.file_offset, *plen, true, cache);
 }
 
 // Read the section data into SD.  This is code common to Sized_relobj
@@ -96,7 +96,8 @@ Object::read_section_data(elfcpp::Elf_fi
   // Read the section headers.
   const off_t shoff = elf_file->shoff();
   const unsigned int shnum = this->shnum();
-  sd->section_headers = this->get_lasting_view(shoff, shnum * shdr_size, true);
+  sd->section_headers = this->get_lasting_view(shoff, shnum * shdr_size,
+					       true, true);
 
   // Read the section names.
   const unsigned char* pshdrs = sd->section_headers->data();
@@ -110,7 +111,8 @@ Object::read_section_data(elfcpp::Elf_fi
   sd->section_names_size =
     convert_to_section_size_type(shdrnames.get_sh_size());
   sd->section_names = this->get_lasting_view(shdrnames.get_sh_offset(),
-					     sd->section_names_size, false);
+					     sd->section_names_size, false,
+					     false);
 }
 
 // If NAME is the name of a special .gnu.warning section, arrange for
@@ -319,7 +321,7 @@ Sized_relobj<size, big_endian>::do_read_
   off_t readoff = this->has_eh_frame_ ? dataoff : extoff;
   section_size_type readsize = this->has_eh_frame_ ? datasize : extsize;
 
-  File_view* fvsymtab = this->get_lasting_view(readoff, readsize, false);
+  File_view* fvsymtab = this->get_lasting_view(readoff, readsize, true, false);
 
   // Read the section header for the symbol names.
   unsigned int strtab_shndx = symtabshdr.get_sh_link();
@@ -338,7 +340,8 @@ Sized_relobj<size, big_endian>::do_read_
 
   // Read the symbol names.
   File_view* fvstrtab = this->get_lasting_view(strtabshdr.get_sh_offset(),
-					       strtabshdr.get_sh_size(), true);
+					       strtabshdr.get_sh_size(),
+					       false, true);
 
   sd->symbols = fvsymtab;
   sd->symbols_size = readsize;
@@ -390,7 +393,7 @@ Sized_relobj<size, big_endian>::include_
 {
   // Read the section contents.
   const unsigned char* pcon = this->get_view(shdr.get_sh_offset(),
-					     shdr.get_sh_size(), false);
+					     shdr.get_sh_size(), true, false);
   const elfcpp::Elf_Word* pword =
     reinterpret_cast<const elfcpp::Elf_Word*>(pcon);
 
@@ -417,7 +420,8 @@ Sized_relobj<size, big_endian>::include_
       return false;
     }
   off_t symoff = symshdr.get_sh_offset() + shdr.get_sh_info() * This::sym_size;
-  const unsigned char* psym = this->get_view(symoff, This::sym_size, false);
+  const unsigned char* psym = this->get_view(symoff, This::sym_size, true,
+					     false);
   elfcpp::Sym<size, big_endian> sym(psym);
 
   // Read the symbol table names.
@@ -849,7 +853,7 @@ Sized_relobj<size, big_endian>::do_count
   gold_assert(loccount == symtabshdr.get_sh_info());
   off_t locsize = loccount * sym_size;
   const unsigned char* psyms = this->get_view(symtabshdr.get_sh_offset(),
-					      locsize, true);
+					      locsize, true, true);
 
   // Read the symbol names.
   const unsigned int strtab_shndx = symtabshdr.get_sh_link();
@@ -1084,7 +1088,7 @@ Sized_relobj<size, big_endian>::write_lo
   const int sym_size = This::sym_size;
   off_t locsize = loccount * sym_size;
   const unsigned char* psyms = this->get_view(symtabshdr.get_sh_offset(),
-					      locsize, false);
+					      locsize, true, false);
 
   // Read the symbol names.
   const unsigned int strtab_shndx = symtabshdr.get_sh_link();
Index: object.h
===================================================================
RCS file: /cvs/src/src/gold/object.h,v
retrieving revision 1.56
diff -p -u -r1.56 object.h
--- object.h	25 Mar 2008 18:37:16 -0000	1.56
+++ object.h	2 Apr 2008 19:06:53 -0000
@@ -295,7 +295,7 @@ class Object
   // Return a View.
   View
   view(off_t file_offset, section_size_type data_size)
-  { return View(this->get_view(file_offset, data_size, true)); }
+  { return View(this->get_view(file_offset, data_size, true, true)); }
 
   // Report an error.
   void
@@ -314,22 +314,23 @@ class Object
 
   // Get a View given a Location.
   View view(Location loc)
-  { return View(this->get_view(loc.file_offset, loc.data_size, true)); }
+  { return View(this->get_view(loc.file_offset, loc.data_size, true, true)); }
 
   // Get a view into the underlying file.
   const unsigned char*
-  get_view(off_t start, section_size_type size, bool cache)
+  get_view(off_t start, section_size_type size, bool aligned, bool cache)
   {
-    return this->input_file()->file().get_view(start + this->offset_, size,
-					       cache);
+    return this->input_file()->file().get_view(this->offset_, start, size,
+					       aligned, cache);
   }
 
   // Get a lasting view into the underlying file.
   File_view*
-  get_lasting_view(off_t start, section_size_type size, bool cache)
+  get_lasting_view(off_t start, section_size_type size, bool aligned,
+		   bool cache)
   {
-    return this->input_file()->file().get_lasting_view(start + this->offset_,
-						       size, cache);
+    return this->input_file()->file().get_lasting_view(this->offset_, start,
+						       size, aligned, cache);
   }
 
   // Read data from the underlying file.
Index: reloc.cc
===================================================================
RCS file: /cvs/src/src/gold/reloc.cc,v
retrieving revision 1.33
diff -p -u -r1.33 reloc.cc
--- reloc.cc	13 Mar 2008 21:04:21 -0000	1.33
+++ reloc.cc	2 Apr 2008 19:06:53 -0000
@@ -197,7 +197,7 @@ Sized_relobj<size, big_endian>::do_read_
 
   const unsigned char *pshdrs = this->get_view(this->elf_file_.shoff(),
 					       shnum * This::shdr_size,
-					       true);
+					       true, true);
   // Skip the first, dummy, section.
   const unsigned char *ps = pshdrs + This::shdr_size;
   for (unsigned int i = 1; i < shnum; ++i, ps += This::shdr_size)
@@ -269,7 +269,7 @@ Sized_relobj<size, big_endian>::do_read_
       sr.reloc_shndx = i;
       sr.data_shndx = shndx;
       sr.contents = this->get_lasting_view(shdr.get_sh_offset(), sh_size,
-					   true);
+					   true, true);
       sr.sh_type = sh_type;
       sr.reloc_count = reloc_count;
       sr.output_section = os;
@@ -291,7 +291,7 @@ Sized_relobj<size, big_endian>::do_read_
       gold_assert(loccount == symtabshdr.get_sh_info());
       off_t locsize = loccount * sym_size;
       rd->local_symbols = this->get_lasting_view(symtabshdr.get_sh_offset(),
-						 locsize, true);
+						 locsize, true, true);
     }
 }
 
@@ -465,7 +465,7 @@ Sized_relobj<size, big_endian>::do_reloc
   // Read the section headers.
   const unsigned char* pshdrs = this->get_view(this->elf_file_.shoff(),
 					       shnum * This::shdr_size,
-					       true);
+					       true, true);
 
   Views views;
   views.resize(shnum);
@@ -745,7 +745,7 @@ Sized_relobj<size, big_endian>::relocate
 
       off_t sh_size = shdr.get_sh_size();
       const unsigned char* prelocs = this->get_view(shdr.get_sh_offset(),
-						    sh_size, false);
+						    sh_size, true, false);
 
       unsigned int reloc_size;
       if (sh_type == elfcpp::SHT_REL)

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