diff options
author | Ian Lance Taylor <ian@airs.com> | 2008-04-02 20:58:21 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2008-04-02 20:58:21 +0000 |
commit | 39d0cb0e83f9eb33feb96a18f24607065426d089 (patch) | |
tree | 3b147c4a9fe94f4eb2cb847999db7adc5ae70e5c | |
parent | 5caffa0e9b4a3cab0749be6b30fa7ebeda6b62f5 (diff) | |
download | gdb-39d0cb0e83f9eb33feb96a18f24607065426d089.zip gdb-39d0cb0e83f9eb33feb96a18f24607065426d089.tar.gz gdb-39d0cb0e83f9eb33feb96a18f24607065426d089.tar.bz2 |
* 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.
-rw-r--r-- | gold/ChangeLog | 30 | ||||
-rw-r--r-- | gold/archive.cc | 8 | ||||
-rw-r--r-- | gold/archive.h | 9 | ||||
-rw-r--r-- | gold/binary.cc | 2 | ||||
-rw-r--r-- | gold/dynobj.cc | 12 | ||||
-rw-r--r-- | gold/fileread.cc | 209 | ||||
-rw-r--r-- | gold/fileread.h | 74 | ||||
-rw-r--r-- | gold/object.cc | 22 | ||||
-rw-r--r-- | gold/object.h | 17 | ||||
-rw-r--r-- | gold/reloc.cc | 10 |
10 files changed, 285 insertions, 108 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 44b0de6..7af52ff 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,33 @@ +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. + 2008-03-31 Cary Coutant <ccoutant@google.com> Add thin archive support. diff --git a/gold/archive.cc b/gold/archive.cc index 222db96..25708ee 100644 --- a/gold/archive.cc +++ b/gold/archive.cc @@ -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_); diff --git a/gold/archive.h b/gold/archive.h index 6780398..818bd60 100644 --- a/gold/archive.h +++ b/gold/archive.h @@ -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 diff --git a/gold/binary.cc b/gold/binary.cc index 9909ff4..bee5157 100644 --- a/gold/binary.cc +++ b/gold/binary.cc @@ -132,7 +132,7 @@ Binary_to_elf::sized_convert(const Task* 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) diff --git a/gold/dynobj.cc b/gold/dynobj.cc index b686867..e593b89 100644 --- a/gold/dynobj.cc +++ b/gold/dynobj.cc @@ -183,7 +183,7 @@ Sized_dynobj<size, big_endian>::read_dynsym_section( 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_dynamic(const unsigned char* pshdrs, 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_dynamic(const unsigned char* pshdrs, } 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_symbols(Read_symbols_data* sd) 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_symbols(Read_symbols_data* sd) 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()); diff --git a/gold/fileread.cc b/gold/fileread.cc index 20820e4..6cb056f 100644 --- a/gold/fileread.cc +++ b/gold/fileread.cc @@ -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_size_type size, void* p) const 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, section_size_type size, bool cache) 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, section_size_type size, bool cache) 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, const Read_multiple& rm) 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]); diff --git a/gold/fileread.h b/gold/fileread.h index 3d59f4f..3e25f8b 100644 --- a/gold/fileread.h +++ b/gold/fileread.h @@ -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; diff --git a/gold/object.cc b/gold/object.cc index 378238d..c1ddae4 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -80,7 +80,7 @@ Object::section_contents(unsigned int shndx, section_size_type* plen, { 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_file<size, big_endian, Object>* elf_file, // 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_file<size, big_endian, Object>* elf_file, 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_symbols(Read_symbols_data* sd) 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_symbols(Read_symbols_data* sd) // 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_section_group( { // 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_section_group( 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_local_symbols(Stringpool* pool, 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_local_symbols( 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(); diff --git a/gold/object.h b/gold/object.h index 4a2ad8a..9e64277 100644 --- a/gold/object.h +++ b/gold/object.h @@ -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. diff --git a/gold/reloc.cc b/gold/reloc.cc index e4601a3..c94aa9b 100644 --- a/gold/reloc.cc +++ b/gold/reloc.cc @@ -197,7 +197,7 @@ Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd) 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_relocs(Read_relocs_data* rd) 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_relocs(Read_relocs_data* rd) 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_relocate(const General_options& options, // 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_sections( 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) |