diff options
Diffstat (limited to 'gold/fileread.h')
-rw-r--r-- | gold/fileread.h | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/gold/fileread.h b/gold/fileread.h new file mode 100644 index 000000000000..178e7f355e44 --- /dev/null +++ b/gold/fileread.h @@ -0,0 +1,257 @@ +// fileread.h -- read files for gold -*- C++ -*- + +// Classes used to read data from binary input files. + +#ifndef GOLD_FILEREAD_H +#define GOLD_FILEREAD_H + +#include <list> +#include <map> +#include <string> + +#include "options.h" + +namespace gold +{ + +class Dirsearch; +class File_view; + +// File_read manages a file descriptor for a file we are reading. We +// close file descriptors if we run out of them, so this class reopens +// the file as needed. + +class File_read +{ + public: + File_read() + : name_(), descriptor_(-1), lock_count_(0), views_(), + saved_views_(), contents_(NULL), contents_size_(0) + { } + + ~File_read(); + + // Open a file. + bool + open(const std::string& name); + + // Pretend to open the file, but provide the file contents. No + // actual file system activity will occur. This is used for + // testing. + bool + open(const std::string& name, const unsigned char* contents, off_t size); + + // Return the file name. + const std::string& + filename() const + { return this->name_; } + + // Lock the file for access within a particular Task::run execution. + // This means that the descriptor can not be closed. This routine + // may only be called from the main thread. + void + lock(); + + // Unlock the descriptor, permitting it to be closed if necessary. + void + unlock(); + + // Test whether the object is locked. + bool + is_locked(); + + // Return a view into the file. The pointer will remain valid until + // the File_read is unlocked. If PBYTES is NULL, it is an error if + // we can not read enough data. Otherwise *PBYTES is set to the + // number of bytes read. + const unsigned char* + get_view(off_t start, off_t size, off_t *pbytes = NULL); + + // Read data from the file into the buffer P. PBYTES is as in + // get_view. + void + read(off_t start, off_t size, void* p, off_t *pbytes = NULL); + + // Return a lasting view into the file. 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. PBYTES is handled as with get_view. + File_view* + get_lasting_view(off_t start, off_t size, off_t *pbytes = NULL); + + private: + // This class may not be copied. + File_read(const File_read&); + File_read& operator=(const File_read&); + + // A view into the file when not using mmap. + class View + { + public: + View(off_t start, off_t size, unsigned char* data) + : start_(start), size_(size), data_(data), lock_count_(0) + { } + + ~View(); + + off_t + start() const + { return this->start_; } + + off_t + size() const + { return this->size_; } + + unsigned char* + data() const + { return this->data_; } + + void + lock(); + + void + unlock(); + + bool + is_locked(); + + private: + View(const View&); + View& operator=(const View&); + + off_t start_; + off_t size_; + unsigned char* data_; + int lock_count_; + }; + + friend class File_view; + + // Find a view into the file. + View* + find_view(off_t start, off_t size); + + // Read data from the file into a buffer. + off_t + do_read(off_t start, off_t size, void* p, off_t* pbytes); + + // Find or make a view into the file. + View* + find_or_make_view(off_t start, off_t size, off_t* pbytes); + + // Clear the file views. + void + clear_views(bool); + + // The size of a file page for buffering data. + static const off_t page_size = 8192; + + // Given a file offset, return the page offset. + static off_t + page_offset(off_t file_offset) + { return file_offset & ~ (page_size - 1); } + + // Given a file size, return the size to read integral pages. + static off_t + 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; + + // File name. + std::string name_; + // File descriptor. + int descriptor_; + // Number of locks on the file. + int lock_count_; + // Buffered views into the file. + Views views_; + // List of views which were locked but had to be removed from views_ + // because they were not large enough. + Saved_views saved_views_; + // Specified file contents. Used only for testing purposes. + const unsigned char* contents_; + // Specified file size. Used only for testing purposes. + off_t contents_size_; +}; + +// A view of file data that persists even when the file is unlocked. +// Callers should destroy these when no longer required. These are +// obtained form File_read::get_lasting_view. They may only be +// destroyed when the underlying File_read is locked. + +class File_view +{ + public: + // This may only be called when the underlying File_read is locked. + ~File_view(); + + // Return a pointer to the data associated with this view. + const unsigned char* + data() const + { return this->data_; } + + private: + File_view(const File_view&); + File_view& operator=(const File_view&); + + friend class File_read; + + // Callers have to get these via File_read::get_lasting_view. + File_view(File_read& file, File_read::View* view, const unsigned char* data) + : file_(file), view_(view), data_(data) + { } + + File_read& file_; + File_read::View* view_; + const unsigned char* data_; +}; + +// All the information we hold for a single input file. This can be +// an object file, a shared library, or an archive. + +class Input_file +{ + public: + Input_file(const Input_file_argument* input_argument) + : input_argument_(input_argument), file_() + { } + + // Create an input file with the contents already provided. This is + // only used for testing. With this path, don't call the open + // method. + Input_file(const char* name, const unsigned char* contents, off_t size); + + // Open the file. + void + open(const General_options&, const Dirsearch&); + + // Return the name given by the user. + const char* + name() const + { return this->input_argument_->name(); } + + // Return the file name. + const std::string& + filename() const + { return this->file_.filename(); } + + File_read& + file() + { return this->file_; } + + private: + Input_file(const Input_file&); + Input_file& operator=(const Input_file&); + + const Input_file_argument* input_argument_; + File_read file_; +}; + +} // end namespace gold + +#endif // !defined(GOLD_FILEREAD_H) |