gold regression vs BFD ld: __ehdr_start
Cary Coutant
ccoutant@google.com
Mon Mar 31 22:19:00 GMT 2014
> I was unclear. In the case of a static link with a weak undefined
> reference to __ehdr_start, that must resolve to 0 normally and not
> generate an error.
> The case I was talking about was under -shared, when the treatment of
> an undefined symbol would normally be to generate a dynamic reloc.
> In that case, I think it's acceptable to generate an error instead of
> going back and resizing the dynamic sections and everything you'd have
> to do.
OK, here's a revised patch...
-cary
2014-03-31 Cary Coutant <ccoutant@google.com>
* gold/defstd.cc (in_segment): Define __ehdr_start here...
* gold/layout.cc (Layout::finalize): ...Instead of here. Set the
output segment when known.
* gold/symtab.cc (Symbol::set_output_segment): New function.
(Symbol::set_undefined): New function.
* gold/symtab.h (Symbol::set_output_segment): New function.
(Symbol::set_undefined): New function.
* gold/target-reloc.h (issue_undefined_symbol_error): Check for
hidden undefs.
-------------- next part --------------
2014-03-31 Cary Coutant <ccoutant@google.com>
* gold/defstd.cc (in_segment): Define __ehdr_start here...
* gold/layout.cc (Layout::finalize): ...Instead of here. Set the
output segment when known.
* gold/symtab.cc (Symbol::set_output_segment): New function.
(Symbol::set_undefined): New function.
* gold/symtab.h (Symbol::set_output_segment): New function.
(Symbol::set_undefined): New function.
* gold/target-reloc.h (issue_undefined_symbol_error): Check for
hidden undefs.
diff --git a/gold/defstd.cc b/gold/defstd.cc
index a50e75d..cee68a0 100644
--- a/gold/defstd.cc
+++ b/gold/defstd.cc
@@ -141,6 +141,20 @@ const Define_symbol_in_segment in_segment[] =
true // only_if_ref
},
{
+ "__ehdr_start", // name
+ elfcpp::PT_LOAD, // segment_type
+ elfcpp::PF(0), // segment_flags_set
+ elfcpp::PF(0), // segment_flags_clear
+ 0, // value
+ 0, // size
+ elfcpp::STT_NOTYPE, // type
+ elfcpp::STB_GLOBAL, // binding
+ elfcpp::STV_HIDDEN, // visibility
+ 0, // nonvis
+ Symbol::SEGMENT_START, // offset_from_base
+ true // only_if_ref
+ },
+ {
"etext", // name
elfcpp::PT_LOAD, // segment_type
elfcpp::PF_X, // segment_flags_set
diff --git a/gold/layout.cc b/gold/layout.cc
index c96516c..9bd19c5 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -2743,12 +2743,14 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab,
// If there is a load segment that contains the file and program headers,
// provide a symbol __ehdr_start pointing there.
// A program can use this to examine itself robustly.
- if (load_seg != NULL)
- symtab->define_in_output_segment("__ehdr_start", NULL,
- Symbol_table::PREDEFINED, load_seg, 0, 0,
- elfcpp::STT_NOTYPE, elfcpp::STB_GLOBAL,
- elfcpp::STV_HIDDEN, 0,
- Symbol::SEGMENT_START, true);
+ Symbol *ehdr_start = symtab->lookup("__ehdr_start");
+ if (ehdr_start != NULL && ehdr_start->is_predefined())
+ {
+ if (load_seg != NULL)
+ ehdr_start->set_output_segment(load_seg, Symbol::SEGMENT_START);
+ else
+ ehdr_start->set_undefined();
+ }
// Set the file offsets of all the non-data sections we've seen so
// far which don't have to wait for the input sections. We need
diff --git a/gold/symtab.cc b/gold/symtab.cc
index 1a69f5b..6fa788a 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -527,6 +527,30 @@ Symbol::set_output_section(Output_section* os)
}
}
+// Set the symbol's output segment. This is used for pre-defined
+// symbols whose segments aren't known until after layout is done
+// (e.g., __ehdr_start).
+
+void
+Symbol::set_output_segment(Output_segment* os, Segment_offset_base base)
+{
+ gold_assert(this->source_ == IN_OUTPUT_SEGMENT && this->is_predefined_);
+ this->u_.in_output_segment.output_segment = os;
+ this->u_.in_output_segment.offset_base = base;
+}
+
+// Set the symbol to undefined. This is used for pre-defined
+// symbols whose segments aren't known until after layout is done
+// (e.g., __ehdr_start).
+
+void
+Symbol::set_undefined()
+{
+ gold_assert(this->source_ == IN_OUTPUT_SEGMENT && this->is_predefined_);
+ this->source_ = IS_UNDEFINED;
+ this->is_predefined_ = false;
+}
+
// Class Symbol_table.
Symbol_table::Symbol_table(unsigned int count,
diff --git a/gold/symtab.h b/gold/symtab.h
index b06c7b4..d5aa135 100644
--- a/gold/symtab.h
+++ b/gold/symtab.h
@@ -782,6 +782,18 @@ class Symbol
void
set_output_section(Output_section*);
+ // Set the symbol's output segment. This is used for pre-defined
+ // symbols whose segments aren't known until after layout is done
+ // (e.g., __ehdr_start).
+ void
+ set_output_segment(Output_segment*, Segment_offset_base);
+
+ // Set the symbol to undefined. This is used for pre-defined
+ // symbols whose segments aren't known until after layout is done
+ // (e.g., __ehdr_start).
+ void
+ set_undefined();
+
// Return whether there should be a warning for references to this
// symbol.
bool
diff --git a/gold/target-reloc.h b/gold/target-reloc.h
index f49020a..b47aea8 100644
--- a/gold/target-reloc.h
+++ b/gold/target-reloc.h
@@ -216,6 +216,10 @@ issue_undefined_symbol_error(const Symbol* sym)
return false;
}
+ // If the symbol is hidden, report it.
+ if (sym->visibility() == elfcpp::STV_HIDDEN)
+ return true;
+
// When creating a shared library, only report unresolved symbols if
// -z defs was used.
if (parameters->options().shared() && !parameters->options().defs())
More information about the Binutils
mailing list