Line 678... |
Line 678... |
// absolute symbols when setting dot.
|
// absolute symbols when setting dot.
|
void
|
void
|
set_section_addresses(Symbol_table* symtab, Layout* layout,
|
set_section_addresses(Symbol_table* symtab, Layout* layout,
|
uint64_t* dot_value, uint64_t*, uint64_t*)
|
uint64_t* dot_value, uint64_t*, uint64_t*)
|
{
|
{
|
this->assignment_.set_if_absolute(symtab, layout, true, *dot_value);
|
this->assignment_.set_if_absolute(symtab, layout, true, *dot_value, NULL);
|
}
|
}
|
|
|
// Print for debugging.
|
// Print for debugging.
|
void
|
void
|
print(FILE* f) const
|
print(FILE* f) const
|
Line 712... |
Line 712... |
{
|
{
|
// We ignore the section of the result because outside of an
|
// We ignore the section of the result because outside of an
|
// output section definition the dot symbol is always considered
|
// output section definition the dot symbol is always considered
|
// to be absolute.
|
// to be absolute.
|
*dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value,
|
*dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value,
|
NULL, NULL, NULL);
|
NULL, NULL, NULL, false);
|
}
|
}
|
|
|
// Update the dot symbol while setting section addresses.
|
// Update the dot symbol while setting section addresses.
|
void
|
void
|
set_section_addresses(Symbol_table* symtab, Layout* layout,
|
set_section_addresses(Symbol_table* symtab, Layout* layout,
|
uint64_t* dot_value, uint64_t* dot_alignment,
|
uint64_t* dot_value, uint64_t* dot_alignment,
|
uint64_t* load_address)
|
uint64_t* load_address)
|
{
|
{
|
*dot_value = this->val_->eval_with_dot(symtab, layout, false, *dot_value,
|
*dot_value = this->val_->eval_with_dot(symtab, layout, false, *dot_value,
|
NULL, NULL, dot_alignment);
|
NULL, NULL, dot_alignment, false);
|
*load_address = *dot_value;
|
*load_address = *dot_value;
|
}
|
}
|
|
|
// Print for debugging.
|
// Print for debugging.
|
void
|
void
|
Line 864... |
Line 864... |
// value is absolute, we set the symbol. This permits us to use
|
// value is absolute, we set the symbol. This permits us to use
|
// absolute symbols when setting dot.
|
// absolute symbols when setting dot.
|
void
|
void
|
set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*,
|
set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*,
|
uint64_t, uint64_t* dot_value, uint64_t*,
|
uint64_t, uint64_t* dot_value, uint64_t*,
|
Output_section**, std::string*, Input_section_list*)
|
Output_section** dot_section, std::string*,
|
|
Input_section_list*)
|
{
|
{
|
this->assignment_.set_if_absolute(symtab, layout, true, *dot_value);
|
this->assignment_.set_if_absolute(symtab, layout, true, *dot_value,
|
|
*dot_section);
|
}
|
}
|
|
|
// Print for debugging.
|
// Print for debugging.
|
void
|
void
|
print(FILE* f) const
|
print(FILE* f) const
|
Line 890... |
Line 892... |
public:
|
public:
|
Output_section_element_dot_assignment(Expression* val)
|
Output_section_element_dot_assignment(Expression* val)
|
: val_(val)
|
: val_(val)
|
{ }
|
{ }
|
|
|
|
// An assignment to dot within an output section is enough to force
|
|
// the output section to exist.
|
|
bool
|
|
needs_output_section() const
|
|
{ return true; }
|
|
|
// Finalize the symbol.
|
// Finalize the symbol.
|
void
|
void
|
finalize_symbols(Symbol_table* symtab, const Layout* layout,
|
finalize_symbols(Symbol_table* symtab, const Layout* layout,
|
uint64_t* dot_value, Output_section** dot_section)
|
uint64_t* dot_value, Output_section** dot_section)
|
{
|
{
|
*dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value,
|
*dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value,
|
*dot_section, dot_section, NULL);
|
*dot_section, dot_section, NULL,
|
|
true);
|
}
|
}
|
|
|
// Update the dot symbol while setting section addresses.
|
// Update the dot symbol while setting section addresses.
|
void
|
void
|
set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*,
|
set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*,
|
uint64_t, uint64_t* dot_value, uint64_t*,
|
uint64_t, uint64_t* dot_value, uint64_t*,
|
Output_section**, std::string*, Input_section_list*);
|
Output_section** dot_section, std::string*,
|
|
Input_section_list*);
|
|
|
// Print for debugging.
|
// Print for debugging.
|
void
|
void
|
print(FILE* f) const
|
print(FILE* f) const
|
{
|
{
|
Line 934... |
Line 944... |
std::string* fill,
|
std::string* fill,
|
Input_section_list*)
|
Input_section_list*)
|
{
|
{
|
uint64_t next_dot = this->val_->eval_with_dot(symtab, layout, false,
|
uint64_t next_dot = this->val_->eval_with_dot(symtab, layout, false,
|
*dot_value, *dot_section,
|
*dot_value, *dot_section,
|
dot_section, dot_alignment);
|
dot_section, dot_alignment,
|
|
true);
|
if (next_dot < *dot_value)
|
if (next_dot < *dot_value)
|
gold_error(_("dot may not move backward"));
|
gold_error(_("dot may not move backward"));
|
if (next_dot > *dot_value && output_section != NULL)
|
if (next_dot > *dot_value && output_section != NULL)
|
{
|
{
|
section_size_type length = convert_to_section_size_type(next_dot
|
section_size_type length = convert_to_section_size_type(next_dot
|
Line 1035... |
Line 1046... |
void
|
void
|
Output_data_expression::do_write_to_buffer(unsigned char* buf)
|
Output_data_expression::do_write_to_buffer(unsigned char* buf)
|
{
|
{
|
uint64_t val = this->val_->eval_with_dot(this->symtab_, this->layout_,
|
uint64_t val = this->val_->eval_with_dot(this->symtab_, this->layout_,
|
true, this->dot_value_,
|
true, this->dot_value_,
|
this->dot_section_, NULL, NULL);
|
this->dot_section_, NULL, NULL,
|
|
false);
|
|
|
if (parameters->target().is_big_endian())
|
if (parameters->target().is_big_endian())
|
this->endian_write_to_buffer<true>(val, buf);
|
this->endian_write_to_buffer<true>(val, buf);
|
else
|
else
|
this->endian_write_to_buffer<false>(val, buf);
|
this->endian_write_to_buffer<false>(val, buf);
|
Line 1185... |
Line 1197... |
std::string* fill, Input_section_list*)
|
std::string* fill, Input_section_list*)
|
{
|
{
|
Output_section* fill_section;
|
Output_section* fill_section;
|
uint64_t fill_val = this->val_->eval_with_dot(symtab, layout, false,
|
uint64_t fill_val = this->val_->eval_with_dot(symtab, layout, false,
|
*dot_value, *dot_section,
|
*dot_value, *dot_section,
|
&fill_section, NULL);
|
&fill_section, NULL, false);
|
if (fill_section != NULL)
|
if (fill_section != NULL)
|
gold_warning(_("fill value is not absolute"));
|
gold_warning(_("fill value is not absolute"));
|
// FIXME: The GNU linker supports fill values of arbitrary length.
|
// FIXME: The GNU linker supports fill values of arbitrary length.
|
unsigned char fill_buff[4];
|
unsigned char fill_buff[4];
|
elfcpp::Swap_unaligned<32, true>::writeval(fill_buff, fill_val);
|
elfcpp::Swap_unaligned<32, true>::writeval(fill_buff, fill_val);
|
Line 2106... |
Line 2118... |
uint64_t address = *dot_value;
|
uint64_t address = *dot_value;
|
if (this->address_ != NULL)
|
if (this->address_ != NULL)
|
{
|
{
|
address = this->address_->eval_with_dot(symtab, layout, true,
|
address = this->address_->eval_with_dot(symtab, layout, true,
|
*dot_value, NULL,
|
*dot_value, NULL,
|
NULL, NULL);
|
NULL, NULL, false);
|
}
|
}
|
if (this->align_ != NULL)
|
if (this->align_ != NULL)
|
{
|
{
|
uint64_t align = this->align_->eval_with_dot(symtab, layout, true,
|
uint64_t align = this->align_->eval_with_dot(symtab, layout, true,
|
*dot_value, NULL,
|
*dot_value, NULL,
|
NULL, NULL);
|
NULL, NULL, false);
|
address = align_address(address, align);
|
address = align_address(address, align);
|
}
|
}
|
*dot_value = address;
|
*dot_value = address;
|
}
|
}
|
|
|
Line 2301... |
Line 2313... |
address = *dot_value;
|
address = *dot_value;
|
}
|
}
|
else
|
else
|
address = this->address_->eval_with_dot(symtab, layout, true,
|
address = this->address_->eval_with_dot(symtab, layout, true,
|
*dot_value, NULL, NULL,
|
*dot_value, NULL, NULL,
|
dot_alignment);
|
dot_alignment, false);
|
uint64_t align;
|
uint64_t align;
|
if (this->align_ == NULL)
|
if (this->align_ == NULL)
|
{
|
{
|
if (this->output_section_ == NULL)
|
if (this->output_section_ == NULL)
|
align = 0;
|
align = 0;
|
Line 2314... |
Line 2326... |
}
|
}
|
else
|
else
|
{
|
{
|
Output_section* align_section;
|
Output_section* align_section;
|
align = this->align_->eval_with_dot(symtab, layout, true, *dot_value,
|
align = this->align_->eval_with_dot(symtab, layout, true, *dot_value,
|
NULL, &align_section, NULL);
|
NULL, &align_section, NULL, false);
|
if (align_section != NULL)
|
if (align_section != NULL)
|
gold_warning(_("alignment of section %s is not absolute"),
|
gold_warning(_("alignment of section %s is not absolute"),
|
this->name_.c_str());
|
this->name_.c_str());
|
if (this->output_section_ != NULL)
|
if (this->output_section_ != NULL)
|
this->output_section_->set_addralign(align);
|
this->output_section_->set_addralign(align);
|
Line 2399... |
Line 2411... |
else
|
else
|
{
|
{
|
laddr = this->load_address_->eval_with_dot(symtab, layout, true,
|
laddr = this->load_address_->eval_with_dot(symtab, layout, true,
|
*dot_value,
|
*dot_value,
|
this->output_section_,
|
this->output_section_,
|
NULL, NULL);
|
NULL, NULL, false);
|
if (this->output_section_ != NULL)
|
if (this->output_section_ != NULL)
|
this->output_section_->set_load_address(laddr);
|
this->output_section_->set_load_address(laddr);
|
}
|
}
|
|
|
this->evaluated_load_address_ = laddr;
|
this->evaluated_load_address_ = laddr;
|
Line 2414... |
Line 2426... |
else
|
else
|
{
|
{
|
Output_section* subalign_section;
|
Output_section* subalign_section;
|
subalign = this->subalign_->eval_with_dot(symtab, layout, true,
|
subalign = this->subalign_->eval_with_dot(symtab, layout, true,
|
*dot_value, NULL,
|
*dot_value, NULL,
|
&subalign_section, NULL);
|
&subalign_section, NULL,
|
|
false);
|
if (subalign_section != NULL)
|
if (subalign_section != NULL)
|
gold_warning(_("subalign of section %s is not absolute"),
|
gold_warning(_("subalign of section %s is not absolute"),
|
this->name_.c_str());
|
this->name_.c_str());
|
}
|
}
|
|
|
Line 2429... |
Line 2442... |
// length.
|
// length.
|
Output_section* fill_section;
|
Output_section* fill_section;
|
uint64_t fill_val = this->fill_->eval_with_dot(symtab, layout, true,
|
uint64_t fill_val = this->fill_->eval_with_dot(symtab, layout, true,
|
*dot_value,
|
*dot_value,
|
NULL, &fill_section,
|
NULL, &fill_section,
|
NULL);
|
NULL, false);
|
if (fill_section != NULL)
|
if (fill_section != NULL)
|
gold_warning(_("fill of section %s is not absolute"),
|
gold_warning(_("fill of section %s is not absolute"),
|
this->name_.c_str());
|
this->name_.c_str());
|
unsigned char fill_buff[4];
|
unsigned char fill_buff[4];
|
elfcpp::Swap_unaligned<32, true>::writeval(fill_buff, fill_val);
|
elfcpp::Swap_unaligned<32, true>::writeval(fill_buff, fill_val);
|