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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gold/] [reloc.h] - Blame information for rev 166

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 khays
// reloc.h -- relocate input files for gold   -*- C++ -*-
2
 
3 166 khays
// Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012
4
// Free Software Foundation, Inc.
5 27 khays
// Written by Ian Lance Taylor <iant@google.com>.
6
 
7
// This file is part of gold.
8
 
9
// This program is free software; you can redistribute it and/or modify
10
// it under the terms of the GNU General Public License as published by
11
// the Free Software Foundation; either version 3 of the License, or
12
// (at your option) any later version.
13
 
14
// This program is distributed in the hope that it will be useful,
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
// GNU General Public License for more details.
18
 
19
// You should have received a copy of the GNU General Public License
20
// along with this program; if not, write to the Free Software
21
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22
// MA 02110-1301, USA.
23
 
24
#ifndef GOLD_RELOC_H
25
#define GOLD_RELOC_H
26
 
27
#include <vector>
28
#ifdef HAVE_BYTESWAP_H
29
#include <byteswap.h>
30
#endif
31
 
32
#include "elfcpp.h"
33
#include "workqueue.h"
34
 
35
namespace gold
36
{
37
 
38
class General_options;
39
class Object;
40
class Relobj;
41
class Read_relocs_data;
42
class Symbol;
43
class Layout;
44
class Output_data;
45
class Output_section;
46
 
47
template<int size>
48
class Sized_symbol;
49
 
50
template<int size, bool big_endian>
51
class Sized_relobj_file;
52
 
53
template<int size>
54
class Symbol_value;
55
 
56
template<int sh_type, bool dynamic, int size, bool big_endian>
57
class Output_data_reloc;
58
 
59
// A class to read the relocations for an object file, and then queue
60
// up a task to see if they require any GOT/PLT/COPY relocations in
61
// the symbol table.
62
 
63
class Read_relocs : public Task
64
{
65
 public:
66
  //   THIS_BLOCKER and NEXT_BLOCKER are passed along to a Scan_relocs
67
  // or Gc_process_relocs task, so that they run in a deterministic
68
  // order.
69
  Read_relocs(Symbol_table* symtab, Layout* layout, Relobj* object,
70
              Task_token* this_blocker, Task_token* next_blocker)
71
    : symtab_(symtab), layout_(layout), object_(object),
72
      this_blocker_(this_blocker), next_blocker_(next_blocker)
73
  { }
74
 
75
  // The standard Task methods.
76
 
77
  Task_token*
78
  is_runnable();
79
 
80
  void
81
  locks(Task_locker*);
82
 
83
  void
84
  run(Workqueue*);
85
 
86
  std::string
87
  get_name() const;
88
 
89
 private:
90
  Symbol_table* symtab_;
91
  Layout* layout_;
92
  Relobj* object_;
93
  Task_token* this_blocker_;
94
  Task_token* next_blocker_;
95
};
96
 
97
// Process the relocs to figure out which sections are garbage.
98
// Very similar to scan relocs.
99
 
100
class Gc_process_relocs : public Task
101
{
102
 public:
103
  // THIS_BLOCKER prevents this task from running until the previous
104
  // one is finished.  NEXT_BLOCKER prevents the next task from
105
  // running.
106
  Gc_process_relocs(Symbol_table* symtab, Layout* layout, Relobj* object,
107
                    Read_relocs_data* rd, Task_token* this_blocker,
108
                    Task_token* next_blocker)
109
    : symtab_(symtab), layout_(layout), object_(object), rd_(rd),
110
      this_blocker_(this_blocker), next_blocker_(next_blocker)
111
  { }
112
 
113
  ~Gc_process_relocs();
114
 
115
  // The standard Task methods.
116
 
117
  Task_token*
118
  is_runnable();
119
 
120
  void
121
  locks(Task_locker*);
122
 
123
  void
124
  run(Workqueue*);
125
 
126
  std::string
127
  get_name() const;
128
 
129
 private:
130
  Symbol_table* symtab_;
131
  Layout* layout_;
132
  Relobj* object_;
133
  Read_relocs_data* rd_;
134
  Task_token* this_blocker_;
135
  Task_token* next_blocker_;
136
};
137
 
138
// Scan the relocations for an object to see if they require any
139
// GOT/PLT/COPY relocations.
140
 
141
class Scan_relocs : public Task
142
{
143
 public:
144
  // THIS_BLOCKER prevents this task from running until the previous
145
  // one is finished.  NEXT_BLOCKER prevents the next task from
146
  // running.
147
  Scan_relocs(Symbol_table* symtab, Layout* layout, Relobj* object,
148
              Read_relocs_data* rd, Task_token* this_blocker,
149
              Task_token* next_blocker)
150
    : symtab_(symtab), layout_(layout), object_(object), rd_(rd),
151
      this_blocker_(this_blocker), next_blocker_(next_blocker)
152
  { }
153
 
154
  ~Scan_relocs();
155
 
156
  // The standard Task methods.
157
 
158
  Task_token*
159
  is_runnable();
160
 
161
  void
162
  locks(Task_locker*);
163
 
164
  void
165
  run(Workqueue*);
166
 
167
  std::string
168
  get_name() const;
169
 
170
 private:
171
  Symbol_table* symtab_;
172
  Layout* layout_;
173
  Relobj* object_;
174
  Read_relocs_data* rd_;
175
  Task_token* this_blocker_;
176
  Task_token* next_blocker_;
177
};
178
 
179
// A class to perform all the relocations for an object file.
180
 
181
class Relocate_task : public Task
182
{
183
 public:
184
  Relocate_task(const Symbol_table* symtab, const Layout* layout,
185
                Relobj* object, Output_file* of,
186
                Task_token* input_sections_blocker,
187
                Task_token* output_sections_blocker, Task_token* final_blocker)
188
    : symtab_(symtab), layout_(layout), object_(object), of_(of),
189
      input_sections_blocker_(input_sections_blocker),
190
      output_sections_blocker_(output_sections_blocker),
191
      final_blocker_(final_blocker)
192
  { }
193
 
194
  // The standard Task methods.
195
 
196
  Task_token*
197
  is_runnable();
198
 
199
  void
200
  locks(Task_locker*);
201
 
202
  void
203
  run(Workqueue*);
204
 
205
  std::string
206
  get_name() const;
207
 
208
 private:
209
  const Symbol_table* symtab_;
210
  const Layout* layout_;
211
  Relobj* object_;
212
  Output_file* of_;
213
  Task_token* input_sections_blocker_;
214
  Task_token* output_sections_blocker_;
215
  Task_token* final_blocker_;
216
};
217
 
218
// During a relocatable link, this class records how relocations
219
// should be handled for a single input reloc section.  An instance of
220
// this class is created while scanning relocs, and it is used while
221
// processing relocs.
222
 
223
class Relocatable_relocs
224
{
225
 public:
226
  // We use a vector of unsigned char to indicate how the input relocs
227
  // should be handled.  Each element is one of the following values.
228
  // We create this vector when we initially scan the relocations.
229
  enum Reloc_strategy
230
  {
231
    // Copy the input reloc.  Don't modify it other than updating the
232
    // r_offset field and the r_sym part of the r_info field.
233
    RELOC_COPY,
234
    // Copy the input reloc which is against an STT_SECTION symbol.
235
    // Update the r_offset and r_sym part of the r_info field.  Adjust
236
    // the addend by subtracting the value of the old local symbol and
237
    // adding the value of the new local symbol.  The addend is in the
238
    // SHT_RELA reloc and the contents of the data section do not need
239
    // to be changed.
240
    RELOC_ADJUST_FOR_SECTION_RELA,
241
    // Like RELOC_ADJUST_FOR_SECTION_RELA but the addend should not be
242
    // adjusted.
243
    RELOC_ADJUST_FOR_SECTION_0,
244
    // Like RELOC_ADJUST_FOR_SECTION_RELA but the contents of the
245
    // section need to be changed.  The number indicates the number of
246
    // bytes in the addend in the section contents.
247
    RELOC_ADJUST_FOR_SECTION_1,
248
    RELOC_ADJUST_FOR_SECTION_2,
249
    RELOC_ADJUST_FOR_SECTION_4,
250
    RELOC_ADJUST_FOR_SECTION_8,
251 163 khays
    // Like RELOC_ADJUST_FOR_SECTION_4 but for unaligned relocs.
252
    RELOC_ADJUST_FOR_SECTION_4_UNALIGNED,
253 27 khays
    // Discard the input reloc--process it completely when relocating
254
    // the data section contents.
255
    RELOC_DISCARD,
256
    // An input reloc which is not discarded, but which requires
257
    // target specific processing in order to update it.
258
    RELOC_SPECIAL
259
  };
260
 
261
  Relocatable_relocs()
262
    : reloc_strategies_(), output_reloc_count_(0), posd_(NULL)
263
  { }
264
 
265
  // Record the number of relocs.
266
  void
267
  set_reloc_count(size_t reloc_count)
268
  { this->reloc_strategies_.reserve(reloc_count); }
269
 
270
  // Record what to do for the next reloc.
271
  void
272
  set_next_reloc_strategy(Reloc_strategy strategy)
273
  {
274
    this->reloc_strategies_.push_back(static_cast<unsigned char>(strategy));
275
    if (strategy != RELOC_DISCARD)
276
      ++this->output_reloc_count_;
277
  }
278
 
279
  // Record the Output_data associated with this reloc section.
280
  void
281
  set_output_data(Output_data* posd)
282
  {
283
    gold_assert(this->posd_ == NULL);
284
    this->posd_ = posd;
285
  }
286
 
287
  // Return the Output_data associated with this reloc section.
288
  Output_data*
289
  output_data() const
290
  { return this->posd_; }
291
 
292
  // Return what to do for reloc I.
293
  Reloc_strategy
294
  strategy(unsigned int i) const
295
  {
296
    gold_assert(i < this->reloc_strategies_.size());
297
    return static_cast<Reloc_strategy>(this->reloc_strategies_[i]);
298
  }
299
 
300
  // Return the number of relocations to create in the output file.
301
  size_t
302
  output_reloc_count() const
303
  { return this->output_reloc_count_; }
304
 
305
 private:
306
  typedef std::vector<unsigned char> Reloc_strategies;
307
 
308
  // The strategies for the input reloc.  There is one entry in this
309
  // vector for each relocation in the input section.
310
  Reloc_strategies reloc_strategies_;
311
  // The number of relocations to be created in the output file.
312
  size_t output_reloc_count_;
313
  // The output data structure associated with this relocation.
314
  Output_data* posd_;
315
};
316
 
317
// Standard relocation routines which are used on many targets.  Here
318
// SIZE and BIG_ENDIAN refer to the target, not the relocation type.
319
 
320
template<int size, bool big_endian>
321
class Relocate_functions
322
{
323
private:
324
  // Do a simple relocation with the addend in the section contents.
325
  // VALSIZE is the size of the value.
326
  template<int valsize>
327
  static inline void
328
  rel(unsigned char* view,
329
      typename elfcpp::Swap<valsize, big_endian>::Valtype value)
330
  {
331
    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
332
    Valtype* wv = reinterpret_cast<Valtype*>(view);
333
    Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
334
    elfcpp::Swap<valsize, big_endian>::writeval(wv, x + value);
335
  }
336
 
337 163 khays
  // Like the above but for relocs at unaligned addresses.
338
  template<int valsize>
339
  static inline void
340
  rel_unaligned(unsigned char* view,
341
                typename elfcpp::Swap<valsize, big_endian>::Valtype value)
342
  {
343
    typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype
344
        Valtype;
345
    Valtype x = elfcpp::Swap_unaligned<valsize, big_endian>::readval(view);
346
    elfcpp::Swap_unaligned<valsize, big_endian>::writeval(view, x + value);
347
  }
348
 
349 27 khays
  // Do a simple relocation using a Symbol_value with the addend in
350
  // the section contents.  VALSIZE is the size of the value to
351
  // relocate.
352
  template<int valsize>
353
  static inline void
354
  rel(unsigned char* view,
355
      const Sized_relobj_file<size, big_endian>* object,
356
      const Symbol_value<size>* psymval)
357
  {
358
    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
359
    Valtype* wv = reinterpret_cast<Valtype*>(view);
360
    Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
361
    x = psymval->value(object, x);
362
    elfcpp::Swap<valsize, big_endian>::writeval(wv, x);
363
  }
364
 
365 163 khays
  // Like the above but for relocs at unaligned addresses.
366
  template<int valsize>
367
  static inline void
368
  rel_unaligned(unsigned char* view,
369
                const Sized_relobj_file<size, big_endian>* object,
370
                const Symbol_value<size>* psymval)
371
  {
372
    typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype
373
        Valtype;
374
    Valtype x = elfcpp::Swap_unaligned<valsize, big_endian>::readval(view);
375
    x = psymval->value(object, x);
376
    elfcpp::Swap_unaligned<valsize, big_endian>::writeval(view, x);
377
  }
378
 
379 27 khays
  // Do a simple relocation with the addend in the relocation.
380
  // VALSIZE is the size of the value.
381
  template<int valsize>
382
  static inline void
383
  rela(unsigned char* view,
384
       typename elfcpp::Swap<valsize, big_endian>::Valtype value,
385
       typename elfcpp::Swap<valsize, big_endian>::Valtype addend)
386
  {
387
    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
388
    Valtype* wv = reinterpret_cast<Valtype*>(view);
389
    elfcpp::Swap<valsize, big_endian>::writeval(wv, value + addend);
390
  }
391
 
392
  // Do a simple relocation using a symbol value with the addend in
393
  // the relocation.  VALSIZE is the size of the value.
394
  template<int valsize>
395
  static inline void
396
  rela(unsigned char* view,
397
       const Sized_relobj_file<size, big_endian>* object,
398
       const Symbol_value<size>* psymval,
399
       typename elfcpp::Swap<valsize, big_endian>::Valtype addend)
400
  {
401
    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
402
    Valtype* wv = reinterpret_cast<Valtype*>(view);
403
    Valtype x = psymval->value(object, addend);
404
    elfcpp::Swap<valsize, big_endian>::writeval(wv, x);
405
  }
406
 
407
  // Do a simple PC relative relocation with the addend in the section
408
  // contents.  VALSIZE is the size of the value.
409
  template<int valsize>
410
  static inline void
411
  pcrel(unsigned char* view,
412
        typename elfcpp::Swap<valsize, big_endian>::Valtype value,
413
        typename elfcpp::Elf_types<size>::Elf_Addr address)
414
  {
415
    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
416
    Valtype* wv = reinterpret_cast<Valtype*>(view);
417
    Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
418
    elfcpp::Swap<valsize, big_endian>::writeval(wv, x + value - address);
419
  }
420
 
421 163 khays
  // Like the above but for relocs at unaligned addresses.
422
  template<int valsize>
423
  static inline void
424
  pcrel_unaligned(unsigned char* view,
425
                  typename elfcpp::Swap<valsize, big_endian>::Valtype value,
426
                  typename elfcpp::Elf_types<size>::Elf_Addr address)
427
  {
428
    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
429
    Valtype x = elfcpp::Swap_unaligned<valsize, big_endian>::readval(view);
430
    elfcpp::Swap_unaligned<valsize, big_endian>::writeval(view,
431
                                                          x + value - address);
432
  }
433
 
434 27 khays
  // Do a simple PC relative relocation with a Symbol_value with the
435
  // addend in the section contents.  VALSIZE is the size of the
436
  // value.
437
  template<int valsize>
438
  static inline void
439
  pcrel(unsigned char* view,
440
        const Sized_relobj_file<size, big_endian>* object,
441
        const Symbol_value<size>* psymval,
442
        typename elfcpp::Elf_types<size>::Elf_Addr address)
443
  {
444
    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
445
    Valtype* wv = reinterpret_cast<Valtype*>(view);
446
    Valtype x = elfcpp::Swap<valsize, big_endian>::readval(wv);
447
    x = psymval->value(object, x);
448
    elfcpp::Swap<valsize, big_endian>::writeval(wv, x - address);
449
  }
450
 
451
  // Do a simple PC relative relocation with the addend in the
452
  // relocation.  VALSIZE is the size of the value.
453
  template<int valsize>
454
  static inline void
455
  pcrela(unsigned char* view,
456
         typename elfcpp::Swap<valsize, big_endian>::Valtype value,
457
         typename elfcpp::Swap<valsize, big_endian>::Valtype addend,
458
         typename elfcpp::Elf_types<size>::Elf_Addr address)
459
  {
460
    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
461
    Valtype* wv = reinterpret_cast<Valtype*>(view);
462
    elfcpp::Swap<valsize, big_endian>::writeval(wv, value + addend - address);
463
  }
464
 
465
  // Do a simple PC relative relocation with a Symbol_value with the
466
  // addend in the relocation.  VALSIZE is the size of the value.
467
  template<int valsize>
468
  static inline void
469
  pcrela(unsigned char* view,
470
         const Sized_relobj_file<size, big_endian>* object,
471
         const Symbol_value<size>* psymval,
472
         typename elfcpp::Swap<valsize, big_endian>::Valtype addend,
473
         typename elfcpp::Elf_types<size>::Elf_Addr address)
474
  {
475
    typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype;
476
    Valtype* wv = reinterpret_cast<Valtype*>(view);
477
    Valtype x = psymval->value(object, addend);
478
    elfcpp::Swap<valsize, big_endian>::writeval(wv, x - address);
479
  }
480
 
481
  typedef Relocate_functions<size, big_endian> This;
482
 
483
public:
484
  // Do a simple 8-bit REL relocation with the addend in the section
485
  // contents.
486
  static inline void
487
  rel8(unsigned char* view, unsigned char value)
488
  { This::template rel<8>(view, value); }
489
 
490
  static inline void
491
  rel8(unsigned char* view,
492
       const Sized_relobj_file<size, big_endian>* object,
493
       const Symbol_value<size>* psymval)
494
  { This::template rel<8>(view, object, psymval); }
495
 
496
  // Do an 8-bit RELA relocation with the addend in the relocation.
497
  static inline void
498
  rela8(unsigned char* view, unsigned char value, unsigned char addend)
499
  { This::template rela<8>(view, value, addend); }
500
 
501
  static inline void
502
  rela8(unsigned char* view,
503
        const Sized_relobj_file<size, big_endian>* object,
504
        const Symbol_value<size>* psymval,
505
        unsigned char addend)
506
  { This::template rela<8>(view, object, psymval, addend); }
507
 
508
  // Do a simple 8-bit PC relative relocation with the addend in the
509
  // section contents.
510
  static inline void
511
  pcrel8(unsigned char* view, unsigned char value,
512
         typename elfcpp::Elf_types<size>::Elf_Addr address)
513
  { This::template pcrel<8>(view, value, address); }
514
 
515
  static inline void
516
  pcrel8(unsigned char* view,
517
         const Sized_relobj_file<size, big_endian>* object,
518
         const Symbol_value<size>* psymval,
519
         typename elfcpp::Elf_types<size>::Elf_Addr address)
520
  { This::template pcrel<8>(view, object, psymval, address); }
521
 
522
  // Do a simple 8-bit PC relative RELA relocation with the addend in
523
  // the reloc.
524
  static inline void
525
  pcrela8(unsigned char* view, unsigned char value, unsigned char addend,
526
          typename elfcpp::Elf_types<size>::Elf_Addr address)
527
  { This::template pcrela<8>(view, value, addend, address); }
528
 
529
  static inline void
530
  pcrela8(unsigned char* view,
531
          const Sized_relobj_file<size, big_endian>* object,
532
          const Symbol_value<size>* psymval,
533
          unsigned char addend,
534
          typename elfcpp::Elf_types<size>::Elf_Addr address)
535
  { This::template pcrela<8>(view, object, psymval, addend, address); }
536
 
537
  // Do a simple 16-bit REL relocation with the addend in the section
538
  // contents.
539
  static inline void
540
  rel16(unsigned char* view, elfcpp::Elf_Half value)
541
  { This::template rel<16>(view, value); }
542
 
543
  static inline void
544
  rel16(unsigned char* view,
545
        const Sized_relobj_file<size, big_endian>* object,
546
        const Symbol_value<size>* psymval)
547
  { This::template rel<16>(view, object, psymval); }
548
 
549
  // Do an 16-bit RELA relocation with the addend in the relocation.
550
  static inline void
551
  rela16(unsigned char* view, elfcpp::Elf_Half value, elfcpp::Elf_Half addend)
552
  { This::template rela<16>(view, value, addend); }
553
 
554
  static inline void
555
  rela16(unsigned char* view,
556
         const Sized_relobj_file<size, big_endian>* object,
557
         const Symbol_value<size>* psymval,
558
         elfcpp::Elf_Half addend)
559
  { This::template rela<16>(view, object, psymval, addend); }
560
 
561
  // Do a simple 16-bit PC relative REL relocation with the addend in
562
  // the section contents.
563
  static inline void
564
  pcrel16(unsigned char* view, elfcpp::Elf_Half value,
565
          typename elfcpp::Elf_types<size>::Elf_Addr address)
566
  { This::template pcrel<16>(view, value, address); }
567
 
568
  static inline void
569
  pcrel16(unsigned char* view,
570
          const Sized_relobj_file<size, big_endian>* object,
571
          const Symbol_value<size>* psymval,
572
          typename elfcpp::Elf_types<size>::Elf_Addr address)
573
  { This::template pcrel<16>(view, object, psymval, address); }
574
 
575
  // Do a simple 16-bit PC relative RELA relocation with the addend in
576
  // the reloc.
577
  static inline void
578
  pcrela16(unsigned char* view, elfcpp::Elf_Half value,
579
           elfcpp::Elf_Half addend,
580
           typename elfcpp::Elf_types<size>::Elf_Addr address)
581
  { This::template pcrela<16>(view, value, addend, address); }
582
 
583
  static inline void
584
  pcrela16(unsigned char* view,
585
           const Sized_relobj_file<size, big_endian>* object,
586
           const Symbol_value<size>* psymval,
587
           elfcpp::Elf_Half addend,
588
           typename elfcpp::Elf_types<size>::Elf_Addr address)
589
  { This::template pcrela<16>(view, object, psymval, addend, address); }
590
 
591
  // Do a simple 32-bit REL relocation with the addend in the section
592
  // contents.
593
  static inline void
594
  rel32(unsigned char* view, elfcpp::Elf_Word value)
595
  { This::template rel<32>(view, value); }
596
 
597 163 khays
  // Like above but for relocs at unaligned addresses.
598 27 khays
  static inline void
599 163 khays
  rel32_unaligned(unsigned char* view, elfcpp::Elf_Word value)
600
  { This::template rel_unaligned<32>(view, value); }
601
 
602
  static inline void
603 27 khays
  rel32(unsigned char* view,
604
        const Sized_relobj_file<size, big_endian>* object,
605
        const Symbol_value<size>* psymval)
606
  { This::template rel<32>(view, object, psymval); }
607
 
608 163 khays
  // Like above but for relocs at unaligned addresses.
609
  static inline void
610
  rel32_unaligned(unsigned char* view,
611
                  const Sized_relobj_file<size, big_endian>* object,
612
                  const Symbol_value<size>* psymval)
613
  { This::template rel_unaligned<32>(view, object, psymval); }
614
 
615 27 khays
  // Do an 32-bit RELA relocation with the addend in the relocation.
616
  static inline void
617
  rela32(unsigned char* view, elfcpp::Elf_Word value, elfcpp::Elf_Word addend)
618
  { This::template rela<32>(view, value, addend); }
619
 
620
  static inline void
621
  rela32(unsigned char* view,
622
         const Sized_relobj_file<size, big_endian>* object,
623
         const Symbol_value<size>* psymval,
624
         elfcpp::Elf_Word addend)
625
  { This::template rela<32>(view, object, psymval, addend); }
626
 
627
  // Do a simple 32-bit PC relative REL relocation with the addend in
628
  // the section contents.
629
  static inline void
630
  pcrel32(unsigned char* view, elfcpp::Elf_Word value,
631
          typename elfcpp::Elf_types<size>::Elf_Addr address)
632
  { This::template pcrel<32>(view, value, address); }
633
 
634 163 khays
  // Unaligned version of the above.
635 27 khays
  static inline void
636 163 khays
  pcrel32_unaligned(unsigned char* view, elfcpp::Elf_Word value,
637
                    typename elfcpp::Elf_types<size>::Elf_Addr address)
638
  { This::template pcrel_unaligned<32>(view, value, address); }
639
 
640
  static inline void
641 27 khays
  pcrel32(unsigned char* view,
642
          const Sized_relobj_file<size, big_endian>* object,
643
          const Symbol_value<size>* psymval,
644
          typename elfcpp::Elf_types<size>::Elf_Addr address)
645
  { This::template pcrel<32>(view, object, psymval, address); }
646
 
647
  // Do a simple 32-bit PC relative RELA relocation with the addend in
648
  // the relocation.
649
  static inline void
650
  pcrela32(unsigned char* view, elfcpp::Elf_Word value,
651
           elfcpp::Elf_Word addend,
652
           typename elfcpp::Elf_types<size>::Elf_Addr address)
653
  { This::template pcrela<32>(view, value, addend, address); }
654
 
655
  static inline void
656
  pcrela32(unsigned char* view,
657
           const Sized_relobj_file<size, big_endian>* object,
658
           const Symbol_value<size>* psymval,
659
           elfcpp::Elf_Word addend,
660
           typename elfcpp::Elf_types<size>::Elf_Addr address)
661
  { This::template pcrela<32>(view, object, psymval, addend, address); }
662
 
663
  // Do a simple 64-bit REL relocation with the addend in the section
664
  // contents.
665
  static inline void
666
  rel64(unsigned char* view, elfcpp::Elf_Xword value)
667
  { This::template rel<64>(view, value); }
668
 
669
  static inline void
670
  rel64(unsigned char* view,
671
        const Sized_relobj_file<size, big_endian>* object,
672
        const Symbol_value<size>* psymval)
673
  { This::template rel<64>(view, object, psymval); }
674
 
675
  // Do a 64-bit RELA relocation with the addend in the relocation.
676
  static inline void
677
  rela64(unsigned char* view, elfcpp::Elf_Xword value,
678
         elfcpp::Elf_Xword addend)
679
  { This::template rela<64>(view, value, addend); }
680
 
681
  static inline void
682
  rela64(unsigned char* view,
683
         const Sized_relobj_file<size, big_endian>* object,
684
         const Symbol_value<size>* psymval,
685
         elfcpp::Elf_Xword addend)
686
  { This::template rela<64>(view, object, psymval, addend); }
687
 
688
  // Do a simple 64-bit PC relative REL relocation with the addend in
689
  // the section contents.
690
  static inline void
691
  pcrel64(unsigned char* view, elfcpp::Elf_Xword value,
692
          typename elfcpp::Elf_types<size>::Elf_Addr address)
693
  { This::template pcrel<64>(view, value, address); }
694
 
695
  static inline void
696
  pcrel64(unsigned char* view,
697
          const Sized_relobj_file<size, big_endian>* object,
698
          const Symbol_value<size>* psymval,
699
          typename elfcpp::Elf_types<size>::Elf_Addr address)
700
  { This::template pcrel<64>(view, object, psymval, address); }
701
 
702
  // Do a simple 64-bit PC relative RELA relocation with the addend in
703
  // the relocation.
704
  static inline void
705
  pcrela64(unsigned char* view, elfcpp::Elf_Xword value,
706
           elfcpp::Elf_Xword addend,
707
           typename elfcpp::Elf_types<size>::Elf_Addr address)
708
  { This::template pcrela<64>(view, value, addend, address); }
709
 
710
  static inline void
711
  pcrela64(unsigned char* view,
712
           const Sized_relobj_file<size, big_endian>* object,
713
           const Symbol_value<size>* psymval,
714
           elfcpp::Elf_Xword addend,
715
           typename elfcpp::Elf_types<size>::Elf_Addr address)
716
  { This::template pcrela<64>(view, object, psymval, addend, address); }
717
};
718
 
719 166 khays
// Integer manipulation functions used by various targets when
720
// performing relocations.
721
 
722
template<int bits>
723
class Bits
724
{
725
 public:
726
  // Sign extend an n-bit unsigned integer stored in a uint32_t into
727
  // an int32_t.  BITS must be between 1 and 32.
728
  static inline int32_t
729
  sign_extend32(uint32_t val)
730
  {
731
    gold_assert(bits > 0 && bits <= 32);
732
    if (bits == 32)
733
      return static_cast<int32_t>(val);
734
    uint32_t mask = (~static_cast<uint32_t>(0)) >> (32 - bits);
735
    val &= mask;
736
    uint32_t top_bit = 1U << (bits - 1);
737
    int32_t as_signed = static_cast<int32_t>(val);
738
    if ((val & top_bit) != 0)
739
      as_signed -= static_cast<int32_t>(top_bit * 2);
740
    return as_signed;
741
  }
742
 
743
  // Return true if VAL (stored in a uint32_t) has overflowed a signed
744
  // value with BITS bits.
745
  static inline bool
746
  has_overflow32(uint32_t val)
747
  {
748
    gold_assert(bits > 0 && bits <= 32);
749
    if (bits == 32)
750
      return false;
751
    int32_t max = (1 << (bits - 1)) - 1;
752
    int32_t min = -(1 << (bits - 1));
753
    int32_t as_signed = static_cast<int32_t>(val);
754
    return as_signed > max || as_signed < min;
755
  }
756
 
757
  // Return true if VAL (stored in a uint32_t) has overflowed both a
758
  // signed and an unsigned value.  E.g.,
759
  // Bits<8>::has_signed_unsigned_overflow32 would check -128 <= VAL <
760
  // 255.
761
  static inline bool
762
  has_signed_unsigned_overflow32(uint32_t val)
763
  {
764
    gold_assert(bits > 0 && bits <= 32);
765
    if (bits == 32)
766
      return false;
767
    int32_t max = static_cast<int32_t>((1U << bits) - 1);
768
    int32_t min = -(1 << (bits - 1));
769
    int32_t as_signed = static_cast<int32_t>(val);
770
    return as_signed > max || as_signed < min;
771
  }
772
 
773
  // Select bits from A and B using bits in MASK.  For each n in
774
  // [0..31], the n-th bit in the result is chosen from the n-th bits
775
  // of A and B.  A zero selects A and a one selects B.
776
  static inline uint32_t
777
  bit_select32(uint32_t a, uint32_t b, uint32_t mask)
778
  { return (a & ~mask) | (b & mask); }
779
 
780
  // Sign extend an n-bit unsigned integer stored in a uint64_t into
781
  // an int64_t.  BITS must be between 1 and 64.
782
  static inline int64_t
783
  sign_extend(uint64_t val)
784
  {
785
    gold_assert(bits > 0 && bits <= 64);
786
    if (bits == 64)
787
      return static_cast<int64_t>(val);
788
    uint64_t mask = (~static_cast<uint64_t>(0)) >> (64 - bits);
789
    val &= mask;
790
    uint64_t top_bit = static_cast<uint64_t>(1) << (bits - 1);
791
    int64_t as_signed = static_cast<int64_t>(val);
792
    if ((val & top_bit) != 0)
793
      as_signed -= static_cast<int64_t>(top_bit * 2);
794
    return as_signed;
795
  }
796
 
797
  // Return true if VAL (stored in a uint64_t) has overflowed a signed
798
  // value with BITS bits.
799
  static inline bool
800
  has_overflow(uint64_t val)
801
  {
802
    gold_assert(bits > 0 && bits <= 64);
803
    if (bits == 64)
804
      return false;
805
    int64_t max = (static_cast<int64_t>(1) << (bits - 1)) - 1;
806
    int64_t min = -(static_cast<int64_t>(1) << (bits - 1));
807
    int64_t as_signed = static_cast<int64_t>(val);
808
    return as_signed > max || as_signed < min;
809
  }
810
 
811
  // Return true if VAL (stored in a uint64_t) has overflowed both a
812
  // signed and an unsigned value.  E.g.,
813
  // Bits<8>::has_signed_unsigned_overflow would check -128 <= VAL <
814
  // 255.
815
  static inline bool
816
  has_signed_unsigned_overflow64(uint64_t val)
817
  {
818
    gold_assert(bits > 0 && bits <= 64);
819
    if (bits == 64)
820
      return false;
821
    int64_t max = static_cast<int64_t>((static_cast<uint64_t>(1) << bits) - 1);
822
    int64_t min = -(static_cast<int64_t>(1) << (bits - 1));
823
    int64_t as_signed = static_cast<int64_t>(val);
824
    return as_signed > max || as_signed < min;
825
  }
826
 
827
  // Select bits from A and B using bits in MASK.  For each n in
828
  // [0..31], the n-th bit in the result is chosen from the n-th bits
829
  // of A and B.  A zero selects A and a one selects B.
830
  static inline uint64_t
831
  bit_select64(uint64_t a, uint64_t b, uint64_t mask)
832
  { return (a & ~mask) | (b & mask); }
833
};
834
 
835 27 khays
// Track relocations while reading a section.  This lets you ask for
836
// the relocation at a certain offset, and see how relocs occur
837
// between points of interest.
838
 
839
template<int size, bool big_endian>
840
class Track_relocs
841
{
842
 public:
843
  Track_relocs()
844
    : prelocs_(NULL), len_(0), pos_(0), reloc_size_(0)
845
  { }
846
 
847
  // Initialize the Track_relocs object.  OBJECT is the object holding
848
  // the reloc section, RELOC_SHNDX is the section index of the reloc
849
  // section, and RELOC_TYPE is the type of the reloc section
850
  // (elfcpp::SHT_REL or elfcpp::SHT_RELA).  This returns false if
851
  // something went wrong.
852
  bool
853
  initialize(Object* object, unsigned int reloc_shndx,
854
             unsigned int reloc_type);
855
 
856
  // Return the offset in the data section to which the next reloc
857
  // applies.  This returns -1 if there is no next reloc.
858
  off_t
859
  next_offset() const;
860
 
861
  // Return the symbol index of the next reloc.  This returns -1U if
862
  // there is no next reloc.
863
  unsigned int
864
  next_symndx() const;
865
 
866
  // Return the addend of the next reloc.  This returns 0 if there is
867
  // no next reloc.
868
  uint64_t
869
  next_addend() const;
870
 
871
  // Advance to OFFSET within the data section, and return the number
872
  // of relocs which would be skipped.
873
  int
874
  advance(off_t offset);
875
 
876
 private:
877
  // The contents of the input object's reloc section.
878
  const unsigned char* prelocs_;
879
  // The length of the reloc section.
880
  section_size_type len_;
881
  // Our current position in the reloc section.
882
  section_size_type pos_;
883
  // The size of the relocs in the section.
884
  int reloc_size_;
885
};
886
 
887
} // End namespace gold.
888
 
889
#endif // !defined(GOLD_RELOC_H)

powered by: WebSVN 2.1.0

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