diff options
author | Roland McGrath <roland@gnu.org> | 2013-07-19 23:07:08 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 2013-07-19 23:07:08 +0000 |
commit | a3ed37d8bcb97329ff3acebba63c754d153d3363 (patch) | |
tree | 5808e3e5905998fac75b21690ff89878e316c35c /gold/layout.cc | |
parent | 69091a2cc4cfdd51d5b63c2925ab50ba6aa094cf (diff) | |
download | gdb-a3ed37d8bcb97329ff3acebba63c754d153d3363.zip gdb-a3ed37d8bcb97329ff3acebba63c754d153d3363.tar.gz gdb-a3ed37d8bcb97329ff3acebba63c754d153d3363.tar.bz2 |
gold/
* options.h (General_options): Add -Trodata-segment option.
* parameters.cc (Parameters::check_rodata_segment): New function.
(Parameters::set_target_once): Call it.
* parameters.h (Parameters): Declare it (private member function).
* layout.cc (load_seg_unusable_for_headers): New function, broken
out of Layout::relaxation_loop_body. If TARGET->isolate_execinstr()
then validate rodata segment rather than text segment.
(relaxation_loop_body): Call that.
(is_text_segment): New function. Don't admit a non-executable
segment if TARGET->isolate_execinstr().
(set_segment_offsets): Call it. Honor -Trodata-segment option.
Diffstat (limited to 'gold/layout.cc')
-rw-r--r-- | gold/layout.cc | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/gold/layout.cc b/gold/layout.cc index 818773a..07dbc9b 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -2369,6 +2369,22 @@ Layout::prepare_for_relaxation() this->record_output_section_data_from_script_ = true; } +// If the user set the address of the text segment, that may not be +// compatible with putting the segment headers and file headers into +// that segment. For isolate_execinstr() targets, it's the rodata +// segment rather than text where we might put the headers. +static inline bool +load_seg_unusable_for_headers(const Target* target) +{ + const General_options& options = parameters->options(); + if (target->isolate_execinstr()) + return (options.user_set_Trodata_segment() + && options.Trodata_segment() % target->abi_pagesize() != 0); + else + return (options.user_set_Ttext() + && options.Ttext() % target->abi_pagesize() != 0); +} + // Relaxation loop body: If target has no relaxation, this runs only once // Otherwise, the target relaxation hook is called at the end of // each iteration. If the hook returns true, it means re-layout of @@ -2421,11 +2437,7 @@ Layout::relaxation_loop_body( != General_options::OBJECT_FORMAT_ELF) load_seg = NULL; - // If the user set the address of the text segment, that may not be - // compatible with putting the segment headers and file headers into - // that segment. - if (parameters->options().user_set_Ttext() - && parameters->options().Ttext() % target->abi_pagesize() != 0) + if (load_seg_unusable_for_headers(target)) { load_seg = NULL; phdr_seg = NULL; @@ -3319,6 +3331,20 @@ align_file_offset(off_t off, uint64_t addr, uint64_t abi_pagesize) return aligned_off; } +// On targets where the text segment contains only executable code, +// a non-executable segment is never the text segment. + +static inline bool +is_text_segment(const Target* target, const Output_segment* seg) +{ + elfcpp::Elf_Xword flags = seg->flags(); + if ((flags & elfcpp::PF_W) != 0) + return false; + if ((flags & elfcpp::PF_X) == 0) + return !target->isolate_execinstr(); + return true; +} + // Set the file offsets of all the segments, and all the sections they // contain. They have all been created. LOAD_SEG must be be laid out // first. Return the offset of the data to follow. @@ -3411,8 +3437,14 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg, } else if (parameters->options().user_set_Ttext() && (parameters->options().omagic() - || ((*p)->flags() & elfcpp::PF_W) == 0)) + || is_text_segment(target, *p))) + { + are_addresses_set = true; + } + else if (parameters->options().user_set_Trodata_segment() + && ((*p)->flags() & (elfcpp::PF_W | elfcpp::PF_X)) == 0) { + addr = parameters->options().Trodata_segment(); are_addresses_set = true; } else if (parameters->options().user_set_Tdata() |