From 4c8a1de1fe7ae5bb8aa84cad901db098ffb167c0 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Mon, 10 Dec 2012 17:38:42 +0000 Subject: [PATCH] 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. --- gold/ChangeLog | 7 ++++ gold/fileread.cc | 53 +++++++++++++++++++------------ gold/testsuite/binary_unittest.cc | 25 ++++++++++++++- 3 files changed, 63 insertions(+), 22 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 0765ac0fcbb..d11160af5be 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,10 @@ +2012-12-10 Roland McGrath + + * 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 * powerpc.cc (Target_selector_powerpc::Target_selector_powerpc): diff --git a/gold/fileread.cc b/gold/fileread.cc index 3fd35af48ee..743a1cd3ed2 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 . // This file is part of gold. @@ -137,7 +138,7 @@ File_read::View::~View() break; case DATA_MMAPPED: if (::munmap(const_cast(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(bytes) == size) - return; - if (bytes < 0) + char *read_ptr = static_cast(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(size) - > static_cast(this->size_ - start))) + > static_cast(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(size), static_cast(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 6e7b244121e..fe109226880 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(st.st_size)); CHECK(::close(o) == 0); Binary_to_elf binary(static_cast(0xffff), size, big_endian, -- 2.30.2