1ed0d50c3Schristos // fileread.h -- read files for gold -*- C++ -*- 2ed0d50c3Schristos 3*b88e3e88Schristos // Copyright (C) 2006-2020 Free Software Foundation, Inc. 4ed0d50c3Schristos // Written by Ian Lance Taylor <iant@google.com>. 5ed0d50c3Schristos 6ed0d50c3Schristos // This file is part of gold. 7ed0d50c3Schristos 8ed0d50c3Schristos // This program is free software; you can redistribute it and/or modify 9ed0d50c3Schristos // it under the terms of the GNU General Public License as published by 10ed0d50c3Schristos // the Free Software Foundation; either version 3 of the License, or 11ed0d50c3Schristos // (at your option) any later version. 12ed0d50c3Schristos 13ed0d50c3Schristos // This program is distributed in the hope that it will be useful, 14ed0d50c3Schristos // but WITHOUT ANY WARRANTY; without even the implied warranty of 15ed0d50c3Schristos // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16ed0d50c3Schristos // GNU General Public License for more details. 17ed0d50c3Schristos 18ed0d50c3Schristos // You should have received a copy of the GNU General Public License 19ed0d50c3Schristos // along with this program; if not, write to the Free Software 20ed0d50c3Schristos // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21ed0d50c3Schristos // MA 02110-1301, USA. 22ed0d50c3Schristos 23ed0d50c3Schristos // Classes used to read data from binary input files. 24ed0d50c3Schristos 25ed0d50c3Schristos #ifndef GOLD_FILEREAD_H 26ed0d50c3Schristos #define GOLD_FILEREAD_H 27ed0d50c3Schristos 28ed0d50c3Schristos #include <list> 29ed0d50c3Schristos #include <map> 30ed0d50c3Schristos #include <string> 31ed0d50c3Schristos #include <vector> 32ed0d50c3Schristos 33ed0d50c3Schristos #include "token.h" 34ed0d50c3Schristos 35ed0d50c3Schristos namespace gold 36ed0d50c3Schristos { 37ed0d50c3Schristos 38ed0d50c3Schristos // Since not all system supports stat.st_mtim and struct timespec, 39ed0d50c3Schristos // we define our own structure and fill the nanoseconds if we can. 40ed0d50c3Schristos 41ed0d50c3Schristos struct Timespec 42ed0d50c3Schristos { TimespecTimespec43ed0d50c3Schristos Timespec() 44ed0d50c3Schristos : seconds(0), nanoseconds(0) 45ed0d50c3Schristos { } 46ed0d50c3Schristos TimespecTimespec47ed0d50c3Schristos Timespec(time_t a_seconds, int a_nanoseconds) 48ed0d50c3Schristos : seconds(a_seconds), nanoseconds(a_nanoseconds) 49ed0d50c3Schristos { } 50ed0d50c3Schristos 51ed0d50c3Schristos time_t seconds; 52ed0d50c3Schristos int nanoseconds; 53ed0d50c3Schristos }; 54ed0d50c3Schristos 55ed0d50c3Schristos // Get the last modified time of an unopened file. Returns false if the 56ed0d50c3Schristos // file does not exist. 57ed0d50c3Schristos 58ed0d50c3Schristos bool 59ed0d50c3Schristos get_mtime(const char* filename, Timespec* mtime); 60ed0d50c3Schristos 61ed0d50c3Schristos class Position_dependent_options; 62ed0d50c3Schristos class Input_file_argument; 63ed0d50c3Schristos class Dirsearch; 64ed0d50c3Schristos class File_view; 65ed0d50c3Schristos 66ed0d50c3Schristos // File_read manages a file descriptor and mappings for a file we are 67ed0d50c3Schristos // reading. 68ed0d50c3Schristos 69ed0d50c3Schristos class File_read 70ed0d50c3Schristos { 71ed0d50c3Schristos public: File_read()72ed0d50c3Schristos File_read() 73ed0d50c3Schristos : name_(), descriptor_(-1), is_descriptor_opened_(false), object_count_(0), 74ed0d50c3Schristos size_(0), token_(false), views_(), saved_views_(), mapped_bytes_(0), 75ed0d50c3Schristos released_(true), whole_file_view_(NULL) 76ed0d50c3Schristos { } 77ed0d50c3Schristos 78ed0d50c3Schristos ~File_read(); 79ed0d50c3Schristos 80ed0d50c3Schristos // Open a file. 81ed0d50c3Schristos bool 82ed0d50c3Schristos open(const Task*, const std::string& name); 83ed0d50c3Schristos 84ed0d50c3Schristos // Pretend to open the file, but provide the file contents. No 85ed0d50c3Schristos // actual file system activity will occur. This is used for 86ed0d50c3Schristos // testing. 87ed0d50c3Schristos bool 88ed0d50c3Schristos open(const Task*, const std::string& name, const unsigned char* contents, 89ed0d50c3Schristos off_t size); 90ed0d50c3Schristos 91ed0d50c3Schristos // Return the file name. 92ed0d50c3Schristos const std::string& filename()93ed0d50c3Schristos filename() const 94ed0d50c3Schristos { return this->name_; } 95ed0d50c3Schristos 96ed0d50c3Schristos // Add an object associated with a file. 97ed0d50c3Schristos void add_object()98ed0d50c3Schristos add_object() 99ed0d50c3Schristos { ++this->object_count_; } 100ed0d50c3Schristos 101ed0d50c3Schristos // Remove an object associated with a file. 102ed0d50c3Schristos void remove_object()103ed0d50c3Schristos remove_object() 104ed0d50c3Schristos { --this->object_count_; } 105ed0d50c3Schristos 106ed0d50c3Schristos // Lock the file for exclusive access within a particular Task::run 107ed0d50c3Schristos // execution. This routine may only be called when the workqueue 108ed0d50c3Schristos // lock is held. 109ed0d50c3Schristos void 110ed0d50c3Schristos lock(const Task* t); 111ed0d50c3Schristos 112ed0d50c3Schristos // Unlock the file. 113ed0d50c3Schristos void 114ed0d50c3Schristos unlock(const Task* t); 115ed0d50c3Schristos 116ed0d50c3Schristos // Test whether the object is locked. 117ed0d50c3Schristos bool 118ed0d50c3Schristos is_locked() const; 119ed0d50c3Schristos 120ed0d50c3Schristos // Return the token, so that the task can be queued. 121ed0d50c3Schristos Task_token* token()122ed0d50c3Schristos token() 123ed0d50c3Schristos { return &this->token_; } 124ed0d50c3Schristos 125ed0d50c3Schristos // Release the file. This indicates that we aren't going to do 126ed0d50c3Schristos // anything further with it until it is unlocked. This is used 127ed0d50c3Schristos // because a Task which locks the file never calls either lock or 128ed0d50c3Schristos // unlock; it just locks the token. The basic rule is that a Task 129ed0d50c3Schristos // which locks a file via the Task::locks interface must explicitly 130ed0d50c3Schristos // call release() when it is done. This is not necessary for code 131ed0d50c3Schristos // which calls unlock() on the file. 132ed0d50c3Schristos void 133ed0d50c3Schristos release(); 134ed0d50c3Schristos 135ed0d50c3Schristos // Return the size of the file. 136ed0d50c3Schristos off_t filesize()137ed0d50c3Schristos filesize() const 138ed0d50c3Schristos { return this->size_; } 139ed0d50c3Schristos 140ed0d50c3Schristos // Return a view into the file starting at file offset START for 141ed0d50c3Schristos // SIZE bytes. OFFSET is the offset into the input file for the 142ed0d50c3Schristos // file we are reading; this is zero for a normal object file, 143ed0d50c3Schristos // non-zero for an object file in an archive. ALIGNED is true if 144ed0d50c3Schristos // the data must be naturally aligned (i.e., aligned to the size 145ed0d50c3Schristos // of a target word); this only matters when OFFSET is not zero. 146ed0d50c3Schristos // The pointer will remain valid until the File_read is unlocked. 147ed0d50c3Schristos // It is an error if we can not read enough data from the file. 148ed0d50c3Schristos // The CACHE parameter is a hint as to whether it will be useful 149ed0d50c3Schristos // to cache this data for later accesses--i.e., later calls to 150ed0d50c3Schristos // get_view, read, or get_lasting_view which retrieve the same 151ed0d50c3Schristos // data. 152ed0d50c3Schristos const unsigned char* 153ed0d50c3Schristos get_view(off_t offset, off_t start, section_size_type size, bool aligned, 154ed0d50c3Schristos bool cache); 155ed0d50c3Schristos 156ed0d50c3Schristos // Read data from the file into the buffer P starting at file offset 157ed0d50c3Schristos // START for SIZE bytes. 158ed0d50c3Schristos void 159ed0d50c3Schristos read(off_t start, section_size_type size, void* p); 160ed0d50c3Schristos 161ed0d50c3Schristos // Return a lasting view into the file starting at file offset START 162ed0d50c3Schristos // for SIZE bytes. This is allocated with new, and the caller is 163ed0d50c3Schristos // responsible for deleting it when done. The data associated with 164ed0d50c3Schristos // this view will remain valid until the view is deleted. It is an 165ed0d50c3Schristos // error if we can not read enough data from the file. The OFFSET, 166ed0d50c3Schristos // ALIGNED and CACHE parameters are as in get_view. 167ed0d50c3Schristos File_view* 168ed0d50c3Schristos get_lasting_view(off_t offset, off_t start, section_size_type size, 169ed0d50c3Schristos bool aligned, bool cache); 170ed0d50c3Schristos 171ed0d50c3Schristos // Mark all views as no longer cached. 172ed0d50c3Schristos void 173ed0d50c3Schristos clear_view_cache_marks(); 174ed0d50c3Schristos 175ed0d50c3Schristos // Discard all uncached views. This is normally done by release(), 176ed0d50c3Schristos // but not for objects in archives. FIXME: This is a complicated 177ed0d50c3Schristos // interface, and it would be nice to have something more automatic. 178ed0d50c3Schristos void clear_uncached_views()179ed0d50c3Schristos clear_uncached_views() 180ed0d50c3Schristos { this->clear_views(CLEAR_VIEWS_ARCHIVE); } 181ed0d50c3Schristos 182ed0d50c3Schristos // A struct used to do a multiple read. 183ed0d50c3Schristos struct Read_multiple_entry 184ed0d50c3Schristos { 185ed0d50c3Schristos // The file offset of the data to read. 186ed0d50c3Schristos off_t file_offset; 187ed0d50c3Schristos // The amount of data to read. 188ed0d50c3Schristos section_size_type size; 189ed0d50c3Schristos // The buffer where the data should be placed. 190ed0d50c3Schristos unsigned char* buffer; 191ed0d50c3Schristos Read_multiple_entryRead_multiple_entry192ed0d50c3Schristos Read_multiple_entry(off_t o, section_size_type s, unsigned char* b) 193ed0d50c3Schristos : file_offset(o), size(s), buffer(b) 194ed0d50c3Schristos { } 195ed0d50c3Schristos }; 196ed0d50c3Schristos 197ed0d50c3Schristos typedef std::vector<Read_multiple_entry> Read_multiple; 198ed0d50c3Schristos 199ed0d50c3Schristos // Read a bunch of data from the file into various different 200ed0d50c3Schristos // locations. The vector must be sorted by ascending file_offset. 201ed0d50c3Schristos // BASE is a base offset to be added to all the offsets in the 202ed0d50c3Schristos // vector. 203ed0d50c3Schristos void 204ed0d50c3Schristos read_multiple(off_t base, const Read_multiple&); 205ed0d50c3Schristos 206ed0d50c3Schristos // Dump statistical information to stderr. 207ed0d50c3Schristos static void 208ed0d50c3Schristos print_stats(); 209ed0d50c3Schristos 210ed0d50c3Schristos // Return the open file descriptor (for plugins). 211ed0d50c3Schristos int descriptor()212ed0d50c3Schristos descriptor() 213ed0d50c3Schristos { 214ed0d50c3Schristos this->reopen_descriptor(); 215ed0d50c3Schristos return this->descriptor_; 216ed0d50c3Schristos } 217ed0d50c3Schristos 218ed0d50c3Schristos // Return the file last modification time. Calls gold_fatal if the stat 219ed0d50c3Schristos // system call failed. 220ed0d50c3Schristos Timespec 221ed0d50c3Schristos get_mtime(); 222ed0d50c3Schristos 223ed0d50c3Schristos private: 224ed0d50c3Schristos // Control for what views to clear. 225ed0d50c3Schristos enum Clear_views_mode 226ed0d50c3Schristos { 227ed0d50c3Schristos // Clear uncached views not used by an archive. 228ed0d50c3Schristos CLEAR_VIEWS_NORMAL, 229ed0d50c3Schristos // Clear all uncached views (including in an archive). 230ed0d50c3Schristos CLEAR_VIEWS_ARCHIVE, 231ed0d50c3Schristos // Clear all views (i.e., we're destroying the file). 232ed0d50c3Schristos CLEAR_VIEWS_ALL 233ed0d50c3Schristos }; 234ed0d50c3Schristos 235ed0d50c3Schristos // This class may not be copied. 236ed0d50c3Schristos File_read(const File_read&); 237ed0d50c3Schristos File_read& operator=(const File_read&); 238ed0d50c3Schristos 239ed0d50c3Schristos // Total bytes mapped into memory during the link if --stats. 240ed0d50c3Schristos static unsigned long long total_mapped_bytes; 241ed0d50c3Schristos 242ed0d50c3Schristos // Current number of bytes mapped into memory during the link if 243ed0d50c3Schristos // --stats. 244ed0d50c3Schristos static unsigned long long current_mapped_bytes; 245ed0d50c3Schristos 246ed0d50c3Schristos // High water mark of bytes mapped into memory during the link if 247ed0d50c3Schristos // --stats. 248ed0d50c3Schristos static unsigned long long maximum_mapped_bytes; 249ed0d50c3Schristos 250ed0d50c3Schristos // A view into the file. 251ed0d50c3Schristos class View 252ed0d50c3Schristos { 253ed0d50c3Schristos public: 254ed0d50c3Schristos // Specifies how to dispose the data on destruction of the view. 255ed0d50c3Schristos enum Data_ownership 256ed0d50c3Schristos { 257ed0d50c3Schristos // Data owned by File object - nothing done in destructor. 258ed0d50c3Schristos DATA_NOT_OWNED, 259ed0d50c3Schristos // Data allocated with new[] and owned by this object - should 260ed0d50c3Schristos // use delete[]. 261ed0d50c3Schristos DATA_ALLOCATED_ARRAY, 262ed0d50c3Schristos // Data mmapped and owned by this object - should munmap. 263ed0d50c3Schristos DATA_MMAPPED 264ed0d50c3Schristos }; 265ed0d50c3Schristos View(off_t start,section_size_type size,const unsigned char * data,unsigned int byteshift,bool cache,Data_ownership data_ownership)266ed0d50c3Schristos View(off_t start, section_size_type size, const unsigned char* data, 267ed0d50c3Schristos unsigned int byteshift, bool cache, Data_ownership data_ownership) 268ed0d50c3Schristos : start_(start), size_(size), data_(data), lock_count_(0), 269ed0d50c3Schristos byteshift_(byteshift), cache_(cache), data_ownership_(data_ownership), 270ed0d50c3Schristos accessed_(true) 271ed0d50c3Schristos { } 272ed0d50c3Schristos 273ed0d50c3Schristos ~View(); 274ed0d50c3Schristos 275ed0d50c3Schristos off_t start()276ed0d50c3Schristos start() const 277ed0d50c3Schristos { return this->start_; } 278ed0d50c3Schristos 279ed0d50c3Schristos section_size_type size()280ed0d50c3Schristos size() const 281ed0d50c3Schristos { return this->size_; } 282ed0d50c3Schristos 283ed0d50c3Schristos const unsigned char* data()284ed0d50c3Schristos data() const 285ed0d50c3Schristos { return this->data_; } 286ed0d50c3Schristos 287ed0d50c3Schristos void 288ed0d50c3Schristos lock(); 289ed0d50c3Schristos 290ed0d50c3Schristos void 291ed0d50c3Schristos unlock(); 292ed0d50c3Schristos 293ed0d50c3Schristos bool 294ed0d50c3Schristos is_locked(); 295ed0d50c3Schristos 296ed0d50c3Schristos unsigned int byteshift()297ed0d50c3Schristos byteshift() const 298ed0d50c3Schristos { return this->byteshift_; } 299ed0d50c3Schristos 300ed0d50c3Schristos void set_cache()301ed0d50c3Schristos set_cache() 302ed0d50c3Schristos { this->cache_ = true; } 303ed0d50c3Schristos 304ed0d50c3Schristos void clear_cache()305ed0d50c3Schristos clear_cache() 306ed0d50c3Schristos { this->cache_ = false; } 307ed0d50c3Schristos 308ed0d50c3Schristos bool should_cache()309ed0d50c3Schristos should_cache() const 310ed0d50c3Schristos { return this->cache_; } 311ed0d50c3Schristos 312ed0d50c3Schristos void set_accessed()313ed0d50c3Schristos set_accessed() 314ed0d50c3Schristos { this->accessed_ = true; } 315ed0d50c3Schristos 316ed0d50c3Schristos void clear_accessed()317ed0d50c3Schristos clear_accessed() 318ed0d50c3Schristos { this->accessed_= false; } 319ed0d50c3Schristos 320ed0d50c3Schristos bool accessed()321ed0d50c3Schristos accessed() const 322ed0d50c3Schristos { return this->accessed_; } 323ed0d50c3Schristos 324ed0d50c3Schristos // Returns TRUE if this view contains permanent data -- e.g., data that 325ed0d50c3Schristos // was supplied by the owner of the File object. 326ed0d50c3Schristos bool is_permanent_view()327ed0d50c3Schristos is_permanent_view() const 328ed0d50c3Schristos { return this->data_ownership_ == DATA_NOT_OWNED; } 329ed0d50c3Schristos 330ed0d50c3Schristos private: 331ed0d50c3Schristos View(const View&); 332ed0d50c3Schristos View& operator=(const View&); 333ed0d50c3Schristos 334ed0d50c3Schristos // The file offset of the start of the view. 335ed0d50c3Schristos off_t start_; 336ed0d50c3Schristos // The size of the view. 337ed0d50c3Schristos section_size_type size_; 338ed0d50c3Schristos // A pointer to the actual bytes. 339ed0d50c3Schristos const unsigned char* data_; 340ed0d50c3Schristos // The number of locks on this view. 341ed0d50c3Schristos int lock_count_; 342ed0d50c3Schristos // The number of bytes that the view is shifted relative to the 343ed0d50c3Schristos // underlying file. This is used to align data. This is normally 344ed0d50c3Schristos // zero, except possibly for an object in an archive. 345ed0d50c3Schristos unsigned int byteshift_; 346ed0d50c3Schristos // Whether the view is cached. 347ed0d50c3Schristos bool cache_; 348ed0d50c3Schristos // Whether the view is mapped into memory. If not, data_ points 349ed0d50c3Schristos // to memory allocated using new[]. 350ed0d50c3Schristos Data_ownership data_ownership_; 351ed0d50c3Schristos // Whether the view has been accessed recently. 352ed0d50c3Schristos bool accessed_; 353ed0d50c3Schristos }; 354ed0d50c3Schristos 355ed0d50c3Schristos friend class View; 356ed0d50c3Schristos friend class File_view; 357ed0d50c3Schristos 358ed0d50c3Schristos // The type of a mapping from page start and byte shift to views. 359ed0d50c3Schristos typedef std::map<std::pair<off_t, unsigned int>, View*> Views; 360ed0d50c3Schristos 361ed0d50c3Schristos // A simple list of Views. 362ed0d50c3Schristos typedef std::list<View*> Saved_views; 363ed0d50c3Schristos 364ed0d50c3Schristos // Open the descriptor if necessary. 365ed0d50c3Schristos void 366ed0d50c3Schristos reopen_descriptor(); 367ed0d50c3Schristos 368ed0d50c3Schristos // Find a view into the file. 369ed0d50c3Schristos View* 370ed0d50c3Schristos find_view(off_t start, section_size_type size, unsigned int byteshift, 371ed0d50c3Schristos View** vshifted) const; 372ed0d50c3Schristos 373ed0d50c3Schristos // Read data from the file into a buffer. 374ed0d50c3Schristos void 375ed0d50c3Schristos do_read(off_t start, section_size_type size, void* p); 376ed0d50c3Schristos 377ed0d50c3Schristos // Add a view. 378ed0d50c3Schristos void 379ed0d50c3Schristos add_view(View*); 380ed0d50c3Schristos 381ed0d50c3Schristos // Make a view into the file. 382ed0d50c3Schristos View* 383ed0d50c3Schristos make_view(off_t start, section_size_type size, unsigned int byteshift, 384ed0d50c3Schristos bool cache); 385ed0d50c3Schristos 386ed0d50c3Schristos // Find or make a view into the file. 387ed0d50c3Schristos View* 388ed0d50c3Schristos find_or_make_view(off_t offset, off_t start, section_size_type size, 389ed0d50c3Schristos bool aligned, bool cache); 390ed0d50c3Schristos 391ed0d50c3Schristos // Clear the file views. 392ed0d50c3Schristos void 393ed0d50c3Schristos clear_views(Clear_views_mode); 394ed0d50c3Schristos 395ed0d50c3Schristos // The size of a file page for buffering data. 396ed0d50c3Schristos static const off_t page_size = 8192; 397ed0d50c3Schristos 398ed0d50c3Schristos // Given a file offset, return the page offset. 399ed0d50c3Schristos static off_t page_offset(off_t file_offset)400ed0d50c3Schristos page_offset(off_t file_offset) 401ed0d50c3Schristos { return file_offset & ~ (page_size - 1); } 402ed0d50c3Schristos 403ed0d50c3Schristos // Given a file size, return the size to read integral pages. 404ed0d50c3Schristos static off_t pages(off_t file_size)405ed0d50c3Schristos pages(off_t file_size) 406ed0d50c3Schristos { return (file_size + (page_size - 1)) & ~ (page_size - 1); } 407ed0d50c3Schristos 408ed0d50c3Schristos // The maximum number of entries we will pass to ::readv. 409ed0d50c3Schristos static const size_t max_readv_entries = 128; 410ed0d50c3Schristos 411ed0d50c3Schristos // Use readv to read data. 412ed0d50c3Schristos void 413ed0d50c3Schristos do_readv(off_t base, const Read_multiple&, size_t start, size_t count); 414ed0d50c3Schristos 415ed0d50c3Schristos // File name. 416ed0d50c3Schristos std::string name_; 417ed0d50c3Schristos // File descriptor. 418ed0d50c3Schristos int descriptor_; 419ed0d50c3Schristos // Whether we have regained the descriptor after releasing the file. 420ed0d50c3Schristos bool is_descriptor_opened_; 421ed0d50c3Schristos // The number of objects associated with this file. This will be 422ed0d50c3Schristos // more than 1 in the case of an archive. 423ed0d50c3Schristos int object_count_; 424ed0d50c3Schristos // File size. 425ed0d50c3Schristos off_t size_; 426ed0d50c3Schristos // A token used to lock the file. 427ed0d50c3Schristos Task_token token_; 428ed0d50c3Schristos // Buffered views into the file. 429ed0d50c3Schristos Views views_; 430ed0d50c3Schristos // List of views which were locked but had to be removed from views_ 431ed0d50c3Schristos // because they were not large enough. 432ed0d50c3Schristos Saved_views saved_views_; 433ed0d50c3Schristos // Total amount of space mapped into memory. This is only changed 434ed0d50c3Schristos // while the file is locked. When we unlock the file, we transfer 435ed0d50c3Schristos // the total to total_mapped_bytes, and reset this to zero. 436ed0d50c3Schristos size_t mapped_bytes_; 437ed0d50c3Schristos // Whether the file was released. 438ed0d50c3Schristos bool released_; 439ed0d50c3Schristos // A view containing the whole file. May be NULL if we mmap only 440ed0d50c3Schristos // the relevant parts of the file. Not NULL if: 441ed0d50c3Schristos // - Flag --mmap_whole_files is set (default on 64-bit hosts). 442ed0d50c3Schristos // - The contents was specified in the constructor. Used only for 443ed0d50c3Schristos // testing purposes). 444ed0d50c3Schristos View* whole_file_view_; 445ed0d50c3Schristos }; 446ed0d50c3Schristos 447ed0d50c3Schristos // A view of file data that persists even when the file is unlocked. 448ed0d50c3Schristos // Callers should destroy these when no longer required. These are 449ed0d50c3Schristos // obtained form File_read::get_lasting_view. They may only be 450ed0d50c3Schristos // destroyed when the underlying File_read is locked. 451ed0d50c3Schristos 452ed0d50c3Schristos class File_view 453ed0d50c3Schristos { 454ed0d50c3Schristos public: 455ed0d50c3Schristos // This may only be called when the underlying File_read is locked. 456ed0d50c3Schristos ~File_view(); 457ed0d50c3Schristos 458ed0d50c3Schristos // Return a pointer to the data associated with this view. 459ed0d50c3Schristos const unsigned char* data()460ed0d50c3Schristos data() const 461ed0d50c3Schristos { return this->data_; } 462ed0d50c3Schristos 463ed0d50c3Schristos private: 464ed0d50c3Schristos File_view(const File_view&); 465ed0d50c3Schristos File_view& operator=(const File_view&); 466ed0d50c3Schristos 467ed0d50c3Schristos friend class File_read; 468ed0d50c3Schristos 469ed0d50c3Schristos // Callers have to get these via File_read::get_lasting_view. File_view(File_read & file,File_read::View * view,const unsigned char * data)470ed0d50c3Schristos File_view(File_read& file, File_read::View* view, const unsigned char* data) 471ed0d50c3Schristos : file_(file), view_(view), data_(data) 472ed0d50c3Schristos { } 473ed0d50c3Schristos 474ed0d50c3Schristos File_read& file_; 475ed0d50c3Schristos File_read::View* view_; 476ed0d50c3Schristos const unsigned char* data_; 477ed0d50c3Schristos }; 478ed0d50c3Schristos 479ed0d50c3Schristos // All the information we hold for a single input file. This can be 480ed0d50c3Schristos // an object file, a shared library, or an archive. 481ed0d50c3Schristos 482ed0d50c3Schristos class Input_file 483ed0d50c3Schristos { 484ed0d50c3Schristos public: 485ed0d50c3Schristos enum Format 486ed0d50c3Schristos { 487ed0d50c3Schristos FORMAT_NONE, 488ed0d50c3Schristos FORMAT_ELF, 489ed0d50c3Schristos FORMAT_BINARY 490ed0d50c3Schristos }; 491ed0d50c3Schristos Input_file(const Input_file_argument * input_argument)492ed0d50c3Schristos Input_file(const Input_file_argument* input_argument) 493ed0d50c3Schristos : input_argument_(input_argument), found_name_(), file_(), 494ed0d50c3Schristos is_in_sysroot_(false), format_(FORMAT_NONE) 495ed0d50c3Schristos { } 496ed0d50c3Schristos 497ed0d50c3Schristos // Create an input file given just a filename. 498ed0d50c3Schristos Input_file(const char* name); 499ed0d50c3Schristos 500ed0d50c3Schristos // Create an input file with the contents already provided. This is 501ed0d50c3Schristos // only used for testing. With this path, don't call the open 502ed0d50c3Schristos // method. 503ed0d50c3Schristos Input_file(const Task*, const char* name, const unsigned char* contents, 504ed0d50c3Schristos off_t size); 505ed0d50c3Schristos 506ed0d50c3Schristos // Return the command line argument. 507ed0d50c3Schristos const Input_file_argument* input_file_argument()508ed0d50c3Schristos input_file_argument() const 509ed0d50c3Schristos { return this->input_argument_; } 510ed0d50c3Schristos 511ed0d50c3Schristos // Return whether this is a file that we will search for in the list 512ed0d50c3Schristos // of directories. 513ed0d50c3Schristos bool 514ed0d50c3Schristos will_search_for() const; 515ed0d50c3Schristos 516ed0d50c3Schristos // Open the file. If the open fails, this will report an error and 517ed0d50c3Schristos // return false. If there is a search, it starts at directory 518ed0d50c3Schristos // *PINDEX. *PINDEX should be initialized to zero. It may be 519ed0d50c3Schristos // restarted to find the next file with a matching name by 520ed0d50c3Schristos // incrementing the result and calling this again. 521ed0d50c3Schristos bool 522ed0d50c3Schristos open(const Dirsearch&, const Task*, int* pindex); 523ed0d50c3Schristos 524ed0d50c3Schristos // Return the name given by the user. For -lc this will return "c". 525ed0d50c3Schristos const char* 526ed0d50c3Schristos name() const; 527ed0d50c3Schristos 528ed0d50c3Schristos // Return the file name. For -lc this will return something like 529ed0d50c3Schristos // "/usr/lib/libc.so". 530ed0d50c3Schristos const std::string& filename()531ed0d50c3Schristos filename() const 532ed0d50c3Schristos { return this->file_.filename(); } 533ed0d50c3Schristos 534ed0d50c3Schristos // Return the name under which we found the file, corresponding to 535ed0d50c3Schristos // the command line. For -lc this will return something like 536ed0d50c3Schristos // "libc.so". 537ed0d50c3Schristos const std::string& found_name()538ed0d50c3Schristos found_name() const 539ed0d50c3Schristos { return this->found_name_; } 540ed0d50c3Schristos 541ed0d50c3Schristos // Return the position dependent options. 542ed0d50c3Schristos const Position_dependent_options& 543ed0d50c3Schristos options() const; 544ed0d50c3Schristos 545ed0d50c3Schristos // Return the file. 546ed0d50c3Schristos File_read& file()547ed0d50c3Schristos file() 548ed0d50c3Schristos { return this->file_; } 549ed0d50c3Schristos 550ed0d50c3Schristos const File_read& file()551ed0d50c3Schristos file() const 552ed0d50c3Schristos { return this->file_; } 553ed0d50c3Schristos 554ed0d50c3Schristos // Whether we found the file in a directory in the system root. 555ed0d50c3Schristos bool is_in_sysroot()556ed0d50c3Schristos is_in_sysroot() const 557ed0d50c3Schristos { return this->is_in_sysroot_; } 558ed0d50c3Schristos 559ed0d50c3Schristos // Whether this file is in a system directory. 560ed0d50c3Schristos bool 561ed0d50c3Schristos is_in_system_directory() const; 562ed0d50c3Schristos 563ed0d50c3Schristos // Return whether this file is to be read only for its symbols. 564ed0d50c3Schristos bool 565ed0d50c3Schristos just_symbols() const; 566ed0d50c3Schristos 567ed0d50c3Schristos // Return the format of the unconverted input file. 568ed0d50c3Schristos Format format()569ed0d50c3Schristos format() const 570ed0d50c3Schristos { return this->format_; } 571ed0d50c3Schristos 572ed0d50c3Schristos // Try to find a file in the extra search dirs. Returns true on success. 573ed0d50c3Schristos static bool 574ed0d50c3Schristos try_extra_search_path(int* pindex, 575ed0d50c3Schristos const Input_file_argument* input_argument, 576ed0d50c3Schristos std::string filename, std::string* found_name, 577ed0d50c3Schristos std::string* namep); 578ed0d50c3Schristos 579ed0d50c3Schristos // Find the actual file. 580ed0d50c3Schristos static bool 581ed0d50c3Schristos find_file(const Dirsearch& dirpath, int* pindex, 582ed0d50c3Schristos const Input_file_argument* input_argument, 583ed0d50c3Schristos bool* is_in_sysroot, 584ed0d50c3Schristos std::string* found_name, std::string* namep); 585ed0d50c3Schristos 586ed0d50c3Schristos private: 587ed0d50c3Schristos Input_file(const Input_file&); 588ed0d50c3Schristos Input_file& operator=(const Input_file&); 589ed0d50c3Schristos 590ed0d50c3Schristos // Open a binary file. 591ed0d50c3Schristos bool 592ed0d50c3Schristos open_binary(const Task* task, const std::string& name); 593ed0d50c3Schristos 594ed0d50c3Schristos // The argument from the command line. 595ed0d50c3Schristos const Input_file_argument* input_argument_; 596ed0d50c3Schristos // The name under which we opened the file. This is like the name 597ed0d50c3Schristos // on the command line, but -lc turns into libc.so (or whatever). 598ed0d50c3Schristos // It only includes the full path if the path was on the command 599ed0d50c3Schristos // line. 600ed0d50c3Schristos std::string found_name_; 601ed0d50c3Schristos // The file after we open it. 602ed0d50c3Schristos File_read file_; 603ed0d50c3Schristos // Whether we found the file in a directory in the system root. 604ed0d50c3Schristos bool is_in_sysroot_; 605ed0d50c3Schristos // Format of unconverted input file. 606ed0d50c3Schristos Format format_; 607ed0d50c3Schristos }; 608ed0d50c3Schristos 609ed0d50c3Schristos } // end namespace gold 610ed0d50c3Schristos 611ed0d50c3Schristos #endif // !defined(GOLD_FILEREAD_H) 612