summaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2007-08-21 20:37:32 +0000
committerIan Lance Taylor <iant@google.com>2007-08-21 20:37:32 +0000
commitd35f29c97545c4ef13013ca7c724a468ad697a56 (patch)
tree32b2233f9f390bbdd7a3a80152f126adca0beac8 /gold
parent2bb7063b6618cedfc31e1db6bdc6ec7755b06a17 (diff)
downloadbinutils-redhat-d35f29c97545c4ef13013ca7c724a468ad697a56.tar.gz
Add support for -rpath.
Diffstat (limited to 'gold')
-rw-r--r--gold/layout.cc29
-rw-r--r--gold/options.cc3
-rw-r--r--gold/options.h12
-rw-r--r--gold/output.h4
4 files changed, 47 insertions, 1 deletions
diff --git a/gold/layout.cc b/gold/layout.cc
index 62ba5f30de..2f85db4d30 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -1148,6 +1148,35 @@ Layout::finish_dynamic_section(const Input_objects* input_objects,
odyn->add_symbol(elfcpp::DT_FINI, sym);
// FIXME: Support DT_INIT_ARRAY and DT_FINI_ARRAY.
+
+ // Add a DT_RPATH entry if needed.
+ const General_options::Dir_list& rpath(this->options_.rpath());
+ if (!rpath.empty())
+ {
+ std::string rpath_val;
+ for (General_options::Dir_list::const_iterator p = rpath.begin();
+ p != rpath.end();
+ ++p)
+ {
+ if (rpath_val.empty())
+ rpath_val = *p;
+ else
+ {
+ // Eliminate duplicates.
+ General_options::Dir_list::const_iterator q;
+ for (q = rpath.begin(); q != p; ++q)
+ if (strcmp(*q, *p) == 0)
+ break;
+ if (q == p)
+ {
+ rpath_val += ':';
+ rpath_val += *p;
+ }
+ }
+ }
+
+ odyn->add_string(elfcpp::DT_RPATH, rpath_val);
+ }
}
// The mapping of .gnu.linkonce section names to real section names.
diff --git a/gold/options.cc b/gold/options.cc
index b8339e8a62..36e0044c23 100644
--- a/gold/options.cc
+++ b/gold/options.cc
@@ -244,6 +244,9 @@ options::Command_line_options::options[] =
&General_options::set_output_file_name),
GENERAL_NOARG('r', NULL, N_("Generate relocatable output"), NULL,
ONE_DASH, &General_options::set_relocatable),
+ GENERAL_ARG('R', "rpath", N_("Add directory to runtime search path"),
+ N_("-R DIR, -rpath DIR"), ONE_DASH,
+ &General_options::add_to_rpath),
GENERAL_NOARG('\0', "shared", N_("Generate shared library"),
NULL, ONE_DASH, &General_options::set_shared),
GENERAL_NOARG('\0', "static", N_("Do not link against shared libraries"),
diff --git a/gold/options.h b/gold/options.h
index 56907c058e..dc38b2f1c7 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -43,7 +43,7 @@ class General_options
{ return this->dynamic_linker_; }
// -L: Library search path.
- typedef std::list<const char*> Dir_list;
+ typedef std::vector<const char*> Dir_list;
const Dir_list&
search_path() const
@@ -59,6 +59,11 @@ class General_options
is_relocatable() const
{ return this->is_relocatable_; }
+ // --rpath: The runtime search path.
+ const Dir_list&
+ rpath() const
+ { return this->rpath_; }
+
// --shared: Whether generating a shared object.
bool
is_shared() const
@@ -94,6 +99,10 @@ class General_options
{ this->is_relocatable_ = true; }
void
+ add_to_rpath(const char* arg)
+ { this->rpath_.push_back(arg); }
+
+ void
set_shared()
{ this->is_shared_ = true; }
@@ -109,6 +118,7 @@ class General_options
Dir_list search_path_;
const char* output_file_name_;
bool is_relocatable_;
+ Dir_list rpath_;
bool is_shared_;
bool is_static_;
};
diff --git a/gold/output.h b/gold/output.h
index 7ed53ff06d..3147080320 100644
--- a/gold/output.h
+++ b/gold/output.h
@@ -1040,6 +1040,10 @@ class Output_data_dynamic : public Output_section_data
add_string(elfcpp::DT tag, const char* str)
{ this->add_entry(Dynamic_entry(tag, this->pool_->add(str, NULL))); }
+ void
+ add_string(elfcpp::DT tag, const std::string& str)
+ { this->add_string(tag, str.c_str()); }
+
// Set the final data size.
void
do_set_address(uint64_t, off_t);