From f6973bdcb778ca7a54817a696cb0c6457f4ae96f Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 23 Apr 2010 04:47:33 +0000 Subject: * expression.cc (Expression::Expression_eval_info): Add result_alignment_pointer field. (Expression::eval_with_dot): Add result_alignment_pointer parameter. Change all callers. (Expression::eval_maybe_dot): Likewise. (class Binary_expression): Add alignment_pointer parameter to left_value and right_value. Change all callers. (BINARY_EXPRESSION): Set result alignment. (class Trinary_expression): Add alignment_pointer parameter to arg2_value and arg3_value. Change all callers. (Trinary_cond::value): Set result alignment. (Max_expression::value, Min_expression::value): Likewise. (Align_expression::value): Likewise. * script-sections.cc (class Sections_element): Add dot_alignment parameter to set_section_addresses virtual function. Update instantiations. (class Output_section_element): Likewise. (Script_sections::create_segments): Add dot_alignment parameter. Change all callers. (Script_sections::create_segments_from_phdrs_clause): Likewise. (Script_sections::set_phdrs_clause_addresses): Likewise. * script-sections.h: Update declarations. * script.h: Update declarations. * output.h (Output_segment::set_minimum_p_align): Don't decrease min_p_align. * testsuite/script_test_3.t: Set large alignment. * testsuite/script_test_3.sh: Make sure that at least one LOAD segment has expected alignment. --- gold/script-sections.cc | 92 +++++++++++++++++++++++++++++-------------------- 1 file changed, 55 insertions(+), 37 deletions(-) (limited to 'gold/script-sections.cc') diff --git a/gold/script-sections.cc b/gold/script-sections.cc index 24b9103..b4cbb40 100644 --- a/gold/script-sections.cc +++ b/gold/script-sections.cc @@ -369,7 +369,8 @@ class Sections_element // Set section addresses. This includes applying assignments if the // the expression is an absolute value. virtual void - set_section_addresses(Symbol_table*, Layout*, uint64_t*, uint64_t*) + set_section_addresses(Symbol_table*, Layout*, uint64_t*, uint64_t*, + uint64_t*) { } // Check a constraint (ONLY_IF_RO, etc.) on an output section. If @@ -447,7 +448,7 @@ class Sections_element_assignment : public Sections_element // absolute symbols when setting dot. void set_section_addresses(Symbol_table* symtab, Layout* layout, - uint64_t* dot_value, uint64_t*) + uint64_t* dot_value, uint64_t*, uint64_t*) { this->assignment_.set_if_absolute(symtab, layout, true, *dot_value); } @@ -484,17 +485,18 @@ class Sections_element_dot_assignment : public Sections_element // to be absolute. Output_section* dummy; *dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value, - NULL, &dummy); + NULL, &dummy, NULL); } // Update the dot symbol while setting section addresses. void set_section_addresses(Symbol_table* symtab, Layout* layout, - uint64_t* dot_value, uint64_t* load_address) + uint64_t* dot_value, uint64_t* dot_alignment, + uint64_t* load_address) { Output_section* dummy; *dot_value = this->val_->eval_with_dot(symtab, layout, false, *dot_value, - NULL, &dummy); + NULL, &dummy, dot_alignment); *load_address = *dot_value; } @@ -577,7 +579,7 @@ class Output_section_element // the expression is an absolute value. virtual void set_section_addresses(Symbol_table*, Layout*, Output_section*, uint64_t, - uint64_t*, Output_section**, std::string*, + uint64_t*, uint64_t*, Output_section**, std::string*, Input_section_list*) { } @@ -635,8 +637,8 @@ class Output_section_element_assignment : public Output_section_element // absolute symbols when setting dot. void set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*, - uint64_t, uint64_t* dot_value, Output_section**, - std::string*, Input_section_list*) + uint64_t, uint64_t* dot_value, uint64_t*, + Output_section**, std::string*, Input_section_list*) { this->assignment_.set_if_absolute(symtab, layout, true, *dot_value); } @@ -668,14 +670,14 @@ class Output_section_element_dot_assignment : public Output_section_element uint64_t* dot_value, Output_section** dot_section) { *dot_value = this->val_->eval_with_dot(symtab, layout, true, *dot_value, - *dot_section, dot_section); + *dot_section, dot_section, NULL); } // Update the dot symbol while setting section addresses. void set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*, - uint64_t, uint64_t* dot_value, Output_section**, - std::string*, Input_section_list*); + uint64_t, uint64_t* dot_value, uint64_t*, + Output_section**, std::string*, Input_section_list*); // Print for debugging. void @@ -699,13 +701,14 @@ Output_section_element_dot_assignment::set_section_addresses( Output_section* output_section, uint64_t, uint64_t* dot_value, + uint64_t* dot_alignment, Output_section** dot_section, std::string* fill, Input_section_list*) { uint64_t next_dot = this->val_->eval_with_dot(symtab, layout, false, *dot_value, *dot_section, - dot_section); + dot_section, dot_alignment); if (next_dot < *dot_value) gold_error(_("dot may not move backward")); if (next_dot > *dot_value && output_section != NULL) @@ -807,7 +810,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_, true, this->dot_value_, - this->dot_section_, &dummy); + this->dot_section_, &dummy, NULL); if (parameters->target().is_big_endian()) this->endian_write_to_buffer(val, buf); @@ -868,8 +871,8 @@ class Output_section_element_data : public Output_section_element // Store the value in the section. void set_section_addresses(Symbol_table*, Layout*, Output_section*, uint64_t, - uint64_t* dot_value, Output_section**, std::string*, - Input_section_list*); + uint64_t* dot_value, uint64_t*, Output_section**, + std::string*, Input_section_list*); // Print for debugging. void @@ -893,6 +896,7 @@ Output_section_element_data::set_section_addresses( Output_section* os, uint64_t, uint64_t* dot_value, + uint64_t*, Output_section** dot_section, std::string*, Input_section_list*) @@ -949,14 +953,14 @@ class Output_section_element_fill : public Output_section_element // Update the fill value while setting section addresses. void set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*, - uint64_t, uint64_t* dot_value, + uint64_t, uint64_t* dot_value, uint64_t*, Output_section** dot_section, std::string* fill, Input_section_list*) { Output_section* fill_section; uint64_t fill_val = this->val_->eval_with_dot(symtab, layout, false, *dot_value, *dot_section, - &fill_section); + &fill_section, NULL); if (fill_section != NULL) gold_warning(_("fill value is not absolute")); // FIXME: The GNU linker supports fill values of arbitrary length. @@ -1012,7 +1016,7 @@ class Output_section_element_input : public Output_section_element // Set the section address. void set_section_addresses(Symbol_table* symtab, Layout* layout, Output_section*, - uint64_t subalign, uint64_t* dot_value, + uint64_t subalign, uint64_t* dot_value, uint64_t*, Output_section**, std::string* fill, Input_section_list*); @@ -1309,6 +1313,7 @@ Output_section_element_input::set_section_addresses( 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) @@ -1629,7 +1634,8 @@ class Output_section_definition : public Sections_element // Set the section address. void set_section_addresses(Symbol_table* symtab, Layout* layout, - uint64_t* dot_value, uint64_t* load_address); + uint64_t* dot_value, uint64_t*, + uint64_t* load_address); // Check a constraint (ONLY_IF_RO, etc.) on an output section. If // this section is constrained, and the input sections do not match, @@ -1861,7 +1867,7 @@ Output_section_definition::finalize_symbols(Symbol_table* symtab, Output_section* dummy; address = this->address_->eval_with_dot(symtab, layout, true, *dot_value, NULL, - &dummy); + &dummy, NULL); } if (this->align_ != NULL) { @@ -1869,7 +1875,7 @@ Output_section_definition::finalize_symbols(Symbol_table* symtab, uint64_t align = this->align_->eval_with_dot(symtab, layout, true, *dot_value, NULL, - &dummy); + &dummy, NULL); address = align_address(address, align); } *dot_value = address; @@ -1918,6 +1924,7 @@ void Output_section_definition::set_section_addresses(Symbol_table* symtab, Layout* layout, uint64_t* dot_value, + uint64_t* dot_alignment, uint64_t* load_address) { uint64_t address; @@ -1930,7 +1937,8 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, { Output_section* dummy; address = this->address_->eval_with_dot(symtab, layout, true, - *dot_value, NULL, &dummy); + *dot_value, NULL, &dummy, + dot_alignment); } uint64_t align; @@ -1945,7 +1953,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, { Output_section* align_section; align = this->align_->eval_with_dot(symtab, layout, true, *dot_value, - NULL, &align_section); + NULL, &align_section, NULL); if (align_section != NULL) gold_warning(_("alignment of section %s is not absolute"), this->name_.c_str()); @@ -1976,7 +1984,8 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, Output_section* dummy; uint64_t laddr = this->load_address_->eval_with_dot(symtab, layout, true, *dot_value, - this->output_section_, &dummy); + this->output_section_, &dummy, + NULL); if (this->output_section_ != NULL) this->output_section_->set_load_address(laddr); this->evaluated_load_address_ = laddr; @@ -1990,7 +1999,7 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, Output_section* subalign_section; subalign = this->subalign_->eval_with_dot(symtab, layout, true, *dot_value, NULL, - &subalign_section); + &subalign_section, NULL); if (subalign_section != NULL) gold_warning(_("subalign of section %s is not absolute"), this->name_.c_str()); @@ -2004,8 +2013,8 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, Output_section* fill_section; uint64_t fill_val = this->fill_->eval_with_dot(symtab, layout, true, *dot_value, - NULL, - &fill_section); + NULL, &fill_section, + NULL); if (fill_section != NULL) gold_warning(_("fill of section %s is not absolute"), this->name_.c_str()); @@ -2031,8 +2040,8 @@ Output_section_definition::set_section_addresses(Symbol_table* symtab, p != this->elements_.end(); ++p) (*p)->set_section_addresses(symtab, layout, this->output_section_, - subalign, dot_value, &dot_section, &fill, - &input_sections); + subalign, dot_value, dot_alignment, + &dot_section, &fill, &input_sections); gold_assert(input_sections.empty()); @@ -2339,7 +2348,8 @@ class Orphan_output_section : public Sections_element // Set section addresses. void - set_section_addresses(Symbol_table*, Layout*, uint64_t*, uint64_t*); + set_section_addresses(Symbol_table*, Layout*, uint64_t*, uint64_t*, + uint64_t*); // Get the list of segments to use for an allocated section when // using a PHDRS clause. @@ -2368,6 +2378,7 @@ class Orphan_output_section : public Sections_element void Orphan_output_section::set_section_addresses(Symbol_table*, Layout*, uint64_t* dot_value, + uint64_t*, uint64_t* load_address) { typedef std::list Input_section_list; @@ -2950,6 +2961,7 @@ Script_sections::set_section_addresses(Symbol_table* symtab, Layout* layout) // For a relocatable link, we implicitly set dot to zero. uint64_t dot_value = 0; + uint64_t dot_alignment = 0; uint64_t load_address = 0; // Check to see if we want to use any of -Ttext, -Tdata and -Tbss options @@ -2995,7 +3007,8 @@ Script_sections::set_section_addresses(Symbol_table* symtab, Layout* layout) } } - (*p)->set_section_addresses(symtab, layout, &dot_value, &load_address); + (*p)->set_section_addresses(symtab, layout, &dot_value, &dot_alignment, + &load_address); } if (this->phdrs_elements_ != NULL) @@ -3006,7 +3019,7 @@ Script_sections::set_section_addresses(Symbol_table* symtab, Layout* layout) (*p)->eval_load_address(symtab, layout); } - return this->create_segments(layout); + return this->create_segments(layout, dot_alignment); } // Sort the sections in order to put them into segments. @@ -3114,7 +3127,7 @@ Script_sections::header_size_adjustment(uint64_t lma, // if any. Output_segment* -Script_sections::create_segments(Layout* layout) +Script_sections::create_segments(Layout* layout, uint64_t dot_alignment) { gold_assert(this->saw_sections_clause_); @@ -3122,7 +3135,7 @@ Script_sections::create_segments(Layout* layout) return NULL; if (this->saw_phdrs_clause()) - return create_segments_from_phdrs_clause(layout); + return create_segments_from_phdrs_clause(layout, dot_alignment); Layout::Section_list sections; layout->get_allocated_sections(§ions); @@ -3195,6 +3208,7 @@ Script_sections::create_segments(Layout* layout) current_seg = layout->make_output_segment(elfcpp::PT_LOAD, seg_flags); current_seg->set_addresses(vma, lma); + current_seg->set_minimum_p_align(dot_alignment); if (first_seg == NULL) first_seg = current_seg; is_current_seg_readonly = true; @@ -3388,10 +3402,11 @@ Script_sections::expected_segment_count(const Layout* layout) const // should hold the file header and program headers, if any. Output_segment* -Script_sections::create_segments_from_phdrs_clause(Layout* layout) +Script_sections::create_segments_from_phdrs_clause(Layout* layout, + uint64_t dot_alignment) { this->attach_sections_using_phdrs_clause(layout); - return this->set_phdrs_clause_addresses(layout); + return this->set_phdrs_clause_addresses(layout, dot_alignment); } // Create the segments from the PHDRS clause, and put the output @@ -3485,7 +3500,8 @@ Script_sections::attach_sections_using_phdrs_clause(Layout* layout) // if any. Output_segment* -Script_sections::set_phdrs_clause_addresses(Layout* layout) +Script_sections::set_phdrs_clause_addresses(Layout* layout, + uint64_t dot_alignment) { Output_segment* load_seg = NULL; for (Phdrs_elements::const_iterator p = this->phdrs_elements_->begin(); @@ -3508,6 +3524,8 @@ Script_sections::set_phdrs_clause_addresses(Layout* layout) continue; } + oseg->set_minimum_p_align(dot_alignment); + // The output sections should have addresses from the SECTIONS // clause. The addresses don't have to be in order, so find the // one with the lowest load address. Use that to set the -- cgit v1.1