[PATCH][GOLD] Handle -Ttext, -Tdata and -Tbss options in scripts.
Doug Kwan (關振德)
dougkwan@google.com
Thu Oct 15 09:06:00 GMT 2009
Hi,
This patch adds support of -Ttext, -Tdata and -Tbss options in
scripts. Basically, it does a dot assignment at the first section of
the appropriate type.
-Doug
2009-10-15 Doug Kwan <dougkwan@google.com>
* script-sections.cc (Script_sections::set_section_addresses):
Handle -Ttext, -Tdata and -Tbbs options.
(Script_sections::create_segments): If the -Tbss option is used,
begin a new segment when seeing a new run of BBS sections.
-------------- next part --------------
Index: gold/script-sections.cc
===================================================================
RCS file: /cvs/src/src/gold/script-sections.cc,v
retrieving revision 1.22
diff -u -p -r1.22 script-sections.cc
--- gold/script-sections.cc 9 Oct 2009 23:18:19 -0000 1.22
+++ gold/script-sections.cc 15 Oct 2009 08:46:55 -0000
@@ -2827,10 +2827,69 @@ Script_sections::set_section_addresses(S
// For a relocatable link, we implicitly set dot to zero.
uint64_t dot_value = 0;
uint64_t load_address = 0;
+
+ bool any_T_segment_address_set =
+ (parameters->options().user_set_Ttext()
+ || parameters->options().user_set_Tdata()
+ || parameters->options().user_set_Tbss());
+ bool first_read_only_section_seen = false;
+ bool first_writable_section_seen = false;
+ bool first_nobits_section_seen = false;
for (Sections_elements::iterator p = this->sections_elements_->begin();
p != this->sections_elements_->end();
++p)
- (*p)->set_section_addresses(symtab, layout, &dot_value, &load_address);
+ {
+ Output_section* os = (*p)->get_output_section();
+
+ // Handle -Ttext, -Tdata and -Tbss options. We do this by looking for
+ // the first section of the appropriate type for each of these segments
+ // and do a dot assignment right before that.
+ if (any_T_segment_address_set
+ && os != NULL
+ && (os->flags() & elfcpp::SHF_ALLOC) != 0)
+ {
+ uint64_t new_dot_value = dot_value;
+
+ if (!first_read_only_section_seen
+ && (os->flags() & elfcpp::SHF_WRITE) == 0)
+ {
+ // We assume the segment containing the first read-only
+ // section to be the text segment.
+ if (parameters->options().user_set_Ttext())
+ new_dot_value = parameters->options().Ttext();
+ first_read_only_section_seen = true;
+ }
+ else if (!first_writable_section_seen
+ && (os->flags() & elfcpp::SHF_WRITE) != 0)
+ {
+ // We assume the segment containing the first writable
+ // section to be the data segment.
+ if (parameters->options().user_set_Tdata())
+ new_dot_value = parameters->options().Tdata();
+ first_writable_section_seen = true;
+ }
+ else if (!first_nobits_section_seen
+ && os->type() == elfcpp::SHT_NOBITS)
+ {
+ // We assume the segment containing the first NOBITS section to
+ // be the bss segment.
+ if (parameters->options().user_set_Tbss())
+ new_dot_value = parameters->options().Tbss();
+ first_nobits_section_seen = true;
+ }
+
+ // Update dot and load address if necessary.
+ if (new_dot_value < dot_value)
+ gold_error(_("dot may not move backward"));
+ else if (new_dot_value != dot_value)
+ {
+ dot_value = new_dot_value;
+ load_address = new_dot_value;
+ }
+ }
+
+ (*p)->set_section_addresses(symtab, layout, &dot_value, &load_address);
+ }
if (this->phdrs_elements_ != NULL)
{
@@ -2995,6 +3054,14 @@ Script_sections::create_segments(Layout*
// skipping a page.
need_new_segment = true;
}
+ else if (parameters->options().user_set_Tbss()
+ && !is_bss_section(*plast)
+ && is_bss_section(*p))
+ {
+ // If -Tbss is specified, we need to separate the data and BSS
+ // segments.
+ need_new_segment = true;
+ }
else if (is_bss_section(*plast) && !is_bss_section(*p))
{
// A non-BSS section can not follow a BSS section in the
More information about the Binutils
mailing list