1 // reloc.h -- relocate input files for gold -*- C++ -*- 2 3 // Copyright (C) 2006-2016 Free Software Foundation, Inc. 4 // Written by Ian Lance Taylor <iant@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_RELOC_H 24 #define GOLD_RELOC_H 25 26 #include <vector> 27 #ifdef HAVE_BYTESWAP_H 28 #include <byteswap.h> 29 #endif 30 31 #include "elfcpp.h" 32 #include "workqueue.h" 33 34 namespace gold 35 { 36 37 class General_options; 38 class Object; 39 class Relobj; 40 struct Read_relocs_data; 41 class Symbol; 42 class Layout; 43 class Output_data; 44 class Output_section; 45 46 template<int size> 47 class Sized_symbol; 48 49 template<int size, bool big_endian> 50 class Sized_relobj_file; 51 52 template<int size> 53 class Symbol_value; 54 55 template<int sh_type, bool dynamic, int size, bool big_endian> 56 class Output_data_reloc; 57 58 // A class to read the relocations for an object file, and then queue 59 // up a task to see if they require any GOT/PLT/COPY relocations in 60 // the symbol table. 61 62 class Read_relocs : public Task 63 { 64 public: 65 // THIS_BLOCKER and NEXT_BLOCKER are passed along to a Scan_relocs 66 // or Gc_process_relocs task, so that they run in a deterministic 67 // order. Read_relocs(Symbol_table * symtab,Layout * layout,Relobj * object,Task_token * this_blocker,Task_token * next_blocker)68 Read_relocs(Symbol_table* symtab, Layout* layout, Relobj* object, 69 Task_token* this_blocker, Task_token* next_blocker) 70 : symtab_(symtab), layout_(layout), object_(object), 71 this_blocker_(this_blocker), next_blocker_(next_blocker) 72 { } 73 74 // The standard Task methods. 75 76 Task_token* 77 is_runnable(); 78 79 void 80 locks(Task_locker*); 81 82 void 83 run(Workqueue*); 84 85 std::string 86 get_name() const; 87 88 private: 89 Symbol_table* symtab_; 90 Layout* layout_; 91 Relobj* object_; 92 Task_token* this_blocker_; 93 Task_token* next_blocker_; 94 }; 95 96 // Process the relocs to figure out which sections are garbage. 97 // Very similar to scan relocs. 98 99 class Gc_process_relocs : public Task 100 { 101 public: 102 // THIS_BLOCKER prevents this task from running until the previous 103 // one is finished. NEXT_BLOCKER prevents the next task from 104 // running. Gc_process_relocs(Symbol_table * symtab,Layout * layout,Relobj * object,Read_relocs_data * rd,Task_token * this_blocker,Task_token * next_blocker)105 Gc_process_relocs(Symbol_table* symtab, Layout* layout, Relobj* object, 106 Read_relocs_data* rd, Task_token* this_blocker, 107 Task_token* next_blocker) 108 : symtab_(symtab), layout_(layout), object_(object), rd_(rd), 109 this_blocker_(this_blocker), next_blocker_(next_blocker) 110 { } 111 112 ~Gc_process_relocs(); 113 114 // The standard Task methods. 115 116 Task_token* 117 is_runnable(); 118 119 void 120 locks(Task_locker*); 121 122 void 123 run(Workqueue*); 124 125 std::string 126 get_name() const; 127 128 private: 129 Symbol_table* symtab_; 130 Layout* layout_; 131 Relobj* object_; 132 Read_relocs_data* rd_; 133 Task_token* this_blocker_; 134 Task_token* next_blocker_; 135 }; 136 137 // Scan the relocations for an object to see if they require any 138 // GOT/PLT/COPY relocations. 139 140 class Scan_relocs : public Task 141 { 142 public: 143 // THIS_BLOCKER prevents this task from running until the previous 144 // one is finished. NEXT_BLOCKER prevents the next task from 145 // running. Scan_relocs(Symbol_table * symtab,Layout * layout,Relobj * object,Read_relocs_data * rd,Task_token * this_blocker,Task_token * next_blocker)146 Scan_relocs(Symbol_table* symtab, Layout* layout, Relobj* object, 147 Read_relocs_data* rd, Task_token* this_blocker, 148 Task_token* next_blocker) 149 : symtab_(symtab), layout_(layout), object_(object), rd_(rd), 150 this_blocker_(this_blocker), next_blocker_(next_blocker) 151 { } 152 153 ~Scan_relocs(); 154 155 // The standard Task methods. 156 157 Task_token* 158 is_runnable(); 159 160 void 161 locks(Task_locker*); 162 163 void 164 run(Workqueue*); 165 166 std::string 167 get_name() const; 168 169 private: 170 Symbol_table* symtab_; 171 Layout* layout_; 172 Relobj* object_; 173 Read_relocs_data* rd_; 174 Task_token* this_blocker_; 175 Task_token* next_blocker_; 176 }; 177 178 // A class to perform all the relocations for an object file. 179 180 class Relocate_task : public Task 181 { 182 public: Relocate_task(const Symbol_table * symtab,const Layout * layout,Relobj * object,Output_file * of,Task_token * input_sections_blocker,Task_token * output_sections_blocker,Task_token * final_blocker)183 Relocate_task(const Symbol_table* symtab, const Layout* layout, 184 Relobj* object, Output_file* of, 185 Task_token* input_sections_blocker, 186 Task_token* output_sections_blocker, Task_token* final_blocker) 187 : symtab_(symtab), layout_(layout), object_(object), of_(of), 188 input_sections_blocker_(input_sections_blocker), 189 output_sections_blocker_(output_sections_blocker), 190 final_blocker_(final_blocker) 191 { } 192 193 // The standard Task methods. 194 195 Task_token* 196 is_runnable(); 197 198 void 199 locks(Task_locker*); 200 201 void 202 run(Workqueue*); 203 204 std::string 205 get_name() const; 206 207 private: 208 const Symbol_table* symtab_; 209 const Layout* layout_; 210 Relobj* object_; 211 Output_file* of_; 212 Task_token* input_sections_blocker_; 213 Task_token* output_sections_blocker_; 214 Task_token* final_blocker_; 215 }; 216 217 // During a relocatable link, this class records how relocations 218 // should be handled for a single input reloc section. An instance of 219 // this class is created while scanning relocs, and it is used while 220 // processing relocs. 221 222 class Relocatable_relocs 223 { 224 public: 225 // We use a vector of unsigned char to indicate how the input relocs 226 // should be handled. Each element is one of the following values. 227 // We create this vector when we initially scan the relocations. 228 enum Reloc_strategy 229 { 230 // Copy the input reloc. Don't modify it other than updating the 231 // r_offset field and the r_sym part of the r_info field. 232 RELOC_COPY, 233 // Copy the input reloc which is against an STT_SECTION symbol. 234 // Update the r_offset and r_sym part of the r_info field. Adjust 235 // the addend by subtracting the value of the old local symbol and 236 // adding the value of the new local symbol. The addend is in the 237 // SHT_RELA reloc and the contents of the data section do not need 238 // to be changed. 239 RELOC_ADJUST_FOR_SECTION_RELA, 240 // Like RELOC_ADJUST_FOR_SECTION_RELA but the addend should not be 241 // adjusted. 242 RELOC_ADJUST_FOR_SECTION_0, 243 // Like RELOC_ADJUST_FOR_SECTION_RELA but the contents of the 244 // section need to be changed. The number indicates the number of 245 // bytes in the addend in the section contents. 246 RELOC_ADJUST_FOR_SECTION_1, 247 RELOC_ADJUST_FOR_SECTION_2, 248 RELOC_ADJUST_FOR_SECTION_4, 249 RELOC_ADJUST_FOR_SECTION_8, 250 // Like RELOC_ADJUST_FOR_SECTION_4 but for unaligned relocs. 251 RELOC_ADJUST_FOR_SECTION_4_UNALIGNED, 252 // Discard the input reloc--process it completely when relocating 253 // the data section contents. 254 RELOC_DISCARD, 255 // An input reloc which is not discarded, but which requires 256 // target specific processing in order to update it. 257 RELOC_SPECIAL 258 }; 259 Relocatable_relocs()260 Relocatable_relocs() 261 : reloc_strategies_(), output_reloc_count_(0), posd_(NULL) 262 { } 263 264 // Record the number of relocs. 265 void set_reloc_count(size_t reloc_count)266 set_reloc_count(size_t reloc_count) 267 { this->reloc_strategies_.reserve(reloc_count); } 268 269 // Record what to do for the next reloc. 270 void set_next_reloc_strategy(Reloc_strategy strategy)271 set_next_reloc_strategy(Reloc_strategy strategy) 272 { 273 this->reloc_strategies_.push_back(static_cast<unsigned char>(strategy)); 274 if (strategy != RELOC_DISCARD) 275 ++this->output_reloc_count_; 276 } 277 278 // Record the Output_data associated with this reloc section. 279 void set_output_data(Output_data * posd)280 set_output_data(Output_data* posd) 281 { 282 gold_assert(this->posd_ == NULL); 283 this->posd_ = posd; 284 } 285 286 // Return the Output_data associated with this reloc section. 287 Output_data* output_data()288 output_data() const 289 { return this->posd_; } 290 291 // Return what to do for reloc I. 292 Reloc_strategy strategy(unsigned int i)293 strategy(unsigned int i) const 294 { 295 gold_assert(i < this->reloc_strategies_.size()); 296 return static_cast<Reloc_strategy>(this->reloc_strategies_[i]); 297 } 298 299 // Set the strategy for reloc I. 300 void set_strategy(unsigned int i,Reloc_strategy strategy)301 set_strategy(unsigned int i, Reloc_strategy strategy) 302 { 303 gold_assert(i < this->reloc_strategies_.size()); 304 this->reloc_strategies_[i] = strategy; 305 } 306 307 // Return the number of relocations to create in the output file. 308 size_t output_reloc_count()309 output_reloc_count() const 310 { return this->output_reloc_count_; } 311 312 private: 313 typedef std::vector<unsigned char> Reloc_strategies; 314 315 // The strategies for the input reloc. There is one entry in this 316 // vector for each relocation in the input section. 317 Reloc_strategies reloc_strategies_; 318 // The number of relocations to be created in the output file. 319 size_t output_reloc_count_; 320 // The output data structure associated with this relocation. 321 Output_data* posd_; 322 }; 323 324 template<int valsize> 325 class Bits; 326 327 // Standard relocation routines which are used on many targets. Here 328 // SIZE and BIG_ENDIAN refer to the target, not the relocation type. 329 330 template<int size, bool big_endian> 331 class Relocate_functions 332 { 333 public: 334 typedef typename elfcpp::Elf_types<size>::Elf_Addr Address; 335 typedef typename elfcpp::Elf_types<size>::Elf_Swxword Addendtype; 336 337 enum Overflow_check 338 { 339 // No overflow checking. 340 CHECK_NONE, 341 // Check for overflow of a signed value. 342 CHECK_SIGNED, 343 // Check for overflow of an unsigned value. 344 CHECK_UNSIGNED, 345 // Check for overflow of a signed or unsigned value. 346 // (i.e., no error if either signed or unsigned fits.) 347 CHECK_SIGNED_OR_UNSIGNED 348 }; 349 350 enum Reloc_status 351 { 352 RELOC_OK, 353 RELOC_OVERFLOW 354 }; 355 356 private: 357 // Check for overflow. 358 template<int valsize> 359 static inline Reloc_status check_overflow(Address value,Overflow_check check)360 check_overflow(Address value, Overflow_check check) 361 { 362 switch (check) 363 { 364 case CHECK_SIGNED: 365 if (size == 32) 366 return (Bits<valsize>::has_overflow32(value) 367 ? RELOC_OVERFLOW 368 : RELOC_OK); 369 else 370 return (Bits<valsize>::has_overflow(value) 371 ? RELOC_OVERFLOW 372 : RELOC_OK); 373 case CHECK_UNSIGNED: 374 if (size == 32) 375 return (Bits<valsize>::has_unsigned_overflow32(value) 376 ? RELOC_OVERFLOW 377 : RELOC_OK); 378 else 379 return (Bits<valsize>::has_unsigned_overflow(value) 380 ? RELOC_OVERFLOW 381 : RELOC_OK); 382 case CHECK_SIGNED_OR_UNSIGNED: 383 if (size == 32) 384 return (Bits<valsize>::has_signed_unsigned_overflow32(value) 385 ? RELOC_OVERFLOW 386 : RELOC_OK); 387 else 388 return (Bits<valsize>::has_signed_unsigned_overflow64(value) 389 ? RELOC_OVERFLOW 390 : RELOC_OK); 391 case CHECK_NONE: 392 default: 393 return RELOC_OK; 394 } 395 } 396 397 // Do a simple relocation with the addend in the section contents. 398 // VALSIZE is the size of the value. 399 template<int valsize> 400 static inline Reloc_status rel(unsigned char * view,Address value,Overflow_check check)401 rel(unsigned char* view, Address value, Overflow_check check) 402 { 403 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype; 404 Valtype* wv = reinterpret_cast<Valtype*>(view); 405 Valtype addend = elfcpp::Swap<valsize, big_endian>::readval(wv); 406 value += addend; 407 elfcpp::Swap<valsize, big_endian>:: 408 writeval(wv, static_cast<Valtype>(value)); 409 return check_overflow<valsize>(value, check); 410 } 411 412 // Like the above but for relocs at unaligned addresses. 413 template<int valsize> 414 static inline Reloc_status rel_unaligned(unsigned char * view,Address value,Overflow_check check)415 rel_unaligned(unsigned char* view, Address value, Overflow_check check) 416 { 417 typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype 418 Valtype; 419 Valtype addend = elfcpp::Swap_unaligned<valsize, big_endian>::readval(view); 420 value += addend; 421 elfcpp::Swap_unaligned<valsize, big_endian>:: 422 writeval(view, static_cast<Valtype>(value)); 423 return check_overflow<valsize>(value, check); 424 } 425 426 // Do a simple relocation using a Symbol_value with the addend in 427 // the section contents. VALSIZE is the size of the value to 428 // relocate. 429 template<int valsize> 430 static inline Reloc_status rel(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Overflow_check check)431 rel(unsigned char* view, 432 const Sized_relobj_file<size, big_endian>* object, 433 const Symbol_value<size>* psymval, 434 Overflow_check check) 435 { 436 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype; 437 Valtype* wv = reinterpret_cast<Valtype*>(view); 438 Valtype addend = elfcpp::Swap<valsize, big_endian>::readval(wv); 439 Address value = psymval->value(object, addend); 440 elfcpp::Swap<valsize, big_endian>:: 441 writeval(wv, static_cast<Valtype>(value)); 442 return check_overflow<valsize>(value, check); 443 } 444 445 // Like the above but for relocs at unaligned addresses. 446 template<int valsize> 447 static inline Reloc_status rel_unaligned(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Overflow_check check)448 rel_unaligned(unsigned char* view, 449 const Sized_relobj_file<size, big_endian>* object, 450 const Symbol_value<size>* psymval, 451 Overflow_check check) 452 { 453 typedef typename elfcpp::Swap_unaligned<valsize, big_endian>::Valtype 454 Valtype; 455 Valtype addend = elfcpp::Swap_unaligned<valsize, big_endian>::readval(view); 456 Address value = psymval->value(object, addend); 457 elfcpp::Swap_unaligned<valsize, big_endian>::writeval(view, value); 458 return check_overflow<valsize>(value, check); 459 } 460 461 // Do a simple relocation with the addend in the relocation. 462 // VALSIZE is the size of the value. 463 template<int valsize> 464 static inline Reloc_status rela(unsigned char * view,Address value,Addendtype addend,Overflow_check check)465 rela(unsigned char* view, Address value, Addendtype addend, 466 Overflow_check check) 467 { 468 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype; 469 Valtype* wv = reinterpret_cast<Valtype*>(view); 470 value += addend; 471 elfcpp::Swap<valsize, big_endian>::writeval(wv, value); 472 return check_overflow<valsize>(value, check); 473 } 474 475 // Do a simple relocation using a symbol value with the addend in 476 // the relocation. VALSIZE is the size of the value. 477 template<int valsize> 478 static inline Reloc_status rela(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Addendtype addend,Overflow_check check)479 rela(unsigned char* view, 480 const Sized_relobj_file<size, big_endian>* object, 481 const Symbol_value<size>* psymval, 482 Addendtype addend, 483 Overflow_check check) 484 { 485 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype; 486 Valtype* wv = reinterpret_cast<Valtype*>(view); 487 Address value = psymval->value(object, addend); 488 elfcpp::Swap<valsize, big_endian>::writeval(wv, value); 489 return check_overflow<valsize>(value, check); 490 } 491 492 // Do a simple PC relative relocation with the addend in the section 493 // contents. VALSIZE is the size of the value. 494 template<int valsize> 495 static inline Reloc_status pcrel(unsigned char * view,Address value,Address address,Overflow_check check)496 pcrel(unsigned char* view, Address value, Address address, 497 Overflow_check check) 498 { 499 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype; 500 Valtype* wv = reinterpret_cast<Valtype*>(view); 501 Valtype addend = elfcpp::Swap<valsize, big_endian>::readval(wv); 502 value = value + addend - address; 503 elfcpp::Swap<valsize, big_endian>::writeval(wv, value); 504 return check_overflow<valsize>(value, check); 505 } 506 507 // Like the above but for relocs at unaligned addresses. 508 template<int valsize> 509 static inline Reloc_status pcrel_unaligned(unsigned char * view,Address value,Address address,Overflow_check check)510 pcrel_unaligned(unsigned char* view, Address value, Address address, 511 Overflow_check check) 512 { 513 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype; 514 Valtype addend = elfcpp::Swap_unaligned<valsize, big_endian>::readval(view); 515 value = value + addend - address; 516 elfcpp::Swap_unaligned<valsize, big_endian>::writeval(view, value); 517 return check_overflow<valsize>(value, check); 518 } 519 520 // Do a simple PC relative relocation with a Symbol_value with the 521 // addend in the section contents. VALSIZE is the size of the 522 // value. 523 template<int valsize> 524 static inline Reloc_status pcrel(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Address address,Overflow_check check)525 pcrel(unsigned char* view, 526 const Sized_relobj_file<size, big_endian>* object, 527 const Symbol_value<size>* psymval, 528 Address address, 529 Overflow_check check) 530 { 531 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype; 532 Valtype* wv = reinterpret_cast<Valtype*>(view); 533 Valtype addend = elfcpp::Swap<valsize, big_endian>::readval(wv); 534 Address value = psymval->value(object, addend) - address; 535 elfcpp::Swap<valsize, big_endian>::writeval(wv, value); 536 return check_overflow<valsize>(value, check); 537 } 538 539 // Do a simple PC relative relocation with the addend in the 540 // relocation. VALSIZE is the size of the value. 541 template<int valsize> 542 static inline Reloc_status pcrela(unsigned char * view,Address value,Addendtype addend,Address address,Overflow_check check)543 pcrela(unsigned char* view, Address value, Addendtype addend, Address address, 544 Overflow_check check) 545 { 546 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype; 547 Valtype* wv = reinterpret_cast<Valtype*>(view); 548 value = value + addend - address; 549 elfcpp::Swap<valsize, big_endian>::writeval(wv, value); 550 return check_overflow<valsize>(value, check); 551 } 552 553 // Do a simple PC relative relocation with a Symbol_value with the 554 // addend in the relocation. VALSIZE is the size of the value. 555 template<int valsize> 556 static inline Reloc_status pcrela(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Addendtype addend,Address address,Overflow_check check)557 pcrela(unsigned char* view, 558 const Sized_relobj_file<size, big_endian>* object, 559 const Symbol_value<size>* psymval, 560 Addendtype addend, 561 Address address, 562 Overflow_check check) 563 { 564 typedef typename elfcpp::Swap<valsize, big_endian>::Valtype Valtype; 565 Valtype* wv = reinterpret_cast<Valtype*>(view); 566 Address value = psymval->value(object, addend) - address; 567 elfcpp::Swap<valsize, big_endian>::writeval(wv, value); 568 return check_overflow<valsize>(value, check); 569 } 570 571 typedef Relocate_functions<size, big_endian> This; 572 573 public: 574 // Do a simple 8-bit REL relocation with the addend in the section 575 // contents. 576 static inline void rel8(unsigned char * view,Address value)577 rel8(unsigned char* view, Address value) 578 { This::template rel<8>(view, value, CHECK_NONE); } 579 580 static inline Reloc_status rel8_check(unsigned char * view,Address value,Overflow_check check)581 rel8_check(unsigned char* view, Address value, Overflow_check check) 582 { return This::template rel<8>(view, value, check); } 583 584 static inline void rel8(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval)585 rel8(unsigned char* view, 586 const Sized_relobj_file<size, big_endian>* object, 587 const Symbol_value<size>* psymval) 588 { This::template rel<8>(view, object, psymval, CHECK_NONE); } 589 590 static inline Reloc_status rel8_check(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Overflow_check check)591 rel8_check(unsigned char* view, 592 const Sized_relobj_file<size, big_endian>* object, 593 const Symbol_value<size>* psymval, 594 Overflow_check check) 595 { return This::template rel<8>(view, object, psymval, check); } 596 597 // Do an 8-bit RELA relocation with the addend in the relocation. 598 static inline void rela8(unsigned char * view,Address value,Addendtype addend)599 rela8(unsigned char* view, Address value, Addendtype addend) 600 { This::template rela<8>(view, value, addend, CHECK_NONE); } 601 602 static inline Reloc_status rela8_check(unsigned char * view,Address value,Addendtype addend,Overflow_check check)603 rela8_check(unsigned char* view, Address value, Addendtype addend, 604 Overflow_check check) 605 { return This::template rela<8>(view, value, addend, check); } 606 607 static inline void rela8(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Addendtype addend)608 rela8(unsigned char* view, 609 const Sized_relobj_file<size, big_endian>* object, 610 const Symbol_value<size>* psymval, 611 Addendtype addend) 612 { This::template rela<8>(view, object, psymval, addend, CHECK_NONE); } 613 614 static inline Reloc_status rela8_check(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Addendtype addend,Overflow_check check)615 rela8_check(unsigned char* view, 616 const Sized_relobj_file<size, big_endian>* object, 617 const Symbol_value<size>* psymval, 618 Addendtype addend, 619 Overflow_check check) 620 { return This::template rela<8>(view, object, psymval, addend, check); } 621 622 // Do a simple 8-bit PC relative relocation with the addend in the 623 // section contents. 624 static inline void pcrel8(unsigned char * view,unsigned char value,Address address)625 pcrel8(unsigned char* view, unsigned char value, Address address) 626 { This::template pcrel<8>(view, value, address, CHECK_NONE); } 627 628 static inline Reloc_status pcrel8_check(unsigned char * view,unsigned char value,Address address,Overflow_check check)629 pcrel8_check(unsigned char* view, unsigned char value, Address address, 630 Overflow_check check) 631 { return This::template pcrel<8>(view, value, address, check); } 632 633 static inline void pcrel8(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Address address)634 pcrel8(unsigned char* view, 635 const Sized_relobj_file<size, big_endian>* object, 636 const Symbol_value<size>* psymval, 637 Address address) 638 { This::template pcrel<8>(view, object, psymval, address, CHECK_NONE); } 639 640 static inline Reloc_status pcrel8_check(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Address address,Overflow_check check)641 pcrel8_check(unsigned char* view, 642 const Sized_relobj_file<size, big_endian>* object, 643 const Symbol_value<size>* psymval, 644 Address address, 645 Overflow_check check) 646 { return This::template pcrel<8>(view, object, psymval, address, check); } 647 648 // Do a simple 8-bit PC relative RELA relocation with the addend in 649 // the reloc. 650 static inline void pcrela8(unsigned char * view,Address value,Addendtype addend,Address address)651 pcrela8(unsigned char* view, Address value, Addendtype addend, 652 Address address) 653 { This::template pcrela<8>(view, value, addend, address, CHECK_NONE); } 654 655 static inline Reloc_status pcrela8_check(unsigned char * view,Address value,Addendtype addend,Address address,Overflow_check check)656 pcrela8_check(unsigned char* view, Address value, Addendtype addend, 657 Address address, Overflow_check check) 658 { return This::template pcrela<8>(view, value, addend, address, check); } 659 660 static inline void pcrela8(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Addendtype addend,Address address)661 pcrela8(unsigned char* view, 662 const Sized_relobj_file<size, big_endian>* object, 663 const Symbol_value<size>* psymval, 664 Addendtype addend, 665 Address address) 666 { This::template pcrela<8>(view, object, psymval, addend, address, 667 CHECK_NONE); } 668 669 static inline Reloc_status pcrela8_check(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Addendtype addend,Address address,Overflow_check check)670 pcrela8_check(unsigned char* view, 671 const Sized_relobj_file<size, big_endian>* object, 672 const Symbol_value<size>* psymval, 673 Addendtype addend, 674 Address address, 675 Overflow_check check) 676 { return This::template pcrela<8>(view, object, psymval, addend, address, 677 check); } 678 679 // Do a simple 16-bit REL relocation with the addend in the section 680 // contents. 681 static inline void rel16(unsigned char * view,Address value)682 rel16(unsigned char* view, Address value) 683 { This::template rel<16>(view, value, CHECK_NONE); } 684 685 static inline Reloc_status rel16_check(unsigned char * view,Address value,Overflow_check check)686 rel16_check(unsigned char* view, Address value, Overflow_check check) 687 { return This::template rel<16>(view, value, check); } 688 689 static inline void rel16(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval)690 rel16(unsigned char* view, 691 const Sized_relobj_file<size, big_endian>* object, 692 const Symbol_value<size>* psymval) 693 { This::template rel<16>(view, object, psymval, CHECK_NONE); } 694 695 static inline Reloc_status rel16_check(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Overflow_check check)696 rel16_check(unsigned char* view, 697 const Sized_relobj_file<size, big_endian>* object, 698 const Symbol_value<size>* psymval, 699 Overflow_check check) 700 { return This::template rel<16>(view, object, psymval, check); } 701 702 // Do an 16-bit RELA relocation with the addend in the relocation. 703 static inline void rela16(unsigned char * view,Address value,Addendtype addend)704 rela16(unsigned char* view, Address value, Addendtype addend) 705 { This::template rela<16>(view, value, addend, CHECK_NONE); } 706 707 static inline Reloc_status rela16_check(unsigned char * view,Address value,Addendtype addend,Overflow_check check)708 rela16_check(unsigned char* view, Address value, Addendtype addend, 709 Overflow_check check) 710 { return This::template rela<16>(view, value, addend, check); } 711 712 static inline void rela16(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Addendtype addend)713 rela16(unsigned char* view, 714 const Sized_relobj_file<size, big_endian>* object, 715 const Symbol_value<size>* psymval, 716 Addendtype addend) 717 { This::template rela<16>(view, object, psymval, addend, CHECK_NONE); } 718 719 static inline Reloc_status rela16_check(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Addendtype addend,Overflow_check check)720 rela16_check(unsigned char* view, 721 const Sized_relobj_file<size, big_endian>* object, 722 const Symbol_value<size>* psymval, 723 Addendtype addend, 724 Overflow_check check) 725 { return This::template rela<16>(view, object, psymval, addend, check); } 726 727 // Do a simple 16-bit PC relative REL relocation with the addend in 728 // the section contents. 729 static inline void pcrel16(unsigned char * view,Address value,Address address)730 pcrel16(unsigned char* view, Address value, Address address) 731 { This::template pcrel<16>(view, value, address, CHECK_NONE); } 732 733 static inline Reloc_status pcrel16_check(unsigned char * view,Address value,Address address,Overflow_check check)734 pcrel16_check(unsigned char* view, Address value, Address address, 735 Overflow_check check) 736 { return This::template pcrel<16>(view, value, address, check); } 737 738 static inline void pcrel16(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Address address)739 pcrel16(unsigned char* view, 740 const Sized_relobj_file<size, big_endian>* object, 741 const Symbol_value<size>* psymval, 742 Address address) 743 { This::template pcrel<16>(view, object, psymval, address, CHECK_NONE); } 744 745 static inline Reloc_status pcrel16_check(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Address address,Overflow_check check)746 pcrel16_check(unsigned char* view, 747 const Sized_relobj_file<size, big_endian>* object, 748 const Symbol_value<size>* psymval, 749 Address address, 750 Overflow_check check) 751 { return This::template pcrel<16>(view, object, psymval, address, check); } 752 753 // Do a simple 16-bit PC relative RELA relocation with the addend in 754 // the reloc. 755 static inline void pcrela16(unsigned char * view,Address value,Addendtype addend,Address address)756 pcrela16(unsigned char* view, Address value, Addendtype addend, 757 Address address) 758 { This::template pcrela<16>(view, value, addend, address, CHECK_NONE); } 759 760 static inline Reloc_status pcrela16_check(unsigned char * view,Address value,Addendtype addend,Address address,Overflow_check check)761 pcrela16_check(unsigned char* view, Address value, Addendtype addend, 762 Address address, Overflow_check check) 763 { return This::template pcrela<16>(view, value, addend, address, check); } 764 765 static inline void pcrela16(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Addendtype addend,Address address)766 pcrela16(unsigned char* view, 767 const Sized_relobj_file<size, big_endian>* object, 768 const Symbol_value<size>* psymval, 769 Addendtype addend, 770 Address address) 771 { This::template pcrela<16>(view, object, psymval, addend, address, 772 CHECK_NONE); } 773 774 static inline Reloc_status pcrela16_check(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Addendtype addend,Address address,Overflow_check check)775 pcrela16_check(unsigned char* view, 776 const Sized_relobj_file<size, big_endian>* object, 777 const Symbol_value<size>* psymval, 778 Addendtype addend, 779 Address address, 780 Overflow_check check) 781 { return This::template pcrela<16>(view, object, psymval, addend, address, 782 check); } 783 784 // Do a simple 32-bit REL relocation with the addend in the section 785 // contents. 786 static inline void rel32(unsigned char * view,Address value)787 rel32(unsigned char* view, Address value) 788 { This::template rel<32>(view, value, CHECK_NONE); } 789 790 static inline Reloc_status rel32_check(unsigned char * view,Address value,Overflow_check check)791 rel32_check(unsigned char* view, Address value, Overflow_check check) 792 { return This::template rel<32>(view, value, check); } 793 794 // Like above but for relocs at unaligned addresses. 795 static inline void rel32_unaligned(unsigned char * view,Address value)796 rel32_unaligned(unsigned char* view, Address value) 797 { This::template rel_unaligned<32>(view, value, CHECK_NONE); } 798 799 static inline Reloc_status rel32_unaligned_check(unsigned char * view,Address value,Overflow_check check)800 rel32_unaligned_check(unsigned char* view, Address value, 801 Overflow_check check) 802 { return This::template rel_unaligned<32>(view, value, check); } 803 804 static inline void rel32(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval)805 rel32(unsigned char* view, 806 const Sized_relobj_file<size, big_endian>* object, 807 const Symbol_value<size>* psymval) 808 { This::template rel<32>(view, object, psymval, CHECK_NONE); } 809 810 static inline Reloc_status rel32_check(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Overflow_check check)811 rel32_check(unsigned char* view, 812 const Sized_relobj_file<size, big_endian>* object, 813 const Symbol_value<size>* psymval, 814 Overflow_check check) 815 { return This::template rel<32>(view, object, psymval, check); } 816 817 // Like above but for relocs at unaligned addresses. 818 static inline void rel32_unaligned(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval)819 rel32_unaligned(unsigned char* view, 820 const Sized_relobj_file<size, big_endian>* object, 821 const Symbol_value<size>* psymval) 822 { This::template rel_unaligned<32>(view, object, psymval, CHECK_NONE); } 823 824 static inline Reloc_status rel32_unaligned_check(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Overflow_check check)825 rel32_unaligned_check(unsigned char* view, 826 const Sized_relobj_file<size, big_endian>* object, 827 const Symbol_value<size>* psymval, 828 Overflow_check check) 829 { return This::template rel_unaligned<32>(view, object, psymval, check); } 830 831 // Do a 32-bit RELA relocation with the addend in the relocation. 832 static inline void rela32(unsigned char * view,Address value,Addendtype addend)833 rela32(unsigned char* view, Address value, Addendtype addend) 834 { This::template rela<32>(view, value, addend, CHECK_NONE); } 835 836 static inline Reloc_status rela32(unsigned char * view,Address value,Addendtype addend,Overflow_check check)837 rela32(unsigned char* view, Address value, Addendtype addend, 838 Overflow_check check) 839 { return This::template rela<32>(view, value, addend, check); } 840 841 static inline void rela32(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Addendtype addend)842 rela32(unsigned char* view, 843 const Sized_relobj_file<size, big_endian>* object, 844 const Symbol_value<size>* psymval, 845 Addendtype addend) 846 { This::template rela<32>(view, object, psymval, addend, CHECK_NONE); } 847 848 static inline Reloc_status rela32_check(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Addendtype addend,Overflow_check check)849 rela32_check(unsigned char* view, 850 const Sized_relobj_file<size, big_endian>* object, 851 const Symbol_value<size>* psymval, 852 Addendtype addend, 853 Overflow_check check) 854 { return This::template rela<32>(view, object, psymval, addend, check); } 855 856 // Do a simple 32-bit PC relative REL relocation with the addend in 857 // the section contents. 858 static inline void pcrel32(unsigned char * view,Address value,Address address)859 pcrel32(unsigned char* view, Address value, Address address) 860 { This::template pcrel<32>(view, value, address, CHECK_NONE); } 861 862 static inline Reloc_status pcrel32_check(unsigned char * view,Address value,Address address,Overflow_check check)863 pcrel32_check(unsigned char* view, Address value, Address address, 864 Overflow_check check) 865 { return This::template pcrel<32>(view, value, address, check); } 866 867 // Unaligned version of the above. 868 static inline void pcrel32_unaligned(unsigned char * view,Address value,Address address)869 pcrel32_unaligned(unsigned char* view, Address value, Address address) 870 { This::template pcrel_unaligned<32>(view, value, address, CHECK_NONE); } 871 872 static inline Reloc_status pcrel32_unaligned_check(unsigned char * view,Address value,Address address,Overflow_check check)873 pcrel32_unaligned_check(unsigned char* view, Address value, Address address, 874 Overflow_check check) 875 { return This::template pcrel_unaligned<32>(view, value, address, check); } 876 877 static inline void pcrel32(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Address address)878 pcrel32(unsigned char* view, 879 const Sized_relobj_file<size, big_endian>* object, 880 const Symbol_value<size>* psymval, 881 Address address) 882 { This::template pcrel<32>(view, object, psymval, address, CHECK_NONE); } 883 884 static inline Reloc_status pcrel32_check(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Address address,Overflow_check check)885 pcrel32_check(unsigned char* view, 886 const Sized_relobj_file<size, big_endian>* object, 887 const Symbol_value<size>* psymval, 888 Address address, 889 Overflow_check check) 890 { return This::template pcrel<32>(view, object, psymval, address, check); } 891 892 // Do a simple 32-bit PC relative RELA relocation with the addend in 893 // the relocation. 894 static inline void pcrela32(unsigned char * view,Address value,Addendtype addend,Address address)895 pcrela32(unsigned char* view, Address value, Addendtype addend, 896 Address address) 897 { This::template pcrela<32>(view, value, addend, address, CHECK_NONE); } 898 899 static inline Reloc_status pcrela32_check(unsigned char * view,Address value,Addendtype addend,Address address,Overflow_check check)900 pcrela32_check(unsigned char* view, Address value, Addendtype addend, 901 Address address, Overflow_check check) 902 { return This::template pcrela<32>(view, value, addend, address, check); } 903 904 static inline void pcrela32(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Addendtype addend,Address address)905 pcrela32(unsigned char* view, 906 const Sized_relobj_file<size, big_endian>* object, 907 const Symbol_value<size>* psymval, 908 Addendtype addend, 909 Address address) 910 { This::template pcrela<32>(view, object, psymval, addend, address, 911 CHECK_NONE); } 912 913 static inline Reloc_status pcrela32_check(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Addendtype addend,Address address,Overflow_check check)914 pcrela32_check(unsigned char* view, 915 const Sized_relobj_file<size, big_endian>* object, 916 const Symbol_value<size>* psymval, 917 Addendtype addend, 918 Address address, 919 Overflow_check check) 920 { return This::template pcrela<32>(view, object, psymval, addend, address, 921 check); } 922 923 // Do a simple 64-bit REL relocation with the addend in the section 924 // contents. 925 static inline void rel64(unsigned char * view,Address value)926 rel64(unsigned char* view, Address value) 927 { This::template rel<64>(view, value, CHECK_NONE); } 928 929 static inline void rel64(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval)930 rel64(unsigned char* view, 931 const Sized_relobj_file<size, big_endian>* object, 932 const Symbol_value<size>* psymval) 933 { This::template rel<64>(view, object, psymval, CHECK_NONE); } 934 935 // Do a 64-bit RELA relocation with the addend in the relocation. 936 static inline void rela64(unsigned char * view,Address value,Addendtype addend)937 rela64(unsigned char* view, Address value, Addendtype addend) 938 { This::template rela<64>(view, value, addend, CHECK_NONE); } 939 940 static inline void rela64(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Addendtype addend)941 rela64(unsigned char* view, 942 const Sized_relobj_file<size, big_endian>* object, 943 const Symbol_value<size>* psymval, 944 Addendtype addend) 945 { This::template rela<64>(view, object, psymval, addend, CHECK_NONE); } 946 947 // Do a simple 64-bit PC relative REL relocation with the addend in 948 // the section contents. 949 static inline void pcrel64(unsigned char * view,Address value,Address address)950 pcrel64(unsigned char* view, Address value, Address address) 951 { This::template pcrel<64>(view, value, address, CHECK_NONE); } 952 953 static inline void pcrel64(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Address address)954 pcrel64(unsigned char* view, 955 const Sized_relobj_file<size, big_endian>* object, 956 const Symbol_value<size>* psymval, 957 Address address) 958 { This::template pcrel<64>(view, object, psymval, address, CHECK_NONE); } 959 960 // Do a simple 64-bit PC relative RELA relocation with the addend in 961 // the relocation. 962 static inline void pcrela64(unsigned char * view,Address value,Addendtype addend,Address address)963 pcrela64(unsigned char* view, Address value, Addendtype addend, 964 Address address) 965 { This::template pcrela<64>(view, value, addend, address, CHECK_NONE); } 966 967 static inline void pcrela64(unsigned char * view,const Sized_relobj_file<size,big_endian> * object,const Symbol_value<size> * psymval,Addendtype addend,Address address)968 pcrela64(unsigned char* view, 969 const Sized_relobj_file<size, big_endian>* object, 970 const Symbol_value<size>* psymval, 971 Addendtype addend, 972 Address address) 973 { This::template pcrela<64>(view, object, psymval, addend, address, 974 CHECK_NONE); } 975 }; 976 977 // Convenience class for min and max values of a given BITS length. 978 979 template<int bits> 980 class Limits 981 { 982 public: 983 static const uint64_t MAX_UNSIGNED = (1ULL << bits) - 1; 984 static const int64_t MAX_SIGNED = MAX_UNSIGNED >> 1; 985 static const int64_t MIN_SIGNED = -MAX_SIGNED - 1; 986 }; 987 988 template<> 989 class Limits<64> 990 { 991 public: 992 static const uint64_t MAX_UNSIGNED = ~0ULL; 993 static const int64_t MAX_SIGNED = MAX_UNSIGNED >> 1; 994 static const int64_t MIN_SIGNED = -MAX_SIGNED - 1; 995 }; 996 997 // Integer manipulation functions used by various targets when 998 // performing relocations. 999 1000 template<int bits> 1001 class Bits 1002 { 1003 public: 1004 // Sign extend an n-bit unsigned integer stored in a uint32_t into 1005 // an int32_t. BITS must be between 1 and 32. 1006 static inline int32_t sign_extend32(uint32_t val)1007 sign_extend32(uint32_t val) 1008 { 1009 gold_assert(bits > 0 && bits <= 32); 1010 if (bits == 32) 1011 return static_cast<int32_t>(val); 1012 uint32_t mask = (~static_cast<uint32_t>(0)) >> (32 - bits); 1013 val &= mask; 1014 uint32_t top_bit = 1U << (bits - 1); 1015 int32_t as_signed = static_cast<int32_t>(val); 1016 if ((val & top_bit) != 0) 1017 as_signed -= static_cast<int32_t>(top_bit * 2); 1018 return as_signed; 1019 } 1020 1021 // Return true if VAL (stored in a uint32_t) has overflowed a signed 1022 // value with BITS bits. 1023 static inline bool has_overflow32(uint32_t val)1024 has_overflow32(uint32_t val) 1025 { 1026 gold_assert(bits > 0 && bits <= 32); 1027 if (bits == 32) 1028 return false; 1029 const int32_t max = static_cast<int32_t>(Limits<bits>::MAX_SIGNED); 1030 const int32_t min = static_cast<int32_t>(Limits<bits>::MIN_SIGNED); 1031 int32_t as_signed = static_cast<int32_t>(val); 1032 return as_signed > max || as_signed < min; 1033 } 1034 1035 // Return true if VAL (stored in a uint32_t) has overflowed an unsigned 1036 // value with BITS bits. 1037 static inline bool has_unsigned_overflow32(uint32_t val)1038 has_unsigned_overflow32(uint32_t val) 1039 { 1040 gold_assert(bits > 0 && bits <= 32); 1041 if (bits == 32) 1042 return false; 1043 const uint32_t max = static_cast<uint32_t>(Limits<bits>::MAX_UNSIGNED); 1044 return val > max; 1045 } 1046 1047 // Return true if VAL (stored in a uint32_t) has overflowed both a 1048 // signed and an unsigned value. E.g., 1049 // Bits<8>::has_signed_unsigned_overflow32 would check -128 <= VAL < 1050 // 255. 1051 static inline bool has_signed_unsigned_overflow32(uint32_t val)1052 has_signed_unsigned_overflow32(uint32_t val) 1053 { 1054 gold_assert(bits > 0 && bits <= 32); 1055 if (bits == 32) 1056 return false; 1057 const int32_t max = static_cast<int32_t>(Limits<bits>::MAX_UNSIGNED); 1058 const int32_t min = static_cast<int32_t>(Limits<bits>::MIN_SIGNED); 1059 int32_t as_signed = static_cast<int32_t>(val); 1060 return as_signed > max || as_signed < min; 1061 } 1062 1063 // Select bits from A and B using bits in MASK. For each n in 1064 // [0..31], the n-th bit in the result is chosen from the n-th bits 1065 // of A and B. A zero selects A and a one selects B. 1066 static inline uint32_t bit_select32(uint32_t a,uint32_t b,uint32_t mask)1067 bit_select32(uint32_t a, uint32_t b, uint32_t mask) 1068 { return (a & ~mask) | (b & mask); } 1069 1070 // Sign extend an n-bit unsigned integer stored in a uint64_t into 1071 // an int64_t. BITS must be between 1 and 64. 1072 static inline int64_t sign_extend(uint64_t val)1073 sign_extend(uint64_t val) 1074 { 1075 gold_assert(bits > 0 && bits <= 64); 1076 if (bits == 64) 1077 return static_cast<int64_t>(val); 1078 uint64_t mask = (~static_cast<uint64_t>(0)) >> (64 - bits); 1079 val &= mask; 1080 uint64_t top_bit = static_cast<uint64_t>(1) << (bits - 1); 1081 int64_t as_signed = static_cast<int64_t>(val); 1082 if ((val & top_bit) != 0) 1083 as_signed -= static_cast<int64_t>(top_bit * 2); 1084 return as_signed; 1085 } 1086 1087 // Return true if VAL (stored in a uint64_t) has overflowed a signed 1088 // value with BITS bits. 1089 static inline bool has_overflow(uint64_t val)1090 has_overflow(uint64_t val) 1091 { 1092 gold_assert(bits > 0 && bits <= 64); 1093 if (bits == 64) 1094 return false; 1095 const int64_t max = Limits<bits>::MAX_SIGNED; 1096 const int64_t min = Limits<bits>::MIN_SIGNED; 1097 int64_t as_signed = static_cast<int64_t>(val); 1098 return as_signed > max || as_signed < min; 1099 } 1100 1101 // Return true if VAL (stored in a uint64_t) has overflowed an unsigned 1102 // value with BITS bits. 1103 static inline bool has_unsigned_overflow(uint64_t val)1104 has_unsigned_overflow(uint64_t val) 1105 { 1106 gold_assert(bits > 0 && bits <= 64); 1107 if (bits == 64) 1108 return false; 1109 const uint64_t max = Limits<bits>::MAX_UNSIGNED; 1110 return val > max; 1111 } 1112 1113 // Return true if VAL (stored in a uint64_t) has overflowed both a 1114 // signed and an unsigned value. E.g., 1115 // Bits<8>::has_signed_unsigned_overflow would check -128 <= VAL < 1116 // 255. 1117 static inline bool has_signed_unsigned_overflow64(uint64_t val)1118 has_signed_unsigned_overflow64(uint64_t val) 1119 { 1120 gold_assert(bits > 0 && bits <= 64); 1121 if (bits == 64) 1122 return false; 1123 const int64_t max = static_cast<int64_t>(Limits<bits>::MAX_UNSIGNED); 1124 const int64_t min = Limits<bits>::MIN_SIGNED; 1125 int64_t as_signed = static_cast<int64_t>(val); 1126 return as_signed > max || as_signed < min; 1127 } 1128 1129 // Select bits from A and B using bits in MASK. For each n in 1130 // [0..31], the n-th bit in the result is chosen from the n-th bits 1131 // of A and B. A zero selects A and a one selects B. 1132 static inline uint64_t bit_select64(uint64_t a,uint64_t b,uint64_t mask)1133 bit_select64(uint64_t a, uint64_t b, uint64_t mask) 1134 { return (a & ~mask) | (b & mask); } 1135 }; 1136 1137 // Track relocations while reading a section. This lets you ask for 1138 // the relocation at a certain offset, and see how relocs occur 1139 // between points of interest. 1140 1141 template<int size, bool big_endian> 1142 class Track_relocs 1143 { 1144 public: Track_relocs()1145 Track_relocs() 1146 : prelocs_(NULL), len_(0), pos_(0), reloc_size_(0) 1147 { } 1148 1149 // Initialize the Track_relocs object. OBJECT is the object holding 1150 // the reloc section, RELOC_SHNDX is the section index of the reloc 1151 // section, and RELOC_TYPE is the type of the reloc section 1152 // (elfcpp::SHT_REL or elfcpp::SHT_RELA). This returns false if 1153 // something went wrong. 1154 bool 1155 initialize(Object* object, unsigned int reloc_shndx, 1156 unsigned int reloc_type); 1157 1158 // Return the offset in the data section to which the next reloc 1159 // applies. This returns -1 if there is no next reloc. 1160 off_t 1161 next_offset() const; 1162 1163 // Return the symbol index of the next reloc. This returns -1U if 1164 // there is no next reloc. 1165 unsigned int 1166 next_symndx() const; 1167 1168 // Return the addend of the next reloc. This returns 0 if there is 1169 // no next reloc. 1170 uint64_t 1171 next_addend() const; 1172 1173 // Advance to OFFSET within the data section, and return the number 1174 // of relocs which would be skipped. 1175 int 1176 advance(off_t offset); 1177 1178 // Checkpoint the current position in the reloc section. 1179 section_size_type checkpoint()1180 checkpoint() const 1181 { return this->pos_; } 1182 1183 // Reset the position to CHECKPOINT. 1184 void reset(section_size_type checkpoint)1185 reset(section_size_type checkpoint) 1186 { this->pos_ = checkpoint; } 1187 1188 private: 1189 // The contents of the input object's reloc section. 1190 const unsigned char* prelocs_; 1191 // The length of the reloc section. 1192 section_size_type len_; 1193 // Our current position in the reloc section. 1194 section_size_type pos_; 1195 // The size of the relocs in the section. 1196 int reloc_size_; 1197 }; 1198 1199 } // End namespace gold. 1200 1201 #endif // !defined(GOLD_RELOC_H) 1202