175fd0b74Schristos // script-sections.h -- linker script SECTIONS for gold -*- C++ -*- 275fd0b74Schristos 3*e992f068Schristos // Copyright (C) 2008-2022 Free Software Foundation, Inc. 475fd0b74Schristos // Written by Ian Lance Taylor <iant@google.com>. 575fd0b74Schristos 675fd0b74Schristos // This file is part of gold. 775fd0b74Schristos 875fd0b74Schristos // This program is free software; you can redistribute it and/or modify 975fd0b74Schristos // it under the terms of the GNU General Public License as published by 1075fd0b74Schristos // the Free Software Foundation; either version 3 of the License, or 1175fd0b74Schristos // (at your option) any later version. 1275fd0b74Schristos 1375fd0b74Schristos // This program is distributed in the hope that it will be useful, 1475fd0b74Schristos // but WITHOUT ANY WARRANTY; without even the implied warranty of 1575fd0b74Schristos // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1675fd0b74Schristos // GNU General Public License for more details. 1775fd0b74Schristos 1875fd0b74Schristos // You should have received a copy of the GNU General Public License 1975fd0b74Schristos // along with this program; if not, write to the Free Software 2075fd0b74Schristos // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 2175fd0b74Schristos // MA 02110-1301, USA. 2275fd0b74Schristos 2375fd0b74Schristos // This is for the support of the SECTIONS clause in linker scripts. 2475fd0b74Schristos 2575fd0b74Schristos #ifndef GOLD_SCRIPT_SECTIONS_H 2675fd0b74Schristos #define GOLD_SCRIPT_SECTIONS_H 2775fd0b74Schristos 2875fd0b74Schristos #include <cstdio> 2975fd0b74Schristos #include <list> 3075fd0b74Schristos #include <vector> 3175fd0b74Schristos 3275fd0b74Schristos namespace gold 3375fd0b74Schristos { 3475fd0b74Schristos 3575fd0b74Schristos struct Parser_output_section_header; 3675fd0b74Schristos struct Parser_output_section_trailer; 3775fd0b74Schristos struct Input_section_spec; 3875fd0b74Schristos class Expression; 3975fd0b74Schristos class Sections_element; 4075fd0b74Schristos class Memory_region; 4175fd0b74Schristos class Phdrs_element; 4275fd0b74Schristos class Output_data; 4375fd0b74Schristos class Output_section_definition; 4475fd0b74Schristos class Output_section; 4575fd0b74Schristos class Output_segment; 4675fd0b74Schristos class Orphan_section_placement; 4775fd0b74Schristos 4875fd0b74Schristos class Script_sections 4975fd0b74Schristos { 5075fd0b74Schristos public: 5175fd0b74Schristos // This is a list, not a vector, because we insert orphan sections 5275fd0b74Schristos // in the middle. 5375fd0b74Schristos typedef std::list<Sections_element*> Sections_elements; 5475fd0b74Schristos 5575fd0b74Schristos // Logical script section types. We map section types returned by the 5675fd0b74Schristos // parser into these since some section types have the same semantics. 5775fd0b74Schristos enum Section_type 5875fd0b74Schristos { 5975fd0b74Schristos // No section type specified. 6075fd0b74Schristos ST_NONE, 6175fd0b74Schristos // Section is NOLOAD. We allocate space in the output but section 6275fd0b74Schristos // is not loaded in runtime. 6375fd0b74Schristos ST_NOLOAD, 6475fd0b74Schristos // No space is allocated to section. 6575fd0b74Schristos ST_NOALLOC 6675fd0b74Schristos }; 6775fd0b74Schristos 6875fd0b74Schristos Script_sections(); 6975fd0b74Schristos 7075fd0b74Schristos // Start a SECTIONS clause. 7175fd0b74Schristos void 7275fd0b74Schristos start_sections(); 7375fd0b74Schristos 7475fd0b74Schristos // Finish a SECTIONS clause. 7575fd0b74Schristos void 7675fd0b74Schristos finish_sections(); 7775fd0b74Schristos 7875fd0b74Schristos // Return whether we ever saw a SECTIONS clause. If we did, then 7975fd0b74Schristos // all section layout needs to go through this class. 8075fd0b74Schristos bool saw_sections_clause()8175fd0b74Schristos saw_sections_clause() const 8275fd0b74Schristos { return this->saw_sections_clause_; } 8375fd0b74Schristos 8475fd0b74Schristos // Return whether we are currently processing a SECTIONS clause. 8575fd0b74Schristos bool in_sections_clause()8675fd0b74Schristos in_sections_clause() const 8775fd0b74Schristos { return this->in_sections_clause_; } 8875fd0b74Schristos 8975fd0b74Schristos // Return whether we ever saw a PHDRS clause. We ignore the PHDRS 9075fd0b74Schristos // clause unless we also saw a SECTIONS clause. 9175fd0b74Schristos bool saw_phdrs_clause()9275fd0b74Schristos saw_phdrs_clause() const 9375fd0b74Schristos { return this->saw_sections_clause_ && this->phdrs_elements_ != NULL; } 9475fd0b74Schristos 9575fd0b74Schristos // Start processing entries for an output section. 9675fd0b74Schristos void 9775fd0b74Schristos start_output_section(const char* name, size_t namelen, 9875fd0b74Schristos const Parser_output_section_header*); 9975fd0b74Schristos 10075fd0b74Schristos // Finish processing entries for an output section. 10175fd0b74Schristos void 10275fd0b74Schristos finish_output_section(const Parser_output_section_trailer*); 10375fd0b74Schristos 10475fd0b74Schristos // Add a data item to the current output section. 10575fd0b74Schristos void 10675fd0b74Schristos add_data(int size, bool is_signed, Expression* val); 10775fd0b74Schristos 10875fd0b74Schristos // Add a symbol to be defined. 10975fd0b74Schristos void 11075fd0b74Schristos add_symbol_assignment(const char* name, size_t length, Expression* value, 11175fd0b74Schristos bool provide, bool hidden); 11275fd0b74Schristos 11375fd0b74Schristos // Add an assignment to the special dot symbol. 11475fd0b74Schristos void 11575fd0b74Schristos add_dot_assignment(Expression* value); 11675fd0b74Schristos 11775fd0b74Schristos // Add an assertion. 11875fd0b74Schristos void 11975fd0b74Schristos add_assertion(Expression* check, const char* message, size_t messagelen); 12075fd0b74Schristos 12175fd0b74Schristos // Add a setting for the fill value. 12275fd0b74Schristos void 12375fd0b74Schristos add_fill(Expression* val); 12475fd0b74Schristos 12575fd0b74Schristos // Add an input section specification. 12675fd0b74Schristos void 12775fd0b74Schristos add_input_section(const Input_section_spec* spec, bool keep); 12875fd0b74Schristos 12975fd0b74Schristos // Saw DATA_SEGMENT_ALIGN. 13075fd0b74Schristos void 13175fd0b74Schristos data_segment_align(); 13275fd0b74Schristos 13375fd0b74Schristos // Saw DATA_SEGMENT_RELRO_END. 13475fd0b74Schristos void 13575fd0b74Schristos data_segment_relro_end(); 13675fd0b74Schristos 13775fd0b74Schristos // Create any required sections. 13875fd0b74Schristos void 13975fd0b74Schristos create_sections(Layout*); 14075fd0b74Schristos 14175fd0b74Schristos // Add any symbols we are defining to the symbol table. 14275fd0b74Schristos void 14375fd0b74Schristos add_symbols_to_table(Symbol_table*); 14475fd0b74Schristos 14575fd0b74Schristos // Finalize symbol values and check assertions. 14675fd0b74Schristos void 14775fd0b74Schristos finalize_symbols(Symbol_table* symtab, const Layout* layout); 14875fd0b74Schristos 14975fd0b74Schristos // Find the name of the output section to use for an input file name 15075fd0b74Schristos // and section name. This returns a name, and sets 15175fd0b74Schristos // *OUTPUT_SECTION_SLOT to point to the address where the actual 15275fd0b74Schristos // output section may be stored. 15375fd0b74Schristos // 1) If the input section should be discarded, this returns NULL 15475fd0b74Schristos // and sets *OUTPUT_SECTION_SLOT to NULL. 15575fd0b74Schristos // 2) If the input section is mapped by the SECTIONS clause, this 15675fd0b74Schristos // returns the name to use for the output section (in permanent 15775fd0b74Schristos // storage), and sets *OUTPUT_SECTION_SLOT to point to where the 15875fd0b74Schristos // output section should be stored. **OUTPUT_SECTION_SLOT will be 15975fd0b74Schristos // non-NULL if we have seen this output section already. 16075fd0b74Schristos // 3) If the input section is not mapped by the SECTIONS clause, 16175fd0b74Schristos // this returns SECTION_NAME, and sets *OUTPUT_SECTION_SLOT to 16275fd0b74Schristos // NULL. 16375fd0b74Schristos // PSCRIPT_SECTION_TYPE points to a location for returning the section 16475fd0b74Schristos // type specified in script. This can be SCRIPT_SECTION_TYPE_NONE if 16575fd0b74Schristos // no type is specified. 16675fd0b74Schristos // *KEEP indicates whether the section should survive garbage collection. 167ede78133Schristos // MATCH_INPUT_SPEC indicates whether the section should be matched 168ede78133Schristos // with input section specs or simply against the output section name 169ede78133Schristos // (i.e., for linker-created sections like .dynamic). 17075fd0b74Schristos const char* 17175fd0b74Schristos output_section_name(const char* file_name, const char* section_name, 17275fd0b74Schristos Output_section*** output_section_slot, 17375fd0b74Schristos Section_type* pscript_section_type, 174ede78133Schristos bool* keep, bool match_input_spec); 17575fd0b74Schristos 17675fd0b74Schristos // Place a marker for an orphan output section into the SECTIONS 17775fd0b74Schristos // clause. 17875fd0b74Schristos void 17975fd0b74Schristos place_orphan(Output_section* os); 18075fd0b74Schristos 18175fd0b74Schristos // Set the addresses of all the output sections. Return the segment 18275fd0b74Schristos // which holds the file header and segment headers, if any. 18375fd0b74Schristos Output_segment* 18475fd0b74Schristos set_section_addresses(Symbol_table*, Layout*); 18575fd0b74Schristos 18675fd0b74Schristos // Add a program header definition. 18775fd0b74Schristos void 18875fd0b74Schristos add_phdr(const char* name, size_t namelen, unsigned int type, 18975fd0b74Schristos bool filehdr, bool phdrs, bool is_flags_valid, unsigned int flags, 19075fd0b74Schristos Expression* load_address); 19175fd0b74Schristos 19275fd0b74Schristos // Return the number of segments we expect to create based on the 19375fd0b74Schristos // SECTIONS clause. 19475fd0b74Schristos size_t 19575fd0b74Schristos expected_segment_count(const Layout*) const; 19675fd0b74Schristos 19775fd0b74Schristos // Add the file header and segment header to non-load segments as 19875fd0b74Schristos // specified by the PHDRS clause. 19975fd0b74Schristos void 20075fd0b74Schristos put_headers_in_phdrs(Output_data* file_header, Output_data* segment_headers); 20175fd0b74Schristos 20275fd0b74Schristos // Look for an output section by name and return the address, the 20375fd0b74Schristos // load address, the alignment, and the size. This is used when an 20475fd0b74Schristos // expression refers to an output section which was not actually 20575fd0b74Schristos // created. This returns true if the section was found, false 20675fd0b74Schristos // otherwise. 20775fd0b74Schristos bool 20875fd0b74Schristos get_output_section_info(const char* name, uint64_t* address, 20975fd0b74Schristos uint64_t* load_address, uint64_t* addralign, 21075fd0b74Schristos uint64_t* size) const; 21175fd0b74Schristos 21275fd0b74Schristos // Release all Output_segments. This is used in relaxation. 21375fd0b74Schristos void 21475fd0b74Schristos release_segments(); 21575fd0b74Schristos 21675fd0b74Schristos // Whether we ever saw a SEGMENT_START expression, the presence of which 21775fd0b74Schristos // changes the behaviour of -Ttext, -Tdata and -Tbss options. 21875fd0b74Schristos bool saw_segment_start_expression()21975fd0b74Schristos saw_segment_start_expression() const 22075fd0b74Schristos { return this->saw_segment_start_expression_; } 22175fd0b74Schristos 22275fd0b74Schristos // Set the flag which indicates whether we saw a SEGMENT_START expression. 22375fd0b74Schristos void set_saw_segment_start_expression(bool value)22475fd0b74Schristos set_saw_segment_start_expression(bool value) 22575fd0b74Schristos { this->saw_segment_start_expression_ = value; } 22675fd0b74Schristos 22775fd0b74Schristos // Add a memory region. 22875fd0b74Schristos void 22975fd0b74Schristos add_memory_region(const char*, size_t, unsigned int, 23075fd0b74Schristos Expression*, Expression*); 23175fd0b74Schristos 23275fd0b74Schristos // Find a memory region's origin. 23375fd0b74Schristos Expression* 23475fd0b74Schristos find_memory_region_origin(const char*, size_t); 23575fd0b74Schristos 23675fd0b74Schristos // Find a memory region's length. 23775fd0b74Schristos Expression* 23875fd0b74Schristos find_memory_region_length(const char*, size_t); 23975fd0b74Schristos 24075fd0b74Schristos // Find a memory region by name. 24175fd0b74Schristos Memory_region* 24275fd0b74Schristos find_memory_region(const char*, size_t); 24375fd0b74Schristos 24475fd0b74Schristos // Find a memory region that should be used by a given output section. 24575fd0b74Schristos Memory_region* 24675fd0b74Schristos find_memory_region(Output_section_definition*, bool, bool, 24775fd0b74Schristos Output_section_definition**); 24875fd0b74Schristos 24975fd0b74Schristos // Returns true if the provide block of memory is contained 25075fd0b74Schristos // within a memory region. 25175fd0b74Schristos bool 25275fd0b74Schristos block_in_region(Symbol_table*, Layout*, uint64_t, uint64_t) const; 25375fd0b74Schristos 25475fd0b74Schristos // Set the memory region of the section. 25575fd0b74Schristos void 25675fd0b74Schristos set_memory_region(Memory_region*, bool); 25775fd0b74Schristos 25875fd0b74Schristos // Print the contents to the FILE. This is for debugging. 25975fd0b74Schristos void 26075fd0b74Schristos print(FILE*) const; 26175fd0b74Schristos 26275fd0b74Schristos // Used for orphan sections. 26375fd0b74Schristos typedef Sections_elements::iterator Elements_iterator; 26475fd0b74Schristos 26575fd0b74Schristos private: 26675fd0b74Schristos typedef std::vector<Memory_region*> Memory_regions; 26775fd0b74Schristos typedef std::vector<Phdrs_element*> Phdrs_elements; 26875fd0b74Schristos 26975fd0b74Schristos // Create segments. 27075fd0b74Schristos Output_segment* 27175fd0b74Schristos create_segments(Layout*, uint64_t); 27275fd0b74Schristos 27375fd0b74Schristos // Create PT_NOTE and PT_TLS segments. 27475fd0b74Schristos void 27575fd0b74Schristos create_note_and_tls_segments(Layout*, const std::vector<Output_section*>*); 27675fd0b74Schristos 27775fd0b74Schristos // Return whether the section is a BSS section. 27875fd0b74Schristos static bool 27975fd0b74Schristos is_bss_section(const Output_section*); 28075fd0b74Schristos 28175fd0b74Schristos // Return the total size of the headers. 28275fd0b74Schristos size_t 28375fd0b74Schristos total_header_size(Layout* layout) const; 28475fd0b74Schristos 285ede78133Schristos // Return the amount we have to subtract from the LMA to accommodate 28675fd0b74Schristos // headers of the given size. 28775fd0b74Schristos uint64_t 28875fd0b74Schristos header_size_adjustment(uint64_t lma, size_t sizeof_headers) const; 28975fd0b74Schristos 29075fd0b74Schristos // Create the segments from a PHDRS clause. 29175fd0b74Schristos Output_segment* 29275fd0b74Schristos create_segments_from_phdrs_clause(Layout* layout, uint64_t); 29375fd0b74Schristos 29475fd0b74Schristos // Attach sections to segments from a PHDRS clause. 29575fd0b74Schristos void 29675fd0b74Schristos attach_sections_using_phdrs_clause(Layout*); 29775fd0b74Schristos 29875fd0b74Schristos // Set addresses of segments from a PHDRS clause. 29975fd0b74Schristos Output_segment* 30075fd0b74Schristos set_phdrs_clause_addresses(Layout*, uint64_t); 30175fd0b74Schristos 30275fd0b74Schristos // True if we ever saw a SECTIONS clause. 30375fd0b74Schristos bool saw_sections_clause_; 30475fd0b74Schristos // True if we are currently processing a SECTIONS clause. 30575fd0b74Schristos bool in_sections_clause_; 30675fd0b74Schristos // The list of elements in the SECTIONS clause. 30775fd0b74Schristos Sections_elements* sections_elements_; 30875fd0b74Schristos // The current output section, if there is one. 30975fd0b74Schristos Output_section_definition* output_section_; 31075fd0b74Schristos // The list of memory regions in the MEMORY clause. 31175fd0b74Schristos Memory_regions* memory_regions_; 31275fd0b74Schristos // The list of program headers in the PHDRS clause. 31375fd0b74Schristos Phdrs_elements* phdrs_elements_; 31475fd0b74Schristos // Where to put orphan sections. 31575fd0b74Schristos Orphan_section_placement* orphan_section_placement_; 31675fd0b74Schristos // A pointer to the last Sections_element when we see 31775fd0b74Schristos // DATA_SEGMENT_ALIGN. 31875fd0b74Schristos Sections_elements::iterator data_segment_align_start_; 31975fd0b74Schristos // Whether we have seen DATA_SEGMENT_ALIGN. 32075fd0b74Schristos bool saw_data_segment_align_; 32175fd0b74Schristos // Whether we have seen DATA_SEGMENT_RELRO_END. 32275fd0b74Schristos bool saw_relro_end_; 32375fd0b74Schristos // Whether we have seen SEGMENT_START. 32475fd0b74Schristos bool saw_segment_start_expression_; 32575fd0b74Schristos // Whether we have created all necessary segments. 32675fd0b74Schristos bool segments_created_; 32775fd0b74Schristos }; 32875fd0b74Schristos 32975fd0b74Schristos // Attributes for memory regions. 33075fd0b74Schristos enum 33175fd0b74Schristos { 33275fd0b74Schristos MEM_EXECUTABLE = (1 << 0), 33375fd0b74Schristos MEM_WRITEABLE = (1 << 1), 33475fd0b74Schristos MEM_READABLE = (1 << 2), 33575fd0b74Schristos MEM_ALLOCATABLE = (1 << 3), 33675fd0b74Schristos MEM_INITIALIZED = (1 << 4), 33775fd0b74Schristos MEM_ATTR_MASK = (1 << 5) - 1 33875fd0b74Schristos }; 33975fd0b74Schristos 34075fd0b74Schristos } // End namespace gold. 34175fd0b74Schristos 34275fd0b74Schristos #endif // !defined(GOLD_SCRIPT_SECTIONS_H 343