diff options
-rw-r--r-- | gold/ChangeLog | 11 | ||||
-rw-r--r-- | gold/layout.cc | 4 | ||||
-rw-r--r-- | gold/output.cc | 20 | ||||
-rw-r--r-- | gold/output.h | 2 |
4 files changed, 32 insertions, 5 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index c48ea60..2e3b87f 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,14 @@ +2010-11-16 Doug Kwan <dougkwan@google.com> + Cary Coutant <ccoutant@google.com> + + * output.h (Output_segment::set_section_addresses): Pass increase_relro + by reference; adjust all callers. + * output.cc (Output_segment::set_section_addresses): Adjust references + to increase_relro. Add padding to *increase_relro when ORDER_RELRO_LAST + list is empty. + (Output_segment::set_offset): Assert if PT_GNU_RELRO segment does not + end at page boundary. + 2010-11-16 Cary Coutant <ccoutant@google.com> PR gold/12220 diff --git a/gold/layout.cc b/gold/layout.cc index f5784fb..52120cc 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -2679,7 +2679,7 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg, unsigned int shndx_hold = *pshndx; bool has_relro = false; uint64_t new_addr = (*p)->set_section_addresses(this, false, addr, - increase_relro, + &increase_relro, &has_relro, &off, pshndx); @@ -2709,7 +2709,7 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg, off = orig_off + ((addr - orig_addr) & (abi_pagesize - 1)); off = align_file_offset(off, addr, abi_pagesize); new_addr = (*p)->set_section_addresses(this, true, addr, - increase_relro, + &increase_relro, &has_relro, &off, pshndx); } diff --git a/gold/output.cc b/gold/output.cc index 766e0ff..1158a77 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -3692,7 +3692,7 @@ Output_segment::has_dynamic_reloc_list(const Output_data_list* pdl) const uint64_t Output_segment::set_section_addresses(const Layout* layout, bool reset, uint64_t addr, - unsigned int increase_relro, + unsigned int* increase_relro, bool* has_relro, off_t* poff, unsigned int* pshndx) @@ -3752,7 +3752,7 @@ Output_segment::set_section_addresses(const Layout* layout, bool reset, if (p != pdl->end()) break; } - relro_size += increase_relro; + relro_size += *increase_relro; // Pad the total relro size to a multiple of the maximum // section alignment seen. uint64_t aligned_size = align_address(relro_size, max_align); @@ -3795,6 +3795,13 @@ Output_segment::set_section_addresses(const Layout* layout, bool reset, { *poff += last_relro_pad; addr += last_relro_pad; + if (this->output_lists_[i].empty()) + { + // If there is nothing in the ORDER_RELRO_LAST list, + // the padding will occur at the end of the relro + // segment, and we need to add it to *INCREASE_RELRO. + *increase_relro += last_relro_pad; + } } addr = this->set_section_list_addresses(layout, reset, &this->output_lists_[i], @@ -4014,6 +4021,15 @@ Output_segment::set_offset(unsigned int increase) this->filesz_ += increase; this->memsz_ += increase; + // If this is a RELRO segment, verify that the segment ends at a + // page boundary. + if (this->type_ == elfcpp::PT_GNU_RELRO) + { + uint64_t page_align = parameters->target().common_pagesize(); + uint64_t segment_end = this->vaddr_ + this->memsz_; + gold_assert(segment_end == align_address(segment_end, page_align)); + } + // If this is a TLS segment, align the memory size. The code in // set_section_list ensures that the section after the TLS segment // is aligned to give us room. diff --git a/gold/output.h b/gold/output.h index 1bfb054..9ccc21a 100644 --- a/gold/output.h +++ b/gold/output.h @@ -3911,7 +3911,7 @@ class Output_segment // *PSHNDX. This should only be called for a PT_LOAD segment. uint64_t set_section_addresses(const Layout*, bool reset, uint64_t addr, - unsigned int increase_relro, bool* has_relro, + unsigned int* increase_relro, bool* has_relro, off_t* poff, unsigned int* pshndx); // Set the minimum alignment of this segment. This may be adjusted |