aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gold/ChangeLog11
-rw-r--r--gold/layout.cc4
-rw-r--r--gold/output.cc20
-rw-r--r--gold/output.h2
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