diff options
author | Roland McGrath <roland@gnu.org> | 2012-12-10 17:38:42 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 2012-12-10 17:38:42 +0000 |
commit | 4c8a1de1fe7ae5bb8aa84cad901db098ffb167c0 (patch) | |
tree | 044a65d6fd067495f95da4a29a771000907633ea | |
parent | 8b9737bf8cca3d3f999bb48a27019933f2138c2c (diff) | |
download | gdb-4c8a1de1fe7ae5bb8aa84cad901db098ffb167c0.zip gdb-4c8a1de1fe7ae5bb8aa84cad901db098ffb167c0.tar.gz gdb-4c8a1de1fe7ae5bb8aa84cad901db098ffb167c0.tar.bz2 |
gold/
* testsuite/binary_unittest.cc (read_all): New function.
(Sized_binary_test): Use it instead of ::read.
* fileread.cc (do_read): Don't assume pread always reads the whole
amount in a single call.
-rw-r--r-- | gold/ChangeLog | 7 | ||||
-rw-r--r-- | gold/fileread.cc | 53 | ||||
-rw-r--r-- | gold/testsuite/binary_unittest.cc | 25 |
3 files changed, 63 insertions, 22 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 0765ac0..d11160a 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,10 @@ +2012-12-10 Roland McGrath <mcgrathr@google.com> + + * testsuite/binary_unittest.cc (read_all): New function. + (Sized_binary_test): Use it instead of ::read. + * fileread.cc (do_read): Don't assume pread always reads the whole + amount in a single call. + 2012-12-10 Alan Modra <amodra@gmail.com> * powerpc.cc (Target_selector_powerpc::Target_selector_powerpc): diff --git a/gold/fileread.cc b/gold/fileread.cc index 3fd35af..743a1cd 100644 --- a/gold/fileread.cc +++ b/gold/fileread.cc @@ -1,6 +1,7 @@ // fileread.cc -- read files for gold -// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012 +// Free Software Foundation, Inc. // Written by Ian Lance Taylor <iant@google.com>. // This file is part of gold. @@ -137,7 +138,7 @@ File_read::View::~View() break; case DATA_MMAPPED: if (::munmap(const_cast<unsigned char*>(this->data_), this->size_) != 0) - gold_warning(_("munmap failed: %s"), strerror(errno)); + gold_warning(_("munmap failed: %s"), strerror(errno)); if (!parameters->options_valid() || parameters->options().stats()) { file_counts_initialize_lock.initialize(); @@ -209,7 +210,7 @@ File_read::open(const Task* task, const std::string& name) this->name_.c_str(), strerror(errno)); this->size_ = s.st_size; gold_debug(DEBUG_FILES, "Attempt to open %s succeeded", - this->name_.c_str()); + this->name_.c_str()); this->token_.add_writer(task); } @@ -228,7 +229,7 @@ File_read::open(const Task* task, const std::string& name, && this->name_.empty()); this->name_ = name; this->whole_file_view_ = new View(0, size, contents, 0, false, - View::DATA_NOT_OWNED); + View::DATA_NOT_OWNED); this->add_view(this->whole_file_view_); this->size_ = size; this->token_.add_writer(task); @@ -389,16 +390,26 @@ File_read::do_read(off_t start, section_size_type size, void* p) else { this->reopen_descriptor(); - bytes = ::pread(this->descriptor_, p, size, start); - if (static_cast<section_size_type>(bytes) == size) - return; - if (bytes < 0) + char *read_ptr = static_cast<char *>(p); + off_t read_pos = start; + size_t to_read = size; + do { - gold_fatal(_("%s: pread failed: %s"), - this->filename().c_str(), strerror(errno)); - return; + bytes = ::pread(this->descriptor_, read_ptr, to_read, read_pos); + if (bytes < 0) + gold_fatal(_("%s: pread failed: %s"), + this->filename().c_str(), strerror(errno)); + + read_pos += bytes; + read_ptr += bytes; + to_read -= bytes; + if (to_read == 0) + return; } + while (bytes > 0); + + bytes = size - to_read; } gold_fatal(_("%s: file too short: read only %lld of %lld bytes at %lld"), @@ -523,9 +534,9 @@ File_read::find_or_make_view(off_t offset, off_t start, // Check that start and end of the view are within the file. if (start > this->size_ || (static_cast<unsigned long long>(size) - > static_cast<unsigned long long>(this->size_ - start))) + > static_cast<unsigned long long>(this->size_ - start))) gold_fatal(_("%s: attempt to map %lld bytes at offset %lld exceeds " - "size of file; the file may be corrupt"), + "size of file; the file may be corrupt"), this->filename().c_str(), static_cast<long long>(size), static_cast<long long>(start)); @@ -583,7 +594,7 @@ File_read::find_or_make_view(off_t offset, off_t start, memcpy(pbytes + byteshift, v->data() + v->byteshift(), v->size()); File_read::View* shifted_view = - new File_read::View(v->start(), v->size(), pbytes, byteshift, + new File_read::View(v->start(), v->size(), pbytes, byteshift, cache, View::DATA_ALLOCATED_ARRAY); this->add_view(shifted_view); @@ -735,10 +746,10 @@ File_read::read_multiple(off_t base, const Read_multiple& rm) { const Read_multiple_entry& k_entry(rm[k]); gold_assert((convert_to_section_size_type(k_entry.file_offset - - i_off) - + k_entry.size) + - i_off) + + k_entry.size) <= convert_to_section_size_type(end_off - - i_off)); + - i_off)); memcpy(k_entry.buffer, v + (k_entry.file_offset - i_off), k_entry.size); @@ -794,8 +805,8 @@ File_read::clear_views(Clear_views_mode mode) && keep_files_mapped) should_delete = false; else if (this->object_count_ > 1 - && p->second->accessed() - && mode != CLEAR_VIEWS_ARCHIVE) + && p->second->accessed() + && mode != CLEAR_VIEWS_ARCHIVE) should_delete = false; else should_delete = true; @@ -863,7 +874,7 @@ Input_file::Input_file(const char* name) { this->input_argument_ = new Input_file_argument(name, Input_file_argument::INPUT_FILE_TYPE_FILE, - "", false, Position_dependent_options()); + "", false, Position_dependent_options()); } // Create a file for testing. @@ -874,7 +885,7 @@ Input_file::Input_file(const Task* task, const char* name, { this->input_argument_ = new Input_file_argument(name, Input_file_argument::INPUT_FILE_TYPE_FILE, - "", false, Position_dependent_options()); + "", false, Position_dependent_options()); bool ok = this->file_.open(task, name, contents, size); gold_assert(ok); } diff --git a/gold/testsuite/binary_unittest.cc b/gold/testsuite/binary_unittest.cc index 6e7b244..fe10922 100644 --- a/gold/testsuite/binary_unittest.cc +++ b/gold/testsuite/binary_unittest.cc @@ -38,6 +38,29 @@ #include "test.h" #include "testfile.h" +namespace +{ + +ssize_t +read_all (int fd, unsigned char* buf, ssize_t size) +{ + ssize_t total_read = 0; + while (size > 0) + { + ssize_t nread = ::read(fd, buf, size); + if (nread < 0) + return nread; + if (nread == 0) + break; + buf += nread; + size -= nread; + total_read += nread; + } + return total_read; +} + +} // End anonymous namespace. + namespace gold_testsuite { @@ -57,7 +80,7 @@ Sized_binary_test() int o = open_descriptor(-1, gold::program_name, O_RDONLY); CHECK(o >= 0); unsigned char* filedata = new unsigned char[st.st_size]; - CHECK(::read(o, filedata, st.st_size) == st.st_size); + CHECK(read_all(o, filedata, st.st_size) == static_cast<ssize_t>(st.st_size)); CHECK(::close(o) == 0); Binary_to_elf binary(static_cast<elfcpp::EM>(0xffff), size, big_endian, |