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