Lay out object file sections when we add the symbols to the symbol
table.
This commit is contained in:
parent
33423b7ffe
commit
12e14209f0
11 changed files with 214 additions and 184 deletions
|
@ -218,7 +218,8 @@ Archive::read_header(off_t off, std::string* pname)
|
||||||
// may be satisfied by other objects in the archive.
|
// may be satisfied by other objects in the archive.
|
||||||
|
|
||||||
void
|
void
|
||||||
Archive::add_symbols(Symbol_table* symtab, Input_objects* input_objects)
|
Archive::add_symbols(Symbol_table* symtab, Layout* layout,
|
||||||
|
Input_objects* input_objects)
|
||||||
{
|
{
|
||||||
size_t armap_size = this->armap_.size();
|
size_t armap_size = this->armap_.size();
|
||||||
std::vector<bool> seen;
|
std::vector<bool> seen;
|
||||||
|
@ -253,7 +254,7 @@ Archive::add_symbols(Symbol_table* symtab, Input_objects* input_objects)
|
||||||
|
|
||||||
// We want to include this object in the link.
|
// We want to include this object in the link.
|
||||||
last = this->armap_[i].offset;
|
last = this->armap_[i].offset;
|
||||||
this->include_member(symtab, input_objects, last);
|
this->include_member(symtab, layout, input_objects, last);
|
||||||
added_new_object = true;
|
added_new_object = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -264,8 +265,8 @@ Archive::add_symbols(Symbol_table* symtab, Input_objects* input_objects)
|
||||||
// the member header.
|
// the member header.
|
||||||
|
|
||||||
void
|
void
|
||||||
Archive::include_member(Symbol_table* symtab, Input_objects* input_objects,
|
Archive::include_member(Symbol_table* symtab, Layout* layout,
|
||||||
off_t off)
|
Input_objects* input_objects, off_t off)
|
||||||
{
|
{
|
||||||
std::string n;
|
std::string n;
|
||||||
this->read_header(off, &n);
|
this->read_header(off, &n);
|
||||||
|
@ -305,8 +306,10 @@ Archive::include_member(Symbol_table* symtab, Input_objects* input_objects,
|
||||||
|
|
||||||
input_objects->add_object(obj);
|
input_objects->add_object(obj);
|
||||||
|
|
||||||
Read_symbols_data sd = obj->read_symbols();
|
Read_symbols_data sd;
|
||||||
obj->add_symbols(symtab, sd);
|
obj->read_symbols(&sd);
|
||||||
|
obj->layout(layout, &sd);
|
||||||
|
obj->add_symbols(symtab, &sd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add_archive_symbols methods.
|
// Add_archive_symbols methods.
|
||||||
|
@ -354,7 +357,8 @@ Add_archive_symbols::locks(Workqueue* workqueue)
|
||||||
void
|
void
|
||||||
Add_archive_symbols::run(Workqueue*)
|
Add_archive_symbols::run(Workqueue*)
|
||||||
{
|
{
|
||||||
this->archive_->add_symbols(this->symtab_, this->input_objects_);
|
this->archive_->add_symbols(this->symtab_, this->layout_,
|
||||||
|
this->input_objects_);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End namespace gold.
|
} // End namespace gold.
|
||||||
|
|
|
@ -13,6 +13,7 @@ namespace gold
|
||||||
|
|
||||||
class Input_file;
|
class Input_file;
|
||||||
class Input_objects;
|
class Input_objects;
|
||||||
|
class Layout;
|
||||||
class Symbol_table;
|
class Symbol_table;
|
||||||
|
|
||||||
// This class represents an archive--generally a libNAME.a file.
|
// This class represents an archive--generally a libNAME.a file.
|
||||||
|
@ -61,7 +62,7 @@ class Archive
|
||||||
// Select members from the archive as needed and add them to the
|
// Select members from the archive as needed and add them to the
|
||||||
// link.
|
// link.
|
||||||
void
|
void
|
||||||
add_symbols(Symbol_table*, Input_objects*);
|
add_symbols(Symbol_table*, Layout*, Input_objects*);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Archive(const Archive&);
|
Archive(const Archive&);
|
||||||
|
@ -81,7 +82,7 @@ class Archive
|
||||||
|
|
||||||
// Include an archive member in the link.
|
// Include an archive member in the link.
|
||||||
void
|
void
|
||||||
include_member(Symbol_table*, Input_objects*, off_t off);
|
include_member(Symbol_table*, Layout*, Input_objects*, off_t off);
|
||||||
|
|
||||||
// An entry in the archive map of symbols to object files.
|
// An entry in the archive map of symbols to object files.
|
||||||
struct Armap_entry
|
struct Armap_entry
|
||||||
|
@ -108,11 +109,13 @@ class Archive
|
||||||
class Add_archive_symbols : public Task
|
class Add_archive_symbols : public Task
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Add_archive_symbols(Symbol_table* symtab, Input_objects* input_objects,
|
Add_archive_symbols(Symbol_table* symtab, Layout* layout,
|
||||||
|
Input_objects* input_objects,
|
||||||
Archive* archive, Task_token* this_blocker,
|
Archive* archive, Task_token* this_blocker,
|
||||||
Task_token* next_blocker)
|
Task_token* next_blocker)
|
||||||
: symtab_(symtab), input_objects_(input_objects), archive_(archive),
|
: symtab_(symtab), layout_(layout), input_objects_(input_objects),
|
||||||
this_blocker_(this_blocker), next_blocker_(next_blocker)
|
archive_(archive), this_blocker_(this_blocker),
|
||||||
|
next_blocker_(next_blocker)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~Add_archive_symbols();
|
~Add_archive_symbols();
|
||||||
|
@ -132,6 +135,7 @@ class Add_archive_symbols : public Task
|
||||||
class Add_archive_symbols_locker;
|
class Add_archive_symbols_locker;
|
||||||
|
|
||||||
Symbol_table* symtab_;
|
Symbol_table* symtab_;
|
||||||
|
Layout* layout_;
|
||||||
Input_objects* input_objects_;
|
Input_objects* input_objects_;
|
||||||
Archive* archive_;
|
Archive* archive_;
|
||||||
Task_token* this_blocker_;
|
Task_token* this_blocker_;
|
||||||
|
|
11
gold/gold.cc
11
gold/gold.cc
|
@ -70,7 +70,7 @@ queue_initial_tasks(const General_options& options,
|
||||||
const Dirsearch& search_path,
|
const Dirsearch& search_path,
|
||||||
const Command_line::Input_argument_list& inputs,
|
const Command_line::Input_argument_list& inputs,
|
||||||
Workqueue* workqueue, Input_objects* input_objects,
|
Workqueue* workqueue, Input_objects* input_objects,
|
||||||
Symbol_table* symtab)
|
Symbol_table* symtab, Layout* layout)
|
||||||
{
|
{
|
||||||
if (inputs.empty())
|
if (inputs.empty())
|
||||||
gold_fatal(_("no input files"), false);
|
gold_fatal(_("no input files"), false);
|
||||||
|
@ -86,13 +86,13 @@ queue_initial_tasks(const General_options& options,
|
||||||
{
|
{
|
||||||
Task_token* next_blocker = new Task_token();
|
Task_token* next_blocker = new Task_token();
|
||||||
next_blocker->add_blocker();
|
next_blocker->add_blocker();
|
||||||
workqueue->queue(new Read_symbols(options, input_objects, symtab,
|
workqueue->queue(new Read_symbols(options, input_objects, symtab, layout,
|
||||||
search_path, *p, this_blocker,
|
search_path, *p, this_blocker,
|
||||||
next_blocker));
|
next_blocker));
|
||||||
this_blocker = next_blocker;
|
this_blocker = next_blocker;
|
||||||
}
|
}
|
||||||
|
|
||||||
workqueue->queue(new Layout_task(options, input_objects, symtab,
|
workqueue->queue(new Layout_task(options, input_objects, symtab, layout,
|
||||||
this_blocker));
|
this_blocker));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +170,9 @@ main(int argc, char** argv)
|
||||||
// The symbol table.
|
// The symbol table.
|
||||||
Symbol_table symtab;
|
Symbol_table symtab;
|
||||||
|
|
||||||
|
// The layout object.
|
||||||
|
Layout layout(command_line.options());
|
||||||
|
|
||||||
// Get the search path from the -L options.
|
// Get the search path from the -L options.
|
||||||
Dirsearch search_path;
|
Dirsearch search_path;
|
||||||
search_path.add(&workqueue, command_line.options().search_path());
|
search_path.add(&workqueue, command_line.options().search_path());
|
||||||
|
@ -177,7 +180,7 @@ main(int argc, char** argv)
|
||||||
// Queue up the first set of tasks.
|
// Queue up the first set of tasks.
|
||||||
queue_initial_tasks(command_line.options(), search_path,
|
queue_initial_tasks(command_line.options(), search_path,
|
||||||
command_line.inputs(), &workqueue, &input_objects,
|
command_line.inputs(), &workqueue, &input_objects,
|
||||||
&symtab);
|
&symtab, &layout);
|
||||||
|
|
||||||
// Run the main task processing loop.
|
// Run the main task processing loop.
|
||||||
workqueue.process();
|
workqueue.process();
|
||||||
|
|
|
@ -45,15 +45,8 @@ Layout_task::locks(Workqueue*)
|
||||||
void
|
void
|
||||||
Layout_task::run(Workqueue* workqueue)
|
Layout_task::run(Workqueue* workqueue)
|
||||||
{
|
{
|
||||||
// Nothing ever frees this.
|
off_t file_size = this->layout_->finalize(this->input_objects_,
|
||||||
Layout* layout = new Layout(this->options_);
|
this->symtab_);
|
||||||
layout->init();
|
|
||||||
for (Input_objects::Object_list::const_iterator p =
|
|
||||||
this->input_objects_->begin();
|
|
||||||
p != this->input_objects_->end();
|
|
||||||
++p)
|
|
||||||
(*p)->layout(layout);
|
|
||||||
off_t file_size = layout->finalize(this->input_objects_, this->symtab_);
|
|
||||||
|
|
||||||
// Now we know the final size of the output file and we know where
|
// Now we know the final size of the output file and we know where
|
||||||
// each piece of information goes.
|
// each piece of information goes.
|
||||||
|
@ -62,7 +55,7 @@ Layout_task::run(Workqueue* workqueue)
|
||||||
|
|
||||||
// Queue up the final set of tasks.
|
// Queue up the final set of tasks.
|
||||||
gold::queue_final_tasks(this->options_, this->input_objects_,
|
gold::queue_final_tasks(this->options_, this->input_objects_,
|
||||||
this->symtab_, layout, workqueue, of);
|
this->symtab_, this->layout_, workqueue, of);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layout methods.
|
// Layout methods.
|
||||||
|
@ -71,13 +64,6 @@ Layout::Layout(const General_options& options)
|
||||||
: options_(options), last_shndx_(0), namepool_(), sympool_(), signatures_(),
|
: options_(options), last_shndx_(0), namepool_(), sympool_(), signatures_(),
|
||||||
section_name_map_(), segment_list_(), section_list_(),
|
section_name_map_(), segment_list_(), section_list_(),
|
||||||
special_output_list_()
|
special_output_list_()
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare for doing layout.
|
|
||||||
|
|
||||||
void
|
|
||||||
Layout::init()
|
|
||||||
{
|
{
|
||||||
// Make space for more than enough segments for a typical file.
|
// Make space for more than enough segments for a typical file.
|
||||||
// This is just for efficiency--it's OK if we wind up needing more.
|
// This is just for efficiency--it's OK if we wind up needing more.
|
||||||
|
|
|
@ -37,9 +37,10 @@ class Layout_task : public Task
|
||||||
Layout_task(const General_options& options,
|
Layout_task(const General_options& options,
|
||||||
const Input_objects* input_objects,
|
const Input_objects* input_objects,
|
||||||
Symbol_table* symtab,
|
Symbol_table* symtab,
|
||||||
|
Layout* layout,
|
||||||
Task_token* this_blocker)
|
Task_token* this_blocker)
|
||||||
: options_(options), input_objects_(input_objects), symtab_(symtab),
|
: options_(options), input_objects_(input_objects), symtab_(symtab),
|
||||||
this_blocker_(this_blocker)
|
layout_(layout), this_blocker_(this_blocker)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~Layout_task();
|
~Layout_task();
|
||||||
|
@ -62,6 +63,7 @@ class Layout_task : public Task
|
||||||
const General_options& options_;
|
const General_options& options_;
|
||||||
const Input_objects* input_objects_;
|
const Input_objects* input_objects_;
|
||||||
Symbol_table* symtab_;
|
Symbol_table* symtab_;
|
||||||
|
Layout* layout_;
|
||||||
Task_token* this_blocker_;
|
Task_token* this_blocker_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -72,10 +74,6 @@ class Layout
|
||||||
public:
|
public:
|
||||||
Layout(const General_options& options);
|
Layout(const General_options& options);
|
||||||
|
|
||||||
// Initialize the object.
|
|
||||||
void
|
|
||||||
init();
|
|
||||||
|
|
||||||
// Given an input section named NAME with data in SHDR from the
|
// Given an input section named NAME with data in SHDR from the
|
||||||
// object file OBJECT, return the output section where this input
|
// object file OBJECT, return the output section where this input
|
||||||
// section should go. Set *OFFSET to the offset within the output
|
// section should go. Set *OFFSET to the offset within the output
|
||||||
|
|
169
gold/object.cc
169
gold/object.cc
|
@ -44,6 +44,7 @@ Sized_object<size, big_endian>::Sized_object(
|
||||||
off_t offset,
|
off_t offset,
|
||||||
const elfcpp::Ehdr<size, big_endian>& ehdr)
|
const elfcpp::Ehdr<size, big_endian>& ehdr)
|
||||||
: Object(name, input_file, false, offset),
|
: Object(name, input_file, false, offset),
|
||||||
|
section_headers_(NULL),
|
||||||
flags_(ehdr.get_e_flags()),
|
flags_(ehdr.get_e_flags()),
|
||||||
shoff_(ehdr.get_e_shoff()),
|
shoff_(ehdr.get_e_shoff()),
|
||||||
shstrndx_(0),
|
shstrndx_(0),
|
||||||
|
@ -105,6 +106,7 @@ Sized_object<size, big_endian>::setup(
|
||||||
gold_exit(false);
|
gold_exit(false);
|
||||||
}
|
}
|
||||||
this->set_target(target);
|
this->set_target(target);
|
||||||
|
|
||||||
unsigned int shnum = ehdr.get_e_shnum();
|
unsigned int shnum = ehdr.get_e_shnum();
|
||||||
unsigned int shstrndx = ehdr.get_e_shstrndx();
|
unsigned int shstrndx = ehdr.get_e_shstrndx();
|
||||||
if ((shnum == 0 || shstrndx == elfcpp::SHN_XINDEX)
|
if ((shnum == 0 || shstrndx == elfcpp::SHN_XINDEX)
|
||||||
|
@ -122,12 +124,19 @@ Sized_object<size, big_endian>::setup(
|
||||||
if (shnum == 0)
|
if (shnum == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Find the SHT_SYMTAB section.
|
// We store the section headers in a File_view until do_read_symbols.
|
||||||
const unsigned char* p = this->get_view (this->shoff_,
|
this->section_headers_ = this->get_lasting_view(this->shoff_,
|
||||||
shnum * This::shdr_size);
|
shnum * This::shdr_size);
|
||||||
|
|
||||||
|
// Find the SHT_SYMTAB section. The ELF standard says that maybe in
|
||||||
|
// the future there can be more than one SHT_SYMTAB section. Until
|
||||||
|
// somebody figures out how that could work, we assume there is only
|
||||||
|
// one.
|
||||||
|
const unsigned char* p = this->section_headers_->data();
|
||||||
|
|
||||||
// Skip the first section, which is always empty.
|
// Skip the first section, which is always empty.
|
||||||
p += This::shdr_size;
|
p += This::shdr_size;
|
||||||
for (unsigned int i = 1; i < shnum; ++i)
|
for (unsigned int i = 1; i < shnum; ++i, p += This::shdr_size)
|
||||||
{
|
{
|
||||||
typename This::Shdr shdr(p);
|
typename This::Shdr shdr(p);
|
||||||
if (shdr.get_sh_type() == elfcpp::SHT_SYMTAB)
|
if (shdr.get_sh_type() == elfcpp::SHT_SYMTAB)
|
||||||
|
@ -135,29 +144,40 @@ Sized_object<size, big_endian>::setup(
|
||||||
this->symtab_shnum_ = i;
|
this->symtab_shnum_ = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
p += This::shdr_size;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the symbols and relocations from an object file.
|
// Read the sections and symbols from an object file.
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
Read_symbols_data
|
void
|
||||||
Sized_object<size, big_endian>::do_read_symbols()
|
Sized_object<size, big_endian>::do_read_symbols(Read_symbols_data* sd)
|
||||||
{
|
{
|
||||||
|
// Transfer our view of the section headers to SD.
|
||||||
|
sd->section_headers = this->section_headers_;
|
||||||
|
this->section_headers_ = NULL;
|
||||||
|
|
||||||
|
// Read the section names.
|
||||||
|
const unsigned char* pshdrs = sd->section_headers->data();
|
||||||
|
const unsigned char* pshdrnames = pshdrs + this->shstrndx_ * This::shdr_size;
|
||||||
|
typename This::Shdr shdrnames(pshdrnames);
|
||||||
|
sd->section_names_size = shdrnames.get_sh_size();
|
||||||
|
sd->section_names = this->get_lasting_view(shdrnames.get_sh_offset(),
|
||||||
|
sd->section_names_size);
|
||||||
|
|
||||||
if (this->symtab_shnum_ == 0)
|
if (this->symtab_shnum_ == 0)
|
||||||
{
|
{
|
||||||
// No symbol table. Weird but legal.
|
// No symbol table. Weird but legal.
|
||||||
Read_symbols_data ret;
|
sd->symbols = NULL;
|
||||||
ret.symbols = NULL;
|
sd->symbols_size = 0;
|
||||||
ret.symbols_size = 0;
|
sd->symbol_names = NULL;
|
||||||
ret.symbol_names = NULL;
|
sd->symbol_names_size = 0;
|
||||||
ret.symbol_names_size = 0;
|
return;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the symbol table section header.
|
// Get the symbol table section header.
|
||||||
typename This::Shdr symtabshdr(this->section_header(this->symtab_shnum_));
|
typename This::Shdr symtabshdr(pshdrs
|
||||||
|
+ this->symtab_shnum_ * This::shdr_size);
|
||||||
assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB);
|
assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB);
|
||||||
|
|
||||||
// We only need the external symbols.
|
// We only need the external symbols.
|
||||||
|
@ -191,49 +211,10 @@ Sized_object<size, big_endian>::do_read_symbols()
|
||||||
File_view* fvstrtab = this->get_lasting_view(strtabshdr.get_sh_offset(),
|
File_view* fvstrtab = this->get_lasting_view(strtabshdr.get_sh_offset(),
|
||||||
strtabshdr.get_sh_size());
|
strtabshdr.get_sh_size());
|
||||||
|
|
||||||
Read_symbols_data ret;
|
sd->symbols = fvsymtab;
|
||||||
ret.symbols = fvsymtab;
|
sd->symbols_size = extsize;
|
||||||
ret.symbols_size = extsize;
|
sd->symbol_names = fvstrtab;
|
||||||
ret.symbol_names = fvstrtab;
|
sd->symbol_names_size = strtabshdr.get_sh_size();
|
||||||
ret.symbol_names_size = strtabshdr.get_sh_size();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the symbols to the symbol table.
|
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
|
||||||
void
|
|
||||||
Sized_object<size, big_endian>::do_add_symbols(Symbol_table* symtab,
|
|
||||||
Read_symbols_data sd)
|
|
||||||
{
|
|
||||||
if (sd.symbols == NULL)
|
|
||||||
{
|
|
||||||
assert(sd.symbol_names == NULL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int sym_size = This::sym_size;
|
|
||||||
size_t symcount = sd.symbols_size / sym_size;
|
|
||||||
if (symcount * sym_size != sd.symbols_size)
|
|
||||||
{
|
|
||||||
fprintf(stderr,
|
|
||||||
_("%s: %s: size of symbols is not multiple of symbol size\n"),
|
|
||||||
program_name, this->name().c_str());
|
|
||||||
gold_exit(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->symbols_ = new Symbol*[symcount];
|
|
||||||
|
|
||||||
const elfcpp::Sym<size, big_endian>* syms =
|
|
||||||
reinterpret_cast<const elfcpp::Sym<size, big_endian>*>(sd.symbols->data());
|
|
||||||
const char* sym_names =
|
|
||||||
reinterpret_cast<const char*>(sd.symbol_names->data());
|
|
||||||
symtab->add_from_object(this, syms, symcount, sym_names,
|
|
||||||
sd.symbol_names_size, this->symbols_);
|
|
||||||
|
|
||||||
delete sd.symbols;
|
|
||||||
delete sd.symbol_names;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return whether to include a section group in the link. LAYOUT is
|
// Return whether to include a section group in the link. LAYOUT is
|
||||||
|
@ -377,24 +358,18 @@ Sized_object<size, big_endian>::include_linkonce_section(
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
void
|
void
|
||||||
Sized_object<size, big_endian>::do_layout(Layout* layout)
|
Sized_object<size, big_endian>::do_layout(Layout* layout,
|
||||||
|
Read_symbols_data* sd)
|
||||||
{
|
{
|
||||||
// This is always called from the main thread. Lock the file to
|
unsigned int shnum = this->shnum();
|
||||||
// keep the error checks happy.
|
if (shnum == 0)
|
||||||
Task_locker_obj<File_read> frl(this->input_file()->file());
|
return;
|
||||||
|
|
||||||
// Get the section headers.
|
// Get the section headers.
|
||||||
unsigned int shnum = this->shnum();
|
const unsigned char* pshdrs = sd->section_headers->data();
|
||||||
const unsigned char* pshdrs = this->get_view(this->shoff_,
|
|
||||||
shnum * This::shdr_size);
|
|
||||||
|
|
||||||
// Get the section names.
|
// Get the section names.
|
||||||
const unsigned char* pshdrnames = pshdrs + this->shstrndx_ * This::shdr_size;
|
const unsigned char* pnamesu = sd->section_names->data();
|
||||||
typename This::Shdr shdrnames(pshdrnames);
|
|
||||||
typename elfcpp::Elf_types<size>::Elf_WXword names_size =
|
|
||||||
shdrnames.get_sh_size();
|
|
||||||
const unsigned char* pnamesu = this->get_view(shdrnames.get_sh_offset(),
|
|
||||||
shdrnames.get_sh_size());
|
|
||||||
const char* pnames = reinterpret_cast<const char*>(pnamesu);
|
const char* pnames = reinterpret_cast<const char*>(pnamesu);
|
||||||
|
|
||||||
std::vector<Map_to_output>& map_sections(this->map_to_output());
|
std::vector<Map_to_output>& map_sections(this->map_to_output());
|
||||||
|
@ -403,11 +378,11 @@ Sized_object<size, big_endian>::do_layout(Layout* layout)
|
||||||
// Keep track of which sections to omit.
|
// Keep track of which sections to omit.
|
||||||
std::vector<bool> omit(shnum, false);
|
std::vector<bool> omit(shnum, false);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < shnum; ++i)
|
for (unsigned int i = 0; i < shnum; ++i, pshdrs += This::shdr_size)
|
||||||
{
|
{
|
||||||
typename This::Shdr shdr(pshdrs);
|
typename This::Shdr shdr(pshdrs);
|
||||||
|
|
||||||
if (shdr.get_sh_name() >= names_size)
|
if (shdr.get_sh_name() >= sd->section_names_size)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
_("%s: %s: bad section name offset for section %u: %lu\n"),
|
_("%s: %s: bad section name offset for section %u: %lu\n"),
|
||||||
|
@ -445,9 +420,51 @@ Sized_object<size, big_endian>::do_layout(Layout* layout)
|
||||||
|
|
||||||
map_sections[i].output_section = os;
|
map_sections[i].output_section = os;
|
||||||
map_sections[i].offset = offset;
|
map_sections[i].offset = offset;
|
||||||
|
|
||||||
pshdrs += This::shdr_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete sd->section_headers;
|
||||||
|
sd->section_headers = NULL;
|
||||||
|
delete sd->section_names;
|
||||||
|
sd->section_names = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the symbols to the symbol table.
|
||||||
|
|
||||||
|
template<int size, bool big_endian>
|
||||||
|
void
|
||||||
|
Sized_object<size, big_endian>::do_add_symbols(Symbol_table* symtab,
|
||||||
|
Read_symbols_data* sd)
|
||||||
|
{
|
||||||
|
if (sd->symbols == NULL)
|
||||||
|
{
|
||||||
|
assert(sd->symbol_names == NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int sym_size = This::sym_size;
|
||||||
|
size_t symcount = sd->symbols_size / sym_size;
|
||||||
|
if (symcount * sym_size != sd->symbols_size)
|
||||||
|
{
|
||||||
|
fprintf(stderr,
|
||||||
|
_("%s: %s: size of symbols is not multiple of symbol size\n"),
|
||||||
|
program_name, this->name().c_str());
|
||||||
|
gold_exit(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->symbols_ = new Symbol*[symcount];
|
||||||
|
|
||||||
|
const unsigned char* psyms = sd->symbols->data();
|
||||||
|
const elfcpp::Sym<size, big_endian>* syms =
|
||||||
|
reinterpret_cast<const elfcpp::Sym<size, big_endian>*>(psyms);
|
||||||
|
const char* sym_names =
|
||||||
|
reinterpret_cast<const char*>(sd->symbol_names->data());
|
||||||
|
symtab->add_from_object(this, syms, symcount, sym_names,
|
||||||
|
sd->symbol_names_size, this->symbols_);
|
||||||
|
|
||||||
|
delete sd->symbols;
|
||||||
|
sd->symbols = NULL;
|
||||||
|
delete sd->symbol_names;
|
||||||
|
sd->symbol_names = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finalize the local symbols. Here we record the file offset at
|
// Finalize the local symbols. Here we record the file offset at
|
||||||
|
|
|
@ -23,6 +23,12 @@ class Output_file;
|
||||||
|
|
||||||
struct Read_symbols_data
|
struct Read_symbols_data
|
||||||
{
|
{
|
||||||
|
// Section headers.
|
||||||
|
File_view* section_headers;
|
||||||
|
// Section names.
|
||||||
|
File_view* section_names;
|
||||||
|
// Size of section name data in bytes.
|
||||||
|
off_t section_names_size;
|
||||||
// Symbol data.
|
// Symbol data.
|
||||||
File_view* symbols;
|
File_view* symbols;
|
||||||
// Size of symbol data in bytes.
|
// Size of symbol data in bytes.
|
||||||
|
@ -93,20 +99,20 @@ class Object
|
||||||
sized_target(ACCEPT_SIZE_ENDIAN_ONLY);
|
sized_target(ACCEPT_SIZE_ENDIAN_ONLY);
|
||||||
|
|
||||||
// Read the symbol and relocation information.
|
// Read the symbol and relocation information.
|
||||||
Read_symbols_data
|
void
|
||||||
read_symbols()
|
read_symbols(Read_symbols_data* sd)
|
||||||
{ return this->do_read_symbols(); }
|
{ return this->do_read_symbols(sd); }
|
||||||
|
|
||||||
// Add symbol information to the global symbol table.
|
// Add symbol information to the global symbol table.
|
||||||
void
|
void
|
||||||
add_symbols(Symbol_table* symtab, Read_symbols_data rd)
|
add_symbols(Symbol_table* symtab, Read_symbols_data* sd)
|
||||||
{ this->do_add_symbols(symtab, rd); }
|
{ this->do_add_symbols(symtab, sd); }
|
||||||
|
|
||||||
// Pass sections which should be included in the link to the Layout
|
// Pass sections which should be included in the link to the Layout
|
||||||
// object, and record where the sections go in the output file.
|
// object, and record where the sections go in the output file.
|
||||||
void
|
void
|
||||||
layout(Layout* lay)
|
layout(Layout* lay, Read_symbols_data* sd)
|
||||||
{ this->do_layout(lay); }
|
{ this->do_layout(lay, sd); }
|
||||||
|
|
||||||
// Initial local symbol processing: set the offset where local
|
// Initial local symbol processing: set the offset where local
|
||||||
// symbol information will be stored; add local symbol names to
|
// symbol information will be stored; add local symbol names to
|
||||||
|
@ -144,17 +150,17 @@ class Object
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Read the symbols--implemented by child class.
|
// Read the symbols--implemented by child class.
|
||||||
virtual Read_symbols_data
|
virtual void
|
||||||
do_read_symbols() = 0;
|
do_read_symbols(Read_symbols_data*) = 0;
|
||||||
|
|
||||||
// Add symbol information to the global symbol table--implemented by
|
// Add symbol information to the global symbol table--implemented by
|
||||||
// child class.
|
// child class.
|
||||||
virtual void
|
virtual void
|
||||||
do_add_symbols(Symbol_table*, Read_symbols_data) = 0;
|
do_add_symbols(Symbol_table*, Read_symbols_data*) = 0;
|
||||||
|
|
||||||
// Lay out sections--implemented by child class.
|
// Lay out sections--implemented by child class.
|
||||||
virtual void
|
virtual void
|
||||||
do_layout(Layout*) = 0;
|
do_layout(Layout*, Read_symbols_data*) = 0;
|
||||||
|
|
||||||
// Finalize local symbols--implemented by child class.
|
// Finalize local symbols--implemented by child class.
|
||||||
virtual off_t
|
virtual off_t
|
||||||
|
@ -258,16 +264,16 @@ class Sized_object : public Object
|
||||||
setup(const typename elfcpp::Ehdr<size, big_endian>&);
|
setup(const typename elfcpp::Ehdr<size, big_endian>&);
|
||||||
|
|
||||||
// Read the symbols.
|
// Read the symbols.
|
||||||
Read_symbols_data
|
|
||||||
do_read_symbols();
|
|
||||||
|
|
||||||
// Add the symbols to the symbol table.
|
|
||||||
void
|
void
|
||||||
do_add_symbols(Symbol_table*, Read_symbols_data);
|
do_read_symbols(Read_symbols_data*);
|
||||||
|
|
||||||
// Lay out the input sections.
|
// Lay out the input sections.
|
||||||
void
|
void
|
||||||
do_layout(Layout*);
|
do_layout(Layout*, Read_symbols_data*);
|
||||||
|
|
||||||
|
// Add the symbols to the symbol table.
|
||||||
|
void
|
||||||
|
do_add_symbols(Symbol_table*, Read_symbols_data*);
|
||||||
|
|
||||||
// Finalize the local symbols.
|
// Finalize the local symbols.
|
||||||
off_t
|
off_t
|
||||||
|
@ -337,6 +343,8 @@ class Sized_object : public Object
|
||||||
void
|
void
|
||||||
write_local_symbols(Output_file*, const Stringpool*);
|
write_local_symbols(Output_file*, const Stringpool*);
|
||||||
|
|
||||||
|
// If non-NULL, a view of the section header data.
|
||||||
|
File_view* section_headers_;
|
||||||
// ELF file header e_flags field.
|
// ELF file header e_flags field.
|
||||||
unsigned int flags_;
|
unsigned int flags_;
|
||||||
// File offset of section header table.
|
// File offset of section header table.
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2006-09-29 12:54-0700\n"
|
"POT-Creation-Date: 2006-10-04 08:37-0700\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -51,7 +51,7 @@ msgstr ""
|
||||||
msgid "%s: %s: bad extended name entry at header %ld\n"
|
msgid "%s: %s: bad extended name entry at header %ld\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: archive.cc:283 archive.cc:296
|
#: archive.cc:284 archive.cc:297
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: member at %ld is not an ELF object"
|
msgid "%s: %s: member at %ld is not an ELF object"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -149,113 +149,113 @@ msgstr ""
|
||||||
msgid "%s: %s: unsupported RELA reloc section\n"
|
msgid "%s: %s: unsupported RELA reloc section\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:59
|
#: object.cc:60
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: bad e_ehsize field (%d != %d)\n"
|
msgid "%s: %s: bad e_ehsize field (%d != %d)\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:66
|
#: object.cc:67
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: bad e_shentsize field (%d != %d)\n"
|
msgid "%s: %s: bad e_shentsize field (%d != %d)\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:103
|
#: object.cc:104
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: unsupported ELF machine number %d\n"
|
msgid "%s: %s: unsupported ELF machine number %d\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:176
|
#: object.cc:196
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: invalid symbol table name index: %u\n"
|
msgid "%s: %s: invalid symbol table name index: %u\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:184
|
#: object.cc:204
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: symbol table name section has wrong type: %u\n"
|
msgid "%s: %s: symbol table name section has wrong type: %u\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:221
|
#: object.cc:256
|
||||||
#, c-format
|
|
||||||
msgid "%s: %s: size of symbols is not multiple of symbol size\n"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: object.cc:275
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: section group %u link %u out of range\n"
|
msgid "%s: %s: section group %u link %u out of range\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:285
|
#: object.cc:266
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: section group %u info %u out of range\n"
|
msgid "%s: %s: section group %u info %u out of range\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:296
|
#: object.cc:277
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s; %s: symtab section %u link %u out of range\n"
|
msgid "%s; %s: symtab section %u link %u out of range\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:312
|
#: object.cc:293
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: symbol %u name offset %u out of range\n"
|
msgid "%s: %s: symbol %u name offset %u out of range\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:334
|
#: object.cc:315
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: section %u in section group %u out of range"
|
msgid "%s: %s: section %u in section group %u out of range"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:413
|
#: object.cc:388
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: bad section name offset for section %u: %lu\n"
|
msgid "%s: %s: bad section name offset for section %u: %lu\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:520
|
#: object.cc:449
|
||||||
|
#, c-format
|
||||||
|
msgid "%s: %s: size of symbols is not multiple of symbol size\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: object.cc:537
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: unknown section index %u for local symbol %u\n"
|
msgid "%s: %s: unknown section index %u for local symbol %u\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:531
|
#: object.cc:548
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: local symbol %u section index %u out of range\n"
|
msgid "%s: %s: local symbol %u section index %u out of range\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. elfcpp::ET_DYN
|
#. elfcpp::ET_DYN
|
||||||
#: object.cc:684
|
#: object.cc:701
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: dynamic objects are not yet supported\n"
|
msgid "%s: %s: dynamic objects are not yet supported\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:708 object.cc:761 object.cc:782
|
#: object.cc:725 object.cc:778 object.cc:799
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: ELF file too short\n"
|
msgid "%s: %s: ELF file too short\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:717
|
#: object.cc:734
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: invalid ELF version 0\n"
|
msgid "%s: %s: invalid ELF version 0\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:720
|
#: object.cc:737
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: unsupported ELF version %d\n"
|
msgid "%s: %s: unsupported ELF version %d\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:728
|
#: object.cc:745
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: invalid ELF class 0\n"
|
msgid "%s: %s: invalid ELF class 0\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:735
|
#: object.cc:752
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: unsupported ELF class %d\n"
|
msgid "%s: %s: unsupported ELF class %d\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:743
|
#: object.cc:760
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: invalid ELF data encoding\n"
|
msgid "%s: %s: invalid ELF data encoding\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: object.cc:750
|
#: object.cc:767
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: unsupported ELF data encoding %d\n"
|
msgid "%s: %s: unsupported ELF data encoding %d\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -326,44 +326,44 @@ msgstr ""
|
||||||
msgid "%s: -%c: %s\n"
|
msgid "%s: -%c: %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: output.cc:383
|
#: output.cc:385
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: invalid alignment %lu for section \"%s\"\n"
|
msgid "%s: %s: invalid alignment %lu for section \"%s\"\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: output.cc:773
|
#: output.cc:775
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: open: %s\n"
|
msgid "%s: %s: open: %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: output.cc:782
|
#: output.cc:784
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: lseek: %s\n"
|
msgid "%s: %s: lseek: %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: output.cc:789
|
#: output.cc:791
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: write: %s\n"
|
msgid "%s: %s: write: %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: output.cc:799
|
#: output.cc:801
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: mmap: %s\n"
|
msgid "%s: %s: mmap: %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: output.cc:813
|
#: output.cc:815
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: munmap: %s\n"
|
msgid "%s: %s: munmap: %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: output.cc:821
|
#: output.cc:823
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: close: %s\n"
|
msgid "%s: %s: close: %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. Here we have to handle archives and any other input file
|
#. Here we have to handle archives and any other input file
|
||||||
#. types we need.
|
#. types we need.
|
||||||
#: readsyms.cc:107
|
#: readsyms.cc:110
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: not an object or archive\n"
|
msgid "%s: %s: not an object or archive\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -388,22 +388,22 @@ msgstr ""
|
||||||
msgid "%s: %s: reloc section %u size %lu uneven"
|
msgid "%s: %s: reloc section %u size %lu uneven"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: resolve.cc:144
|
#: resolve.cc:138
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: invalid STB_LOCAL symbol %s in external symbols\n"
|
msgid "%s: %s: invalid STB_LOCAL symbol %s in external symbols\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: resolve.cc:150
|
#: resolve.cc:144
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: unsupported symbol binding %d for symbol %s\n"
|
msgid "%s: %s: unsupported symbol binding %d for symbol %s\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: symtab.cc:347
|
#: symtab.cc:303
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: mixing 32-bit and 64-bit ELF objects\n"
|
msgid "%s: %s: mixing 32-bit and 64-bit ELF objects\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: symtab.cc:361
|
#: symtab.cc:317
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: %s: bad global symbol name offset %u at %lu\n"
|
msgid "%s: %s: bad global symbol name offset %u at %lu\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
|
@ -74,8 +74,10 @@ Read_symbols::run(Workqueue* workqueue)
|
||||||
|
|
||||||
this->input_objects_->add_object(obj);
|
this->input_objects_->add_object(obj);
|
||||||
|
|
||||||
Read_symbols_data sd = obj->read_symbols();
|
Read_symbols_data* sd = new Read_symbols_data;
|
||||||
workqueue->queue(new Add_symbols(this->symtab_, obj, sd,
|
obj->read_symbols(sd);
|
||||||
|
workqueue->queue(new Add_symbols(this->symtab_, this->layout_,
|
||||||
|
obj, sd,
|
||||||
this->this_blocker_,
|
this->this_blocker_,
|
||||||
this->next_blocker_));
|
this->next_blocker_));
|
||||||
|
|
||||||
|
@ -94,6 +96,7 @@ Read_symbols::run(Workqueue* workqueue)
|
||||||
Archive* arch = new Archive(this->input_.name(), input_file);
|
Archive* arch = new Archive(this->input_.name(), input_file);
|
||||||
arch->setup();
|
arch->setup();
|
||||||
workqueue->queue(new Add_archive_symbols(this->symtab_,
|
workqueue->queue(new Add_archive_symbols(this->symtab_,
|
||||||
|
this->layout_,
|
||||||
this->input_objects_,
|
this->input_objects_,
|
||||||
arch,
|
arch,
|
||||||
this->this_blocker_,
|
this->this_blocker_,
|
||||||
|
@ -155,7 +158,10 @@ Add_symbols::locks(Workqueue* workqueue)
|
||||||
void
|
void
|
||||||
Add_symbols::run(Workqueue*)
|
Add_symbols::run(Workqueue*)
|
||||||
{
|
{
|
||||||
|
this->object_->layout(this->layout_, this->sd_);
|
||||||
this->object_->add_symbols(this->symtab_, this->sd_);
|
this->object_->add_symbols(this->symtab_, this->sd_);
|
||||||
|
delete this->sd_;
|
||||||
|
this->sd_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End namespace gold.
|
} // End namespace gold.
|
||||||
|
|
|
@ -29,12 +29,12 @@ class Read_symbols : public Task
|
||||||
// has completed; it will be NULL for the first task. NEXT_BLOCKER
|
// has completed; it will be NULL for the first task. NEXT_BLOCKER
|
||||||
// is used to block the next input file from adding symbols.
|
// is used to block the next input file from adding symbols.
|
||||||
Read_symbols(const General_options& options, Input_objects* input_objects,
|
Read_symbols(const General_options& options, Input_objects* input_objects,
|
||||||
Symbol_table* symtab, const Dirsearch& dirpath,
|
Symbol_table* symtab, Layout* layout, const Dirsearch& dirpath,
|
||||||
const Input_argument& input,
|
const Input_argument& input,
|
||||||
Task_token* this_blocker, Task_token* next_blocker)
|
Task_token* this_blocker, Task_token* next_blocker)
|
||||||
: options_(options), input_objects_(input_objects), symtab_(symtab),
|
: options_(options), input_objects_(input_objects), symtab_(symtab),
|
||||||
dirpath_(dirpath), input_(input), this_blocker_(this_blocker),
|
layout_(layout), dirpath_(dirpath), input_(input),
|
||||||
next_blocker_(next_blocker)
|
this_blocker_(this_blocker), next_blocker_(next_blocker)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~Read_symbols();
|
~Read_symbols();
|
||||||
|
@ -54,6 +54,7 @@ class Read_symbols : public Task
|
||||||
const General_options& options_;
|
const General_options& options_;
|
||||||
Input_objects* input_objects_;
|
Input_objects* input_objects_;
|
||||||
Symbol_table* symtab_;
|
Symbol_table* symtab_;
|
||||||
|
Layout* layout_;
|
||||||
const Dirsearch& dirpath_;
|
const Dirsearch& dirpath_;
|
||||||
const Input_argument& input_;
|
const Input_argument& input_;
|
||||||
Task_token* this_blocker_;
|
Task_token* this_blocker_;
|
||||||
|
@ -70,10 +71,11 @@ class Add_symbols : public Task
|
||||||
// THIS_BLOCKER is used to prevent this task from running before the
|
// THIS_BLOCKER is used to prevent this task from running before the
|
||||||
// one for the previous input file. NEXT_BLOCKER is used to prevent
|
// one for the previous input file. NEXT_BLOCKER is used to prevent
|
||||||
// the next task from running.
|
// the next task from running.
|
||||||
Add_symbols(Symbol_table* symtab, Object* object, Read_symbols_data sd,
|
Add_symbols(Symbol_table* symtab, Layout* layout, Object* object,
|
||||||
Task_token* this_blocker, Task_token* next_blocker)
|
Read_symbols_data* sd, Task_token* this_blocker,
|
||||||
: symtab_(symtab), object_(object), sd_(sd), this_blocker_(this_blocker),
|
Task_token* next_blocker)
|
||||||
next_blocker_(next_blocker)
|
: symtab_(symtab), layout_(layout), object_(object), sd_(sd),
|
||||||
|
this_blocker_(this_blocker), next_blocker_(next_blocker)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~Add_symbols();
|
~Add_symbols();
|
||||||
|
@ -93,8 +95,9 @@ private:
|
||||||
class Add_symbols_locker;
|
class Add_symbols_locker;
|
||||||
|
|
||||||
Symbol_table* symtab_;
|
Symbol_table* symtab_;
|
||||||
|
Layout* layout_;
|
||||||
Object* object_;
|
Object* object_;
|
||||||
Read_symbols_data sd_;
|
Read_symbols_data* sd_;
|
||||||
Task_token* this_blocker_;
|
Task_token* this_blocker_;
|
||||||
Task_token* next_blocker_;
|
Task_token* next_blocker_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -184,9 +184,10 @@ Symbol_table::resolve(Sized_symbol<size>* to,
|
||||||
switch (tobits * 16 + frombits)
|
switch (tobits * 16 + frombits)
|
||||||
{
|
{
|
||||||
case DEF * 16 + DEF:
|
case DEF * 16 + DEF:
|
||||||
// Two definitions of the same symbol. We can't give an error
|
// Two definitions of the same symbol.
|
||||||
// here, because we have not yet discarded linkonce and comdat
|
fprintf(stderr, "%s: %s: multiple definition of %s\n",
|
||||||
// sections. FIXME.
|
program_name, object->name().c_str(), to->name());
|
||||||
|
// FIXME: Report locations. Record that we have seen an error.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case WEAK_DEF * 16 + DEF:
|
case WEAK_DEF * 16 + DEF:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue