Don't check assertions until symbols are finalized. Create an output
section if the script uses a data statement with no input sections. Don't create a loadable segment for the headers if there is no room.
This commit is contained in:
parent
15cf077ef4
commit
919ed24cbc
8 changed files with 166 additions and 58 deletions
|
@ -54,6 +54,8 @@ struct Expression::Expression_eval_info
|
|||
const Symbol_table* symtab;
|
||||
// The layout--we use this to get section information.
|
||||
const Layout* layout;
|
||||
// Whether to check assertions.
|
||||
bool check_assertions;
|
||||
// Whether expressions can refer to the dot symbol. The dot symbol
|
||||
// is only available within a SECTIONS clause.
|
||||
bool is_dot_available;
|
||||
|
@ -69,21 +71,24 @@ struct Expression::Expression_eval_info
|
|||
// Evaluate an expression.
|
||||
|
||||
uint64_t
|
||||
Expression::eval(const Symbol_table* symtab, const Layout* layout)
|
||||
Expression::eval(const Symbol_table* symtab, const Layout* layout,
|
||||
bool check_assertions)
|
||||
{
|
||||
Output_section* dummy;
|
||||
return this->eval_maybe_dot(symtab, layout, false, 0, NULL, &dummy);
|
||||
return this->eval_maybe_dot(symtab, layout, check_assertions,
|
||||
false, 0, NULL, &dummy);
|
||||
}
|
||||
|
||||
// Evaluate an expression which may refer to the dot symbol.
|
||||
|
||||
uint64_t
|
||||
Expression::eval_with_dot(const Symbol_table* symtab, const Layout* layout,
|
||||
uint64_t dot_value, Output_section* dot_section,
|
||||
bool check_assertions, uint64_t dot_value,
|
||||
Output_section* dot_section,
|
||||
Output_section** result_section_pointer)
|
||||
{
|
||||
return this->eval_maybe_dot(symtab, layout, true, dot_value, dot_section,
|
||||
result_section_pointer);
|
||||
return this->eval_maybe_dot(symtab, layout, check_assertions, true,
|
||||
dot_value, dot_section, result_section_pointer);
|
||||
}
|
||||
|
||||
// Evaluate an expression which may or may not refer to the dot
|
||||
|
@ -91,13 +96,14 @@ Expression::eval_with_dot(const Symbol_table* symtab, const Layout* layout,
|
|||
|
||||
uint64_t
|
||||
Expression::eval_maybe_dot(const Symbol_table* symtab, const Layout* layout,
|
||||
bool is_dot_available, uint64_t dot_value,
|
||||
Output_section* dot_section,
|
||||
bool check_assertions, bool is_dot_available,
|
||||
uint64_t dot_value, Output_section* dot_section,
|
||||
Output_section** result_section_pointer)
|
||||
{
|
||||
Expression_eval_info eei;
|
||||
eei.symtab = symtab;
|
||||
eei.layout = layout;
|
||||
eei.check_assertions = check_assertions;
|
||||
eei.is_dot_available = is_dot_available;
|
||||
eei.dot_value = dot_value;
|
||||
eei.dot_section = dot_section;
|
||||
|
@ -237,6 +243,7 @@ class Unary_expression : public Expression
|
|||
Output_section** arg_section_pointer) const
|
||||
{
|
||||
return this->arg_->eval_maybe_dot(eei->symtab, eei->layout,
|
||||
eei->check_assertions,
|
||||
eei->is_dot_available,
|
||||
eei->dot_value,
|
||||
eei->dot_section,
|
||||
|
@ -313,6 +320,7 @@ class Binary_expression : public Expression
|
|||
Output_section** section_pointer) const
|
||||
{
|
||||
return this->left_->eval_maybe_dot(eei->symtab, eei->layout,
|
||||
eei->check_assertions,
|
||||
eei->is_dot_available,
|
||||
eei->dot_value,
|
||||
eei->dot_section,
|
||||
|
@ -324,6 +332,7 @@ class Binary_expression : public Expression
|
|||
Output_section** section_pointer) const
|
||||
{
|
||||
return this->right_->eval_maybe_dot(eei->symtab, eei->layout,
|
||||
eei->check_assertions,
|
||||
eei->is_dot_available,
|
||||
eei->dot_value,
|
||||
eei->dot_section,
|
||||
|
@ -456,6 +465,7 @@ class Trinary_expression : public Expression
|
|||
Output_section** section_pointer) const
|
||||
{
|
||||
return this->arg1_->eval_maybe_dot(eei->symtab, eei->layout,
|
||||
eei->check_assertions,
|
||||
eei->is_dot_available,
|
||||
eei->dot_value,
|
||||
eei->dot_section,
|
||||
|
@ -467,6 +477,7 @@ class Trinary_expression : public Expression
|
|||
Output_section** section_pointer) const
|
||||
{
|
||||
return this->arg1_->eval_maybe_dot(eei->symtab, eei->layout,
|
||||
eei->check_assertions,
|
||||
eei->is_dot_available,
|
||||
eei->dot_value,
|
||||
eei->dot_section,
|
||||
|
@ -478,6 +489,7 @@ class Trinary_expression : public Expression
|
|||
Output_section** section_pointer) const
|
||||
{
|
||||
return this->arg1_->eval_maybe_dot(eei->symtab, eei->layout,
|
||||
eei->check_assertions,
|
||||
eei->is_dot_available,
|
||||
eei->dot_value,
|
||||
eei->dot_section,
|
||||
|
@ -738,7 +750,7 @@ class Assert_expression : public Unary_expression
|
|||
value(const Expression_eval_info* eei)
|
||||
{
|
||||
uint64_t value = this->arg_value(eei, eei->result_section_pointer);
|
||||
if (!value)
|
||||
if (!value && eei->check_assertions)
|
||||
gold_error("%s", this->message_.c_str());
|
||||
return value;
|
||||
}
|
||||
|
|
|
@ -202,6 +202,9 @@ queue_middle_tasks(const General_options& options,
|
|||
// TODO: if this is too slow, do this as a task, rather than inline.
|
||||
symtab->detect_odr_violations(task, options.output_file_name());
|
||||
|
||||
// Create any output sections required by any linker script.
|
||||
layout->create_script_sections();
|
||||
|
||||
// Define some sections and symbols needed for a dynamic link. This
|
||||
// handles some cases we want to see before we read the relocs.
|
||||
layout->create_initial_dynamic_sections(symtab);
|
||||
|
|
|
@ -712,6 +712,18 @@ Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
|
|||
return os;
|
||||
}
|
||||
|
||||
// Make an output section for a script.
|
||||
|
||||
Output_section*
|
||||
Layout::make_output_section_for_script(const char* name)
|
||||
{
|
||||
name = this->namepool_.add(name, false, NULL);
|
||||
Output_section* os = this->make_output_section(name, elfcpp::SHT_PROGBITS,
|
||||
elfcpp::SHF_ALLOC);
|
||||
os->set_found_in_sections_clause();
|
||||
return os;
|
||||
}
|
||||
|
||||
// Return the number of segments we expect to see.
|
||||
|
||||
size_t
|
||||
|
|
|
@ -168,6 +168,11 @@ class Layout
|
|||
void
|
||||
define_section_symbols(Symbol_table*);
|
||||
|
||||
// Create sections for linker scripts.
|
||||
void
|
||||
create_script_sections()
|
||||
{ this->script_options_->create_script_sections(this); }
|
||||
|
||||
// Define symbols from any linker script.
|
||||
void
|
||||
define_script_symbols(Symbol_table* symtab)
|
||||
|
@ -314,6 +319,10 @@ class Layout
|
|||
void
|
||||
get_allocated_sections(Section_list*) const;
|
||||
|
||||
// Make a section for a linker script to hold data.
|
||||
Output_section*
|
||||
make_output_section_for_script(const char* name);
|
||||
|
||||
// Make a segment. This is used by the linker script code.
|
||||
Output_segment*
|
||||
make_output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags);
|
||||
|
|
|
@ -54,6 +54,12 @@ class Sections_element
|
|||
virtual ~Sections_element()
|
||||
{ }
|
||||
|
||||
// Create any required output sections. The only real
|
||||
// implementation is in Output_section_definition.
|
||||
virtual void
|
||||
create_sections(Layout*)
|
||||
{ }
|
||||
|
||||
// Add any symbol being defined to the symbol table.
|
||||
virtual void
|
||||
add_symbols_to_table(Symbol_table*)
|
||||
|
@ -175,7 +181,7 @@ class Sections_element_dot_assignment : public Sections_element
|
|||
// output section definition the dot symbol is always considered
|
||||
// to be absolute.
|
||||
Output_section* dummy;
|
||||
*dot_value = this->val_->eval_with_dot(symtab, layout, *dot_value,
|
||||
*dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value,
|
||||
NULL, &dummy);
|
||||
}
|
||||
|
||||
|
@ -185,7 +191,7 @@ class Sections_element_dot_assignment : public Sections_element
|
|||
uint64_t* dot_value, uint64_t* load_address)
|
||||
{
|
||||
Output_section* dummy;
|
||||
*dot_value = this->val_->eval_with_dot(symtab, layout, *dot_value,
|
||||
*dot_value = this->val_->eval_with_dot(symtab, layout, false, *dot_value,
|
||||
NULL, &dummy);
|
||||
*load_address = *dot_value;
|
||||
}
|
||||
|
@ -244,6 +250,11 @@ class Output_section_element
|
|||
virtual ~Output_section_element()
|
||||
{ }
|
||||
|
||||
// Return whether this element requires an output section to exist.
|
||||
virtual bool
|
||||
needs_output_section() const
|
||||
{ return false; }
|
||||
|
||||
// Add any symbol being defined to the symbol table.
|
||||
virtual void
|
||||
add_symbols_to_table(Symbol_table*)
|
||||
|
@ -354,7 +365,7 @@ class Output_section_element_dot_assignment : public Output_section_element
|
|||
finalize_symbols(Symbol_table* symtab, const Layout* layout,
|
||||
uint64_t* dot_value, Output_section** dot_section)
|
||||
{
|
||||
*dot_value = this->val_->eval_with_dot(symtab, layout, *dot_value,
|
||||
*dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value,
|
||||
*dot_section, dot_section);
|
||||
}
|
||||
|
||||
|
@ -390,8 +401,9 @@ Output_section_element_dot_assignment::set_section_addresses(
|
|||
std::string* fill,
|
||||
Input_section_list*)
|
||||
{
|
||||
uint64_t next_dot = this->val_->eval_with_dot(symtab, layout, *dot_value,
|
||||
*dot_section, dot_section);
|
||||
uint64_t next_dot = this->val_->eval_with_dot(symtab, layout, false,
|
||||
*dot_value, *dot_section,
|
||||
dot_section);
|
||||
if (next_dot < *dot_value)
|
||||
gold_error(_("dot may not move backward"));
|
||||
if (next_dot > *dot_value && output_section != NULL)
|
||||
|
@ -486,7 +498,7 @@ Output_data_expression::do_write_to_buffer(unsigned char* buf)
|
|||
{
|
||||
Output_section* dummy;
|
||||
uint64_t val = this->val_->eval_with_dot(this->symtab_, this->layout_,
|
||||
this->dot_value_,
|
||||
true, this->dot_value_,
|
||||
this->dot_section_, &dummy);
|
||||
|
||||
if (parameters->target().is_big_endian())
|
||||
|
@ -534,6 +546,11 @@ class Output_section_element_data : public Output_section_element
|
|||
: size_(size), is_signed_(is_signed), val_(val)
|
||||
{ }
|
||||
|
||||
// If there is a data item, then we must create an output section.
|
||||
bool
|
||||
needs_output_section() const
|
||||
{ return true; }
|
||||
|
||||
// Finalize symbols--we just need to update dot.
|
||||
void
|
||||
finalize_symbols(Symbol_table*, const Layout*, uint64_t* dot_value,
|
||||
|
@ -631,7 +648,7 @@ class Output_section_element_fill : public Output_section_element
|
|||
std::string* fill, Input_section_list*)
|
||||
{
|
||||
Output_section* fill_section;
|
||||
uint64_t fill_val = this->val_->eval_with_dot(symtab, layout,
|
||||
uint64_t fill_val = this->val_->eval_with_dot(symtab, layout, false,
|
||||
*dot_value, *dot_section,
|
||||
&fill_section);
|
||||
if (fill_section != NULL)
|
||||
|
@ -1195,6 +1212,10 @@ class Output_section_definition : public Sections_element
|
|||
void
|
||||
add_input_section(const Input_section_spec* spec, bool keep);
|
||||
|
||||
// Create any required output sections.
|
||||
void
|
||||
create_sections(Layout*);
|
||||
|
||||
// Add any symbols being defined to the symbol table.
|
||||
void
|
||||
add_symbols_to_table(Symbol_table* symtab);
|
||||
|
@ -1365,6 +1386,27 @@ Output_section_definition::add_input_section(const Input_section_spec* spec,
|
|||
this->elements_.push_back(p);
|
||||
}
|
||||
|
||||
// Create any required output sections. We need an output section if
|
||||
// there is a data statement here.
|
||||
|
||||
void
|
||||
Output_section_definition::create_sections(Layout* layout)
|
||||
{
|
||||
if (this->output_section_ != NULL)
|
||||
return;
|
||||
for (Output_section_elements::const_iterator p = this->elements_.begin();
|
||||
p != this->elements_.end();
|
||||
++p)
|
||||
{
|
||||
if ((*p)->needs_output_section())
|
||||
{
|
||||
const char* name = this->name_.c_str();
|
||||
this->output_section_ = layout->make_output_section_for_script(name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add any symbols being defined to the symbol table.
|
||||
|
||||
void
|
||||
|
@ -1391,14 +1433,14 @@ Output_section_definition::finalize_symbols(Symbol_table* symtab,
|
|||
if (this->address_ != NULL)
|
||||
{
|
||||
Output_section* dummy;
|
||||
address = this->address_->eval_with_dot(symtab, layout,
|
||||
address = this->address_->eval_with_dot(symtab, layout, true,
|
||||
*dot_value, NULL,
|
||||
&dummy);
|
||||
}
|
||||
if (this->align_ != NULL)
|
||||
{
|
||||
Output_section* dummy;
|
||||
uint64_t align = this->align_->eval_with_dot(symtab, layout,
|
||||
uint64_t align = this->align_->eval_with_dot(symtab, layout, true,
|
||||
*dot_value,
|
||||
NULL,
|
||||
&dummy);
|
||||
|
@ -1570,8 +1612,8 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
|
|||
else
|
||||
{
|
||||
Output_section* dummy;
|
||||
address = this->address_->eval_with_dot(symtab, layout, *dot_value,
|
||||
NULL, &dummy);
|
||||
address = this->address_->eval_with_dot(symtab, layout, true,
|
||||
*dot_value, NULL, &dummy);
|
||||
}
|
||||
|
||||
uint64_t align;
|
||||
|
@ -1585,7 +1627,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
|
|||
else
|
||||
{
|
||||
Output_section* align_section;
|
||||
align = this->align_->eval_with_dot(symtab, layout, *dot_value,
|
||||
align = this->align_->eval_with_dot(symtab, layout, true, *dot_value,
|
||||
NULL, &align_section);
|
||||
if (align_section != NULL)
|
||||
gold_warning(_("alignment of section %s is not absolute"),
|
||||
|
@ -1610,7 +1652,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
|
|||
{
|
||||
Output_section* dummy;
|
||||
uint64_t load_address =
|
||||
this->load_address_->eval_with_dot(symtab, layout, *dot_value,
|
||||
this->load_address_->eval_with_dot(symtab, layout, true, *dot_value,
|
||||
this->output_section_, &dummy);
|
||||
this->output_section_->set_load_address(load_address);
|
||||
}
|
||||
|
@ -1621,8 +1663,9 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
|
|||
else
|
||||
{
|
||||
Output_section* subalign_section;
|
||||
subalign = this->subalign_->eval_with_dot(symtab, layout, *dot_value,
|
||||
NULL, &subalign_section);
|
||||
subalign = this->subalign_->eval_with_dot(symtab, layout, true,
|
||||
*dot_value, NULL,
|
||||
&subalign_section);
|
||||
if (subalign_section != NULL)
|
||||
gold_warning(_("subalign of section %s is not absolute"),
|
||||
this->name_.c_str());
|
||||
|
@ -1634,7 +1677,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab,
|
|||
// FIXME: The GNU linker supports fill values of arbitrary
|
||||
// length.
|
||||
Output_section* fill_section;
|
||||
uint64_t fill_val = this->fill_->eval_with_dot(symtab, layout,
|
||||
uint64_t fill_val = this->fill_->eval_with_dot(symtab, layout, true,
|
||||
*dot_value,
|
||||
NULL,
|
||||
&fill_section);
|
||||
|
@ -2002,7 +2045,8 @@ class Phdrs_element
|
|||
eval_load_address(Symbol_table* symtab, Layout* layout)
|
||||
{
|
||||
if (this->load_address_ != NULL)
|
||||
this->load_address_value_ = this->load_address_->eval(symtab, layout);
|
||||
this->load_address_value_ = this->load_address_->eval(symtab, layout,
|
||||
true);
|
||||
}
|
||||
|
||||
// Return the load address.
|
||||
|
@ -2216,6 +2260,19 @@ Script_sections::add_input_section(const Input_section_spec* spec, bool keep)
|
|||
this->output_section_->add_input_section(spec, keep);
|
||||
}
|
||||
|
||||
// Create any required sections.
|
||||
|
||||
void
|
||||
Script_sections::create_sections(Layout* layout)
|
||||
{
|
||||
if (!this->saw_sections_clause_)
|
||||
return;
|
||||
for (Sections_elements::iterator p = this->sections_elements_->begin();
|
||||
p != this->sections_elements_->end();
|
||||
++p)
|
||||
(*p)->create_sections(layout);
|
||||
}
|
||||
|
||||
// Add any symbols we are defining to the symbol table.
|
||||
|
||||
void
|
||||
|
@ -2575,38 +2632,32 @@ Script_sections::create_segments(Layout* layout)
|
|||
// efficient in any case. We try to use the first PT_LOAD segment
|
||||
// if we can, otherwise we make a new one.
|
||||
|
||||
if (first_seg == NULL)
|
||||
return NULL;
|
||||
|
||||
size_t sizeof_headers = this->total_header_size(layout);
|
||||
|
||||
if (first_seg != NULL
|
||||
&& (first_seg->paddr() & (abi_pagesize - 1)) >= sizeof_headers)
|
||||
if ((first_seg->paddr() & (abi_pagesize - 1)) >= sizeof_headers)
|
||||
{
|
||||
first_seg->set_addresses(first_seg->vaddr() - sizeof_headers,
|
||||
first_seg->paddr() - sizeof_headers);
|
||||
return first_seg;
|
||||
}
|
||||
|
||||
Output_segment* load_seg = layout->make_output_segment(elfcpp::PT_LOAD,
|
||||
elfcpp::PF_R);
|
||||
if (first_seg == NULL)
|
||||
load_seg->set_addresses(0, 0);
|
||||
else
|
||||
{
|
||||
uint64_t vma = first_seg->vaddr();
|
||||
uint64_t lma = first_seg->paddr();
|
||||
|
||||
uint64_t subtract = this->header_size_adjustment(lma, sizeof_headers);
|
||||
if (lma >= subtract && vma >= subtract)
|
||||
|
||||
// If there is no room to squeeze in the headers, then punt. The
|
||||
// resulting executable probably won't run on GNU/Linux, but we
|
||||
// trust that the user knows what they are doing.
|
||||
if (lma < subtract || vma < subtract)
|
||||
return NULL;
|
||||
|
||||
Output_segment* load_seg = layout->make_output_segment(elfcpp::PT_LOAD,
|
||||
elfcpp::PF_R);
|
||||
load_seg->set_addresses(vma - subtract, lma - subtract);
|
||||
else
|
||||
{
|
||||
// We could handle this case by create the file header
|
||||
// outside of any PT_LOAD segment, and creating a new
|
||||
// PT_LOAD segment after the others to hold the segment
|
||||
// headers.
|
||||
gold_error(_("sections loaded on first page without room for "
|
||||
"file and program headers are not supported"));
|
||||
}
|
||||
}
|
||||
|
||||
return load_seg;
|
||||
}
|
||||
|
|
|
@ -106,6 +106,10 @@ class Script_sections
|
|||
void
|
||||
add_input_section(const Input_section_spec* spec, bool keep);
|
||||
|
||||
// Create any required sections.
|
||||
void
|
||||
create_sections(Layout*);
|
||||
|
||||
// Add any symbols we are defining to the symbol table.
|
||||
void
|
||||
add_symbols_to_table(Symbol_table*);
|
||||
|
|
|
@ -980,7 +980,7 @@ Symbol_assignment::sized_finalize(Symbol_table* symtab, const Layout* layout,
|
|||
Output_section* dot_section)
|
||||
{
|
||||
Output_section* section;
|
||||
uint64_t final_val = this->val_->eval_maybe_dot(symtab, layout,
|
||||
uint64_t final_val = this->val_->eval_maybe_dot(symtab, layout, true,
|
||||
is_dot_available,
|
||||
dot_value, dot_section,
|
||||
§ion);
|
||||
|
@ -1000,8 +1000,9 @@ Symbol_assignment::set_if_absolute(Symbol_table* symtab, const Layout* layout,
|
|||
return;
|
||||
|
||||
Output_section* val_section;
|
||||
uint64_t val = this->val_->eval_maybe_dot(symtab, layout, is_dot_available,
|
||||
dot_value, NULL, &val_section);
|
||||
uint64_t val = this->val_->eval_maybe_dot(symtab, layout, false,
|
||||
is_dot_available, dot_value,
|
||||
NULL, &val_section);
|
||||
if (val_section != NULL)
|
||||
return;
|
||||
|
||||
|
@ -1055,7 +1056,7 @@ Symbol_assignment::print(FILE* f) const
|
|||
void
|
||||
Script_assertion::check(const Symbol_table* symtab, const Layout* layout)
|
||||
{
|
||||
if (!this->check_->eval(symtab, layout))
|
||||
if (!this->check_->eval(symtab, layout, true))
|
||||
gold_error("%s", this->message_.c_str());
|
||||
}
|
||||
|
||||
|
@ -1122,6 +1123,15 @@ Script_options::add_assertion(Expression* check, const char* message,
|
|||
}
|
||||
}
|
||||
|
||||
// Create sections required by any linker scripts.
|
||||
|
||||
void
|
||||
Script_options::create_script_sections(Layout* layout)
|
||||
{
|
||||
if (this->saw_sections_clause())
|
||||
this->script_sections_.create_sections(layout);
|
||||
}
|
||||
|
||||
// Add any symbols we are defining to the symbol table.
|
||||
|
||||
void
|
||||
|
|
|
@ -67,9 +67,10 @@ class Expression
|
|||
{ }
|
||||
|
||||
// Return the value of the expression which is not permitted to
|
||||
// refer to the dot symbol.
|
||||
// refer to the dot symbol. CHECK_ASSERTIONS is true if we should
|
||||
// check whether assertions are true.
|
||||
uint64_t
|
||||
eval(const Symbol_table*, const Layout*);
|
||||
eval(const Symbol_table*, const Layout*, bool check_assertions);
|
||||
|
||||
// Return the value of an expression which is permitted to refer to
|
||||
// the dot symbol. DOT_VALUE is the absolute value of the dot
|
||||
|
@ -82,15 +83,17 @@ class Expression
|
|||
// value; to get a section relative value the caller must subtract
|
||||
// the section address.
|
||||
uint64_t
|
||||
eval_with_dot(const Symbol_table*, const Layout*, uint64_t dot_value,
|
||||
Output_section* dot_section, Output_section** result_section);
|
||||
eval_with_dot(const Symbol_table*, const Layout*, bool check_assertions,
|
||||
uint64_t dot_value, Output_section* dot_section,
|
||||
Output_section** result_section);
|
||||
|
||||
// Return the value of an expression which may or may not be
|
||||
// permitted to refer to the dot symbol, depending on
|
||||
// is_dot_available.
|
||||
uint64_t
|
||||
eval_maybe_dot(const Symbol_table*, const Layout*, bool is_dot_available,
|
||||
uint64_t dot_value, Output_section* dot_section,
|
||||
eval_maybe_dot(const Symbol_table*, const Layout*, bool check_assertions,
|
||||
bool is_dot_available, uint64_t dot_value,
|
||||
Output_section* dot_section,
|
||||
Output_section** result_section);
|
||||
|
||||
// Print the expression to the FILE. This is for debugging.
|
||||
|
@ -219,7 +222,7 @@ class Symbol_assignment
|
|||
|
||||
// Set the symbol value, but only if the value is absolute. This is
|
||||
// used while processing a SECTIONS clause. We assume that dot is
|
||||
// an absolute value here.
|
||||
// an absolute value here. We do not check assertions.
|
||||
void
|
||||
set_if_absolute(Symbol_table*, const Layout*, bool is_dot_available,
|
||||
uint64_t dot_value);
|
||||
|
@ -307,6 +310,10 @@ class Script_options
|
|||
bool
|
||||
define_symbol(const char* definition);
|
||||
|
||||
// Create sections required by any linker scripts.
|
||||
void
|
||||
create_script_sections(Layout*);
|
||||
|
||||
// Add all symbol definitions to the symbol table.
|
||||
void
|
||||
add_symbols_to_table(Symbol_table*);
|
||||
|
|
Loading…
Reference in a new issue