X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gold%2Flayout.h;h=c4f1f8c35bea1c1ce5b4ee6c71f35b94b7262338;hb=abdb711e0855f0597a96db0486b598144b788212;hp=f81ea3b9a737a1ece0c2ca2753aa5dc6970b8cb0;hpb=c1027032c2fec15b7a334a09bab8882984716764;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/layout.h b/gold/layout.h index f81ea3b9a7..c4f1f8c35b 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-2019 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -66,6 +66,10 @@ 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. @@ -171,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), @@ -418,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, @@ -521,12 +537,46 @@ 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_; } @@ -535,6 +585,14 @@ class Layout 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. off_t @@ -594,6 +652,12 @@ 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. @@ -602,6 +666,13 @@ class Layout 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 @@ -622,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 @@ -709,11 +799,12 @@ 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 @@ -736,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); @@ -850,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 @@ -883,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, @@ -903,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. @@ -919,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&); @@ -933,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. @@ -958,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 @@ -982,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. @@ -992,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* @@ -1007,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); @@ -1064,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* @@ -1079,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 @@ -1087,7 +1219,7 @@ 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* @@ -1134,7 +1266,7 @@ class Layout 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; @@ -1205,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&); @@ -1218,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 @@ -1237,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. @@ -1261,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. @@ -1330,6 +1474,9 @@ class Layout // 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_; @@ -1344,6 +1491,11 @@ class Layout // 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. @@ -1352,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 @@ -1364,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) { } @@ -1391,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_; }; @@ -1433,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) { } @@ -1459,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_; @@ -1504,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. @@ -1522,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.