X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gold%2Flayout.h;h=8305b2af76b35b613edc4742bde1a4b5dccfce10;hb=32641fa9259dbe2e576add1992434f404d1d6881;hp=1afe913f1e4793ea8666179ec589c0a9dd9607ab;hpb=10b4f10252b11483486df1be14037c1dd4c554bb;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/layout.h b/gold/layout.h index 1afe913f1e..8305b2af76 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, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +// Copyright (C) 2006-2018 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -58,6 +58,7 @@ class Output_symtab_xindex; class Output_reduced_debug_abbrev_section; class Output_reduced_debug_info_section; class Eh_frame; +class Gdb_index; class Target; struct Timespec; @@ -65,40 +66,70 @@ struct Timespec; extern bool is_compressed_debug_section(const char* secname); +// Return the name of the corresponding uncompressed debug section. +extern std::string +corresponding_uncompressed_section_name(std::string secname); + // Maintain a list of free space within a section, segment, or file. // Used for incremental update links. class Free_list { public: + struct Free_list_node + { + Free_list_node(off_t start, off_t end) + : start_(start), end_(end) + { } + off_t start_; + off_t end_; + }; + typedef std::list::const_iterator Const_iterator; + Free_list() - : list_(), last_remove_(list_.begin()), extend_(false), length_(0) + : list_(), last_remove_(list_.begin()), extend_(false), length_(0), + min_hole_(0) { } + // Initialize the free list for a section of length LEN. + // If EXTEND is true, free space may be allocated past the end. void init(off_t len, bool extend); + // Set the minimum hole size that is allowed when allocating + // from the free list. + void + set_min_hole_size(off_t min_hole) + { this->min_hole_ = min_hole; } + + // Remove a chunk from the free list. void remove(off_t start, off_t end); + // Allocate a chunk of space from the free list of length LEN, + // with alignment ALIGN, and minimum offset MINOFF. off_t allocate(off_t len, uint64_t align, off_t minoff); + // Return an iterator for the beginning of the free list. + Const_iterator + begin() const + { return this->list_.begin(); } + + // Return an iterator for the end of the free list. + Const_iterator + end() const + { return this->list_.end(); } + + // Dump the free list (for debugging). void dump(); + // Print usage statistics. static void print_stats(); private: - struct Free_list_node - { - Free_list_node(off_t start, off_t end) - : start_(start), end_(end) - { } - off_t start_; - off_t end_; - }; typedef std::list::iterator Iterator; // The free list. @@ -113,6 +144,10 @@ class Free_list // The total length of the section, segment, or file. off_t length_; + // The minimum hole size allowed. When allocating from the free list, + // we must not leave a hole smaller than this. + off_t min_hole_; + // Statistics: // The total number of free lists used. static unsigned int num_lists; @@ -140,7 +175,7 @@ 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, + Target* target, Layout* layout, Mapfile* mapfile) : options_(options), input_objects_(input_objects), symtab_(symtab), @@ -387,9 +422,21 @@ enum Output_section_order // The PLT. ORDER_PLT, + // The hot text sections, prefixed by .text.hot. + ORDER_TEXT_HOT, + // The regular text sections. ORDER_TEXT, + // The startup text sections, prefixed by .text.startup. + ORDER_TEXT_STARTUP, + + // The startup text sections, prefixed by .text.startup. + ORDER_TEXT_EXIT, + + // The unlikely text sections, prefixed by .text.unlikely. + ORDER_TEXT_UNLIKELY, + // The .fini section. ORDER_FINI, @@ -490,7 +537,61 @@ class Layout Output_section* layout(Sized_relobj_file *object, unsigned int shndx, const char* name, const elfcpp::Shdr& shdr, - unsigned int reloc_shndx, unsigned int reloc_type, off_t* offset); + unsigned int sh_type, unsigned int reloc_shndx, + unsigned int reloc_type, off_t* offset); + + std::map* + get_section_order_map() + { return &this->section_order_map_; } + + // Struct to store segment info when mapping some input sections to + // unique segments using linker plugins. Mapping an input section to + // a unique segment is done by first placing such input sections in + // unique output sections and then mapping the output section to a + // unique segment. NAME is the name of the output section. FLAGS + // and ALIGN are the extra flags and alignment of the segment. + struct Unique_segment_info + { + // Identifier for the segment. ELF segments don't have names. This + // is used as the name of the output section mapped to the segment. + const char* name; + // Additional segment flags. + uint64_t flags; + // Segment alignment. + uint64_t align; + }; + + // Mapping from input section to segment. + typedef std::map + Section_segment_map; + + // Maps section SECN to SEGMENT s. + void + insert_section_segment_map(Const_section_id secn, Unique_segment_info *s); + + // Some input sections require special ordering, for compatibility + // with GNU ld. Given the name of an input section, return -1 if it + // does not require special ordering. Otherwise, return the index + // by which it should be ordered compared to other input sections + // that require special ordering. + static int + special_ordering_of_input_section(const char* name); + + bool + is_section_ordering_specified() + { return this->section_ordering_specified_; } + + void + set_section_ordering_specified() + { this->section_ordering_specified_ = true; } + + bool + is_unique_segment_for_sections_specified() const + { return this->unique_segment_for_sections_specified_; } + + void + set_unique_segment_for_sections_specified() + { this->unique_segment_for_sections_specified_ = true; } // For incremental updates, allocate a block of memory from the // free list. Find a block starting at or after MINOFF. @@ -501,6 +602,8 @@ class Layout unsigned int find_section_order_index(const std::string&); + // Read the sequence of input sections from the file specified with + // linker option --section-ordering-file. void read_layout_from_file(); @@ -549,6 +652,39 @@ class Layout unsigned int reloc_shndx, unsigned int reloc_type, off_t* offset); + // After processing all input files, we call this to make sure that + // the optimized .eh_frame sections have been added to the output + // section. + void + finalize_eh_frame_section(); + + // Add .eh_frame information for a PLT. The FDE must start with a + // 4-byte PC-relative reference to the start of the PLT, followed by + // a 4-byte size of PLT. + void + add_eh_frame_for_plt(Output_data* plt, const unsigned char* cie_data, + size_t cie_length, const unsigned char* fde_data, + size_t fde_length); + + // Remove .eh_frame information for a PLT. FDEs using the CIE must + // be removed in reverse order to the order they were added. + void + remove_eh_frame_for_plt(Output_data* plt, const unsigned char* cie_data, + size_t cie_length, const unsigned char* fde_data, + size_t fde_length); + + // Scan a .debug_info or .debug_types section, and add summary + // information to the .gdb_index section. + template + void + add_to_gdb_index(bool is_type_unit, + Sized_relobj* object, + const unsigned char* symbols, + off_t symbols_size, + unsigned int shndx, + unsigned int reloc_shndx, + unsigned int reloc_type); + // Handle a GNU stack note. This is called once per input object // file. SEEN_GNU_STACK is true if the object file has a // .note.GNU-stack section. GNU_STACK_FLAGS is the section flags @@ -557,6 +693,25 @@ class Layout layout_gnu_stack(bool seen_gnu_stack, uint64_t gnu_stack_flags, const Object*); + // Layout a .note.gnu.property section. + void + layout_gnu_property(unsigned int note_type, + unsigned int pr_type, + size_t pr_datasz, + const unsigned char* pr_data, + const Object* object); + + // Merge per-object properties with program properties. + void + merge_gnu_properties(const Object* object); + + // Add a target-specific property for the output .note.gnu.property section. + void + add_gnu_property(unsigned int note_type, + unsigned int pr_type, + size_t pr_datasz, + const unsigned char* pr_data); + // Add an Output_section_data to the layout. This is used for // special sections like the GOT section. ORDER is where the // section should wind up in the output segment. IS_RELRO is true @@ -609,6 +764,12 @@ class Layout dynpool() const { return &this->dynpool_; } + // Return the .dynamic output section. This is only valid after the + // layout has been finalized. + Output_section* + dynamic_section() const + { return this->dynamic_section_; } + // Return the symtab_xindex section used to hold large section // indexes for the normal symbol table. Output_symtab_xindex* @@ -638,13 +799,26 @@ class Layout { // Debugging sections can only be recognized by name. return (strncmp(name, ".debug", sizeof(".debug") - 1) == 0 - || strncmp(name, ".zdebug", sizeof(".zdebug") - 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); + || strncmp(name, ".zdebug", sizeof(".zdebug") - 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 + || strncmp(name, ".pdr", sizeof(".pdr") - 1) == 0); } + // Return true if RELOBJ is an input file whose base name matches + // FILE_NAME. The base name must have an extension of ".o", and + // must be exactly FILE_NAME.o or FILE_NAME, one character, ".o". + static bool + match_file_name(const Relobj* relobj, const char* file_name); + + // Return whether section SHNDX in RELOBJ is a .ctors/.dtors section + // with more than one word being mapped to a .init_array/.fini_array + // section. + bool + is_ctors_in_init_array(Relobj* relobj, unsigned int shndx) const; + // Check if a comdat group or .gnu.linkonce section with the given // NAME is selected for the link. If there is already a section, // *KEPT_SECTION is set to point to the signature and the function @@ -653,7 +827,7 @@ class Layout // *KEPT_SECTION is set to the internal copy and the function return // false. bool - find_or_add_kept_section(const std::string& name, Relobj* object, + find_or_add_kept_section(const std::string& name, Relobj* object, unsigned int shndx, bool is_comdat, bool is_group_name, Kept_section** kept_section); @@ -689,6 +863,10 @@ class Layout off_t symtab_section_offset() const; + // Return the section index of the normal symbol tabl.e + unsigned int + symtab_section_shndx() const; + // Return the dynamic symbol table. Output_section* dynsym_section() const @@ -763,9 +941,13 @@ class Layout const Output_data_reloc_generic* dyn_rel, bool add_debug, bool dynrel_includes_plt); + // Add a target-specific dynamic tag with constant value. + void + add_target_specific_dynamic_tag(elfcpp::DT tag, unsigned int val); + // Compute and write out the build ID if needed. void - write_build_id(Output_file*) const; + write_build_id(Output_file*, unsigned char*, size_t) const; // Rewrite output file in binary format. void @@ -796,6 +978,10 @@ class Layout void get_allocated_sections(Section_list*) const; + // Store the executable sections into the section list. + void + get_executable_sections(Section_list*) const; + // Make a section for a linker script to hold data. Output_section* make_output_section_for_script(const char* name, @@ -816,7 +1002,7 @@ class Layout // Attach sections to segments. void - attach_sections_to_segments(); + attach_sections_to_segments(const Target*); // For relaxation clean up, we need to know output section data created // from a linker script. @@ -832,6 +1018,21 @@ class Layout section_list() const { return this->section_list_; } + // Returns TRUE iff NAME (an input section from RELOBJ) will + // be mapped to an output section that should be KEPT. + bool + keep_input_section(const Relobj*, const char*); + + // Add a special output object that will be recreated afresh + // if there is another relaxation iteration. + void + add_relax_output(Output_data* data) + { this->relax_output_list_.push_back(data); } + + // Clear out (and free) everything added by add_relax_output. + void + reset_relax_output(); + private: Layout(const Layout&); Layout& operator=(const Layout&); @@ -846,6 +1047,14 @@ class Layout }; static const Section_name_mapping section_name_mapping[]; static const int section_name_mapping_count; + static const Section_name_mapping text_section_name_mapping[]; + static const int text_section_name_mapping_count; + + // Find section name NAME in map and return the mapped name if found + // with the length set in PLEN. + static const char* match_section_name(const Section_name_mapping* map, + const int count, const char* name, + size_t* plen); // During a relocatable link, a list of group sections and // signatures. @@ -871,13 +1080,17 @@ class Layout create_note(const char* name, int note_type, const char* section_name, size_t descsz, bool allocate, size_t* trailing_padding); + // Create a note section for gnu program properties. + void + create_gnu_properties_note(); + // Create a note section for gold version. void create_gold_note(); - // Record whether the stack must be executable. + // Record whether the stack must be executable, and a user-supplied size. void - create_executable_stack_info(); + create_stack_segment(); // Create a build ID note if needed. void @@ -895,7 +1108,7 @@ class Layout // Find the first read-only PT_LOAD segment, creating one if // necessary. Output_segment* - find_first_load_seg(); + find_first_load_seg(const Target*); // Count the local symbols in the regular symbol table and the dynamic // symbol table, and build the respective string pools. @@ -905,7 +1118,7 @@ class Layout // Create the output sections for the symbol table. void create_symtab_sections(const Input_objects*, Symbol_table*, - unsigned int, off_t*); + unsigned int, off_t*, unsigned int); // Create the .shstrtab section. Output_section* @@ -920,6 +1133,7 @@ class Layout create_dynamic_symtab(const Input_objects*, Symbol_table*, Output_section** pdynstr, unsigned int* plocal_dynamic_count, + unsigned int* pforced_local_dynamic_count, std::vector* pdynamic_symbols, Versions* versions); @@ -965,7 +1179,7 @@ class Layout // name. Set *PLEN to the length of the name. *PLEN must be // initialized to the length of NAME. static const char* - output_section_name(const char* name, size_t* plen); + output_section_name(const Relobj*, const char* name, size_t* plen); // Return the number of allocated output sections. size_t @@ -977,12 +1191,17 @@ class Layout elfcpp::Elf_Word type, elfcpp::Elf_Xword flags, Output_section_order order, bool is_relro); + // Clear the input section flags that should not be copied to the + // output section. + elfcpp::Elf_Xword + get_output_section_flags (elfcpp::Elf_Xword input_section_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, Output_section_order order, - bool is_relro); + bool is_relro, bool is_reloc, bool match_input_spec); // Create a new Output_section. Output_section* @@ -992,7 +1211,7 @@ class Layout // Attach a section to a segment. void - attach_section_to_segment(Output_section*); + attach_section_to_segment(const Target*, Output_section*); // Get section order. Output_section_order @@ -1000,7 +1219,11 @@ class Layout // Attach an allocated section to a segment. void - attach_allocated_section_to_segment(Output_section*); + attach_allocated_section_to_segment(const Target*, Output_section*); + + // Make the .eh_frame section. + Output_section* + make_eh_frame_section(const Relobj*); // Set the final file offsets of all the segments. off_t @@ -1040,10 +1263,10 @@ class Layout place_orphan_sections_in_script(); // Return whether SEG1 comes before SEG2 in the output file. - static bool + bool segment_precedes(const Output_segment* seg1, const Output_segment* seg2); - // Use to save and restore segments during relaxation. + // Use to save and restore segments during relaxation. typedef Unordered_map Segment_states; @@ -1090,11 +1313,19 @@ class Layout // A comparison class for segments. - struct Compare_segments + class Compare_segments { + public: + Compare_segments(Layout* layout) + : layout_(layout) + { } + bool operator()(const Output_segment* seg1, const Output_segment* seg2) - { return Layout::segment_precedes(seg1, seg2); } + { return this->layout_->segment_precedes(seg1, seg2); } + + private: + Layout* layout_; }; typedef std::vector Output_section_data_list; @@ -1106,12 +1337,13 @@ class Layout Relaxation_debug_check() : section_infos_() { } - + // Check that sections and special data are in reset states. void check_output_data_for_reset_values(const Layout::Section_list&, - const Layout::Data_list&); - + const Layout::Data_list& special_outputs, + const Layout::Data_list& relax_outputs); + // Record information of a section list. void read_sections(const Layout::Section_list&); @@ -1119,7 +1351,7 @@ class Layout // Verify a section list with recorded information. void verify_sections(const Layout::Section_list&); - + private: // Information we care about a section. struct Section_info @@ -1138,6 +1370,14 @@ class Layout std::vector section_infos_; }; + // Program properties from .note.gnu.property sections. + struct Gnu_property + { + size_t pr_datasz; + unsigned char* pr_data; + }; + typedef std::map Gnu_properties; + // The number of input files, for sizing tables. int number_of_input_files_; // Information set by scripts or by command line options. @@ -1162,6 +1402,9 @@ class Layout // The list of unattached Output_data objects which require special // handling because they are not Output_sections. Data_list special_output_list_; + // Like special_output_list_, but cleared and recreated on each + // iteration of relaxation. + Data_list relax_output_list_; // The section headers. Output_section_headers* section_headers_; // A pointer to the PT_TLS segment if there is one. @@ -1195,6 +1438,8 @@ class Layout bool added_eh_frame_data_; // The exception frame header output section if there is one. Output_section* eh_frame_hdr_section_; + // The data for the .gdb_index section. + Gdb_index* gdb_index_data_; // The space for the build ID checksum if there is one. Output_section_data* build_id_note_; // The output section containing dwarf abbreviations @@ -1226,6 +1471,12 @@ class Layout bool resized_signatures_; // Whether we have created a .stab*str output section. bool have_stabstr_section_; + // True if the input sections in the output sections should be sorted + // as specified in a section ordering file. + bool section_ordering_specified_; + // True if some input sections need to be mapped to a unique segment, + // after being mapped to a unique Output_section. + bool unique_segment_for_sections_specified_; // In incremental build, holds information check the inputs and build the // .gnu_incremental_inputs section. Incremental_inputs* incremental_inputs_; @@ -1237,6 +1488,14 @@ class Layout Segment_states* segment_states_; // A relaxation debug checker. We only create one when in debugging mode. Relaxation_debug_check* relaxation_debug_check_; + // Plugins specify section_ordering using this map. This is set in + // update_section_order in plugin.cc + std::map section_order_map_; + // This maps an input section to a unique segment. This is done by first + // placing such input sections in unique output sections and then mapping + // the output section to a unique segment. Unique_segment_info stores + // any additional flags and alignment of the new segment. + Section_segment_map section_segment_map_; // Hash a pattern to its position in the section ordering file. Unordered_map input_section_position_; // Vector of glob only patterns in the section_ordering file. @@ -1245,6 +1504,8 @@ class Layout Incremental_binary* incremental_base_; // For incremental links, a list of free space within the file. Free_list free_list_; + // Program properties. + Gnu_properties gnu_properties_; }; // This task handles writing out data in output sections which is not @@ -1257,9 +1518,11 @@ class Write_sections_task : public Task public: Write_sections_task(const Layout* layout, Output_file* of, Task_token* output_sections_blocker, + Task_token* input_sections_blocker, Task_token* final_blocker) : layout_(layout), of_(of), output_sections_blocker_(output_sections_blocker), + input_sections_blocker_(input_sections_blocker), final_blocker_(final_blocker) { } @@ -1284,6 +1547,7 @@ class Write_sections_task : public Task const Layout* layout_; Output_file* of_; Task_token* output_sections_blocker_; + Task_token* input_sections_blocker_; Task_token* final_blocker_; }; @@ -1326,10 +1590,10 @@ class Write_symbols_task : public Task { public: Write_symbols_task(const Layout* layout, const Symbol_table* symtab, - const Input_objects* input_objects, + const Input_objects* /*input_objects*/, const Stringpool* sympool, const Stringpool* dynpool, Output_file* of, Task_token* final_blocker) - : layout_(layout), symtab_(symtab), input_objects_(input_objects), + : layout_(layout), symtab_(symtab), sympool_(sympool), dynpool_(dynpool), of_(of), final_blocker_(final_blocker) { } @@ -1352,7 +1616,6 @@ class Write_symbols_task : public Task private: const Layout* layout_; const Symbol_table* symtab_; - const Input_objects* input_objects_; const Stringpool* sympool_; const Stringpool* dynpool_; Output_file* of_; @@ -1397,14 +1660,40 @@ class Write_after_input_sections_task : public Task Task_token* final_blocker_; }; +// This task function handles computation of the build id. +// When using --build-id=tree, it schedules the tasks that +// compute the hashes for each chunk of the file. This task +// cannot run until we have finalized the size of the output +// file, after the completion of Write_after_input_sections_task. + +class Build_id_task_runner : public Task_function_runner +{ + public: + Build_id_task_runner(const General_options* options, const Layout* layout, + Output_file* of) + : options_(options), layout_(layout), of_(of) + { } + + // Run the operation. + void + run(Workqueue*, const Task*); + + private: + const General_options* options_; + const Layout* layout_; + Output_file* of_; +}; + // This task function handles closing the file. class Close_task_runner : public Task_function_runner { public: Close_task_runner(const General_options* options, const Layout* layout, - Output_file* of) - : options_(options), layout_(layout), of_(of) + Output_file* of, unsigned char* array_of_hashes, + size_t size_of_hashes) + : options_(options), layout_(layout), of_(of), + array_of_hashes_(array_of_hashes), size_of_hashes_(size_of_hashes) { } // Run the operation. @@ -1415,6 +1704,8 @@ class Close_task_runner : public Task_function_runner const General_options* options_; const Layout* layout_; Output_file* of_; + unsigned char* const array_of_hashes_; + const size_t size_of_hashes_; }; // A small helper function to align an address.