aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gold/ChangeLog21
-rw-r--r--gold/errors.cc20
-rw-r--r--gold/errors.h4
-rw-r--r--gold/gold.h4
-rw-r--r--gold/object.cc4
-rw-r--r--gold/options.cc15
-rw-r--r--gold/options.h47
-rw-r--r--gold/symtab.cc15
8 files changed, 102 insertions, 28 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 3a8aba5..a230f59 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,3 +1,24 @@
+2008-04-17 Cary Coutant <ccoutant@google.com>
+
+ * errors.cc (Errors::info): New function.
+ (gold_info): New function.
+ * errors.h (Errors::info): New function.
+ * gold.h (gold_info): New function.
+ * object.cc (Input_objects::add_object): Print trace output.
+ * options.cc (options::parse_set): New function.
+ (General_options::parse_wrap): Deleted.
+ (General_options::General_options): Deleted initializer.
+ * options.h (options::String_set): New typedef.
+ (options::parse_set): New function.
+ (DEFINE_set): New macro.
+ (General_options::wrap): Changed to use DEFINE_set. Changed
+ callers of any_wrap_symbols and is_wrap_symbol.
+ (General_options::trace, General_options::trace_symbol):
+ New options.
+ (General_options::any_wrap_symbols, General_options::is_wrap_symbol)
+ (General_options::wrap_symbols_): Deleted.
+ * symtab.cc (Symbol_table::add_from_object): Print trace output.
+
2008-04-17 David S. Miller <davem@davemloft.net>
* options.cc (General_options::parse_V): New function.
diff --git a/gold/errors.cc b/gold/errors.cc
index c43e9f3..01ce97f 100644
--- a/gold/errors.cc
+++ b/gold/errors.cc
@@ -110,6 +110,15 @@ Errors::warning(const char* format, va_list args)
this->increment_counter(&this->warning_count_);
}
+// Print an informational message.
+
+void
+Errors::info(const char* format, va_list args)
+{
+ vfprintf(stderr, format, args);
+ fputc('\n', stderr);
+}
+
// Report an error at a reloc location.
template<int size, bool big_endian>
@@ -219,6 +228,17 @@ gold_warning(const char* format, ...)
va_end(args);
}
+// Print an informational message.
+
+void
+gold_info(const char* format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ parameters->errors()->info(format, args);
+ va_end(args);
+}
+
// Report an error at a location.
template<int size, bool big_endian>
diff --git a/gold/errors.h b/gold/errors.h
index 0decc4c..bc77994 100644
--- a/gold/errors.h
+++ b/gold/errors.h
@@ -57,6 +57,10 @@ class Errors
void
warning(const char* format, va_list);
+ // Print an informational message and continue.
+ void
+ info(const char* format, va_list);
+
// Report an error at a reloc location.
template<int size, bool big_endian>
void
diff --git a/gold/gold.h b/gold/gold.h
index 1b1a84c..62c014e 100644
--- a/gold/gold.h
+++ b/gold/gold.h
@@ -157,6 +157,10 @@ gold_error(const char* msg, ...) ATTRIBUTE_PRINTF_1;
extern void
gold_warning(const char* msg, ...) ATTRIBUTE_PRINTF_1;
+// This function is called to print an informational message.
+extern void
+gold_info(const char* msg, ...) ATTRIBUTE_PRINTF_1;
+
// Work around a bug in gcc 4.3.0. http://gcc.gnu.org/PR35546 . This
// can probably be removed after the bug has been fixed for a while.
#ifdef HAVE_TEMPLATE_ATTRIBUTES
diff --git a/gold/object.cc b/gold/object.cc
index 36d3dcc..2849093 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -1269,6 +1269,10 @@ Input_objects::add_object(Object* obj)
return false;
}
+ // Print the filename if the -t/--trace option is selected.
+ if (parameters->options().trace())
+ gold_info("%s", obj->name().c_str());
+
if (!obj->is_dynamic())
this->relobj_list_.push_back(static_cast<Relobj*>(obj));
else
diff --git a/gold/options.cc b/gold/options.cc
index 2b4978a..af024b5 100644
--- a/gold/options.cc
+++ b/gold/options.cc
@@ -222,6 +222,12 @@ parse_dirlist(const char*, const char* arg, Dir_list* retval)
}
void
+parse_set(const char*, const char* arg, String_set* retval)
+{
+ retval->insert(std::string(arg));
+}
+
+void
parse_choices(const char* option_name, const char* arg, const char** retval,
const char* choices[], int num_choices)
{
@@ -338,13 +344,6 @@ General_options::parse_version_script(const char*, const char* arg,
}
void
-General_options::parse_wrap(const char*, const char* arg,
- Command_line*)
-{
- this->wrap_symbols_.insert(std::string(arg));
-}
-
-void
General_options::parse_start_group(const char*, const char*,
Command_line* cmdline)
{
@@ -601,7 +600,7 @@ namespace gold
General_options::General_options()
: execstack_status_(General_options::EXECSTACK_FROM_INPUT), static_(false),
- do_demangle_(false), wrap_symbols_()
+ do_demangle_(false)
{
}
diff --git a/gold/options.h b/gold/options.h
index 100e53b..419e70b 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -61,6 +61,7 @@ class Target;
namespace options
{
typedef std::vector<Search_directory> Dir_list;
+typedef Unordered_set<std::string> String_set;
// These routines convert from a string option to various types.
// Each gives a fatal error if it cannot parse the argument.
@@ -88,6 +89,9 @@ extern void
parse_dirlist(const char* option_name, const char* arg, Dir_list* retval);
extern void
+parse_set(const char* option_name, const char* arg, String_set* retval);
+
+extern void
parse_choices(const char* option_name, const char* arg, const char** retval,
const char* choices[], int num_choices);
@@ -347,6 +351,24 @@ struct Struct_special : public Struct_var
add_search_directory_to_##varname__(const Search_directory& dir) \
{ this->varname__##_.value.push_back(dir); }
+// This is like DEFINE_string, but we store a set of strings.
+#define DEFINE_set(varname__, dashes__, shortname__, \
+ helpstring__, helparg__) \
+ DEFINE_var(varname__, dashes__, shortname__, , \
+ "", helpstring__, helparg__, false, options::String_set, \
+ const options::String_set&, options::parse_set) \
+ public: \
+ bool \
+ any_##varname__() const \
+ { return !this->varname__##_.value.empty(); } \
+ bool \
+ is_##varname__(const char* symbol) const \
+ { \
+ return (!this->varname__##_.value.empty() \
+ && (this->varname__##_.value.find(std::string(symbol)) \
+ != this->varname__##_.value.end())); \
+ }
+
// When you have a list of possible values (expressed as string)
// After helparg__ should come an initializer list, like
// {"foo", "bar", "baz"}
@@ -625,6 +647,9 @@ class General_options
DEFINE_string(sysroot, options::TWO_DASHES, '\0', "",
N_("Set target system root directory"), N_("DIR"));
+ DEFINE_bool(trace, options::TWO_DASHES, 't', false,
+ N_("Print the name of each input file"), NULL);
+
DEFINE_special(script, options::TWO_DASHES, 'T',
N_("Read linker script"), N_("FILE"));
@@ -657,8 +682,11 @@ class General_options
N_("Include all archive contents"),
N_("Include only needed archive contents"));
- DEFINE_special(wrap, options::TWO_DASHES, '\0',
- N_("Use wrapper functions for SYMBOL"), N_("SYMBOL"));
+ DEFINE_set(wrap, options::TWO_DASHES, '\0',
+ N_("Use wrapper functions for SYMBOL"), N_("SYMBOL"));
+
+ DEFINE_set(trace_symbol, options::TWO_DASHES, 'y',
+ N_("Trace references to symbol"), N_("SYMBOL"));
DEFINE_string(Y, options::EXACTLY_ONE_DASH, 'Y', "",
N_("Default search path for Solaris compatibility"),
@@ -767,19 +795,6 @@ class General_options
do_demangle() const
{ return this->do_demangle_; }
- // Whether there are any symbols to wrap.
- bool
- any_wrap_symbols() const
- { return !this->wrap_symbols_.empty(); }
-
- // Whether to wrap SYMBOL.
- bool
- is_wrap_symbol(const char* symbol) const
- {
- return (this->wrap_symbols_.find(std::string(symbol))
- != this->wrap_symbols_.end());
- }
-
private:
// Don't copy this structure.
General_options(const General_options&);
@@ -823,8 +838,6 @@ class General_options
bool static_;
// Whether to do demangling.
bool do_demangle_;
- // List of symbols used with --wrap.
- Unordered_set<std::string> wrap_symbols_;
};
// The position-dependent options. We use this to store the state of
diff --git a/gold/symtab.cc b/gold/symtab.cc
index dc86582..517d011 100644
--- a/gold/symtab.cc
+++ b/gold/symtab.cc
@@ -495,7 +495,7 @@ Symbol_table::wrap_symbol(Object* object, const char* name,
++name;
}
- if (parameters->options().is_wrap_symbol(name))
+ if (parameters->options().is_wrap(name))
{
// Turn NAME into __wrap_NAME.
std::string s;
@@ -513,7 +513,7 @@ Symbol_table::wrap_symbol(Object* object, const char* name,
const char* const real_prefix = "__real_";
const size_t real_prefix_length = strlen(real_prefix);
if (strncmp(name, real_prefix, real_prefix_length) == 0
- && parameters->options().is_wrap_symbol(name + real_prefix_length))
+ && parameters->options().is_wrap(name + real_prefix_length))
{
// Turn __real_NAME into NAME.
std::string s;
@@ -565,10 +565,19 @@ Symbol_table::add_from_object(Object* object,
const elfcpp::Sym<size, big_endian>& sym,
const elfcpp::Sym<size, big_endian>& orig_sym)
{
+ // Print a message if this symbol is being traced.
+ if (parameters->options().is_trace_symbol(name))
+ {
+ if (orig_sym.get_st_shndx() == elfcpp::SHN_UNDEF)
+ gold_info(_("%s: reference to %s"), object->name().c_str(), name);
+ else
+ gold_info(_("%s: definition of %s"), object->name().c_str(), name);
+ }
+
// For an undefined symbol, we may need to adjust the name using
// --wrap.
if (orig_sym.get_st_shndx() == elfcpp::SHN_UNDEF
- && parameters->options().any_wrap_symbols())
+ && parameters->options().any_wrap())
{
const char* wrap_name = this->wrap_symbol(object, name, &name_key);
if (wrap_name != name)