175fd0b74Schristos // script-sections.cc -- linker script SECTIONS for gold
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 #include "gold.h"
2475fd0b74Schristos
2575fd0b74Schristos #include <cstring>
2675fd0b74Schristos #include <algorithm>
2775fd0b74Schristos #include <list>
2875fd0b74Schristos #include <map>
2975fd0b74Schristos #include <string>
3075fd0b74Schristos #include <vector>
3175fd0b74Schristos #include <fnmatch.h>
3275fd0b74Schristos
3375fd0b74Schristos #include "parameters.h"
3475fd0b74Schristos #include "object.h"
3575fd0b74Schristos #include "layout.h"
3675fd0b74Schristos #include "output.h"
3775fd0b74Schristos #include "script-c.h"
3875fd0b74Schristos #include "script.h"
3975fd0b74Schristos #include "script-sections.h"
4075fd0b74Schristos
4175fd0b74Schristos // Support for the SECTIONS clause in linker scripts.
4275fd0b74Schristos
4375fd0b74Schristos namespace gold
4475fd0b74Schristos {
4575fd0b74Schristos
4675fd0b74Schristos // A region of memory.
4775fd0b74Schristos class Memory_region
4875fd0b74Schristos {
4975fd0b74Schristos public:
Memory_region(const char * name,size_t namelen,unsigned int attributes,Expression * start,Expression * length)5075fd0b74Schristos Memory_region(const char* name, size_t namelen, unsigned int attributes,
5175fd0b74Schristos Expression* start, Expression* length)
5275fd0b74Schristos : name_(name, namelen),
5375fd0b74Schristos attributes_(attributes),
5475fd0b74Schristos start_(start),
5575fd0b74Schristos length_(length),
5675fd0b74Schristos current_offset_(0),
5775fd0b74Schristos vma_sections_(),
5875fd0b74Schristos lma_sections_(),
5975fd0b74Schristos last_section_(NULL)
6075fd0b74Schristos { }
6175fd0b74Schristos
6275fd0b74Schristos // Return the name of this region.
6375fd0b74Schristos const std::string&
name() const6475fd0b74Schristos name() const
6575fd0b74Schristos { return this->name_; }
6675fd0b74Schristos
6775fd0b74Schristos // Return the start address of this region.
6875fd0b74Schristos Expression*
start_address() const6975fd0b74Schristos start_address() const
7075fd0b74Schristos { return this->start_; }
7175fd0b74Schristos
7275fd0b74Schristos // Return the length of this region.
7375fd0b74Schristos Expression*
length() const7475fd0b74Schristos length() const
7575fd0b74Schristos { return this->length_; }
7675fd0b74Schristos
7775fd0b74Schristos // Print the region (when debugging).
7875fd0b74Schristos void
7975fd0b74Schristos print(FILE*) const;
8075fd0b74Schristos
8175fd0b74Schristos // Return true if <name,namelen> matches this region.
8275fd0b74Schristos bool
name_match(const char * name,size_t namelen)8375fd0b74Schristos name_match(const char* name, size_t namelen)
8475fd0b74Schristos {
8575fd0b74Schristos return (this->name_.length() == namelen
8675fd0b74Schristos && strncmp(this->name_.c_str(), name, namelen) == 0);
8775fd0b74Schristos }
8875fd0b74Schristos
8975fd0b74Schristos Expression*
get_current_address() const9075fd0b74Schristos get_current_address() const
9175fd0b74Schristos {
9275fd0b74Schristos return
9375fd0b74Schristos script_exp_binary_add(this->start_,
9475fd0b74Schristos script_exp_integer(this->current_offset_));
9575fd0b74Schristos }
9675fd0b74Schristos
9775fd0b74Schristos void
set_address(uint64_t addr,const Symbol_table * symtab,const Layout * layout)9875fd0b74Schristos set_address(uint64_t addr, const Symbol_table* symtab, const Layout* layout)
9975fd0b74Schristos {
10075fd0b74Schristos uint64_t start = this->start_->eval(symtab, layout, false);
10175fd0b74Schristos uint64_t len = this->length_->eval(symtab, layout, false);
10275fd0b74Schristos if (addr < start || addr >= start + len)
10375fd0b74Schristos gold_error(_("address 0x%llx is not within region %s"),
10475fd0b74Schristos static_cast<unsigned long long>(addr),
10575fd0b74Schristos this->name_.c_str());
10675fd0b74Schristos else if (addr < start + this->current_offset_)
10775fd0b74Schristos gold_error(_("address 0x%llx moves dot backwards in region %s"),
10875fd0b74Schristos static_cast<unsigned long long>(addr),
10975fd0b74Schristos this->name_.c_str());
11075fd0b74Schristos this->current_offset_ = addr - start;
11175fd0b74Schristos }
11275fd0b74Schristos
11375fd0b74Schristos void
increment_offset(std::string section_name,uint64_t amount,const Symbol_table * symtab,const Layout * layout)11475fd0b74Schristos increment_offset(std::string section_name, uint64_t amount,
11575fd0b74Schristos const Symbol_table* symtab, const Layout* layout)
11675fd0b74Schristos {
11775fd0b74Schristos this->current_offset_ += amount;
11875fd0b74Schristos
11975fd0b74Schristos if (this->current_offset_
12075fd0b74Schristos > this->length_->eval(symtab, layout, false))
12175fd0b74Schristos gold_error(_("section %s overflows end of region %s"),
12275fd0b74Schristos section_name.c_str(), this->name_.c_str());
12375fd0b74Schristos }
12475fd0b74Schristos
12575fd0b74Schristos // Returns true iff there is room left in this region
12675fd0b74Schristos // for AMOUNT more bytes of data.
12775fd0b74Schristos bool
has_room_for(const Symbol_table * symtab,const Layout * layout,uint64_t amount) const12875fd0b74Schristos has_room_for(const Symbol_table* symtab, const Layout* layout,
12975fd0b74Schristos uint64_t amount) const
13075fd0b74Schristos {
13175fd0b74Schristos return (this->current_offset_ + amount
13275fd0b74Schristos < this->length_->eval(symtab, layout, false));
13375fd0b74Schristos }
13475fd0b74Schristos
13575fd0b74Schristos // Return true if the provided section flags
13675fd0b74Schristos // are compatible with this region's attributes.
13775fd0b74Schristos bool
13875fd0b74Schristos attributes_compatible(elfcpp::Elf_Xword flags, elfcpp::Elf_Xword type) const;
13975fd0b74Schristos
14075fd0b74Schristos void
add_section(Output_section_definition * sec,bool vma)14175fd0b74Schristos add_section(Output_section_definition* sec, bool vma)
14275fd0b74Schristos {
14375fd0b74Schristos if (vma)
14475fd0b74Schristos this->vma_sections_.push_back(sec);
14575fd0b74Schristos else
14675fd0b74Schristos this->lma_sections_.push_back(sec);
14775fd0b74Schristos }
14875fd0b74Schristos
14975fd0b74Schristos typedef std::vector<Output_section_definition*> Section_list;
15075fd0b74Schristos
15175fd0b74Schristos // Return the start of the list of sections
15275fd0b74Schristos // whose VMAs are taken from this region.
15375fd0b74Schristos Section_list::const_iterator
get_vma_section_list_start() const15475fd0b74Schristos get_vma_section_list_start() const
15575fd0b74Schristos { return this->vma_sections_.begin(); }
15675fd0b74Schristos
15775fd0b74Schristos // Return the start of the list of sections
15875fd0b74Schristos // whose LMAs are taken from this region.
15975fd0b74Schristos Section_list::const_iterator
get_lma_section_list_start() const16075fd0b74Schristos get_lma_section_list_start() const
16175fd0b74Schristos { return this->lma_sections_.begin(); }
16275fd0b74Schristos
16375fd0b74Schristos // Return the end of the list of sections
16475fd0b74Schristos // whose VMAs are taken from this region.
16575fd0b74Schristos Section_list::const_iterator
get_vma_section_list_end() const16675fd0b74Schristos get_vma_section_list_end() const
16775fd0b74Schristos { return this->vma_sections_.end(); }
16875fd0b74Schristos
16975fd0b74Schristos // Return the end of the list of sections
17075fd0b74Schristos // whose LMAs are taken from this region.
17175fd0b74Schristos Section_list::const_iterator
get_lma_section_list_end() const17275fd0b74Schristos get_lma_section_list_end() const
17375fd0b74Schristos { return this->lma_sections_.end(); }
17475fd0b74Schristos
17575fd0b74Schristos Output_section_definition*
get_last_section() const17675fd0b74Schristos get_last_section() const
17775fd0b74Schristos { return this->last_section_; }
17875fd0b74Schristos
17975fd0b74Schristos void
set_last_section(Output_section_definition * sec)18075fd0b74Schristos set_last_section(Output_section_definition* sec)
18175fd0b74Schristos { this->last_section_ = sec; }
18275fd0b74Schristos
18375fd0b74Schristos private:
18475fd0b74Schristos
18575fd0b74Schristos std::string name_;
18675fd0b74Schristos unsigned int attributes_;
18775fd0b74Schristos Expression* start_;
18875fd0b74Schristos Expression* length_;
18975fd0b74Schristos // The offset to the next free byte in the region.
19075fd0b74Schristos // Note - for compatibility with GNU LD we only maintain one offset
19175fd0b74Schristos // regardless of whether the region is being used for VMA values,
19275fd0b74Schristos // LMA values, or both.
19375fd0b74Schristos uint64_t current_offset_;
19475fd0b74Schristos // A list of sections whose VMAs are set inside this region.
19575fd0b74Schristos Section_list vma_sections_;
19675fd0b74Schristos // A list of sections whose LMAs are set inside this region.
19775fd0b74Schristos Section_list lma_sections_;
19875fd0b74Schristos // The latest section to make use of this region.
19975fd0b74Schristos Output_section_definition* last_section_;
20075fd0b74Schristos };
20175fd0b74Schristos
20275fd0b74Schristos // Return true if the provided section flags
20375fd0b74Schristos // are compatible with this region's attributes.
20475fd0b74Schristos
20575fd0b74Schristos bool
attributes_compatible(elfcpp::Elf_Xword flags,elfcpp::Elf_Xword type) const20675fd0b74Schristos Memory_region::attributes_compatible(elfcpp::Elf_Xword flags,
20775fd0b74Schristos elfcpp::Elf_Xword type) const
20875fd0b74Schristos {
20975fd0b74Schristos unsigned int attrs = this->attributes_;
21075fd0b74Schristos
21175fd0b74Schristos // No attributes means that this region is not compatible with anything.
21275fd0b74Schristos if (attrs == 0)
21375fd0b74Schristos return false;
21475fd0b74Schristos
21575fd0b74Schristos bool match = true;
21675fd0b74Schristos do
21775fd0b74Schristos {
21875fd0b74Schristos switch (attrs & - attrs)
21975fd0b74Schristos {
22075fd0b74Schristos case MEM_EXECUTABLE:
22175fd0b74Schristos if ((flags & elfcpp::SHF_EXECINSTR) == 0)
22275fd0b74Schristos match = false;
22375fd0b74Schristos break;
22475fd0b74Schristos
22575fd0b74Schristos case MEM_WRITEABLE:
22675fd0b74Schristos if ((flags & elfcpp::SHF_WRITE) == 0)
22775fd0b74Schristos match = false;
22875fd0b74Schristos break;
22975fd0b74Schristos
23075fd0b74Schristos case MEM_READABLE:
23175fd0b74Schristos // All sections are presumed readable.
23275fd0b74Schristos break;
23375fd0b74Schristos
23475fd0b74Schristos case MEM_ALLOCATABLE:
23575fd0b74Schristos if ((flags & elfcpp::SHF_ALLOC) == 0)
23675fd0b74Schristos match = false;
23775fd0b74Schristos break;
23875fd0b74Schristos
23975fd0b74Schristos case MEM_INITIALIZED:
24075fd0b74Schristos if ((type & elfcpp::SHT_NOBITS) != 0)
24175fd0b74Schristos match = false;
24275fd0b74Schristos break;
24375fd0b74Schristos }
24475fd0b74Schristos attrs &= ~ (attrs & - attrs);
24575fd0b74Schristos }
24675fd0b74Schristos while (attrs != 0);
24775fd0b74Schristos
24875fd0b74Schristos return match;
24975fd0b74Schristos }
25075fd0b74Schristos
25175fd0b74Schristos // Print a memory region.
25275fd0b74Schristos
25375fd0b74Schristos void
print(FILE * f) const25475fd0b74Schristos Memory_region::print(FILE* f) const
25575fd0b74Schristos {
25675fd0b74Schristos fprintf(f, " %s", this->name_.c_str());
25775fd0b74Schristos
25875fd0b74Schristos unsigned int attrs = this->attributes_;
25975fd0b74Schristos if (attrs != 0)
26075fd0b74Schristos {
26175fd0b74Schristos fprintf(f, " (");
26275fd0b74Schristos do
26375fd0b74Schristos {
26475fd0b74Schristos switch (attrs & - attrs)
26575fd0b74Schristos {
26675fd0b74Schristos case MEM_EXECUTABLE: fputc('x', f); break;
26775fd0b74Schristos case MEM_WRITEABLE: fputc('w', f); break;
26875fd0b74Schristos case MEM_READABLE: fputc('r', f); break;
26975fd0b74Schristos case MEM_ALLOCATABLE: fputc('a', f); break;
27075fd0b74Schristos case MEM_INITIALIZED: fputc('i', f); break;
27175fd0b74Schristos default:
27275fd0b74Schristos gold_unreachable();
27375fd0b74Schristos }
27475fd0b74Schristos attrs &= ~ (attrs & - attrs);
27575fd0b74Schristos }
27675fd0b74Schristos while (attrs != 0);
27775fd0b74Schristos fputc(')', f);
27875fd0b74Schristos }
27975fd0b74Schristos
28075fd0b74Schristos fprintf(f, " : origin = ");
28175fd0b74Schristos this->start_->print(f);
28275fd0b74Schristos fprintf(f, ", length = ");
28375fd0b74Schristos this->length_->print(f);
28475fd0b74Schristos fprintf(f, "\n");
28575fd0b74Schristos }
28675fd0b74Schristos
28775fd0b74Schristos // Manage orphan sections. This is intended to be largely compatible
28875fd0b74Schristos // with the GNU linker. The Linux kernel implicitly relies on
28975fd0b74Schristos // something similar to the GNU linker's orphan placement. We
29075fd0b74Schristos // originally used a simpler scheme here, but it caused the kernel
29175fd0b74Schristos // build to fail, and was also rather inefficient.
29275fd0b74Schristos
29375fd0b74Schristos class Orphan_section_placement
29475fd0b74Schristos {
29575fd0b74Schristos private:
29675fd0b74Schristos typedef Script_sections::Elements_iterator Elements_iterator;
29775fd0b74Schristos
29875fd0b74Schristos public:
29975fd0b74Schristos Orphan_section_placement();
30075fd0b74Schristos
30175fd0b74Schristos // Handle an output section during initialization of this mapping.
30275fd0b74Schristos void
30375fd0b74Schristos output_section_init(const std::string& name, Output_section*,
30475fd0b74Schristos Elements_iterator location);
30575fd0b74Schristos
30675fd0b74Schristos // Initialize the last location.
30775fd0b74Schristos void
30875fd0b74Schristos last_init(Elements_iterator location);
30975fd0b74Schristos
31075fd0b74Schristos // Set *PWHERE to the address of an iterator pointing to the
31175fd0b74Schristos // location to use for an orphan section. Return true if the
31275fd0b74Schristos // iterator has a value, false otherwise.
31375fd0b74Schristos bool
31475fd0b74Schristos find_place(Output_section*, Elements_iterator** pwhere);
31575fd0b74Schristos
316ede78133Schristos // Update PLACE_LAST_ALLOC.
317ede78133Schristos void
318ede78133Schristos update_last_alloc(Elements_iterator where);
319ede78133Schristos
32075fd0b74Schristos // Return the iterator being used for sections at the very end of
32175fd0b74Schristos // the linker script.
32275fd0b74Schristos Elements_iterator
32375fd0b74Schristos last_place() const;
32475fd0b74Schristos
32575fd0b74Schristos private:
32675fd0b74Schristos // The places that we specifically recognize. This list is copied
32775fd0b74Schristos // from the GNU linker.
32875fd0b74Schristos enum Place_index
32975fd0b74Schristos {
33075fd0b74Schristos PLACE_TEXT,
33175fd0b74Schristos PLACE_RODATA,
33275fd0b74Schristos PLACE_DATA,
33375fd0b74Schristos PLACE_TLS,
33475fd0b74Schristos PLACE_TLS_BSS,
33575fd0b74Schristos PLACE_BSS,
336ede78133Schristos PLACE_LAST_ALLOC,
33775fd0b74Schristos PLACE_REL,
33875fd0b74Schristos PLACE_INTERP,
33975fd0b74Schristos PLACE_NONALLOC,
34075fd0b74Schristos PLACE_LAST,
34175fd0b74Schristos PLACE_MAX
34275fd0b74Schristos };
34375fd0b74Schristos
34475fd0b74Schristos // The information we keep for a specific place.
34575fd0b74Schristos struct Place
34675fd0b74Schristos {
34775fd0b74Schristos // The name of sections for this place.
34875fd0b74Schristos const char* name;
34975fd0b74Schristos // Whether we have a location for this place.
35075fd0b74Schristos bool have_location;
35175fd0b74Schristos // The iterator for this place.
35275fd0b74Schristos Elements_iterator location;
35375fd0b74Schristos };
35475fd0b74Schristos
35575fd0b74Schristos // Initialize one place element.
35675fd0b74Schristos void
35775fd0b74Schristos initialize_place(Place_index, const char*);
35875fd0b74Schristos
35975fd0b74Schristos // The places.
36075fd0b74Schristos Place places_[PLACE_MAX];
36175fd0b74Schristos // True if this is the first call to output_section_init.
36275fd0b74Schristos bool first_init_;
36375fd0b74Schristos };
36475fd0b74Schristos
36575fd0b74Schristos // Initialize Orphan_section_placement.
36675fd0b74Schristos
Orphan_section_placement()36775fd0b74Schristos Orphan_section_placement::Orphan_section_placement()
36875fd0b74Schristos : first_init_(true)
36975fd0b74Schristos {
37075fd0b74Schristos this->initialize_place(PLACE_TEXT, ".text");
37175fd0b74Schristos this->initialize_place(PLACE_RODATA, ".rodata");
37275fd0b74Schristos this->initialize_place(PLACE_DATA, ".data");
37375fd0b74Schristos this->initialize_place(PLACE_TLS, NULL);
37475fd0b74Schristos this->initialize_place(PLACE_TLS_BSS, NULL);
37575fd0b74Schristos this->initialize_place(PLACE_BSS, ".bss");
376ede78133Schristos this->initialize_place(PLACE_LAST_ALLOC, NULL);
37775fd0b74Schristos this->initialize_place(PLACE_REL, NULL);
37875fd0b74Schristos this->initialize_place(PLACE_INTERP, ".interp");
37975fd0b74Schristos this->initialize_place(PLACE_NONALLOC, NULL);
38075fd0b74Schristos this->initialize_place(PLACE_LAST, NULL);
38175fd0b74Schristos }
38275fd0b74Schristos
38375fd0b74Schristos // Initialize one place element.
38475fd0b74Schristos
38575fd0b74Schristos void
initialize_place(Place_index index,const char * name)38675fd0b74Schristos Orphan_section_placement::initialize_place(Place_index index, const char* name)
38775fd0b74Schristos {
38875fd0b74Schristos this->places_[index].name = name;
38975fd0b74Schristos this->places_[index].have_location = false;
39075fd0b74Schristos }
39175fd0b74Schristos
39275fd0b74Schristos // While initializing the Orphan_section_placement information, this
39375fd0b74Schristos // is called once for each output section named in the linker script.
39475fd0b74Schristos // If we found an output section during the link, it will be passed in
39575fd0b74Schristos // OS.
39675fd0b74Schristos
39775fd0b74Schristos void
output_section_init(const std::string & name,Output_section * os,Elements_iterator location)39875fd0b74Schristos Orphan_section_placement::output_section_init(const std::string& name,
39975fd0b74Schristos Output_section* os,
40075fd0b74Schristos Elements_iterator location)
40175fd0b74Schristos {
40275fd0b74Schristos bool first_init = this->first_init_;
40375fd0b74Schristos this->first_init_ = false;
40475fd0b74Schristos
405ede78133Schristos // Remember the last allocated section. Any orphan bss sections
406ede78133Schristos // will be placed after it.
407ede78133Schristos if (os != NULL
408ede78133Schristos && (os->flags() & elfcpp::SHF_ALLOC) != 0)
409ede78133Schristos {
410ede78133Schristos this->places_[PLACE_LAST_ALLOC].location = location;
411ede78133Schristos this->places_[PLACE_LAST_ALLOC].have_location = true;
412ede78133Schristos }
413ede78133Schristos
41475fd0b74Schristos for (int i = 0; i < PLACE_MAX; ++i)
41575fd0b74Schristos {
41675fd0b74Schristos if (this->places_[i].name != NULL && this->places_[i].name == name)
41775fd0b74Schristos {
41875fd0b74Schristos if (this->places_[i].have_location)
41975fd0b74Schristos {
42075fd0b74Schristos // We have already seen a section with this name.
42175fd0b74Schristos return;
42275fd0b74Schristos }
42375fd0b74Schristos
42475fd0b74Schristos this->places_[i].location = location;
42575fd0b74Schristos this->places_[i].have_location = true;
42675fd0b74Schristos
42775fd0b74Schristos // If we just found the .bss section, restart the search for
42875fd0b74Schristos // an unallocated section. This follows the GNU linker's
42975fd0b74Schristos // behaviour.
43075fd0b74Schristos if (i == PLACE_BSS)
43175fd0b74Schristos this->places_[PLACE_NONALLOC].have_location = false;
43275fd0b74Schristos
43375fd0b74Schristos return;
43475fd0b74Schristos }
43575fd0b74Schristos }
43675fd0b74Schristos
43775fd0b74Schristos // Relocation sections.
43875fd0b74Schristos if (!this->places_[PLACE_REL].have_location
43975fd0b74Schristos && os != NULL
44075fd0b74Schristos && (os->type() == elfcpp::SHT_REL || os->type() == elfcpp::SHT_RELA)
44175fd0b74Schristos && (os->flags() & elfcpp::SHF_ALLOC) != 0)
44275fd0b74Schristos {
44375fd0b74Schristos this->places_[PLACE_REL].location = location;
44475fd0b74Schristos this->places_[PLACE_REL].have_location = true;
44575fd0b74Schristos }
44675fd0b74Schristos
44775fd0b74Schristos // We find the location for unallocated sections by finding the
44875fd0b74Schristos // first debugging or comment section after the BSS section (if
44975fd0b74Schristos // there is one).
45075fd0b74Schristos if (!this->places_[PLACE_NONALLOC].have_location
45175fd0b74Schristos && (name == ".comment" || Layout::is_debug_info_section(name.c_str())))
45275fd0b74Schristos {
45375fd0b74Schristos // We add orphan sections after the location in PLACES_. We
45475fd0b74Schristos // want to store unallocated sections before LOCATION. If this
45575fd0b74Schristos // is the very first section, we can't use it.
45675fd0b74Schristos if (!first_init)
45775fd0b74Schristos {
45875fd0b74Schristos --location;
45975fd0b74Schristos this->places_[PLACE_NONALLOC].location = location;
46075fd0b74Schristos this->places_[PLACE_NONALLOC].have_location = true;
46175fd0b74Schristos }
46275fd0b74Schristos }
46375fd0b74Schristos }
46475fd0b74Schristos
46575fd0b74Schristos // Initialize the last location.
46675fd0b74Schristos
46775fd0b74Schristos void
last_init(Elements_iterator location)46875fd0b74Schristos Orphan_section_placement::last_init(Elements_iterator location)
46975fd0b74Schristos {
47075fd0b74Schristos this->places_[PLACE_LAST].location = location;
47175fd0b74Schristos this->places_[PLACE_LAST].have_location = true;
47275fd0b74Schristos }
47375fd0b74Schristos
47475fd0b74Schristos // Set *PWHERE to the address of an iterator pointing to the location
47575fd0b74Schristos // to use for an orphan section. Return true if the iterator has a
47675fd0b74Schristos // value, false otherwise.
47775fd0b74Schristos
47875fd0b74Schristos bool
find_place(Output_section * os,Elements_iterator ** pwhere)47975fd0b74Schristos Orphan_section_placement::find_place(Output_section* os,
48075fd0b74Schristos Elements_iterator** pwhere)
48175fd0b74Schristos {
48275fd0b74Schristos // Figure out where OS should go. This is based on the GNU linker
48375fd0b74Schristos // code. FIXME: The GNU linker handles small data sections
48475fd0b74Schristos // specially, but we don't.
48575fd0b74Schristos elfcpp::Elf_Word type = os->type();
48675fd0b74Schristos elfcpp::Elf_Xword flags = os->flags();
48775fd0b74Schristos Place_index index;
48875fd0b74Schristos if ((flags & elfcpp::SHF_ALLOC) == 0
48975fd0b74Schristos && !Layout::is_debug_info_section(os->name()))
49075fd0b74Schristos index = PLACE_NONALLOC;
49175fd0b74Schristos else if ((flags & elfcpp::SHF_ALLOC) == 0)
49275fd0b74Schristos index = PLACE_LAST;
49375fd0b74Schristos else if (type == elfcpp::SHT_NOTE)
49475fd0b74Schristos index = PLACE_INTERP;
49575fd0b74Schristos else if ((flags & elfcpp::SHF_TLS) != 0)
49675fd0b74Schristos {
49775fd0b74Schristos if (type == elfcpp::SHT_NOBITS)
49875fd0b74Schristos index = PLACE_TLS_BSS;
49975fd0b74Schristos else
50075fd0b74Schristos index = PLACE_TLS;
50175fd0b74Schristos }
50275fd0b74Schristos else if (type == elfcpp::SHT_NOBITS)
50375fd0b74Schristos index = PLACE_BSS;
50475fd0b74Schristos else if ((flags & elfcpp::SHF_WRITE) != 0)
50575fd0b74Schristos index = PLACE_DATA;
50675fd0b74Schristos else if (type == elfcpp::SHT_REL || type == elfcpp::SHT_RELA)
50775fd0b74Schristos index = PLACE_REL;
50875fd0b74Schristos else if ((flags & elfcpp::SHF_EXECINSTR) == 0)
50975fd0b74Schristos index = PLACE_RODATA;
51075fd0b74Schristos else
51175fd0b74Schristos index = PLACE_TEXT;
51275fd0b74Schristos
51375fd0b74Schristos // If we don't have a location yet, try to find one based on a
51475fd0b74Schristos // plausible ordering of sections.
51575fd0b74Schristos if (!this->places_[index].have_location)
51675fd0b74Schristos {
51775fd0b74Schristos Place_index follow;
51875fd0b74Schristos switch (index)
51975fd0b74Schristos {
52075fd0b74Schristos default:
52175fd0b74Schristos follow = PLACE_MAX;
52275fd0b74Schristos break;
52375fd0b74Schristos case PLACE_RODATA:
52475fd0b74Schristos follow = PLACE_TEXT;
52575fd0b74Schristos break;
526ede78133Schristos case PLACE_DATA:
527ede78133Schristos follow = PLACE_RODATA;
528ede78133Schristos if (!this->places_[PLACE_RODATA].have_location)
529ede78133Schristos follow = PLACE_TEXT;
530ede78133Schristos break;
53175fd0b74Schristos case PLACE_BSS:
532ede78133Schristos follow = PLACE_LAST_ALLOC;
53375fd0b74Schristos break;
53475fd0b74Schristos case PLACE_REL:
53575fd0b74Schristos follow = PLACE_TEXT;
53675fd0b74Schristos break;
53775fd0b74Schristos case PLACE_INTERP:
53875fd0b74Schristos follow = PLACE_TEXT;
53975fd0b74Schristos break;
54075fd0b74Schristos case PLACE_TLS:
54175fd0b74Schristos follow = PLACE_DATA;
54275fd0b74Schristos break;
54375fd0b74Schristos case PLACE_TLS_BSS:
54475fd0b74Schristos follow = PLACE_TLS;
54575fd0b74Schristos if (!this->places_[PLACE_TLS].have_location)
54675fd0b74Schristos follow = PLACE_DATA;
54775fd0b74Schristos break;
54875fd0b74Schristos }
54975fd0b74Schristos if (follow != PLACE_MAX && this->places_[follow].have_location)
55075fd0b74Schristos {
55175fd0b74Schristos // Set the location of INDEX to the location of FOLLOW. The
55275fd0b74Schristos // location of INDEX will then be incremented by the caller,
55375fd0b74Schristos // so anything in INDEX will continue to be after anything
55475fd0b74Schristos // in FOLLOW.
55575fd0b74Schristos this->places_[index].location = this->places_[follow].location;
55675fd0b74Schristos this->places_[index].have_location = true;
55775fd0b74Schristos }
55875fd0b74Schristos }
55975fd0b74Schristos
56075fd0b74Schristos *pwhere = &this->places_[index].location;
56175fd0b74Schristos bool ret = this->places_[index].have_location;
56275fd0b74Schristos
56375fd0b74Schristos // The caller will set the location.
56475fd0b74Schristos this->places_[index].have_location = true;
56575fd0b74Schristos
56675fd0b74Schristos return ret;
56775fd0b74Schristos }
56875fd0b74Schristos
569ede78133Schristos // Update PLACE_LAST_ALLOC.
570ede78133Schristos void
update_last_alloc(Elements_iterator elem)571ede78133Schristos Orphan_section_placement::update_last_alloc(Elements_iterator elem)
572ede78133Schristos {
573ede78133Schristos Elements_iterator prev = elem;
574ede78133Schristos --prev;
575ede78133Schristos if (this->places_[PLACE_LAST_ALLOC].have_location
576ede78133Schristos && this->places_[PLACE_LAST_ALLOC].location == prev)
577ede78133Schristos {
578ede78133Schristos this->places_[PLACE_LAST_ALLOC].have_location = true;
579ede78133Schristos this->places_[PLACE_LAST_ALLOC].location = elem;
580ede78133Schristos }
581ede78133Schristos }
582ede78133Schristos
58375fd0b74Schristos // Return the iterator being used for sections at the very end of the
58475fd0b74Schristos // linker script.
58575fd0b74Schristos
58675fd0b74Schristos Orphan_section_placement::Elements_iterator
last_place() const58775fd0b74Schristos Orphan_section_placement::last_place() const
58875fd0b74Schristos {
58975fd0b74Schristos gold_assert(this->places_[PLACE_LAST].have_location);
59075fd0b74Schristos return this->places_[PLACE_LAST].location;
59175fd0b74Schristos }
59275fd0b74Schristos
59375fd0b74Schristos // An element in a SECTIONS clause.
59475fd0b74Schristos
59575fd0b74Schristos class Sections_element
59675fd0b74Schristos {
59775fd0b74Schristos public:
Sections_element()59875fd0b74Schristos Sections_element()
59975fd0b74Schristos { }
60075fd0b74Schristos
~Sections_element()60175fd0b74Schristos virtual ~Sections_element()
60275fd0b74Schristos { }
60375fd0b74Schristos
60475fd0b74Schristos // Return whether an output section is relro.
60575fd0b74Schristos virtual bool
is_relro() const60675fd0b74Schristos is_relro() const
60775fd0b74Schristos { return false; }
60875fd0b74Schristos
60975fd0b74Schristos // Record that an output section is relro.
61075fd0b74Schristos virtual void
set_is_relro()61175fd0b74Schristos set_is_relro()
61275fd0b74Schristos { }
61375fd0b74Schristos
61475fd0b74Schristos // Create any required output sections. The only real
61575fd0b74Schristos // implementation is in Output_section_definition.
61675fd0b74Schristos virtual void
create_sections(Layout *)61775fd0b74Schristos create_sections(Layout*)
61875fd0b74Schristos { }
61975fd0b74Schristos
62075fd0b74Schristos // Add any symbol being defined to the symbol table.
62175fd0b74Schristos virtual void
add_symbols_to_table(Symbol_table *)62275fd0b74Schristos add_symbols_to_table(Symbol_table*)
62375fd0b74Schristos { }
62475fd0b74Schristos
62575fd0b74Schristos // Finalize symbols and check assertions.
62675fd0b74Schristos virtual void
finalize_symbols(Symbol_table *,const Layout *,uint64_t *)62775fd0b74Schristos finalize_symbols(Symbol_table*, const Layout*, uint64_t*)
62875fd0b74Schristos { }
62975fd0b74Schristos
63075fd0b74Schristos // Return the output section name to use for an input file name and
63175fd0b74Schristos // section name. This only real implementation is in
63275fd0b74Schristos // Output_section_definition.
63375fd0b74Schristos virtual const char*
output_section_name(const char *,const char *,Output_section ***,Script_sections::Section_type *,bool *,bool)63475fd0b74Schristos output_section_name(const char*, const char*, Output_section***,
635ede78133Schristos Script_sections::Section_type*, bool*, bool)
63675fd0b74Schristos { return NULL; }
63775fd0b74Schristos
63875fd0b74Schristos // Initialize OSP with an output section.
63975fd0b74Schristos virtual void
orphan_section_init(Orphan_section_placement *,Script_sections::Elements_iterator)64075fd0b74Schristos orphan_section_init(Orphan_section_placement*,
64175fd0b74Schristos Script_sections::Elements_iterator)
64275fd0b74Schristos { }
64375fd0b74Schristos
64475fd0b74Schristos // Set section addresses. This includes applying assignments if the
64575fd0b74Schristos // expression is an absolute value.
64675fd0b74Schristos virtual void
set_section_addresses(Symbol_table *,Layout *,uint64_t *,uint64_t *,uint64_t *)64775fd0b74Schristos set_section_addresses(Symbol_table*, Layout*, uint64_t*, uint64_t*,
64875fd0b74Schristos uint64_t*)
64975fd0b74Schristos { }
65075fd0b74Schristos
65175fd0b74Schristos // Check a constraint (ONLY_IF_RO, etc.) on an output section. If
65275fd0b74Schristos // this section is constrained, and the input sections do not match,
65375fd0b74Schristos // return the constraint, and set *POSD.
65475fd0b74Schristos virtual Section_constraint
check_constraint(Output_section_definition **)65575fd0b74Schristos check_constraint(Output_section_definition**)
65675fd0b74Schristos { return CONSTRAINT_NONE; }
65775fd0b74Schristos
65875fd0b74Schristos // See if this is the alternate output section for a constrained
65975fd0b74Schristos // output section. If it is, transfer the Output_section and return
66075fd0b74Schristos // true. Otherwise return false.
66175fd0b74Schristos virtual bool
alternate_constraint(Output_section_definition *,Section_constraint)66275fd0b74Schristos alternate_constraint(Output_section_definition*, Section_constraint)
66375fd0b74Schristos { return false; }
66475fd0b74Schristos
66575fd0b74Schristos // Get the list of segments to use for an allocated section when
66675fd0b74Schristos // using a PHDRS clause. If this is an allocated section, return
66775fd0b74Schristos // the Output_section, and set *PHDRS_LIST (the first parameter) to
66875fd0b74Schristos // the list of PHDRS to which it should be attached. If the PHDRS
66975fd0b74Schristos // were not specified, don't change *PHDRS_LIST. When not returning
67075fd0b74Schristos // NULL, set *ORPHAN (the second parameter) according to whether
67175fd0b74Schristos // this is an orphan section--one that is not mentioned in the
67275fd0b74Schristos // linker script.
67375fd0b74Schristos virtual Output_section*
allocate_to_segment(String_list **,bool *)67475fd0b74Schristos allocate_to_segment(String_list**, bool*)
67575fd0b74Schristos { return NULL; }
67675fd0b74Schristos
67775fd0b74Schristos // Look for an output section by name and return the address, the
67875fd0b74Schristos // load address, the alignment, and the size. This is used when an
67975fd0b74Schristos // expression refers to an output section which was not actually
68075fd0b74Schristos // created. This returns true if the section was found, false
68175fd0b74Schristos // otherwise. The only real definition is for
68275fd0b74Schristos // Output_section_definition.
68375fd0b74Schristos virtual bool
get_output_section_info(const char *,uint64_t *,uint64_t *,uint64_t *,uint64_t *) const68475fd0b74Schristos get_output_section_info(const char*, uint64_t*, uint64_t*, uint64_t*,
68575fd0b74Schristos uint64_t*) const
68675fd0b74Schristos { return false; }
68775fd0b74Schristos
68875fd0b74Schristos // Return the associated Output_section if there is one.
68975fd0b74Schristos virtual Output_section*
get_output_section() const69075fd0b74Schristos get_output_section() const
69175fd0b74Schristos { return NULL; }
69275fd0b74Schristos
69375fd0b74Schristos // Set the section's memory regions.
69475fd0b74Schristos virtual void
set_memory_region(Memory_region *,bool)69575fd0b74Schristos set_memory_region(Memory_region*, bool)
69675fd0b74Schristos { gold_error(_("Attempt to set a memory region for a non-output section")); }
69775fd0b74Schristos
69875fd0b74Schristos // Print the element for debugging purposes.
69975fd0b74Schristos virtual void
70075fd0b74Schristos print(FILE* f) const = 0;
70175fd0b74Schristos };
70275fd0b74Schristos
70375fd0b74Schristos // An assignment in a SECTIONS clause outside of an output section.
70475fd0b74Schristos
70575fd0b74Schristos class Sections_element_assignment : public Sections_element
70675fd0b74Schristos {
70775fd0b74Schristos public:
Sections_element_assignment(const char * name,size_t namelen,Expression * val,bool provide,bool hidden)70875fd0b74Schristos Sections_element_assignment(const char* name, size_t namelen,
70975fd0b74Schristos Expression* val, bool provide, bool hidden)
71075fd0b74Schristos : assignment_(name, namelen, false, val, provide, hidden)
71175fd0b74Schristos { }
71275fd0b74Schristos
71375fd0b74Schristos // Add the symbol to the symbol table.
71475fd0b74Schristos void
add_symbols_to_table(Symbol_table * symtab)71575fd0b74Schristos add_symbols_to_table(Symbol_table* symtab)
71675fd0b74Schristos { this->assignment_.add_to_table(symtab); }
71775fd0b74Schristos
71875fd0b74Schristos // Finalize the symbol.
71975fd0b74Schristos void
finalize_symbols(Symbol_table * symtab,const Layout * layout,uint64_t * dot_value)72075fd0b74Schristos finalize_symbols(Symbol_table* symtab, const Layout* layout,
72175fd0b74Schristos uint64_t* dot_value)
72275fd0b74Schristos {
72375fd0b74Schristos this->assignment_.finalize_with_dot(symtab, layout, *dot_value, NULL);
72475fd0b74Schristos }
72575fd0b74Schristos
72675fd0b74Schristos // Set the section address. There is no section here, but if the
72775fd0b74Schristos // value is absolute, we set the symbol. This permits us to use
72875fd0b74Schristos // absolute symbols when setting dot.
72975fd0b74Schristos void
set_section_addresses(Symbol_table * symtab,Layout * layout,uint64_t * dot_value,uint64_t *,uint64_t *)73075fd0b74Schristos set_section_addresses(Symbol_table* symtab, Layout* layout,
73175fd0b74Schristos uint64_t* dot_value, uint64_t*, uint64_t*)
73275fd0b74Schristos {
73375fd0b74Schristos this->assignment_.set_if_absolute(symtab, layout, true, *dot_value, NULL);
73475fd0b74Schristos }
73575fd0b74Schristos
73675fd0b74Schristos // Print for debugging.
73775fd0b74Schristos void
print(FILE * f) const73875fd0b74Schristos print(FILE* f) const
73975fd0b74Schristos {
74075fd0b74Schristos fprintf(f, " ");
74175fd0b74Schristos this->assignment_.print(f);
74275fd0b74Schristos }
74375fd0b74Schristos
74475fd0b74Schristos private:
74575fd0b74Schristos Symbol_assignment assignment_;
74675fd0b74Schristos };
74775fd0b74Schristos
74875fd0b74Schristos // An assignment to the dot symbol in a SECTIONS clause outside of an
74975fd0b74Schristos // output section.
75075fd0b74Schristos
75175fd0b74Schristos class Sections_element_dot_assignment : public Sections_element
75275fd0b74Schristos {
75375fd0b74Schristos public:
Sections_element_dot_assignment(Expression * val)75475fd0b74Schristos Sections_element_dot_assignment(Expression* val)
75575fd0b74Schristos : val_(val)
75675fd0b74Schristos { }
75775fd0b74Schristos
75875fd0b74Schristos // Finalize the symbol.
75975fd0b74Schristos void
finalize_symbols(Symbol_table * symtab,const Layout * layout,uint64_t * dot_value)76075fd0b74Schristos finalize_symbols(Symbol_table* symtab, const Layout* layout,
76175fd0b74Schristos uint64_t* dot_value)
76275fd0b74Schristos {
76375fd0b74Schristos // We ignore the section of the result because outside of an
76475fd0b74Schristos // output section definition the dot symbol is always considered
76575fd0b74Schristos // to be absolute.
76675fd0b74Schristos *dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value,
76775fd0b74Schristos NULL, NULL, NULL, false);
76875fd0b74Schristos }
76975fd0b74Schristos
77075fd0b74Schristos // Update the dot symbol while setting section addresses.
77175fd0b74Schristos void
set_section_addresses(Symbol_table * symtab,Layout * layout,uint64_t * dot_value,uint64_t * dot_alignment,uint64_t * load_address)77275fd0b74Schristos set_section_addresses(Symbol_table* symtab, Layout* layout,
77375fd0b74Schristos uint64_t* dot_value, uint64_t* dot_alignment,
77475fd0b74Schristos uint64_t* load_address)
77575fd0b74Schristos {
77675fd0b74Schristos *dot_value = this->val_->eval_with_dot(symtab, layout, false, *dot_value,
77775fd0b74Schristos NULL, NULL, dot_alignment, false);
77875fd0b74Schristos *load_address = *dot_value;
77975fd0b74Schristos }
78075fd0b74Schristos
78175fd0b74Schristos // Print for debugging.
78275fd0b74Schristos void
print(FILE * f) const78375fd0b74Schristos print(FILE* f) const
78475fd0b74Schristos {
78575fd0b74Schristos fprintf(f, " . = ");
78675fd0b74Schristos this->val_->print(f);
78775fd0b74Schristos fprintf(f, "\n");
78875fd0b74Schristos }
78975fd0b74Schristos
79075fd0b74Schristos private:
79175fd0b74Schristos Expression* val_;
79275fd0b74Schristos };
79375fd0b74Schristos
79475fd0b74Schristos // An assertion in a SECTIONS clause outside of an output section.
79575fd0b74Schristos
79675fd0b74Schristos class Sections_element_assertion : public Sections_element
79775fd0b74Schristos {
79875fd0b74Schristos public:
Sections_element_assertion(Expression * check,const char * message,size_t messagelen)79975fd0b74Schristos Sections_element_assertion(Expression* check, const char* message,
80075fd0b74Schristos size_t messagelen)
80175fd0b74Schristos : assertion_(check, message, messagelen)
80275fd0b74Schristos { }
80375fd0b74Schristos
80475fd0b74Schristos // Check the assertion.
80575fd0b74Schristos void
finalize_symbols(Symbol_table * symtab,const Layout * layout,uint64_t *)80675fd0b74Schristos finalize_symbols(Symbol_table* symtab, const Layout* layout, uint64_t*)
80775fd0b74Schristos { this->assertion_.check(symtab, layout); }
80875fd0b74Schristos
80975fd0b74Schristos // Print for debugging.
81075fd0b74Schristos void
print(FILE * f) const81175fd0b74Schristos print(FILE* f) const
81275fd0b74Schristos {
81375fd0b74Schristos fprintf(f, " ");
81475fd0b74Schristos this->assertion_.print(f);
81575fd0b74Schristos }
81675fd0b74Schristos
81775fd0b74Schristos private:
81875fd0b74Schristos Script_assertion assertion_;
81975fd0b74Schristos };
82075fd0b74Schristos
82175fd0b74Schristos // An element in an output section in a SECTIONS clause.
82275fd0b74Schristos
82375fd0b74Schristos class Output_section_element
82475fd0b74Schristos {
82575fd0b74Schristos public:
82675fd0b74Schristos // A list of input sections.
82775fd0b74Schristos typedef std::list<Output_section::Input_section> Input_section_list;
82875fd0b74Schristos
Output_section_element()82975fd0b74Schristos Output_section_element()
83075fd0b74Schristos { }
83175fd0b74Schristos
~Output_section_element()83275fd0b74Schristos virtual ~Output_section_element()
83375fd0b74Schristos { }
83475fd0b74Schristos
83575fd0b74Schristos // Return whether this element requires an output section to exist.
83675fd0b74Schristos virtual bool
needs_output_section() const83775fd0b74Schristos needs_output_section() const
83875fd0b74Schristos { return false; }
83975fd0b74Schristos
84075fd0b74Schristos // Add any symbol being defined to the symbol table.
84175fd0b74Schristos virtual void
add_symbols_to_table(Symbol_table *)84275fd0b74Schristos add_symbols_to_table(Symbol_table*)
84375fd0b74Schristos { }
84475fd0b74Schristos
84575fd0b74Schristos // Finalize symbols and check assertions.
84675fd0b74Schristos virtual void
finalize_symbols(Symbol_table *,const Layout *,uint64_t *,Output_section **)84775fd0b74Schristos finalize_symbols(Symbol_table*, const Layout*, uint64_t*, Output_section**)
84875fd0b74Schristos { }
84975fd0b74Schristos
85075fd0b74Schristos // Return whether this element matches FILE_NAME and SECTION_NAME.
85175fd0b74Schristos // The only real implementation is in Output_section_element_input.
85275fd0b74Schristos virtual bool
match_name(const char *,const char *,bool *) const85375fd0b74Schristos match_name(const char*, const char*, bool *) const
85475fd0b74Schristos { return false; }
85575fd0b74Schristos
85675fd0b74Schristos // Set section addresses. This includes applying assignments if the
85775fd0b74Schristos // expression is an absolute value.
85875fd0b74Schristos virtual void
set_section_addresses(Symbol_table *,Layout *,Output_section *,uint64_t,uint64_t *,uint64_t *,Output_section **,std::string *,Input_section_list *)85975fd0b74Schristos set_section_addresses(Symbol_table*, Layout*, Output_section*, uint64_t,
86075fd0b74Schristos uint64_t*, uint64_t*, Output_section**, std::string*,
86175fd0b74Schristos Input_section_list*)
86275fd0b74Schristos { }
86375fd0b74Schristos
86475fd0b74Schristos // Print the element for debugging purposes.
86575fd0b74Schristos virtual void
86675fd0b74Schristos print(FILE* f) const = 0;
86775fd0b74Schristos
86875fd0b74Schristos protected:
86975fd0b74Schristos // Return a fill string that is LENGTH bytes long, filling it with
87075fd0b74Schristos // FILL.
87175fd0b74Schristos std::string
87275fd0b74Schristos get_fill_string(const std::string* fill, section_size_type length) const;
87375fd0b74Schristos };
87475fd0b74Schristos
87575fd0b74Schristos std::string
get_fill_string(const std::string * fill,section_size_type length) const87675fd0b74Schristos Output_section_element::get_fill_string(const std::string* fill,
87775fd0b74Schristos section_size_type length) const
87875fd0b74Schristos {
87975fd0b74Schristos std::string this_fill;
88075fd0b74Schristos this_fill.reserve(length);
88175fd0b74Schristos while (this_fill.length() + fill->length() <= length)
88275fd0b74Schristos this_fill += *fill;
88375fd0b74Schristos if (this_fill.length() < length)
88475fd0b74Schristos this_fill.append(*fill, 0, length - this_fill.length());
88575fd0b74Schristos return this_fill;
88675fd0b74Schristos }
88775fd0b74Schristos
88875fd0b74Schristos // A symbol assignment in an output section.
88975fd0b74Schristos
89075fd0b74Schristos class Output_section_element_assignment : public Output_section_element
89175fd0b74Schristos {
89275fd0b74Schristos public:
Output_section_element_assignment(const char * name,size_t namelen,Expression * val,bool provide,bool hidden)89375fd0b74Schristos Output_section_element_assignment(const char* name, size_t namelen,
89475fd0b74Schristos Expression* val, bool provide,
89575fd0b74Schristos bool hidden)
89675fd0b74Schristos : assignment_(name, namelen, false, val, provide, hidden)
89775fd0b74Schristos { }
89875fd0b74Schristos
89975fd0b74Schristos // Add the symbol to the symbol table.
90075fd0b74Schristos void
add_symbols_to_table(Symbol_table * symtab)90175fd0b74Schristos add_symbols_to_table(Symbol_table* symtab)
90275fd0b74Schristos { this->assignment_.add_to_table(symtab); }
90375fd0b74Schristos
90475fd0b74Schristos // Finalize the symbol.
90575fd0b74Schristos void
finalize_symbols(Symbol_table * symtab,const Layout * layout,uint64_t * dot_value,Output_section ** dot_section)90675fd0b74Schristos finalize_symbols(Symbol_table* symtab, const Layout* layout,
90775fd0b74Schristos uint64_t* dot_value, Output_section** dot_section)
90875fd0b74Schristos {
90975fd0b74Schristos this->assignment_.finalize_with_dot(symtab, layout, *dot_value,
91075fd0b74Schristos *dot_section);
91175fd0b74Schristos }
91275fd0b74Schristos
91375fd0b74Schristos // Set the section address. There is no section here, but if the
91475fd0b74Schristos // value is absolute, we set the symbol. This permits us to use
91575fd0b74Schristos // absolute symbols when setting dot.
91675fd0b74Schristos void
set_section_addresses(Symbol_table * symtab,Layout * layout,Output_section *,uint64_t,uint64_t * dot_value,uint64_t *,Output_section ** dot_section,std::string *,Input_section_list *)91775fd0b74Schristos set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*,
91875fd0b74Schristos uint64_t, uint64_t* dot_value, uint64_t*,
91975fd0b74Schristos Output_section** dot_section, std::string*,
92075fd0b74Schristos Input_section_list*)
92175fd0b74Schristos {
92275fd0b74Schristos this->assignment_.set_if_absolute(symtab, layout, true, *dot_value,
92375fd0b74Schristos *dot_section);
92475fd0b74Schristos }
92575fd0b74Schristos
92675fd0b74Schristos // Print for debugging.
92775fd0b74Schristos void
print(FILE * f) const92875fd0b74Schristos print(FILE* f) const
92975fd0b74Schristos {
93075fd0b74Schristos fprintf(f, " ");
93175fd0b74Schristos this->assignment_.print(f);
93275fd0b74Schristos }
93375fd0b74Schristos
93475fd0b74Schristos private:
93575fd0b74Schristos Symbol_assignment assignment_;
93675fd0b74Schristos };
93775fd0b74Schristos
93875fd0b74Schristos // An assignment to the dot symbol in an output section.
93975fd0b74Schristos
94075fd0b74Schristos class Output_section_element_dot_assignment : public Output_section_element
94175fd0b74Schristos {
94275fd0b74Schristos public:
Output_section_element_dot_assignment(Expression * val)94375fd0b74Schristos Output_section_element_dot_assignment(Expression* val)
94475fd0b74Schristos : val_(val)
94575fd0b74Schristos { }
94675fd0b74Schristos
94775fd0b74Schristos // An assignment to dot within an output section is enough to force
94875fd0b74Schristos // the output section to exist.
94975fd0b74Schristos bool
needs_output_section() const95075fd0b74Schristos needs_output_section() const
95175fd0b74Schristos { return true; }
95275fd0b74Schristos
95375fd0b74Schristos // Finalize the symbol.
95475fd0b74Schristos void
finalize_symbols(Symbol_table * symtab,const Layout * layout,uint64_t * dot_value,Output_section ** dot_section)95575fd0b74Schristos finalize_symbols(Symbol_table* symtab, const Layout* layout,
95675fd0b74Schristos uint64_t* dot_value, Output_section** dot_section)
95775fd0b74Schristos {
95875fd0b74Schristos *dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value,
95975fd0b74Schristos *dot_section, dot_section, NULL,
96075fd0b74Schristos true);
96175fd0b74Schristos }
96275fd0b74Schristos
96375fd0b74Schristos // Update the dot symbol while setting section addresses.
96475fd0b74Schristos void
96575fd0b74Schristos set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*,
96675fd0b74Schristos uint64_t, uint64_t* dot_value, uint64_t*,
96775fd0b74Schristos Output_section** dot_section, std::string*,
96875fd0b74Schristos Input_section_list*);
96975fd0b74Schristos
97075fd0b74Schristos // Print for debugging.
97175fd0b74Schristos void
print(FILE * f) const97275fd0b74Schristos print(FILE* f) const
97375fd0b74Schristos {
97475fd0b74Schristos fprintf(f, " . = ");
97575fd0b74Schristos this->val_->print(f);
97675fd0b74Schristos fprintf(f, "\n");
97775fd0b74Schristos }
97875fd0b74Schristos
97975fd0b74Schristos private:
98075fd0b74Schristos Expression* val_;
98175fd0b74Schristos };
98275fd0b74Schristos
98375fd0b74Schristos // Update the dot symbol while setting section addresses.
98475fd0b74Schristos
98575fd0b74Schristos void
set_section_addresses(Symbol_table * symtab,Layout * layout,Output_section * output_section,uint64_t,uint64_t * dot_value,uint64_t * dot_alignment,Output_section ** dot_section,std::string * fill,Input_section_list *)98675fd0b74Schristos Output_section_element_dot_assignment::set_section_addresses(
98775fd0b74Schristos Symbol_table* symtab,
98875fd0b74Schristos Layout* layout,
98975fd0b74Schristos Output_section* output_section,
99075fd0b74Schristos uint64_t,
99175fd0b74Schristos uint64_t* dot_value,
99275fd0b74Schristos uint64_t* dot_alignment,
99375fd0b74Schristos Output_section** dot_section,
99475fd0b74Schristos std::string* fill,
99575fd0b74Schristos Input_section_list*)
99675fd0b74Schristos {
99775fd0b74Schristos uint64_t next_dot = this->val_->eval_with_dot(symtab, layout, false,
99875fd0b74Schristos *dot_value, *dot_section,
99975fd0b74Schristos dot_section, dot_alignment,
100075fd0b74Schristos true);
100175fd0b74Schristos if (next_dot < *dot_value)
100275fd0b74Schristos gold_error(_("dot may not move backward"));
100375fd0b74Schristos if (next_dot > *dot_value && output_section != NULL)
100475fd0b74Schristos {
100575fd0b74Schristos section_size_type length = convert_to_section_size_type(next_dot
100675fd0b74Schristos - *dot_value);
100775fd0b74Schristos Output_section_data* posd;
100875fd0b74Schristos if (fill->empty())
100975fd0b74Schristos posd = new Output_data_zero_fill(length, 0);
101075fd0b74Schristos else
101175fd0b74Schristos {
101275fd0b74Schristos std::string this_fill = this->get_fill_string(fill, length);
101375fd0b74Schristos posd = new Output_data_const(this_fill, 0);
101475fd0b74Schristos }
101575fd0b74Schristos output_section->add_output_section_data(posd);
101675fd0b74Schristos layout->new_output_section_data_from_script(posd);
101775fd0b74Schristos }
101875fd0b74Schristos *dot_value = next_dot;
101975fd0b74Schristos }
102075fd0b74Schristos
102175fd0b74Schristos // An assertion in an output section.
102275fd0b74Schristos
102375fd0b74Schristos class Output_section_element_assertion : public Output_section_element
102475fd0b74Schristos {
102575fd0b74Schristos public:
Output_section_element_assertion(Expression * check,const char * message,size_t messagelen)102675fd0b74Schristos Output_section_element_assertion(Expression* check, const char* message,
102775fd0b74Schristos size_t messagelen)
102875fd0b74Schristos : assertion_(check, message, messagelen)
102975fd0b74Schristos { }
103075fd0b74Schristos
103175fd0b74Schristos void
print(FILE * f) const103275fd0b74Schristos print(FILE* f) const
103375fd0b74Schristos {
103475fd0b74Schristos fprintf(f, " ");
103575fd0b74Schristos this->assertion_.print(f);
103675fd0b74Schristos }
103775fd0b74Schristos
103875fd0b74Schristos private:
103975fd0b74Schristos Script_assertion assertion_;
104075fd0b74Schristos };
104175fd0b74Schristos
104275fd0b74Schristos // We use a special instance of Output_section_data to handle BYTE,
104375fd0b74Schristos // SHORT, etc. This permits forward references to symbols in the
104475fd0b74Schristos // expressions.
104575fd0b74Schristos
104675fd0b74Schristos class Output_data_expression : public Output_section_data
104775fd0b74Schristos {
104875fd0b74Schristos public:
Output_data_expression(int size,bool is_signed,Expression * val,const Symbol_table * symtab,const Layout * layout,uint64_t dot_value,Output_section * dot_section)104975fd0b74Schristos Output_data_expression(int size, bool is_signed, Expression* val,
105075fd0b74Schristos const Symbol_table* symtab, const Layout* layout,
105175fd0b74Schristos uint64_t dot_value, Output_section* dot_section)
105275fd0b74Schristos : Output_section_data(size, 0, true),
105375fd0b74Schristos is_signed_(is_signed), val_(val), symtab_(symtab),
105475fd0b74Schristos layout_(layout), dot_value_(dot_value), dot_section_(dot_section)
105575fd0b74Schristos { }
105675fd0b74Schristos
105775fd0b74Schristos protected:
105875fd0b74Schristos // Write the data to the output file.
105975fd0b74Schristos void
106075fd0b74Schristos do_write(Output_file*);
106175fd0b74Schristos
106275fd0b74Schristos // Write the data to a buffer.
106375fd0b74Schristos void
106475fd0b74Schristos do_write_to_buffer(unsigned char*);
106575fd0b74Schristos
106675fd0b74Schristos // Write to a map file.
106775fd0b74Schristos void
do_print_to_mapfile(Mapfile * mapfile) const106875fd0b74Schristos do_print_to_mapfile(Mapfile* mapfile) const
106975fd0b74Schristos { mapfile->print_output_data(this, _("** expression")); }
107075fd0b74Schristos
107175fd0b74Schristos private:
107275fd0b74Schristos template<bool big_endian>
107375fd0b74Schristos void
107475fd0b74Schristos endian_write_to_buffer(uint64_t, unsigned char*);
107575fd0b74Schristos
107675fd0b74Schristos bool is_signed_;
107775fd0b74Schristos Expression* val_;
107875fd0b74Schristos const Symbol_table* symtab_;
107975fd0b74Schristos const Layout* layout_;
108075fd0b74Schristos uint64_t dot_value_;
108175fd0b74Schristos Output_section* dot_section_;
108275fd0b74Schristos };
108375fd0b74Schristos
108475fd0b74Schristos // Write the data element to the output file.
108575fd0b74Schristos
108675fd0b74Schristos void
do_write(Output_file * of)108775fd0b74Schristos Output_data_expression::do_write(Output_file* of)
108875fd0b74Schristos {
108975fd0b74Schristos unsigned char* view = of->get_output_view(this->offset(), this->data_size());
109075fd0b74Schristos this->write_to_buffer(view);
109175fd0b74Schristos of->write_output_view(this->offset(), this->data_size(), view);
109275fd0b74Schristos }
109375fd0b74Schristos
109475fd0b74Schristos // Write the data element to a buffer.
109575fd0b74Schristos
109675fd0b74Schristos void
do_write_to_buffer(unsigned char * buf)109775fd0b74Schristos Output_data_expression::do_write_to_buffer(unsigned char* buf)
109875fd0b74Schristos {
109975fd0b74Schristos uint64_t val = this->val_->eval_with_dot(this->symtab_, this->layout_,
110075fd0b74Schristos true, this->dot_value_,
110175fd0b74Schristos this->dot_section_, NULL, NULL,
110275fd0b74Schristos false);
110375fd0b74Schristos
110475fd0b74Schristos if (parameters->target().is_big_endian())
110575fd0b74Schristos this->endian_write_to_buffer<true>(val, buf);
110675fd0b74Schristos else
110775fd0b74Schristos this->endian_write_to_buffer<false>(val, buf);
110875fd0b74Schristos }
110975fd0b74Schristos
111075fd0b74Schristos template<bool big_endian>
111175fd0b74Schristos void
endian_write_to_buffer(uint64_t val,unsigned char * buf)111275fd0b74Schristos Output_data_expression::endian_write_to_buffer(uint64_t val,
111375fd0b74Schristos unsigned char* buf)
111475fd0b74Schristos {
111575fd0b74Schristos switch (this->data_size())
111675fd0b74Schristos {
111775fd0b74Schristos case 1:
111875fd0b74Schristos elfcpp::Swap_unaligned<8, big_endian>::writeval(buf, val);
111975fd0b74Schristos break;
112075fd0b74Schristos case 2:
112175fd0b74Schristos elfcpp::Swap_unaligned<16, big_endian>::writeval(buf, val);
112275fd0b74Schristos break;
112375fd0b74Schristos case 4:
112475fd0b74Schristos elfcpp::Swap_unaligned<32, big_endian>::writeval(buf, val);
112575fd0b74Schristos break;
112675fd0b74Schristos case 8:
112775fd0b74Schristos if (parameters->target().get_size() == 32)
112875fd0b74Schristos {
112975fd0b74Schristos val &= 0xffffffff;
113075fd0b74Schristos if (this->is_signed_ && (val & 0x80000000) != 0)
113175fd0b74Schristos val |= 0xffffffff00000000LL;
113275fd0b74Schristos }
113375fd0b74Schristos elfcpp::Swap_unaligned<64, big_endian>::writeval(buf, val);
113475fd0b74Schristos break;
113575fd0b74Schristos default:
113675fd0b74Schristos gold_unreachable();
113775fd0b74Schristos }
113875fd0b74Schristos }
113975fd0b74Schristos
114075fd0b74Schristos // A data item in an output section.
114175fd0b74Schristos
114275fd0b74Schristos class Output_section_element_data : public Output_section_element
114375fd0b74Schristos {
114475fd0b74Schristos public:
Output_section_element_data(int size,bool is_signed,Expression * val)114575fd0b74Schristos Output_section_element_data(int size, bool is_signed, Expression* val)
114675fd0b74Schristos : size_(size), is_signed_(is_signed), val_(val)
114775fd0b74Schristos { }
114875fd0b74Schristos
114975fd0b74Schristos // If there is a data item, then we must create an output section.
115075fd0b74Schristos bool
needs_output_section() const115175fd0b74Schristos needs_output_section() const
115275fd0b74Schristos { return true; }
115375fd0b74Schristos
115475fd0b74Schristos // Finalize symbols--we just need to update dot.
115575fd0b74Schristos void
finalize_symbols(Symbol_table *,const Layout *,uint64_t * dot_value,Output_section **)115675fd0b74Schristos finalize_symbols(Symbol_table*, const Layout*, uint64_t* dot_value,
115775fd0b74Schristos Output_section**)
115875fd0b74Schristos { *dot_value += this->size_; }
115975fd0b74Schristos
116075fd0b74Schristos // Store the value in the section.
116175fd0b74Schristos void
116275fd0b74Schristos set_section_addresses(Symbol_table*, Layout*, Output_section*, uint64_t,
116375fd0b74Schristos uint64_t* dot_value, uint64_t*, Output_section**,
116475fd0b74Schristos std::string*, Input_section_list*);
116575fd0b74Schristos
116675fd0b74Schristos // Print for debugging.
116775fd0b74Schristos void
116875fd0b74Schristos print(FILE*) const;
116975fd0b74Schristos
117075fd0b74Schristos private:
117175fd0b74Schristos // The size in bytes.
117275fd0b74Schristos int size_;
117375fd0b74Schristos // Whether the value is signed.
117475fd0b74Schristos bool is_signed_;
117575fd0b74Schristos // The value.
117675fd0b74Schristos Expression* val_;
117775fd0b74Schristos };
117875fd0b74Schristos
117975fd0b74Schristos // Store the value in the section.
118075fd0b74Schristos
118175fd0b74Schristos void
set_section_addresses(Symbol_table * symtab,Layout * layout,Output_section * os,uint64_t,uint64_t * dot_value,uint64_t *,Output_section ** dot_section,std::string *,Input_section_list *)118275fd0b74Schristos Output_section_element_data::set_section_addresses(
118375fd0b74Schristos Symbol_table* symtab,
118475fd0b74Schristos Layout* layout,
118575fd0b74Schristos Output_section* os,
118675fd0b74Schristos uint64_t,
118775fd0b74Schristos uint64_t* dot_value,
118875fd0b74Schristos uint64_t*,
118975fd0b74Schristos Output_section** dot_section,
119075fd0b74Schristos std::string*,
119175fd0b74Schristos Input_section_list*)
119275fd0b74Schristos {
119375fd0b74Schristos gold_assert(os != NULL);
119475fd0b74Schristos Output_data_expression* expression =
119575fd0b74Schristos new Output_data_expression(this->size_, this->is_signed_, this->val_,
119675fd0b74Schristos symtab, layout, *dot_value, *dot_section);
119775fd0b74Schristos os->add_output_section_data(expression);
119875fd0b74Schristos layout->new_output_section_data_from_script(expression);
119975fd0b74Schristos *dot_value += this->size_;
120075fd0b74Schristos }
120175fd0b74Schristos
120275fd0b74Schristos // Print for debugging.
120375fd0b74Schristos
120475fd0b74Schristos void
print(FILE * f) const120575fd0b74Schristos Output_section_element_data::print(FILE* f) const
120675fd0b74Schristos {
120775fd0b74Schristos const char* s;
120875fd0b74Schristos switch (this->size_)
120975fd0b74Schristos {
121075fd0b74Schristos case 1:
121175fd0b74Schristos s = "BYTE";
121275fd0b74Schristos break;
121375fd0b74Schristos case 2:
121475fd0b74Schristos s = "SHORT";
121575fd0b74Schristos break;
121675fd0b74Schristos case 4:
121775fd0b74Schristos s = "LONG";
121875fd0b74Schristos break;
121975fd0b74Schristos case 8:
122075fd0b74Schristos if (this->is_signed_)
122175fd0b74Schristos s = "SQUAD";
122275fd0b74Schristos else
122375fd0b74Schristos s = "QUAD";
122475fd0b74Schristos break;
122575fd0b74Schristos default:
122675fd0b74Schristos gold_unreachable();
122775fd0b74Schristos }
122875fd0b74Schristos fprintf(f, " %s(", s);
122975fd0b74Schristos this->val_->print(f);
123075fd0b74Schristos fprintf(f, ")\n");
123175fd0b74Schristos }
123275fd0b74Schristos
123375fd0b74Schristos // A fill value setting in an output section.
123475fd0b74Schristos
123575fd0b74Schristos class Output_section_element_fill : public Output_section_element
123675fd0b74Schristos {
123775fd0b74Schristos public:
Output_section_element_fill(Expression * val)123875fd0b74Schristos Output_section_element_fill(Expression* val)
123975fd0b74Schristos : val_(val)
124075fd0b74Schristos { }
124175fd0b74Schristos
124275fd0b74Schristos // Update the fill value while setting section addresses.
124375fd0b74Schristos void
set_section_addresses(Symbol_table * symtab,Layout * layout,Output_section *,uint64_t,uint64_t * dot_value,uint64_t *,Output_section ** dot_section,std::string * fill,Input_section_list *)124475fd0b74Schristos set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*,
124575fd0b74Schristos uint64_t, uint64_t* dot_value, uint64_t*,
124675fd0b74Schristos Output_section** dot_section,
124775fd0b74Schristos std::string* fill, Input_section_list*)
124875fd0b74Schristos {
124975fd0b74Schristos Output_section* fill_section;
125075fd0b74Schristos uint64_t fill_val = this->val_->eval_with_dot(symtab, layout, false,
125175fd0b74Schristos *dot_value, *dot_section,
125275fd0b74Schristos &fill_section, NULL, false);
125375fd0b74Schristos if (fill_section != NULL)
125475fd0b74Schristos gold_warning(_("fill value is not absolute"));
125575fd0b74Schristos // FIXME: The GNU linker supports fill values of arbitrary length.
125675fd0b74Schristos unsigned char fill_buff[4];
125775fd0b74Schristos elfcpp::Swap_unaligned<32, true>::writeval(fill_buff, fill_val);
125875fd0b74Schristos fill->assign(reinterpret_cast<char*>(fill_buff), 4);
125975fd0b74Schristos }
126075fd0b74Schristos
126175fd0b74Schristos // Print for debugging.
126275fd0b74Schristos void
print(FILE * f) const126375fd0b74Schristos print(FILE* f) const
126475fd0b74Schristos {
126575fd0b74Schristos fprintf(f, " FILL(");
126675fd0b74Schristos this->val_->print(f);
126775fd0b74Schristos fprintf(f, ")\n");
126875fd0b74Schristos }
126975fd0b74Schristos
127075fd0b74Schristos private:
127175fd0b74Schristos // The new fill value.
127275fd0b74Schristos Expression* val_;
127375fd0b74Schristos };
127475fd0b74Schristos
127575fd0b74Schristos // An input section specification in an output section
127675fd0b74Schristos
127775fd0b74Schristos class Output_section_element_input : public Output_section_element
127875fd0b74Schristos {
127975fd0b74Schristos public:
128075fd0b74Schristos Output_section_element_input(const Input_section_spec* spec, bool keep);
128175fd0b74Schristos
128275fd0b74Schristos // Finalize symbols--just update the value of the dot symbol.
128375fd0b74Schristos void
finalize_symbols(Symbol_table *,const Layout *,uint64_t * dot_value,Output_section ** dot_section)128475fd0b74Schristos finalize_symbols(Symbol_table*, const Layout*, uint64_t* dot_value,
128575fd0b74Schristos Output_section** dot_section)
128675fd0b74Schristos {
128775fd0b74Schristos *dot_value = this->final_dot_value_;
128875fd0b74Schristos *dot_section = this->final_dot_section_;
128975fd0b74Schristos }
129075fd0b74Schristos
129175fd0b74Schristos // See whether we match FILE_NAME and SECTION_NAME as an input section.
129275fd0b74Schristos // If we do then also indicate whether the section should be KEPT.
129375fd0b74Schristos bool
129475fd0b74Schristos match_name(const char* file_name, const char* section_name, bool* keep) const;
129575fd0b74Schristos
129675fd0b74Schristos // Set the section address.
129775fd0b74Schristos void
129875fd0b74Schristos set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*,
129975fd0b74Schristos uint64_t subalign, uint64_t* dot_value, uint64_t*,
130075fd0b74Schristos Output_section**, std::string* fill,
130175fd0b74Schristos Input_section_list*);
130275fd0b74Schristos
130375fd0b74Schristos // Print for debugging.
130475fd0b74Schristos void
130575fd0b74Schristos print(FILE* f) const;
130675fd0b74Schristos
130775fd0b74Schristos private:
130875fd0b74Schristos // An input section pattern.
130975fd0b74Schristos struct Input_section_pattern
131075fd0b74Schristos {
131175fd0b74Schristos std::string pattern;
131275fd0b74Schristos bool pattern_is_wildcard;
131375fd0b74Schristos Sort_wildcard sort;
131475fd0b74Schristos
Input_section_patterngold::Output_section_element_input::Input_section_pattern131575fd0b74Schristos Input_section_pattern(const char* patterna, size_t patternlena,
131675fd0b74Schristos Sort_wildcard sorta)
131775fd0b74Schristos : pattern(patterna, patternlena),
131875fd0b74Schristos pattern_is_wildcard(is_wildcard_string(this->pattern.c_str())),
131975fd0b74Schristos sort(sorta)
132075fd0b74Schristos { }
132175fd0b74Schristos };
132275fd0b74Schristos
132375fd0b74Schristos typedef std::vector<Input_section_pattern> Input_section_patterns;
132475fd0b74Schristos
132575fd0b74Schristos // Filename_exclusions is a pair of filename pattern and a bool
132675fd0b74Schristos // indicating whether the filename is a wildcard.
132775fd0b74Schristos typedef std::vector<std::pair<std::string, bool> > Filename_exclusions;
132875fd0b74Schristos
132975fd0b74Schristos // Return whether STRING matches PATTERN, where IS_WILDCARD_PATTERN
133075fd0b74Schristos // indicates whether this is a wildcard pattern.
133175fd0b74Schristos static inline bool
match(const char * string,const char * pattern,bool is_wildcard_pattern)133275fd0b74Schristos match(const char* string, const char* pattern, bool is_wildcard_pattern)
133375fd0b74Schristos {
133475fd0b74Schristos return (is_wildcard_pattern
133575fd0b74Schristos ? fnmatch(pattern, string, 0) == 0
133675fd0b74Schristos : strcmp(string, pattern) == 0);
133775fd0b74Schristos }
133875fd0b74Schristos
133975fd0b74Schristos // See if we match a file name.
134075fd0b74Schristos bool
134175fd0b74Schristos match_file_name(const char* file_name) const;
134275fd0b74Schristos
134375fd0b74Schristos // The file name pattern. If this is the empty string, we match all
134475fd0b74Schristos // files.
134575fd0b74Schristos std::string filename_pattern_;
134675fd0b74Schristos // Whether the file name pattern is a wildcard.
134775fd0b74Schristos bool filename_is_wildcard_;
134875fd0b74Schristos // How the file names should be sorted. This may only be
134975fd0b74Schristos // SORT_WILDCARD_NONE or SORT_WILDCARD_BY_NAME.
135075fd0b74Schristos Sort_wildcard filename_sort_;
135175fd0b74Schristos // The list of file names to exclude.
135275fd0b74Schristos Filename_exclusions filename_exclusions_;
135375fd0b74Schristos // The list of input section patterns.
135475fd0b74Schristos Input_section_patterns input_section_patterns_;
135575fd0b74Schristos // Whether to keep this section when garbage collecting.
135675fd0b74Schristos bool keep_;
135775fd0b74Schristos // The value of dot after including all matching sections.
135875fd0b74Schristos uint64_t final_dot_value_;
135975fd0b74Schristos // The section where dot is defined after including all matching
136075fd0b74Schristos // sections.
136175fd0b74Schristos Output_section* final_dot_section_;
136275fd0b74Schristos };
136375fd0b74Schristos
136475fd0b74Schristos // Construct Output_section_element_input. The parser records strings
136575fd0b74Schristos // as pointers into a copy of the script file, which will go away when
136675fd0b74Schristos // parsing is complete. We make sure they are in std::string objects.
136775fd0b74Schristos
Output_section_element_input(const Input_section_spec * spec,bool keep)136875fd0b74Schristos Output_section_element_input::Output_section_element_input(
136975fd0b74Schristos const Input_section_spec* spec,
137075fd0b74Schristos bool keep)
137175fd0b74Schristos : filename_pattern_(),
137275fd0b74Schristos filename_is_wildcard_(false),
137375fd0b74Schristos filename_sort_(spec->file.sort),
137475fd0b74Schristos filename_exclusions_(),
137575fd0b74Schristos input_section_patterns_(),
137675fd0b74Schristos keep_(keep),
137775fd0b74Schristos final_dot_value_(0),
137875fd0b74Schristos final_dot_section_(NULL)
137975fd0b74Schristos {
138075fd0b74Schristos // The filename pattern "*" is common, and matches all files. Turn
138175fd0b74Schristos // it into the empty string.
138275fd0b74Schristos if (spec->file.name.length != 1 || spec->file.name.value[0] != '*')
138375fd0b74Schristos this->filename_pattern_.assign(spec->file.name.value,
138475fd0b74Schristos spec->file.name.length);
138575fd0b74Schristos this->filename_is_wildcard_ = is_wildcard_string(this->filename_pattern_.c_str());
138675fd0b74Schristos
138775fd0b74Schristos if (spec->input_sections.exclude != NULL)
138875fd0b74Schristos {
138975fd0b74Schristos for (String_list::const_iterator p =
139075fd0b74Schristos spec->input_sections.exclude->begin();
139175fd0b74Schristos p != spec->input_sections.exclude->end();
139275fd0b74Schristos ++p)
139375fd0b74Schristos {
139475fd0b74Schristos bool is_wildcard = is_wildcard_string((*p).c_str());
139575fd0b74Schristos this->filename_exclusions_.push_back(std::make_pair(*p,
139675fd0b74Schristos is_wildcard));
139775fd0b74Schristos }
139875fd0b74Schristos }
139975fd0b74Schristos
140075fd0b74Schristos if (spec->input_sections.sections != NULL)
140175fd0b74Schristos {
140275fd0b74Schristos Input_section_patterns& isp(this->input_section_patterns_);
140375fd0b74Schristos for (String_sort_list::const_iterator p =
140475fd0b74Schristos spec->input_sections.sections->begin();
140575fd0b74Schristos p != spec->input_sections.sections->end();
140675fd0b74Schristos ++p)
140775fd0b74Schristos isp.push_back(Input_section_pattern(p->name.value, p->name.length,
140875fd0b74Schristos p->sort));
140975fd0b74Schristos }
141075fd0b74Schristos }
141175fd0b74Schristos
141275fd0b74Schristos // See whether we match FILE_NAME.
141375fd0b74Schristos
141475fd0b74Schristos bool
match_file_name(const char * file_name) const141575fd0b74Schristos Output_section_element_input::match_file_name(const char* file_name) const
141675fd0b74Schristos {
141775fd0b74Schristos if (!this->filename_pattern_.empty())
141875fd0b74Schristos {
141975fd0b74Schristos // If we were called with no filename, we refuse to match a
142075fd0b74Schristos // pattern which requires a file name.
142175fd0b74Schristos if (file_name == NULL)
142275fd0b74Schristos return false;
142375fd0b74Schristos
142475fd0b74Schristos if (!match(file_name, this->filename_pattern_.c_str(),
142575fd0b74Schristos this->filename_is_wildcard_))
142675fd0b74Schristos return false;
142775fd0b74Schristos }
142875fd0b74Schristos
142975fd0b74Schristos if (file_name != NULL)
143075fd0b74Schristos {
143175fd0b74Schristos // Now we have to see whether FILE_NAME matches one of the
143275fd0b74Schristos // exclusion patterns, if any.
143375fd0b74Schristos for (Filename_exclusions::const_iterator p =
143475fd0b74Schristos this->filename_exclusions_.begin();
143575fd0b74Schristos p != this->filename_exclusions_.end();
143675fd0b74Schristos ++p)
143775fd0b74Schristos {
143875fd0b74Schristos if (match(file_name, p->first.c_str(), p->second))
143975fd0b74Schristos return false;
144075fd0b74Schristos }
144175fd0b74Schristos }
144275fd0b74Schristos
144375fd0b74Schristos return true;
144475fd0b74Schristos }
144575fd0b74Schristos
144675fd0b74Schristos // See whether we match FILE_NAME and SECTION_NAME. If we do then
144775fd0b74Schristos // KEEP indicates whether the section should survive garbage collection.
144875fd0b74Schristos
144975fd0b74Schristos bool
match_name(const char * file_name,const char * section_name,bool * keep) const145075fd0b74Schristos Output_section_element_input::match_name(const char* file_name,
145175fd0b74Schristos const char* section_name,
145275fd0b74Schristos bool *keep) const
145375fd0b74Schristos {
145475fd0b74Schristos if (!this->match_file_name(file_name))
145575fd0b74Schristos return false;
145675fd0b74Schristos
145775fd0b74Schristos *keep = this->keep_;
145875fd0b74Schristos
145975fd0b74Schristos // If there are no section name patterns, then we match.
146075fd0b74Schristos if (this->input_section_patterns_.empty())
146175fd0b74Schristos return true;
146275fd0b74Schristos
146375fd0b74Schristos // See whether we match the section name patterns.
146475fd0b74Schristos for (Input_section_patterns::const_iterator p =
146575fd0b74Schristos this->input_section_patterns_.begin();
146675fd0b74Schristos p != this->input_section_patterns_.end();
146775fd0b74Schristos ++p)
146875fd0b74Schristos {
146975fd0b74Schristos if (match(section_name, p->pattern.c_str(), p->pattern_is_wildcard))
147075fd0b74Schristos return true;
147175fd0b74Schristos }
147275fd0b74Schristos
147375fd0b74Schristos // We didn't match any section names, so we didn't match.
147475fd0b74Schristos return false;
147575fd0b74Schristos }
147675fd0b74Schristos
147775fd0b74Schristos // Information we use to sort the input sections.
147875fd0b74Schristos
147975fd0b74Schristos class Input_section_info
148075fd0b74Schristos {
148175fd0b74Schristos public:
Input_section_info(const Output_section::Input_section & input_section)148275fd0b74Schristos Input_section_info(const Output_section::Input_section& input_section)
148375fd0b74Schristos : input_section_(input_section), section_name_(),
148475fd0b74Schristos size_(0), addralign_(1)
148575fd0b74Schristos { }
148675fd0b74Schristos
148775fd0b74Schristos // Return the simple input section.
148875fd0b74Schristos const Output_section::Input_section&
input_section() const148975fd0b74Schristos input_section() const
149075fd0b74Schristos { return this->input_section_; }
149175fd0b74Schristos
149275fd0b74Schristos // Return the object.
149375fd0b74Schristos Relobj*
relobj() const149475fd0b74Schristos relobj() const
149575fd0b74Schristos { return this->input_section_.relobj(); }
149675fd0b74Schristos
149775fd0b74Schristos // Return the section index.
149875fd0b74Schristos unsigned int
shndx()149975fd0b74Schristos shndx()
150075fd0b74Schristos { return this->input_section_.shndx(); }
150175fd0b74Schristos
150275fd0b74Schristos // Return the section name.
150375fd0b74Schristos const std::string&
section_name() const150475fd0b74Schristos section_name() const
150575fd0b74Schristos { return this->section_name_; }
150675fd0b74Schristos
150775fd0b74Schristos // Set the section name.
150875fd0b74Schristos void
set_section_name(const std::string name)150975fd0b74Schristos set_section_name(const std::string name)
151075fd0b74Schristos {
151175fd0b74Schristos if (is_compressed_debug_section(name.c_str()))
151275fd0b74Schristos this->section_name_ = corresponding_uncompressed_section_name(name);
151375fd0b74Schristos else
151475fd0b74Schristos this->section_name_ = name;
151575fd0b74Schristos }
151675fd0b74Schristos
151775fd0b74Schristos // Return the section size.
151875fd0b74Schristos uint64_t
size() const151975fd0b74Schristos size() const
152075fd0b74Schristos { return this->size_; }
152175fd0b74Schristos
152275fd0b74Schristos // Set the section size.
152375fd0b74Schristos void
set_size(uint64_t size)152475fd0b74Schristos set_size(uint64_t size)
152575fd0b74Schristos { this->size_ = size; }
152675fd0b74Schristos
152775fd0b74Schristos // Return the address alignment.
152875fd0b74Schristos uint64_t
addralign() const152975fd0b74Schristos addralign() const
153075fd0b74Schristos { return this->addralign_; }
153175fd0b74Schristos
153275fd0b74Schristos // Set the address alignment.
153375fd0b74Schristos void
set_addralign(uint64_t addralign)153475fd0b74Schristos set_addralign(uint64_t addralign)
153575fd0b74Schristos { this->addralign_ = addralign; }
153675fd0b74Schristos
153775fd0b74Schristos private:
153875fd0b74Schristos // Input section, can be a relaxed section.
153975fd0b74Schristos Output_section::Input_section input_section_;
154075fd0b74Schristos // Name of the section.
154175fd0b74Schristos std::string section_name_;
154275fd0b74Schristos // Section size.
154375fd0b74Schristos uint64_t size_;
154475fd0b74Schristos // Address alignment.
154575fd0b74Schristos uint64_t addralign_;
154675fd0b74Schristos };
154775fd0b74Schristos
154875fd0b74Schristos // A class to sort the input sections.
154975fd0b74Schristos
155075fd0b74Schristos class Input_section_sorter
155175fd0b74Schristos {
155275fd0b74Schristos public:
Input_section_sorter(Sort_wildcard filename_sort,Sort_wildcard section_sort)155375fd0b74Schristos Input_section_sorter(Sort_wildcard filename_sort, Sort_wildcard section_sort)
155475fd0b74Schristos : filename_sort_(filename_sort), section_sort_(section_sort)
155575fd0b74Schristos { }
155675fd0b74Schristos
155775fd0b74Schristos bool
155875fd0b74Schristos operator()(const Input_section_info&, const Input_section_info&) const;
155975fd0b74Schristos
156075fd0b74Schristos private:
156175fd0b74Schristos static unsigned long
156275fd0b74Schristos get_init_priority(const char*);
156375fd0b74Schristos
156475fd0b74Schristos Sort_wildcard filename_sort_;
156575fd0b74Schristos Sort_wildcard section_sort_;
156675fd0b74Schristos };
156775fd0b74Schristos
156875fd0b74Schristos // Return a relative priority of the section with the specified NAME
156975fd0b74Schristos // (a lower value meand a higher priority), or 0 if it should be compared
157075fd0b74Schristos // with others as strings.
157175fd0b74Schristos // The implementation of this function is copied from ld/ldlang.c.
157275fd0b74Schristos
157375fd0b74Schristos unsigned long
get_init_priority(const char * name)157475fd0b74Schristos Input_section_sorter::get_init_priority(const char* name)
157575fd0b74Schristos {
157675fd0b74Schristos char* end;
157775fd0b74Schristos unsigned long init_priority;
157875fd0b74Schristos
157975fd0b74Schristos // GCC uses the following section names for the init_priority
158075fd0b74Schristos // attribute with numerical values 101 and 65535 inclusive. A
158175fd0b74Schristos // lower value means a higher priority.
158275fd0b74Schristos //
158375fd0b74Schristos // 1: .init_array.NNNN/.fini_array.NNNN: Where NNNN is the
158475fd0b74Schristos // decimal numerical value of the init_priority attribute.
158575fd0b74Schristos // The order of execution in .init_array is forward and
158675fd0b74Schristos // .fini_array is backward.
158775fd0b74Schristos // 2: .ctors.NNNN/.dtors.NNNN: Where NNNN is 65535 minus the
158875fd0b74Schristos // decimal numerical value of the init_priority attribute.
158975fd0b74Schristos // The order of execution in .ctors is backward and .dtors
159075fd0b74Schristos // is forward.
159175fd0b74Schristos
159275fd0b74Schristos if (strncmp(name, ".init_array.", 12) == 0
159375fd0b74Schristos || strncmp(name, ".fini_array.", 12) == 0)
159475fd0b74Schristos {
159575fd0b74Schristos init_priority = strtoul(name + 12, &end, 10);
159675fd0b74Schristos return *end ? 0 : init_priority;
159775fd0b74Schristos }
159875fd0b74Schristos else if (strncmp(name, ".ctors.", 7) == 0
159975fd0b74Schristos || strncmp(name, ".dtors.", 7) == 0)
160075fd0b74Schristos {
160175fd0b74Schristos init_priority = strtoul(name + 7, &end, 10);
160275fd0b74Schristos return *end ? 0 : 65535 - init_priority;
160375fd0b74Schristos }
160475fd0b74Schristos
160575fd0b74Schristos return 0;
160675fd0b74Schristos }
160775fd0b74Schristos
160875fd0b74Schristos bool
operator ()(const Input_section_info & isi1,const Input_section_info & isi2) const160975fd0b74Schristos Input_section_sorter::operator()(const Input_section_info& isi1,
161075fd0b74Schristos const Input_section_info& isi2) const
161175fd0b74Schristos {
161275fd0b74Schristos if (this->section_sort_ == SORT_WILDCARD_BY_INIT_PRIORITY)
161375fd0b74Schristos {
161475fd0b74Schristos unsigned long ip1 = get_init_priority(isi1.section_name().c_str());
161575fd0b74Schristos unsigned long ip2 = get_init_priority(isi2.section_name().c_str());
161675fd0b74Schristos if (ip1 != 0 && ip2 != 0 && ip1 != ip2)
161775fd0b74Schristos return ip1 < ip2;
161875fd0b74Schristos }
161975fd0b74Schristos if (this->section_sort_ == SORT_WILDCARD_BY_NAME
162075fd0b74Schristos || this->section_sort_ == SORT_WILDCARD_BY_NAME_BY_ALIGNMENT
162175fd0b74Schristos || (this->section_sort_ == SORT_WILDCARD_BY_ALIGNMENT_BY_NAME
162275fd0b74Schristos && isi1.addralign() == isi2.addralign())
162375fd0b74Schristos || this->section_sort_ == SORT_WILDCARD_BY_INIT_PRIORITY)
162475fd0b74Schristos {
162575fd0b74Schristos if (isi1.section_name() != isi2.section_name())
162675fd0b74Schristos return isi1.section_name() < isi2.section_name();
162775fd0b74Schristos }
162875fd0b74Schristos if (this->section_sort_ == SORT_WILDCARD_BY_ALIGNMENT
162975fd0b74Schristos || this->section_sort_ == SORT_WILDCARD_BY_NAME_BY_ALIGNMENT
163075fd0b74Schristos || this->section_sort_ == SORT_WILDCARD_BY_ALIGNMENT_BY_NAME)
163175fd0b74Schristos {
163275fd0b74Schristos if (isi1.addralign() != isi2.addralign())
163375fd0b74Schristos return isi1.addralign() < isi2.addralign();
163475fd0b74Schristos }
163575fd0b74Schristos if (this->filename_sort_ == SORT_WILDCARD_BY_NAME)
163675fd0b74Schristos {
163775fd0b74Schristos if (isi1.relobj()->name() != isi2.relobj()->name())
163875fd0b74Schristos return (isi1.relobj()->name() < isi2.relobj()->name());
163975fd0b74Schristos }
164075fd0b74Schristos
164175fd0b74Schristos // Otherwise we leave them in the same order.
164275fd0b74Schristos return false;
164375fd0b74Schristos }
164475fd0b74Schristos
164575fd0b74Schristos // Set the section address. Look in INPUT_SECTIONS for sections which
164675fd0b74Schristos // match this spec, sort them as specified, and add them to the output
164775fd0b74Schristos // section.
164875fd0b74Schristos
164975fd0b74Schristos void
set_section_addresses(Symbol_table *,Layout * layout,Output_section * output_section,uint64_t subalign,uint64_t * dot_value,uint64_t *,Output_section ** dot_section,std::string * fill,Input_section_list * input_sections)165075fd0b74Schristos Output_section_element_input::set_section_addresses(
165175fd0b74Schristos Symbol_table*,
165275fd0b74Schristos Layout* layout,
165375fd0b74Schristos Output_section* output_section,
165475fd0b74Schristos uint64_t subalign,
165575fd0b74Schristos uint64_t* dot_value,
165675fd0b74Schristos uint64_t*,
165775fd0b74Schristos Output_section** dot_section,
165875fd0b74Schristos std::string* fill,
165975fd0b74Schristos Input_section_list* input_sections)
166075fd0b74Schristos {
166175fd0b74Schristos // We build a list of sections which match each
166275fd0b74Schristos // Input_section_pattern.
166375fd0b74Schristos
166475fd0b74Schristos // If none of the patterns specify a sort option, we throw all
166575fd0b74Schristos // matching input sections into a single bin, in the order we
166675fd0b74Schristos // find them. Otherwise, we put matching input sections into
166775fd0b74Schristos // a separate bin for each pattern, and sort each one as
166875fd0b74Schristos // specified. Thus, an input section spec like this:
166975fd0b74Schristos // *(.foo .bar)
167075fd0b74Schristos // will group all .foo and .bar sections in the order seen,
167175fd0b74Schristos // whereas this:
167275fd0b74Schristos // *(.foo) *(.bar)
167375fd0b74Schristos // will group all .foo sections followed by all .bar sections.
167475fd0b74Schristos // This matches Gnu ld behavior.
167575fd0b74Schristos
167675fd0b74Schristos // Things get really weird, though, when you add a sort spec
167775fd0b74Schristos // on some, but not all, of the patterns, like this:
167875fd0b74Schristos // *(SORT_BY_NAME(.foo) .bar)
167975fd0b74Schristos // We do not attempt to match Gnu ld behavior in this case.
168075fd0b74Schristos
168175fd0b74Schristos typedef std::vector<std::vector<Input_section_info> > Matching_sections;
168275fd0b74Schristos size_t input_pattern_count = this->input_section_patterns_.size();
168375fd0b74Schristos size_t bin_count = 1;
168475fd0b74Schristos bool any_patterns_with_sort = false;
168575fd0b74Schristos for (size_t i = 0; i < input_pattern_count; ++i)
168675fd0b74Schristos {
168775fd0b74Schristos const Input_section_pattern& isp(this->input_section_patterns_[i]);
168875fd0b74Schristos if (isp.sort != SORT_WILDCARD_NONE)
168975fd0b74Schristos any_patterns_with_sort = true;
169075fd0b74Schristos }
169175fd0b74Schristos if (any_patterns_with_sort)
169275fd0b74Schristos bin_count = input_pattern_count;
169375fd0b74Schristos Matching_sections matching_sections(bin_count);
169475fd0b74Schristos
169575fd0b74Schristos // Look through the list of sections for this output section. Add
169675fd0b74Schristos // each one which matches to one of the elements of
169775fd0b74Schristos // MATCHING_SECTIONS.
169875fd0b74Schristos
169975fd0b74Schristos Input_section_list::iterator p = input_sections->begin();
170075fd0b74Schristos while (p != input_sections->end())
170175fd0b74Schristos {
170275fd0b74Schristos Relobj* relobj = p->relobj();
170375fd0b74Schristos unsigned int shndx = p->shndx();
170475fd0b74Schristos Input_section_info isi(*p);
170575fd0b74Schristos
170675fd0b74Schristos // Calling section_name and section_addralign is not very
170775fd0b74Schristos // efficient.
170875fd0b74Schristos
170975fd0b74Schristos // Lock the object so that we can get information about the
171075fd0b74Schristos // section. This is OK since we know we are single-threaded
171175fd0b74Schristos // here.
171275fd0b74Schristos {
171375fd0b74Schristos const Task* task = reinterpret_cast<const Task*>(-1);
171475fd0b74Schristos Task_lock_obj<Object> tl(task, relobj);
171575fd0b74Schristos
171675fd0b74Schristos isi.set_section_name(relobj->section_name(shndx));
171775fd0b74Schristos if (p->is_relaxed_input_section())
171875fd0b74Schristos {
171975fd0b74Schristos // We use current data size because relaxed section sizes may not
172075fd0b74Schristos // have finalized yet.
172175fd0b74Schristos isi.set_size(p->relaxed_input_section()->current_data_size());
172275fd0b74Schristos isi.set_addralign(p->relaxed_input_section()->addralign());
172375fd0b74Schristos }
172475fd0b74Schristos else
172575fd0b74Schristos {
172675fd0b74Schristos isi.set_size(relobj->section_size(shndx));
172775fd0b74Schristos isi.set_addralign(relobj->section_addralign(shndx));
172875fd0b74Schristos }
172975fd0b74Schristos }
173075fd0b74Schristos
173175fd0b74Schristos if (!this->match_file_name(relobj->name().c_str()))
173275fd0b74Schristos ++p;
173375fd0b74Schristos else if (this->input_section_patterns_.empty())
173475fd0b74Schristos {
173575fd0b74Schristos matching_sections[0].push_back(isi);
173675fd0b74Schristos p = input_sections->erase(p);
173775fd0b74Schristos }
173875fd0b74Schristos else
173975fd0b74Schristos {
174075fd0b74Schristos size_t i;
174175fd0b74Schristos for (i = 0; i < input_pattern_count; ++i)
174275fd0b74Schristos {
174375fd0b74Schristos const Input_section_pattern&
174475fd0b74Schristos isp(this->input_section_patterns_[i]);
174575fd0b74Schristos if (match(isi.section_name().c_str(), isp.pattern.c_str(),
174675fd0b74Schristos isp.pattern_is_wildcard))
174775fd0b74Schristos break;
174875fd0b74Schristos }
174975fd0b74Schristos
175075fd0b74Schristos if (i >= input_pattern_count)
175175fd0b74Schristos ++p;
175275fd0b74Schristos else
175375fd0b74Schristos {
175475fd0b74Schristos if (i >= bin_count)
175575fd0b74Schristos i = 0;
175675fd0b74Schristos matching_sections[i].push_back(isi);
175775fd0b74Schristos p = input_sections->erase(p);
175875fd0b74Schristos }
175975fd0b74Schristos }
176075fd0b74Schristos }
176175fd0b74Schristos
176275fd0b74Schristos // Look through MATCHING_SECTIONS. Sort each one as specified,
176375fd0b74Schristos // using a stable sort so that we get the default order when
176475fd0b74Schristos // sections are otherwise equal. Add each input section to the
176575fd0b74Schristos // output section.
176675fd0b74Schristos
176775fd0b74Schristos uint64_t dot = *dot_value;
176875fd0b74Schristos for (size_t i = 0; i < bin_count; ++i)
176975fd0b74Schristos {
177075fd0b74Schristos if (matching_sections[i].empty())
177175fd0b74Schristos continue;
177275fd0b74Schristos
177375fd0b74Schristos gold_assert(output_section != NULL);
177475fd0b74Schristos
177575fd0b74Schristos const Input_section_pattern& isp(this->input_section_patterns_[i]);
177675fd0b74Schristos if (isp.sort != SORT_WILDCARD_NONE
177775fd0b74Schristos || this->filename_sort_ != SORT_WILDCARD_NONE)
177875fd0b74Schristos std::stable_sort(matching_sections[i].begin(),
177975fd0b74Schristos matching_sections[i].end(),
178075fd0b74Schristos Input_section_sorter(this->filename_sort_,
178175fd0b74Schristos isp.sort));
178275fd0b74Schristos
178375fd0b74Schristos for (std::vector<Input_section_info>::const_iterator p =
178475fd0b74Schristos matching_sections[i].begin();
178575fd0b74Schristos p != matching_sections[i].end();
178675fd0b74Schristos ++p)
178775fd0b74Schristos {
1788ede78133Schristos // Override the original address alignment if SUBALIGN is specified.
1789ede78133Schristos // We need to make a copy of the input section to modify the
1790ede78133Schristos // alignment.
179175fd0b74Schristos Output_section::Input_section sis(p->input_section());
179275fd0b74Schristos
179375fd0b74Schristos uint64_t this_subalign = sis.addralign();
179475fd0b74Schristos if (!sis.is_input_section())
179575fd0b74Schristos sis.output_section_data()->finalize_data_size();
179675fd0b74Schristos uint64_t data_size = sis.data_size();
1797ede78133Schristos if (subalign > 0)
179875fd0b74Schristos {
179975fd0b74Schristos this_subalign = subalign;
180075fd0b74Schristos sis.set_addralign(subalign);
180175fd0b74Schristos }
180275fd0b74Schristos
180375fd0b74Schristos uint64_t address = align_address(dot, this_subalign);
180475fd0b74Schristos
180575fd0b74Schristos if (address > dot && !fill->empty())
180675fd0b74Schristos {
180775fd0b74Schristos section_size_type length =
180875fd0b74Schristos convert_to_section_size_type(address - dot);
180975fd0b74Schristos std::string this_fill = this->get_fill_string(fill, length);
181075fd0b74Schristos Output_section_data* posd = new Output_data_const(this_fill, 0);
181175fd0b74Schristos output_section->add_output_section_data(posd);
181275fd0b74Schristos layout->new_output_section_data_from_script(posd);
181375fd0b74Schristos }
181475fd0b74Schristos
181575fd0b74Schristos output_section->add_script_input_section(sis);
181675fd0b74Schristos dot = address + data_size;
181775fd0b74Schristos }
181875fd0b74Schristos }
181975fd0b74Schristos
182075fd0b74Schristos // An SHF_TLS/SHT_NOBITS section does not take up any
182175fd0b74Schristos // address space.
182275fd0b74Schristos if (output_section == NULL
182375fd0b74Schristos || (output_section->flags() & elfcpp::SHF_TLS) == 0
182475fd0b74Schristos || output_section->type() != elfcpp::SHT_NOBITS)
182575fd0b74Schristos *dot_value = dot;
182675fd0b74Schristos
182775fd0b74Schristos this->final_dot_value_ = *dot_value;
182875fd0b74Schristos this->final_dot_section_ = *dot_section;
182975fd0b74Schristos }
183075fd0b74Schristos
183175fd0b74Schristos // Print for debugging.
183275fd0b74Schristos
183375fd0b74Schristos void
print(FILE * f) const183475fd0b74Schristos Output_section_element_input::print(FILE* f) const
183575fd0b74Schristos {
183675fd0b74Schristos fprintf(f, " ");
183775fd0b74Schristos
183875fd0b74Schristos if (this->keep_)
183975fd0b74Schristos fprintf(f, "KEEP(");
184075fd0b74Schristos
184175fd0b74Schristos if (!this->filename_pattern_.empty())
184275fd0b74Schristos {
184375fd0b74Schristos bool need_close_paren = false;
184475fd0b74Schristos switch (this->filename_sort_)
184575fd0b74Schristos {
184675fd0b74Schristos case SORT_WILDCARD_NONE:
184775fd0b74Schristos break;
184875fd0b74Schristos case SORT_WILDCARD_BY_NAME:
184975fd0b74Schristos fprintf(f, "SORT_BY_NAME(");
185075fd0b74Schristos need_close_paren = true;
185175fd0b74Schristos break;
185275fd0b74Schristos default:
185375fd0b74Schristos gold_unreachable();
185475fd0b74Schristos }
185575fd0b74Schristos
185675fd0b74Schristos fprintf(f, "%s", this->filename_pattern_.c_str());
185775fd0b74Schristos
185875fd0b74Schristos if (need_close_paren)
185975fd0b74Schristos fprintf(f, ")");
186075fd0b74Schristos }
186175fd0b74Schristos
186275fd0b74Schristos if (!this->input_section_patterns_.empty()
186375fd0b74Schristos || !this->filename_exclusions_.empty())
186475fd0b74Schristos {
186575fd0b74Schristos fprintf(f, "(");
186675fd0b74Schristos
186775fd0b74Schristos bool need_space = false;
186875fd0b74Schristos if (!this->filename_exclusions_.empty())
186975fd0b74Schristos {
187075fd0b74Schristos fprintf(f, "EXCLUDE_FILE(");
187175fd0b74Schristos bool need_comma = false;
187275fd0b74Schristos for (Filename_exclusions::const_iterator p =
187375fd0b74Schristos this->filename_exclusions_.begin();
187475fd0b74Schristos p != this->filename_exclusions_.end();
187575fd0b74Schristos ++p)
187675fd0b74Schristos {
187775fd0b74Schristos if (need_comma)
187875fd0b74Schristos fprintf(f, ", ");
187975fd0b74Schristos fprintf(f, "%s", p->first.c_str());
188075fd0b74Schristos need_comma = true;
188175fd0b74Schristos }
188275fd0b74Schristos fprintf(f, ")");
188375fd0b74Schristos need_space = true;
188475fd0b74Schristos }
188575fd0b74Schristos
188675fd0b74Schristos for (Input_section_patterns::const_iterator p =
188775fd0b74Schristos this->input_section_patterns_.begin();
188875fd0b74Schristos p != this->input_section_patterns_.end();
188975fd0b74Schristos ++p)
189075fd0b74Schristos {
189175fd0b74Schristos if (need_space)
189275fd0b74Schristos fprintf(f, " ");
189375fd0b74Schristos
189475fd0b74Schristos int close_parens = 0;
189575fd0b74Schristos switch (p->sort)
189675fd0b74Schristos {
189775fd0b74Schristos case SORT_WILDCARD_NONE:
189875fd0b74Schristos break;
189975fd0b74Schristos case SORT_WILDCARD_BY_NAME:
190075fd0b74Schristos fprintf(f, "SORT_BY_NAME(");
190175fd0b74Schristos close_parens = 1;
190275fd0b74Schristos break;
190375fd0b74Schristos case SORT_WILDCARD_BY_ALIGNMENT:
190475fd0b74Schristos fprintf(f, "SORT_BY_ALIGNMENT(");
190575fd0b74Schristos close_parens = 1;
190675fd0b74Schristos break;
190775fd0b74Schristos case SORT_WILDCARD_BY_NAME_BY_ALIGNMENT:
190875fd0b74Schristos fprintf(f, "SORT_BY_NAME(SORT_BY_ALIGNMENT(");
190975fd0b74Schristos close_parens = 2;
191075fd0b74Schristos break;
191175fd0b74Schristos case SORT_WILDCARD_BY_ALIGNMENT_BY_NAME:
191275fd0b74Schristos fprintf(f, "SORT_BY_ALIGNMENT(SORT_BY_NAME(");
191375fd0b74Schristos close_parens = 2;
191475fd0b74Schristos break;
191575fd0b74Schristos case SORT_WILDCARD_BY_INIT_PRIORITY:
191675fd0b74Schristos fprintf(f, "SORT_BY_INIT_PRIORITY(");
191775fd0b74Schristos close_parens = 1;
191875fd0b74Schristos break;
191975fd0b74Schristos default:
192075fd0b74Schristos gold_unreachable();
192175fd0b74Schristos }
192275fd0b74Schristos
192375fd0b74Schristos fprintf(f, "%s", p->pattern.c_str());
192475fd0b74Schristos
192575fd0b74Schristos for (int i = 0; i < close_parens; ++i)
192675fd0b74Schristos fprintf(f, ")");
192775fd0b74Schristos
192875fd0b74Schristos need_space = true;
192975fd0b74Schristos }
193075fd0b74Schristos
193175fd0b74Schristos fprintf(f, ")");
193275fd0b74Schristos }
193375fd0b74Schristos
193475fd0b74Schristos if (this->keep_)
193575fd0b74Schristos fprintf(f, ")");
193675fd0b74Schristos
193775fd0b74Schristos fprintf(f, "\n");
193875fd0b74Schristos }
193975fd0b74Schristos
194075fd0b74Schristos // An output section.
194175fd0b74Schristos
194275fd0b74Schristos class Output_section_definition : public Sections_element
194375fd0b74Schristos {
194475fd0b74Schristos public:
194575fd0b74Schristos typedef Output_section_element::Input_section_list Input_section_list;
194675fd0b74Schristos
194775fd0b74Schristos Output_section_definition(const char* name, size_t namelen,
194875fd0b74Schristos const Parser_output_section_header* header);
194975fd0b74Schristos
195075fd0b74Schristos // Finish the output section with the information in the trailer.
195175fd0b74Schristos void
195275fd0b74Schristos finish(const Parser_output_section_trailer* trailer);
195375fd0b74Schristos
195475fd0b74Schristos // Add a symbol to be defined.
195575fd0b74Schristos void
195675fd0b74Schristos add_symbol_assignment(const char* name, size_t length, Expression* value,
195775fd0b74Schristos bool provide, bool hidden);
195875fd0b74Schristos
195975fd0b74Schristos // Add an assignment to the special dot symbol.
196075fd0b74Schristos void
196175fd0b74Schristos add_dot_assignment(Expression* value);
196275fd0b74Schristos
196375fd0b74Schristos // Add an assertion.
196475fd0b74Schristos void
196575fd0b74Schristos add_assertion(Expression* check, const char* message, size_t messagelen);
196675fd0b74Schristos
196775fd0b74Schristos // Add a data item to the current output section.
196875fd0b74Schristos void
196975fd0b74Schristos add_data(int size, bool is_signed, Expression* val);
197075fd0b74Schristos
197175fd0b74Schristos // Add a setting for the fill value.
197275fd0b74Schristos void
197375fd0b74Schristos add_fill(Expression* val);
197475fd0b74Schristos
197575fd0b74Schristos // Add an input section specification.
197675fd0b74Schristos void
197775fd0b74Schristos add_input_section(const Input_section_spec* spec, bool keep);
197875fd0b74Schristos
197975fd0b74Schristos // Return whether the output section is relro.
198075fd0b74Schristos bool
is_relro() const198175fd0b74Schristos is_relro() const
198275fd0b74Schristos { return this->is_relro_; }
198375fd0b74Schristos
198475fd0b74Schristos // Record that the output section is relro.
198575fd0b74Schristos void
set_is_relro()198675fd0b74Schristos set_is_relro()
198775fd0b74Schristos { this->is_relro_ = true; }
198875fd0b74Schristos
198975fd0b74Schristos // Create any required output sections.
199075fd0b74Schristos void
199175fd0b74Schristos create_sections(Layout*);
199275fd0b74Schristos
199375fd0b74Schristos // Add any symbols being defined to the symbol table.
199475fd0b74Schristos void
199575fd0b74Schristos add_symbols_to_table(Symbol_table* symtab);
199675fd0b74Schristos
199775fd0b74Schristos // Finalize symbols and check assertions.
199875fd0b74Schristos void
199975fd0b74Schristos finalize_symbols(Symbol_table*, const Layout*, uint64_t*);
200075fd0b74Schristos
200175fd0b74Schristos // Return the output section name to use for an input file name and
200275fd0b74Schristos // section name.
200375fd0b74Schristos const char*
200475fd0b74Schristos output_section_name(const char* file_name, const char* section_name,
200575fd0b74Schristos Output_section***, Script_sections::Section_type*,
2006ede78133Schristos bool*, bool);
200775fd0b74Schristos
200875fd0b74Schristos // Initialize OSP with an output section.
200975fd0b74Schristos void
orphan_section_init(Orphan_section_placement * osp,Script_sections::Elements_iterator p)201075fd0b74Schristos orphan_section_init(Orphan_section_placement* osp,
201175fd0b74Schristos Script_sections::Elements_iterator p)
201275fd0b74Schristos { osp->output_section_init(this->name_, this->output_section_, p); }
201375fd0b74Schristos
201475fd0b74Schristos // Set the section address.
201575fd0b74Schristos void
201675fd0b74Schristos set_section_addresses(Symbol_table* symtab, Layout* layout,
201775fd0b74Schristos uint64_t* dot_value, uint64_t*,
201875fd0b74Schristos uint64_t* load_address);
201975fd0b74Schristos
202075fd0b74Schristos // Check a constraint (ONLY_IF_RO, etc.) on an output section. If
202175fd0b74Schristos // this section is constrained, and the input sections do not match,
202275fd0b74Schristos // return the constraint, and set *POSD.
202375fd0b74Schristos Section_constraint
202475fd0b74Schristos check_constraint(Output_section_definition** posd);
202575fd0b74Schristos
202675fd0b74Schristos // See if this is the alternate output section for a constrained
202775fd0b74Schristos // output section. If it is, transfer the Output_section and return
202875fd0b74Schristos // true. Otherwise return false.
202975fd0b74Schristos bool
203075fd0b74Schristos alternate_constraint(Output_section_definition*, Section_constraint);
203175fd0b74Schristos
203275fd0b74Schristos // Get the list of segments to use for an allocated section when
203375fd0b74Schristos // using a PHDRS clause.
203475fd0b74Schristos Output_section*
203575fd0b74Schristos allocate_to_segment(String_list** phdrs_list, bool* orphan);
203675fd0b74Schristos
203775fd0b74Schristos // Look for an output section by name and return the address, the
203875fd0b74Schristos // load address, the alignment, and the size. This is used when an
203975fd0b74Schristos // expression refers to an output section which was not actually
204075fd0b74Schristos // created. This returns true if the section was found, false
204175fd0b74Schristos // otherwise.
204275fd0b74Schristos bool
204375fd0b74Schristos get_output_section_info(const char*, uint64_t*, uint64_t*, uint64_t*,
204475fd0b74Schristos uint64_t*) const;
204575fd0b74Schristos
204675fd0b74Schristos // Return the associated Output_section if there is one.
204775fd0b74Schristos Output_section*
get_output_section() const204875fd0b74Schristos get_output_section() const
204975fd0b74Schristos { return this->output_section_; }
205075fd0b74Schristos
205175fd0b74Schristos // Print the contents to the FILE. This is for debugging.
205275fd0b74Schristos void
205375fd0b74Schristos print(FILE*) const;
205475fd0b74Schristos
205575fd0b74Schristos // Return the output section type if specified or Script_sections::ST_NONE.
205675fd0b74Schristos Script_sections::Section_type
205775fd0b74Schristos section_type() const;
205875fd0b74Schristos
205975fd0b74Schristos // Store the memory region to use.
206075fd0b74Schristos void
206175fd0b74Schristos set_memory_region(Memory_region*, bool set_vma);
206275fd0b74Schristos
206375fd0b74Schristos void
set_section_vma(Expression * address)206475fd0b74Schristos set_section_vma(Expression* address)
206575fd0b74Schristos { this->address_ = address; }
206675fd0b74Schristos
206775fd0b74Schristos void
set_section_lma(Expression * address)206875fd0b74Schristos set_section_lma(Expression* address)
206975fd0b74Schristos { this->load_address_ = address; }
207075fd0b74Schristos
207175fd0b74Schristos const std::string&
get_section_name() const207275fd0b74Schristos get_section_name() const
207375fd0b74Schristos { return this->name_; }
207475fd0b74Schristos
207575fd0b74Schristos private:
207675fd0b74Schristos static const char*
207775fd0b74Schristos script_section_type_name(Script_section_type);
207875fd0b74Schristos
207975fd0b74Schristos typedef std::vector<Output_section_element*> Output_section_elements;
208075fd0b74Schristos
208175fd0b74Schristos // The output section name.
208275fd0b74Schristos std::string name_;
208375fd0b74Schristos // The address. This may be NULL.
208475fd0b74Schristos Expression* address_;
208575fd0b74Schristos // The load address. This may be NULL.
208675fd0b74Schristos Expression* load_address_;
208775fd0b74Schristos // The alignment. This may be NULL.
208875fd0b74Schristos Expression* align_;
208975fd0b74Schristos // The input section alignment. This may be NULL.
209075fd0b74Schristos Expression* subalign_;
209175fd0b74Schristos // The constraint, if any.
209275fd0b74Schristos Section_constraint constraint_;
209375fd0b74Schristos // The fill value. This may be NULL.
209475fd0b74Schristos Expression* fill_;
209575fd0b74Schristos // The list of segments this section should go into. This may be
209675fd0b74Schristos // NULL.
209775fd0b74Schristos String_list* phdrs_;
209875fd0b74Schristos // The list of elements defining the section.
209975fd0b74Schristos Output_section_elements elements_;
210075fd0b74Schristos // The Output_section created for this definition. This will be
210175fd0b74Schristos // NULL if none was created.
210275fd0b74Schristos Output_section* output_section_;
210375fd0b74Schristos // The address after it has been evaluated.
210475fd0b74Schristos uint64_t evaluated_address_;
210575fd0b74Schristos // The load address after it has been evaluated.
210675fd0b74Schristos uint64_t evaluated_load_address_;
210775fd0b74Schristos // The alignment after it has been evaluated.
210875fd0b74Schristos uint64_t evaluated_addralign_;
210975fd0b74Schristos // The output section is relro.
211075fd0b74Schristos bool is_relro_;
211175fd0b74Schristos // The output section type if specified.
211275fd0b74Schristos enum Script_section_type script_section_type_;
211375fd0b74Schristos };
211475fd0b74Schristos
211575fd0b74Schristos // Constructor.
211675fd0b74Schristos
Output_section_definition(const char * name,size_t namelen,const Parser_output_section_header * header)211775fd0b74Schristos Output_section_definition::Output_section_definition(
211875fd0b74Schristos const char* name,
211975fd0b74Schristos size_t namelen,
212075fd0b74Schristos const Parser_output_section_header* header)
212175fd0b74Schristos : name_(name, namelen),
212275fd0b74Schristos address_(header->address),
212375fd0b74Schristos load_address_(header->load_address),
212475fd0b74Schristos align_(header->align),
212575fd0b74Schristos subalign_(header->subalign),
212675fd0b74Schristos constraint_(header->constraint),
212775fd0b74Schristos fill_(NULL),
212875fd0b74Schristos phdrs_(NULL),
212975fd0b74Schristos elements_(),
213075fd0b74Schristos output_section_(NULL),
213175fd0b74Schristos evaluated_address_(0),
213275fd0b74Schristos evaluated_load_address_(0),
213375fd0b74Schristos evaluated_addralign_(0),
213475fd0b74Schristos is_relro_(false),
213575fd0b74Schristos script_section_type_(header->section_type)
213675fd0b74Schristos {
213775fd0b74Schristos }
213875fd0b74Schristos
213975fd0b74Schristos // Finish an output section.
214075fd0b74Schristos
214175fd0b74Schristos void
finish(const Parser_output_section_trailer * trailer)214275fd0b74Schristos Output_section_definition::finish(const Parser_output_section_trailer* trailer)
214375fd0b74Schristos {
214475fd0b74Schristos this->fill_ = trailer->fill;
214575fd0b74Schristos this->phdrs_ = trailer->phdrs;
214675fd0b74Schristos }
214775fd0b74Schristos
214875fd0b74Schristos // Add a symbol to be defined.
214975fd0b74Schristos
215075fd0b74Schristos void
add_symbol_assignment(const char * name,size_t length,Expression * value,bool provide,bool hidden)215175fd0b74Schristos Output_section_definition::add_symbol_assignment(const char* name,
215275fd0b74Schristos size_t length,
215375fd0b74Schristos Expression* value,
215475fd0b74Schristos bool provide,
215575fd0b74Schristos bool hidden)
215675fd0b74Schristos {
215775fd0b74Schristos Output_section_element* p = new Output_section_element_assignment(name,
215875fd0b74Schristos length,
215975fd0b74Schristos value,
216075fd0b74Schristos provide,
216175fd0b74Schristos hidden);
216275fd0b74Schristos this->elements_.push_back(p);
216375fd0b74Schristos }
216475fd0b74Schristos
216575fd0b74Schristos // Add an assignment to the special dot symbol.
216675fd0b74Schristos
216775fd0b74Schristos void
add_dot_assignment(Expression * value)216875fd0b74Schristos Output_section_definition::add_dot_assignment(Expression* value)
216975fd0b74Schristos {
217075fd0b74Schristos Output_section_element* p = new Output_section_element_dot_assignment(value);
217175fd0b74Schristos this->elements_.push_back(p);
217275fd0b74Schristos }
217375fd0b74Schristos
217475fd0b74Schristos // Add an assertion.
217575fd0b74Schristos
217675fd0b74Schristos void
add_assertion(Expression * check,const char * message,size_t messagelen)217775fd0b74Schristos Output_section_definition::add_assertion(Expression* check,
217875fd0b74Schristos const char* message,
217975fd0b74Schristos size_t messagelen)
218075fd0b74Schristos {
218175fd0b74Schristos Output_section_element* p = new Output_section_element_assertion(check,
218275fd0b74Schristos message,
218375fd0b74Schristos messagelen);
218475fd0b74Schristos this->elements_.push_back(p);
218575fd0b74Schristos }
218675fd0b74Schristos
218775fd0b74Schristos // Add a data item to the current output section.
218875fd0b74Schristos
218975fd0b74Schristos void
add_data(int size,bool is_signed,Expression * val)219075fd0b74Schristos Output_section_definition::add_data(int size, bool is_signed, Expression* val)
219175fd0b74Schristos {
219275fd0b74Schristos Output_section_element* p = new Output_section_element_data(size, is_signed,
219375fd0b74Schristos val);
219475fd0b74Schristos this->elements_.push_back(p);
219575fd0b74Schristos }
219675fd0b74Schristos
219775fd0b74Schristos // Add a setting for the fill value.
219875fd0b74Schristos
219975fd0b74Schristos void
add_fill(Expression * val)220075fd0b74Schristos Output_section_definition::add_fill(Expression* val)
220175fd0b74Schristos {
220275fd0b74Schristos Output_section_element* p = new Output_section_element_fill(val);
220375fd0b74Schristos this->elements_.push_back(p);
220475fd0b74Schristos }
220575fd0b74Schristos
220675fd0b74Schristos // Add an input section specification.
220775fd0b74Schristos
220875fd0b74Schristos void
add_input_section(const Input_section_spec * spec,bool keep)220975fd0b74Schristos Output_section_definition::add_input_section(const Input_section_spec* spec,
221075fd0b74Schristos bool keep)
221175fd0b74Schristos {
221275fd0b74Schristos Output_section_element* p = new Output_section_element_input(spec, keep);
221375fd0b74Schristos this->elements_.push_back(p);
221475fd0b74Schristos }
221575fd0b74Schristos
221675fd0b74Schristos // Create any required output sections. We need an output section if
221775fd0b74Schristos // there is a data statement here.
221875fd0b74Schristos
221975fd0b74Schristos void
create_sections(Layout * layout)222075fd0b74Schristos Output_section_definition::create_sections(Layout* layout)
222175fd0b74Schristos {
222275fd0b74Schristos if (this->output_section_ != NULL)
222375fd0b74Schristos return;
222475fd0b74Schristos for (Output_section_elements::const_iterator p = this->elements_.begin();
222575fd0b74Schristos p != this->elements_.end();
222675fd0b74Schristos ++p)
222775fd0b74Schristos {
222875fd0b74Schristos if ((*p)->needs_output_section())
222975fd0b74Schristos {
223075fd0b74Schristos const char* name = this->name_.c_str();
223175fd0b74Schristos this->output_section_ =
223275fd0b74Schristos layout->make_output_section_for_script(name, this->section_type());
223375fd0b74Schristos return;
223475fd0b74Schristos }
223575fd0b74Schristos }
223675fd0b74Schristos }
223775fd0b74Schristos
223875fd0b74Schristos // Add any symbols being defined to the symbol table.
223975fd0b74Schristos
224075fd0b74Schristos void
add_symbols_to_table(Symbol_table * symtab)224175fd0b74Schristos Output_section_definition::add_symbols_to_table(Symbol_table* symtab)
224275fd0b74Schristos {
224375fd0b74Schristos for (Output_section_elements::iterator p = this->elements_.begin();
224475fd0b74Schristos p != this->elements_.end();
224575fd0b74Schristos ++p)
224675fd0b74Schristos (*p)->add_symbols_to_table(symtab);
224775fd0b74Schristos }
224875fd0b74Schristos
224975fd0b74Schristos // Finalize symbols and check assertions.
225075fd0b74Schristos
225175fd0b74Schristos void
finalize_symbols(Symbol_table * symtab,const Layout * layout,uint64_t * dot_value)225275fd0b74Schristos Output_section_definition::finalize_symbols(Symbol_table* symtab,
225375fd0b74Schristos const Layout* layout,
225475fd0b74Schristos uint64_t* dot_value)
225575fd0b74Schristos {
225675fd0b74Schristos if (this->output_section_ != NULL)
225775fd0b74Schristos *dot_value = this->output_section_->address();
225875fd0b74Schristos else
225975fd0b74Schristos {
226075fd0b74Schristos uint64_t address = *dot_value;
226175fd0b74Schristos if (this->address_ != NULL)
226275fd0b74Schristos {
226375fd0b74Schristos address = this->address_->eval_with_dot(symtab, layout, true,
226475fd0b74Schristos *dot_value, NULL,
226575fd0b74Schristos NULL, NULL, false);
226675fd0b74Schristos }
226775fd0b74Schristos if (this->align_ != NULL)
226875fd0b74Schristos {
226975fd0b74Schristos uint64_t align = this->align_->eval_with_dot(symtab, layout, true,
227075fd0b74Schristos *dot_value, NULL,
227175fd0b74Schristos NULL, NULL, false);
227275fd0b74Schristos address = align_address(address, align);
227375fd0b74Schristos }
227475fd0b74Schristos *dot_value = address;
227575fd0b74Schristos }
227675fd0b74Schristos
227775fd0b74Schristos Output_section* dot_section = this->output_section_;
227875fd0b74Schristos for (Output_section_elements::iterator p = this->elements_.begin();
227975fd0b74Schristos p != this->elements_.end();
228075fd0b74Schristos ++p)
228175fd0b74Schristos (*p)->finalize_symbols(symtab, layout, dot_value, &dot_section);
228275fd0b74Schristos }
228375fd0b74Schristos
228475fd0b74Schristos // Return the output section name to use for an input section name.
228575fd0b74Schristos
228675fd0b74Schristos const char*
output_section_name(const char * file_name,const char * section_name,Output_section *** slot,Script_sections::Section_type * psection_type,bool * keep,bool match_input_spec)228775fd0b74Schristos Output_section_definition::output_section_name(
228875fd0b74Schristos const char* file_name,
228975fd0b74Schristos const char* section_name,
229075fd0b74Schristos Output_section*** slot,
229175fd0b74Schristos Script_sections::Section_type* psection_type,
2292ede78133Schristos bool* keep,
2293ede78133Schristos bool match_input_spec)
229475fd0b74Schristos {
2295ede78133Schristos // If the section is a linker-created output section, just look for a match
2296ede78133Schristos // on the output section name.
2297ede78133Schristos if (!match_input_spec && this->name_ != "/DISCARD/")
2298ede78133Schristos {
2299ede78133Schristos if (this->name_ != section_name)
2300ede78133Schristos return NULL;
2301ede78133Schristos *slot = &this->output_section_;
2302ede78133Schristos *psection_type = this->section_type();
2303ede78133Schristos return this->name_.c_str();
2304ede78133Schristos }
2305ede78133Schristos
230675fd0b74Schristos // Ask each element whether it matches NAME.
230775fd0b74Schristos for (Output_section_elements::const_iterator p = this->elements_.begin();
230875fd0b74Schristos p != this->elements_.end();
230975fd0b74Schristos ++p)
231075fd0b74Schristos {
231175fd0b74Schristos if ((*p)->match_name(file_name, section_name, keep))
231275fd0b74Schristos {
231375fd0b74Schristos // We found a match for NAME, which means that it should go
231475fd0b74Schristos // into this output section.
231575fd0b74Schristos *slot = &this->output_section_;
231675fd0b74Schristos *psection_type = this->section_type();
231775fd0b74Schristos return this->name_.c_str();
231875fd0b74Schristos }
231975fd0b74Schristos }
232075fd0b74Schristos
232175fd0b74Schristos // We don't know about this section name.
232275fd0b74Schristos return NULL;
232375fd0b74Schristos }
232475fd0b74Schristos
232575fd0b74Schristos // Return true if memory from START to START + LENGTH is contained
232675fd0b74Schristos // within a memory region.
232775fd0b74Schristos
232875fd0b74Schristos bool
block_in_region(Symbol_table * symtab,Layout * layout,uint64_t start,uint64_t length) const232975fd0b74Schristos Script_sections::block_in_region(Symbol_table* symtab, Layout* layout,
233075fd0b74Schristos uint64_t start, uint64_t length) const
233175fd0b74Schristos {
233275fd0b74Schristos if (this->memory_regions_ == NULL)
233375fd0b74Schristos return false;
233475fd0b74Schristos
233575fd0b74Schristos for (Memory_regions::const_iterator mr = this->memory_regions_->begin();
233675fd0b74Schristos mr != this->memory_regions_->end();
233775fd0b74Schristos ++mr)
233875fd0b74Schristos {
233975fd0b74Schristos uint64_t s = (*mr)->start_address()->eval(symtab, layout, false);
234075fd0b74Schristos uint64_t l = (*mr)->length()->eval(symtab, layout, false);
234175fd0b74Schristos
234275fd0b74Schristos if (s <= start
234375fd0b74Schristos && (s + l) >= (start + length))
234475fd0b74Schristos return true;
234575fd0b74Schristos }
234675fd0b74Schristos
234775fd0b74Schristos return false;
234875fd0b74Schristos }
234975fd0b74Schristos
235075fd0b74Schristos // Find a memory region that should be used by a given output SECTION.
235175fd0b74Schristos // If provided set PREVIOUS_SECTION_RETURN to point to the last section
235275fd0b74Schristos // that used the return memory region.
235375fd0b74Schristos
235475fd0b74Schristos Memory_region*
find_memory_region(Output_section_definition * section,bool find_vma_region,bool explicit_only,Output_section_definition ** previous_section_return)235575fd0b74Schristos Script_sections::find_memory_region(
235675fd0b74Schristos Output_section_definition* section,
235775fd0b74Schristos bool find_vma_region,
235875fd0b74Schristos bool explicit_only,
235975fd0b74Schristos Output_section_definition** previous_section_return)
236075fd0b74Schristos {
236175fd0b74Schristos if (previous_section_return != NULL)
236275fd0b74Schristos * previous_section_return = NULL;
236375fd0b74Schristos
236475fd0b74Schristos // Walk the memory regions specified in this script, if any.
236575fd0b74Schristos if (this->memory_regions_ == NULL)
236675fd0b74Schristos return NULL;
236775fd0b74Schristos
236875fd0b74Schristos // The /DISCARD/ section never gets assigned to any region.
236975fd0b74Schristos if (section->get_section_name() == "/DISCARD/")
237075fd0b74Schristos return NULL;
237175fd0b74Schristos
237275fd0b74Schristos Memory_region* first_match = NULL;
237375fd0b74Schristos
237475fd0b74Schristos // First check to see if a region has been assigned to this section.
237575fd0b74Schristos for (Memory_regions::const_iterator mr = this->memory_regions_->begin();
237675fd0b74Schristos mr != this->memory_regions_->end();
237775fd0b74Schristos ++mr)
237875fd0b74Schristos {
237975fd0b74Schristos if (find_vma_region)
238075fd0b74Schristos {
238175fd0b74Schristos for (Memory_region::Section_list::const_iterator s =
238275fd0b74Schristos (*mr)->get_vma_section_list_start();
238375fd0b74Schristos s != (*mr)->get_vma_section_list_end();
238475fd0b74Schristos ++s)
238575fd0b74Schristos if ((*s) == section)
238675fd0b74Schristos {
238775fd0b74Schristos (*mr)->set_last_section(section);
238875fd0b74Schristos return *mr;
238975fd0b74Schristos }
239075fd0b74Schristos }
239175fd0b74Schristos else
239275fd0b74Schristos {
239375fd0b74Schristos for (Memory_region::Section_list::const_iterator s =
239475fd0b74Schristos (*mr)->get_lma_section_list_start();
239575fd0b74Schristos s != (*mr)->get_lma_section_list_end();
239675fd0b74Schristos ++s)
239775fd0b74Schristos if ((*s) == section)
239875fd0b74Schristos {
239975fd0b74Schristos (*mr)->set_last_section(section);
240075fd0b74Schristos return *mr;
240175fd0b74Schristos }
240275fd0b74Schristos }
240375fd0b74Schristos
240475fd0b74Schristos if (!explicit_only)
240575fd0b74Schristos {
240675fd0b74Schristos // Make a note of the first memory region whose attributes
240775fd0b74Schristos // are compatible with the section. If we do not find an
240875fd0b74Schristos // explicit region assignment, then we will return this region.
240975fd0b74Schristos Output_section* out_sec = section->get_output_section();
241075fd0b74Schristos if (first_match == NULL
241175fd0b74Schristos && out_sec != NULL
241275fd0b74Schristos && (*mr)->attributes_compatible(out_sec->flags(),
241375fd0b74Schristos out_sec->type()))
241475fd0b74Schristos first_match = *mr;
241575fd0b74Schristos }
241675fd0b74Schristos }
241775fd0b74Schristos
241875fd0b74Schristos // With LMA computations, if an explicit region has not been specified then
241975fd0b74Schristos // we will want to set the difference between the VMA and the LMA of the
242075fd0b74Schristos // section were searching for to be the same as the difference between the
242175fd0b74Schristos // VMA and LMA of the last section to be added to first matched region.
242275fd0b74Schristos // Hence, if it was asked for, we return a pointer to the last section
242375fd0b74Schristos // known to be used by the first matched region.
242475fd0b74Schristos if (first_match != NULL
242575fd0b74Schristos && previous_section_return != NULL)
242675fd0b74Schristos *previous_section_return = first_match->get_last_section();
242775fd0b74Schristos
242875fd0b74Schristos return first_match;
242975fd0b74Schristos }
243075fd0b74Schristos
243175fd0b74Schristos // Set the section address. Note that the OUTPUT_SECTION_ field will
243275fd0b74Schristos // be NULL if no input sections were mapped to this output section.
243375fd0b74Schristos // We still have to adjust dot and process symbol assignments.
243475fd0b74Schristos
243575fd0b74Schristos void
set_section_addresses(Symbol_table * symtab,Layout * layout,uint64_t * dot_value,uint64_t * dot_alignment,uint64_t * load_address)243675fd0b74Schristos Output_section_definition::set_section_addresses(Symbol_table* symtab,
243775fd0b74Schristos Layout* layout,
243875fd0b74Schristos uint64_t* dot_value,
243975fd0b74Schristos uint64_t* dot_alignment,
244075fd0b74Schristos uint64_t* load_address)
244175fd0b74Schristos {
244275fd0b74Schristos Memory_region* vma_region = NULL;
244375fd0b74Schristos Memory_region* lma_region = NULL;
244475fd0b74Schristos Script_sections* script_sections =
244575fd0b74Schristos layout->script_options()->script_sections();
244675fd0b74Schristos uint64_t address;
244775fd0b74Schristos uint64_t old_dot_value = *dot_value;
244875fd0b74Schristos uint64_t old_load_address = *load_address;
244975fd0b74Schristos
245075fd0b74Schristos // If input section sorting is requested via --section-ordering-file or
245175fd0b74Schristos // linker plugins, then do it here. This is important because we want
245275fd0b74Schristos // any sorting specified in the linker scripts, which will be done after
245375fd0b74Schristos // this, to take precedence. The final order of input sections is then
245475fd0b74Schristos // guaranteed to be according to the linker script specification.
245575fd0b74Schristos if (this->output_section_ != NULL
245675fd0b74Schristos && this->output_section_->input_section_order_specified())
245775fd0b74Schristos this->output_section_->sort_attached_input_sections();
245875fd0b74Schristos
245975fd0b74Schristos // Decide the start address for the section. The algorithm is:
246075fd0b74Schristos // 1) If an address has been specified in a linker script, use that.
246175fd0b74Schristos // 2) Otherwise if a memory region has been specified for the section,
246275fd0b74Schristos // use the next free address in the region.
246375fd0b74Schristos // 3) Otherwise if memory regions have been specified find the first
246475fd0b74Schristos // region whose attributes are compatible with this section and
246575fd0b74Schristos // install it into that region.
246675fd0b74Schristos // 4) Otherwise use the current location counter.
246775fd0b74Schristos
246875fd0b74Schristos if (this->output_section_ != NULL
246975fd0b74Schristos // Check for --section-start.
247075fd0b74Schristos && parameters->options().section_start(this->output_section_->name(),
247175fd0b74Schristos &address))
247275fd0b74Schristos ;
247375fd0b74Schristos else if (this->address_ == NULL)
247475fd0b74Schristos {
247575fd0b74Schristos vma_region = script_sections->find_memory_region(this, true, false, NULL);
247675fd0b74Schristos if (vma_region != NULL)
247775fd0b74Schristos address = vma_region->get_current_address()->eval(symtab, layout,
247875fd0b74Schristos false);
247975fd0b74Schristos else
248075fd0b74Schristos address = *dot_value;
248175fd0b74Schristos }
248275fd0b74Schristos else
248375fd0b74Schristos {
248475fd0b74Schristos vma_region = script_sections->find_memory_region(this, true, true, NULL);
248575fd0b74Schristos address = this->address_->eval_with_dot(symtab, layout, true,
248675fd0b74Schristos *dot_value, NULL, NULL,
248775fd0b74Schristos dot_alignment, false);
248875fd0b74Schristos if (vma_region != NULL)
248975fd0b74Schristos vma_region->set_address(address, symtab, layout);
249075fd0b74Schristos }
249175fd0b74Schristos
249275fd0b74Schristos uint64_t align;
249375fd0b74Schristos if (this->align_ == NULL)
249475fd0b74Schristos {
249575fd0b74Schristos if (this->output_section_ == NULL)
249675fd0b74Schristos align = 0;
249775fd0b74Schristos else
249875fd0b74Schristos align = this->output_section_->addralign();
249975fd0b74Schristos }
250075fd0b74Schristos else
250175fd0b74Schristos {
250275fd0b74Schristos Output_section* align_section;
250375fd0b74Schristos align = this->align_->eval_with_dot(symtab, layout, true, *dot_value,
250475fd0b74Schristos NULL, &align_section, NULL, false);
250575fd0b74Schristos if (align_section != NULL)
250675fd0b74Schristos gold_warning(_("alignment of section %s is not absolute"),
250775fd0b74Schristos this->name_.c_str());
250875fd0b74Schristos if (this->output_section_ != NULL)
250975fd0b74Schristos this->output_section_->set_addralign(align);
251075fd0b74Schristos }
251175fd0b74Schristos
2512ede78133Schristos uint64_t subalign;
2513ede78133Schristos if (this->subalign_ == NULL)
2514ede78133Schristos subalign = 0;
2515ede78133Schristos else
2516ede78133Schristos {
2517ede78133Schristos Output_section* subalign_section;
2518ede78133Schristos subalign = this->subalign_->eval_with_dot(symtab, layout, true,
2519ede78133Schristos *dot_value, NULL,
2520ede78133Schristos &subalign_section, NULL,
2521ede78133Schristos false);
2522ede78133Schristos if (subalign_section != NULL)
2523ede78133Schristos gold_warning(_("subalign of section %s is not absolute"),
2524ede78133Schristos this->name_.c_str());
2525ede78133Schristos
2526ede78133Schristos // Reserve a value of 0 to mean there is no SUBALIGN property.
2527ede78133Schristos if (subalign == 0)
2528ede78133Schristos subalign = 1;
2529ede78133Schristos
2530ede78133Schristos // The external alignment of the output section must be at least
2531ede78133Schristos // as large as that of the input sections. If there is no
2532ede78133Schristos // explicit ALIGN property, we set the output section alignment
2533ede78133Schristos // to match the input section alignment.
2534ede78133Schristos if (align < subalign || this->align_ == NULL)
2535ede78133Schristos {
2536ede78133Schristos align = subalign;
2537ede78133Schristos this->output_section_->set_addralign(align);
2538ede78133Schristos }
2539ede78133Schristos }
2540ede78133Schristos
254175fd0b74Schristos address = align_address(address, align);
254275fd0b74Schristos
254375fd0b74Schristos uint64_t start_address = address;
254475fd0b74Schristos
254575fd0b74Schristos *dot_value = address;
254675fd0b74Schristos
254775fd0b74Schristos // Except for NOLOAD sections, the address of non-SHF_ALLOC sections is
254875fd0b74Schristos // forced to zero, regardless of what the linker script wants.
254975fd0b74Schristos if (this->output_section_ != NULL
255075fd0b74Schristos && ((this->output_section_->flags() & elfcpp::SHF_ALLOC) != 0
255175fd0b74Schristos || this->output_section_->is_noload()))
255275fd0b74Schristos this->output_section_->set_address(address);
255375fd0b74Schristos
255475fd0b74Schristos this->evaluated_address_ = address;
255575fd0b74Schristos this->evaluated_addralign_ = align;
255675fd0b74Schristos
255775fd0b74Schristos uint64_t laddr;
255875fd0b74Schristos
255975fd0b74Schristos if (this->load_address_ == NULL)
256075fd0b74Schristos {
256175fd0b74Schristos Output_section_definition* previous_section;
256275fd0b74Schristos
256375fd0b74Schristos // Determine if an LMA region has been set for this section.
256475fd0b74Schristos lma_region = script_sections->find_memory_region(this, false, false,
256575fd0b74Schristos &previous_section);
256675fd0b74Schristos
256775fd0b74Schristos if (lma_region != NULL)
256875fd0b74Schristos {
256975fd0b74Schristos if (previous_section == NULL)
257075fd0b74Schristos // The LMA address was explicitly set to the given region.
257175fd0b74Schristos laddr = lma_region->get_current_address()->eval(symtab, layout,
257275fd0b74Schristos false);
257375fd0b74Schristos else
257475fd0b74Schristos {
257575fd0b74Schristos // We are not going to use the discovered lma_region, so
257675fd0b74Schristos // make sure that we do not update it in the code below.
257775fd0b74Schristos lma_region = NULL;
257875fd0b74Schristos
257975fd0b74Schristos if (this->address_ != NULL || previous_section == this)
258075fd0b74Schristos {
258175fd0b74Schristos // Either an explicit VMA address has been set, or an
258275fd0b74Schristos // explicit VMA region has been set, so set the LMA equal to
258375fd0b74Schristos // the VMA.
258475fd0b74Schristos laddr = address;
258575fd0b74Schristos }
258675fd0b74Schristos else
258775fd0b74Schristos {
258875fd0b74Schristos // The LMA address was not explicitly or implicitly set.
258975fd0b74Schristos //
259075fd0b74Schristos // We have been given the first memory region that is
259175fd0b74Schristos // compatible with the current section and a pointer to the
259275fd0b74Schristos // last section to use this region. Set the LMA of this
259375fd0b74Schristos // section so that the difference between its' VMA and LMA
259475fd0b74Schristos // is the same as the difference between the VMA and LMA of
259575fd0b74Schristos // the last section in the given region.
259675fd0b74Schristos laddr = address + (previous_section->evaluated_load_address_
259775fd0b74Schristos - previous_section->evaluated_address_);
259875fd0b74Schristos }
259975fd0b74Schristos }
260075fd0b74Schristos
260175fd0b74Schristos if (this->output_section_ != NULL)
260275fd0b74Schristos this->output_section_->set_load_address(laddr);
260375fd0b74Schristos }
260475fd0b74Schristos else
260575fd0b74Schristos {
260675fd0b74Schristos // Do not set the load address of the output section, if one exists.
260775fd0b74Schristos // This allows future sections to determine what the load address
260875fd0b74Schristos // should be. If none is ever set, it will default to being the
260975fd0b74Schristos // same as the vma address.
261075fd0b74Schristos laddr = address;
261175fd0b74Schristos }
261275fd0b74Schristos }
261375fd0b74Schristos else
261475fd0b74Schristos {
261575fd0b74Schristos laddr = this->load_address_->eval_with_dot(symtab, layout, true,
261675fd0b74Schristos *dot_value,
261775fd0b74Schristos this->output_section_,
261875fd0b74Schristos NULL, NULL, false);
261975fd0b74Schristos if (this->output_section_ != NULL)
262075fd0b74Schristos this->output_section_->set_load_address(laddr);
262175fd0b74Schristos }
262275fd0b74Schristos
262375fd0b74Schristos this->evaluated_load_address_ = laddr;
262475fd0b74Schristos
262575fd0b74Schristos std::string fill;
262675fd0b74Schristos if (this->fill_ != NULL)
262775fd0b74Schristos {
262875fd0b74Schristos // FIXME: The GNU linker supports fill values of arbitrary
262975fd0b74Schristos // length.
263075fd0b74Schristos Output_section* fill_section;
263175fd0b74Schristos uint64_t fill_val = this->fill_->eval_with_dot(symtab, layout, true,
263275fd0b74Schristos *dot_value,
263375fd0b74Schristos NULL, &fill_section,
263475fd0b74Schristos NULL, false);
263575fd0b74Schristos if (fill_section != NULL)
263675fd0b74Schristos gold_warning(_("fill of section %s is not absolute"),
263775fd0b74Schristos this->name_.c_str());
263875fd0b74Schristos unsigned char fill_buff[4];
263975fd0b74Schristos elfcpp::Swap_unaligned<32, true>::writeval(fill_buff, fill_val);
264075fd0b74Schristos fill.assign(reinterpret_cast<char*>(fill_buff), 4);
264175fd0b74Schristos }
264275fd0b74Schristos
264375fd0b74Schristos Input_section_list input_sections;
264475fd0b74Schristos if (this->output_section_ != NULL)
264575fd0b74Schristos {
264675fd0b74Schristos // Get the list of input sections attached to this output
264775fd0b74Schristos // section. This will leave the output section with only
264875fd0b74Schristos // Output_section_data entries.
264975fd0b74Schristos address += this->output_section_->get_input_sections(address,
265075fd0b74Schristos fill,
265175fd0b74Schristos &input_sections);
265275fd0b74Schristos *dot_value = address;
265375fd0b74Schristos }
265475fd0b74Schristos
265575fd0b74Schristos Output_section* dot_section = this->output_section_;
265675fd0b74Schristos for (Output_section_elements::iterator p = this->elements_.begin();
265775fd0b74Schristos p != this->elements_.end();
265875fd0b74Schristos ++p)
265975fd0b74Schristos (*p)->set_section_addresses(symtab, layout, this->output_section_,
266075fd0b74Schristos subalign, dot_value, dot_alignment,
266175fd0b74Schristos &dot_section, &fill, &input_sections);
266275fd0b74Schristos
266375fd0b74Schristos gold_assert(input_sections.empty());
266475fd0b74Schristos
266575fd0b74Schristos if (vma_region != NULL)
266675fd0b74Schristos {
266775fd0b74Schristos // Update the VMA region being used by the section now that we know how
266875fd0b74Schristos // big it is. Use the current address in the region, rather than
266975fd0b74Schristos // start_address because that might have been aligned upwards and we
267075fd0b74Schristos // need to allow for the padding.
267175fd0b74Schristos Expression* addr = vma_region->get_current_address();
267275fd0b74Schristos uint64_t size = *dot_value - addr->eval(symtab, layout, false);
267375fd0b74Schristos
267475fd0b74Schristos vma_region->increment_offset(this->get_section_name(), size,
267575fd0b74Schristos symtab, layout);
267675fd0b74Schristos }
267775fd0b74Schristos
267875fd0b74Schristos // If the LMA region is different from the VMA region, then increment the
267975fd0b74Schristos // offset there as well. Note that we use the same "dot_value -
268075fd0b74Schristos // start_address" formula that is used in the load_address assignment below.
268175fd0b74Schristos if (lma_region != NULL && lma_region != vma_region)
268275fd0b74Schristos lma_region->increment_offset(this->get_section_name(),
268375fd0b74Schristos *dot_value - start_address,
268475fd0b74Schristos symtab, layout);
268575fd0b74Schristos
268675fd0b74Schristos // Compute the load address for the following section.
268775fd0b74Schristos if (this->output_section_ == NULL)
268875fd0b74Schristos *load_address = *dot_value;
268975fd0b74Schristos else if (this->load_address_ == NULL)
269075fd0b74Schristos {
269175fd0b74Schristos if (lma_region == NULL)
269275fd0b74Schristos *load_address = *dot_value;
269375fd0b74Schristos else
269475fd0b74Schristos *load_address =
269575fd0b74Schristos lma_region->get_current_address()->eval(symtab, layout, false);
269675fd0b74Schristos }
269775fd0b74Schristos else
269875fd0b74Schristos *load_address = (this->output_section_->load_address()
269975fd0b74Schristos + (*dot_value - start_address));
270075fd0b74Schristos
270175fd0b74Schristos if (this->output_section_ != NULL)
270275fd0b74Schristos {
270375fd0b74Schristos if (this->is_relro_)
270475fd0b74Schristos this->output_section_->set_is_relro();
270575fd0b74Schristos else
270675fd0b74Schristos this->output_section_->clear_is_relro();
270775fd0b74Schristos
270875fd0b74Schristos // If this is a NOLOAD section, keep dot and load address unchanged.
270975fd0b74Schristos if (this->output_section_->is_noload())
271075fd0b74Schristos {
271175fd0b74Schristos *dot_value = old_dot_value;
271275fd0b74Schristos *load_address = old_load_address;
271375fd0b74Schristos }
271475fd0b74Schristos }
271575fd0b74Schristos }
271675fd0b74Schristos
271775fd0b74Schristos // Check a constraint (ONLY_IF_RO, etc.) on an output section. If
271875fd0b74Schristos // this section is constrained, and the input sections do not match,
271975fd0b74Schristos // return the constraint, and set *POSD.
272075fd0b74Schristos
272175fd0b74Schristos Section_constraint
check_constraint(Output_section_definition ** posd)272275fd0b74Schristos Output_section_definition::check_constraint(Output_section_definition** posd)
272375fd0b74Schristos {
272475fd0b74Schristos switch (this->constraint_)
272575fd0b74Schristos {
272675fd0b74Schristos case CONSTRAINT_NONE:
272775fd0b74Schristos return CONSTRAINT_NONE;
272875fd0b74Schristos
272975fd0b74Schristos case CONSTRAINT_ONLY_IF_RO:
273075fd0b74Schristos if (this->output_section_ != NULL
273175fd0b74Schristos && (this->output_section_->flags() & elfcpp::SHF_WRITE) != 0)
273275fd0b74Schristos {
273375fd0b74Schristos *posd = this;
273475fd0b74Schristos return CONSTRAINT_ONLY_IF_RO;
273575fd0b74Schristos }
273675fd0b74Schristos return CONSTRAINT_NONE;
273775fd0b74Schristos
273875fd0b74Schristos case CONSTRAINT_ONLY_IF_RW:
273975fd0b74Schristos if (this->output_section_ != NULL
274075fd0b74Schristos && (this->output_section_->flags() & elfcpp::SHF_WRITE) == 0)
274175fd0b74Schristos {
274275fd0b74Schristos *posd = this;
274375fd0b74Schristos return CONSTRAINT_ONLY_IF_RW;
274475fd0b74Schristos }
274575fd0b74Schristos return CONSTRAINT_NONE;
274675fd0b74Schristos
274775fd0b74Schristos case CONSTRAINT_SPECIAL:
274875fd0b74Schristos if (this->output_section_ != NULL)
274975fd0b74Schristos gold_error(_("SPECIAL constraints are not implemented"));
275075fd0b74Schristos return CONSTRAINT_NONE;
275175fd0b74Schristos
275275fd0b74Schristos default:
275375fd0b74Schristos gold_unreachable();
275475fd0b74Schristos }
275575fd0b74Schristos }
275675fd0b74Schristos
275775fd0b74Schristos // See if this is the alternate output section for a constrained
275875fd0b74Schristos // output section. If it is, transfer the Output_section and return
275975fd0b74Schristos // true. Otherwise return false.
276075fd0b74Schristos
276175fd0b74Schristos bool
alternate_constraint(Output_section_definition * posd,Section_constraint constraint)276275fd0b74Schristos Output_section_definition::alternate_constraint(
276375fd0b74Schristos Output_section_definition* posd,
276475fd0b74Schristos Section_constraint constraint)
276575fd0b74Schristos {
276675fd0b74Schristos if (this->name_ != posd->name_)
276775fd0b74Schristos return false;
276875fd0b74Schristos
276975fd0b74Schristos switch (constraint)
277075fd0b74Schristos {
277175fd0b74Schristos case CONSTRAINT_ONLY_IF_RO:
277275fd0b74Schristos if (this->constraint_ != CONSTRAINT_ONLY_IF_RW)
277375fd0b74Schristos return false;
277475fd0b74Schristos break;
277575fd0b74Schristos
277675fd0b74Schristos case CONSTRAINT_ONLY_IF_RW:
277775fd0b74Schristos if (this->constraint_ != CONSTRAINT_ONLY_IF_RO)
277875fd0b74Schristos return false;
277975fd0b74Schristos break;
278075fd0b74Schristos
278175fd0b74Schristos default:
278275fd0b74Schristos gold_unreachable();
278375fd0b74Schristos }
278475fd0b74Schristos
278575fd0b74Schristos // We have found the alternate constraint. We just need to move
278675fd0b74Schristos // over the Output_section. When constraints are used properly,
278775fd0b74Schristos // THIS should not have an output_section pointer, as all the input
278875fd0b74Schristos // sections should have matched the other definition.
278975fd0b74Schristos
279075fd0b74Schristos if (this->output_section_ != NULL)
279175fd0b74Schristos gold_error(_("mismatched definition for constrained sections"));
279275fd0b74Schristos
279375fd0b74Schristos this->output_section_ = posd->output_section_;
279475fd0b74Schristos posd->output_section_ = NULL;
279575fd0b74Schristos
279675fd0b74Schristos if (this->is_relro_)
279775fd0b74Schristos this->output_section_->set_is_relro();
279875fd0b74Schristos else
279975fd0b74Schristos this->output_section_->clear_is_relro();
280075fd0b74Schristos
280175fd0b74Schristos return true;
280275fd0b74Schristos }
280375fd0b74Schristos
280475fd0b74Schristos // Get the list of segments to use for an allocated section when using
280575fd0b74Schristos // a PHDRS clause.
280675fd0b74Schristos
280775fd0b74Schristos Output_section*
allocate_to_segment(String_list ** phdrs_list,bool * orphan)280875fd0b74Schristos Output_section_definition::allocate_to_segment(String_list** phdrs_list,
280975fd0b74Schristos bool* orphan)
281075fd0b74Schristos {
281175fd0b74Schristos // Update phdrs_list even if we don't have an output section. It
281275fd0b74Schristos // might be used by the following sections.
281375fd0b74Schristos if (this->phdrs_ != NULL)
281475fd0b74Schristos *phdrs_list = this->phdrs_;
281575fd0b74Schristos
281675fd0b74Schristos if (this->output_section_ == NULL)
281775fd0b74Schristos return NULL;
281875fd0b74Schristos if ((this->output_section_->flags() & elfcpp::SHF_ALLOC) == 0)
281975fd0b74Schristos return NULL;
282075fd0b74Schristos *orphan = false;
282175fd0b74Schristos return this->output_section_;
282275fd0b74Schristos }
282375fd0b74Schristos
282475fd0b74Schristos // Look for an output section by name and return the address, the load
282575fd0b74Schristos // address, the alignment, and the size. This is used when an
282675fd0b74Schristos // expression refers to an output section which was not actually
282775fd0b74Schristos // created. This returns true if the section was found, false
282875fd0b74Schristos // otherwise.
282975fd0b74Schristos
283075fd0b74Schristos bool
get_output_section_info(const char * name,uint64_t * address,uint64_t * load_address,uint64_t * addralign,uint64_t * size) const283175fd0b74Schristos Output_section_definition::get_output_section_info(const char* name,
283275fd0b74Schristos uint64_t* address,
283375fd0b74Schristos uint64_t* load_address,
283475fd0b74Schristos uint64_t* addralign,
283575fd0b74Schristos uint64_t* size) const
283675fd0b74Schristos {
283775fd0b74Schristos if (this->name_ != name)
283875fd0b74Schristos return false;
283975fd0b74Schristos
284075fd0b74Schristos if (this->output_section_ != NULL)
284175fd0b74Schristos {
284275fd0b74Schristos *address = this->output_section_->address();
284375fd0b74Schristos if (this->output_section_->has_load_address())
284475fd0b74Schristos *load_address = this->output_section_->load_address();
284575fd0b74Schristos else
284675fd0b74Schristos *load_address = *address;
284775fd0b74Schristos *addralign = this->output_section_->addralign();
284875fd0b74Schristos *size = this->output_section_->current_data_size();
284975fd0b74Schristos }
285075fd0b74Schristos else
285175fd0b74Schristos {
285275fd0b74Schristos *address = this->evaluated_address_;
285375fd0b74Schristos *load_address = this->evaluated_load_address_;
285475fd0b74Schristos *addralign = this->evaluated_addralign_;
285575fd0b74Schristos *size = 0;
285675fd0b74Schristos }
285775fd0b74Schristos
285875fd0b74Schristos return true;
285975fd0b74Schristos }
286075fd0b74Schristos
286175fd0b74Schristos // Print for debugging.
286275fd0b74Schristos
286375fd0b74Schristos void
print(FILE * f) const286475fd0b74Schristos Output_section_definition::print(FILE* f) const
286575fd0b74Schristos {
286675fd0b74Schristos fprintf(f, " %s ", this->name_.c_str());
286775fd0b74Schristos
286875fd0b74Schristos if (this->address_ != NULL)
286975fd0b74Schristos {
287075fd0b74Schristos this->address_->print(f);
287175fd0b74Schristos fprintf(f, " ");
287275fd0b74Schristos }
287375fd0b74Schristos
287475fd0b74Schristos if (this->script_section_type_ != SCRIPT_SECTION_TYPE_NONE)
287575fd0b74Schristos fprintf(f, "(%s) ",
287675fd0b74Schristos this->script_section_type_name(this->script_section_type_));
287775fd0b74Schristos
287875fd0b74Schristos fprintf(f, ": ");
287975fd0b74Schristos
288075fd0b74Schristos if (this->load_address_ != NULL)
288175fd0b74Schristos {
288275fd0b74Schristos fprintf(f, "AT(");
288375fd0b74Schristos this->load_address_->print(f);
288475fd0b74Schristos fprintf(f, ") ");
288575fd0b74Schristos }
288675fd0b74Schristos
288775fd0b74Schristos if (this->align_ != NULL)
288875fd0b74Schristos {
288975fd0b74Schristos fprintf(f, "ALIGN(");
289075fd0b74Schristos this->align_->print(f);
289175fd0b74Schristos fprintf(f, ") ");
289275fd0b74Schristos }
289375fd0b74Schristos
289475fd0b74Schristos if (this->subalign_ != NULL)
289575fd0b74Schristos {
289675fd0b74Schristos fprintf(f, "SUBALIGN(");
289775fd0b74Schristos this->subalign_->print(f);
289875fd0b74Schristos fprintf(f, ") ");
289975fd0b74Schristos }
290075fd0b74Schristos
290175fd0b74Schristos fprintf(f, "{\n");
290275fd0b74Schristos
290375fd0b74Schristos for (Output_section_elements::const_iterator p = this->elements_.begin();
290475fd0b74Schristos p != this->elements_.end();
290575fd0b74Schristos ++p)
290675fd0b74Schristos (*p)->print(f);
290775fd0b74Schristos
290875fd0b74Schristos fprintf(f, " }");
290975fd0b74Schristos
291075fd0b74Schristos if (this->fill_ != NULL)
291175fd0b74Schristos {
291275fd0b74Schristos fprintf(f, " = ");
291375fd0b74Schristos this->fill_->print(f);
291475fd0b74Schristos }
291575fd0b74Schristos
291675fd0b74Schristos if (this->phdrs_ != NULL)
291775fd0b74Schristos {
291875fd0b74Schristos for (String_list::const_iterator p = this->phdrs_->begin();
291975fd0b74Schristos p != this->phdrs_->end();
292075fd0b74Schristos ++p)
292175fd0b74Schristos fprintf(f, " :%s", p->c_str());
292275fd0b74Schristos }
292375fd0b74Schristos
292475fd0b74Schristos fprintf(f, "\n");
292575fd0b74Schristos }
292675fd0b74Schristos
292775fd0b74Schristos Script_sections::Section_type
section_type() const292875fd0b74Schristos Output_section_definition::section_type() const
292975fd0b74Schristos {
293075fd0b74Schristos switch (this->script_section_type_)
293175fd0b74Schristos {
293275fd0b74Schristos case SCRIPT_SECTION_TYPE_NONE:
293375fd0b74Schristos return Script_sections::ST_NONE;
293475fd0b74Schristos case SCRIPT_SECTION_TYPE_NOLOAD:
293575fd0b74Schristos return Script_sections::ST_NOLOAD;
293675fd0b74Schristos case SCRIPT_SECTION_TYPE_COPY:
293775fd0b74Schristos case SCRIPT_SECTION_TYPE_DSECT:
293875fd0b74Schristos case SCRIPT_SECTION_TYPE_INFO:
293975fd0b74Schristos case SCRIPT_SECTION_TYPE_OVERLAY:
294075fd0b74Schristos // There are not really support so we treat them as ST_NONE. The
294175fd0b74Schristos // parse should have issued errors for them already.
294275fd0b74Schristos return Script_sections::ST_NONE;
294375fd0b74Schristos default:
294475fd0b74Schristos gold_unreachable();
294575fd0b74Schristos }
294675fd0b74Schristos }
294775fd0b74Schristos
294875fd0b74Schristos // Return the name of a script section type.
294975fd0b74Schristos
295075fd0b74Schristos const char*
script_section_type_name(Script_section_type script_section_type)295175fd0b74Schristos Output_section_definition::script_section_type_name(
295275fd0b74Schristos Script_section_type script_section_type)
295375fd0b74Schristos {
295475fd0b74Schristos switch (script_section_type)
295575fd0b74Schristos {
295675fd0b74Schristos case SCRIPT_SECTION_TYPE_NONE:
295775fd0b74Schristos return "NONE";
295875fd0b74Schristos case SCRIPT_SECTION_TYPE_NOLOAD:
295975fd0b74Schristos return "NOLOAD";
296075fd0b74Schristos case SCRIPT_SECTION_TYPE_DSECT:
296175fd0b74Schristos return "DSECT";
296275fd0b74Schristos case SCRIPT_SECTION_TYPE_COPY:
296375fd0b74Schristos return "COPY";
296475fd0b74Schristos case SCRIPT_SECTION_TYPE_INFO:
296575fd0b74Schristos return "INFO";
296675fd0b74Schristos case SCRIPT_SECTION_TYPE_OVERLAY:
296775fd0b74Schristos return "OVERLAY";
296875fd0b74Schristos default:
296975fd0b74Schristos gold_unreachable();
297075fd0b74Schristos }
297175fd0b74Schristos }
297275fd0b74Schristos
297375fd0b74Schristos void
set_memory_region(Memory_region * mr,bool set_vma)297475fd0b74Schristos Output_section_definition::set_memory_region(Memory_region* mr, bool set_vma)
297575fd0b74Schristos {
297675fd0b74Schristos gold_assert(mr != NULL);
297775fd0b74Schristos // Add the current section to the specified region's list.
297875fd0b74Schristos mr->add_section(this, set_vma);
297975fd0b74Schristos }
298075fd0b74Schristos
298175fd0b74Schristos // An output section created to hold orphaned input sections. These
298275fd0b74Schristos // do not actually appear in linker scripts. However, for convenience
298375fd0b74Schristos // when setting the output section addresses, we put a marker to these
298475fd0b74Schristos // sections in the appropriate place in the list of SECTIONS elements.
298575fd0b74Schristos
298675fd0b74Schristos class Orphan_output_section : public Sections_element
298775fd0b74Schristos {
298875fd0b74Schristos public:
Orphan_output_section(Output_section * os)298975fd0b74Schristos Orphan_output_section(Output_section* os)
299075fd0b74Schristos : os_(os)
299175fd0b74Schristos { }
299275fd0b74Schristos
299375fd0b74Schristos // Return whether the orphan output section is relro. We can just
299475fd0b74Schristos // check the output section because we always set the flag, if
299575fd0b74Schristos // needed, just after we create the Orphan_output_section.
299675fd0b74Schristos bool
is_relro() const299775fd0b74Schristos is_relro() const
299875fd0b74Schristos { return this->os_->is_relro(); }
299975fd0b74Schristos
300075fd0b74Schristos // Initialize OSP with an output section. This should have been
300175fd0b74Schristos // done already.
300275fd0b74Schristos void
orphan_section_init(Orphan_section_placement *,Script_sections::Elements_iterator)300375fd0b74Schristos orphan_section_init(Orphan_section_placement*,
300475fd0b74Schristos Script_sections::Elements_iterator)
300575fd0b74Schristos { gold_unreachable(); }
300675fd0b74Schristos
300775fd0b74Schristos // Set section addresses.
300875fd0b74Schristos void
300975fd0b74Schristos set_section_addresses(Symbol_table*, Layout*, uint64_t*, uint64_t*,
301075fd0b74Schristos uint64_t*);
301175fd0b74Schristos
301275fd0b74Schristos // Get the list of segments to use for an allocated section when
301375fd0b74Schristos // using a PHDRS clause.
301475fd0b74Schristos Output_section*
301575fd0b74Schristos allocate_to_segment(String_list**, bool*);
301675fd0b74Schristos
301775fd0b74Schristos // Return the associated Output_section.
301875fd0b74Schristos Output_section*
get_output_section() const301975fd0b74Schristos get_output_section() const
302075fd0b74Schristos { return this->os_; }
302175fd0b74Schristos
302275fd0b74Schristos // Print for debugging.
302375fd0b74Schristos void
print(FILE * f) const302475fd0b74Schristos print(FILE* f) const
302575fd0b74Schristos {
302675fd0b74Schristos fprintf(f, " marker for orphaned output section %s\n",
302775fd0b74Schristos this->os_->name());
302875fd0b74Schristos }
302975fd0b74Schristos
303075fd0b74Schristos private:
303175fd0b74Schristos Output_section* os_;
303275fd0b74Schristos };
303375fd0b74Schristos
303475fd0b74Schristos // Set section addresses.
303575fd0b74Schristos
303675fd0b74Schristos void
set_section_addresses(Symbol_table *,Layout *,uint64_t * dot_value,uint64_t *,uint64_t * load_address)303775fd0b74Schristos Orphan_output_section::set_section_addresses(Symbol_table*, Layout*,
303875fd0b74Schristos uint64_t* dot_value,
303975fd0b74Schristos uint64_t*,
304075fd0b74Schristos uint64_t* load_address)
304175fd0b74Schristos {
304275fd0b74Schristos typedef std::list<Output_section::Input_section> Input_section_list;
304375fd0b74Schristos
304475fd0b74Schristos bool have_load_address = *load_address != *dot_value;
304575fd0b74Schristos
304675fd0b74Schristos uint64_t address = *dot_value;
304775fd0b74Schristos address = align_address(address, this->os_->addralign());
304875fd0b74Schristos
304975fd0b74Schristos // If input section sorting is requested via --section-ordering-file or
305075fd0b74Schristos // linker plugins, then do it here. This is important because we want
305175fd0b74Schristos // any sorting specified in the linker scripts, which will be done after
305275fd0b74Schristos // this, to take precedence. The final order of input sections is then
305375fd0b74Schristos // guaranteed to be according to the linker script specification.
305475fd0b74Schristos if (this->os_ != NULL
305575fd0b74Schristos && this->os_->input_section_order_specified())
305675fd0b74Schristos this->os_->sort_attached_input_sections();
305775fd0b74Schristos
305875fd0b74Schristos // For a relocatable link, all orphan sections are put at
305975fd0b74Schristos // address 0. In general we expect all sections to be at
306075fd0b74Schristos // address 0 for a relocatable link, but we permit the linker
306175fd0b74Schristos // script to override that for specific output sections.
306275fd0b74Schristos if (parameters->options().relocatable())
306375fd0b74Schristos {
306475fd0b74Schristos address = 0;
306575fd0b74Schristos *load_address = 0;
306675fd0b74Schristos have_load_address = false;
306775fd0b74Schristos }
306875fd0b74Schristos
306975fd0b74Schristos if ((this->os_->flags() & elfcpp::SHF_ALLOC) != 0)
307075fd0b74Schristos {
307175fd0b74Schristos this->os_->set_address(address);
307275fd0b74Schristos if (have_load_address)
307375fd0b74Schristos this->os_->set_load_address(align_address(*load_address,
307475fd0b74Schristos this->os_->addralign()));
307575fd0b74Schristos }
307675fd0b74Schristos
307775fd0b74Schristos Input_section_list input_sections;
307875fd0b74Schristos address += this->os_->get_input_sections(address, "", &input_sections);
307975fd0b74Schristos
308075fd0b74Schristos for (Input_section_list::iterator p = input_sections.begin();
308175fd0b74Schristos p != input_sections.end();
308275fd0b74Schristos ++p)
308375fd0b74Schristos {
308475fd0b74Schristos uint64_t addralign = p->addralign();
308575fd0b74Schristos if (!p->is_input_section())
308675fd0b74Schristos p->output_section_data()->finalize_data_size();
308775fd0b74Schristos uint64_t size = p->data_size();
308875fd0b74Schristos address = align_address(address, addralign);
308975fd0b74Schristos this->os_->add_script_input_section(*p);
309075fd0b74Schristos address += size;
309175fd0b74Schristos }
309275fd0b74Schristos
309375fd0b74Schristos if (parameters->options().relocatable())
309475fd0b74Schristos {
309575fd0b74Schristos // For a relocatable link, reset DOT_VALUE to 0.
309675fd0b74Schristos *dot_value = 0;
309775fd0b74Schristos *load_address = 0;
309875fd0b74Schristos }
309975fd0b74Schristos else if (this->os_ == NULL
310075fd0b74Schristos || (this->os_->flags() & elfcpp::SHF_TLS) == 0
310175fd0b74Schristos || this->os_->type() != elfcpp::SHT_NOBITS)
310275fd0b74Schristos {
310375fd0b74Schristos // An SHF_TLS/SHT_NOBITS section does not take up any address space.
310475fd0b74Schristos if (!have_load_address)
310575fd0b74Schristos *load_address = address;
310675fd0b74Schristos else
310775fd0b74Schristos *load_address += address - *dot_value;
310875fd0b74Schristos
310975fd0b74Schristos *dot_value = address;
311075fd0b74Schristos }
311175fd0b74Schristos }
311275fd0b74Schristos
311375fd0b74Schristos // Get the list of segments to use for an allocated section when using
311475fd0b74Schristos // a PHDRS clause. If this is an allocated section, return the
311575fd0b74Schristos // Output_section. We don't change the list of segments.
311675fd0b74Schristos
311775fd0b74Schristos Output_section*
allocate_to_segment(String_list **,bool * orphan)311875fd0b74Schristos Orphan_output_section::allocate_to_segment(String_list**, bool* orphan)
311975fd0b74Schristos {
312075fd0b74Schristos if ((this->os_->flags() & elfcpp::SHF_ALLOC) == 0)
312175fd0b74Schristos return NULL;
312275fd0b74Schristos *orphan = true;
312375fd0b74Schristos return this->os_;
312475fd0b74Schristos }
312575fd0b74Schristos
312675fd0b74Schristos // Class Phdrs_element. A program header from a PHDRS clause.
312775fd0b74Schristos
312875fd0b74Schristos class Phdrs_element
312975fd0b74Schristos {
313075fd0b74Schristos public:
Phdrs_element(const char * name,size_t namelen,unsigned int type,bool includes_filehdr,bool includes_phdrs,bool is_flags_valid,unsigned int flags,Expression * load_address)313175fd0b74Schristos Phdrs_element(const char* name, size_t namelen, unsigned int type,
313275fd0b74Schristos bool includes_filehdr, bool includes_phdrs,
313375fd0b74Schristos bool is_flags_valid, unsigned int flags,
313475fd0b74Schristos Expression* load_address)
313575fd0b74Schristos : name_(name, namelen), type_(type), includes_filehdr_(includes_filehdr),
313675fd0b74Schristos includes_phdrs_(includes_phdrs), is_flags_valid_(is_flags_valid),
313775fd0b74Schristos flags_(flags), load_address_(load_address), load_address_value_(0),
313875fd0b74Schristos segment_(NULL)
313975fd0b74Schristos { }
314075fd0b74Schristos
314175fd0b74Schristos // Return the name of this segment.
314275fd0b74Schristos const std::string&
name() const314375fd0b74Schristos name() const
314475fd0b74Schristos { return this->name_; }
314575fd0b74Schristos
314675fd0b74Schristos // Return the type of the segment.
314775fd0b74Schristos unsigned int
type() const314875fd0b74Schristos type() const
314975fd0b74Schristos { return this->type_; }
315075fd0b74Schristos
315175fd0b74Schristos // Whether to include the file header.
315275fd0b74Schristos bool
includes_filehdr() const315375fd0b74Schristos includes_filehdr() const
315475fd0b74Schristos { return this->includes_filehdr_; }
315575fd0b74Schristos
315675fd0b74Schristos // Whether to include the program headers.
315775fd0b74Schristos bool
includes_phdrs() const315875fd0b74Schristos includes_phdrs() const
315975fd0b74Schristos { return this->includes_phdrs_; }
316075fd0b74Schristos
316175fd0b74Schristos // Return whether there is a load address.
316275fd0b74Schristos bool
has_load_address() const316375fd0b74Schristos has_load_address() const
316475fd0b74Schristos { return this->load_address_ != NULL; }
316575fd0b74Schristos
316675fd0b74Schristos // Evaluate the load address expression if there is one.
316775fd0b74Schristos void
eval_load_address(Symbol_table * symtab,Layout * layout)316875fd0b74Schristos eval_load_address(Symbol_table* symtab, Layout* layout)
316975fd0b74Schristos {
317075fd0b74Schristos if (this->load_address_ != NULL)
317175fd0b74Schristos this->load_address_value_ = this->load_address_->eval(symtab, layout,
317275fd0b74Schristos true);
317375fd0b74Schristos }
317475fd0b74Schristos
317575fd0b74Schristos // Return the load address.
317675fd0b74Schristos uint64_t
load_address() const317775fd0b74Schristos load_address() const
317875fd0b74Schristos {
317975fd0b74Schristos gold_assert(this->load_address_ != NULL);
318075fd0b74Schristos return this->load_address_value_;
318175fd0b74Schristos }
318275fd0b74Schristos
318375fd0b74Schristos // Create the segment.
318475fd0b74Schristos Output_segment*
create_segment(Layout * layout)318575fd0b74Schristos create_segment(Layout* layout)
318675fd0b74Schristos {
318775fd0b74Schristos this->segment_ = layout->make_output_segment(this->type_, this->flags_);
318875fd0b74Schristos return this->segment_;
318975fd0b74Schristos }
319075fd0b74Schristos
319175fd0b74Schristos // Return the segment.
319275fd0b74Schristos Output_segment*
segment()319375fd0b74Schristos segment()
319475fd0b74Schristos { return this->segment_; }
319575fd0b74Schristos
319675fd0b74Schristos // Release the segment.
319775fd0b74Schristos void
release_segment()319875fd0b74Schristos release_segment()
319975fd0b74Schristos { this->segment_ = NULL; }
320075fd0b74Schristos
320175fd0b74Schristos // Set the segment flags if appropriate.
320275fd0b74Schristos void
set_flags_if_valid()320375fd0b74Schristos set_flags_if_valid()
320475fd0b74Schristos {
320575fd0b74Schristos if (this->is_flags_valid_)
320675fd0b74Schristos this->segment_->set_flags(this->flags_);
320775fd0b74Schristos }
320875fd0b74Schristos
320975fd0b74Schristos // Print for debugging.
321075fd0b74Schristos void
321175fd0b74Schristos print(FILE*) const;
321275fd0b74Schristos
321375fd0b74Schristos private:
321475fd0b74Schristos // The name used in the script.
321575fd0b74Schristos std::string name_;
321675fd0b74Schristos // The type of the segment (PT_LOAD, etc.).
321775fd0b74Schristos unsigned int type_;
321875fd0b74Schristos // Whether this segment includes the file header.
321975fd0b74Schristos bool includes_filehdr_;
322075fd0b74Schristos // Whether this segment includes the section headers.
322175fd0b74Schristos bool includes_phdrs_;
322275fd0b74Schristos // Whether the flags were explicitly specified.
322375fd0b74Schristos bool is_flags_valid_;
322475fd0b74Schristos // The flags for this segment (PF_R, etc.) if specified.
322575fd0b74Schristos unsigned int flags_;
322675fd0b74Schristos // The expression for the load address for this segment. This may
322775fd0b74Schristos // be NULL.
322875fd0b74Schristos Expression* load_address_;
322975fd0b74Schristos // The actual load address from evaluating the expression.
323075fd0b74Schristos uint64_t load_address_value_;
323175fd0b74Schristos // The segment itself.
323275fd0b74Schristos Output_segment* segment_;
323375fd0b74Schristos };
323475fd0b74Schristos
323575fd0b74Schristos // Print for debugging.
323675fd0b74Schristos
323775fd0b74Schristos void
print(FILE * f) const323875fd0b74Schristos Phdrs_element::print(FILE* f) const
323975fd0b74Schristos {
324075fd0b74Schristos fprintf(f, " %s 0x%x", this->name_.c_str(), this->type_);
324175fd0b74Schristos if (this->includes_filehdr_)
324275fd0b74Schristos fprintf(f, " FILEHDR");
324375fd0b74Schristos if (this->includes_phdrs_)
324475fd0b74Schristos fprintf(f, " PHDRS");
324575fd0b74Schristos if (this->is_flags_valid_)
324675fd0b74Schristos fprintf(f, " FLAGS(%u)", this->flags_);
324775fd0b74Schristos if (this->load_address_ != NULL)
324875fd0b74Schristos {
324975fd0b74Schristos fprintf(f, " AT(");
325075fd0b74Schristos this->load_address_->print(f);
325175fd0b74Schristos fprintf(f, ")");
325275fd0b74Schristos }
325375fd0b74Schristos fprintf(f, ";\n");
325475fd0b74Schristos }
325575fd0b74Schristos
325675fd0b74Schristos // Add a memory region.
325775fd0b74Schristos
325875fd0b74Schristos void
add_memory_region(const char * name,size_t namelen,unsigned int attributes,Expression * start,Expression * length)325975fd0b74Schristos Script_sections::add_memory_region(const char* name, size_t namelen,
326075fd0b74Schristos unsigned int attributes,
326175fd0b74Schristos Expression* start, Expression* length)
326275fd0b74Schristos {
326375fd0b74Schristos if (this->memory_regions_ == NULL)
326475fd0b74Schristos this->memory_regions_ = new Memory_regions();
326575fd0b74Schristos else if (this->find_memory_region(name, namelen))
326675fd0b74Schristos {
326775fd0b74Schristos gold_error(_("region '%.*s' already defined"), static_cast<int>(namelen),
326875fd0b74Schristos name);
326975fd0b74Schristos // FIXME: Add a GOLD extension to allow multiple regions with the same
327075fd0b74Schristos // name. This would amount to a single region covering disjoint blocks
327175fd0b74Schristos // of memory, which is useful for embedded devices.
327275fd0b74Schristos }
327375fd0b74Schristos
327475fd0b74Schristos // FIXME: Check the length and start values. Currently we allow
327575fd0b74Schristos // non-constant expressions for these values, whereas LD does not.
327675fd0b74Schristos
327775fd0b74Schristos // FIXME: Add a GOLD extension to allow NEGATIVE LENGTHS. This would
327875fd0b74Schristos // describe a region that packs from the end address going down, rather
327975fd0b74Schristos // than the start address going up. This would be useful for embedded
328075fd0b74Schristos // devices.
328175fd0b74Schristos
328275fd0b74Schristos this->memory_regions_->push_back(new Memory_region(name, namelen, attributes,
328375fd0b74Schristos start, length));
328475fd0b74Schristos }
328575fd0b74Schristos
328675fd0b74Schristos // Find a memory region.
328775fd0b74Schristos
328875fd0b74Schristos Memory_region*
find_memory_region(const char * name,size_t namelen)328975fd0b74Schristos Script_sections::find_memory_region(const char* name, size_t namelen)
329075fd0b74Schristos {
329175fd0b74Schristos if (this->memory_regions_ == NULL)
329275fd0b74Schristos return NULL;
329375fd0b74Schristos
329475fd0b74Schristos for (Memory_regions::const_iterator m = this->memory_regions_->begin();
329575fd0b74Schristos m != this->memory_regions_->end();
329675fd0b74Schristos ++m)
329775fd0b74Schristos if ((*m)->name_match(name, namelen))
329875fd0b74Schristos return *m;
329975fd0b74Schristos
330075fd0b74Schristos return NULL;
330175fd0b74Schristos }
330275fd0b74Schristos
330375fd0b74Schristos // Find a memory region's origin.
330475fd0b74Schristos
330575fd0b74Schristos Expression*
find_memory_region_origin(const char * name,size_t namelen)330675fd0b74Schristos Script_sections::find_memory_region_origin(const char* name, size_t namelen)
330775fd0b74Schristos {
330875fd0b74Schristos Memory_region* mr = find_memory_region(name, namelen);
330975fd0b74Schristos if (mr == NULL)
331075fd0b74Schristos return NULL;
331175fd0b74Schristos
331275fd0b74Schristos return mr->start_address();
331375fd0b74Schristos }
331475fd0b74Schristos
331575fd0b74Schristos // Find a memory region's length.
331675fd0b74Schristos
331775fd0b74Schristos Expression*
find_memory_region_length(const char * name,size_t namelen)331875fd0b74Schristos Script_sections::find_memory_region_length(const char* name, size_t namelen)
331975fd0b74Schristos {
332075fd0b74Schristos Memory_region* mr = find_memory_region(name, namelen);
332175fd0b74Schristos if (mr == NULL)
332275fd0b74Schristos return NULL;
332375fd0b74Schristos
332475fd0b74Schristos return mr->length();
332575fd0b74Schristos }
332675fd0b74Schristos
332775fd0b74Schristos // Set the memory region to use for the current section.
332875fd0b74Schristos
332975fd0b74Schristos void
set_memory_region(Memory_region * mr,bool set_vma)333075fd0b74Schristos Script_sections::set_memory_region(Memory_region* mr, bool set_vma)
333175fd0b74Schristos {
333275fd0b74Schristos gold_assert(!this->sections_elements_->empty());
333375fd0b74Schristos this->sections_elements_->back()->set_memory_region(mr, set_vma);
333475fd0b74Schristos }
333575fd0b74Schristos
333675fd0b74Schristos // Class Script_sections.
333775fd0b74Schristos
Script_sections()333875fd0b74Schristos Script_sections::Script_sections()
333975fd0b74Schristos : saw_sections_clause_(false),
334075fd0b74Schristos in_sections_clause_(false),
334175fd0b74Schristos sections_elements_(NULL),
334275fd0b74Schristos output_section_(NULL),
334375fd0b74Schristos memory_regions_(NULL),
334475fd0b74Schristos phdrs_elements_(NULL),
334575fd0b74Schristos orphan_section_placement_(NULL),
334675fd0b74Schristos data_segment_align_start_(),
334775fd0b74Schristos saw_data_segment_align_(false),
334875fd0b74Schristos saw_relro_end_(false),
334975fd0b74Schristos saw_segment_start_expression_(false),
335075fd0b74Schristos segments_created_(false)
335175fd0b74Schristos {
335275fd0b74Schristos }
335375fd0b74Schristos
335475fd0b74Schristos // Start a SECTIONS clause.
335575fd0b74Schristos
335675fd0b74Schristos void
start_sections()335775fd0b74Schristos Script_sections::start_sections()
335875fd0b74Schristos {
335975fd0b74Schristos gold_assert(!this->in_sections_clause_ && this->output_section_ == NULL);
336075fd0b74Schristos this->saw_sections_clause_ = true;
336175fd0b74Schristos this->in_sections_clause_ = true;
336275fd0b74Schristos if (this->sections_elements_ == NULL)
336375fd0b74Schristos this->sections_elements_ = new Sections_elements;
336475fd0b74Schristos }
336575fd0b74Schristos
336675fd0b74Schristos // Finish a SECTIONS clause.
336775fd0b74Schristos
336875fd0b74Schristos void
finish_sections()336975fd0b74Schristos Script_sections::finish_sections()
337075fd0b74Schristos {
337175fd0b74Schristos gold_assert(this->in_sections_clause_ && this->output_section_ == NULL);
337275fd0b74Schristos this->in_sections_clause_ = false;
337375fd0b74Schristos }
337475fd0b74Schristos
337575fd0b74Schristos // Add a symbol to be defined.
337675fd0b74Schristos
337775fd0b74Schristos void
add_symbol_assignment(const char * name,size_t length,Expression * val,bool provide,bool hidden)337875fd0b74Schristos Script_sections::add_symbol_assignment(const char* name, size_t length,
337975fd0b74Schristos Expression* val, bool provide,
338075fd0b74Schristos bool hidden)
338175fd0b74Schristos {
338275fd0b74Schristos if (this->output_section_ != NULL)
338375fd0b74Schristos this->output_section_->add_symbol_assignment(name, length, val,
338475fd0b74Schristos provide, hidden);
338575fd0b74Schristos else
338675fd0b74Schristos {
338775fd0b74Schristos Sections_element* p = new Sections_element_assignment(name, length,
338875fd0b74Schristos val, provide,
338975fd0b74Schristos hidden);
339075fd0b74Schristos this->sections_elements_->push_back(p);
339175fd0b74Schristos }
339275fd0b74Schristos }
339375fd0b74Schristos
339475fd0b74Schristos // Add an assignment to the special dot symbol.
339575fd0b74Schristos
339675fd0b74Schristos void
add_dot_assignment(Expression * val)339775fd0b74Schristos Script_sections::add_dot_assignment(Expression* val)
339875fd0b74Schristos {
339975fd0b74Schristos if (this->output_section_ != NULL)
340075fd0b74Schristos this->output_section_->add_dot_assignment(val);
340175fd0b74Schristos else
340275fd0b74Schristos {
340375fd0b74Schristos // The GNU linker permits assignments to . to appears outside of
340475fd0b74Schristos // a SECTIONS clause, and treats it as appearing inside, so
340575fd0b74Schristos // sections_elements_ may be NULL here.
340675fd0b74Schristos if (this->sections_elements_ == NULL)
340775fd0b74Schristos {
340875fd0b74Schristos this->sections_elements_ = new Sections_elements;
340975fd0b74Schristos this->saw_sections_clause_ = true;
341075fd0b74Schristos }
341175fd0b74Schristos
341275fd0b74Schristos Sections_element* p = new Sections_element_dot_assignment(val);
341375fd0b74Schristos this->sections_elements_->push_back(p);
341475fd0b74Schristos }
341575fd0b74Schristos }
341675fd0b74Schristos
341775fd0b74Schristos // Add an assertion.
341875fd0b74Schristos
341975fd0b74Schristos void
add_assertion(Expression * check,const char * message,size_t messagelen)342075fd0b74Schristos Script_sections::add_assertion(Expression* check, const char* message,
342175fd0b74Schristos size_t messagelen)
342275fd0b74Schristos {
342375fd0b74Schristos if (this->output_section_ != NULL)
342475fd0b74Schristos this->output_section_->add_assertion(check, message, messagelen);
342575fd0b74Schristos else
342675fd0b74Schristos {
342775fd0b74Schristos Sections_element* p = new Sections_element_assertion(check, message,
342875fd0b74Schristos messagelen);
342975fd0b74Schristos this->sections_elements_->push_back(p);
343075fd0b74Schristos }
343175fd0b74Schristos }
343275fd0b74Schristos
343375fd0b74Schristos // Start processing entries for an output section.
343475fd0b74Schristos
343575fd0b74Schristos void
start_output_section(const char * name,size_t namelen,const Parser_output_section_header * header)343675fd0b74Schristos Script_sections::start_output_section(
343775fd0b74Schristos const char* name,
343875fd0b74Schristos size_t namelen,
343975fd0b74Schristos const Parser_output_section_header* header)
344075fd0b74Schristos {
344175fd0b74Schristos Output_section_definition* posd = new Output_section_definition(name,
344275fd0b74Schristos namelen,
344375fd0b74Schristos header);
344475fd0b74Schristos this->sections_elements_->push_back(posd);
344575fd0b74Schristos gold_assert(this->output_section_ == NULL);
344675fd0b74Schristos this->output_section_ = posd;
344775fd0b74Schristos }
344875fd0b74Schristos
344975fd0b74Schristos // Stop processing entries for an output section.
345075fd0b74Schristos
345175fd0b74Schristos void
finish_output_section(const Parser_output_section_trailer * trailer)345275fd0b74Schristos Script_sections::finish_output_section(
345375fd0b74Schristos const Parser_output_section_trailer* trailer)
345475fd0b74Schristos {
345575fd0b74Schristos gold_assert(this->output_section_ != NULL);
345675fd0b74Schristos this->output_section_->finish(trailer);
345775fd0b74Schristos this->output_section_ = NULL;
345875fd0b74Schristos }
345975fd0b74Schristos
346075fd0b74Schristos // Add a data item to the current output section.
346175fd0b74Schristos
346275fd0b74Schristos void
add_data(int size,bool is_signed,Expression * val)346375fd0b74Schristos Script_sections::add_data(int size, bool is_signed, Expression* val)
346475fd0b74Schristos {
346575fd0b74Schristos gold_assert(this->output_section_ != NULL);
346675fd0b74Schristos this->output_section_->add_data(size, is_signed, val);
346775fd0b74Schristos }
346875fd0b74Schristos
346975fd0b74Schristos // Add a fill value setting to the current output section.
347075fd0b74Schristos
347175fd0b74Schristos void
add_fill(Expression * val)347275fd0b74Schristos Script_sections::add_fill(Expression* val)
347375fd0b74Schristos {
347475fd0b74Schristos gold_assert(this->output_section_ != NULL);
347575fd0b74Schristos this->output_section_->add_fill(val);
347675fd0b74Schristos }
347775fd0b74Schristos
347875fd0b74Schristos // Add an input section specification to the current output section.
347975fd0b74Schristos
348075fd0b74Schristos void
add_input_section(const Input_section_spec * spec,bool keep)348175fd0b74Schristos Script_sections::add_input_section(const Input_section_spec* spec, bool keep)
348275fd0b74Schristos {
348375fd0b74Schristos gold_assert(this->output_section_ != NULL);
348475fd0b74Schristos this->output_section_->add_input_section(spec, keep);
348575fd0b74Schristos }
348675fd0b74Schristos
348775fd0b74Schristos // This is called when we see DATA_SEGMENT_ALIGN. It means that any
348875fd0b74Schristos // subsequent output sections may be relro.
348975fd0b74Schristos
349075fd0b74Schristos void
data_segment_align()349175fd0b74Schristos Script_sections::data_segment_align()
349275fd0b74Schristos {
349375fd0b74Schristos if (this->saw_data_segment_align_)
349475fd0b74Schristos gold_error(_("DATA_SEGMENT_ALIGN may only appear once in a linker script"));
349575fd0b74Schristos gold_assert(!this->sections_elements_->empty());
349675fd0b74Schristos Sections_elements::iterator p = this->sections_elements_->end();
349775fd0b74Schristos --p;
349875fd0b74Schristos this->data_segment_align_start_ = p;
349975fd0b74Schristos this->saw_data_segment_align_ = true;
350075fd0b74Schristos }
350175fd0b74Schristos
350275fd0b74Schristos // This is called when we see DATA_SEGMENT_RELRO_END. It means that
350375fd0b74Schristos // any output sections seen since DATA_SEGMENT_ALIGN are relro.
350475fd0b74Schristos
350575fd0b74Schristos void
data_segment_relro_end()350675fd0b74Schristos Script_sections::data_segment_relro_end()
350775fd0b74Schristos {
350875fd0b74Schristos if (this->saw_relro_end_)
350975fd0b74Schristos gold_error(_("DATA_SEGMENT_RELRO_END may only appear once "
351075fd0b74Schristos "in a linker script"));
351175fd0b74Schristos this->saw_relro_end_ = true;
351275fd0b74Schristos
351375fd0b74Schristos if (!this->saw_data_segment_align_)
351475fd0b74Schristos gold_error(_("DATA_SEGMENT_RELRO_END must follow DATA_SEGMENT_ALIGN"));
351575fd0b74Schristos else
351675fd0b74Schristos {
351775fd0b74Schristos Sections_elements::iterator p = this->data_segment_align_start_;
351875fd0b74Schristos for (++p; p != this->sections_elements_->end(); ++p)
351975fd0b74Schristos (*p)->set_is_relro();
352075fd0b74Schristos }
352175fd0b74Schristos }
352275fd0b74Schristos
352375fd0b74Schristos // Create any required sections.
352475fd0b74Schristos
352575fd0b74Schristos void
create_sections(Layout * layout)352675fd0b74Schristos Script_sections::create_sections(Layout* layout)
352775fd0b74Schristos {
352875fd0b74Schristos if (!this->saw_sections_clause_)
352975fd0b74Schristos return;
353075fd0b74Schristos for (Sections_elements::iterator p = this->sections_elements_->begin();
353175fd0b74Schristos p != this->sections_elements_->end();
353275fd0b74Schristos ++p)
353375fd0b74Schristos (*p)->create_sections(layout);
353475fd0b74Schristos }
353575fd0b74Schristos
353675fd0b74Schristos // Add any symbols we are defining to the symbol table.
353775fd0b74Schristos
353875fd0b74Schristos void
add_symbols_to_table(Symbol_table * symtab)353975fd0b74Schristos Script_sections::add_symbols_to_table(Symbol_table* symtab)
354075fd0b74Schristos {
354175fd0b74Schristos if (!this->saw_sections_clause_)
354275fd0b74Schristos return;
354375fd0b74Schristos for (Sections_elements::iterator p = this->sections_elements_->begin();
354475fd0b74Schristos p != this->sections_elements_->end();
354575fd0b74Schristos ++p)
354675fd0b74Schristos (*p)->add_symbols_to_table(symtab);
354775fd0b74Schristos }
354875fd0b74Schristos
354975fd0b74Schristos // Finalize symbols and check assertions.
355075fd0b74Schristos
355175fd0b74Schristos void
finalize_symbols(Symbol_table * symtab,const Layout * layout)355275fd0b74Schristos Script_sections::finalize_symbols(Symbol_table* symtab, const Layout* layout)
355375fd0b74Schristos {
355475fd0b74Schristos if (!this->saw_sections_clause_)
355575fd0b74Schristos return;
355675fd0b74Schristos uint64_t dot_value = 0;
355775fd0b74Schristos for (Sections_elements::iterator p = this->sections_elements_->begin();
355875fd0b74Schristos p != this->sections_elements_->end();
355975fd0b74Schristos ++p)
356075fd0b74Schristos (*p)->finalize_symbols(symtab, layout, &dot_value);
356175fd0b74Schristos }
356275fd0b74Schristos
356375fd0b74Schristos // Return the name of the output section to use for an input file name
356475fd0b74Schristos // and section name.
356575fd0b74Schristos
356675fd0b74Schristos const char*
output_section_name(const char * file_name,const char * section_name,Output_section *** output_section_slot,Script_sections::Section_type * psection_type,bool * keep,bool is_input_section)356775fd0b74Schristos Script_sections::output_section_name(
356875fd0b74Schristos const char* file_name,
356975fd0b74Schristos const char* section_name,
357075fd0b74Schristos Output_section*** output_section_slot,
357175fd0b74Schristos Script_sections::Section_type* psection_type,
3572ede78133Schristos bool* keep,
3573ede78133Schristos bool is_input_section)
357475fd0b74Schristos {
357575fd0b74Schristos for (Sections_elements::const_iterator p = this->sections_elements_->begin();
357675fd0b74Schristos p != this->sections_elements_->end();
357775fd0b74Schristos ++p)
357875fd0b74Schristos {
357975fd0b74Schristos const char* ret = (*p)->output_section_name(file_name, section_name,
358075fd0b74Schristos output_section_slot,
3581ede78133Schristos psection_type, keep,
3582ede78133Schristos is_input_section);
358375fd0b74Schristos
358475fd0b74Schristos if (ret != NULL)
358575fd0b74Schristos {
358675fd0b74Schristos // The special name /DISCARD/ means that the input section
358775fd0b74Schristos // should be discarded.
358875fd0b74Schristos if (strcmp(ret, "/DISCARD/") == 0)
358975fd0b74Schristos {
359075fd0b74Schristos *output_section_slot = NULL;
359175fd0b74Schristos *psection_type = Script_sections::ST_NONE;
359275fd0b74Schristos return NULL;
359375fd0b74Schristos }
359475fd0b74Schristos return ret;
359575fd0b74Schristos }
359675fd0b74Schristos }
359775fd0b74Schristos
3598ede78133Schristos // We have an orphan section.
359975fd0b74Schristos *output_section_slot = NULL;
360075fd0b74Schristos *psection_type = Script_sections::ST_NONE;
3601ede78133Schristos *keep = false;
360275fd0b74Schristos
3603ede78133Schristos General_options::Orphan_handling orphan_handling =
3604ede78133Schristos parameters->options().orphan_handling_enum();
3605ede78133Schristos if (orphan_handling == General_options::ORPHAN_DISCARD)
3606ede78133Schristos return NULL;
3607ede78133Schristos if (orphan_handling == General_options::ORPHAN_ERROR)
3608ede78133Schristos {
3609ede78133Schristos if (file_name == NULL)
3610ede78133Schristos gold_error(_("unplaced orphan section '%s'"), section_name);
3611ede78133Schristos else
3612ede78133Schristos gold_error(_("unplaced orphan section '%s' from '%s'"),
3613ede78133Schristos section_name, file_name);
3614ede78133Schristos return NULL;
3615ede78133Schristos }
3616ede78133Schristos if (orphan_handling == General_options::ORPHAN_WARN)
3617ede78133Schristos {
3618ede78133Schristos if (file_name == NULL)
3619ede78133Schristos gold_warning(_("orphan section '%s' is being placed in section '%s'"),
3620ede78133Schristos section_name, section_name);
3621ede78133Schristos else
3622ede78133Schristos gold_warning(_("orphan section '%s' from '%s' is being placed "
3623ede78133Schristos "in section '%s'"),
3624ede78133Schristos section_name, file_name, section_name);
3625ede78133Schristos }
3626ede78133Schristos
3627ede78133Schristos // If we couldn't find a mapping for the name, the output section
3628ede78133Schristos // gets the name of the input section.
362975fd0b74Schristos return section_name;
363075fd0b74Schristos }
363175fd0b74Schristos
363275fd0b74Schristos // Place a marker for an orphan output section into the SECTIONS
363375fd0b74Schristos // clause.
363475fd0b74Schristos
363575fd0b74Schristos void
place_orphan(Output_section * os)363675fd0b74Schristos Script_sections::place_orphan(Output_section* os)
363775fd0b74Schristos {
363875fd0b74Schristos Orphan_section_placement* osp = this->orphan_section_placement_;
363975fd0b74Schristos if (osp == NULL)
364075fd0b74Schristos {
364175fd0b74Schristos // Initialize the Orphan_section_placement structure.
364275fd0b74Schristos osp = new Orphan_section_placement();
364375fd0b74Schristos for (Sections_elements::iterator p = this->sections_elements_->begin();
364475fd0b74Schristos p != this->sections_elements_->end();
364575fd0b74Schristos ++p)
364675fd0b74Schristos (*p)->orphan_section_init(osp, p);
364775fd0b74Schristos gold_assert(!this->sections_elements_->empty());
364875fd0b74Schristos Sections_elements::iterator last = this->sections_elements_->end();
364975fd0b74Schristos --last;
365075fd0b74Schristos osp->last_init(last);
365175fd0b74Schristos this->orphan_section_placement_ = osp;
365275fd0b74Schristos }
365375fd0b74Schristos
365475fd0b74Schristos Orphan_output_section* orphan = new Orphan_output_section(os);
365575fd0b74Schristos
365675fd0b74Schristos // Look for where to put ORPHAN.
365775fd0b74Schristos Sections_elements::iterator* where;
365875fd0b74Schristos if (osp->find_place(os, &where))
365975fd0b74Schristos {
366075fd0b74Schristos if ((**where)->is_relro())
366175fd0b74Schristos os->set_is_relro();
366275fd0b74Schristos else
366375fd0b74Schristos os->clear_is_relro();
366475fd0b74Schristos
366575fd0b74Schristos // We want to insert ORPHAN after *WHERE, and then update *WHERE
366675fd0b74Schristos // so that the next one goes after this one.
366775fd0b74Schristos Sections_elements::iterator p = *where;
366875fd0b74Schristos gold_assert(p != this->sections_elements_->end());
366975fd0b74Schristos ++p;
367075fd0b74Schristos *where = this->sections_elements_->insert(p, orphan);
367175fd0b74Schristos }
367275fd0b74Schristos else
367375fd0b74Schristos {
367475fd0b74Schristos os->clear_is_relro();
367575fd0b74Schristos // We don't have a place to put this orphan section. Put it,
367675fd0b74Schristos // and all other sections like it, at the end, but before the
367775fd0b74Schristos // sections which always come at the end.
367875fd0b74Schristos Sections_elements::iterator last = osp->last_place();
367975fd0b74Schristos *where = this->sections_elements_->insert(last, orphan);
368075fd0b74Schristos }
3681ede78133Schristos
3682ede78133Schristos if ((os->flags() & elfcpp::SHF_ALLOC) != 0)
3683ede78133Schristos osp->update_last_alloc(*where);
368475fd0b74Schristos }
368575fd0b74Schristos
368675fd0b74Schristos // Set the addresses of all the output sections. Walk through all the
368775fd0b74Schristos // elements, tracking the dot symbol. Apply assignments which set
368875fd0b74Schristos // absolute symbol values, in case they are used when setting dot.
368975fd0b74Schristos // Fill in data statement values. As we find output sections, set the
369075fd0b74Schristos // address, set the address of all associated input sections, and
369175fd0b74Schristos // update dot. Return the segment which should hold the file header
369275fd0b74Schristos // and segment headers, if any.
369375fd0b74Schristos
369475fd0b74Schristos Output_segment*
set_section_addresses(Symbol_table * symtab,Layout * layout)369575fd0b74Schristos Script_sections::set_section_addresses(Symbol_table* symtab, Layout* layout)
369675fd0b74Schristos {
369775fd0b74Schristos gold_assert(this->saw_sections_clause_);
369875fd0b74Schristos
369975fd0b74Schristos // Implement ONLY_IF_RO/ONLY_IF_RW constraints. These are a pain
370075fd0b74Schristos // for our representation.
370175fd0b74Schristos for (Sections_elements::iterator p = this->sections_elements_->begin();
370275fd0b74Schristos p != this->sections_elements_->end();
370375fd0b74Schristos ++p)
370475fd0b74Schristos {
370575fd0b74Schristos Output_section_definition* posd;
370675fd0b74Schristos Section_constraint failed_constraint = (*p)->check_constraint(&posd);
370775fd0b74Schristos if (failed_constraint != CONSTRAINT_NONE)
370875fd0b74Schristos {
370975fd0b74Schristos Sections_elements::iterator q;
371075fd0b74Schristos for (q = this->sections_elements_->begin();
371175fd0b74Schristos q != this->sections_elements_->end();
371275fd0b74Schristos ++q)
371375fd0b74Schristos {
371475fd0b74Schristos if (q != p)
371575fd0b74Schristos {
371675fd0b74Schristos if ((*q)->alternate_constraint(posd, failed_constraint))
371775fd0b74Schristos break;
371875fd0b74Schristos }
371975fd0b74Schristos }
372075fd0b74Schristos
372175fd0b74Schristos if (q == this->sections_elements_->end())
372275fd0b74Schristos gold_error(_("no matching section constraint"));
372375fd0b74Schristos }
372475fd0b74Schristos }
372575fd0b74Schristos
372675fd0b74Schristos // Force the alignment of the first TLS section to be the maximum
372775fd0b74Schristos // alignment of all TLS sections.
372875fd0b74Schristos Output_section* first_tls = NULL;
372975fd0b74Schristos uint64_t tls_align = 0;
373075fd0b74Schristos for (Sections_elements::const_iterator p = this->sections_elements_->begin();
373175fd0b74Schristos p != this->sections_elements_->end();
373275fd0b74Schristos ++p)
373375fd0b74Schristos {
373475fd0b74Schristos Output_section* os = (*p)->get_output_section();
373575fd0b74Schristos if (os != NULL && (os->flags() & elfcpp::SHF_TLS) != 0)
373675fd0b74Schristos {
373775fd0b74Schristos if (first_tls == NULL)
373875fd0b74Schristos first_tls = os;
373975fd0b74Schristos if (os->addralign() > tls_align)
374075fd0b74Schristos tls_align = os->addralign();
374175fd0b74Schristos }
374275fd0b74Schristos }
374375fd0b74Schristos if (first_tls != NULL)
374475fd0b74Schristos first_tls->set_addralign(tls_align);
374575fd0b74Schristos
374675fd0b74Schristos // For a relocatable link, we implicitly set dot to zero.
374775fd0b74Schristos uint64_t dot_value = 0;
374875fd0b74Schristos uint64_t dot_alignment = 0;
374975fd0b74Schristos uint64_t load_address = 0;
375075fd0b74Schristos
375175fd0b74Schristos // Check to see if we want to use any of -Ttext, -Tdata and -Tbss options
375275fd0b74Schristos // to set section addresses. If the script has any SEGMENT_START
375375fd0b74Schristos // expression, we do not set the section addresses.
375475fd0b74Schristos bool use_tsection_options =
375575fd0b74Schristos (!this->saw_segment_start_expression_
375675fd0b74Schristos && (parameters->options().user_set_Ttext()
375775fd0b74Schristos || parameters->options().user_set_Tdata()
375875fd0b74Schristos || parameters->options().user_set_Tbss()));
375975fd0b74Schristos
376075fd0b74Schristos for (Sections_elements::iterator p = this->sections_elements_->begin();
376175fd0b74Schristos p != this->sections_elements_->end();
376275fd0b74Schristos ++p)
376375fd0b74Schristos {
376475fd0b74Schristos Output_section* os = (*p)->get_output_section();
376575fd0b74Schristos
376675fd0b74Schristos // Handle -Ttext, -Tdata and -Tbss options. We do this by looking for
376775fd0b74Schristos // the special sections by names and doing dot assignments.
376875fd0b74Schristos if (use_tsection_options
376975fd0b74Schristos && os != NULL
377075fd0b74Schristos && (os->flags() & elfcpp::SHF_ALLOC) != 0)
377175fd0b74Schristos {
377275fd0b74Schristos uint64_t new_dot_value = dot_value;
377375fd0b74Schristos
377475fd0b74Schristos if (parameters->options().user_set_Ttext()
377575fd0b74Schristos && strcmp(os->name(), ".text") == 0)
377675fd0b74Schristos new_dot_value = parameters->options().Ttext();
377775fd0b74Schristos else if (parameters->options().user_set_Tdata()
377875fd0b74Schristos && strcmp(os->name(), ".data") == 0)
377975fd0b74Schristos new_dot_value = parameters->options().Tdata();
378075fd0b74Schristos else if (parameters->options().user_set_Tbss()
378175fd0b74Schristos && strcmp(os->name(), ".bss") == 0)
378275fd0b74Schristos new_dot_value = parameters->options().Tbss();
378375fd0b74Schristos
378475fd0b74Schristos // Update dot and load address if necessary.
378575fd0b74Schristos if (new_dot_value < dot_value)
378675fd0b74Schristos gold_error(_("dot may not move backward"));
378775fd0b74Schristos else if (new_dot_value != dot_value)
378875fd0b74Schristos {
378975fd0b74Schristos dot_value = new_dot_value;
379075fd0b74Schristos load_address = new_dot_value;
379175fd0b74Schristos }
379275fd0b74Schristos }
379375fd0b74Schristos
379475fd0b74Schristos (*p)->set_section_addresses(symtab, layout, &dot_value, &dot_alignment,
379575fd0b74Schristos &load_address);
379675fd0b74Schristos }
379775fd0b74Schristos
379875fd0b74Schristos if (this->phdrs_elements_ != NULL)
379975fd0b74Schristos {
380075fd0b74Schristos for (Phdrs_elements::iterator p = this->phdrs_elements_->begin();
380175fd0b74Schristos p != this->phdrs_elements_->end();
380275fd0b74Schristos ++p)
380375fd0b74Schristos (*p)->eval_load_address(symtab, layout);
380475fd0b74Schristos }
380575fd0b74Schristos
380675fd0b74Schristos return this->create_segments(layout, dot_alignment);
380775fd0b74Schristos }
380875fd0b74Schristos
380975fd0b74Schristos // Sort the sections in order to put them into segments.
381075fd0b74Schristos
381175fd0b74Schristos class Sort_output_sections
381275fd0b74Schristos {
381375fd0b74Schristos public:
Sort_output_sections(const Script_sections::Sections_elements * elements)381475fd0b74Schristos Sort_output_sections(const Script_sections::Sections_elements* elements)
381575fd0b74Schristos : elements_(elements)
381675fd0b74Schristos { }
381775fd0b74Schristos
381875fd0b74Schristos bool
381975fd0b74Schristos operator()(const Output_section* os1, const Output_section* os2) const;
382075fd0b74Schristos
382175fd0b74Schristos private:
382275fd0b74Schristos int
382375fd0b74Schristos script_compare(const Output_section* os1, const Output_section* os2) const;
382475fd0b74Schristos
382575fd0b74Schristos private:
382675fd0b74Schristos const Script_sections::Sections_elements* elements_;
382775fd0b74Schristos };
382875fd0b74Schristos
382975fd0b74Schristos bool
operator ()(const Output_section * os1,const Output_section * os2) const383075fd0b74Schristos Sort_output_sections::operator()(const Output_section* os1,
383175fd0b74Schristos const Output_section* os2) const
383275fd0b74Schristos {
383375fd0b74Schristos // Sort first by the load address.
383475fd0b74Schristos uint64_t lma1 = (os1->has_load_address()
383575fd0b74Schristos ? os1->load_address()
383675fd0b74Schristos : os1->address());
383775fd0b74Schristos uint64_t lma2 = (os2->has_load_address()
383875fd0b74Schristos ? os2->load_address()
383975fd0b74Schristos : os2->address());
384075fd0b74Schristos if (lma1 != lma2)
384175fd0b74Schristos return lma1 < lma2;
384275fd0b74Schristos
384375fd0b74Schristos // Then sort by the virtual address.
384475fd0b74Schristos if (os1->address() != os2->address())
384575fd0b74Schristos return os1->address() < os2->address();
384675fd0b74Schristos
384775fd0b74Schristos // If the linker script says which of these sections is first, go
384875fd0b74Schristos // with what it says.
384975fd0b74Schristos int i = this->script_compare(os1, os2);
385075fd0b74Schristos if (i != 0)
385175fd0b74Schristos return i < 0;
385275fd0b74Schristos
385375fd0b74Schristos // Sort PROGBITS before NOBITS.
385475fd0b74Schristos bool nobits1 = os1->type() == elfcpp::SHT_NOBITS;
385575fd0b74Schristos bool nobits2 = os2->type() == elfcpp::SHT_NOBITS;
385675fd0b74Schristos if (nobits1 != nobits2)
385775fd0b74Schristos return nobits2;
385875fd0b74Schristos
385975fd0b74Schristos // Sort PROGBITS TLS sections to the end, NOBITS TLS sections to the
386075fd0b74Schristos // beginning.
386175fd0b74Schristos bool tls1 = (os1->flags() & elfcpp::SHF_TLS) != 0;
386275fd0b74Schristos bool tls2 = (os2->flags() & elfcpp::SHF_TLS) != 0;
386375fd0b74Schristos if (tls1 != tls2)
386475fd0b74Schristos return nobits1 ? tls1 : tls2;
386575fd0b74Schristos
386675fd0b74Schristos // Sort non-NOLOAD before NOLOAD.
386775fd0b74Schristos if (os1->is_noload() && !os2->is_noload())
386875fd0b74Schristos return true;
386975fd0b74Schristos if (!os1->is_noload() && os2->is_noload())
387075fd0b74Schristos return true;
387175fd0b74Schristos
387275fd0b74Schristos // The sections seem practically identical. Sort by name to get a
387375fd0b74Schristos // stable sort.
387475fd0b74Schristos return os1->name() < os2->name();
387575fd0b74Schristos }
387675fd0b74Schristos
387775fd0b74Schristos // Return -1 if OS1 comes before OS2 in ELEMENTS_, 1 if comes after, 0
387875fd0b74Schristos // if either OS1 or OS2 is not mentioned. This ensures that we keep
387975fd0b74Schristos // empty sections in the order in which they appear in a linker
388075fd0b74Schristos // script.
388175fd0b74Schristos
388275fd0b74Schristos int
script_compare(const Output_section * os1,const Output_section * os2) const388375fd0b74Schristos Sort_output_sections::script_compare(const Output_section* os1,
388475fd0b74Schristos const Output_section* os2) const
388575fd0b74Schristos {
388675fd0b74Schristos if (this->elements_ == NULL)
388775fd0b74Schristos return 0;
388875fd0b74Schristos
388975fd0b74Schristos bool found_os1 = false;
389075fd0b74Schristos bool found_os2 = false;
389175fd0b74Schristos for (Script_sections::Sections_elements::const_iterator
389275fd0b74Schristos p = this->elements_->begin();
389375fd0b74Schristos p != this->elements_->end();
389475fd0b74Schristos ++p)
389575fd0b74Schristos {
389675fd0b74Schristos if (os2 == (*p)->get_output_section())
389775fd0b74Schristos {
389875fd0b74Schristos if (found_os1)
389975fd0b74Schristos return -1;
390075fd0b74Schristos found_os2 = true;
390175fd0b74Schristos }
390275fd0b74Schristos else if (os1 == (*p)->get_output_section())
390375fd0b74Schristos {
390475fd0b74Schristos if (found_os2)
390575fd0b74Schristos return 1;
390675fd0b74Schristos found_os1 = true;
390775fd0b74Schristos }
390875fd0b74Schristos }
390975fd0b74Schristos
391075fd0b74Schristos return 0;
391175fd0b74Schristos }
391275fd0b74Schristos
391375fd0b74Schristos // Return whether OS is a BSS section. This is a SHT_NOBITS section.
391475fd0b74Schristos // We treat a section with the SHF_TLS flag set as taking up space
391575fd0b74Schristos // even if it is SHT_NOBITS (this is true of .tbss), as we allocate
391675fd0b74Schristos // space for them in the file.
391775fd0b74Schristos
391875fd0b74Schristos bool
is_bss_section(const Output_section * os)391975fd0b74Schristos Script_sections::is_bss_section(const Output_section* os)
392075fd0b74Schristos {
392175fd0b74Schristos return (os->type() == elfcpp::SHT_NOBITS
392275fd0b74Schristos && (os->flags() & elfcpp::SHF_TLS) == 0);
392375fd0b74Schristos }
392475fd0b74Schristos
392575fd0b74Schristos // Return the size taken by the file header and the program headers.
392675fd0b74Schristos
392775fd0b74Schristos size_t
total_header_size(Layout * layout) const392875fd0b74Schristos Script_sections::total_header_size(Layout* layout) const
392975fd0b74Schristos {
393075fd0b74Schristos size_t segment_count = layout->segment_count();
393175fd0b74Schristos size_t file_header_size;
393275fd0b74Schristos size_t segment_headers_size;
393375fd0b74Schristos if (parameters->target().get_size() == 32)
393475fd0b74Schristos {
393575fd0b74Schristos file_header_size = elfcpp::Elf_sizes<32>::ehdr_size;
393675fd0b74Schristos segment_headers_size = segment_count * elfcpp::Elf_sizes<32>::phdr_size;
393775fd0b74Schristos }
393875fd0b74Schristos else if (parameters->target().get_size() == 64)
393975fd0b74Schristos {
394075fd0b74Schristos file_header_size = elfcpp::Elf_sizes<64>::ehdr_size;
394175fd0b74Schristos segment_headers_size = segment_count * elfcpp::Elf_sizes<64>::phdr_size;
394275fd0b74Schristos }
394375fd0b74Schristos else
394475fd0b74Schristos gold_unreachable();
394575fd0b74Schristos
394675fd0b74Schristos return file_header_size + segment_headers_size;
394775fd0b74Schristos }
394875fd0b74Schristos
394975fd0b74Schristos // Return the amount we have to subtract from the LMA to accommodate
395075fd0b74Schristos // headers of the given size. The complication is that the file
395175fd0b74Schristos // header have to be at the start of a page, as otherwise it will not
395275fd0b74Schristos // be at the start of the file.
395375fd0b74Schristos
395475fd0b74Schristos uint64_t
header_size_adjustment(uint64_t lma,size_t sizeof_headers) const395575fd0b74Schristos Script_sections::header_size_adjustment(uint64_t lma,
395675fd0b74Schristos size_t sizeof_headers) const
395775fd0b74Schristos {
395875fd0b74Schristos const uint64_t abi_pagesize = parameters->target().abi_pagesize();
395975fd0b74Schristos uint64_t hdr_lma = lma - sizeof_headers;
396075fd0b74Schristos hdr_lma &= ~(abi_pagesize - 1);
396175fd0b74Schristos return lma - hdr_lma;
396275fd0b74Schristos }
396375fd0b74Schristos
396475fd0b74Schristos // Create the PT_LOAD segments when using a SECTIONS clause. Returns
396575fd0b74Schristos // the segment which should hold the file header and segment headers,
396675fd0b74Schristos // if any.
396775fd0b74Schristos
396875fd0b74Schristos Output_segment*
create_segments(Layout * layout,uint64_t dot_alignment)396975fd0b74Schristos Script_sections::create_segments(Layout* layout, uint64_t dot_alignment)
397075fd0b74Schristos {
397175fd0b74Schristos gold_assert(this->saw_sections_clause_);
397275fd0b74Schristos
397375fd0b74Schristos if (parameters->options().relocatable())
397475fd0b74Schristos return NULL;
397575fd0b74Schristos
397675fd0b74Schristos if (this->saw_phdrs_clause())
397775fd0b74Schristos return create_segments_from_phdrs_clause(layout, dot_alignment);
397875fd0b74Schristos
397975fd0b74Schristos Layout::Section_list sections;
398075fd0b74Schristos layout->get_allocated_sections(§ions);
398175fd0b74Schristos
398275fd0b74Schristos // Sort the sections by address.
398375fd0b74Schristos std::stable_sort(sections.begin(), sections.end(),
398475fd0b74Schristos Sort_output_sections(this->sections_elements_));
398575fd0b74Schristos
398675fd0b74Schristos this->create_note_and_tls_segments(layout, §ions);
398775fd0b74Schristos
398875fd0b74Schristos // Walk through the sections adding them to PT_LOAD segments.
398975fd0b74Schristos const uint64_t abi_pagesize = parameters->target().abi_pagesize();
399075fd0b74Schristos Output_segment* first_seg = NULL;
399175fd0b74Schristos Output_segment* current_seg = NULL;
399275fd0b74Schristos bool is_current_seg_readonly = true;
399375fd0b74Schristos uint64_t last_vma = 0;
399475fd0b74Schristos uint64_t last_lma = 0;
399575fd0b74Schristos uint64_t last_size = 0;
3996ede78133Schristos bool in_bss = false;
399775fd0b74Schristos for (Layout::Section_list::iterator p = sections.begin();
399875fd0b74Schristos p != sections.end();
399975fd0b74Schristos ++p)
400075fd0b74Schristos {
400175fd0b74Schristos const uint64_t vma = (*p)->address();
400275fd0b74Schristos const uint64_t lma = ((*p)->has_load_address()
400375fd0b74Schristos ? (*p)->load_address()
400475fd0b74Schristos : vma);
400575fd0b74Schristos const uint64_t size = (*p)->current_data_size();
400675fd0b74Schristos
400775fd0b74Schristos bool need_new_segment;
400875fd0b74Schristos if (current_seg == NULL)
400975fd0b74Schristos need_new_segment = true;
401075fd0b74Schristos else if (lma - vma != last_lma - last_vma)
401175fd0b74Schristos {
401275fd0b74Schristos // This section has a different LMA relationship than the
401375fd0b74Schristos // last one; we need a new segment.
401475fd0b74Schristos need_new_segment = true;
401575fd0b74Schristos }
401675fd0b74Schristos else if (align_address(last_lma + last_size, abi_pagesize)
401775fd0b74Schristos < align_address(lma, abi_pagesize))
401875fd0b74Schristos {
401975fd0b74Schristos // Putting this section in the segment would require
402075fd0b74Schristos // skipping a page.
402175fd0b74Schristos need_new_segment = true;
402275fd0b74Schristos }
4023ede78133Schristos else if (in_bss && !is_bss_section(*p))
402475fd0b74Schristos {
402575fd0b74Schristos // A non-BSS section can not follow a BSS section in the
402675fd0b74Schristos // same segment.
402775fd0b74Schristos need_new_segment = true;
402875fd0b74Schristos }
402975fd0b74Schristos else if (is_current_seg_readonly
403075fd0b74Schristos && ((*p)->flags() & elfcpp::SHF_WRITE) != 0
403175fd0b74Schristos && !parameters->options().omagic())
403275fd0b74Schristos {
403375fd0b74Schristos // Don't put a writable section in the same segment as a
403475fd0b74Schristos // non-writable section.
403575fd0b74Schristos need_new_segment = true;
403675fd0b74Schristos }
403775fd0b74Schristos else
403875fd0b74Schristos {
403975fd0b74Schristos // Otherwise, reuse the existing segment.
404075fd0b74Schristos need_new_segment = false;
404175fd0b74Schristos }
404275fd0b74Schristos
404375fd0b74Schristos elfcpp::Elf_Word seg_flags =
404475fd0b74Schristos Layout::section_flags_to_segment((*p)->flags());
404575fd0b74Schristos
404675fd0b74Schristos if (need_new_segment)
404775fd0b74Schristos {
404875fd0b74Schristos current_seg = layout->make_output_segment(elfcpp::PT_LOAD,
404975fd0b74Schristos seg_flags);
405075fd0b74Schristos current_seg->set_addresses(vma, lma);
405175fd0b74Schristos current_seg->set_minimum_p_align(dot_alignment);
405275fd0b74Schristos if (first_seg == NULL)
405375fd0b74Schristos first_seg = current_seg;
405475fd0b74Schristos is_current_seg_readonly = true;
4055ede78133Schristos in_bss = false;
405675fd0b74Schristos }
405775fd0b74Schristos
405875fd0b74Schristos current_seg->add_output_section_to_load(layout, *p, seg_flags);
405975fd0b74Schristos
406075fd0b74Schristos if (((*p)->flags() & elfcpp::SHF_WRITE) != 0)
406175fd0b74Schristos is_current_seg_readonly = false;
406275fd0b74Schristos
4063ede78133Schristos if (is_bss_section(*p) && size > 0)
4064ede78133Schristos in_bss = true;
4065ede78133Schristos
406675fd0b74Schristos last_vma = vma;
406775fd0b74Schristos last_lma = lma;
406875fd0b74Schristos last_size = size;
406975fd0b74Schristos }
407075fd0b74Schristos
407175fd0b74Schristos // An ELF program should work even if the program headers are not in
407275fd0b74Schristos // a PT_LOAD segment. However, it appears that the Linux kernel
407375fd0b74Schristos // does not set the AT_PHDR auxiliary entry in that case. It sets
407475fd0b74Schristos // the load address to p_vaddr - p_offset of the first PT_LOAD
407575fd0b74Schristos // segment. It then sets AT_PHDR to the load address plus the
407675fd0b74Schristos // offset to the program headers, e_phoff in the file header. This
407775fd0b74Schristos // fails when the program headers appear in the file before the
407875fd0b74Schristos // first PT_LOAD segment. Therefore, we always create a PT_LOAD
407975fd0b74Schristos // segment to hold the file header and the program headers. This is
408075fd0b74Schristos // effectively what the GNU linker does, and it is slightly more
408175fd0b74Schristos // efficient in any case. We try to use the first PT_LOAD segment
408275fd0b74Schristos // if we can, otherwise we make a new one.
408375fd0b74Schristos
408475fd0b74Schristos if (first_seg == NULL)
408575fd0b74Schristos return NULL;
408675fd0b74Schristos
408775fd0b74Schristos // -n or -N mean that the program is not demand paged and there is
408875fd0b74Schristos // no need to put the program headers in a PT_LOAD segment.
408975fd0b74Schristos if (parameters->options().nmagic() || parameters->options().omagic())
409075fd0b74Schristos return NULL;
409175fd0b74Schristos
409275fd0b74Schristos size_t sizeof_headers = this->total_header_size(layout);
409375fd0b74Schristos
409475fd0b74Schristos uint64_t vma = first_seg->vaddr();
409575fd0b74Schristos uint64_t lma = first_seg->paddr();
409675fd0b74Schristos
409775fd0b74Schristos uint64_t subtract = this->header_size_adjustment(lma, sizeof_headers);
409875fd0b74Schristos
409975fd0b74Schristos if ((lma & (abi_pagesize - 1)) >= sizeof_headers)
410075fd0b74Schristos {
410175fd0b74Schristos first_seg->set_addresses(vma - subtract, lma - subtract);
410275fd0b74Schristos return first_seg;
410375fd0b74Schristos }
410475fd0b74Schristos
410575fd0b74Schristos // If there is no room to squeeze in the headers, then punt. The
410675fd0b74Schristos // resulting executable probably won't run on GNU/Linux, but we
410775fd0b74Schristos // trust that the user knows what they are doing.
410875fd0b74Schristos if (lma < subtract || vma < subtract)
410975fd0b74Schristos return NULL;
411075fd0b74Schristos
411175fd0b74Schristos // If memory regions have been specified and the address range
411275fd0b74Schristos // we are about to use is not contained within any region then
411375fd0b74Schristos // issue a warning message about the segment we are going to
411475fd0b74Schristos // create. It will be outside of any region and so possibly
411575fd0b74Schristos // using non-existent or protected memory. We test LMA rather
411675fd0b74Schristos // than VMA since we assume that the headers will never be
411775fd0b74Schristos // relocated.
411875fd0b74Schristos if (this->memory_regions_ != NULL
411975fd0b74Schristos && !this->block_in_region (NULL, layout, lma - subtract, subtract))
412075fd0b74Schristos gold_warning(_("creating a segment to contain the file and program"
412175fd0b74Schristos " headers outside of any MEMORY region"));
412275fd0b74Schristos
412375fd0b74Schristos Output_segment* load_seg = layout->make_output_segment(elfcpp::PT_LOAD,
412475fd0b74Schristos elfcpp::PF_R);
412575fd0b74Schristos load_seg->set_addresses(vma - subtract, lma - subtract);
412675fd0b74Schristos
412775fd0b74Schristos return load_seg;
412875fd0b74Schristos }
412975fd0b74Schristos
413075fd0b74Schristos // Create a PT_NOTE segment for each SHT_NOTE section and a PT_TLS
413175fd0b74Schristos // segment if there are any SHT_TLS sections.
413275fd0b74Schristos
413375fd0b74Schristos void
create_note_and_tls_segments(Layout * layout,const Layout::Section_list * sections)413475fd0b74Schristos Script_sections::create_note_and_tls_segments(
413575fd0b74Schristos Layout* layout,
413675fd0b74Schristos const Layout::Section_list* sections)
413775fd0b74Schristos {
413875fd0b74Schristos gold_assert(!this->saw_phdrs_clause());
413975fd0b74Schristos
414075fd0b74Schristos bool saw_tls = false;
414175fd0b74Schristos for (Layout::Section_list::const_iterator p = sections->begin();
414275fd0b74Schristos p != sections->end();
414375fd0b74Schristos ++p)
414475fd0b74Schristos {
414575fd0b74Schristos if ((*p)->type() == elfcpp::SHT_NOTE)
414675fd0b74Schristos {
414775fd0b74Schristos elfcpp::Elf_Word seg_flags =
414875fd0b74Schristos Layout::section_flags_to_segment((*p)->flags());
414975fd0b74Schristos Output_segment* oseg = layout->make_output_segment(elfcpp::PT_NOTE,
415075fd0b74Schristos seg_flags);
415175fd0b74Schristos oseg->add_output_section_to_nonload(*p, seg_flags);
415275fd0b74Schristos
415375fd0b74Schristos // Incorporate any subsequent SHT_NOTE sections, in the
415475fd0b74Schristos // hopes that the script is sensible.
415575fd0b74Schristos Layout::Section_list::const_iterator pnext = p + 1;
415675fd0b74Schristos while (pnext != sections->end()
415775fd0b74Schristos && (*pnext)->type() == elfcpp::SHT_NOTE)
415875fd0b74Schristos {
415975fd0b74Schristos seg_flags = Layout::section_flags_to_segment((*pnext)->flags());
416075fd0b74Schristos oseg->add_output_section_to_nonload(*pnext, seg_flags);
416175fd0b74Schristos p = pnext;
416275fd0b74Schristos ++pnext;
416375fd0b74Schristos }
416475fd0b74Schristos }
416575fd0b74Schristos
416675fd0b74Schristos if (((*p)->flags() & elfcpp::SHF_TLS) != 0)
416775fd0b74Schristos {
416875fd0b74Schristos if (saw_tls)
416975fd0b74Schristos gold_error(_("TLS sections are not adjacent"));
417075fd0b74Schristos
417175fd0b74Schristos elfcpp::Elf_Word seg_flags =
417275fd0b74Schristos Layout::section_flags_to_segment((*p)->flags());
417375fd0b74Schristos Output_segment* oseg = layout->make_output_segment(elfcpp::PT_TLS,
417475fd0b74Schristos seg_flags);
417575fd0b74Schristos oseg->add_output_section_to_nonload(*p, seg_flags);
417675fd0b74Schristos
417775fd0b74Schristos Layout::Section_list::const_iterator pnext = p + 1;
417875fd0b74Schristos while (pnext != sections->end()
417975fd0b74Schristos && ((*pnext)->flags() & elfcpp::SHF_TLS) != 0)
418075fd0b74Schristos {
418175fd0b74Schristos seg_flags = Layout::section_flags_to_segment((*pnext)->flags());
418275fd0b74Schristos oseg->add_output_section_to_nonload(*pnext, seg_flags);
418375fd0b74Schristos p = pnext;
418475fd0b74Schristos ++pnext;
418575fd0b74Schristos }
418675fd0b74Schristos
418775fd0b74Schristos saw_tls = true;
418875fd0b74Schristos }
418975fd0b74Schristos
419075fd0b74Schristos // If we see a section named .interp then put the .interp section
419175fd0b74Schristos // in a PT_INTERP segment.
419275fd0b74Schristos // This is for GNU ld compatibility.
419375fd0b74Schristos if (strcmp((*p)->name(), ".interp") == 0)
419475fd0b74Schristos {
419575fd0b74Schristos elfcpp::Elf_Word seg_flags =
419675fd0b74Schristos Layout::section_flags_to_segment((*p)->flags());
419775fd0b74Schristos Output_segment* oseg = layout->make_output_segment(elfcpp::PT_INTERP,
419875fd0b74Schristos seg_flags);
419975fd0b74Schristos oseg->add_output_section_to_nonload(*p, seg_flags);
420075fd0b74Schristos }
420175fd0b74Schristos }
420275fd0b74Schristos
420375fd0b74Schristos this->segments_created_ = true;
420475fd0b74Schristos }
420575fd0b74Schristos
420675fd0b74Schristos // Add a program header. The PHDRS clause is syntactically distinct
420775fd0b74Schristos // from the SECTIONS clause, but we implement it with the SECTIONS
420875fd0b74Schristos // support because PHDRS is useless if there is no SECTIONS clause.
420975fd0b74Schristos
421075fd0b74Schristos void
add_phdr(const char * name,size_t namelen,unsigned int type,bool includes_filehdr,bool includes_phdrs,bool is_flags_valid,unsigned int flags,Expression * load_address)421175fd0b74Schristos Script_sections::add_phdr(const char* name, size_t namelen, unsigned int type,
421275fd0b74Schristos bool includes_filehdr, bool includes_phdrs,
421375fd0b74Schristos bool is_flags_valid, unsigned int flags,
421475fd0b74Schristos Expression* load_address)
421575fd0b74Schristos {
421675fd0b74Schristos if (this->phdrs_elements_ == NULL)
421775fd0b74Schristos this->phdrs_elements_ = new Phdrs_elements();
421875fd0b74Schristos this->phdrs_elements_->push_back(new Phdrs_element(name, namelen, type,
421975fd0b74Schristos includes_filehdr,
422075fd0b74Schristos includes_phdrs,
422175fd0b74Schristos is_flags_valid, flags,
422275fd0b74Schristos load_address));
422375fd0b74Schristos }
422475fd0b74Schristos
422575fd0b74Schristos // Return the number of segments we expect to create based on the
422675fd0b74Schristos // SECTIONS clause. This is used to implement SIZEOF_HEADERS.
422775fd0b74Schristos
422875fd0b74Schristos size_t
expected_segment_count(const Layout * layout) const422975fd0b74Schristos Script_sections::expected_segment_count(const Layout* layout) const
423075fd0b74Schristos {
423175fd0b74Schristos // If we've already created the segments, we won't be adding any more.
423275fd0b74Schristos if (this->segments_created_)
423375fd0b74Schristos return 0;
423475fd0b74Schristos
423575fd0b74Schristos if (this->saw_phdrs_clause())
423675fd0b74Schristos return this->phdrs_elements_->size();
423775fd0b74Schristos
423875fd0b74Schristos Layout::Section_list sections;
423975fd0b74Schristos layout->get_allocated_sections(§ions);
424075fd0b74Schristos
424175fd0b74Schristos // We assume that we will need two PT_LOAD segments.
424275fd0b74Schristos size_t ret = 2;
424375fd0b74Schristos
424475fd0b74Schristos bool saw_note = false;
424575fd0b74Schristos bool saw_tls = false;
424675fd0b74Schristos bool saw_interp = false;
424775fd0b74Schristos for (Layout::Section_list::const_iterator p = sections.begin();
424875fd0b74Schristos p != sections.end();
424975fd0b74Schristos ++p)
425075fd0b74Schristos {
425175fd0b74Schristos if ((*p)->type() == elfcpp::SHT_NOTE)
425275fd0b74Schristos {
425375fd0b74Schristos // Assume that all note sections will fit into a single
425475fd0b74Schristos // PT_NOTE segment.
425575fd0b74Schristos if (!saw_note)
425675fd0b74Schristos {
425775fd0b74Schristos ++ret;
425875fd0b74Schristos saw_note = true;
425975fd0b74Schristos }
426075fd0b74Schristos }
426175fd0b74Schristos else if (((*p)->flags() & elfcpp::SHF_TLS) != 0)
426275fd0b74Schristos {
426375fd0b74Schristos // There can only be one PT_TLS segment.
426475fd0b74Schristos if (!saw_tls)
426575fd0b74Schristos {
426675fd0b74Schristos ++ret;
426775fd0b74Schristos saw_tls = true;
426875fd0b74Schristos }
426975fd0b74Schristos }
427075fd0b74Schristos else if (strcmp((*p)->name(), ".interp") == 0)
427175fd0b74Schristos {
427275fd0b74Schristos // There can only be one PT_INTERP segment.
427375fd0b74Schristos if (!saw_interp)
427475fd0b74Schristos {
427575fd0b74Schristos ++ret;
427675fd0b74Schristos saw_interp = true;
427775fd0b74Schristos }
427875fd0b74Schristos }
427975fd0b74Schristos }
428075fd0b74Schristos
428175fd0b74Schristos return ret;
428275fd0b74Schristos }
428375fd0b74Schristos
428475fd0b74Schristos // Create the segments from a PHDRS clause. Return the segment which
428575fd0b74Schristos // should hold the file header and program headers, if any.
428675fd0b74Schristos
428775fd0b74Schristos Output_segment*
create_segments_from_phdrs_clause(Layout * layout,uint64_t dot_alignment)428875fd0b74Schristos Script_sections::create_segments_from_phdrs_clause(Layout* layout,
428975fd0b74Schristos uint64_t dot_alignment)
429075fd0b74Schristos {
429175fd0b74Schristos this->attach_sections_using_phdrs_clause(layout);
429275fd0b74Schristos return this->set_phdrs_clause_addresses(layout, dot_alignment);
429375fd0b74Schristos }
429475fd0b74Schristos
429575fd0b74Schristos // Create the segments from the PHDRS clause, and put the output
429675fd0b74Schristos // sections in them.
429775fd0b74Schristos
429875fd0b74Schristos void
attach_sections_using_phdrs_clause(Layout * layout)429975fd0b74Schristos Script_sections::attach_sections_using_phdrs_clause(Layout* layout)
430075fd0b74Schristos {
430175fd0b74Schristos typedef std::map<std::string, Output_segment*> Name_to_segment;
430275fd0b74Schristos Name_to_segment name_to_segment;
430375fd0b74Schristos for (Phdrs_elements::const_iterator p = this->phdrs_elements_->begin();
430475fd0b74Schristos p != this->phdrs_elements_->end();
430575fd0b74Schristos ++p)
430675fd0b74Schristos name_to_segment[(*p)->name()] = (*p)->create_segment(layout);
430775fd0b74Schristos this->segments_created_ = true;
430875fd0b74Schristos
430975fd0b74Schristos // Walk through the output sections and attach them to segments.
431075fd0b74Schristos // Output sections in the script which do not list segments are
431175fd0b74Schristos // attached to the same set of segments as the immediately preceding
431275fd0b74Schristos // output section.
431375fd0b74Schristos
431475fd0b74Schristos String_list* phdr_names = NULL;
431575fd0b74Schristos bool load_segments_only = false;
431675fd0b74Schristos for (Sections_elements::const_iterator p = this->sections_elements_->begin();
431775fd0b74Schristos p != this->sections_elements_->end();
431875fd0b74Schristos ++p)
431975fd0b74Schristos {
432075fd0b74Schristos bool is_orphan;
432175fd0b74Schristos String_list* old_phdr_names = phdr_names;
432275fd0b74Schristos Output_section* os = (*p)->allocate_to_segment(&phdr_names, &is_orphan);
432375fd0b74Schristos if (os == NULL)
432475fd0b74Schristos continue;
432575fd0b74Schristos
432675fd0b74Schristos elfcpp::Elf_Word seg_flags =
432775fd0b74Schristos Layout::section_flags_to_segment(os->flags());
432875fd0b74Schristos
432975fd0b74Schristos if (phdr_names == NULL)
433075fd0b74Schristos {
433175fd0b74Schristos // Don't worry about empty orphan sections.
433275fd0b74Schristos if (is_orphan && os->current_data_size() > 0)
433375fd0b74Schristos gold_error(_("allocated section %s not in any segment"),
433475fd0b74Schristos os->name());
433575fd0b74Schristos
433675fd0b74Schristos // To avoid later crashes drop this section into the first
433775fd0b74Schristos // PT_LOAD segment.
433875fd0b74Schristos for (Phdrs_elements::const_iterator ppe =
433975fd0b74Schristos this->phdrs_elements_->begin();
434075fd0b74Schristos ppe != this->phdrs_elements_->end();
434175fd0b74Schristos ++ppe)
434275fd0b74Schristos {
434375fd0b74Schristos Output_segment* oseg = (*ppe)->segment();
434475fd0b74Schristos if (oseg->type() == elfcpp::PT_LOAD)
434575fd0b74Schristos {
434675fd0b74Schristos oseg->add_output_section_to_load(layout, os, seg_flags);
434775fd0b74Schristos break;
434875fd0b74Schristos }
434975fd0b74Schristos }
435075fd0b74Schristos
435175fd0b74Schristos continue;
435275fd0b74Schristos }
435375fd0b74Schristos
435475fd0b74Schristos // We see a list of segments names. Disable PT_LOAD segment only
435575fd0b74Schristos // filtering.
435675fd0b74Schristos if (old_phdr_names != phdr_names)
435775fd0b74Schristos load_segments_only = false;
435875fd0b74Schristos
435975fd0b74Schristos // If this is an orphan section--one that was not explicitly
436075fd0b74Schristos // mentioned in the linker script--then it should not inherit
436175fd0b74Schristos // any segment type other than PT_LOAD. Otherwise, e.g., the
436275fd0b74Schristos // PT_INTERP segment will pick up following orphan sections,
436375fd0b74Schristos // which does not make sense. If this is not an orphan section,
436475fd0b74Schristos // we trust the linker script.
436575fd0b74Schristos if (is_orphan)
436675fd0b74Schristos {
436775fd0b74Schristos // Enable PT_LOAD segments only filtering until we see another
436875fd0b74Schristos // list of segment names.
436975fd0b74Schristos load_segments_only = true;
437075fd0b74Schristos }
437175fd0b74Schristos
437275fd0b74Schristos bool in_load_segment = false;
437375fd0b74Schristos for (String_list::const_iterator q = phdr_names->begin();
437475fd0b74Schristos q != phdr_names->end();
437575fd0b74Schristos ++q)
437675fd0b74Schristos {
437775fd0b74Schristos Name_to_segment::const_iterator r = name_to_segment.find(*q);
437875fd0b74Schristos if (r == name_to_segment.end())
437975fd0b74Schristos gold_error(_("no segment %s"), q->c_str());
438075fd0b74Schristos else
438175fd0b74Schristos {
438275fd0b74Schristos if (load_segments_only
438375fd0b74Schristos && r->second->type() != elfcpp::PT_LOAD)
438475fd0b74Schristos continue;
438575fd0b74Schristos
438675fd0b74Schristos if (r->second->type() != elfcpp::PT_LOAD)
438775fd0b74Schristos r->second->add_output_section_to_nonload(os, seg_flags);
438875fd0b74Schristos else
438975fd0b74Schristos {
439075fd0b74Schristos r->second->add_output_section_to_load(layout, os, seg_flags);
439175fd0b74Schristos if (in_load_segment)
439275fd0b74Schristos gold_error(_("section in two PT_LOAD segments"));
439375fd0b74Schristos in_load_segment = true;
439475fd0b74Schristos }
439575fd0b74Schristos }
439675fd0b74Schristos }
439775fd0b74Schristos
439875fd0b74Schristos if (!in_load_segment)
439975fd0b74Schristos gold_error(_("allocated section not in any PT_LOAD segment"));
440075fd0b74Schristos }
440175fd0b74Schristos }
440275fd0b74Schristos
440375fd0b74Schristos // Set the addresses for segments created from a PHDRS clause. Return
440475fd0b74Schristos // the segment which should hold the file header and program headers,
440575fd0b74Schristos // if any.
440675fd0b74Schristos
440775fd0b74Schristos Output_segment*
set_phdrs_clause_addresses(Layout * layout,uint64_t dot_alignment)440875fd0b74Schristos Script_sections::set_phdrs_clause_addresses(Layout* layout,
440975fd0b74Schristos uint64_t dot_alignment)
441075fd0b74Schristos {
441175fd0b74Schristos Output_segment* load_seg = NULL;
441275fd0b74Schristos for (Phdrs_elements::const_iterator p = this->phdrs_elements_->begin();
441375fd0b74Schristos p != this->phdrs_elements_->end();
441475fd0b74Schristos ++p)
441575fd0b74Schristos {
441675fd0b74Schristos // Note that we have to set the flags after adding the output
441775fd0b74Schristos // sections to the segment, as adding an output segment can
441875fd0b74Schristos // change the flags.
441975fd0b74Schristos (*p)->set_flags_if_valid();
442075fd0b74Schristos
442175fd0b74Schristos Output_segment* oseg = (*p)->segment();
442275fd0b74Schristos
442375fd0b74Schristos if (oseg->type() != elfcpp::PT_LOAD)
442475fd0b74Schristos {
442575fd0b74Schristos // The addresses of non-PT_LOAD segments are set from the
442675fd0b74Schristos // PT_LOAD segments.
442775fd0b74Schristos if ((*p)->has_load_address())
442875fd0b74Schristos gold_error(_("may only specify load address for PT_LOAD segment"));
442975fd0b74Schristos continue;
443075fd0b74Schristos }
443175fd0b74Schristos
443275fd0b74Schristos oseg->set_minimum_p_align(dot_alignment);
443375fd0b74Schristos
443475fd0b74Schristos // The output sections should have addresses from the SECTIONS
443575fd0b74Schristos // clause. The addresses don't have to be in order, so find the
443675fd0b74Schristos // one with the lowest load address. Use that to set the
443775fd0b74Schristos // address of the segment.
443875fd0b74Schristos
443975fd0b74Schristos Output_section* osec = oseg->section_with_lowest_load_address();
444075fd0b74Schristos if (osec == NULL)
444175fd0b74Schristos {
444275fd0b74Schristos oseg->set_addresses(0, 0);
444375fd0b74Schristos continue;
444475fd0b74Schristos }
444575fd0b74Schristos
444675fd0b74Schristos uint64_t vma = osec->address();
444775fd0b74Schristos uint64_t lma = osec->has_load_address() ? osec->load_address() : vma;
444875fd0b74Schristos
444975fd0b74Schristos // Override the load address of the section with the load
445075fd0b74Schristos // address specified for the segment.
445175fd0b74Schristos if ((*p)->has_load_address())
445275fd0b74Schristos {
445375fd0b74Schristos if (osec->has_load_address())
445475fd0b74Schristos gold_warning(_("PHDRS load address overrides "
445575fd0b74Schristos "section %s load address"),
445675fd0b74Schristos osec->name());
445775fd0b74Schristos
445875fd0b74Schristos lma = (*p)->load_address();
445975fd0b74Schristos }
446075fd0b74Schristos
446175fd0b74Schristos bool headers = (*p)->includes_filehdr() && (*p)->includes_phdrs();
446275fd0b74Schristos if (!headers && ((*p)->includes_filehdr() || (*p)->includes_phdrs()))
446375fd0b74Schristos {
446475fd0b74Schristos // We could support this if we wanted to.
446575fd0b74Schristos gold_error(_("using only one of FILEHDR and PHDRS is "
446675fd0b74Schristos "not currently supported"));
446775fd0b74Schristos }
446875fd0b74Schristos if (headers)
446975fd0b74Schristos {
447075fd0b74Schristos size_t sizeof_headers = this->total_header_size(layout);
447175fd0b74Schristos uint64_t subtract = this->header_size_adjustment(lma,
447275fd0b74Schristos sizeof_headers);
447375fd0b74Schristos if (lma >= subtract && vma >= subtract)
447475fd0b74Schristos {
447575fd0b74Schristos lma -= subtract;
447675fd0b74Schristos vma -= subtract;
447775fd0b74Schristos }
447875fd0b74Schristos else
447975fd0b74Schristos {
448075fd0b74Schristos gold_error(_("sections loaded on first page without room "
448175fd0b74Schristos "for file and program headers "
448275fd0b74Schristos "are not supported"));
448375fd0b74Schristos }
448475fd0b74Schristos
448575fd0b74Schristos if (load_seg != NULL)
448675fd0b74Schristos gold_error(_("using FILEHDR and PHDRS on more than one "
448775fd0b74Schristos "PT_LOAD segment is not currently supported"));
448875fd0b74Schristos load_seg = oseg;
448975fd0b74Schristos }
449075fd0b74Schristos
449175fd0b74Schristos oseg->set_addresses(vma, lma);
449275fd0b74Schristos }
449375fd0b74Schristos
449475fd0b74Schristos return load_seg;
449575fd0b74Schristos }
449675fd0b74Schristos
449775fd0b74Schristos // Add the file header and segment headers to non-load segments
449875fd0b74Schristos // specified in the PHDRS clause.
449975fd0b74Schristos
450075fd0b74Schristos void
put_headers_in_phdrs(Output_data * file_header,Output_data * segment_headers)450175fd0b74Schristos Script_sections::put_headers_in_phdrs(Output_data* file_header,
450275fd0b74Schristos Output_data* segment_headers)
450375fd0b74Schristos {
450475fd0b74Schristos gold_assert(this->saw_phdrs_clause());
450575fd0b74Schristos for (Phdrs_elements::iterator p = this->phdrs_elements_->begin();
450675fd0b74Schristos p != this->phdrs_elements_->end();
450775fd0b74Schristos ++p)
450875fd0b74Schristos {
450975fd0b74Schristos if ((*p)->type() != elfcpp::PT_LOAD)
451075fd0b74Schristos {
451175fd0b74Schristos if ((*p)->includes_phdrs())
451275fd0b74Schristos (*p)->segment()->add_initial_output_data(segment_headers);
451375fd0b74Schristos if ((*p)->includes_filehdr())
451475fd0b74Schristos (*p)->segment()->add_initial_output_data(file_header);
451575fd0b74Schristos }
451675fd0b74Schristos }
451775fd0b74Schristos }
451875fd0b74Schristos
451975fd0b74Schristos // Look for an output section by name and return the address, the load
452075fd0b74Schristos // address, the alignment, and the size. This is used when an
452175fd0b74Schristos // expression refers to an output section which was not actually
452275fd0b74Schristos // created. This returns true if the section was found, false
452375fd0b74Schristos // otherwise.
452475fd0b74Schristos
452575fd0b74Schristos bool
get_output_section_info(const char * name,uint64_t * address,uint64_t * load_address,uint64_t * addralign,uint64_t * size) const452675fd0b74Schristos Script_sections::get_output_section_info(const char* name, uint64_t* address,
452775fd0b74Schristos uint64_t* load_address,
452875fd0b74Schristos uint64_t* addralign,
452975fd0b74Schristos uint64_t* size) const
453075fd0b74Schristos {
453175fd0b74Schristos if (!this->saw_sections_clause_)
453275fd0b74Schristos return false;
453375fd0b74Schristos for (Sections_elements::const_iterator p = this->sections_elements_->begin();
453475fd0b74Schristos p != this->sections_elements_->end();
453575fd0b74Schristos ++p)
453675fd0b74Schristos if ((*p)->get_output_section_info(name, address, load_address, addralign,
453775fd0b74Schristos size))
453875fd0b74Schristos return true;
453975fd0b74Schristos return false;
454075fd0b74Schristos }
454175fd0b74Schristos
454275fd0b74Schristos // Release all Output_segments. This remove all pointers to all
454375fd0b74Schristos // Output_segments.
454475fd0b74Schristos
454575fd0b74Schristos void
release_segments()454675fd0b74Schristos Script_sections::release_segments()
454775fd0b74Schristos {
454875fd0b74Schristos if (this->saw_phdrs_clause())
454975fd0b74Schristos {
455075fd0b74Schristos for (Phdrs_elements::const_iterator p = this->phdrs_elements_->begin();
455175fd0b74Schristos p != this->phdrs_elements_->end();
455275fd0b74Schristos ++p)
455375fd0b74Schristos (*p)->release_segment();
455475fd0b74Schristos }
4555ede78133Schristos this->segments_created_ = false;
455675fd0b74Schristos }
455775fd0b74Schristos
455875fd0b74Schristos // Print the SECTIONS clause to F for debugging.
455975fd0b74Schristos
456075fd0b74Schristos void
print(FILE * f) const456175fd0b74Schristos Script_sections::print(FILE* f) const
456275fd0b74Schristos {
456375fd0b74Schristos if (this->phdrs_elements_ != NULL)
456475fd0b74Schristos {
456575fd0b74Schristos fprintf(f, "PHDRS {\n");
456675fd0b74Schristos for (Phdrs_elements::const_iterator p = this->phdrs_elements_->begin();
456775fd0b74Schristos p != this->phdrs_elements_->end();
456875fd0b74Schristos ++p)
456975fd0b74Schristos (*p)->print(f);
457075fd0b74Schristos fprintf(f, "}\n");
457175fd0b74Schristos }
457275fd0b74Schristos
457375fd0b74Schristos if (this->memory_regions_ != NULL)
457475fd0b74Schristos {
457575fd0b74Schristos fprintf(f, "MEMORY {\n");
457675fd0b74Schristos for (Memory_regions::const_iterator m = this->memory_regions_->begin();
457775fd0b74Schristos m != this->memory_regions_->end();
457875fd0b74Schristos ++m)
457975fd0b74Schristos (*m)->print(f);
458075fd0b74Schristos fprintf(f, "}\n");
458175fd0b74Schristos }
458275fd0b74Schristos
458375fd0b74Schristos if (!this->saw_sections_clause_)
458475fd0b74Schristos return;
458575fd0b74Schristos
458675fd0b74Schristos fprintf(f, "SECTIONS {\n");
458775fd0b74Schristos
458875fd0b74Schristos for (Sections_elements::const_iterator p = this->sections_elements_->begin();
458975fd0b74Schristos p != this->sections_elements_->end();
459075fd0b74Schristos ++p)
459175fd0b74Schristos (*p)->print(f);
459275fd0b74Schristos
459375fd0b74Schristos fprintf(f, "}\n");
459475fd0b74Schristos }
459575fd0b74Schristos
459675fd0b74Schristos } // End namespace gold.
4597