Annotation of src/external/gpl3/binutils.old/dist/gold/object.h, Revision 1.1
1.1 ! christos 1: // object.h -- support for an object file for linking in gold -*- C++ -*-
! 2:
! 3: // Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012
! 4: // Free Software Foundation, Inc.
! 5: // Written by Ian Lance Taylor <iant@google.com>.
! 6:
! 7: // This file is part of gold.
! 8:
! 9: // This program is free software; you can redistribute it and/or modify
! 10: // it under the terms of the GNU General Public License as published by
! 11: // the Free Software Foundation; either version 3 of the License, or
! 12: // (at your option) any later version.
! 13:
! 14: // This program is distributed in the hope that it will be useful,
! 15: // but WITHOUT ANY WARRANTY; without even the implied warranty of
! 16: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 17: // GNU General Public License for more details.
! 18:
! 19: // You should have received a copy of the GNU General Public License
! 20: // along with this program; if not, write to the Free Software
! 21: // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
! 22: // MA 02110-1301, USA.
! 23:
! 24: #ifndef GOLD_OBJECT_H
! 25: #define GOLD_OBJECT_H
! 26:
! 27: #include <string>
! 28: #include <vector>
! 29:
! 30: #include "elfcpp.h"
! 31: #include "elfcpp_file.h"
! 32: #include "fileread.h"
! 33: #include "target.h"
! 34: #include "archive.h"
! 35:
! 36: namespace gold
! 37: {
! 38:
! 39: class General_options;
! 40: class Task;
! 41: class Cref;
! 42: class Layout;
! 43: class Output_data;
! 44: class Output_section;
! 45: class Output_file;
! 46: class Output_symtab_xindex;
! 47: class Pluginobj;
! 48: class Dynobj;
! 49: class Object_merge_map;
! 50: class Relocatable_relocs;
! 51: struct Symbols_data;
! 52:
! 53: template<typename Stringpool_char>
! 54: class Stringpool_template;
! 55:
! 56: // Data to pass from read_symbols() to add_symbols().
! 57:
! 58: struct Read_symbols_data
! 59: {
! 60: Read_symbols_data()
! 61: : section_headers(NULL), section_names(NULL), symbols(NULL),
! 62: symbol_names(NULL), versym(NULL), verdef(NULL), verneed(NULL)
! 63: { }
! 64:
! 65: ~Read_symbols_data();
! 66:
! 67: // Section headers.
! 68: File_view* section_headers;
! 69: // Section names.
! 70: File_view* section_names;
! 71: // Size of section name data in bytes.
! 72: section_size_type section_names_size;
! 73: // Symbol data.
! 74: File_view* symbols;
! 75: // Size of symbol data in bytes.
! 76: section_size_type symbols_size;
! 77: // Offset of external symbols within symbol data. This structure
! 78: // sometimes contains only external symbols, in which case this will
! 79: // be zero. Sometimes it contains all symbols.
! 80: section_offset_type external_symbols_offset;
! 81: // Symbol names.
! 82: File_view* symbol_names;
! 83: // Size of symbol name data in bytes.
! 84: section_size_type symbol_names_size;
! 85:
! 86: // Version information. This is only used on dynamic objects.
! 87: // Version symbol data (from SHT_GNU_versym section).
! 88: File_view* versym;
! 89: section_size_type versym_size;
! 90: // Version definition data (from SHT_GNU_verdef section).
! 91: File_view* verdef;
! 92: section_size_type verdef_size;
! 93: unsigned int verdef_info;
! 94: // Needed version data (from SHT_GNU_verneed section).
! 95: File_view* verneed;
! 96: section_size_type verneed_size;
! 97: unsigned int verneed_info;
! 98: };
! 99:
! 100: // Information used to print error messages.
! 101:
! 102: struct Symbol_location_info
! 103: {
! 104: std::string source_file;
! 105: std::string enclosing_symbol_name;
! 106: int line_number;
! 107: };
! 108:
! 109: // Data about a single relocation section. This is read in
! 110: // read_relocs and processed in scan_relocs.
! 111:
! 112: struct Section_relocs
! 113: {
! 114: Section_relocs()
! 115: : contents(NULL)
! 116: { }
! 117:
! 118: ~Section_relocs()
! 119: { delete this->contents; }
! 120:
! 121: // Index of reloc section.
! 122: unsigned int reloc_shndx;
! 123: // Index of section that relocs apply to.
! 124: unsigned int data_shndx;
! 125: // Contents of reloc section.
! 126: File_view* contents;
! 127: // Reloc section type.
! 128: unsigned int sh_type;
! 129: // Number of reloc entries.
! 130: size_t reloc_count;
! 131: // Output section.
! 132: Output_section* output_section;
! 133: // Whether this section has special handling for offsets.
! 134: bool needs_special_offset_handling;
! 135: // Whether the data section is allocated (has the SHF_ALLOC flag set).
! 136: bool is_data_section_allocated;
! 137: };
! 138:
! 139: // Relocations in an object file. This is read in read_relocs and
! 140: // processed in scan_relocs.
! 141:
! 142: struct Read_relocs_data
! 143: {
! 144: Read_relocs_data()
! 145: : local_symbols(NULL)
! 146: { }
! 147:
! 148: ~Read_relocs_data()
! 149: { delete this->local_symbols; }
! 150:
! 151: typedef std::vector<Section_relocs> Relocs_list;
! 152: // The relocations.
! 153: Relocs_list relocs;
! 154: // The local symbols.
! 155: File_view* local_symbols;
! 156: };
! 157:
! 158: // The Xindex class manages section indexes for objects with more than
! 159: // 0xff00 sections.
! 160:
! 161: class Xindex
! 162: {
! 163: public:
! 164: Xindex(int large_shndx_offset)
! 165: : large_shndx_offset_(large_shndx_offset), symtab_xindex_()
! 166: { }
! 167:
! 168: // Initialize the symtab_xindex_ array, given the object and the
! 169: // section index of the symbol table to use.
! 170: template<int size, bool big_endian>
! 171: void
! 172: initialize_symtab_xindex(Object*, unsigned int symtab_shndx);
! 173:
! 174: // Read in the symtab_xindex_ array, given its section index.
! 175: // PSHDRS may optionally point to the section headers.
! 176: template<int size, bool big_endian>
! 177: void
! 178: read_symtab_xindex(Object*, unsigned int xindex_shndx,
! 179: const unsigned char* pshdrs);
! 180:
! 181: // Symbol SYMNDX in OBJECT has a section of SHN_XINDEX; return the
! 182: // real section index.
! 183: unsigned int
! 184: sym_xindex_to_shndx(Object* object, unsigned int symndx);
! 185:
! 186: private:
! 187: // The type of the array giving the real section index for symbols
! 188: // whose st_shndx field holds SHN_XINDEX.
! 189: typedef std::vector<unsigned int> Symtab_xindex;
! 190:
! 191: // Adjust a section index if necessary. This should only be called
! 192: // for ordinary section indexes.
! 193: unsigned int
! 194: adjust_shndx(unsigned int shndx)
! 195: {
! 196: if (shndx >= elfcpp::SHN_LORESERVE)
! 197: shndx += this->large_shndx_offset_;
! 198: return shndx;
! 199: }
! 200:
! 201: // Adjust to apply to large section indexes.
! 202: int large_shndx_offset_;
! 203: // The data from the SHT_SYMTAB_SHNDX section.
! 204: Symtab_xindex symtab_xindex_;
! 205: };
! 206:
! 207: // A GOT offset list. A symbol may have more than one GOT offset
! 208: // (e.g., when mixing modules compiled with two different TLS models),
! 209: // but will usually have at most one. GOT_TYPE identifies the type of
! 210: // GOT entry; its values are specific to each target.
! 211:
! 212: class Got_offset_list
! 213: {
! 214: public:
! 215: Got_offset_list()
! 216: : got_type_(-1U), got_offset_(0), got_next_(NULL)
! 217: { }
! 218:
! 219: Got_offset_list(unsigned int got_type, unsigned int got_offset)
! 220: : got_type_(got_type), got_offset_(got_offset), got_next_(NULL)
! 221: { }
! 222:
! 223: ~Got_offset_list()
! 224: {
! 225: if (this->got_next_ != NULL)
! 226: {
! 227: delete this->got_next_;
! 228: this->got_next_ = NULL;
! 229: }
! 230: }
! 231:
! 232: // Initialize the fields to their default values.
! 233: void
! 234: init()
! 235: {
! 236: this->got_type_ = -1U;
! 237: this->got_offset_ = 0;
! 238: this->got_next_ = NULL;
! 239: }
! 240:
! 241: // Set the offset for the GOT entry of type GOT_TYPE.
! 242: void
! 243: set_offset(unsigned int got_type, unsigned int got_offset)
! 244: {
! 245: if (this->got_type_ == -1U)
! 246: {
! 247: this->got_type_ = got_type;
! 248: this->got_offset_ = got_offset;
! 249: }
! 250: else
! 251: {
! 252: for (Got_offset_list* g = this; g != NULL; g = g->got_next_)
! 253: {
! 254: if (g->got_type_ == got_type)
! 255: {
! 256: g->got_offset_ = got_offset;
! 257: return;
! 258: }
! 259: }
! 260: Got_offset_list* g = new Got_offset_list(got_type, got_offset);
! 261: g->got_next_ = this->got_next_;
! 262: this->got_next_ = g;
! 263: }
! 264: }
! 265:
! 266: // Return the offset for a GOT entry of type GOT_TYPE.
! 267: unsigned int
! 268: get_offset(unsigned int got_type) const
! 269: {
! 270: for (const Got_offset_list* g = this; g != NULL; g = g->got_next_)
! 271: {
! 272: if (g->got_type_ == got_type)
! 273: return g->got_offset_;
! 274: }
! 275: return -1U;
! 276: }
! 277:
! 278: // Return a pointer to the list, or NULL if the list is empty.
! 279: const Got_offset_list*
! 280: get_list() const
! 281: {
! 282: if (this->got_type_ == -1U)
! 283: return NULL;
! 284: return this;
! 285: }
! 286:
! 287: // Abstract visitor class for iterating over GOT offsets.
! 288: class Visitor
! 289: {
! 290: public:
! 291: Visitor()
! 292: { }
! 293:
! 294: virtual
! 295: ~Visitor()
! 296: { }
! 297:
! 298: virtual void
! 299: visit(unsigned int, unsigned int) = 0;
! 300: };
! 301:
! 302: // Loop over all GOT offset entries, calling a visitor class V for each.
! 303: void
! 304: for_all_got_offsets(Visitor* v) const
! 305: {
! 306: if (this->got_type_ == -1U)
! 307: return;
! 308: for (const Got_offset_list* g = this; g != NULL; g = g->got_next_)
! 309: v->visit(g->got_type_, g->got_offset_);
! 310: }
! 311:
! 312: private:
! 313: unsigned int got_type_;
! 314: unsigned int got_offset_;
! 315: Got_offset_list* got_next_;
! 316: };
! 317:
! 318: // Object is an abstract base class which represents either a 32-bit
! 319: // or a 64-bit input object. This can be a regular object file
! 320: // (ET_REL) or a shared object (ET_DYN).
! 321:
! 322: class Object
! 323: {
! 324: public:
! 325: typedef std::vector<Symbol*> Symbols;
! 326:
! 327: // NAME is the name of the object as we would report it to the user
! 328: // (e.g., libfoo.a(bar.o) if this is in an archive. INPUT_FILE is
! 329: // used to read the file. OFFSET is the offset within the input
! 330: // file--0 for a .o or .so file, something else for a .a file.
! 331: Object(const std::string& name, Input_file* input_file, bool is_dynamic,
! 332: off_t offset = 0)
! 333: : name_(name), input_file_(input_file), offset_(offset), shnum_(-1U),
! 334: is_dynamic_(is_dynamic), is_needed_(false), uses_split_stack_(false),
! 335: has_no_split_stack_(false), no_export_(false),
! 336: is_in_system_directory_(false), as_needed_(false), xindex_(NULL)
! 337: {
! 338: if (input_file != NULL)
! 339: {
! 340: input_file->file().add_object();
! 341: this->is_in_system_directory_ = input_file->is_in_system_directory();
! 342: this->as_needed_ = input_file->options().as_needed();
! 343: }
! 344: }
! 345:
! 346: virtual ~Object()
! 347: {
! 348: if (this->input_file_ != NULL)
! 349: this->input_file_->file().remove_object();
! 350: }
! 351:
! 352: // Return the name of the object as we would report it to the tuser.
! 353: const std::string&
! 354: name() const
! 355: { return this->name_; }
! 356:
! 357: // Get the offset into the file.
! 358: off_t
! 359: offset() const
! 360: { return this->offset_; }
! 361:
! 362: // Return whether this is a dynamic object.
! 363: bool
! 364: is_dynamic() const
! 365: { return this->is_dynamic_; }
! 366:
! 367: // Return whether this object is needed--true if it is a dynamic
! 368: // object which defines some symbol referenced by a regular object.
! 369: // We keep the flag here rather than in Dynobj for convenience when
! 370: // setting it.
! 371: bool
! 372: is_needed() const
! 373: { return this->is_needed_; }
! 374:
! 375: // Record that this object is needed.
! 376: void
! 377: set_is_needed()
! 378: { this->is_needed_ = true; }
! 379:
! 380: // Return whether this object was compiled with -fsplit-stack.
! 381: bool
! 382: uses_split_stack() const
! 383: { return this->uses_split_stack_; }
! 384:
! 385: // Return whether this object contains any functions compiled with
! 386: // the no_split_stack attribute.
! 387: bool
! 388: has_no_split_stack() const
! 389: { return this->has_no_split_stack_; }
! 390:
! 391: // Returns NULL for Objects that are not dynamic objects. This method
! 392: // is overridden in the Dynobj class.
! 393: Dynobj*
! 394: dynobj()
! 395: { return this->do_dynobj(); }
! 396:
! 397: // Returns NULL for Objects that are not plugin objects. This method
! 398: // is overridden in the Pluginobj class.
! 399: Pluginobj*
! 400: pluginobj()
! 401: { return this->do_pluginobj(); }
! 402:
! 403: // Get the file. We pass on const-ness.
! 404: Input_file*
! 405: input_file()
! 406: {
! 407: gold_assert(this->input_file_ != NULL);
! 408: return this->input_file_;
! 409: }
! 410:
! 411: const Input_file*
! 412: input_file() const
! 413: {
! 414: gold_assert(this->input_file_ != NULL);
! 415: return this->input_file_;
! 416: }
! 417:
! 418: // Lock the underlying file.
! 419: void
! 420: lock(const Task* t)
! 421: {
! 422: if (this->input_file_ != NULL)
! 423: this->input_file_->file().lock(t);
! 424: }
! 425:
! 426: // Unlock the underlying file.
! 427: void
! 428: unlock(const Task* t)
! 429: {
! 430: if (this->input_file_ != NULL)
! 431: this->input_file()->file().unlock(t);
! 432: }
! 433:
! 434: // Return whether the underlying file is locked.
! 435: bool
! 436: is_locked() const
! 437: { return this->input_file_ != NULL && this->input_file_->file().is_locked(); }
! 438:
! 439: // Return the token, so that the task can be queued.
! 440: Task_token*
! 441: token()
! 442: {
! 443: if (this->input_file_ == NULL)
! 444: return NULL;
! 445: return this->input_file()->file().token();
! 446: }
! 447:
! 448: // Release the underlying file.
! 449: void
! 450: release()
! 451: {
! 452: if (this->input_file_ != NULL)
! 453: this->input_file()->file().release();
! 454: }
! 455:
! 456: // Return whether we should just read symbols from this file.
! 457: bool
! 458: just_symbols() const
! 459: { return this->input_file()->just_symbols(); }
! 460:
! 461: // Return whether this is an incremental object.
! 462: bool
! 463: is_incremental() const
! 464: { return this->do_is_incremental(); }
! 465:
! 466: // Return the last modified time of the file.
! 467: Timespec
! 468: get_mtime()
! 469: { return this->do_get_mtime(); }
! 470:
! 471: // Get the number of sections.
! 472: unsigned int
! 473: shnum() const
! 474: { return this->shnum_; }
! 475:
! 476: // Return a view of the contents of a section. Set *PLEN to the
! 477: // size. CACHE is a hint as in File_read::get_view.
! 478: const unsigned char*
! 479: section_contents(unsigned int shndx, section_size_type* plen, bool cache);
! 480:
! 481: // Adjust a symbol's section index as needed. SYMNDX is the index
! 482: // of the symbol and SHNDX is the symbol's section from
! 483: // get_st_shndx. This returns the section index. It sets
! 484: // *IS_ORDINARY to indicate whether this is a normal section index,
! 485: // rather than a special code between SHN_LORESERVE and
! 486: // SHN_HIRESERVE.
! 487: unsigned int
! 488: adjust_sym_shndx(unsigned int symndx, unsigned int shndx, bool* is_ordinary)
! 489: {
! 490: if (shndx < elfcpp::SHN_LORESERVE)
! 491: *is_ordinary = true;
! 492: else if (shndx == elfcpp::SHN_XINDEX)
! 493: {
! 494: if (this->xindex_ == NULL)
! 495: this->xindex_ = this->do_initialize_xindex();
! 496: shndx = this->xindex_->sym_xindex_to_shndx(this, symndx);
! 497: *is_ordinary = true;
! 498: }
! 499: else
! 500: *is_ordinary = false;
! 501: return shndx;
! 502: }
! 503:
! 504: // Return the size of a section given a section index.
! 505: uint64_t
! 506: section_size(unsigned int shndx)
! 507: { return this->do_section_size(shndx); }
! 508:
! 509: // Return the name of a section given a section index.
! 510: std::string
! 511: section_name(unsigned int shndx)
! 512: { return this->do_section_name(shndx); }
! 513:
! 514: // Return the section flags given a section index.
! 515: uint64_t
! 516: section_flags(unsigned int shndx)
! 517: { return this->do_section_flags(shndx); }
! 518:
! 519: // Return the section entsize given a section index.
! 520: uint64_t
! 521: section_entsize(unsigned int shndx)
! 522: { return this->do_section_entsize(shndx); }
! 523:
! 524: // Return the section address given a section index.
! 525: uint64_t
! 526: section_address(unsigned int shndx)
! 527: { return this->do_section_address(shndx); }
! 528:
! 529: // Return the section type given a section index.
! 530: unsigned int
! 531: section_type(unsigned int shndx)
! 532: { return this->do_section_type(shndx); }
! 533:
! 534: // Return the section link field given a section index.
! 535: unsigned int
! 536: section_link(unsigned int shndx)
! 537: { return this->do_section_link(shndx); }
! 538:
! 539: // Return the section info field given a section index.
! 540: unsigned int
! 541: section_info(unsigned int shndx)
! 542: { return this->do_section_info(shndx); }
! 543:
! 544: // Return the required section alignment given a section index.
! 545: uint64_t
! 546: section_addralign(unsigned int shndx)
! 547: { return this->do_section_addralign(shndx); }
! 548:
! 549: // Return the output section given a section index.
! 550: Output_section*
! 551: output_section(unsigned int shndx) const
! 552: { return this->do_output_section(shndx); }
! 553:
! 554: // Given a section index, return the offset in the Output_section.
! 555: // The return value will be -1U if the section is specially mapped,
! 556: // such as a merge section.
! 557: uint64_t
! 558: output_section_offset(unsigned int shndx) const
! 559: { return this->do_output_section_offset(shndx); }
! 560:
! 561: // Read the symbol information.
! 562: void
! 563: read_symbols(Read_symbols_data* sd)
! 564: { return this->do_read_symbols(sd); }
! 565:
! 566: // Pass sections which should be included in the link to the Layout
! 567: // object, and record where the sections go in the output file.
! 568: void
! 569: layout(Symbol_table* symtab, Layout* layout, Read_symbols_data* sd)
! 570: { this->do_layout(symtab, layout, sd); }
! 571:
! 572: // Add symbol information to the global symbol table.
! 573: void
! 574: add_symbols(Symbol_table* symtab, Read_symbols_data* sd, Layout *layout)
! 575: { this->do_add_symbols(symtab, sd, layout); }
! 576:
! 577: // Add symbol information to the global symbol table.
! 578: Archive::Should_include
! 579: should_include_member(Symbol_table* symtab, Layout* layout,
! 580: Read_symbols_data* sd, std::string* why)
! 581: { return this->do_should_include_member(symtab, layout, sd, why); }
! 582:
! 583: // Iterate over global symbols, calling a visitor class V for each.
! 584: void
! 585: for_all_global_symbols(Read_symbols_data* sd,
! 586: Library_base::Symbol_visitor_base* v)
! 587: { return this->do_for_all_global_symbols(sd, v); }
! 588:
! 589: // Iterate over local symbols, calling a visitor class V for each GOT offset
! 590: // associated with a local symbol.
! 591: void
! 592: for_all_local_got_entries(Got_offset_list::Visitor* v) const
! 593: { this->do_for_all_local_got_entries(v); }
! 594:
! 595: // Functions and types for the elfcpp::Elf_file interface. This
! 596: // permit us to use Object as the File template parameter for
! 597: // elfcpp::Elf_file.
! 598:
! 599: // The View class is returned by view. It must support a single
! 600: // method, data(). This is trivial, because get_view does what we
! 601: // need.
! 602: class View
! 603: {
! 604: public:
! 605: View(const unsigned char* p)
! 606: : p_(p)
! 607: { }
! 608:
! 609: const unsigned char*
! 610: data() const
! 611: { return this->p_; }
! 612:
! 613: private:
! 614: const unsigned char* p_;
! 615: };
! 616:
! 617: // Return a View.
! 618: View
! 619: view(off_t file_offset, section_size_type data_size)
! 620: { return View(this->get_view(file_offset, data_size, true, true)); }
! 621:
! 622: // Report an error.
! 623: void
! 624: error(const char* format, ...) const ATTRIBUTE_PRINTF_2;
! 625:
! 626: // A location in the file.
! 627: struct Location
! 628: {
! 629: off_t file_offset;
! 630: off_t data_size;
! 631:
! 632: Location(off_t fo, section_size_type ds)
! 633: : file_offset(fo), data_size(ds)
! 634: { }
! 635: };
! 636:
! 637: // Get a View given a Location.
! 638: View view(Location loc)
! 639: { return View(this->get_view(loc.file_offset, loc.data_size, true, true)); }
! 640:
! 641: // Get a view into the underlying file.
! 642: const unsigned char*
! 643: get_view(off_t start, section_size_type size, bool aligned, bool cache)
! 644: {
! 645: return this->input_file()->file().get_view(this->offset_, start, size,
! 646: aligned, cache);
! 647: }
! 648:
! 649: // Get a lasting view into the underlying file.
! 650: File_view*
! 651: get_lasting_view(off_t start, section_size_type size, bool aligned,
! 652: bool cache)
! 653: {
! 654: return this->input_file()->file().get_lasting_view(this->offset_, start,
! 655: size, aligned, cache);
! 656: }
! 657:
! 658: // Read data from the underlying file.
! 659: void
! 660: read(off_t start, section_size_type size, void* p)
! 661: { this->input_file()->file().read(start + this->offset_, size, p); }
! 662:
! 663: // Read multiple data from the underlying file.
! 664: void
! 665: read_multiple(const File_read::Read_multiple& rm)
! 666: { this->input_file()->file().read_multiple(this->offset_, rm); }
! 667:
! 668: // Stop caching views in the underlying file.
! 669: void
! 670: clear_view_cache_marks()
! 671: {
! 672: if (this->input_file_ != NULL)
! 673: this->input_file_->file().clear_view_cache_marks();
! 674: }
! 675:
! 676: // Get the number of global symbols defined by this object, and the
! 677: // number of the symbols whose final definition came from this
! 678: // object.
! 679: void
! 680: get_global_symbol_counts(const Symbol_table* symtab, size_t* defined,
! 681: size_t* used) const
! 682: { this->do_get_global_symbol_counts(symtab, defined, used); }
! 683:
! 684: // Get the symbols defined in this object.
! 685: const Symbols*
! 686: get_global_symbols() const
! 687: { return this->do_get_global_symbols(); }
! 688:
! 689: // Set flag that this object was found in a system directory.
! 690: void
! 691: set_is_in_system_directory()
! 692: { this->is_in_system_directory_ = true; }
! 693:
! 694: // Return whether this object was found in a system directory.
! 695: bool
! 696: is_in_system_directory() const
! 697: { return this->is_in_system_directory_; }
! 698:
! 699: // Set flag that this object was linked with --as-needed.
! 700: void
! 701: set_as_needed()
! 702: { this->as_needed_ = true; }
! 703:
! 704: // Return whether this object was linked with --as-needed.
! 705: bool
! 706: as_needed() const
! 707: { return this->as_needed_; }
! 708:
! 709: // Return whether we found this object by searching a directory.
! 710: bool
! 711: searched_for() const
! 712: { return this->input_file()->will_search_for(); }
! 713:
! 714: bool
! 715: no_export() const
! 716: { return this->no_export_; }
! 717:
! 718: void
! 719: set_no_export(bool value)
! 720: { this->no_export_ = value; }
! 721:
! 722: // Return TRUE if the section is a compressed debug section, and set
! 723: // *UNCOMPRESSED_SIZE to the size of the uncompressed data.
! 724: bool
! 725: section_is_compressed(unsigned int shndx,
! 726: section_size_type* uncompressed_size) const
! 727: { return this->do_section_is_compressed(shndx, uncompressed_size); }
! 728:
! 729: // Return a view of the decompressed contents of a section. Set *PLEN
! 730: // to the size. Set *IS_NEW to true if the contents need to be freed
! 731: // by the caller.
! 732: const unsigned char*
! 733: decompressed_section_contents(unsigned int shndx, section_size_type* plen,
! 734: bool* is_cached)
! 735: { return this->do_decompressed_section_contents(shndx, plen, is_cached); }
! 736:
! 737: // Discard any buffers of decompressed sections. This is done
! 738: // at the end of the Add_symbols task.
! 739: void
! 740: discard_decompressed_sections()
! 741: { this->do_discard_decompressed_sections(); }
! 742:
! 743: // Return the index of the first incremental relocation for symbol SYMNDX.
! 744: unsigned int
! 745: get_incremental_reloc_base(unsigned int symndx) const
! 746: { return this->do_get_incremental_reloc_base(symndx); }
! 747:
! 748: // Return the number of incremental relocations for symbol SYMNDX.
! 749: unsigned int
! 750: get_incremental_reloc_count(unsigned int symndx) const
! 751: { return this->do_get_incremental_reloc_count(symndx); }
! 752:
! 753: protected:
! 754: // Returns NULL for Objects that are not dynamic objects. This method
! 755: // is overridden in the Dynobj class.
! 756: virtual Dynobj*
! 757: do_dynobj()
! 758: { return NULL; }
! 759:
! 760: // Returns NULL for Objects that are not plugin objects. This method
! 761: // is overridden in the Pluginobj class.
! 762: virtual Pluginobj*
! 763: do_pluginobj()
! 764: { return NULL; }
! 765:
! 766: // Return TRUE if this is an incremental (unchanged) input file.
! 767: // We return FALSE by default; the incremental object classes
! 768: // override this method.
! 769: virtual bool
! 770: do_is_incremental() const
! 771: { return false; }
! 772:
! 773: // Return the last modified time of the file. This method may be
! 774: // overridden for subclasses that don't use an actual file (e.g.,
! 775: // Incremental objects).
! 776: virtual Timespec
! 777: do_get_mtime()
! 778: { return this->input_file()->file().get_mtime(); }
! 779:
! 780: // Read the symbols--implemented by child class.
! 781: virtual void
! 782: do_read_symbols(Read_symbols_data*) = 0;
! 783:
! 784: // Lay out sections--implemented by child class.
! 785: virtual void
! 786: do_layout(Symbol_table*, Layout*, Read_symbols_data*) = 0;
! 787:
! 788: // Add symbol information to the global symbol table--implemented by
! 789: // child class.
! 790: virtual void
! 791: do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*) = 0;
! 792:
! 793: virtual Archive::Should_include
! 794: do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
! 795: std::string* why) = 0;
! 796:
! 797: // Iterate over global symbols, calling a visitor class V for each.
! 798: virtual void
! 799: do_for_all_global_symbols(Read_symbols_data* sd,
! 800: Library_base::Symbol_visitor_base* v) = 0;
! 801:
! 802: // Iterate over local symbols, calling a visitor class V for each GOT offset
! 803: // associated with a local symbol.
! 804: virtual void
! 805: do_for_all_local_got_entries(Got_offset_list::Visitor* v) const = 0;
! 806:
! 807: // Return the location of the contents of a section. Implemented by
! 808: // child class.
! 809: virtual const unsigned char*
! 810: do_section_contents(unsigned int shndx, section_size_type* plen,
! 811: bool cache) = 0;
! 812:
! 813: // Get the size of a section--implemented by child class.
! 814: virtual uint64_t
! 815: do_section_size(unsigned int shndx) = 0;
! 816:
! 817: // Get the name of a section--implemented by child class.
! 818: virtual std::string
! 819: do_section_name(unsigned int shndx) = 0;
! 820:
! 821: // Get section flags--implemented by child class.
! 822: virtual uint64_t
! 823: do_section_flags(unsigned int shndx) = 0;
! 824:
! 825: // Get section entsize--implemented by child class.
! 826: virtual uint64_t
! 827: do_section_entsize(unsigned int shndx) = 0;
! 828:
! 829: // Get section address--implemented by child class.
! 830: virtual uint64_t
! 831: do_section_address(unsigned int shndx) = 0;
! 832:
! 833: // Get section type--implemented by child class.
! 834: virtual unsigned int
! 835: do_section_type(unsigned int shndx) = 0;
! 836:
! 837: // Get section link field--implemented by child class.
! 838: virtual unsigned int
! 839: do_section_link(unsigned int shndx) = 0;
! 840:
! 841: // Get section info field--implemented by child class.
! 842: virtual unsigned int
! 843: do_section_info(unsigned int shndx) = 0;
! 844:
! 845: // Get section alignment--implemented by child class.
! 846: virtual uint64_t
! 847: do_section_addralign(unsigned int shndx) = 0;
! 848:
! 849: // Return the output section given a section index--implemented
! 850: // by child class.
! 851: virtual Output_section*
! 852: do_output_section(unsigned int) const
! 853: { gold_unreachable(); }
! 854:
! 855: // Get the offset of a section--implemented by child class.
! 856: virtual uint64_t
! 857: do_output_section_offset(unsigned int) const
! 858: { gold_unreachable(); }
! 859:
! 860: // Return the Xindex structure to use.
! 861: virtual Xindex*
! 862: do_initialize_xindex() = 0;
! 863:
! 864: // Implement get_global_symbol_counts--implemented by child class.
! 865: virtual void
! 866: do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const = 0;
! 867:
! 868: virtual const Symbols*
! 869: do_get_global_symbols() const = 0;
! 870:
! 871: // Set the number of sections.
! 872: void
! 873: set_shnum(int shnum)
! 874: { this->shnum_ = shnum; }
! 875:
! 876: // Functions used by both Sized_relobj_file and Sized_dynobj.
! 877:
! 878: // Read the section data into a Read_symbols_data object.
! 879: template<int size, bool big_endian>
! 880: void
! 881: read_section_data(elfcpp::Elf_file<size, big_endian, Object>*,
! 882: Read_symbols_data*);
! 883:
! 884: // Let the child class initialize the xindex object directly.
! 885: void
! 886: set_xindex(Xindex* xindex)
! 887: {
! 888: gold_assert(this->xindex_ == NULL);
! 889: this->xindex_ = xindex;
! 890: }
! 891:
! 892: // If NAME is the name of a special .gnu.warning section, arrange
! 893: // for the warning to be issued. SHNDX is the section index.
! 894: // Return whether it is a warning section.
! 895: bool
! 896: handle_gnu_warning_section(const char* name, unsigned int shndx,
! 897: Symbol_table*);
! 898:
! 899: // If NAME is the name of the special section which indicates that
! 900: // this object was compiled with -fsplit-stack, mark it accordingly,
! 901: // and return true. Otherwise return false.
! 902: bool
! 903: handle_split_stack_section(const char* name);
! 904:
! 905: // Return TRUE if the section is a compressed debug section, and set
! 906: // *UNCOMPRESSED_SIZE to the size of the uncompressed data.
! 907: virtual bool
! 908: do_section_is_compressed(unsigned int, section_size_type*) const
! 909: { return false; }
! 910:
! 911: // Return a view of the decompressed contents of a section. Set *PLEN
! 912: // to the size. This default implementation simply returns the
! 913: // raw section contents and sets *IS_NEW to false to indicate
! 914: // that the contents do not need to be freed by the caller.
! 915: // This function must be overridden for any types of object files
! 916: // that might contain compressed sections.
! 917: virtual const unsigned char*
! 918: do_decompressed_section_contents(unsigned int shndx,
! 919: section_size_type* plen,
! 920: bool* is_new)
! 921: {
! 922: *is_new = false;
! 923: return this->do_section_contents(shndx, plen, false);
! 924: }
! 925:
! 926: // Discard any buffers of decompressed sections. This is done
! 927: // at the end of the Add_symbols task.
! 928: virtual void
! 929: do_discard_decompressed_sections()
! 930: { }
! 931:
! 932: // Return the index of the first incremental relocation for symbol SYMNDX--
! 933: // implemented by child class.
! 934: virtual unsigned int
! 935: do_get_incremental_reloc_base(unsigned int) const
! 936: { gold_unreachable(); }
! 937:
! 938: // Return the number of incremental relocations for symbol SYMNDX--
! 939: // implemented by child class.
! 940: virtual unsigned int
! 941: do_get_incremental_reloc_count(unsigned int) const
! 942: { gold_unreachable(); }
! 943:
! 944: private:
! 945: // This class may not be copied.
! 946: Object(const Object&);
! 947: Object& operator=(const Object&);
! 948:
! 949: // Name of object as printed to user.
! 950: std::string name_;
! 951: // For reading the file.
! 952: Input_file* input_file_;
! 953: // Offset within the file--0 for an object file, non-0 for an
! 954: // archive.
! 955: off_t offset_;
! 956: // Number of input sections.
! 957: unsigned int shnum_;
! 958: // Whether this is a dynamic object.
! 959: bool is_dynamic_ : 1;
! 960: // Whether this object is needed. This is only set for dynamic
! 961: // objects, and means that the object defined a symbol which was
! 962: // used by a reference from a regular object.
! 963: bool is_needed_ : 1;
! 964: // Whether this object was compiled with -fsplit-stack.
! 965: bool uses_split_stack_ : 1;
! 966: // Whether this object contains any functions compiled with the
! 967: // no_split_stack attribute.
! 968: bool has_no_split_stack_ : 1;
! 969: // True if exclude this object from automatic symbol export.
! 970: // This is used only for archive objects.
! 971: bool no_export_ : 1;
! 972: // True if the object was found in a system directory.
! 973: bool is_in_system_directory_ : 1;
! 974: // True if the object was linked with --as-needed.
! 975: bool as_needed_ : 1;
! 976: // Many sections for objects with more than SHN_LORESERVE sections.
! 977: Xindex* xindex_;
! 978: };
! 979:
! 980: // A regular object (ET_REL). This is an abstract base class itself.
! 981: // The implementation is the template class Sized_relobj_file.
! 982:
! 983: class Relobj : public Object
! 984: {
! 985: public:
! 986: Relobj(const std::string& name, Input_file* input_file, off_t offset = 0)
! 987: : Object(name, input_file, false, offset),
! 988: output_sections_(),
! 989: map_to_relocatable_relocs_(NULL),
! 990: object_merge_map_(NULL),
! 991: relocs_must_follow_section_writes_(false),
! 992: sd_(NULL),
! 993: reloc_counts_(NULL),
! 994: reloc_bases_(NULL),
! 995: first_dyn_reloc_(0),
! 996: dyn_reloc_count_(0)
! 997: { }
! 998:
! 999: // During garbage collection, the Read_symbols_data pass for
! 1000: // each object is stored as layout needs to be done after
! 1001: // reloc processing.
! 1002: Symbols_data*
! 1003: get_symbols_data()
! 1004: { return this->sd_; }
! 1005:
! 1006: // Decides which section names have to be included in the worklist
! 1007: // as roots.
! 1008: bool
! 1009: is_section_name_included(const char* name);
! 1010:
! 1011: void
! 1012: copy_symbols_data(Symbols_data* gc_sd, Read_symbols_data* sd,
! 1013: unsigned int section_header_size);
! 1014:
! 1015: void
! 1016: set_symbols_data(Symbols_data* sd)
! 1017: { this->sd_ = sd; }
! 1018:
! 1019: // During garbage collection, the Read_relocs pass for all objects
! 1020: // is done before scanning the relocs. In that case, this->rd_ is
! 1021: // used to store the information from Read_relocs for each object.
! 1022: // This data is also used to compute the list of relevant sections.
! 1023: Read_relocs_data*
! 1024: get_relocs_data()
! 1025: { return this->rd_; }
! 1026:
! 1027: void
! 1028: set_relocs_data(Read_relocs_data* rd)
! 1029: { this->rd_ = rd; }
! 1030:
! 1031: virtual bool
! 1032: is_output_section_offset_invalid(unsigned int shndx) const = 0;
! 1033:
! 1034: // Read the relocs.
! 1035: void
! 1036: read_relocs(Read_relocs_data* rd)
! 1037: { return this->do_read_relocs(rd); }
! 1038:
! 1039: // Process the relocs, during garbage collection only.
! 1040: void
! 1041: gc_process_relocs(Symbol_table* symtab, Layout* layout, Read_relocs_data* rd)
! 1042: { return this->do_gc_process_relocs(symtab, layout, rd); }
! 1043:
! 1044: // Scan the relocs and adjust the symbol table.
! 1045: void
! 1046: scan_relocs(Symbol_table* symtab, Layout* layout, Read_relocs_data* rd)
! 1047: { return this->do_scan_relocs(symtab, layout, rd); }
! 1048:
! 1049: // Return the value of the local symbol whose index is SYMNDX, plus
! 1050: // ADDEND. ADDEND is passed in so that we can correctly handle the
! 1051: // section symbol for a merge section.
! 1052: uint64_t
! 1053: local_symbol_value(unsigned int symndx, uint64_t addend) const
! 1054: { return this->do_local_symbol_value(symndx, addend); }
! 1055:
! 1056: // Return the PLT offset for a local symbol. It is an error to call
! 1057: // this if it doesn't have one.
! 1058: unsigned int
! 1059: local_plt_offset(unsigned int symndx) const
! 1060: { return this->do_local_plt_offset(symndx); }
! 1061:
! 1062: // Return whether the local symbol SYMNDX has a GOT offset of type
! 1063: // GOT_TYPE.
! 1064: bool
! 1065: local_has_got_offset(unsigned int symndx, unsigned int got_type) const
! 1066: { return this->do_local_has_got_offset(symndx, got_type); }
! 1067:
! 1068: // Return the GOT offset of type GOT_TYPE of the local symbol
! 1069: // SYMNDX. It is an error to call this if the symbol does not have
! 1070: // a GOT offset of the specified type.
! 1071: unsigned int
! 1072: local_got_offset(unsigned int symndx, unsigned int got_type) const
! 1073: { return this->do_local_got_offset(symndx, got_type); }
! 1074:
! 1075: // Set the GOT offset with type GOT_TYPE of the local symbol SYMNDX
! 1076: // to GOT_OFFSET.
! 1077: void
! 1078: set_local_got_offset(unsigned int symndx, unsigned int got_type,
! 1079: unsigned int got_offset)
! 1080: { this->do_set_local_got_offset(symndx, got_type, got_offset); }
! 1081:
! 1082: // The number of local symbols in the input symbol table.
! 1083: virtual unsigned int
! 1084: local_symbol_count() const
! 1085: { return this->do_local_symbol_count(); }
! 1086:
! 1087: // The number of local symbols in the output symbol table.
! 1088: virtual unsigned int
! 1089: output_local_symbol_count() const
! 1090: { return this->do_output_local_symbol_count(); }
! 1091:
! 1092: // The file offset for local symbols in the output symbol table.
! 1093: virtual off_t
! 1094: local_symbol_offset() const
! 1095: { return this->do_local_symbol_offset(); }
! 1096:
! 1097: // Initial local symbol processing: count the number of local symbols
! 1098: // in the output symbol table and dynamic symbol table; add local symbol
! 1099: // names to *POOL and *DYNPOOL.
! 1100: void
! 1101: count_local_symbols(Stringpool_template<char>* pool,
! 1102: Stringpool_template<char>* dynpool)
! 1103: { return this->do_count_local_symbols(pool, dynpool); }
! 1104:
! 1105: // Set the values of the local symbols, set the output symbol table
! 1106: // indexes for the local variables, and set the offset where local
! 1107: // symbol information will be stored. Returns the new local symbol index.
! 1108: unsigned int
! 1109: finalize_local_symbols(unsigned int index, off_t off, Symbol_table* symtab)
! 1110: { return this->do_finalize_local_symbols(index, off, symtab); }
! 1111:
! 1112: // Set the output dynamic symbol table indexes for the local variables.
! 1113: unsigned int
! 1114: set_local_dynsym_indexes(unsigned int index)
! 1115: { return this->do_set_local_dynsym_indexes(index); }
! 1116:
! 1117: // Set the offset where local dynamic symbol information will be stored.
! 1118: unsigned int
! 1119: set_local_dynsym_offset(off_t off)
! 1120: { return this->do_set_local_dynsym_offset(off); }
! 1121:
! 1122: // Record a dynamic relocation against an input section from this object.
! 1123: void
! 1124: add_dyn_reloc(unsigned int index)
! 1125: {
! 1126: if (this->dyn_reloc_count_ == 0)
! 1127: this->first_dyn_reloc_ = index;
! 1128: ++this->dyn_reloc_count_;
! 1129: }
! 1130:
! 1131: // Return the index of the first dynamic relocation.
! 1132: unsigned int
! 1133: first_dyn_reloc() const
! 1134: { return this->first_dyn_reloc_; }
! 1135:
! 1136: // Return the count of dynamic relocations.
! 1137: unsigned int
! 1138: dyn_reloc_count() const
! 1139: { return this->dyn_reloc_count_; }
! 1140:
! 1141: // Relocate the input sections and write out the local symbols.
! 1142: void
! 1143: relocate(const Symbol_table* symtab, const Layout* layout, Output_file* of)
! 1144: { return this->do_relocate(symtab, layout, of); }
! 1145:
! 1146: // Return whether an input section is being included in the link.
! 1147: bool
! 1148: is_section_included(unsigned int shndx) const
! 1149: {
! 1150: gold_assert(shndx < this->output_sections_.size());
! 1151: return this->output_sections_[shndx] != NULL;
! 1152: }
! 1153:
! 1154: // The the output section of the input section with index SHNDX.
! 1155: // This is only used currently to remove a section from the link in
! 1156: // relaxation.
! 1157: void
! 1158: set_output_section(unsigned int shndx, Output_section* os)
! 1159: {
! 1160: gold_assert(shndx < this->output_sections_.size());
! 1161: this->output_sections_[shndx] = os;
! 1162: }
! 1163:
! 1164: // Set the offset of an input section within its output section.
! 1165: void
! 1166: set_section_offset(unsigned int shndx, uint64_t off)
! 1167: { this->do_set_section_offset(shndx, off); }
! 1168:
! 1169: // Return true if we need to wait for output sections to be written
! 1170: // before we can apply relocations. This is true if the object has
! 1171: // any relocations for sections which require special handling, such
! 1172: // as the exception frame section.
! 1173: bool
! 1174: relocs_must_follow_section_writes() const
! 1175: { return this->relocs_must_follow_section_writes_; }
! 1176:
! 1177: // Return the object merge map.
! 1178: Object_merge_map*
! 1179: merge_map() const
! 1180: { return this->object_merge_map_; }
! 1181:
! 1182: // Set the object merge map.
! 1183: void
! 1184: set_merge_map(Object_merge_map* object_merge_map)
! 1185: {
! 1186: gold_assert(this->object_merge_map_ == NULL);
! 1187: this->object_merge_map_ = object_merge_map;
! 1188: }
! 1189:
! 1190: // Record the relocatable reloc info for an input reloc section.
! 1191: void
! 1192: set_relocatable_relocs(unsigned int reloc_shndx, Relocatable_relocs* rr)
! 1193: {
! 1194: gold_assert(reloc_shndx < this->shnum());
! 1195: (*this->map_to_relocatable_relocs_)[reloc_shndx] = rr;
! 1196: }
! 1197:
! 1198: // Get the relocatable reloc info for an input reloc section.
! 1199: Relocatable_relocs*
! 1200: relocatable_relocs(unsigned int reloc_shndx)
! 1201: {
! 1202: gold_assert(reloc_shndx < this->shnum());
! 1203: return (*this->map_to_relocatable_relocs_)[reloc_shndx];
! 1204: }
! 1205:
! 1206: // Layout sections whose layout was deferred while waiting for
! 1207: // input files from a plugin.
! 1208: void
! 1209: layout_deferred_sections(Layout* layout)
! 1210: { this->do_layout_deferred_sections(layout); }
! 1211:
! 1212: // Return the index of the first incremental relocation for symbol SYMNDX.
! 1213: virtual unsigned int
! 1214: do_get_incremental_reloc_base(unsigned int symndx) const
! 1215: { return this->reloc_bases_[symndx]; }
! 1216:
! 1217: // Return the number of incremental relocations for symbol SYMNDX.
! 1218: virtual unsigned int
! 1219: do_get_incremental_reloc_count(unsigned int symndx) const
! 1220: { return this->reloc_counts_[symndx]; }
! 1221:
! 1222: protected:
! 1223: // The output section to be used for each input section, indexed by
! 1224: // the input section number. The output section is NULL if the
! 1225: // input section is to be discarded.
! 1226: typedef std::vector<Output_section*> Output_sections;
! 1227:
! 1228: // Read the relocs--implemented by child class.
! 1229: virtual void
! 1230: do_read_relocs(Read_relocs_data*) = 0;
! 1231:
! 1232: // Process the relocs--implemented by child class.
! 1233: virtual void
! 1234: do_gc_process_relocs(Symbol_table*, Layout*, Read_relocs_data*) = 0;
! 1235:
! 1236: // Scan the relocs--implemented by child class.
! 1237: virtual void
! 1238: do_scan_relocs(Symbol_table*, Layout*, Read_relocs_data*) = 0;
! 1239:
! 1240: // Return the value of a local symbol.
! 1241: virtual uint64_t
! 1242: do_local_symbol_value(unsigned int symndx, uint64_t addend) const = 0;
! 1243:
! 1244: // Return the PLT offset of a local symbol.
! 1245: virtual unsigned int
! 1246: do_local_plt_offset(unsigned int symndx) const = 0;
! 1247:
! 1248: // Return whether a local symbol has a GOT offset of a given type.
! 1249: virtual bool
! 1250: do_local_has_got_offset(unsigned int symndx,
! 1251: unsigned int got_type) const = 0;
! 1252:
! 1253: // Return the GOT offset of a given type of a local symbol.
! 1254: virtual unsigned int
! 1255: do_local_got_offset(unsigned int symndx, unsigned int got_type) const = 0;
! 1256:
! 1257: // Set the GOT offset with a given type for a local symbol.
! 1258: virtual void
! 1259: do_set_local_got_offset(unsigned int symndx, unsigned int got_type,
! 1260: unsigned int got_offset) = 0;
! 1261:
! 1262: // Return the number of local symbols--implemented by child class.
! 1263: virtual unsigned int
! 1264: do_local_symbol_count() const = 0;
! 1265:
! 1266: // Return the number of output local symbols--implemented by child class.
! 1267: virtual unsigned int
! 1268: do_output_local_symbol_count() const = 0;
! 1269:
! 1270: // Return the file offset for local symbols--implemented by child class.
! 1271: virtual off_t
! 1272: do_local_symbol_offset() const = 0;
! 1273:
! 1274: // Count local symbols--implemented by child class.
! 1275: virtual void
! 1276: do_count_local_symbols(Stringpool_template<char>*,
! 1277: Stringpool_template<char>*) = 0;
! 1278:
! 1279: // Finalize the local symbols. Set the output symbol table indexes
! 1280: // for the local variables, and set the offset where local symbol
! 1281: // information will be stored.
! 1282: virtual unsigned int
! 1283: do_finalize_local_symbols(unsigned int, off_t, Symbol_table*) = 0;
! 1284:
! 1285: // Set the output dynamic symbol table indexes for the local variables.
! 1286: virtual unsigned int
! 1287: do_set_local_dynsym_indexes(unsigned int) = 0;
! 1288:
! 1289: // Set the offset where local dynamic symbol information will be stored.
! 1290: virtual unsigned int
! 1291: do_set_local_dynsym_offset(off_t) = 0;
! 1292:
! 1293: // Relocate the input sections and write out the local
! 1294: // symbols--implemented by child class.
! 1295: virtual void
! 1296: do_relocate(const Symbol_table* symtab, const Layout*, Output_file* of) = 0;
! 1297:
! 1298: // Set the offset of a section--implemented by child class.
! 1299: virtual void
! 1300: do_set_section_offset(unsigned int shndx, uint64_t off) = 0;
! 1301:
! 1302: // Layout sections whose layout was deferred while waiting for
! 1303: // input files from a plugin--implemented by child class.
! 1304: virtual void
! 1305: do_layout_deferred_sections(Layout*) = 0;
! 1306:
! 1307: // Given a section index, return the corresponding Output_section.
! 1308: // The return value will be NULL if the section is not included in
! 1309: // the link.
! 1310: Output_section*
! 1311: do_output_section(unsigned int shndx) const
! 1312: {
! 1313: gold_assert(shndx < this->output_sections_.size());
! 1314: return this->output_sections_[shndx];
! 1315: }
! 1316:
! 1317: // Return the vector mapping input sections to output sections.
! 1318: Output_sections&
! 1319: output_sections()
! 1320: { return this->output_sections_; }
! 1321:
! 1322: const Output_sections&
! 1323: output_sections() const
! 1324: { return this->output_sections_; }
! 1325:
! 1326: // Set the size of the relocatable relocs array.
! 1327: void
! 1328: size_relocatable_relocs()
! 1329: {
! 1330: this->map_to_relocatable_relocs_ =
! 1331: new std::vector<Relocatable_relocs*>(this->shnum());
! 1332: }
! 1333:
! 1334: // Record that we must wait for the output sections to be written
! 1335: // before applying relocations.
! 1336: void
! 1337: set_relocs_must_follow_section_writes()
! 1338: { this->relocs_must_follow_section_writes_ = true; }
! 1339:
! 1340: // Allocate the array for counting incremental relocations.
! 1341: void
! 1342: allocate_incremental_reloc_counts()
! 1343: {
! 1344: unsigned int nsyms = this->do_get_global_symbols()->size();
! 1345: this->reloc_counts_ = new unsigned int[nsyms];
! 1346: gold_assert(this->reloc_counts_ != NULL);
! 1347: memset(this->reloc_counts_, 0, nsyms * sizeof(unsigned int));
! 1348: }
! 1349:
! 1350: // Record a relocation in this object referencing global symbol SYMNDX.
! 1351: // Used for tracking incremental link information.
! 1352: void
! 1353: count_incremental_reloc(unsigned int symndx)
! 1354: {
! 1355: unsigned int nsyms = this->do_get_global_symbols()->size();
! 1356: gold_assert(symndx < nsyms);
! 1357: gold_assert(this->reloc_counts_ != NULL);
! 1358: ++this->reloc_counts_[symndx];
! 1359: }
! 1360:
! 1361: // Finalize the incremental relocation information.
! 1362: void
! 1363: finalize_incremental_relocs(Layout* layout, bool clear_counts);
! 1364:
! 1365: // Return the index of the next relocation to be written for global symbol
! 1366: // SYMNDX. Only valid after finalize_incremental_relocs() has been called.
! 1367: unsigned int
! 1368: next_incremental_reloc_index(unsigned int symndx)
! 1369: {
! 1370: unsigned int nsyms = this->do_get_global_symbols()->size();
! 1371:
! 1372: gold_assert(this->reloc_counts_ != NULL);
! 1373: gold_assert(this->reloc_bases_ != NULL);
! 1374: gold_assert(symndx < nsyms);
! 1375:
! 1376: unsigned int counter = this->reloc_counts_[symndx]++;
! 1377: return this->reloc_bases_[symndx] + counter;
! 1378: }
! 1379:
! 1380: private:
! 1381: // Mapping from input sections to output section.
! 1382: Output_sections output_sections_;
! 1383: // Mapping from input section index to the information recorded for
! 1384: // the relocations. This is only used for a relocatable link.
! 1385: std::vector<Relocatable_relocs*>* map_to_relocatable_relocs_;
! 1386: // Mappings for merge sections. This is managed by the code in the
! 1387: // Merge_map class.
! 1388: Object_merge_map* object_merge_map_;
! 1389: // Whether we need to wait for output sections to be written before
! 1390: // we can apply relocations.
! 1391: bool relocs_must_follow_section_writes_;
! 1392: // Used to store the relocs data computed by the Read_relocs pass.
! 1393: // Used during garbage collection of unused sections.
! 1394: Read_relocs_data* rd_;
! 1395: // Used to store the symbols data computed by the Read_symbols pass.
! 1396: // Again used during garbage collection when laying out referenced
! 1397: // sections.
! 1398: gold::Symbols_data* sd_;
! 1399: // Per-symbol counts of relocations, for incremental links.
! 1400: unsigned int* reloc_counts_;
! 1401: // Per-symbol base indexes of relocations, for incremental links.
! 1402: unsigned int* reloc_bases_;
! 1403: // Index of the first dynamic relocation for this object.
! 1404: unsigned int first_dyn_reloc_;
! 1405: // Count of dynamic relocations for this object.
! 1406: unsigned int dyn_reloc_count_;
! 1407: };
! 1408:
! 1409: // This class is used to handle relocations against a section symbol
! 1410: // in an SHF_MERGE section. For such a symbol, we need to know the
! 1411: // addend of the relocation before we can determine the final value.
! 1412: // The addend gives us the location in the input section, and we can
! 1413: // determine how it is mapped to the output section. For a
! 1414: // non-section symbol, we apply the addend to the final value of the
! 1415: // symbol; that is done in finalize_local_symbols, and does not use
! 1416: // this class.
! 1417:
! 1418: template<int size>
! 1419: class Merged_symbol_value
! 1420: {
! 1421: public:
! 1422: typedef typename elfcpp::Elf_types<size>::Elf_Addr Value;
! 1423:
! 1424: // We use a hash table to map offsets in the input section to output
! 1425: // addresses.
! 1426: typedef Unordered_map<section_offset_type, Value> Output_addresses;
! 1427:
! 1428: Merged_symbol_value(Value input_value, Value output_start_address)
! 1429: : input_value_(input_value), output_start_address_(output_start_address),
! 1430: output_addresses_()
! 1431: { }
! 1432:
! 1433: // Initialize the hash table.
! 1434: void
! 1435: initialize_input_to_output_map(const Relobj*, unsigned int input_shndx);
! 1436:
! 1437: // Release the hash table to save space.
! 1438: void
! 1439: free_input_to_output_map()
! 1440: { this->output_addresses_.clear(); }
! 1441:
! 1442: // Get the output value corresponding to an addend. The object and
! 1443: // input section index are passed in because the caller will have
! 1444: // them; otherwise we could store them here.
! 1445: Value
! 1446: value(const Relobj* object, unsigned int input_shndx, Value addend) const
! 1447: {
! 1448: // This is a relocation against a section symbol. ADDEND is the
! 1449: // offset in the section. The result should be the start of some
! 1450: // merge area. If the object file wants something else, it should
! 1451: // use a regular symbol rather than a section symbol.
! 1452: // Unfortunately, PR 6658 shows a case in which the object file
! 1453: // refers to the section symbol, but uses a negative ADDEND to
! 1454: // compensate for a PC relative reloc. We can't handle the
! 1455: // general case. However, we can handle the special case of a
! 1456: // negative addend, by assuming that it refers to the start of the
! 1457: // section. Of course, that means that we have to guess when
! 1458: // ADDEND is negative. It is normal to see a 32-bit value here
! 1459: // even when the template parameter size is 64, as 64-bit object
! 1460: // file formats have 32-bit relocations. We know this is a merge
! 1461: // section, so we know it has to fit into memory. So we assume
! 1462: // that we won't see a value larger than a large 32-bit unsigned
! 1463: // value. This will break objects with very very large merge
! 1464: // sections; they probably break in other ways anyhow.
! 1465: Value input_offset = this->input_value_;
! 1466: if (addend < 0xffffff00)
! 1467: {
! 1468: input_offset += addend;
! 1469: addend = 0;
! 1470: }
! 1471: typename Output_addresses::const_iterator p =
! 1472: this->output_addresses_.find(input_offset);
! 1473: if (p != this->output_addresses_.end())
! 1474: return p->second + addend;
! 1475:
! 1476: return (this->value_from_output_section(object, input_shndx, input_offset)
! 1477: + addend);
! 1478: }
! 1479:
! 1480: private:
! 1481: // Get the output value for an input offset if we couldn't find it
! 1482: // in the hash table.
! 1483: Value
! 1484: value_from_output_section(const Relobj*, unsigned int input_shndx,
! 1485: Value input_offset) const;
! 1486:
! 1487: // The value of the section symbol in the input file. This is
! 1488: // normally zero, but could in principle be something else.
! 1489: Value input_value_;
! 1490: // The start address of this merged section in the output file.
! 1491: Value output_start_address_;
! 1492: // A hash table which maps offsets in the input section to output
! 1493: // addresses. This only maps specific offsets, not all offsets.
! 1494: Output_addresses output_addresses_;
! 1495: };
! 1496:
! 1497: // This POD class is holds the value of a symbol. This is used for
! 1498: // local symbols, and for all symbols during relocation processing.
! 1499: // For special sections, such as SHF_MERGE sections, this calls a
! 1500: // function to get the final symbol value.
! 1501:
! 1502: template<int size>
! 1503: class Symbol_value
! 1504: {
! 1505: public:
! 1506: typedef typename elfcpp::Elf_types<size>::Elf_Addr Value;
! 1507:
! 1508: Symbol_value()
! 1509: : output_symtab_index_(0), output_dynsym_index_(-1U), input_shndx_(0),
! 1510: is_ordinary_shndx_(false), is_section_symbol_(false),
! 1511: is_tls_symbol_(false), is_ifunc_symbol_(false), has_output_value_(true)
! 1512: { this->u_.value = 0; }
! 1513:
! 1514: ~Symbol_value()
! 1515: {
! 1516: if (!this->has_output_value_)
! 1517: delete this->u_.merged_symbol_value;
! 1518: }
! 1519:
! 1520: // Get the value of this symbol. OBJECT is the object in which this
! 1521: // symbol is defined, and ADDEND is an addend to add to the value.
! 1522: template<bool big_endian>
! 1523: Value
! 1524: value(const Sized_relobj_file<size, big_endian>* object, Value addend) const
! 1525: {
! 1526: if (this->has_output_value_)
! 1527: return this->u_.value + addend;
! 1528: else
! 1529: {
! 1530: gold_assert(this->is_ordinary_shndx_);
! 1531: return this->u_.merged_symbol_value->value(object, this->input_shndx_,
! 1532: addend);
! 1533: }
! 1534: }
! 1535:
! 1536: // Set the value of this symbol in the output symbol table.
! 1537: void
! 1538: set_output_value(Value value)
! 1539: { this->u_.value = value; }
! 1540:
! 1541: // For a section symbol in a merged section, we need more
! 1542: // information.
! 1543: void
! 1544: set_merged_symbol_value(Merged_symbol_value<size>* msv)
! 1545: {
! 1546: gold_assert(this->is_section_symbol_);
! 1547: this->has_output_value_ = false;
! 1548: this->u_.merged_symbol_value = msv;
! 1549: }
! 1550:
! 1551: // Initialize the input to output map for a section symbol in a
! 1552: // merged section. We also initialize the value of a non-section
! 1553: // symbol in a merged section.
! 1554: void
! 1555: initialize_input_to_output_map(const Relobj* object)
! 1556: {
! 1557: if (!this->has_output_value_)
! 1558: {
! 1559: gold_assert(this->is_section_symbol_ && this->is_ordinary_shndx_);
! 1560: Merged_symbol_value<size>* msv = this->u_.merged_symbol_value;
! 1561: msv->initialize_input_to_output_map(object, this->input_shndx_);
! 1562: }
! 1563: }
! 1564:
! 1565: // Free the input to output map for a section symbol in a merged
! 1566: // section.
! 1567: void
! 1568: free_input_to_output_map()
! 1569: {
! 1570: if (!this->has_output_value_)
! 1571: this->u_.merged_symbol_value->free_input_to_output_map();
! 1572: }
! 1573:
! 1574: // Set the value of the symbol from the input file. This is only
! 1575: // called by count_local_symbols, to communicate the value to
! 1576: // finalize_local_symbols.
! 1577: void
! 1578: set_input_value(Value value)
! 1579: { this->u_.value = value; }
! 1580:
! 1581: // Return the input value. This is only called by
! 1582: // finalize_local_symbols and (in special cases) relocate_section.
! 1583: Value
! 1584: input_value() const
! 1585: { return this->u_.value; }
! 1586:
! 1587: // Return whether we have set the index in the output symbol table
! 1588: // yet.
! 1589: bool
! 1590: is_output_symtab_index_set() const
! 1591: {
! 1592: return (this->output_symtab_index_ != 0
! 1593: && this->output_symtab_index_ != -2U);
! 1594: }
! 1595:
! 1596: // Return whether this symbol may be discarded from the normal
! 1597: // symbol table.
! 1598: bool
! 1599: may_be_discarded_from_output_symtab() const
! 1600: {
! 1601: gold_assert(!this->is_output_symtab_index_set());
! 1602: return this->output_symtab_index_ != -2U;
! 1603: }
! 1604:
! 1605: // Return whether this symbol has an entry in the output symbol
! 1606: // table.
! 1607: bool
! 1608: has_output_symtab_entry() const
! 1609: {
! 1610: gold_assert(this->is_output_symtab_index_set());
! 1611: return this->output_symtab_index_ != -1U;
! 1612: }
! 1613:
! 1614: // Return the index in the output symbol table.
! 1615: unsigned int
! 1616: output_symtab_index() const
! 1617: {
! 1618: gold_assert(this->is_output_symtab_index_set()
! 1619: && this->output_symtab_index_ != -1U);
! 1620: return this->output_symtab_index_;
! 1621: }
! 1622:
! 1623: // Set the index in the output symbol table.
! 1624: void
! 1625: set_output_symtab_index(unsigned int i)
! 1626: {
! 1627: gold_assert(!this->is_output_symtab_index_set());
! 1628: gold_assert(i != 0 && i != -1U && i != -2U);
! 1629: this->output_symtab_index_ = i;
! 1630: }
! 1631:
! 1632: // Record that this symbol should not go into the output symbol
! 1633: // table.
! 1634: void
! 1635: set_no_output_symtab_entry()
! 1636: {
! 1637: gold_assert(this->output_symtab_index_ == 0);
! 1638: this->output_symtab_index_ = -1U;
! 1639: }
! 1640:
! 1641: // Record that this symbol must go into the output symbol table,
! 1642: // because it there is a relocation that uses it.
! 1643: void
! 1644: set_must_have_output_symtab_entry()
! 1645: {
! 1646: gold_assert(!this->is_output_symtab_index_set());
! 1647: this->output_symtab_index_ = -2U;
! 1648: }
! 1649:
! 1650: // Set the index in the output dynamic symbol table.
! 1651: void
! 1652: set_needs_output_dynsym_entry()
! 1653: {
! 1654: gold_assert(!this->is_section_symbol());
! 1655: this->output_dynsym_index_ = 0;
! 1656: }
! 1657:
! 1658: // Return whether this symbol should go into the dynamic symbol
! 1659: // table.
! 1660: bool
! 1661: needs_output_dynsym_entry() const
! 1662: {
! 1663: return this->output_dynsym_index_ != -1U;
! 1664: }
! 1665:
! 1666: // Return whether this symbol has an entry in the dynamic symbol
! 1667: // table.
! 1668: bool
! 1669: has_output_dynsym_entry() const
! 1670: {
! 1671: gold_assert(this->output_dynsym_index_ != 0);
! 1672: return this->output_dynsym_index_ != -1U;
! 1673: }
! 1674:
! 1675: // Record that this symbol should go into the dynamic symbol table.
! 1676: void
! 1677: set_output_dynsym_index(unsigned int i)
! 1678: {
! 1679: gold_assert(this->output_dynsym_index_ == 0);
! 1680: gold_assert(i != 0 && i != -1U);
! 1681: this->output_dynsym_index_ = i;
! 1682: }
! 1683:
! 1684: // Return the index in the output dynamic symbol table.
! 1685: unsigned int
! 1686: output_dynsym_index() const
! 1687: {
! 1688: gold_assert(this->output_dynsym_index_ != 0
! 1689: && this->output_dynsym_index_ != -1U);
! 1690: return this->output_dynsym_index_;
! 1691: }
! 1692:
! 1693: // Set the index of the input section in the input file.
! 1694: void
! 1695: set_input_shndx(unsigned int i, bool is_ordinary)
! 1696: {
! 1697: this->input_shndx_ = i;
! 1698: // input_shndx_ field is a bitfield, so make sure that the value
! 1699: // fits.
! 1700: gold_assert(this->input_shndx_ == i);
! 1701: this->is_ordinary_shndx_ = is_ordinary;
! 1702: }
! 1703:
! 1704: // Return the index of the input section in the input file.
! 1705: unsigned int
! 1706: input_shndx(bool* is_ordinary) const
! 1707: {
! 1708: *is_ordinary = this->is_ordinary_shndx_;
! 1709: return this->input_shndx_;
! 1710: }
! 1711:
! 1712: // Whether this is a section symbol.
! 1713: bool
! 1714: is_section_symbol() const
! 1715: { return this->is_section_symbol_; }
! 1716:
! 1717: // Record that this is a section symbol.
! 1718: void
! 1719: set_is_section_symbol()
! 1720: {
! 1721: gold_assert(!this->needs_output_dynsym_entry());
! 1722: this->is_section_symbol_ = true;
! 1723: }
! 1724:
! 1725: // Record that this is a TLS symbol.
! 1726: void
! 1727: set_is_tls_symbol()
! 1728: { this->is_tls_symbol_ = true; }
! 1729:
! 1730: // Return true if this is a TLS symbol.
! 1731: bool
! 1732: is_tls_symbol() const
! 1733: { return this->is_tls_symbol_; }
! 1734:
! 1735: // Record that this is an IFUNC symbol.
! 1736: void
! 1737: set_is_ifunc_symbol()
! 1738: { this->is_ifunc_symbol_ = true; }
! 1739:
! 1740: // Return true if this is an IFUNC symbol.
! 1741: bool
! 1742: is_ifunc_symbol() const
! 1743: { return this->is_ifunc_symbol_; }
! 1744:
! 1745: // Return true if this has output value.
! 1746: bool
! 1747: has_output_value() const
! 1748: { return this->has_output_value_; }
! 1749:
! 1750: private:
! 1751: // The index of this local symbol in the output symbol table. This
! 1752: // will be 0 if no value has been assigned yet, and the symbol may
! 1753: // be omitted. This will be -1U if the symbol should not go into
! 1754: // the symbol table. This will be -2U if the symbol must go into
! 1755: // the symbol table, but no index has been assigned yet.
! 1756: unsigned int output_symtab_index_;
! 1757: // The index of this local symbol in the dynamic symbol table. This
! 1758: // will be -1U if the symbol should not go into the symbol table.
! 1759: unsigned int output_dynsym_index_;
! 1760: // The section index in the input file in which this symbol is
! 1761: // defined.
! 1762: unsigned int input_shndx_ : 27;
! 1763: // Whether the section index is an ordinary index, not a special
! 1764: // value.
! 1765: bool is_ordinary_shndx_ : 1;
! 1766: // Whether this is a STT_SECTION symbol.
! 1767: bool is_section_symbol_ : 1;
! 1768: // Whether this is a STT_TLS symbol.
! 1769: bool is_tls_symbol_ : 1;
! 1770: // Whether this is a STT_GNU_IFUNC symbol.
! 1771: bool is_ifunc_symbol_ : 1;
! 1772: // Whether this symbol has a value for the output file. This is
! 1773: // normally set to true during Layout::finalize, by
! 1774: // finalize_local_symbols. It will be false for a section symbol in
! 1775: // a merge section, as for such symbols we can not determine the
! 1776: // value to use in a relocation until we see the addend.
! 1777: bool has_output_value_ : 1;
! 1778: union
! 1779: {
! 1780: // This is used if has_output_value_ is true. Between
! 1781: // count_local_symbols and finalize_local_symbols, this is the
! 1782: // value in the input file. After finalize_local_symbols, it is
! 1783: // the value in the output file.
! 1784: Value value;
! 1785: // This is used if has_output_value_ is false. It points to the
! 1786: // information we need to get the value for a merge section.
! 1787: Merged_symbol_value<size>* merged_symbol_value;
! 1788: } u_;
! 1789: };
! 1790:
! 1791: // This type is used to modify relocations for -fsplit-stack. It is
! 1792: // indexed by relocation index, and means that the relocation at that
! 1793: // index should use the symbol from the vector, rather than the one
! 1794: // indicated by the relocation.
! 1795:
! 1796: class Reloc_symbol_changes
! 1797: {
! 1798: public:
! 1799: Reloc_symbol_changes(size_t count)
! 1800: : vec_(count, NULL)
! 1801: { }
! 1802:
! 1803: void
! 1804: set(size_t i, Symbol* sym)
! 1805: { this->vec_[i] = sym; }
! 1806:
! 1807: const Symbol*
! 1808: operator[](size_t i) const
! 1809: { return this->vec_[i]; }
! 1810:
! 1811: private:
! 1812: std::vector<Symbol*> vec_;
! 1813: };
! 1814:
! 1815: // Type for mapping section index to uncompressed size and contents.
! 1816:
! 1817: struct Compressed_section_info
! 1818: {
! 1819: section_size_type size;
! 1820: const unsigned char* contents;
! 1821: };
! 1822: typedef std::map<unsigned int, Compressed_section_info> Compressed_section_map;
! 1823:
! 1824: // Abstract base class for a regular object file, either a real object file
! 1825: // or an incremental (unchanged) object. This is size and endian specific.
! 1826:
! 1827: template<int size, bool big_endian>
! 1828: class Sized_relobj : public Relobj
! 1829: {
! 1830: public:
! 1831: typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
! 1832: typedef Relobj::Symbols Symbols;
! 1833:
! 1834: static const Address invalid_address = static_cast<Address>(0) - 1;
! 1835:
! 1836: Sized_relobj(const std::string& name, Input_file* input_file)
! 1837: : Relobj(name, input_file), local_got_offsets_(), section_offsets_()
! 1838: { }
! 1839:
! 1840: Sized_relobj(const std::string& name, Input_file* input_file,
! 1841: off_t offset)
! 1842: : Relobj(name, input_file, offset), local_got_offsets_(), section_offsets_()
! 1843: { }
! 1844:
! 1845: ~Sized_relobj()
! 1846: { }
! 1847:
! 1848: // If this is a regular object, return a pointer to the Sized_relobj_file
! 1849: // object. Otherwise, return NULL.
! 1850: virtual Sized_relobj_file<size, big_endian>*
! 1851: sized_relobj()
! 1852: { return NULL; }
! 1853:
! 1854: const virtual Sized_relobj_file<size, big_endian>*
! 1855: sized_relobj() const
! 1856: { return NULL; }
! 1857:
! 1858: // Checks if the offset of input section SHNDX within its output
! 1859: // section is invalid.
! 1860: bool
! 1861: is_output_section_offset_invalid(unsigned int shndx) const
! 1862: { return this->get_output_section_offset(shndx) == invalid_address; }
! 1863:
! 1864: // Get the offset of input section SHNDX within its output section.
! 1865: // This is -1 if the input section requires a special mapping, such
! 1866: // as a merge section. The output section can be found in the
! 1867: // output_sections_ field of the parent class Relobj.
! 1868: Address
! 1869: get_output_section_offset(unsigned int shndx) const
! 1870: {
! 1871: gold_assert(shndx < this->section_offsets_.size());
! 1872: return this->section_offsets_[shndx];
! 1873: }
! 1874:
! 1875: // Iterate over local symbols, calling a visitor class V for each GOT offset
! 1876: // associated with a local symbol.
! 1877: void
! 1878: do_for_all_local_got_entries(Got_offset_list::Visitor* v) const;
! 1879:
! 1880: protected:
! 1881: typedef Relobj::Output_sections Output_sections;
! 1882:
! 1883: // Clear the local symbol information.
! 1884: void
! 1885: clear_got_offsets()
! 1886: { this->local_got_offsets_.clear(); }
! 1887:
! 1888: // Return the vector of section offsets.
! 1889: std::vector<Address>&
! 1890: section_offsets()
! 1891: { return this->section_offsets_; }
! 1892:
! 1893: // Get the offset of a section.
! 1894: uint64_t
! 1895: do_output_section_offset(unsigned int shndx) const
! 1896: {
! 1897: Address off = this->get_output_section_offset(shndx);
! 1898: if (off == invalid_address)
! 1899: return -1ULL;
! 1900: return off;
! 1901: }
! 1902:
! 1903: // Set the offset of a section.
! 1904: void
! 1905: do_set_section_offset(unsigned int shndx, uint64_t off)
! 1906: {
! 1907: gold_assert(shndx < this->section_offsets_.size());
! 1908: this->section_offsets_[shndx] =
! 1909: (off == static_cast<uint64_t>(-1)
! 1910: ? invalid_address
! 1911: : convert_types<Address, uint64_t>(off));
! 1912: }
! 1913:
! 1914: // Return whether the local symbol SYMNDX has a GOT offset of type
! 1915: // GOT_TYPE.
! 1916: bool
! 1917: do_local_has_got_offset(unsigned int symndx, unsigned int got_type) const
! 1918: {
! 1919: Local_got_offsets::const_iterator p =
! 1920: this->local_got_offsets_.find(symndx);
! 1921: return (p != this->local_got_offsets_.end()
! 1922: && p->second->get_offset(got_type) != -1U);
! 1923: }
! 1924:
! 1925: // Return the GOT offset of type GOT_TYPE of the local symbol
! 1926: // SYMNDX.
! 1927: unsigned int
! 1928: do_local_got_offset(unsigned int symndx, unsigned int got_type) const
! 1929: {
! 1930: Local_got_offsets::const_iterator p =
! 1931: this->local_got_offsets_.find(symndx);
! 1932: gold_assert(p != this->local_got_offsets_.end());
! 1933: unsigned int off = p->second->get_offset(got_type);
! 1934: gold_assert(off != -1U);
! 1935: return off;
! 1936: }
! 1937:
! 1938: // Set the GOT offset with type GOT_TYPE of the local symbol SYMNDX
! 1939: // to GOT_OFFSET.
! 1940: void
! 1941: do_set_local_got_offset(unsigned int symndx, unsigned int got_type,
! 1942: unsigned int got_offset)
! 1943: {
! 1944: Local_got_offsets::const_iterator p =
! 1945: this->local_got_offsets_.find(symndx);
! 1946: if (p != this->local_got_offsets_.end())
! 1947: p->second->set_offset(got_type, got_offset);
! 1948: else
! 1949: {
! 1950: Got_offset_list* g = new Got_offset_list(got_type, got_offset);
! 1951: std::pair<Local_got_offsets::iterator, bool> ins =
! 1952: this->local_got_offsets_.insert(std::make_pair(symndx, g));
! 1953: gold_assert(ins.second);
! 1954: }
! 1955: }
! 1956:
! 1957: private:
! 1958: // The GOT offsets of local symbols. This map also stores GOT offsets
! 1959: // for tp-relative offsets for TLS symbols.
! 1960: typedef Unordered_map<unsigned int, Got_offset_list*> Local_got_offsets;
! 1961:
! 1962: // GOT offsets for local non-TLS symbols, and tp-relative offsets
! 1963: // for TLS symbols, indexed by symbol number.
! 1964: Local_got_offsets local_got_offsets_;
! 1965: // For each input section, the offset of the input section in its
! 1966: // output section. This is INVALID_ADDRESS if the input section requires a
! 1967: // special mapping.
! 1968: std::vector<Address> section_offsets_;
! 1969: };
! 1970:
! 1971: // A regular object file. This is size and endian specific.
! 1972:
! 1973: template<int size, bool big_endian>
! 1974: class Sized_relobj_file : public Sized_relobj<size, big_endian>
! 1975: {
! 1976: public:
! 1977: typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
! 1978: typedef typename Sized_relobj<size, big_endian>::Symbols Symbols;
! 1979: typedef std::vector<Symbol_value<size> > Local_values;
! 1980:
! 1981: static const Address invalid_address = static_cast<Address>(0) - 1;
! 1982:
! 1983: enum Compute_final_local_value_status
! 1984: {
! 1985: // No error.
! 1986: CFLV_OK,
! 1987: // An error occurred.
! 1988: CFLV_ERROR,
! 1989: // The local symbol has no output section.
! 1990: CFLV_DISCARDED
! 1991: };
! 1992:
! 1993: Sized_relobj_file(const std::string& name,
! 1994: Input_file* input_file,
! 1995: off_t offset,
! 1996: const typename elfcpp::Ehdr<size, big_endian>&);
! 1997:
! 1998: ~Sized_relobj_file();
! 1999:
! 2000: // Set up the object file based on TARGET.
! 2001: void
! 2002: setup()
! 2003: { this->do_setup(); }
! 2004:
! 2005: // Return a pointer to the Sized_relobj_file object.
! 2006: Sized_relobj_file<size, big_endian>*
! 2007: sized_relobj()
! 2008: { return this; }
! 2009:
! 2010: const Sized_relobj_file<size, big_endian>*
! 2011: sized_relobj() const
! 2012: { return this; }
! 2013:
! 2014: // Return the ELF file type.
! 2015: int
! 2016: e_type() const
! 2017: { return this->e_type_; }
! 2018:
! 2019: // Return the number of symbols. This is only valid after
! 2020: // Object::add_symbols has been called.
! 2021: unsigned int
! 2022: symbol_count() const
! 2023: { return this->local_symbol_count_ + this->symbols_.size(); }
! 2024:
! 2025: // If SYM is the index of a global symbol in the object file's
! 2026: // symbol table, return the Symbol object. Otherwise, return NULL.
! 2027: Symbol*
! 2028: global_symbol(unsigned int sym) const
! 2029: {
! 2030: if (sym >= this->local_symbol_count_)
! 2031: {
! 2032: gold_assert(sym - this->local_symbol_count_ < this->symbols_.size());
! 2033: return this->symbols_[sym - this->local_symbol_count_];
! 2034: }
! 2035: return NULL;
! 2036: }
! 2037:
! 2038: // Return the section index of symbol SYM. Set *VALUE to its value
! 2039: // in the object file. Set *IS_ORDINARY if this is an ordinary
! 2040: // section index, not a special code between SHN_LORESERVE and
! 2041: // SHN_HIRESERVE. Note that for a symbol which is not defined in
! 2042: // this object file, this will set *VALUE to 0 and return SHN_UNDEF;
! 2043: // it will not return the final value of the symbol in the link.
! 2044: unsigned int
! 2045: symbol_section_and_value(unsigned int sym, Address* value, bool* is_ordinary);
! 2046:
! 2047: // Return a pointer to the Symbol_value structure which holds the
! 2048: // value of a local symbol.
! 2049: const Symbol_value<size>*
! 2050: local_symbol(unsigned int sym) const
! 2051: {
! 2052: gold_assert(sym < this->local_values_.size());
! 2053: return &this->local_values_[sym];
! 2054: }
! 2055:
! 2056: // Return the index of local symbol SYM in the ordinary symbol
! 2057: // table. A value of -1U means that the symbol is not being output.
! 2058: unsigned int
! 2059: symtab_index(unsigned int sym) const
! 2060: {
! 2061: gold_assert(sym < this->local_values_.size());
! 2062: return this->local_values_[sym].output_symtab_index();
! 2063: }
! 2064:
! 2065: // Return the index of local symbol SYM in the dynamic symbol
! 2066: // table. A value of -1U means that the symbol is not being output.
! 2067: unsigned int
! 2068: dynsym_index(unsigned int sym) const
! 2069: {
! 2070: gold_assert(sym < this->local_values_.size());
! 2071: return this->local_values_[sym].output_dynsym_index();
! 2072: }
! 2073:
! 2074: // Return the input section index of local symbol SYM.
! 2075: unsigned int
! 2076: local_symbol_input_shndx(unsigned int sym, bool* is_ordinary) const
! 2077: {
! 2078: gold_assert(sym < this->local_values_.size());
! 2079: return this->local_values_[sym].input_shndx(is_ordinary);
! 2080: }
! 2081:
! 2082: // Record that local symbol SYM must be in the output symbol table.
! 2083: void
! 2084: set_must_have_output_symtab_entry(unsigned int sym)
! 2085: {
! 2086: gold_assert(sym < this->local_values_.size());
! 2087: this->local_values_[sym].set_must_have_output_symtab_entry();
! 2088: }
! 2089:
! 2090: // Record that local symbol SYM needs a dynamic symbol entry.
! 2091: void
! 2092: set_needs_output_dynsym_entry(unsigned int sym)
! 2093: {
! 2094: gold_assert(sym < this->local_values_.size());
! 2095: this->local_values_[sym].set_needs_output_dynsym_entry();
! 2096: }
! 2097:
! 2098: // Return whether the local symbol SYMNDX has a PLT offset.
! 2099: bool
! 2100: local_has_plt_offset(unsigned int symndx) const;
! 2101:
! 2102: // Set the PLT offset of the local symbol SYMNDX.
! 2103: void
! 2104: set_local_plt_offset(unsigned int symndx, unsigned int plt_offset);
! 2105:
! 2106: // Return the name of the symbol that spans the given offset in the
! 2107: // specified section in this object. This is used only for error
! 2108: // messages and is not particularly efficient.
! 2109: bool
! 2110: get_symbol_location_info(unsigned int shndx, off_t offset,
! 2111: Symbol_location_info* info);
! 2112:
! 2113: // Look for a kept section corresponding to the given discarded section,
! 2114: // and return its output address. This is used only for relocations in
! 2115: // debugging sections.
! 2116: Address
! 2117: map_to_kept_section(unsigned int shndx, bool* found) const;
! 2118:
! 2119: // Compute final local symbol value. R_SYM is the local symbol index.
! 2120: // LV_IN points to a local symbol value containing the input value.
! 2121: // LV_OUT points to a local symbol value storing the final output value,
! 2122: // which must not be a merged symbol value since before calling this
! 2123: // method to avoid memory leak. SYMTAB points to a symbol table.
! 2124: //
! 2125: // The method returns a status code at return. If the return status is
! 2126: // CFLV_OK, *LV_OUT contains the final value. If the return status is
! 2127: // CFLV_ERROR, *LV_OUT is 0. If the return status is CFLV_DISCARDED,
! 2128: // *LV_OUT is not modified.
! 2129: Compute_final_local_value_status
! 2130: compute_final_local_value(unsigned int r_sym,
! 2131: const Symbol_value<size>* lv_in,
! 2132: Symbol_value<size>* lv_out,
! 2133: const Symbol_table* symtab);
! 2134:
! 2135: protected:
! 2136: typedef typename Sized_relobj<size, big_endian>::Output_sections
! 2137: Output_sections;
! 2138:
! 2139: // Set up.
! 2140: virtual void
! 2141: do_setup();
! 2142:
! 2143: // Read the symbols.
! 2144: void
! 2145: do_read_symbols(Read_symbols_data*);
! 2146:
! 2147: // Return the value of a local symbol.
! 2148: uint64_t
! 2149: do_local_symbol_value(unsigned int symndx, uint64_t addend) const
! 2150: {
! 2151: const Symbol_value<size>* symval = this->local_symbol(symndx);
! 2152: return symval->value(this, addend);
! 2153: }
! 2154:
! 2155: // Return the PLT offset for a local symbol. It is an error to call
! 2156: // this if it doesn't have one.
! 2157: unsigned int
! 2158: do_local_plt_offset(unsigned int symndx) const;
! 2159:
! 2160: // Return the number of local symbols.
! 2161: unsigned int
! 2162: do_local_symbol_count() const
! 2163: { return this->local_symbol_count_; }
! 2164:
! 2165: // Return the number of local symbols in the output symbol table.
! 2166: unsigned int
! 2167: do_output_local_symbol_count() const
! 2168: { return this->output_local_symbol_count_; }
! 2169:
! 2170: // Return the number of local symbols in the output symbol table.
! 2171: off_t
! 2172: do_local_symbol_offset() const
! 2173: { return this->local_symbol_offset_; }
! 2174:
! 2175: // Lay out the input sections.
! 2176: void
! 2177: do_layout(Symbol_table*, Layout*, Read_symbols_data*);
! 2178:
! 2179: // Layout sections whose layout was deferred while waiting for
! 2180: // input files from a plugin.
! 2181: void
! 2182: do_layout_deferred_sections(Layout*);
! 2183:
! 2184: // Add the symbols to the symbol table.
! 2185: void
! 2186: do_add_symbols(Symbol_table*, Read_symbols_data*, Layout*);
! 2187:
! 2188: Archive::Should_include
! 2189: do_should_include_member(Symbol_table* symtab, Layout*, Read_symbols_data*,
! 2190: std::string* why);
! 2191:
! 2192: // Iterate over global symbols, calling a visitor class V for each.
! 2193: void
! 2194: do_for_all_global_symbols(Read_symbols_data* sd,
! 2195: Library_base::Symbol_visitor_base* v);
! 2196:
! 2197: // Read the relocs.
! 2198: void
! 2199: do_read_relocs(Read_relocs_data*);
! 2200:
! 2201: // Process the relocs to find list of referenced sections. Used only
! 2202: // during garbage collection.
! 2203: void
! 2204: do_gc_process_relocs(Symbol_table*, Layout*, Read_relocs_data*);
! 2205:
! 2206: // Scan the relocs and adjust the symbol table.
! 2207: void
! 2208: do_scan_relocs(Symbol_table*, Layout*, Read_relocs_data*);
! 2209:
! 2210: // Count the local symbols.
! 2211: void
! 2212: do_count_local_symbols(Stringpool_template<char>*,
! 2213: Stringpool_template<char>*);
! 2214:
! 2215: // Finalize the local symbols.
! 2216: unsigned int
! 2217: do_finalize_local_symbols(unsigned int, off_t, Symbol_table*);
! 2218:
! 2219: // Set the offset where local dynamic symbol information will be stored.
! 2220: unsigned int
! 2221: do_set_local_dynsym_indexes(unsigned int);
! 2222:
! 2223: // Set the offset where local dynamic symbol information will be stored.
! 2224: unsigned int
! 2225: do_set_local_dynsym_offset(off_t);
! 2226:
! 2227: // Relocate the input sections and write out the local symbols.
! 2228: void
! 2229: do_relocate(const Symbol_table* symtab, const Layout*, Output_file* of);
! 2230:
! 2231: // Get the size of a section.
! 2232: uint64_t
! 2233: do_section_size(unsigned int shndx)
! 2234: { return this->elf_file_.section_size(shndx); }
! 2235:
! 2236: // Get the name of a section.
! 2237: std::string
! 2238: do_section_name(unsigned int shndx)
! 2239: { return this->elf_file_.section_name(shndx); }
! 2240:
! 2241: // Return the location of the contents of a section.
! 2242: const unsigned char*
! 2243: do_section_contents(unsigned int shndx, section_size_type* plen,
! 2244: bool cache)
! 2245: {
! 2246: Object::Location loc(this->elf_file_.section_contents(shndx));
! 2247: *plen = convert_to_section_size_type(loc.data_size);
! 2248: if (*plen == 0)
! 2249: {
! 2250: static const unsigned char empty[1] = { '\0' };
! 2251: return empty;
! 2252: }
! 2253: return this->get_view(loc.file_offset, *plen, true, cache);
! 2254: }
! 2255:
! 2256: // Return section flags.
! 2257: uint64_t
! 2258: do_section_flags(unsigned int shndx);
! 2259:
! 2260: // Return section entsize.
! 2261: uint64_t
! 2262: do_section_entsize(unsigned int shndx);
! 2263:
! 2264: // Return section address.
! 2265: uint64_t
! 2266: do_section_address(unsigned int shndx)
! 2267: { return this->elf_file_.section_addr(shndx); }
! 2268:
! 2269: // Return section type.
! 2270: unsigned int
! 2271: do_section_type(unsigned int shndx)
! 2272: { return this->elf_file_.section_type(shndx); }
! 2273:
! 2274: // Return the section link field.
! 2275: unsigned int
! 2276: do_section_link(unsigned int shndx)
! 2277: { return this->elf_file_.section_link(shndx); }
! 2278:
! 2279: // Return the section info field.
! 2280: unsigned int
! 2281: do_section_info(unsigned int shndx)
! 2282: { return this->elf_file_.section_info(shndx); }
! 2283:
! 2284: // Return the section alignment.
! 2285: uint64_t
! 2286: do_section_addralign(unsigned int shndx)
! 2287: { return this->elf_file_.section_addralign(shndx); }
! 2288:
! 2289: // Return the Xindex structure to use.
! 2290: Xindex*
! 2291: do_initialize_xindex();
! 2292:
! 2293: // Get symbol counts.
! 2294: void
! 2295: do_get_global_symbol_counts(const Symbol_table*, size_t*, size_t*) const;
! 2296:
! 2297: // Get the global symbols.
! 2298: const Symbols*
! 2299: do_get_global_symbols() const
! 2300: { return &this->symbols_; }
! 2301:
! 2302: // Adjust a section index if necessary.
! 2303: unsigned int
! 2304: adjust_shndx(unsigned int shndx)
! 2305: {
! 2306: if (shndx >= elfcpp::SHN_LORESERVE)
! 2307: shndx += this->elf_file_.large_shndx_offset();
! 2308: return shndx;
! 2309: }
! 2310:
! 2311: // Initialize input to output maps for section symbols in merged
! 2312: // sections.
! 2313: void
! 2314: initialize_input_to_output_maps();
! 2315:
! 2316: // Free the input to output maps for section symbols in merged
! 2317: // sections.
! 2318: void
! 2319: free_input_to_output_maps();
! 2320:
! 2321: // Return symbol table section index.
! 2322: unsigned int
! 2323: symtab_shndx() const
! 2324: { return this->symtab_shndx_; }
! 2325:
! 2326: // Allow a child class to access the ELF file.
! 2327: elfcpp::Elf_file<size, big_endian, Object>*
! 2328: elf_file()
! 2329: { return &this->elf_file_; }
! 2330:
! 2331: // Allow a child class to access the local values.
! 2332: Local_values*
! 2333: local_values()
! 2334: { return &this->local_values_; }
! 2335:
! 2336: // Views and sizes when relocating.
! 2337: struct View_size
! 2338: {
! 2339: unsigned char* view;
! 2340: typename elfcpp::Elf_types<size>::Elf_Addr address;
! 2341: off_t offset;
! 2342: section_size_type view_size;
! 2343: bool is_input_output_view;
! 2344: bool is_postprocessing_view;
! 2345: bool is_ctors_reverse_view;
! 2346: };
! 2347:
! 2348: typedef std::vector<View_size> Views;
! 2349:
! 2350: // This may be overriden by a child class.
! 2351: virtual void
! 2352: do_relocate_sections(const Symbol_table* symtab, const Layout* layout,
! 2353: const unsigned char* pshdrs, Output_file* of,
! 2354: Views* pviews);
! 2355:
! 2356: // Allow a child to set output local symbol count.
! 2357: void
! 2358: set_output_local_symbol_count(unsigned int value)
! 2359: { this->output_local_symbol_count_ = value; }
! 2360:
! 2361: // Return TRUE if the section is a compressed debug section, and set
! 2362: // *UNCOMPRESSED_SIZE to the size of the uncompressed data.
! 2363: bool
! 2364: do_section_is_compressed(unsigned int shndx,
! 2365: section_size_type* uncompressed_size) const
! 2366: {
! 2367: if (this->compressed_sections_ == NULL)
! 2368: return false;
! 2369: Compressed_section_map::const_iterator p =
! 2370: this->compressed_sections_->find(shndx);
! 2371: if (p != this->compressed_sections_->end())
! 2372: {
! 2373: if (uncompressed_size != NULL)
! 2374: *uncompressed_size = p->second.size;
! 2375: return true;
! 2376: }
! 2377: return false;
! 2378: }
! 2379:
! 2380: // Return a view of the uncompressed contents of a section. Set *PLEN
! 2381: // to the size. Set *IS_NEW to true if the contents need to be deleted
! 2382: // by the caller.
! 2383: const unsigned char*
! 2384: do_decompressed_section_contents(unsigned int shndx,
! 2385: section_size_type* plen,
! 2386: bool* is_new);
! 2387:
! 2388: // Discard any buffers of decompressed sections. This is done
! 2389: // at the end of the Add_symbols task.
! 2390: void
! 2391: do_discard_decompressed_sections();
! 2392:
! 2393: private:
! 2394: // For convenience.
! 2395: typedef Sized_relobj_file<size, big_endian> This;
! 2396: static const int ehdr_size = elfcpp::Elf_sizes<size>::ehdr_size;
! 2397: static const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
! 2398: static const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
! 2399: typedef elfcpp::Shdr<size, big_endian> Shdr;
! 2400:
! 2401: // To keep track of discarded comdat sections, we need to map a member
! 2402: // section index to the object and section index of the corresponding
! 2403: // kept section.
! 2404: struct Kept_comdat_section
! 2405: {
! 2406: Kept_comdat_section(Relobj* a_object, unsigned int a_shndx)
! 2407: : object(a_object), shndx(a_shndx)
! 2408: { }
! 2409: Relobj* object;
! 2410: unsigned int shndx;
! 2411: };
! 2412: typedef std::map<unsigned int, Kept_comdat_section>
! 2413: Kept_comdat_section_table;
! 2414:
! 2415: // Find the SHT_SYMTAB section, given the section headers.
! 2416: void
! 2417: find_symtab(const unsigned char* pshdrs);
! 2418:
! 2419: // Return whether SHDR has the right flags for a GNU style exception
! 2420: // frame section.
! 2421: bool
! 2422: check_eh_frame_flags(const elfcpp::Shdr<size, big_endian>* shdr) const;
! 2423:
! 2424: // Return whether there is a section named .eh_frame which might be
! 2425: // a GNU style exception frame section.
! 2426: bool
! 2427: find_eh_frame(const unsigned char* pshdrs, const char* names,
! 2428: section_size_type names_size) const;
! 2429:
! 2430: // Whether to include a section group in the link.
! 2431: bool
! 2432: include_section_group(Symbol_table*, Layout*, unsigned int, const char*,
! 2433: const unsigned char*, const char*, section_size_type,
! 2434: std::vector<bool>*);
! 2435:
! 2436: // Whether to include a linkonce section in the link.
! 2437: bool
! 2438: include_linkonce_section(Layout*, unsigned int, const char*,
! 2439: const elfcpp::Shdr<size, big_endian>&);
! 2440:
! 2441: // Layout an input section.
! 2442: void
! 2443: layout_section(Layout* layout, unsigned int shndx, const char* name,
! 2444: const typename This::Shdr& shdr, unsigned int reloc_shndx,
! 2445: unsigned int reloc_type);
! 2446:
! 2447: // Layout an input .eh_frame section.
! 2448: void
! 2449: layout_eh_frame_section(Layout* layout, const unsigned char* symbols_data,
! 2450: section_size_type symbols_size,
! 2451: const unsigned char* symbol_names_data,
! 2452: section_size_type symbol_names_size,
! 2453: unsigned int shndx, const typename This::Shdr&,
! 2454: unsigned int reloc_shndx, unsigned int reloc_type);
! 2455:
! 2456: // Write section data to the output file. Record the views and
! 2457: // sizes in VIEWS for use when relocating.
! 2458: void
! 2459: write_sections(const Layout*, const unsigned char* pshdrs, Output_file*,
! 2460: Views*);
! 2461:
! 2462: // Relocate the sections in the output file.
! 2463: void
! 2464: relocate_sections(const Symbol_table* symtab, const Layout* layout,
! 2465: const unsigned char* pshdrs, Output_file* of,
! 2466: Views* pviews)
! 2467: { this->do_relocate_sections(symtab, layout, pshdrs, of, pviews); }
! 2468:
! 2469: // Reverse the words in a section. Used for .ctors sections mapped
! 2470: // to .init_array sections.
! 2471: void
! 2472: reverse_words(unsigned char*, section_size_type);
! 2473:
! 2474: // Scan the input relocations for --emit-relocs.
! 2475: void
! 2476: emit_relocs_scan(Symbol_table*, Layout*, const unsigned char* plocal_syms,
! 2477: const Read_relocs_data::Relocs_list::iterator&);
! 2478:
! 2479: // Scan the input relocations for --emit-relocs, templatized on the
! 2480: // type of the relocation section.
! 2481: template<int sh_type>
! 2482: void
! 2483: emit_relocs_scan_reltype(Symbol_table*, Layout*,
! 2484: const unsigned char* plocal_syms,
! 2485: const Read_relocs_data::Relocs_list::iterator&,
! 2486: Relocatable_relocs*);
! 2487:
! 2488: // Emit the relocs for --emit-relocs.
! 2489: void
! 2490: emit_relocs(const Relocate_info<size, big_endian>*, unsigned int,
! 2491: unsigned int sh_type, const unsigned char* prelocs,
! 2492: size_t reloc_count, Output_section*, Address output_offset,
! 2493: unsigned char* view, Address address,
! 2494: section_size_type view_size,
! 2495: unsigned char* reloc_view, section_size_type reloc_view_size);
! 2496:
! 2497: // Emit the relocs for --emit-relocs, templatized on the type of the
! 2498: // relocation section.
! 2499: template<int sh_type>
! 2500: void
! 2501: emit_relocs_reltype(const Relocate_info<size, big_endian>*, unsigned int,
! 2502: const unsigned char* prelocs, size_t reloc_count,
! 2503: Output_section*, Address output_offset,
! 2504: unsigned char* view, Address address,
! 2505: section_size_type view_size,
! 2506: unsigned char* reloc_view,
! 2507: section_size_type reloc_view_size);
! 2508:
! 2509: // Scan the input relocations for --incremental.
! 2510: void
! 2511: incremental_relocs_scan(const Read_relocs_data::Relocs_list::iterator&);
! 2512:
! 2513: // Scan the input relocations for --incremental, templatized on the
! 2514: // type of the relocation section.
! 2515: template<int sh_type>
! 2516: void
! 2517: incremental_relocs_scan_reltype(
! 2518: const Read_relocs_data::Relocs_list::iterator&);
! 2519:
! 2520: void
! 2521: incremental_relocs_write(const Relocate_info<size, big_endian>*,
! 2522: unsigned int sh_type,
! 2523: const unsigned char* prelocs,
! 2524: size_t reloc_count,
! 2525: Output_section*,
! 2526: Address output_offset,
! 2527: Output_file*);
! 2528:
! 2529: template<int sh_type>
! 2530: void
! 2531: incremental_relocs_write_reltype(const Relocate_info<size, big_endian>*,
! 2532: const unsigned char* prelocs,
! 2533: size_t reloc_count,
! 2534: Output_section*,
! 2535: Address output_offset,
! 2536: Output_file*);
! 2537:
! 2538: // A type shared by split_stack_adjust_reltype and find_functions.
! 2539: typedef std::map<section_offset_type, section_size_type> Function_offsets;
! 2540:
! 2541: // Check for -fsplit-stack routines calling non-split-stack routines.
! 2542: void
! 2543: split_stack_adjust(const Symbol_table*, const unsigned char* pshdrs,
! 2544: unsigned int sh_type, unsigned int shndx,
! 2545: const unsigned char* prelocs, size_t reloc_count,
! 2546: unsigned char* view, section_size_type view_size,
! 2547: Reloc_symbol_changes** reloc_map);
! 2548:
! 2549: template<int sh_type>
! 2550: void
! 2551: split_stack_adjust_reltype(const Symbol_table*, const unsigned char* pshdrs,
! 2552: unsigned int shndx, const unsigned char* prelocs,
! 2553: size_t reloc_count, unsigned char* view,
! 2554: section_size_type view_size,
! 2555: Reloc_symbol_changes** reloc_map);
! 2556:
! 2557: // Find all functions in a section.
! 2558: void
! 2559: find_functions(const unsigned char* pshdrs, unsigned int shndx,
! 2560: Function_offsets*);
! 2561:
! 2562: // Write out the local symbols.
! 2563: void
! 2564: write_local_symbols(Output_file*,
! 2565: const Stringpool_template<char>*,
! 2566: const Stringpool_template<char>*,
! 2567: Output_symtab_xindex*,
! 2568: Output_symtab_xindex*,
! 2569: off_t);
! 2570:
! 2571: // Record a mapping from discarded section SHNDX to the corresponding
! 2572: // kept section.
! 2573: void
! 2574: set_kept_comdat_section(unsigned int shndx, Relobj* kept_object,
! 2575: unsigned int kept_shndx)
! 2576: {
! 2577: Kept_comdat_section kept(kept_object, kept_shndx);
! 2578: this->kept_comdat_sections_.insert(std::make_pair(shndx, kept));
! 2579: }
! 2580:
! 2581: // Find the kept section corresponding to the discarded section
! 2582: // SHNDX. Return true if found.
! 2583: bool
! 2584: get_kept_comdat_section(unsigned int shndx, Relobj** kept_object,
! 2585: unsigned int* kept_shndx) const
! 2586: {
! 2587: typename Kept_comdat_section_table::const_iterator p =
! 2588: this->kept_comdat_sections_.find(shndx);
! 2589: if (p == this->kept_comdat_sections_.end())
! 2590: return false;
! 2591: *kept_object = p->second.object;
! 2592: *kept_shndx = p->second.shndx;
! 2593: return true;
! 2594: }
! 2595:
! 2596: // Compute final local symbol value. R_SYM is the local symbol index.
! 2597: // LV_IN points to a local symbol value containing the input value.
! 2598: // LV_OUT points to a local symbol value storing the final output value,
! 2599: // which must not be a merged symbol value since before calling this
! 2600: // method to avoid memory leak. RELOCATABLE indicates whether we are
! 2601: // linking a relocatable output. OUT_SECTIONS is an array of output
! 2602: // sections. OUT_OFFSETS is an array of offsets of the sections. SYMTAB
! 2603: // points to a symbol table.
! 2604: //
! 2605: // The method returns a status code at return. If the return status is
! 2606: // CFLV_OK, *LV_OUT contains the final value. If the return status is
! 2607: // CFLV_ERROR, *LV_OUT is 0. If the return status is CFLV_DISCARDED,
! 2608: // *LV_OUT is not modified.
! 2609: inline Compute_final_local_value_status
! 2610: compute_final_local_value_internal(unsigned int r_sym,
! 2611: const Symbol_value<size>* lv_in,
! 2612: Symbol_value<size>* lv_out,
! 2613: bool relocatable,
! 2614: const Output_sections& out_sections,
! 2615: const std::vector<Address>& out_offsets,
! 2616: const Symbol_table* symtab);
! 2617:
! 2618: // The PLT offsets of local symbols.
! 2619: typedef Unordered_map<unsigned int, unsigned int> Local_plt_offsets;
! 2620:
! 2621: // Saved information for sections whose layout was deferred.
! 2622: struct Deferred_layout
! 2623: {
! 2624: static const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
! 2625: Deferred_layout(unsigned int shndx, const char* name,
! 2626: const unsigned char* pshdr,
! 2627: unsigned int reloc_shndx, unsigned int reloc_type)
! 2628: : shndx_(shndx), name_(name), reloc_shndx_(reloc_shndx),
! 2629: reloc_type_(reloc_type)
! 2630: {
! 2631: memcpy(this->shdr_data_, pshdr, shdr_size);
! 2632: }
! 2633: unsigned int shndx_;
! 2634: std::string name_;
! 2635: unsigned int reloc_shndx_;
! 2636: unsigned int reloc_type_;
! 2637: unsigned char shdr_data_[shdr_size];
! 2638: };
! 2639:
! 2640: // General access to the ELF file.
! 2641: elfcpp::Elf_file<size, big_endian, Object> elf_file_;
! 2642: // Type of ELF file (ET_REL or ET_EXEC). ET_EXEC files are allowed
! 2643: // as input files only for the --just-symbols option.
! 2644: int e_type_;
! 2645: // Index of SHT_SYMTAB section.
! 2646: unsigned int symtab_shndx_;
! 2647: // The number of local symbols.
! 2648: unsigned int local_symbol_count_;
! 2649: // The number of local symbols which go into the output file.
! 2650: unsigned int output_local_symbol_count_;
! 2651: // The number of local symbols which go into the output file's dynamic
! 2652: // symbol table.
! 2653: unsigned int output_local_dynsym_count_;
! 2654: // The entries in the symbol table for the external symbols.
! 2655: Symbols symbols_;
! 2656: // Number of symbols defined in object file itself.
! 2657: size_t defined_count_;
! 2658: // File offset for local symbols (relative to start of symbol table).
! 2659: off_t local_symbol_offset_;
! 2660: // File offset for local dynamic symbols (absolute).
! 2661: off_t local_dynsym_offset_;
! 2662: // Values of local symbols.
! 2663: Local_values local_values_;
! 2664: // PLT offsets for local symbols.
! 2665: Local_plt_offsets local_plt_offsets_;
! 2666: // Table mapping discarded comdat sections to corresponding kept sections.
! 2667: Kept_comdat_section_table kept_comdat_sections_;
! 2668: // Whether this object has a GNU style .eh_frame section.
! 2669: bool has_eh_frame_;
! 2670: // If this object has a GNU style .eh_frame section that is discarded in
! 2671: // output, record the index here. Otherwise it is -1U.
! 2672: unsigned int discarded_eh_frame_shndx_;
! 2673: // The list of sections whose layout was deferred.
! 2674: std::vector<Deferred_layout> deferred_layout_;
! 2675: // The list of relocation sections whose layout was deferred.
! 2676: std::vector<Deferred_layout> deferred_layout_relocs_;
! 2677: // For compressed debug sections, map section index to uncompressed size
! 2678: // and contents.
! 2679: Compressed_section_map* compressed_sections_;
! 2680: };
! 2681:
! 2682: // A class to manage the list of all objects.
! 2683:
! 2684: class Input_objects
! 2685: {
! 2686: public:
! 2687: Input_objects()
! 2688: : relobj_list_(), dynobj_list_(), sonames_(), cref_(NULL)
! 2689: { }
! 2690:
! 2691: // The type of the list of input relocateable objects.
! 2692: typedef std::vector<Relobj*> Relobj_list;
! 2693: typedef Relobj_list::const_iterator Relobj_iterator;
! 2694:
! 2695: // The type of the list of input dynamic objects.
! 2696: typedef std::vector<Dynobj*> Dynobj_list;
! 2697: typedef Dynobj_list::const_iterator Dynobj_iterator;
! 2698:
! 2699: // Add an object to the list. Return true if all is well, or false
! 2700: // if this object should be ignored.
! 2701: bool
! 2702: add_object(Object*);
! 2703:
! 2704: // Start processing an archive.
! 2705: void
! 2706: archive_start(Archive*);
! 2707:
! 2708: // Stop processing an archive.
! 2709: void
! 2710: archive_stop(Archive*);
! 2711:
! 2712: // For each dynamic object, check whether we've seen all of its
! 2713: // explicit dependencies.
! 2714: void
! 2715: check_dynamic_dependencies() const;
! 2716:
! 2717: // Return whether an object was found in the system library
! 2718: // directory.
! 2719: bool
! 2720: found_in_system_library_directory(const Object*) const;
! 2721:
! 2722: // Print symbol counts.
! 2723: void
! 2724: print_symbol_counts(const Symbol_table*) const;
! 2725:
! 2726: // Print a cross reference table.
! 2727: void
! 2728: print_cref(const Symbol_table*, FILE*) const;
! 2729:
! 2730: // Iterate over all regular objects.
! 2731:
! 2732: Relobj_iterator
! 2733: relobj_begin() const
! 2734: { return this->relobj_list_.begin(); }
! 2735:
! 2736: Relobj_iterator
! 2737: relobj_end() const
! 2738: { return this->relobj_list_.end(); }
! 2739:
! 2740: // Iterate over all dynamic objects.
! 2741:
! 2742: Dynobj_iterator
! 2743: dynobj_begin() const
! 2744: { return this->dynobj_list_.begin(); }
! 2745:
! 2746: Dynobj_iterator
! 2747: dynobj_end() const
! 2748: { return this->dynobj_list_.end(); }
! 2749:
! 2750: // Return whether we have seen any dynamic objects.
! 2751: bool
! 2752: any_dynamic() const
! 2753: { return !this->dynobj_list_.empty(); }
! 2754:
! 2755: // Return the number of non dynamic objects.
! 2756: int
! 2757: number_of_relobjs() const
! 2758: { return this->relobj_list_.size(); }
! 2759:
! 2760: // Return the number of input objects.
! 2761: int
! 2762: number_of_input_objects() const
! 2763: { return this->relobj_list_.size() + this->dynobj_list_.size(); }
! 2764:
! 2765: private:
! 2766: Input_objects(const Input_objects&);
! 2767: Input_objects& operator=(const Input_objects&);
! 2768:
! 2769: // The list of ordinary objects included in the link.
! 2770: Relobj_list relobj_list_;
! 2771: // The list of dynamic objects included in the link.
! 2772: Dynobj_list dynobj_list_;
! 2773: // SONAMEs that we have seen.
! 2774: Unordered_set<std::string> sonames_;
! 2775: // Manage cross-references if requested.
! 2776: Cref* cref_;
! 2777: };
! 2778:
! 2779: // Some of the information we pass to the relocation routines. We
! 2780: // group this together to avoid passing a dozen different arguments.
! 2781:
! 2782: template<int size, bool big_endian>
! 2783: struct Relocate_info
! 2784: {
! 2785: // Symbol table.
! 2786: const Symbol_table* symtab;
! 2787: // Layout.
! 2788: const Layout* layout;
! 2789: // Object being relocated.
! 2790: Sized_relobj_file<size, big_endian>* object;
! 2791: // Section index of relocation section.
! 2792: unsigned int reloc_shndx;
! 2793: // Section header of relocation section.
! 2794: const unsigned char* reloc_shdr;
! 2795: // Section index of section being relocated.
! 2796: unsigned int data_shndx;
! 2797: // Section header of data section.
! 2798: const unsigned char* data_shdr;
! 2799:
! 2800: // Return a string showing the location of a relocation. This is
! 2801: // only used for error messages.
! 2802: std::string
! 2803: location(size_t relnum, off_t reloffset) const;
! 2804: };
! 2805:
! 2806: // This is used to represent a section in an object and is used as the
! 2807: // key type for various section maps.
! 2808: typedef std::pair<Object*, unsigned int> Section_id;
! 2809:
! 2810: // This is similar to Section_id but is used when the section
! 2811: // pointers are const.
! 2812: typedef std::pair<const Object*, unsigned int> Const_section_id;
! 2813:
! 2814: // The hash value is based on the address of an object in memory during
! 2815: // linking. It is okay to use this for looking up sections but never use
! 2816: // this in an unordered container that we want to traverse in a repeatable
! 2817: // manner.
! 2818:
! 2819: struct Section_id_hash
! 2820: {
! 2821: size_t operator()(const Section_id& loc) const
! 2822: { return reinterpret_cast<uintptr_t>(loc.first) ^ loc.second; }
! 2823: };
! 2824:
! 2825: struct Const_section_id_hash
! 2826: {
! 2827: size_t operator()(const Const_section_id& loc) const
! 2828: { return reinterpret_cast<uintptr_t>(loc.first) ^ loc.second; }
! 2829: };
! 2830:
! 2831: // Return whether INPUT_FILE contains an ELF object start at file
! 2832: // offset OFFSET. This sets *START to point to a view of the start of
! 2833: // the file. It sets *READ_SIZE to the number of bytes in the view.
! 2834:
! 2835: extern bool
! 2836: is_elf_object(Input_file* input_file, off_t offset,
! 2837: const unsigned char** start, int* read_size);
! 2838:
! 2839: // Return an Object appropriate for the input file. P is BYTES long,
! 2840: // and holds the ELF header. If PUNCONFIGURED is not NULL, then if
! 2841: // this sees an object the linker is not configured to support, it
! 2842: // sets *PUNCONFIGURED to true and returns NULL without giving an
! 2843: // error message.
! 2844:
! 2845: extern Object*
! 2846: make_elf_object(const std::string& name, Input_file*,
! 2847: off_t offset, const unsigned char* p,
! 2848: section_offset_type bytes, bool* punconfigured);
! 2849:
! 2850: } // end namespace gold
! 2851:
! 2852: #endif // !defined(GOLD_OBJECT_H)
CVSweb <webmaster@jp.NetBSD.org>