OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [binutils-2.20.1/] [gold/] [incremental.h] - Blame information for rev 818

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 205 julius
// inremental.h -- incremental linking support for gold   -*- C++ -*-
2
 
3
// Copyright 2009 Free Software Foundation, Inc.
4
// Written by Mikolaj Zalewski <mikolajz@google.com>.
5
 
6
// This file is part of gold.
7
 
8
// This program is free software; you can redistribute it and/or modify
9
// it under the terms of the GNU General Public License as published by
10
// the Free Software Foundation; either version 3 of the License, or
11
// (at your option) any later version.
12
 
13
// This program is distributed in the hope that it will be useful,
14
// but WITHOUT ANY WARRANTY; without even the implied warranty of
15
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
// GNU General Public License for more details.
17
 
18
// You should have received a copy of the GNU General Public License
19
// along with this program; if not, write to the Free Software
20
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21
// MA 02110-1301, USA.
22
 
23
#ifndef GOLD_INCREMENTAL_H
24
#define GOLD_INCREMENTAL_H
25
 
26
#include <map>
27
#include <vector>
28
 
29
#include "elfcpp_file.h"
30
#include "stringpool.h"
31
#include "workqueue.h"
32
#include "fileread.h"
33
#include "output.h"
34
 
35
namespace gold
36
{
37
 
38
class Archive;
39
class Input_argument;
40
class Incremental_inputs_checker;
41
class Object;
42
class Output_section_data;
43
 
44
// Incremental input type as stored in .gnu_incremental_inputs.
45
 
46
enum Incremental_input_type
47
{
48
  INCREMENTAL_INPUT_INVALID = 0,
49
  INCREMENTAL_INPUT_OBJECT = 1,
50
  INCREMENTAL_INPUT_ARCHIVE = 2,
51
  INCREMENTAL_INPUT_SHARED_LIBRARY = 3,
52
  INCREMENTAL_INPUT_SCRIPT = 4
53
};
54
 
55
// An object representing the ELF file we edit during an incremental build.
56
// Similar to Object or Dynobj, but operates on Output_file and contains
57
// method specific to file edition (TBD). This is the abstract parent class
58
// implemented in Sized_incremental_binary<size, big_endian> for a specific
59
// endianness and size.
60
 
61
class Incremental_binary
62
{
63
 public:
64
  Incremental_binary(Output_file* output, Target* target)
65
    : output_(output), target_(target)
66
  { }
67
 
68
  virtual
69
  ~Incremental_binary()
70
  { }
71
 
72
  // Functions and types for the elfcpp::Elf_file interface.  This
73
  // permit us to use Incremental_binary as the File template parameter for
74
  // elfcpp::Elf_file.
75
 
76
  // The View class is returned by view.  It must support a single
77
  // method, data().  This is trivial, because Output_file::get_output_view
78
  // does what we need.
79
  class View
80
  {
81
   public:
82
    View(const unsigned char* p)
83
      : p_(p)
84
    { }
85
 
86
    const unsigned char*
87
    data() const
88
    { return this->p_; }
89
 
90
   private:
91
    const unsigned char* p_;
92
  };
93
 
94
  // Return a View.
95
  View
96
  view(off_t file_offset, section_size_type data_size)
97
  { return View(this->output_->get_input_view(file_offset, data_size)); }
98
 
99
  // A location in the file.
100
  struct Location
101
  {
102
    off_t file_offset;
103
    off_t data_size;
104
 
105
    Location(off_t fo, section_size_type ds)
106
      : file_offset(fo), data_size(ds)
107
    { }
108
 
109
    Location()
110
      : file_offset(0), data_size(0)
111
    { }
112
  };
113
 
114
  // Get a View given a Location.
115
  View view(Location loc)
116
  { return View(this->view(loc.file_offset, loc.data_size)); }
117
 
118
  // Report an error.
119
  void
120
  error(const char* format, ...) const ATTRIBUTE_PRINTF_2;
121
 
122
  // Find the .gnu_incremental_inputs section.  It selects the first section
123
  // of type SHT_GNU_INCREMENTAL_INPUTS.  Returns false if such a section
124
  // is not found.
125
  bool
126
  find_incremental_inputs_section(Location* location,
127
                                  unsigned int* strtab_shndx)
128
  { return do_find_incremental_inputs_section(location, strtab_shndx); }
129
 
130
  // Check the .gnu_incremental_inputs section to see whether an incremental
131
  // build is possible.
132
  // TODO: on success, should report what files needs to be rebuilt.
133
  // INCREMENTAL_INPUTS is used to read the canonical form of the command line
134
  // and read the input arguments.  TODO: for items that don't need to be
135
  // rebuilt, we should also copy the incremental input information.
136
  virtual bool
137
  check_inputs(Incremental_inputs* incremental_inputs)
138
  { return do_check_inputs(incremental_inputs); }
139
 
140
 protected:
141
  // Find incremental inputs section.
142
  virtual bool
143
  do_find_incremental_inputs_section(Location* location,
144
                                     unsigned int* strtab_shndx) = 0;
145
 
146
  // Check the .gnu_incremental_inputs section to see whether an incremental
147
  // build is possible.
148
  virtual bool
149
  do_check_inputs(Incremental_inputs* incremental_inputs) = 0;
150
 
151
 private:
152
  // Edited output file object.
153
  Output_file* output_;
154
  // Target of the output file.
155
  Target* target_;
156
};
157
 
158
template<int size, bool big_endian>
159
class Sized_incremental_binary : public Incremental_binary
160
{
161
 public:
162
  Sized_incremental_binary(Output_file* output,
163
                           const elfcpp::Ehdr<size, big_endian>& ehdr,
164
                           Target* target)
165
    : Incremental_binary(output, target), elf_file_(this, ehdr)
166
  { }
167
 
168
 protected:
169
  virtual bool
170
  do_find_incremental_inputs_section(Location* location,
171
                                     unsigned int* strtab_shndx);
172
 
173
  virtual bool
174
  do_check_inputs(Incremental_inputs* incremental_inputs);
175
 
176
 private:
177
  // Output as an ELF file.
178
  elfcpp::Elf_file<size, big_endian, Incremental_binary> elf_file_;
179
};
180
 
181
// Create an Incremental_binary object for FILE. Returns NULL is this is not
182
// possible, e.g. FILE is not an ELF file or has an unsupported target.
183
Incremental_binary*
184
open_incremental_binary(Output_file* file);
185
 
186
// Code invoked early during an incremental link that checks what files need
187
// to be relinked.
188
class Incremental_checker
189
{
190
 public:
191
  // Check if the file named OUTPUT_NAME can be linked incrementally.
192
  // INCREMENTAL_INPUTS must have the canonical form of the command line
193
  // and input arguments filled - at this point of linking other fields are
194
  // probably not filled yet.  TODO: for inputs that don't need to be
195
  // rebuilt, this function should fill the incremental input information.
196
  Incremental_checker(const char* output_name,
197
                      Incremental_inputs* incremental_inputs)
198
    : output_name_(output_name), incremental_inputs_(incremental_inputs)
199
  { }
200
 
201
  // Analyzes the output file to check if incremental linking is possible and
202
  // what files needs to be relinked.
203
  bool
204
  can_incrementally_link_output_file();
205
 
206
 private:
207
  // Name of the output file to analyze.
208
  const char* output_name_;
209
 
210
  // The Incremental_inputs object. At this stage of link, only the command
211
  // line and inputs are filled.
212
  Incremental_inputs* incremental_inputs_;
213
};
214
 
215
// This class contains the information needed during an incremental
216
// build about the inputs necessary to build the .gnu_incremental_inputs.
217
class Incremental_inputs
218
{
219
 public:
220
  Incremental_inputs()
221
    : lock_(new Lock()), inputs_(NULL), command_line_key_(0),
222
      strtab_(new Stringpool())
223
  { }
224
  ~Incremental_inputs() { delete this->strtab_; }
225
 
226
  // Record the command line.
227
  void
228
  report_command_line(int argc, const char* const* argv);
229
 
230
  // Record the input arguments obtained from parsing the command line.
231
  void
232
  report_inputs(const Input_arguments& inputs)
233
  { this->inputs_ = &inputs; }
234
 
235
  // Record that the input argument INPUT is an archive ARCHIVE.
236
  void
237
  report_archive(const Input_argument* input, Archive* archive);
238
 
239
  // Record that the input argument INPUT is to an object OBJ.
240
  void
241
  report_object(const Input_argument* input, Object* obj);
242
 
243
  // Record that the input argument INPUT is to an script SCRIPT.
244
  void
245
  report_script(const Input_argument* input, Timespec mtime,
246
                Script_info* script);
247
 
248
  // Prepare for layout.  Called from Layout::finalize.
249
  void
250
  finalize();
251
 
252
  // Create the content of the .gnu_incremental_inputs section.
253
  Output_section_data*
254
  create_incremental_inputs_section_data();
255
 
256
  // Return the .gnu_incremental_strtab stringpool.
257
  Stringpool*
258
  get_stringpool()
259
  { return this->strtab_; }
260
 
261
  // Return the canonical form of the command line, as will be stored in
262
  // .gnu_incremental_strtab.
263
  const std::string&
264
  command_line()
265
  { return this->command_line_; }
266
 
267
  // Return the input files found in the command line.
268
  const Input_arguments*
269
  inputs()
270
  { return this->inputs_; }
271
 
272
 private:
273
  // Code for each of the four possible variants of create_inputs_section_data.
274
  template<int size, bool big_endian>
275
  Output_section_data*
276
  sized_create_inputs_section_data();
277
 
278
  // Compute indexes in the order in which the inputs should appear in
279
  // .gnu_incremental_inputs and put file names to the stringtable.
280
  // This needs to be done after all the scripts are parsed.
281
 
282
  void
283
  finalize_inputs(Input_argument_list::const_iterator begin,
284
                  Input_argument_list::const_iterator end,
285
                  unsigned int* index);
286
 
287
  // Additional data about an input needed for an incremental link.
288
  // None of these pointers is owned by the structure.
289
  struct Input_info
290
  {
291
    Input_info()
292
      : type(INCREMENTAL_INPUT_INVALID), archive(NULL), filename_key(0),
293
        index(0)
294
    { }
295
 
296
    // Type of the file pointed by this argument.
297
    Incremental_input_type type;
298
 
299
    union
300
    {
301
      // Present if type == INCREMENTAL_INPUT_ARCHIVE.
302
      Archive* archive;
303
 
304
      // Present if type == INCREMENTAL_INPUT_OBJECT or
305
      // INCREMENTAL_INPUT_SHARED_LIBRARY.
306
      Object* object;
307
 
308
      // Present if type == INCREMENTAL_INPUT_SCRIPT.
309
      Script_info* script;
310
    };
311
 
312
    // Key of the filename string in the section stringtable.
313
    Stringpool::Key filename_key;
314
 
315
    // Position of the entry information in the output section.
316
    unsigned int index;
317
 
318
    // Last modification time of the file.
319
    Timespec mtime;
320
  };
321
 
322
  typedef std::map<const Input_argument*, Input_info> Inputs_info_map;
323
 
324
  // A lock guarding access to inputs_ during the first phase of linking, when
325
  // report_ function may be called from multiple threads.
326
  Lock* lock_;
327
 
328
  // The list of input arguments obtained from parsing the command line.
329
  const Input_arguments* inputs_;
330
 
331
  // A map containing additional information about the input elements.
332
  Inputs_info_map inputs_map_;
333
 
334
  // Canonical form of the command line, as will be stored in
335
  // .gnu_incremental_strtab.
336
  std::string command_line_;
337
 
338
  // The key of the command line string in the string pool.
339
  Stringpool::Key command_line_key_;
340
 
341
  // The .gnu_incremental_strtab string pool associated with the
342
  // .gnu_incremental_inputs.
343
  Stringpool* strtab_;
344
};
345
 
346
} // End namespace gold.
347
 
348
#endif // !defined(GOLD_INCREMENTAL_H)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.