| 1 | // output.h -- manage the output file for gold -*- C++ -*- |
| 2 | |
| 3 | #ifndef GOLD_OUTPUT_H |
| 4 | #define GOLD_OUTPUT_H |
| 5 | |
| 6 | #include <list> |
| 7 | #include <vector> |
| 8 | |
| 9 | #include "elfcpp.h" |
| 10 | #include "layout.h" |
| 11 | #include "reloc-types.h" |
| 12 | |
| 13 | namespace gold |
| 14 | { |
| 15 | |
| 16 | class General_options; |
| 17 | class Object; |
| 18 | class Symbol; |
| 19 | class Output_file; |
| 20 | class Output_section; |
| 21 | class Target; |
| 22 | template<int size, bool big_endian> |
| 23 | class Sized_target; |
| 24 | template<int size, bool big_endian> |
| 25 | class Sized_relobj; |
| 26 | |
| 27 | // An abtract class for data which has to go into the output file. |
| 28 | |
| 29 | class Output_data |
| 30 | { |
| 31 | public: |
| 32 | explicit Output_data(off_t data_size = 0) |
| 33 | : address_(0), data_size_(data_size), offset_(-1) |
| 34 | { } |
| 35 | |
| 36 | virtual |
| 37 | ~Output_data(); |
| 38 | |
| 39 | // Return the address. This is only valid after Layout::finalize is |
| 40 | // finished. |
| 41 | uint64_t |
| 42 | address() const |
| 43 | { return this->address_; } |
| 44 | |
| 45 | // Return the size of the data. This must be valid after |
| 46 | // Layout::finalize calls set_address, but need not be valid before |
| 47 | // then. |
| 48 | off_t |
| 49 | data_size() const |
| 50 | { return this->data_size_; } |
| 51 | |
| 52 | // Return the file offset. This is only valid after |
| 53 | // Layout::finalize is finished. |
| 54 | off_t |
| 55 | offset() const |
| 56 | { return this->offset_; } |
| 57 | |
| 58 | // Return the required alignment. |
| 59 | uint64_t |
| 60 | addralign() const |
| 61 | { return this->do_addralign(); } |
| 62 | |
| 63 | // Return whether this is an Output_section. |
| 64 | bool |
| 65 | is_section() const |
| 66 | { return this->do_is_section(); } |
| 67 | |
| 68 | // Return whether this is an Output_section of the specified type. |
| 69 | bool |
| 70 | is_section_type(elfcpp::Elf_Word stt) const |
| 71 | { return this->do_is_section_type(stt); } |
| 72 | |
| 73 | // Return whether this is an Output_section with the specified flag |
| 74 | // set. |
| 75 | bool |
| 76 | is_section_flag_set(elfcpp::Elf_Xword shf) const |
| 77 | { return this->do_is_section_flag_set(shf); } |
| 78 | |
| 79 | // Return the output section index, if there is an output section. |
| 80 | unsigned int |
| 81 | out_shndx() const |
| 82 | { return this->do_out_shndx(); } |
| 83 | |
| 84 | // Set the output section index, if this is an output section. |
| 85 | void |
| 86 | set_out_shndx(unsigned int shndx) |
| 87 | { this->do_set_out_shndx(shndx); } |
| 88 | |
| 89 | // Set the address and file offset of this data. This is called |
| 90 | // during Layout::finalize. |
| 91 | void |
| 92 | set_address(uint64_t addr, off_t off); |
| 93 | |
| 94 | // Write the data to the output file. This is called after |
| 95 | // Layout::finalize is complete. |
| 96 | void |
| 97 | write(Output_file* file) |
| 98 | { this->do_write(file); } |
| 99 | |
| 100 | // This is called by Layout::finalize to note that all sizes must |
| 101 | // now be fixed. |
| 102 | static void |
| 103 | layout_complete() |
| 104 | { Output_data::sizes_are_fixed = true; } |
| 105 | |
| 106 | protected: |
| 107 | // Functions that child classes may or in some cases must implement. |
| 108 | |
| 109 | // Write the data to the output file. |
| 110 | virtual void |
| 111 | do_write(Output_file*) = 0; |
| 112 | |
| 113 | // Return the required alignment. |
| 114 | virtual uint64_t |
| 115 | do_addralign() const = 0; |
| 116 | |
| 117 | // Return whether this is an Output_section. |
| 118 | virtual bool |
| 119 | do_is_section() const |
| 120 | { return false; } |
| 121 | |
| 122 | // Return whether this is an Output_section of the specified type. |
| 123 | // This only needs to be implement by Output_section. |
| 124 | virtual bool |
| 125 | do_is_section_type(elfcpp::Elf_Word) const |
| 126 | { return false; } |
| 127 | |
| 128 | // Return whether this is an Output_section with the specific flag |
| 129 | // set. This only needs to be implemented by Output_section. |
| 130 | virtual bool |
| 131 | do_is_section_flag_set(elfcpp::Elf_Xword) const |
| 132 | { return false; } |
| 133 | |
| 134 | // Return the output section index, if there is an output section. |
| 135 | virtual unsigned int |
| 136 | do_out_shndx() const |
| 137 | { gold_unreachable(); } |
| 138 | |
| 139 | // Set the output section index, if this is an output section. |
| 140 | virtual void |
| 141 | do_set_out_shndx(unsigned int) |
| 142 | { gold_unreachable(); } |
| 143 | |
| 144 | // Set the address and file offset of the data. This only needs to |
| 145 | // be implemented if the child needs to know. The child class can |
| 146 | // set its size in this call. |
| 147 | virtual void |
| 148 | do_set_address(uint64_t, off_t) |
| 149 | { } |
| 150 | |
| 151 | // Functions that child classes may call. |
| 152 | |
| 153 | // Set the size of the data. |
| 154 | void |
| 155 | set_data_size(off_t data_size) |
| 156 | { |
| 157 | gold_assert(!Output_data::sizes_are_fixed); |
| 158 | this->data_size_ = data_size; |
| 159 | } |
| 160 | |
| 161 | // Return default alignment for a size--32 or 64. |
| 162 | static uint64_t |
| 163 | default_alignment(int size); |
| 164 | |
| 165 | private: |
| 166 | Output_data(const Output_data&); |
| 167 | Output_data& operator=(const Output_data&); |
| 168 | |
| 169 | // This is used for verification, to make sure that we don't try to |
| 170 | // change any sizes after we set the section addresses. |
| 171 | static bool sizes_are_fixed; |
| 172 | |
| 173 | // Memory address in file (not always meaningful). |
| 174 | uint64_t address_; |
| 175 | // Size of data in file. |
| 176 | off_t data_size_; |
| 177 | // Offset within file. |
| 178 | off_t offset_; |
| 179 | }; |
| 180 | |
| 181 | // Output the section headers. |
| 182 | |
| 183 | class Output_section_headers : public Output_data |
| 184 | { |
| 185 | public: |
| 186 | Output_section_headers(int size, |
| 187 | bool big_endian, |
| 188 | const Layout*, |
| 189 | const Layout::Segment_list*, |
| 190 | const Layout::Section_list*, |
| 191 | const Stringpool*); |
| 192 | |
| 193 | // Write the data to the file. |
| 194 | void |
| 195 | do_write(Output_file*); |
| 196 | |
| 197 | // Return the required alignment. |
| 198 | uint64_t |
| 199 | do_addralign() const |
| 200 | { return Output_data::default_alignment(this->size_); } |
| 201 | |
| 202 | private: |
| 203 | // Write the data to the file with the right size and endianness. |
| 204 | template<int size, bool big_endian> |
| 205 | void |
| 206 | do_sized_write(Output_file*); |
| 207 | |
| 208 | int size_; |
| 209 | bool big_endian_; |
| 210 | const Layout* layout_; |
| 211 | const Layout::Segment_list* segment_list_; |
| 212 | const Layout::Section_list* unattached_section_list_; |
| 213 | const Stringpool* secnamepool_; |
| 214 | }; |
| 215 | |
| 216 | // Output the segment headers. |
| 217 | |
| 218 | class Output_segment_headers : public Output_data |
| 219 | { |
| 220 | public: |
| 221 | Output_segment_headers(int size, bool big_endian, |
| 222 | const Layout::Segment_list& segment_list); |
| 223 | |
| 224 | // Write the data to the file. |
| 225 | void |
| 226 | do_write(Output_file*); |
| 227 | |
| 228 | // Return the required alignment. |
| 229 | uint64_t |
| 230 | do_addralign() const |
| 231 | { return Output_data::default_alignment(this->size_); } |
| 232 | |
| 233 | private: |
| 234 | // Write the data to the file with the right size and endianness. |
| 235 | template<int size, bool big_endian> |
| 236 | void |
| 237 | do_sized_write(Output_file*); |
| 238 | |
| 239 | int size_; |
| 240 | bool big_endian_; |
| 241 | const Layout::Segment_list& segment_list_; |
| 242 | }; |
| 243 | |
| 244 | // Output the ELF file header. |
| 245 | |
| 246 | class Output_file_header : public Output_data |
| 247 | { |
| 248 | public: |
| 249 | Output_file_header(int size, |
| 250 | bool big_endian, |
| 251 | const General_options&, |
| 252 | const Target*, |
| 253 | const Symbol_table*, |
| 254 | const Output_segment_headers*); |
| 255 | |
| 256 | // Add information about the section headers. We lay out the ELF |
| 257 | // file header before we create the section headers. |
| 258 | void set_section_info(const Output_section_headers*, |
| 259 | const Output_section* shstrtab); |
| 260 | |
| 261 | // Write the data to the file. |
| 262 | void |
| 263 | do_write(Output_file*); |
| 264 | |
| 265 | // Return the required alignment. |
| 266 | uint64_t |
| 267 | do_addralign() const |
| 268 | { return Output_data::default_alignment(this->size_); } |
| 269 | |
| 270 | // Set the address and offset--we only implement this for error |
| 271 | // checking. |
| 272 | void |
| 273 | do_set_address(uint64_t, off_t off) const |
| 274 | { gold_assert(off == 0); } |
| 275 | |
| 276 | private: |
| 277 | // Write the data to the file with the right size and endianness. |
| 278 | template<int size, bool big_endian> |
| 279 | void |
| 280 | do_sized_write(Output_file*); |
| 281 | |
| 282 | int size_; |
| 283 | bool big_endian_; |
| 284 | const General_options& options_; |
| 285 | const Target* target_; |
| 286 | const Symbol_table* symtab_; |
| 287 | const Output_segment_headers* segment_header_; |
| 288 | const Output_section_headers* section_header_; |
| 289 | const Output_section* shstrtab_; |
| 290 | }; |
| 291 | |
| 292 | // Output sections are mainly comprised of input sections. However, |
| 293 | // there are cases where we have data to write out which is not in an |
| 294 | // input section. Output_section_data is used in such cases. This is |
| 295 | // an abstract base class. |
| 296 | |
| 297 | class Output_section_data : public Output_data |
| 298 | { |
| 299 | public: |
| 300 | Output_section_data(off_t data_size, uint64_t addralign) |
| 301 | : Output_data(data_size), output_section_(NULL), addralign_(addralign) |
| 302 | { } |
| 303 | |
| 304 | Output_section_data(uint64_t addralign) |
| 305 | : Output_data(0), output_section_(NULL), addralign_(addralign) |
| 306 | { } |
| 307 | |
| 308 | // Return the output section. |
| 309 | const Output_section* |
| 310 | output_section() const |
| 311 | { return this->output_section_; } |
| 312 | |
| 313 | // Record the output section. |
| 314 | void |
| 315 | set_output_section(Output_section* os); |
| 316 | |
| 317 | protected: |
| 318 | // The child class must implement do_write. |
| 319 | |
| 320 | // The child class may implement specific adjustments to the output |
| 321 | // section. |
| 322 | virtual void |
| 323 | do_adjust_output_section(Output_section*) |
| 324 | { } |
| 325 | |
| 326 | // Return the required alignment. |
| 327 | uint64_t |
| 328 | do_addralign() const |
| 329 | { return this->addralign_; } |
| 330 | |
| 331 | // Return the section index of the output section. |
| 332 | unsigned int |
| 333 | do_out_shndx() const; |
| 334 | |
| 335 | // Set the alignment. |
| 336 | void |
| 337 | set_addralign(uint64_t addralign) |
| 338 | { this->addralign_ = addralign; } |
| 339 | |
| 340 | private: |
| 341 | // The output section for this section. |
| 342 | const Output_section* output_section_; |
| 343 | // The required alignment. |
| 344 | uint64_t addralign_; |
| 345 | }; |
| 346 | |
| 347 | // A simple case of Output_data in which we have constant data to |
| 348 | // output. |
| 349 | |
| 350 | class Output_data_const : public Output_section_data |
| 351 | { |
| 352 | public: |
| 353 | Output_data_const(const std::string& data, uint64_t addralign) |
| 354 | : Output_section_data(data.size(), addralign), data_(data) |
| 355 | { } |
| 356 | |
| 357 | Output_data_const(const char* p, off_t len, uint64_t addralign) |
| 358 | : Output_section_data(len, addralign), data_(p, len) |
| 359 | { } |
| 360 | |
| 361 | Output_data_const(const unsigned char* p, off_t len, uint64_t addralign) |
| 362 | : Output_section_data(len, addralign), |
| 363 | data_(reinterpret_cast<const char*>(p), len) |
| 364 | { } |
| 365 | |
| 366 | // Add more data. |
| 367 | void |
| 368 | add_data(const std::string& add) |
| 369 | { |
| 370 | this->data_.append(add); |
| 371 | this->set_data_size(this->data_.size()); |
| 372 | } |
| 373 | |
| 374 | // Write the data to the output file. |
| 375 | void |
| 376 | do_write(Output_file*); |
| 377 | |
| 378 | private: |
| 379 | std::string data_; |
| 380 | }; |
| 381 | |
| 382 | // Another version of Output_data with constant data, in which the |
| 383 | // buffer is allocated by the caller. |
| 384 | |
| 385 | class Output_data_const_buffer : public Output_section_data |
| 386 | { |
| 387 | public: |
| 388 | Output_data_const_buffer(const unsigned char* p, off_t len, |
| 389 | uint64_t addralign) |
| 390 | : Output_section_data(len, addralign), p_(p) |
| 391 | { } |
| 392 | |
| 393 | // Write the data the output file. |
| 394 | void |
| 395 | do_write(Output_file*); |
| 396 | |
| 397 | private: |
| 398 | const unsigned char* p_; |
| 399 | }; |
| 400 | |
| 401 | // A place holder for data written out via some other mechanism. |
| 402 | |
| 403 | class Output_data_space : public Output_section_data |
| 404 | { |
| 405 | public: |
| 406 | Output_data_space(off_t data_size, uint64_t addralign) |
| 407 | : Output_section_data(data_size, addralign) |
| 408 | { } |
| 409 | |
| 410 | explicit Output_data_space(uint64_t addralign) |
| 411 | : Output_section_data(addralign) |
| 412 | { } |
| 413 | |
| 414 | // Set the size. |
| 415 | void |
| 416 | set_space_size(off_t space_size) |
| 417 | { this->set_data_size(space_size); } |
| 418 | |
| 419 | // Set the alignment. |
| 420 | void |
| 421 | set_space_alignment(uint64_t align) |
| 422 | { this->set_addralign(align); } |
| 423 | |
| 424 | // Write out the data--this must be handled elsewhere. |
| 425 | void |
| 426 | do_write(Output_file*) |
| 427 | { } |
| 428 | }; |
| 429 | |
| 430 | // A string table which goes into an output section. |
| 431 | |
| 432 | class Output_data_strtab : public Output_section_data |
| 433 | { |
| 434 | public: |
| 435 | Output_data_strtab(Stringpool* strtab) |
| 436 | : Output_section_data(1), strtab_(strtab) |
| 437 | { } |
| 438 | |
| 439 | // This is called to set the address and file offset. Here we make |
| 440 | // sure that the Stringpool is finalized. |
| 441 | void |
| 442 | do_set_address(uint64_t, off_t); |
| 443 | |
| 444 | // Write out the data. |
| 445 | void |
| 446 | do_write(Output_file*); |
| 447 | |
| 448 | private: |
| 449 | Stringpool* strtab_; |
| 450 | }; |
| 451 | |
| 452 | // This POD class is used to represent a single reloc in the output |
| 453 | // file. This could be a private class within Output_data_reloc, but |
| 454 | // the templatization is complex enough that I broke it out into a |
| 455 | // separate class. The class is templatized on either elfcpp::SHT_REL |
| 456 | // or elfcpp::SHT_RELA, and also on whether this is a dynamic |
| 457 | // relocation or an ordinary relocation. |
| 458 | |
| 459 | // A relocation can be against a global symbol, a local symbol, an |
| 460 | // output section, or the undefined symbol at index 0. We represent |
| 461 | // the latter by using a NULL global symbol. |
| 462 | |
| 463 | template<int sh_type, bool dynamic, int size, bool big_endian> |
| 464 | class Output_reloc; |
| 465 | |
| 466 | template<bool dynamic, int size, bool big_endian> |
| 467 | class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> |
| 468 | { |
| 469 | public: |
| 470 | typedef typename elfcpp::Elf_types<size>::Elf_Addr Address; |
| 471 | |
| 472 | // An uninitialized entry. We need this because we want to put |
| 473 | // instances of this class into an STL container. |
| 474 | Output_reloc() |
| 475 | : local_sym_index_(INVALID_CODE) |
| 476 | { } |
| 477 | |
| 478 | // A reloc against a global symbol. |
| 479 | |
| 480 | Output_reloc(Symbol* gsym, unsigned int type, Output_data* od, |
| 481 | Address address) |
| 482 | : address_(address), local_sym_index_(GSYM_CODE), type_(type), |
| 483 | shndx_(INVALID_CODE) |
| 484 | { |
| 485 | this->u1_.gsym = gsym; |
| 486 | this->u2_.od = od; |
| 487 | } |
| 488 | |
| 489 | Output_reloc(Symbol* gsym, unsigned int type, Relobj* relobj, |
| 490 | unsigned int shndx, Address address) |
| 491 | : address_(address), local_sym_index_(GSYM_CODE), type_(type), |
| 492 | shndx_(shndx) |
| 493 | { |
| 494 | gold_assert(shndx != INVALID_CODE); |
| 495 | this->u1_.gsym = gsym; |
| 496 | this->u2_.relobj = relobj; |
| 497 | } |
| 498 | |
| 499 | // A reloc against a local symbol. |
| 500 | |
| 501 | Output_reloc(Sized_relobj<size, big_endian>* relobj, |
| 502 | unsigned int local_sym_index, |
| 503 | unsigned int type, |
| 504 | Output_data* od, |
| 505 | Address address) |
| 506 | : address_(address), local_sym_index_(local_sym_index), type_(type), |
| 507 | shndx_(INVALID_CODE) |
| 508 | { |
| 509 | gold_assert(local_sym_index != GSYM_CODE |
| 510 | && local_sym_index != INVALID_CODE); |
| 511 | this->u1_.relobj = relobj; |
| 512 | this->u2_.od = od; |
| 513 | } |
| 514 | |
| 515 | Output_reloc(Sized_relobj<size, big_endian>* relobj, |
| 516 | unsigned int local_sym_index, |
| 517 | unsigned int type, |
| 518 | unsigned int shndx, |
| 519 | Address address) |
| 520 | : address_(address), local_sym_index_(local_sym_index), type_(type), |
| 521 | shndx_(shndx) |
| 522 | { |
| 523 | gold_assert(local_sym_index != GSYM_CODE |
| 524 | && local_sym_index != INVALID_CODE); |
| 525 | gold_assert(shndx != INVALID_CODE); |
| 526 | this->u1_.relobj = relobj; |
| 527 | this->u2_.relobj = relobj; |
| 528 | } |
| 529 | |
| 530 | // A reloc against the STT_SECTION symbol of an output section. |
| 531 | |
| 532 | Output_reloc(Output_section* os, unsigned int type, Output_data* od, |
| 533 | Address address) |
| 534 | : address_(address), local_sym_index_(SECTION_CODE), type_(type), |
| 535 | shndx_(INVALID_CODE) |
| 536 | { |
| 537 | this->u1_.os = os; |
| 538 | this->u2_.od = od; |
| 539 | } |
| 540 | |
| 541 | Output_reloc(Output_section* os, unsigned int type, Relobj* relobj, |
| 542 | unsigned int shndx, Address address) |
| 543 | : address_(address), local_sym_index_(SECTION_CODE), type_(type), |
| 544 | shndx_(shndx) |
| 545 | { |
| 546 | gold_assert(shndx != INVALID_CODE); |
| 547 | this->u1_.os = os; |
| 548 | this->u2_.relobj = relobj; |
| 549 | } |
| 550 | |
| 551 | // Write the reloc entry to an output view. |
| 552 | void |
| 553 | write(unsigned char* pov) const; |
| 554 | |
| 555 | // Write the offset and info fields to Write_rel. |
| 556 | template<typename Write_rel> |
| 557 | void write_rel(Write_rel*) const; |
| 558 | |
| 559 | private: |
| 560 | // Return the symbol index. We can't do a double template |
| 561 | // specialization, so we do a secondary template here. |
| 562 | unsigned int |
| 563 | get_symbol_index() const; |
| 564 | |
| 565 | // Codes for local_sym_index_. |
| 566 | enum |
| 567 | { |
| 568 | // Global symbol. |
| 569 | GSYM_CODE = -1U, |
| 570 | // Output section. |
| 571 | SECTION_CODE = -2U, |
| 572 | // Invalid uninitialized entry. |
| 573 | INVALID_CODE = -3U |
| 574 | }; |
| 575 | |
| 576 | union |
| 577 | { |
| 578 | // For a local symbol, the object. We will never generate a |
| 579 | // relocation against a local symbol in a dynamic object; that |
| 580 | // doesn't make sense. And our callers will always be |
| 581 | // templatized, so we use Sized_relobj here. |
| 582 | Sized_relobj<size, big_endian>* relobj; |
| 583 | // For a global symbol, the symbol. If this is NULL, it indicates |
| 584 | // a relocation against the undefined 0 symbol. |
| 585 | Symbol* gsym; |
| 586 | // For a relocation against an output section, the output section. |
| 587 | Output_section* os; |
| 588 | } u1_; |
| 589 | union |
| 590 | { |
| 591 | // If shndx_ is not INVALID CODE, the object which holds the input |
| 592 | // section being used to specify the reloc address. |
| 593 | Relobj* relobj; |
| 594 | // If shndx_ is INVALID_CODE, the output data being used to |
| 595 | // specify the reloc address. This may be NULL if the reloc |
| 596 | // address is absolute. |
| 597 | Output_data* od; |
| 598 | } u2_; |
| 599 | // The address offset within the input section or the Output_data. |
| 600 | Address address_; |
| 601 | // For a local symbol, the local symbol index. This is GSYM_CODE |
| 602 | // for a global symbol, or INVALID_CODE for an uninitialized value. |
| 603 | unsigned int local_sym_index_; |
| 604 | // The reloc type--a processor specific code. |
| 605 | unsigned int type_; |
| 606 | // If the reloc address is an input section in an object, the |
| 607 | // section index. This is INVALID_CODE if the reloc address is |
| 608 | // specified in some other way. |
| 609 | unsigned int shndx_; |
| 610 | }; |
| 611 | |
| 612 | // The SHT_RELA version of Output_reloc<>. This is just derived from |
| 613 | // the SHT_REL version of Output_reloc, but it adds an addend. |
| 614 | |
| 615 | template<bool dynamic, int size, bool big_endian> |
| 616 | class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> |
| 617 | { |
| 618 | public: |
| 619 | typedef typename elfcpp::Elf_types<size>::Elf_Addr Address; |
| 620 | typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend; |
| 621 | |
| 622 | // An uninitialized entry. |
| 623 | Output_reloc() |
| 624 | : rel_() |
| 625 | { } |
| 626 | |
| 627 | // A reloc against a global symbol. |
| 628 | |
| 629 | Output_reloc(Symbol* gsym, unsigned int type, Output_data* od, |
| 630 | Address address, Addend addend) |
| 631 | : rel_(gsym, type, od, address), addend_(addend) |
| 632 | { } |
| 633 | |
| 634 | Output_reloc(Symbol* gsym, unsigned int type, Relobj* relobj, |
| 635 | unsigned int shndx, Address address, Addend addend) |
| 636 | : rel_(gsym, type, relobj, shndx, address), addend_(addend) |
| 637 | { } |
| 638 | |
| 639 | // A reloc against a local symbol. |
| 640 | |
| 641 | Output_reloc(Sized_relobj<size, big_endian>* relobj, |
| 642 | unsigned int local_sym_index, |
| 643 | unsigned int type, Output_data* od, Address address, |
| 644 | Addend addend) |
| 645 | : rel_(relobj, local_sym_index, type, od, address), addend_(addend) |
| 646 | { } |
| 647 | |
| 648 | Output_reloc(Sized_relobj<size, big_endian>* relobj, |
| 649 | unsigned int local_sym_index, |
| 650 | unsigned int type, |
| 651 | unsigned int shndx, |
| 652 | Address address, |
| 653 | Addend addend) |
| 654 | : rel_(relobj, local_sym_index, type, shndx, address), |
| 655 | addend_(addend) |
| 656 | { } |
| 657 | |
| 658 | // A reloc against the STT_SECTION symbol of an output section. |
| 659 | |
| 660 | Output_reloc(Output_section* os, unsigned int type, Output_data* od, |
| 661 | Address address, Addend addend) |
| 662 | : rel_(os, type, od, address), addend_(addend) |
| 663 | { } |
| 664 | |
| 665 | Output_reloc(Output_section* os, unsigned int type, Relobj* relobj, |
| 666 | unsigned int shndx, Address address, Addend addend) |
| 667 | : rel_(os, type, relobj, shndx, address), addend_(addend) |
| 668 | { } |
| 669 | |
| 670 | // Write the reloc entry to an output view. |
| 671 | void |
| 672 | write(unsigned char* pov) const; |
| 673 | |
| 674 | private: |
| 675 | // The basic reloc. |
| 676 | Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> rel_; |
| 677 | // The addend. |
| 678 | Addend addend_; |
| 679 | }; |
| 680 | |
| 681 | // Output_data_reloc is used to manage a section containing relocs. |
| 682 | // SH_TYPE is either elfcpp::SHT_REL or elfcpp::SHT_RELA. DYNAMIC |
| 683 | // indicates whether this is a dynamic relocation or a normal |
| 684 | // relocation. Output_data_reloc_base is a base class. |
| 685 | // Output_data_reloc is the real class, which we specialize based on |
| 686 | // the reloc type. |
| 687 | |
| 688 | template<int sh_type, bool dynamic, int size, bool big_endian> |
| 689 | class Output_data_reloc_base : public Output_section_data |
| 690 | { |
| 691 | public: |
| 692 | typedef Output_reloc<sh_type, dynamic, size, big_endian> Output_reloc_type; |
| 693 | typedef typename Output_reloc_type::Address Address; |
| 694 | static const int reloc_size = |
| 695 | Reloc_types<sh_type, size, big_endian>::reloc_size; |
| 696 | |
| 697 | // Construct the section. |
| 698 | Output_data_reloc_base() |
| 699 | : Output_section_data(Output_data::default_alignment(size)) |
| 700 | { } |
| 701 | |
| 702 | // Write out the data. |
| 703 | void |
| 704 | do_write(Output_file*); |
| 705 | |
| 706 | protected: |
| 707 | // Set the entry size and the link. |
| 708 | void |
| 709 | do_adjust_output_section(Output_section *os); |
| 710 | |
| 711 | // Add a relocation entry. |
| 712 | void |
| 713 | add(const Output_reloc_type& reloc) |
| 714 | { |
| 715 | this->relocs_.push_back(reloc); |
| 716 | this->set_data_size(this->relocs_.size() * reloc_size); |
| 717 | } |
| 718 | |
| 719 | private: |
| 720 | typedef std::vector<Output_reloc_type> Relocs; |
| 721 | |
| 722 | Relocs relocs_; |
| 723 | }; |
| 724 | |
| 725 | // The class which callers actually create. |
| 726 | |
| 727 | template<int sh_type, bool dynamic, int size, bool big_endian> |
| 728 | class Output_data_reloc; |
| 729 | |
| 730 | // The SHT_REL version of Output_data_reloc. |
| 731 | |
| 732 | template<bool dynamic, int size, bool big_endian> |
| 733 | class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> |
| 734 | : public Output_data_reloc_base<elfcpp::SHT_REL, dynamic, size, big_endian> |
| 735 | { |
| 736 | private: |
| 737 | typedef Output_data_reloc_base<elfcpp::SHT_REL, dynamic, size, |
| 738 | big_endian> Base; |
| 739 | |
| 740 | public: |
| 741 | typedef typename Base::Output_reloc_type Output_reloc_type; |
| 742 | typedef typename Output_reloc_type::Address Address; |
| 743 | |
| 744 | Output_data_reloc() |
| 745 | : Output_data_reloc_base<elfcpp::SHT_REL, dynamic, size, big_endian>() |
| 746 | { } |
| 747 | |
| 748 | // Add a reloc against a global symbol. |
| 749 | |
| 750 | void |
| 751 | add_global(Symbol* gsym, unsigned int type, Output_data* od, Address address) |
| 752 | { this->add(Output_reloc_type(gsym, type, od, address)); } |
| 753 | |
| 754 | void |
| 755 | add_global(Symbol* gsym, unsigned int type, Relobj* relobj, |
| 756 | unsigned int shndx, Address address) |
| 757 | { this->add(Output_reloc_type(gsym, type, relobj, shndx, address)); } |
| 758 | |
| 759 | // Add a reloc against a local symbol. |
| 760 | |
| 761 | void |
| 762 | add_local(Sized_relobj<size, big_endian>* relobj, |
| 763 | unsigned int local_sym_index, unsigned int type, |
| 764 | Output_data* od, Address address) |
| 765 | { this->add(Output_reloc_type(relobj, local_sym_index, type, od, address)); } |
| 766 | |
| 767 | void |
| 768 | add_local(Sized_relobj<size, big_endian>* relobj, |
| 769 | unsigned int local_sym_index, unsigned int type, |
| 770 | unsigned int shndx, Address address) |
| 771 | { this->add(Output_reloc_type(relobj, local_sym_index, type, shndx, |
| 772 | address)); } |
| 773 | |
| 774 | |
| 775 | // A reloc against the STT_SECTION symbol of an output section. |
| 776 | |
| 777 | void |
| 778 | add_output_section(Output_section* os, unsigned int type, |
| 779 | Output_data* od, Address address) |
| 780 | { this->add(Output_reloc_type(os, type, od, address)); } |
| 781 | |
| 782 | void |
| 783 | add_output_section(Output_section* os, unsigned int type, |
| 784 | Relobj* relobj, unsigned int shndx, Address address) |
| 785 | { this->add(Output_reloc_type(os, type, relobj, shndx, address)); } |
| 786 | }; |
| 787 | |
| 788 | // The SHT_RELA version of Output_data_reloc. |
| 789 | |
| 790 | template<bool dynamic, int size, bool big_endian> |
| 791 | class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian> |
| 792 | : public Output_data_reloc_base<elfcpp::SHT_RELA, dynamic, size, big_endian> |
| 793 | { |
| 794 | private: |
| 795 | typedef Output_data_reloc_base<elfcpp::SHT_RELA, dynamic, size, |
| 796 | big_endian> Base; |
| 797 | |
| 798 | public: |
| 799 | typedef typename Base::Output_reloc_type Output_reloc_type; |
| 800 | typedef typename Output_reloc_type::Address Address; |
| 801 | typedef typename Output_reloc_type::Addend Addend; |
| 802 | |
| 803 | Output_data_reloc() |
| 804 | : Output_data_reloc_base<elfcpp::SHT_RELA, dynamic, size, big_endian>() |
| 805 | { } |
| 806 | |
| 807 | // Add a reloc against a global symbol. |
| 808 | |
| 809 | void |
| 810 | add_global(Symbol* gsym, unsigned int type, Output_data* od, |
| 811 | Address address, Addend addend) |
| 812 | { this->add(Output_reloc_type(gsym, type, od, address, addend)); } |
| 813 | |
| 814 | void |
| 815 | add_global(Symbol* gsym, unsigned int type, Relobj* relobj, |
| 816 | unsigned int shndx, Address address, Addend addend) |
| 817 | { this->add(Output_reloc_type(gsym, type, relobj, shndx, address, addend)); } |
| 818 | |
| 819 | // Add a reloc against a local symbol. |
| 820 | |
| 821 | void |
| 822 | add_local(Sized_relobj<size, big_endian>* relobj, |
| 823 | unsigned int local_sym_index, unsigned int type, |
| 824 | Output_data* od, Address address, Addend addend) |
| 825 | { |
| 826 | this->add(Output_reloc_type(relobj, local_sym_index, type, od, address, |
| 827 | addend)); |
| 828 | } |
| 829 | |
| 830 | void |
| 831 | add_local(Sized_relobj<size, big_endian>* relobj, |
| 832 | unsigned int local_sym_index, unsigned int type, |
| 833 | unsigned int shndx, Address address, Addend addend) |
| 834 | { |
| 835 | this->add(Output_reloc_type(relobj, local_sym_index, type, shndx, address, |
| 836 | addend)); |
| 837 | } |
| 838 | |
| 839 | // A reloc against the STT_SECTION symbol of an output section. |
| 840 | |
| 841 | void |
| 842 | add_output_section(Output_section* os, unsigned int type, Output_data* od, |
| 843 | Address address, Addend addend) |
| 844 | { this->add(Output_reloc_type(os, type, od, address, addend)); } |
| 845 | |
| 846 | void |
| 847 | add_output_section(Output_section* os, unsigned int type, Relobj* relobj, |
| 848 | unsigned int shndx, Address address, Addend addend) |
| 849 | { this->add(Output_reloc_type(os, type, relobj, shndx, address, addend)); } |
| 850 | }; |
| 851 | |
| 852 | // Output_data_got is used to manage a GOT. Each entry in the GOT is |
| 853 | // for one symbol--either a global symbol or a local symbol in an |
| 854 | // object. The target specific code adds entries to the GOT as |
| 855 | // needed. |
| 856 | |
| 857 | template<int size, bool big_endian> |
| 858 | class Output_data_got : public Output_section_data |
| 859 | { |
| 860 | public: |
| 861 | typedef typename elfcpp::Elf_types<size>::Elf_Addr Valtype; |
| 862 | |
| 863 | Output_data_got(const General_options* options) |
| 864 | : Output_section_data(Output_data::default_alignment(size)), |
| 865 | options_(options), entries_() |
| 866 | { } |
| 867 | |
| 868 | // Add an entry for a global symbol to the GOT. Return true if this |
| 869 | // is a new GOT entry, false if the symbol was already in the GOT. |
| 870 | bool |
| 871 | add_global(Symbol* gsym); |
| 872 | |
| 873 | // Add an entry for a local symbol to the GOT. This returns the |
| 874 | // offset of the new entry from the start of the GOT. |
| 875 | unsigned int |
| 876 | add_local(Object* object, unsigned int sym_index) |
| 877 | { |
| 878 | this->entries_.push_back(Got_entry(object, sym_index)); |
| 879 | this->set_got_size(); |
| 880 | return this->last_got_offset(); |
| 881 | } |
| 882 | |
| 883 | // Add a constant to the GOT. This returns the offset of the new |
| 884 | // entry from the start of the GOT. |
| 885 | unsigned int |
| 886 | add_constant(Valtype constant) |
| 887 | { |
| 888 | this->entries_.push_back(Got_entry(constant)); |
| 889 | this->set_got_size(); |
| 890 | return this->last_got_offset(); |
| 891 | } |
| 892 | |
| 893 | // Write out the GOT table. |
| 894 | void |
| 895 | do_write(Output_file*); |
| 896 | |
| 897 | private: |
| 898 | // This POD class holds a single GOT entry. |
| 899 | class Got_entry |
| 900 | { |
| 901 | public: |
| 902 | // Create a zero entry. |
| 903 | Got_entry() |
| 904 | : local_sym_index_(CONSTANT_CODE) |
| 905 | { this->u_.constant = 0; } |
| 906 | |
| 907 | // Create a global symbol entry. |
| 908 | explicit Got_entry(Symbol* gsym) |
| 909 | : local_sym_index_(GSYM_CODE) |
| 910 | { this->u_.gsym = gsym; } |
| 911 | |
| 912 | // Create a local symbol entry. |
| 913 | Got_entry(Object* object, unsigned int local_sym_index) |
| 914 | : local_sym_index_(local_sym_index) |
| 915 | { |
| 916 | gold_assert(local_sym_index != GSYM_CODE |
| 917 | && local_sym_index != CONSTANT_CODE); |
| 918 | this->u_.object = object; |
| 919 | } |
| 920 | |
| 921 | // Create a constant entry. The constant is a host value--it will |
| 922 | // be swapped, if necessary, when it is written out. |
| 923 | explicit Got_entry(Valtype constant) |
| 924 | : local_sym_index_(CONSTANT_CODE) |
| 925 | { this->u_.constant = constant; } |
| 926 | |
| 927 | // Write the GOT entry to an output view. |
| 928 | void |
| 929 | write(const General_options*, unsigned char* pov) const; |
| 930 | |
| 931 | private: |
| 932 | enum |
| 933 | { |
| 934 | GSYM_CODE = -1U, |
| 935 | CONSTANT_CODE = -2U |
| 936 | }; |
| 937 | |
| 938 | union |
| 939 | { |
| 940 | // For a local symbol, the object. |
| 941 | Object* object; |
| 942 | // For a global symbol, the symbol. |
| 943 | Symbol* gsym; |
| 944 | // For a constant, the constant. |
| 945 | Valtype constant; |
| 946 | } u_; |
| 947 | // For a local symbol, the local symbol index. This is GSYM_CODE |
| 948 | // for a global symbol, or CONSTANT_CODE for a constant. |
| 949 | unsigned int local_sym_index_; |
| 950 | }; |
| 951 | |
| 952 | typedef std::vector<Got_entry> Got_entries; |
| 953 | |
| 954 | // Return the offset into the GOT of GOT entry I. |
| 955 | unsigned int |
| 956 | got_offset(unsigned int i) const |
| 957 | { return i * (size / 8); } |
| 958 | |
| 959 | // Return the offset into the GOT of the last entry added. |
| 960 | unsigned int |
| 961 | last_got_offset() const |
| 962 | { return this->got_offset(this->entries_.size() - 1); } |
| 963 | |
| 964 | // Set the size of the section. |
| 965 | void |
| 966 | set_got_size() |
| 967 | { this->set_data_size(this->got_offset(this->entries_.size())); } |
| 968 | |
| 969 | // Options. |
| 970 | const General_options* options_; |
| 971 | // The list of GOT entries. |
| 972 | Got_entries entries_; |
| 973 | }; |
| 974 | |
| 975 | // Output_data_dynamic is used to hold the data in SHT_DYNAMIC |
| 976 | // section. |
| 977 | |
| 978 | class Output_data_dynamic : public Output_section_data |
| 979 | { |
| 980 | public: |
| 981 | Output_data_dynamic(const Target* target, Stringpool* pool) |
| 982 | : Output_section_data(Output_data::default_alignment(target->get_size())), |
| 983 | target_(target), entries_(), pool_(pool) |
| 984 | { } |
| 985 | |
| 986 | // Add a new dynamic entry with a fixed numeric value. |
| 987 | void |
| 988 | add_constant(elfcpp::DT tag, unsigned int val) |
| 989 | { this->add_entry(Dynamic_entry(tag, val)); } |
| 990 | |
| 991 | // Add a new dynamic entry with the address of output data. |
| 992 | void |
| 993 | add_section_address(elfcpp::DT tag, const Output_data* od) |
| 994 | { this->add_entry(Dynamic_entry(tag, od, false)); } |
| 995 | |
| 996 | // Add a new dynamic entry with the size of output data. |
| 997 | void |
| 998 | add_section_size(elfcpp::DT tag, const Output_data* od) |
| 999 | { this->add_entry(Dynamic_entry(tag, od, true)); } |
| 1000 | |
| 1001 | // Add a new dynamic entry with the address of a symbol. |
| 1002 | void |
| 1003 | add_symbol(elfcpp::DT tag, const Symbol* sym) |
| 1004 | { this->add_entry(Dynamic_entry(tag, sym)); } |
| 1005 | |
| 1006 | // Add a new dynamic entry with a string. |
| 1007 | void |
| 1008 | add_string(elfcpp::DT tag, const char* str) |
| 1009 | { this->add_entry(Dynamic_entry(tag, this->pool_->add(str, NULL))); } |
| 1010 | |
| 1011 | // Set the final data size. |
| 1012 | void |
| 1013 | do_set_address(uint64_t, off_t); |
| 1014 | |
| 1015 | // Write out the dynamic entries. |
| 1016 | void |
| 1017 | do_write(Output_file*); |
| 1018 | |
| 1019 | protected: |
| 1020 | // Adjust the output section to set the entry size. |
| 1021 | void |
| 1022 | do_adjust_output_section(Output_section*); |
| 1023 | |
| 1024 | private: |
| 1025 | // This POD class holds a single dynamic entry. |
| 1026 | class Dynamic_entry |
| 1027 | { |
| 1028 | public: |
| 1029 | // Create an entry with a fixed numeric value. |
| 1030 | Dynamic_entry(elfcpp::DT tag, unsigned int val) |
| 1031 | : tag_(tag), classification_(DYNAMIC_NUMBER) |
| 1032 | { this->u_.val = val; } |
| 1033 | |
| 1034 | // Create an entry with the size or address of a section. |
| 1035 | Dynamic_entry(elfcpp::DT tag, const Output_data* od, bool section_size) |
| 1036 | : tag_(tag), |
| 1037 | classification_(section_size |
| 1038 | ? DYNAMIC_SECTION_SIZE |
| 1039 | : DYNAMIC_SECTION_ADDRESS) |
| 1040 | { this->u_.od = od; } |
| 1041 | |
| 1042 | // Create an entry with the address of a symbol. |
| 1043 | Dynamic_entry(elfcpp::DT tag, const Symbol* sym) |
| 1044 | : tag_(tag), classification_(DYNAMIC_SYMBOL) |
| 1045 | { this->u_.sym = sym; } |
| 1046 | |
| 1047 | // Create an entry with a string. |
| 1048 | Dynamic_entry(elfcpp::DT tag, const char* str) |
| 1049 | : tag_(tag), classification_(DYNAMIC_STRING) |
| 1050 | { this->u_.str = str; } |
| 1051 | |
| 1052 | // Write the dynamic entry to an output view. |
| 1053 | template<int size, bool big_endian> |
| 1054 | void |
| 1055 | write(unsigned char* pov, const Stringpool* ACCEPT_SIZE_ENDIAN) const; |
| 1056 | |
| 1057 | private: |
| 1058 | enum Classification |
| 1059 | { |
| 1060 | // Number. |
| 1061 | DYNAMIC_NUMBER, |
| 1062 | // Section address. |
| 1063 | DYNAMIC_SECTION_ADDRESS, |
| 1064 | // Section size. |
| 1065 | DYNAMIC_SECTION_SIZE, |
| 1066 | // Symbol adress. |
| 1067 | DYNAMIC_SYMBOL, |
| 1068 | // String. |
| 1069 | DYNAMIC_STRING |
| 1070 | }; |
| 1071 | |
| 1072 | union |
| 1073 | { |
| 1074 | // For DYNAMIC_NUMBER. |
| 1075 | unsigned int val; |
| 1076 | // For DYNAMIC_SECTION_ADDRESS and DYNAMIC_SECTION_SIZE. |
| 1077 | const Output_data* od; |
| 1078 | // For DYNAMIC_SYMBOL. |
| 1079 | const Symbol* sym; |
| 1080 | // For DYNAMIC_STRING. |
| 1081 | const char* str; |
| 1082 | } u_; |
| 1083 | // The dynamic tag. |
| 1084 | elfcpp::DT tag_; |
| 1085 | // The type of entry. |
| 1086 | Classification classification_; |
| 1087 | }; |
| 1088 | |
| 1089 | // Add an entry to the list. |
| 1090 | void |
| 1091 | add_entry(const Dynamic_entry& entry) |
| 1092 | { this->entries_.push_back(entry); } |
| 1093 | |
| 1094 | // Sized version of write function. |
| 1095 | template<int size, bool big_endian> |
| 1096 | void |
| 1097 | sized_write(Output_file* of); |
| 1098 | |
| 1099 | // The type of the list of entries. |
| 1100 | typedef std::vector<Dynamic_entry> Dynamic_entries; |
| 1101 | |
| 1102 | // The target. |
| 1103 | const Target* target_; |
| 1104 | // The entries. |
| 1105 | Dynamic_entries entries_; |
| 1106 | // The pool used for strings. |
| 1107 | Stringpool* pool_; |
| 1108 | }; |
| 1109 | |
| 1110 | // An output section. We don't expect to have too many output |
| 1111 | // sections, so we don't bother to do a template on the size. |
| 1112 | |
| 1113 | class Output_section : public Output_data |
| 1114 | { |
| 1115 | public: |
| 1116 | // Create an output section, giving the name, type, and flags. |
| 1117 | Output_section(const char* name, elfcpp::Elf_Word, elfcpp::Elf_Xword, |
| 1118 | bool may_add_data); |
| 1119 | virtual ~Output_section(); |
| 1120 | |
| 1121 | // Add a new input section SHNDX, named NAME, with header SHDR, from |
| 1122 | // object OBJECT. Return the offset within the output section. |
| 1123 | template<int size, bool big_endian> |
| 1124 | off_t |
| 1125 | add_input_section(Relobj* object, unsigned int shndx, const char *name, |
| 1126 | const elfcpp::Shdr<size, big_endian>& shdr); |
| 1127 | |
| 1128 | // Add generated data ODATA to this output section. |
| 1129 | void |
| 1130 | add_output_section_data(Output_section_data* posd); |
| 1131 | |
| 1132 | // Return the section name. |
| 1133 | const char* |
| 1134 | name() const |
| 1135 | { return this->name_; } |
| 1136 | |
| 1137 | // Return the section type. |
| 1138 | elfcpp::Elf_Word |
| 1139 | type() const |
| 1140 | { return this->type_; } |
| 1141 | |
| 1142 | // Return the section flags. |
| 1143 | elfcpp::Elf_Xword |
| 1144 | flags() const |
| 1145 | { return this->flags_; } |
| 1146 | |
| 1147 | // Return the section index in the output file. |
| 1148 | unsigned int |
| 1149 | do_out_shndx() const |
| 1150 | { return this->out_shndx_; } |
| 1151 | |
| 1152 | // Set the output section index. |
| 1153 | void |
| 1154 | do_set_out_shndx(unsigned int shndx) |
| 1155 | { this->out_shndx_ = shndx; } |
| 1156 | |
| 1157 | // Return the entsize field. |
| 1158 | uint64_t |
| 1159 | entsize() const |
| 1160 | { return this->entsize_; } |
| 1161 | |
| 1162 | // Set the entsize field. |
| 1163 | void |
| 1164 | set_entsize(uint64_t v); |
| 1165 | |
| 1166 | // Set the link field to the output section index of a section. |
| 1167 | void |
| 1168 | set_link_section(const Output_data* od) |
| 1169 | { |
| 1170 | gold_assert(this->link_ == 0 |
| 1171 | && !this->should_link_to_symtab_ |
| 1172 | && !this->should_link_to_dynsym_); |
| 1173 | this->link_section_ = od; |
| 1174 | } |
| 1175 | |
| 1176 | // Set the link field to a constant. |
| 1177 | void |
| 1178 | set_link(unsigned int v) |
| 1179 | { |
| 1180 | gold_assert(this->link_section_ == NULL |
| 1181 | && !this->should_link_to_symtab_ |
| 1182 | && !this->should_link_to_dynsym_); |
| 1183 | this->link_ = v; |
| 1184 | } |
| 1185 | |
| 1186 | // Record that this section should link to the normal symbol table. |
| 1187 | void |
| 1188 | set_should_link_to_symtab() |
| 1189 | { |
| 1190 | gold_assert(this->link_section_ == NULL |
| 1191 | && this->link_ == 0 |
| 1192 | && !this->should_link_to_dynsym_); |
| 1193 | this->should_link_to_symtab_ = true; |
| 1194 | } |
| 1195 | |
| 1196 | // Record that this section should link to the dynamic symbol table. |
| 1197 | void |
| 1198 | set_should_link_to_dynsym() |
| 1199 | { |
| 1200 | gold_assert(this->link_section_ == NULL |
| 1201 | && this->link_ == 0 |
| 1202 | && !this->should_link_to_symtab_); |
| 1203 | this->should_link_to_dynsym_ = true; |
| 1204 | } |
| 1205 | |
| 1206 | // Return the info field. |
| 1207 | unsigned int |
| 1208 | info() const |
| 1209 | { |
| 1210 | gold_assert(this->info_section_ == NULL); |
| 1211 | return this->info_; |
| 1212 | } |
| 1213 | |
| 1214 | // Set the info field to the output section index of a section. |
| 1215 | void |
| 1216 | set_info_section(const Output_data* od) |
| 1217 | { |
| 1218 | gold_assert(this->info_ == 0); |
| 1219 | this->info_section_ = od; |
| 1220 | } |
| 1221 | |
| 1222 | // Set the info field to a constant. |
| 1223 | void |
| 1224 | set_info(unsigned int v) |
| 1225 | { |
| 1226 | gold_assert(this->info_section_ == NULL); |
| 1227 | this->info_ = v; |
| 1228 | } |
| 1229 | |
| 1230 | // Set the addralign field. |
| 1231 | void |
| 1232 | set_addralign(uint64_t v) |
| 1233 | { this->addralign_ = v; } |
| 1234 | |
| 1235 | // Indicate that we need a symtab index. |
| 1236 | void |
| 1237 | set_needs_symtab_index() |
| 1238 | { this->needs_symtab_index_ = true; } |
| 1239 | |
| 1240 | // Return whether we need a symtab index. |
| 1241 | bool |
| 1242 | needs_symtab_index() const |
| 1243 | { return this->needs_symtab_index_; } |
| 1244 | |
| 1245 | // Get the symtab index. |
| 1246 | unsigned int |
| 1247 | symtab_index() const |
| 1248 | { |
| 1249 | gold_assert(this->symtab_index_ != 0); |
| 1250 | return this->symtab_index_; |
| 1251 | } |
| 1252 | |
| 1253 | // Set the symtab index. |
| 1254 | void |
| 1255 | set_symtab_index(unsigned int index) |
| 1256 | { |
| 1257 | gold_assert(index != 0); |
| 1258 | this->symtab_index_ = index; |
| 1259 | } |
| 1260 | |
| 1261 | // Indicate that we need a dynsym index. |
| 1262 | void |
| 1263 | set_needs_dynsym_index() |
| 1264 | { this->needs_dynsym_index_ = true; } |
| 1265 | |
| 1266 | // Return whether we need a dynsym index. |
| 1267 | bool |
| 1268 | needs_dynsym_index() const |
| 1269 | { return this->needs_dynsym_index_; } |
| 1270 | |
| 1271 | // Get the dynsym index. |
| 1272 | unsigned int |
| 1273 | dynsym_index() const |
| 1274 | { |
| 1275 | gold_assert(this->dynsym_index_ != 0); |
| 1276 | return this->dynsym_index_; |
| 1277 | } |
| 1278 | |
| 1279 | // Set the dynsym index. |
| 1280 | void |
| 1281 | set_dynsym_index(unsigned int index) |
| 1282 | { |
| 1283 | gold_assert(index != 0); |
| 1284 | this->dynsym_index_ = index; |
| 1285 | } |
| 1286 | |
| 1287 | // Set the address of the Output_section. For a typical |
| 1288 | // Output_section, there is nothing to do, but if there are any |
| 1289 | // Output_section_data objects we need to set the final addresses |
| 1290 | // here. |
| 1291 | void |
| 1292 | do_set_address(uint64_t, off_t); |
| 1293 | |
| 1294 | // Write the data to the file. For a typical Output_section, this |
| 1295 | // does nothing: the data is written out by calling Object::Relocate |
| 1296 | // on each input object. But if there are any Output_section_data |
| 1297 | // objects we do need to write them out here. |
| 1298 | void |
| 1299 | do_write(Output_file*); |
| 1300 | |
| 1301 | // Return the address alignment--function required by parent class. |
| 1302 | uint64_t |
| 1303 | do_addralign() const |
| 1304 | { return this->addralign_; } |
| 1305 | |
| 1306 | // Return whether this is an Output_section. |
| 1307 | bool |
| 1308 | do_is_section() const |
| 1309 | { return true; } |
| 1310 | |
| 1311 | // Return whether this is a section of the specified type. |
| 1312 | bool |
| 1313 | do_is_section_type(elfcpp::Elf_Word type) const |
| 1314 | { return this->type_ == type; } |
| 1315 | |
| 1316 | // Return whether the specified section flag is set. |
| 1317 | bool |
| 1318 | do_is_section_flag_set(elfcpp::Elf_Xword flag) const |
| 1319 | { return (this->flags_ & flag) != 0; } |
| 1320 | |
| 1321 | // Write the section header into *OPHDR. |
| 1322 | template<int size, bool big_endian> |
| 1323 | void |
| 1324 | write_header(const Layout*, const Stringpool*, |
| 1325 | elfcpp::Shdr_write<size, big_endian>*) const; |
| 1326 | |
| 1327 | private: |
| 1328 | // In some cases we need to keep a list of the input sections |
| 1329 | // associated with this output section. We only need the list if we |
| 1330 | // might have to change the offsets of the input section within the |
| 1331 | // output section after we add the input section. The ordinary |
| 1332 | // input sections will be written out when we process the object |
| 1333 | // file, and as such we don't need to track them here. We do need |
| 1334 | // to track Output_section_data objects here. We store instances of |
| 1335 | // this structure in a std::vector, so it must be a POD. There can |
| 1336 | // be many instances of this structure, so we use a union to save |
| 1337 | // some space. |
| 1338 | class Input_section |
| 1339 | { |
| 1340 | public: |
| 1341 | Input_section() |
| 1342 | : shndx_(0), p2align_(0), data_size_(0) |
| 1343 | { this->u_.object = NULL; } |
| 1344 | |
| 1345 | Input_section(Relobj* object, unsigned int shndx, off_t data_size, |
| 1346 | uint64_t addralign) |
| 1347 | : shndx_(shndx), |
| 1348 | p2align_(ffsll(static_cast<long long>(addralign))), |
| 1349 | data_size_(data_size) |
| 1350 | { |
| 1351 | gold_assert(shndx != -1U); |
| 1352 | this->u_.object = object; |
| 1353 | } |
| 1354 | |
| 1355 | Input_section(Output_section_data* posd) |
| 1356 | : shndx_(-1U), |
| 1357 | p2align_(ffsll(static_cast<long long>(posd->addralign()))), |
| 1358 | data_size_(0) |
| 1359 | { this->u_.posd = posd; } |
| 1360 | |
| 1361 | // The required alignment. |
| 1362 | uint64_t |
| 1363 | addralign() const |
| 1364 | { |
| 1365 | return (this->p2align_ == 0 |
| 1366 | ? 0 |
| 1367 | : static_cast<uint64_t>(1) << (this->p2align_ - 1)); |
| 1368 | } |
| 1369 | |
| 1370 | // Return the required size. |
| 1371 | off_t |
| 1372 | data_size() const; |
| 1373 | |
| 1374 | // Set the address and file offset. This is called during |
| 1375 | // Layout::finalize. SECOFF is the file offset of the enclosing |
| 1376 | // section. |
| 1377 | void |
| 1378 | set_address(uint64_t addr, off_t off, off_t secoff); |
| 1379 | |
| 1380 | // Write out the data. This does nothing for an input section. |
| 1381 | void |
| 1382 | write(Output_file*); |
| 1383 | |
| 1384 | private: |
| 1385 | // Whether this is an input section. |
| 1386 | bool |
| 1387 | is_input_section() const |
| 1388 | { return this->shndx_ != -1U; } |
| 1389 | |
| 1390 | // For an ordinary input section, this is the section index in |
| 1391 | // the input file. For an Output_section_data, this is -1U. |
| 1392 | unsigned int shndx_; |
| 1393 | // The required alignment, stored as a power of 2. |
| 1394 | unsigned int p2align_; |
| 1395 | // For an ordinary input section, the section size. |
| 1396 | off_t data_size_; |
| 1397 | union |
| 1398 | { |
| 1399 | // If shndx_ != -1U, this points to the object which holds the |
| 1400 | // input section. |
| 1401 | Relobj* object; |
| 1402 | // If shndx_ == -1U, this is the data to write out. |
| 1403 | Output_section_data* posd; |
| 1404 | } u_; |
| 1405 | }; |
| 1406 | |
| 1407 | typedef std::vector<Input_section> Input_section_list; |
| 1408 | |
| 1409 | // Most of these fields are only valid after layout. |
| 1410 | |
| 1411 | // The name of the section. This will point into a Stringpool. |
| 1412 | const char* name_; |
| 1413 | // The section address is in the parent class. |
| 1414 | // The section alignment. |
| 1415 | uint64_t addralign_; |
| 1416 | // The section entry size. |
| 1417 | uint64_t entsize_; |
| 1418 | // The file offset is in the parent class. |
| 1419 | // Set the section link field to the index of this section. |
| 1420 | const Output_data* link_section_; |
| 1421 | // If link_section_ is NULL, this is the link field. |
| 1422 | unsigned int link_; |
| 1423 | // Set the section info field to the index of this section. |
| 1424 | const Output_data* info_section_; |
| 1425 | // If info_section_ is NULL, this is the section info field. |
| 1426 | unsigned int info_; |
| 1427 | // The section type. |
| 1428 | elfcpp::Elf_Word type_; |
| 1429 | // The section flags. |
| 1430 | elfcpp::Elf_Xword flags_; |
| 1431 | // The section index. |
| 1432 | unsigned int out_shndx_; |
| 1433 | // If there is a STT_SECTION for this output section in the normal |
| 1434 | // symbol table, this is the symbol index. This starts out as zero. |
| 1435 | // It is initialized in Layout::finalize() to be the index, or -1U |
| 1436 | // if there isn't one. |
| 1437 | unsigned int symtab_index_; |
| 1438 | // If there is a STT_SECTION for this output section in the dynamic |
| 1439 | // symbol table, this is the symbol index. This starts out as zero. |
| 1440 | // It is initialized in Layout::finalize() to be the index, or -1U |
| 1441 | // if there isn't one. |
| 1442 | unsigned int dynsym_index_; |
| 1443 | // The input sections. This will be empty in cases where we don't |
| 1444 | // need to keep track of them. |
| 1445 | Input_section_list input_sections_; |
| 1446 | // The offset of the first entry in input_sections_. |
| 1447 | off_t first_input_offset_; |
| 1448 | // Whether we permit adding data. |
| 1449 | bool may_add_data_ : 1; |
| 1450 | // Whether this output section needs a STT_SECTION symbol in the |
| 1451 | // normal symbol table. This will be true if there is a relocation |
| 1452 | // which needs it. |
| 1453 | bool needs_symtab_index_ : 1; |
| 1454 | // Whether this output section needs a STT_SECTION symbol in the |
| 1455 | // dynamic symbol table. This will be true if there is a dynamic |
| 1456 | // relocation which needs it. |
| 1457 | bool needs_dynsym_index_ : 1; |
| 1458 | // Whether the link field of this output section should point to the |
| 1459 | // normal symbol table. |
| 1460 | bool should_link_to_symtab_ : 1; |
| 1461 | // Whether the link field of this output section should point to the |
| 1462 | // dynamic symbol table. |
| 1463 | bool should_link_to_dynsym_ : 1; |
| 1464 | }; |
| 1465 | |
| 1466 | // An output segment. PT_LOAD segments are built from collections of |
| 1467 | // output sections. Other segments typically point within PT_LOAD |
| 1468 | // segments, and are built directly as needed. |
| 1469 | |
| 1470 | class Output_segment |
| 1471 | { |
| 1472 | public: |
| 1473 | // Create an output segment, specifying the type and flags. |
| 1474 | Output_segment(elfcpp::Elf_Word, elfcpp::Elf_Word); |
| 1475 | |
| 1476 | // Return the virtual address. |
| 1477 | uint64_t |
| 1478 | vaddr() const |
| 1479 | { return this->vaddr_; } |
| 1480 | |
| 1481 | // Return the physical address. |
| 1482 | uint64_t |
| 1483 | paddr() const |
| 1484 | { return this->paddr_; } |
| 1485 | |
| 1486 | // Return the segment type. |
| 1487 | elfcpp::Elf_Word |
| 1488 | type() const |
| 1489 | { return this->type_; } |
| 1490 | |
| 1491 | // Return the segment flags. |
| 1492 | elfcpp::Elf_Word |
| 1493 | flags() const |
| 1494 | { return this->flags_; } |
| 1495 | |
| 1496 | // Return the memory size. |
| 1497 | uint64_t |
| 1498 | memsz() const |
| 1499 | { return this->memsz_; } |
| 1500 | |
| 1501 | // Return the file size. |
| 1502 | off_t |
| 1503 | filesz() const |
| 1504 | { return this->filesz_; } |
| 1505 | |
| 1506 | // Return the maximum alignment of the Output_data. |
| 1507 | uint64_t |
| 1508 | addralign(); |
| 1509 | |
| 1510 | // Add an Output_section to this segment. |
| 1511 | void |
| 1512 | add_output_section(Output_section* os, elfcpp::Elf_Word seg_flags) |
| 1513 | { this->add_output_section(os, seg_flags, false); } |
| 1514 | |
| 1515 | // Add an Output_section to the start of this segment. |
| 1516 | void |
| 1517 | add_initial_output_section(Output_section* os, elfcpp::Elf_Word seg_flags) |
| 1518 | { this->add_output_section(os, seg_flags, true); } |
| 1519 | |
| 1520 | // Add an Output_data (which is not an Output_section) to the start |
| 1521 | // of this segment. |
| 1522 | void |
| 1523 | add_initial_output_data(Output_data*); |
| 1524 | |
| 1525 | // Set the address of the segment to ADDR and the offset to *POFF |
| 1526 | // (aligned if necessary), and set the addresses and offsets of all |
| 1527 | // contained output sections accordingly. Set the section indexes |
| 1528 | // of all contained output sections starting with *PSHNDX. Return |
| 1529 | // the address of the immediately following segment. Update *POFF |
| 1530 | // and *PSHNDX. This should only be called for a PT_LOAD segment. |
| 1531 | uint64_t |
| 1532 | set_section_addresses(uint64_t addr, off_t* poff, unsigned int* pshndx); |
| 1533 | |
| 1534 | // Set the offset of this segment based on the section. This should |
| 1535 | // only be called for a non-PT_LOAD segment. |
| 1536 | void |
| 1537 | set_offset(); |
| 1538 | |
| 1539 | // Return the number of output sections. |
| 1540 | unsigned int |
| 1541 | output_section_count() const; |
| 1542 | |
| 1543 | // Write the segment header into *OPHDR. |
| 1544 | template<int size, bool big_endian> |
| 1545 | void |
| 1546 | write_header(elfcpp::Phdr_write<size, big_endian>*); |
| 1547 | |
| 1548 | // Write the section headers of associated sections into V. |
| 1549 | template<int size, bool big_endian> |
| 1550 | unsigned char* |
| 1551 | write_section_headers(const Layout*, const Stringpool*, unsigned char* v, |
| 1552 | unsigned int* pshndx ACCEPT_SIZE_ENDIAN) const; |
| 1553 | |
| 1554 | private: |
| 1555 | Output_segment(const Output_segment&); |
| 1556 | Output_segment& operator=(const Output_segment&); |
| 1557 | |
| 1558 | typedef std::list<Output_data*> Output_data_list; |
| 1559 | |
| 1560 | // Add an Output_section to this segment, specifying front or back. |
| 1561 | void |
| 1562 | add_output_section(Output_section*, elfcpp::Elf_Word seg_flags, |
| 1563 | bool front); |
| 1564 | |
| 1565 | // Find the maximum alignment in an Output_data_list. |
| 1566 | static uint64_t |
| 1567 | maximum_alignment(const Output_data_list*); |
| 1568 | |
| 1569 | // Set the section addresses in an Output_data_list. |
| 1570 | uint64_t |
| 1571 | set_section_list_addresses(Output_data_list*, uint64_t addr, off_t* poff, |
| 1572 | unsigned int* pshndx); |
| 1573 | |
| 1574 | // Return the number of Output_sections in an Output_data_list. |
| 1575 | unsigned int |
| 1576 | output_section_count_list(const Output_data_list*) const; |
| 1577 | |
| 1578 | // Write the section headers in the list into V. |
| 1579 | template<int size, bool big_endian> |
| 1580 | unsigned char* |
| 1581 | write_section_headers_list(const Layout*, const Stringpool*, |
| 1582 | const Output_data_list*, unsigned char* v, |
| 1583 | unsigned int* pshdx ACCEPT_SIZE_ENDIAN) const; |
| 1584 | |
| 1585 | // The list of output data with contents attached to this segment. |
| 1586 | Output_data_list output_data_; |
| 1587 | // The list of output data without contents attached to this segment. |
| 1588 | Output_data_list output_bss_; |
| 1589 | // The segment virtual address. |
| 1590 | uint64_t vaddr_; |
| 1591 | // The segment physical address. |
| 1592 | uint64_t paddr_; |
| 1593 | // The size of the segment in memory. |
| 1594 | uint64_t memsz_; |
| 1595 | // The segment alignment. |
| 1596 | uint64_t align_; |
| 1597 | // The offset of the segment data within the file. |
| 1598 | off_t offset_; |
| 1599 | // The size of the segment data in the file. |
| 1600 | off_t filesz_; |
| 1601 | // The segment type; |
| 1602 | elfcpp::Elf_Word type_; |
| 1603 | // The segment flags. |
| 1604 | elfcpp::Elf_Word flags_; |
| 1605 | // Whether we have set align_. |
| 1606 | bool is_align_known_; |
| 1607 | }; |
| 1608 | |
| 1609 | // This class represents the output file. |
| 1610 | |
| 1611 | class Output_file |
| 1612 | { |
| 1613 | public: |
| 1614 | Output_file(const General_options& options); |
| 1615 | |
| 1616 | // Open the output file. FILE_SIZE is the final size of the file. |
| 1617 | void |
| 1618 | open(off_t file_size); |
| 1619 | |
| 1620 | // Close the output file and make sure there are no error. |
| 1621 | void |
| 1622 | close(); |
| 1623 | |
| 1624 | // We currently always use mmap which makes the view handling quite |
| 1625 | // simple. In the future we may support other approaches. |
| 1626 | |
| 1627 | // Write data to the output file. |
| 1628 | void |
| 1629 | write(off_t offset, const void* data, off_t len) |
| 1630 | { memcpy(this->base_ + offset, data, len); } |
| 1631 | |
| 1632 | // Get a buffer to use to write to the file, given the offset into |
| 1633 | // the file and the size. |
| 1634 | unsigned char* |
| 1635 | get_output_view(off_t start, off_t size) |
| 1636 | { |
| 1637 | gold_assert(start >= 0 && size >= 0 && start + size <= this->file_size_); |
| 1638 | return this->base_ + start; |
| 1639 | } |
| 1640 | |
| 1641 | // VIEW must have been returned by get_output_view. Write the |
| 1642 | // buffer to the file, passing in the offset and the size. |
| 1643 | void |
| 1644 | write_output_view(off_t, off_t, unsigned char*) |
| 1645 | { } |
| 1646 | |
| 1647 | private: |
| 1648 | // General options. |
| 1649 | const General_options& options_; |
| 1650 | // File name. |
| 1651 | const char* name_; |
| 1652 | // File descriptor. |
| 1653 | int o_; |
| 1654 | // File size. |
| 1655 | off_t file_size_; |
| 1656 | // Base of file mapped into memory. |
| 1657 | unsigned char* base_; |
| 1658 | }; |
| 1659 | |
| 1660 | } // End namespace gold. |
| 1661 | |
| 1662 | #endif // !defined(GOLD_OUTPUT_H) |