Support selecting target by name.
This commit is contained in:
parent
caa9d5d919
commit
0daa6f62c8
|
@ -698,7 +698,7 @@ Input_file::open(const General_options& options, const Dirsearch& dirpath,
|
|||
else
|
||||
{
|
||||
gold_assert(format == General_options::OBJECT_FORMAT_BINARY);
|
||||
ok = this->open_binary(task, name);
|
||||
ok = this->open_binary(options, task, name);
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
|
@ -714,29 +714,22 @@ Input_file::open(const General_options& options, const Dirsearch& dirpath,
|
|||
// Open a file for --format binary.
|
||||
|
||||
bool
|
||||
Input_file::open_binary(const Task* task, const std::string& name)
|
||||
Input_file::open_binary(const General_options& options,
|
||||
const Task* task, const std::string& name)
|
||||
{
|
||||
// In order to open a binary file, we need machine code, size, and
|
||||
// endianness. If we have a target already, use it, otherwise use
|
||||
// the defaults.
|
||||
elfcpp::EM machine;
|
||||
int size;
|
||||
bool big_endian;
|
||||
// endianness. We may not have a valid target at this point, in
|
||||
// which case we use the default target.
|
||||
Target* target;
|
||||
if (parameters->is_target_valid())
|
||||
{
|
||||
Target* target = parameters->target();
|
||||
machine = target->machine_code();
|
||||
size = target->get_size();
|
||||
big_endian = target->is_big_endian();
|
||||
}
|
||||
target = parameters->target();
|
||||
else
|
||||
{
|
||||
machine = elfcpp::GOLD_DEFAULT_MACHINE;
|
||||
size = GOLD_DEFAULT_SIZE;
|
||||
big_endian = GOLD_DEFAULT_BIG_ENDIAN;
|
||||
}
|
||||
target = options.default_target();
|
||||
|
||||
Binary_to_elf binary_to_elf(machine, size, big_endian, name);
|
||||
Binary_to_elf binary_to_elf(target->machine_code(),
|
||||
target->get_size(),
|
||||
target->is_big_endian(),
|
||||
name);
|
||||
if (!binary_to_elf.convert(task))
|
||||
return false;
|
||||
return this->file_.open(task, name, binary_to_elf.converted_data_leak(),
|
||||
|
|
|
@ -428,7 +428,8 @@ class Input_file
|
|||
|
||||
// Open a binary file.
|
||||
bool
|
||||
open_binary(const Task* task, const std::string& name);
|
||||
open_binary(const General_options&, const Task* task,
|
||||
const std::string& name);
|
||||
|
||||
// The argument from the command line.
|
||||
const Input_file_argument* input_argument_;
|
||||
|
|
11
gold/gold.cc
11
gold/gold.cc
|
@ -31,7 +31,6 @@
|
|||
|
||||
#include "options.h"
|
||||
#include "debug.h"
|
||||
#include "target-select.h"
|
||||
#include "workqueue.h"
|
||||
#include "dirsearch.h"
|
||||
#include "readsyms.h"
|
||||
|
@ -167,15 +166,7 @@ queue_middle_tasks(const General_options& options,
|
|||
// pass an empty archive to the linker and get an empty object file
|
||||
// out. In order to do this we need to use a default target.
|
||||
if (input_objects->number_of_input_objects() == 0)
|
||||
{
|
||||
// The GOLD_xx macros are defined by the configure script.
|
||||
Target* target = select_target(elfcpp::GOLD_DEFAULT_MACHINE,
|
||||
GOLD_DEFAULT_SIZE,
|
||||
GOLD_DEFAULT_BIG_ENDIAN,
|
||||
0, 0);
|
||||
gold_assert(target != NULL);
|
||||
set_parameters_target(target);
|
||||
}
|
||||
set_parameters_target(options.default_target());
|
||||
|
||||
int thread_count = options.thread_count_middle();
|
||||
if (thread_count == 0)
|
||||
|
|
13
gold/i386.cc
13
gold/i386.cc
|
@ -2433,6 +2433,9 @@ public:
|
|||
Target*
|
||||
recognize(int machine, int osabi, int abiversion);
|
||||
|
||||
Target*
|
||||
recognize_by_name(const char* name);
|
||||
|
||||
private:
|
||||
Target_i386* target_;
|
||||
};
|
||||
|
@ -2448,6 +2451,16 @@ Target_selector_i386::recognize(int, int, int)
|
|||
return this->target_;
|
||||
}
|
||||
|
||||
Target*
|
||||
Target_selector_i386::recognize_by_name(const char* name)
|
||||
{
|
||||
if (strcmp(name, "elf32-i386") != 0)
|
||||
return NULL;
|
||||
if (this->target_ == NULL)
|
||||
this->target_ = new Target_i386();
|
||||
return this->target_;
|
||||
}
|
||||
|
||||
Target_selector_i386 target_selector_i386;
|
||||
|
||||
} // End anonymous namespace.
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "debug.h"
|
||||
#include "script.h"
|
||||
#include "target-select.h"
|
||||
#include "options.h"
|
||||
|
||||
namespace gold
|
||||
|
@ -140,7 +141,8 @@ namespace
|
|||
// minimally compatible. In practice for an ELF target this would be
|
||||
// the same target as the input files; that name always start with
|
||||
// "elf". Non-ELF targets would be "srec", "symbolsrec", "tekhex",
|
||||
// "binary", "ihex".
|
||||
// "binary", "ihex". See also
|
||||
// General_options::default_target_settings.
|
||||
|
||||
gold::General_options::Object_format
|
||||
string_to_object_format(const char* arg)
|
||||
|
@ -635,6 +637,7 @@ General_options::General_options(Script_options* script_options)
|
|||
optimization_level_(0),
|
||||
output_file_name_("a.out"),
|
||||
output_format_(OBJECT_FORMAT_ELF),
|
||||
output_format_string_(NULL),
|
||||
is_relocatable_(false),
|
||||
strip_(STRIP_NONE),
|
||||
allow_shlib_undefined_(false),
|
||||
|
@ -678,9 +681,38 @@ General_options::define_symbol(const char* arg)
|
|||
void
|
||||
General_options::set_output_format(const char* arg)
|
||||
{
|
||||
this->output_format_string_ = arg;
|
||||
this->output_format_ = string_to_object_format(arg);
|
||||
}
|
||||
|
||||
// The x86_64 kernel build converts a binary file to an object file
|
||||
// using -r --format binary --oformat elf32-i386 foo.o. In order to
|
||||
// support that for gold we support determining the default target
|
||||
// choice from the output format. We recognize names that the GNU
|
||||
// linker uses.
|
||||
|
||||
Target*
|
||||
General_options::default_target() const
|
||||
{
|
||||
if (this->output_format_string_ != NULL)
|
||||
{
|
||||
Target* target = select_target_by_name(this->output_format_string_);
|
||||
if (target != NULL)
|
||||
return target;
|
||||
|
||||
gold_error(_("unrecognized output format %s"),
|
||||
this->output_format_string_);
|
||||
}
|
||||
|
||||
// The GOLD_DEFAULT_xx macros are defined by the configure script.
|
||||
Target* target = select_target(elfcpp::GOLD_DEFAULT_MACHINE,
|
||||
GOLD_DEFAULT_SIZE,
|
||||
GOLD_DEFAULT_BIG_ENDIAN,
|
||||
0, 0);
|
||||
gold_assert(target != NULL);
|
||||
return target;
|
||||
}
|
||||
|
||||
// Handle the -z option.
|
||||
|
||||
void
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "elfcpp.h"
|
||||
#include "script.h"
|
||||
|
||||
namespace gold
|
||||
|
@ -45,6 +46,7 @@ namespace gold
|
|||
class Command_line;
|
||||
class Input_file_group;
|
||||
class Position_dependent_options;
|
||||
class Target;
|
||||
|
||||
namespace options
|
||||
{
|
||||
|
@ -157,11 +159,14 @@ class General_options
|
|||
{ return this->output_file_name_; }
|
||||
|
||||
// --oformat: Output format.
|
||||
|
||||
Object_format
|
||||
output_format() const
|
||||
{ return this->output_format_; }
|
||||
|
||||
// Return the default target.
|
||||
Target*
|
||||
default_target() const;
|
||||
|
||||
// -r: Whether we are doing a relocatable link.
|
||||
bool
|
||||
is_relocatable() const
|
||||
|
@ -562,6 +567,7 @@ class General_options
|
|||
int optimization_level_;
|
||||
const char* output_file_name_;
|
||||
Object_format output_format_;
|
||||
const char* output_format_string_;
|
||||
bool is_relocatable_;
|
||||
Strip strip_;
|
||||
bool allow_shlib_undefined_;
|
||||
|
|
|
@ -50,7 +50,7 @@ Target_selector::Target_selector(int machine, int size, bool is_big_endian)
|
|||
|
||||
// Find the target for an ELF file.
|
||||
|
||||
extern Target*
|
||||
Target*
|
||||
select_target(int machine, int size, bool is_big_endian, int osabi,
|
||||
int abiversion)
|
||||
{
|
||||
|
@ -69,4 +69,19 @@ select_target(int machine, int size, bool is_big_endian, int osabi,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Find a target using a BFD name. This is used to support the
|
||||
// --oformat option.
|
||||
|
||||
Target*
|
||||
select_target_by_name(const char* name)
|
||||
{
|
||||
for (Target_selector* p = target_selectors; p != NULL; p = p->next())
|
||||
{
|
||||
Target* ret = p->recognize_by_name(name);
|
||||
if (ret != NULL)
|
||||
return ret;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // End namespace gold.
|
||||
|
|
|
@ -49,7 +49,13 @@ class Target_selector
|
|||
|
||||
// If we can handle this target, return a pointer to a target
|
||||
// structure. The size and endianness are known.
|
||||
virtual Target* recognize(int machine, int osabi, int abiversion) = 0;
|
||||
virtual Target*
|
||||
recognize(int machine, int osabi, int abiversion) = 0;
|
||||
|
||||
// If NAME matches the target, return a pointer to a target
|
||||
// structure.
|
||||
virtual Target*
|
||||
recognize_by_name(const char* name) = 0;
|
||||
|
||||
// Return the next Target_selector in the linked list.
|
||||
Target_selector*
|
||||
|
@ -84,6 +90,10 @@ class Target_selector
|
|||
extern Target* select_target(int machine, int size, bool big_endian,
|
||||
int osabi, int abiversion);
|
||||
|
||||
// Select a target using a BFD name.
|
||||
|
||||
extern Target* select_target_by_name(const char* name);
|
||||
|
||||
} // End namespace gold.
|
||||
|
||||
#endif // !defined(GOLD_TARGET_SELECT_H)
|
||||
|
|
|
@ -176,6 +176,10 @@ class Target_selector_test : public Target_selector
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Target*
|
||||
recognize_by_name(const char*)
|
||||
{ return NULL; }
|
||||
};
|
||||
|
||||
// Register the test target selectors. These don't need to be
|
||||
|
|
|
@ -2223,6 +2223,9 @@ public:
|
|||
Target*
|
||||
recognize(int machine, int osabi, int abiversion);
|
||||
|
||||
Target*
|
||||
recognize_by_name(const char*);
|
||||
|
||||
private:
|
||||
Target_x86_64* target_;
|
||||
};
|
||||
|
@ -2238,6 +2241,16 @@ Target_selector_x86_64::recognize(int, int, int)
|
|||
return this->target_;
|
||||
}
|
||||
|
||||
Target*
|
||||
Target_selector_x86_64::recognize_by_name(const char* name)
|
||||
{
|
||||
if (strcmp(name, "elf64-x86-64") != 0)
|
||||
return NULL;
|
||||
if (this->target_ == NULL)
|
||||
this->target_ = new Target_x86_64();
|
||||
return this->target_;
|
||||
}
|
||||
|
||||
Target_selector_x86_64 target_selector_x86_64;
|
||||
|
||||
} // End anonymous namespace.
|
||||
|
|
Loading…
Reference in New Issue