X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gold%2Flayout.h;h=8584a0cabf5e19a0ddea476c3d490beeb83cabd0;hb=e94cf1277329c4eaba3b398b446e693550463c77;hp=131d6a6cd38f691a1b6d95e24c93dceda8880edc;hpb=cb29561284eaa37c5c8967e49a5db0a4064368bf;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/layout.h b/gold/layout.h index 131d6a6cd3..8584a0cabf 100644 --- a/gold/layout.h +++ b/gold/layout.h @@ -1,6 +1,6 @@ // layout.h -- lay out output file sections for gold -*- C++ -*- -// Copyright 2006, 2007 Free Software Foundation, Inc. +// Copyright 2006, 2007, 2008 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -23,11 +23,13 @@ #ifndef GOLD_LAYOUT_H #define GOLD_LAYOUT_H +#include #include #include #include #include +#include "script.h" #include "workqueue.h" #include "object.h" #include "dynobj.h" @@ -45,6 +47,7 @@ class Output_section_headers; class Output_segment; class Output_data; class Output_data_dynamic; +class Output_symtab_xindex; class Eh_frame; class Target; @@ -60,9 +63,10 @@ class Layout_task_runner : public Task_function_runner Layout_task_runner(const General_options& options, const Input_objects* input_objects, Symbol_table* symtab, + Target* target, Layout* layout) : options_(options), input_objects_(input_objects), symtab_(symtab), - layout_(layout) + target_(target), layout_(layout) { } // Run the operation. @@ -76,6 +80,7 @@ class Layout_task_runner : public Task_function_runner const General_options& options_; const Input_objects* input_objects_; Symbol_table* symtab_; + Target* target_; Layout* layout_; }; @@ -84,7 +89,7 @@ class Layout_task_runner : public Task_function_runner class Layout { public: - Layout(const General_options& options); + Layout(const General_options& options, Script_options*); // Given an input section SHNDX, named NAME, with data in SHDR, from // the object file OBJECT, return the output section where this @@ -99,6 +104,29 @@ class Layout const char* name, const elfcpp::Shdr& shdr, unsigned int reloc_shndx, unsigned int reloc_type, off_t* offset); + // Layout an input reloc section when doing a relocatable link. The + // section is RELOC_SHNDX in OBJECT, with data in SHDR. + // DATA_SECTION is the reloc section to which it refers. RR is the + // relocatable information. + template + Output_section* + layout_reloc(Sized_relobj* object, + unsigned int reloc_shndx, + const elfcpp::Shdr& shdr, + Output_section* data_section, + Relocatable_relocs* rr); + + // Layout a group section when doing a relocatable link. + template + void + layout_group(Symbol_table* symtab, + Sized_relobj* object, + unsigned int group_shndx, + const char* group_section_name, + const char* signature, + const elfcpp::Shdr& shdr, + const elfcpp::Elf_Word* contents); + // Like layout, only for exception frame sections. OBJECT is an // object file. SYMBOLS is the contents of the symbol table // section, with size SYMBOLS_SIZE. SYMBOL_NAMES is the contents of @@ -136,11 +164,25 @@ class Layout // Create dynamic sections if necessary. void - create_initial_dynamic_sections(const Input_objects*, Symbol_table*); + create_initial_dynamic_sections(Symbol_table*); // Define __start and __stop symbols for output sections. void - define_section_symbols(Symbol_table*, const Target*); + define_section_symbols(Symbol_table*); + + // Create sections for linker scripts. + void + create_script_sections() + { this->script_options_->create_script_sections(this); } + + // Define symbols from any linker script. + void + define_script_symbols(Symbol_table* symtab) + { this->script_options_->add_symbols_to_table(symtab); } + + // Define symbols for group signatures. + void + define_group_signatures(Symbol_table*); // Return the Stringpool used for symbol names. const Stringpool* @@ -153,22 +195,51 @@ class Layout dynpool() const { return &this->dynpool_; } + // Return the symtab_xindex section used to hold large section + // indexes for the normal symbol table. + Output_symtab_xindex* + symtab_xindex() const + { return this->symtab_xindex_; } + + // Return the dynsym_xindex section used to hold large section + // indexes for the dynamic symbol table. + Output_symtab_xindex* + dynsym_xindex() const + { return this->dynsym_xindex_; } + // Return whether a section is a .gnu.linkonce section, given the // section name. static inline bool is_linkonce(const char* name) { return strncmp(name, ".gnu.linkonce", sizeof(".gnu.linkonce") - 1) == 0; } + // Return true if a section is a debugging section. + static inline bool + is_debug_info_section(const char* name) + { + // Debugging sections can only be recognized by name. + return (strncmp(name, ".debug", sizeof(".debug") - 1) == 0 + || strncmp(name, ".gnu.linkonce.wi.", + sizeof(".gnu.linkonce.wi.") - 1) == 0 + || strncmp(name, ".line", sizeof(".line") - 1) == 0 + || strncmp(name, ".stab", sizeof(".stab") - 1) == 0); + } + // Record the signature of a comdat section, and return whether to // include it in the link. The GROUP parameter is true for a // section group signature, false for a signature derived from a // .gnu.linkonce section. bool - add_comdat(const char*, bool group); + add_comdat(Relobj*, unsigned int, const std::string&, bool group); + + // Find the given comdat signature, and return the object and section + // index of the kept group. + Relobj* + find_kept_object(const std::string&, unsigned int*) const; // Finalize the layout after all the input sections have been added. off_t - finalize(const Input_objects*, Symbol_table*, const Task*); + finalize(const Input_objects*, Symbol_table*, Target*, const Task*); // Return whether any sections require postprocessing. bool @@ -231,6 +302,10 @@ class Layout find_output_segment(elfcpp::PT type, elfcpp::Elf_Word set, elfcpp::Elf_Word clear) const; + // Return the number of segments we expect to produce. + size_t + expected_segment_count() const; + // Set a flag to indicate that an object file uses the static TLS model. void set_has_static_tls() @@ -241,15 +316,32 @@ class Layout has_static_tls() const { return this->has_static_tls_; } + // Return the options which may be set by a linker script. + Script_options* + script_options() + { return this->script_options_; } + + const Script_options* + script_options() const + { return this->script_options_; } + + // Compute and write out the build ID if needed. + void + write_build_id(Output_file*) const; + + // Rewrite output file in binary format. + void + write_binary(Output_file* in) const; + // Dump statistical information to stderr. void print_stats() const; - // The list of segments. + // A list of segments. typedef std::vector Segment_list; - // The list of sections not attached to a segment. + // A list of sections. typedef std::vector Section_list; @@ -257,6 +349,32 @@ class Layout // either a section or a segment. typedef std::vector Data_list; + // Store the allocated sections into the section list. This is used + // by the linker script code. + void + get_allocated_sections(Section_list*) const; + + // Make a section for a linker script to hold data. + Output_section* + make_output_section_for_script(const char* name); + + // Make a segment. This is used by the linker script code. + Output_segment* + make_output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags); + + // Return the number of segments. + size_t + segment_count() const + { return this->segment_list_.size(); } + + // Map from section flags to segment flags. + static elfcpp::Elf_Word + section_flags_to_segment(elfcpp::Elf_Xword flags); + + // Attach sections to segments. + void + attach_sections_to_segments(); + private: Layout(const Layout&); Layout& operator=(const Layout&); @@ -272,6 +390,30 @@ class Layout static const Linkonce_mapping linkonce_mapping[]; static const int linkonce_mapping_count; + // During a relocatable link, a list of group sections and + // signatures. + struct Group_signature + { + // The group section. + Output_section* section; + // The signature. + const char* signature; + + Group_signature() + : section(NULL), signature(NULL) + { } + + Group_signature(Output_section* sectiona, const char* signaturea) + : section(sectiona), signature(signaturea) + { } + }; + typedef std::vector Group_signatures; + + // Create a .note section, filling in the header. + Output_section* + create_note(const char* name, int note_type, size_t descsz, + bool allocate, size_t* trailing_padding); + // Create a .note section for gold. void create_gold_note(); @@ -280,6 +422,10 @@ class Layout void create_executable_stack_info(const Target*); + // Create a build ID note if needed. + void + create_build_id(); + // Find the first read-only PT_LOAD segment, creating one if // necessary. Output_segment* @@ -292,7 +438,8 @@ class Layout // Create the output sections for the symbol table. void - create_symtab_sections(const Input_objects*, Symbol_table*, off_t*); + create_symtab_sections(const Input_objects*, Symbol_table*, + unsigned int, off_t*); // Create the .shstrtab section. Output_section* @@ -300,12 +447,12 @@ class Layout // Create the section header table. void - create_shdrs(off_t*); + create_shdrs(const Output_section* shstrtab_section, off_t*); // Create the dynamic symbol table. void - create_dynamic_symtab(const Input_objects*, const Target*, - Symbol_table*, Output_section** pdynstr, + create_dynamic_symtab(const Input_objects*, Symbol_table*, + Output_section** pdynstr, unsigned int* plocal_dynamic_count, std::vector* pdynamic_symbols, Versions* versions); @@ -336,8 +483,7 @@ class Layout const Symbol_table*, unsigned int local_symcount, const std::vector& dynamic_symbols, - const Output_section* dynstr - ACCEPT_SIZE_ENDIAN); + const Output_section* dynstr); // Return whether to include this section in the link. template @@ -356,20 +502,43 @@ class Layout static const char* linkonce_output_name(const char* name, size_t* plen); + // Return the number of allocated output sections. + size_t + allocated_output_section_count() const; + // Return the output section for NAME, TYPE and FLAGS. Output_section* get_output_section(const char* name, Stringpool::Key name_key, elfcpp::Elf_Word type, elfcpp::Elf_Xword flags); + // Choose the output section for NAME in RELOBJ. + Output_section* + choose_output_section(const Relobj* relobj, const char* name, + elfcpp::Elf_Word type, elfcpp::Elf_Xword flags, + bool is_input_section); + // Create a new Output_section. Output_section* make_output_section(const char* name, elfcpp::Elf_Word type, elfcpp::Elf_Xword flags); + // Attach a section to a segment. + void + attach_section_to_segment(Output_section*); + + // Attach an allocated section to a segment. + void + attach_allocated_section_to_segment(Output_section*); + // Set the final file offsets of all the segments. off_t set_segment_offsets(const Target*, Output_segment*, unsigned int* pshndx); + // Set the file offsets of the sections when doing a relocatable + // link. + off_t + set_relocatable_section_offsets(Output_data*, unsigned int* pshndx); + // Set the final file offsets of all the sections not associated // with a segment. We set section offsets in three passes: the // first handles all allocated sections, the second sections that @@ -390,16 +559,28 @@ class Layout unsigned int set_section_indexes(unsigned int pshndx); + // Set the section addresses when using a script. + Output_segment* + set_section_addresses_from_script(Symbol_table*); + // Return whether SEG1 comes before SEG2 in the output file. static bool segment_precedes(const Output_segment* seg1, const Output_segment* seg2); - // Map from section flags to segment flags. - static elfcpp::Elf_Word - section_flags_to_segment(elfcpp::Elf_Xword flags); - // A mapping used for group signatures. - typedef Unordered_map Signatures; + struct Kept_section + { + Kept_section() + : object_(NULL), shndx_(0), group_(false) + { } + Kept_section(Relobj* object, unsigned int shndx, bool group) + : object_(object), shndx_(shndx), group_(group) + { } + Relobj* object_; + unsigned int shndx_; + bool group_; + }; + typedef Unordered_map Signatures; // Mapping from input section name/type/flags to output section. We // use canonicalized strings here. @@ -426,6 +607,8 @@ class Layout // A reference to the options on the command line. const General_options& options_; + // Information set by scripts or by command line options. + Script_options* script_options_; // The output section names. Stringpool namepool_; // The output symbol names. @@ -443,6 +626,8 @@ class Layout // The list of output sections which are not attached to any output // segment. Section_list unattached_section_list_; + // Whether we have attached the sections to the segments. + bool sections_are_attached_; // The list of unattached Output_data objects which require special // handling because they are not Output_sections. Data_list special_output_list_; @@ -452,8 +637,12 @@ class Layout Output_segment* tls_segment_; // The SHT_SYMTAB output section. Output_section* symtab_section_; + // The SHT_SYMTAB_SHNDX for the regular symbol table if there is one. + Output_symtab_xindex* symtab_xindex_; // The SHT_DYNSYM output section if there is one. Output_section* dynsym_section_; + // The SHT_SYMTAB_SHNDX for the dynamic symbol table if there is one. + Output_symtab_xindex* dynsym_xindex_; // The SHT_DYNAMIC output section if there is one. Output_section* dynamic_section_; // The dynamic data which goes into dynamic_section_. @@ -462,8 +651,14 @@ class Layout Output_section* eh_frame_section_; // The exception frame data for eh_frame_section_. Eh_frame* eh_frame_data_; + // Whether we have added eh_frame_data_ to the .eh_frame section. + bool added_eh_frame_data_; // The exception frame header output section if there is one. Output_section* eh_frame_hdr_section_; + // The space for the build ID checksum if there is one. + Output_section_data* build_id_note_; + // A list of group sections and their signatures. + Group_signatures group_signatures_; // The size of the output file. off_t output_file_size_; // Whether we have seen an object file marked to require an @@ -559,12 +754,13 @@ class Write_data_task : public Task class Write_symbols_task : public Task { public: - Write_symbols_task(const Symbol_table* symtab, + Write_symbols_task(const Layout* layout, const Symbol_table* symtab, const Input_objects* input_objects, const Stringpool* sympool, const Stringpool* dynpool, Output_file* of, Task_token* final_blocker) - : symtab_(symtab), input_objects_(input_objects), sympool_(sympool), - dynpool_(dynpool), of_(of), final_blocker_(final_blocker) + : layout_(layout), symtab_(symtab), input_objects_(input_objects), + sympool_(sympool), dynpool_(dynpool), of_(of), + final_blocker_(final_blocker) { } // The standard Task methods. @@ -583,6 +779,7 @@ class Write_symbols_task : public Task { return "Write_symbols_task"; } private: + const Layout* layout_; const Symbol_table* symtab_; const Input_objects* input_objects_; const Stringpool* sympool_; @@ -634,8 +831,9 @@ class Write_after_input_sections_task : public Task class Close_task_runner : public Task_function_runner { public: - Close_task_runner(Output_file* of) - : of_(of) + Close_task_runner(const General_options* options, const Layout* layout, + Output_file* of) + : options_(options), layout_(layout), of_(of) { } // Run the operation. @@ -643,6 +841,8 @@ class Close_task_runner : public Task_function_runner run(Workqueue*, const Task*); private: + const General_options* options_; + const Layout* layout_; Output_file* of_; };