table.
// may be satisfied by other objects in the archive.
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();
std::vector<bool> seen;
// We want to include this object in the link.
last = this->armap_[i].offset;
- this->include_member(symtab, input_objects, last);
+ this->include_member(symtab, layout, input_objects, last);
added_new_object = true;
}
}
// the member header.
void
-Archive::include_member(Symbol_table* symtab, Input_objects* input_objects,
- off_t off)
+Archive::include_member(Symbol_table* symtab, Layout* layout,
+ Input_objects* input_objects, off_t off)
{
std::string n;
this->read_header(off, &n);
input_objects->add_object(obj);
- Read_symbols_data sd = obj->read_symbols();
- obj->add_symbols(symtab, sd);
+ Read_symbols_data sd;
+ obj->read_symbols(&sd);
+ obj->layout(layout, &sd);
+ obj->add_symbols(symtab, &sd);
}
// Add_archive_symbols methods.
void
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.
class Input_file;
class Input_objects;
+class Layout;
class Symbol_table;
// This class represents an archive--generally a libNAME.a file.
// Select members from the archive as needed and add them to the
// link.
void
- add_symbols(Symbol_table*, Input_objects*);
+ add_symbols(Symbol_table*, Layout*, Input_objects*);
private:
Archive(const Archive&);
// Include an archive member in the link.
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.
struct Armap_entry
class Add_archive_symbols : public Task
{
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,
Task_token* next_blocker)
- : symtab_(symtab), input_objects_(input_objects), archive_(archive),
- this_blocker_(this_blocker), next_blocker_(next_blocker)
+ : symtab_(symtab), layout_(layout), input_objects_(input_objects),
+ archive_(archive), this_blocker_(this_blocker),
+ next_blocker_(next_blocker)
{ }
~Add_archive_symbols();
class Add_archive_symbols_locker;
Symbol_table* symtab_;
+ Layout* layout_;
Input_objects* input_objects_;
Archive* archive_;
Task_token* this_blocker_;
const Dirsearch& search_path,
const Command_line::Input_argument_list& inputs,
Workqueue* workqueue, Input_objects* input_objects,
- Symbol_table* symtab)
+ Symbol_table* symtab, Layout* layout)
{
if (inputs.empty())
gold_fatal(_("no input files"), false);
{
Task_token* next_blocker = new Task_token();
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,
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));
}
// The symbol table.
Symbol_table symtab;
+ // The layout object.
+ Layout layout(command_line.options());
+
// Get the search path from the -L options.
Dirsearch search_path;
search_path.add(&workqueue, command_line.options().search_path());
// Queue up the first set of tasks.
queue_initial_tasks(command_line.options(), search_path,
command_line.inputs(), &workqueue, &input_objects,
- &symtab);
+ &symtab, &layout);
// Run the main task processing loop.
workqueue.process();
void
Layout_task::run(Workqueue* workqueue)
{
- // Nothing ever frees this.
- Layout* layout = new Layout(this->options_);
- 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_);
+ off_t file_size = this->layout_->finalize(this->input_objects_,
+ this->symtab_);
// Now we know the final size of the output file and we know where
// each piece of information goes.
// Queue up the final set of tasks.
gold::queue_final_tasks(this->options_, this->input_objects_,
- this->symtab_, layout, workqueue, of);
+ this->symtab_, this->layout_, workqueue, of);
}
// Layout methods.
: options_(options), last_shndx_(0), namepool_(), sympool_(), signatures_(),
section_name_map_(), segment_list_(), section_list_(),
special_output_list_()
-{
-}
-
-// Prepare for doing layout.
-
-void
-Layout::init()
{
// 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.
Layout_task(const General_options& options,
const Input_objects* input_objects,
Symbol_table* symtab,
+ Layout* layout,
Task_token* this_blocker)
: options_(options), input_objects_(input_objects), symtab_(symtab),
- this_blocker_(this_blocker)
+ layout_(layout), this_blocker_(this_blocker)
{ }
~Layout_task();
const General_options& options_;
const Input_objects* input_objects_;
Symbol_table* symtab_;
+ Layout* layout_;
Task_token* this_blocker_;
};
public:
Layout(const General_options& options);
- // Initialize the object.
- void
- init();
-
// Given an input section named NAME with data in SHDR from the
// object file OBJECT, return the output section where this input
// section should go. Set *OFFSET to the offset within the output
off_t offset,
const elfcpp::Ehdr<size, big_endian>& ehdr)
: Object(name, input_file, false, offset),
+ section_headers_(NULL),
flags_(ehdr.get_e_flags()),
shoff_(ehdr.get_e_shoff()),
shstrndx_(0),
gold_exit(false);
}
this->set_target(target);
+
unsigned int shnum = ehdr.get_e_shnum();
unsigned int shstrndx = ehdr.get_e_shstrndx();
if ((shnum == 0 || shstrndx == elfcpp::SHN_XINDEX)
if (shnum == 0)
return;
- // Find the SHT_SYMTAB section.
- const unsigned char* p = this->get_view (this->shoff_,
- shnum * This::shdr_size);
+ // We store the section headers in a File_view until do_read_symbols.
+ this->section_headers_ = this->get_lasting_view(this->shoff_,
+ 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.
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);
if (shdr.get_sh_type() == elfcpp::SHT_SYMTAB)
this->symtab_shnum_ = i;
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>
-Read_symbols_data
-Sized_object<size, big_endian>::do_read_symbols()
+void
+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)
{
// No symbol table. Weird but legal.
- Read_symbols_data ret;
- ret.symbols = NULL;
- ret.symbols_size = 0;
- ret.symbol_names = NULL;
- ret.symbol_names_size = 0;
- return ret;
+ sd->symbols = NULL;
+ sd->symbols_size = 0;
+ sd->symbol_names = NULL;
+ sd->symbol_names_size = 0;
+ return;
}
- // Read the symbol table section header.
- typename This::Shdr symtabshdr(this->section_header(this->symtab_shnum_));
+ // Get the symbol table section header.
+ typename This::Shdr symtabshdr(pshdrs
+ + this->symtab_shnum_ * This::shdr_size);
assert(symtabshdr.get_sh_type() == elfcpp::SHT_SYMTAB);
// We only need the external symbols.
File_view* fvstrtab = this->get_lasting_view(strtabshdr.get_sh_offset(),
strtabshdr.get_sh_size());
- Read_symbols_data ret;
- ret.symbols = fvsymtab;
- ret.symbols_size = extsize;
- ret.symbol_names = fvstrtab;
- 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;
+ sd->symbols = fvsymtab;
+ sd->symbols_size = extsize;
+ sd->symbol_names = fvstrtab;
+ sd->symbol_names_size = strtabshdr.get_sh_size();
}
// Return whether to include a section group in the link. LAYOUT is
template<int size, bool big_endian>
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
- // keep the error checks happy.
- Task_locker_obj<File_read> frl(this->input_file()->file());
+ unsigned int shnum = this->shnum();
+ if (shnum == 0)
+ return;
// Get the section headers.
- unsigned int shnum = this->shnum();
- const unsigned char* pshdrs = this->get_view(this->shoff_,
- shnum * This::shdr_size);
+ const unsigned char* pshdrs = sd->section_headers->data();
// Get the section names.
- const unsigned char* pshdrnames = pshdrs + this->shstrndx_ * This::shdr_size;
- 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 unsigned char* pnamesu = sd->section_names->data();
const char* pnames = reinterpret_cast<const char*>(pnamesu);
std::vector<Map_to_output>& map_sections(this->map_to_output());
// Keep track of which sections to omit.
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);
- if (shdr.get_sh_name() >= names_size)
+ if (shdr.get_sh_name() >= sd->section_names_size)
{
fprintf(stderr,
_("%s: %s: bad section name offset for section %u: %lu\n"),
map_sections[i].output_section = os;
map_sections[i].offset = offset;
+ }
+
+ delete sd->section_headers;
+ sd->section_headers = NULL;
+ delete sd->section_names;
+ sd->section_names = NULL;
+}
+
+// Add the symbols to the symbol table.
- pshdrs += This::shdr_size;
+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
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.
File_view* symbols;
// Size of symbol data in bytes.
sized_target(ACCEPT_SIZE_ENDIAN_ONLY);
// Read the symbol and relocation information.
- Read_symbols_data
- read_symbols()
- { return this->do_read_symbols(); }
+ void
+ read_symbols(Read_symbols_data* sd)
+ { return this->do_read_symbols(sd); }
// Add symbol information to the global symbol table.
void
- add_symbols(Symbol_table* symtab, Read_symbols_data rd)
- { this->do_add_symbols(symtab, rd); }
+ add_symbols(Symbol_table* symtab, Read_symbols_data* sd)
+ { this->do_add_symbols(symtab, sd); }
// Pass sections which should be included in the link to the Layout
// object, and record where the sections go in the output file.
void
- layout(Layout* lay)
- { this->do_layout(lay); }
+ layout(Layout* lay, Read_symbols_data* sd)
+ { this->do_layout(lay, sd); }
// Initial local symbol processing: set the offset where local
// symbol information will be stored; add local symbol names to
protected:
// Read the symbols--implemented by child class.
- virtual Read_symbols_data
- do_read_symbols() = 0;
+ virtual void
+ do_read_symbols(Read_symbols_data*) = 0;
// Add symbol information to the global symbol table--implemented by
// child class.
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.
virtual void
- do_layout(Layout*) = 0;
+ do_layout(Layout*, Read_symbols_data*) = 0;
// Finalize local symbols--implemented by child class.
virtual off_t
setup(const typename elfcpp::Ehdr<size, big_endian>&);
// Read the symbols.
- Read_symbols_data
- do_read_symbols();
-
- // Add the symbols to the symbol table.
void
- do_add_symbols(Symbol_table*, Read_symbols_data);
+ do_read_symbols(Read_symbols_data*);
// Lay out the input sections.
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.
off_t
void
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.
unsigned int flags_;
// File offset of section header table.
msgstr ""
"Project-Id-Version: PACKAGE VERSION\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"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
msgid "%s: %s: bad extended name entry at header %ld\n"
msgstr ""
-#: archive.cc:283 archive.cc:296
+#: archive.cc:284 archive.cc:297
#, c-format
msgid "%s: %s: member at %ld is not an ELF object"
msgstr ""
msgid "%s: %s: unsupported RELA reloc section\n"
msgstr ""
-#: object.cc:59
+#: object.cc:60
#, c-format
msgid "%s: %s: bad e_ehsize field (%d != %d)\n"
msgstr ""
-#: object.cc:66
+#: object.cc:67
#, c-format
msgid "%s: %s: bad e_shentsize field (%d != %d)\n"
msgstr ""
-#: object.cc:103
+#: object.cc:104
#, c-format
msgid "%s: %s: unsupported ELF machine number %d\n"
msgstr ""
-#: object.cc:176
+#: object.cc:196
#, c-format
msgid "%s: %s: invalid symbol table name index: %u\n"
msgstr ""
-#: object.cc:184
+#: object.cc:204
#, c-format
msgid "%s: %s: symbol table name section has wrong type: %u\n"
msgstr ""
-#: object.cc:221
-#, c-format
-msgid "%s: %s: size of symbols is not multiple of symbol size\n"
-msgstr ""
-
-#: object.cc:275
+#: object.cc:256
#, c-format
msgid "%s: %s: section group %u link %u out of range\n"
msgstr ""
-#: object.cc:285
+#: object.cc:266
#, c-format
msgid "%s: %s: section group %u info %u out of range\n"
msgstr ""
-#: object.cc:296
+#: object.cc:277
#, c-format
msgid "%s; %s: symtab section %u link %u out of range\n"
msgstr ""
-#: object.cc:312
+#: object.cc:293
#, c-format
msgid "%s: %s: symbol %u name offset %u out of range\n"
msgstr ""
-#: object.cc:334
+#: object.cc:315
#, c-format
msgid "%s: %s: section %u in section group %u out of range"
msgstr ""
-#: object.cc:413
+#: object.cc:388
#, c-format
msgid "%s: %s: bad section name offset for section %u: %lu\n"
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
msgid "%s: %s: unknown section index %u for local symbol %u\n"
msgstr ""
-#: object.cc:531
+#: object.cc:548
#, c-format
msgid "%s: %s: local symbol %u section index %u out of range\n"
msgstr ""
#. elfcpp::ET_DYN
-#: object.cc:684
+#: object.cc:701
#, c-format
msgid "%s: %s: dynamic objects are not yet supported\n"
msgstr ""
-#: object.cc:708 object.cc:761 object.cc:782
+#: object.cc:725 object.cc:778 object.cc:799
#, c-format
msgid "%s: %s: ELF file too short\n"
msgstr ""
-#: object.cc:717
+#: object.cc:734
#, c-format
msgid "%s: %s: invalid ELF version 0\n"
msgstr ""
-#: object.cc:720
+#: object.cc:737
#, c-format
msgid "%s: %s: unsupported ELF version %d\n"
msgstr ""
-#: object.cc:728
+#: object.cc:745
#, c-format
msgid "%s: %s: invalid ELF class 0\n"
msgstr ""
-#: object.cc:735
+#: object.cc:752
#, c-format
msgid "%s: %s: unsupported ELF class %d\n"
msgstr ""
-#: object.cc:743
+#: object.cc:760
#, c-format
msgid "%s: %s: invalid ELF data encoding\n"
msgstr ""
-#: object.cc:750
+#: object.cc:767
#, c-format
msgid "%s: %s: unsupported ELF data encoding %d\n"
msgstr ""
msgid "%s: -%c: %s\n"
msgstr ""
-#: output.cc:383
+#: output.cc:385
#, c-format
msgid "%s: %s: invalid alignment %lu for section \"%s\"\n"
msgstr ""
-#: output.cc:773
+#: output.cc:775
#, c-format
msgid "%s: %s: open: %s\n"
msgstr ""
-#: output.cc:782
+#: output.cc:784
#, c-format
msgid "%s: %s: lseek: %s\n"
msgstr ""
-#: output.cc:789
+#: output.cc:791
#, c-format
msgid "%s: %s: write: %s\n"
msgstr ""
-#: output.cc:799
+#: output.cc:801
#, c-format
msgid "%s: %s: mmap: %s\n"
msgstr ""
-#: output.cc:813
+#: output.cc:815
#, c-format
msgid "%s: %s: munmap: %s\n"
msgstr ""
-#: output.cc:821
+#: output.cc:823
#, c-format
msgid "%s: %s: close: %s\n"
msgstr ""
#. Here we have to handle archives and any other input file
#. types we need.
-#: readsyms.cc:107
+#: readsyms.cc:110
#, c-format
msgid "%s: %s: not an object or archive\n"
msgstr ""
msgid "%s: %s: reloc section %u size %lu uneven"
msgstr ""
-#: resolve.cc:144
+#: resolve.cc:138
#, c-format
msgid "%s: %s: invalid STB_LOCAL symbol %s in external symbols\n"
msgstr ""
-#: resolve.cc:150
+#: resolve.cc:144
#, c-format
msgid "%s: %s: unsupported symbol binding %d for symbol %s\n"
msgstr ""
-#: symtab.cc:347
+#: symtab.cc:303
#, c-format
msgid "%s: %s: mixing 32-bit and 64-bit ELF objects\n"
msgstr ""
-#: symtab.cc:361
+#: symtab.cc:317
#, c-format
msgid "%s: %s: bad global symbol name offset %u at %lu\n"
msgstr ""
this->input_objects_->add_object(obj);
- Read_symbols_data sd = obj->read_symbols();
- workqueue->queue(new Add_symbols(this->symtab_, obj, sd,
+ Read_symbols_data* sd = new Read_symbols_data;
+ obj->read_symbols(sd);
+ workqueue->queue(new Add_symbols(this->symtab_, this->layout_,
+ obj, sd,
this->this_blocker_,
this->next_blocker_));
Archive* arch = new Archive(this->input_.name(), input_file);
arch->setup();
workqueue->queue(new Add_archive_symbols(this->symtab_,
+ this->layout_,
this->input_objects_,
arch,
this->this_blocker_,
void
Add_symbols::run(Workqueue*)
{
+ this->object_->layout(this->layout_, this->sd_);
this->object_->add_symbols(this->symtab_, this->sd_);
+ delete this->sd_;
+ this->sd_ = NULL;
}
} // End namespace gold.
// has completed; it will be NULL for the first task. NEXT_BLOCKER
// is used to block the next input file from adding symbols.
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,
Task_token* this_blocker, Task_token* next_blocker)
: options_(options), input_objects_(input_objects), symtab_(symtab),
- dirpath_(dirpath), input_(input), this_blocker_(this_blocker),
- next_blocker_(next_blocker)
+ layout_(layout), dirpath_(dirpath), input_(input),
+ this_blocker_(this_blocker), next_blocker_(next_blocker)
{ }
~Read_symbols();
const General_options& options_;
Input_objects* input_objects_;
Symbol_table* symtab_;
+ Layout* layout_;
const Dirsearch& dirpath_;
const Input_argument& input_;
Task_token* this_blocker_;
// THIS_BLOCKER is used to prevent this task from running before the
// one for the previous input file. NEXT_BLOCKER is used to prevent
// the next task from running.
- Add_symbols(Symbol_table* symtab, Object* object, Read_symbols_data sd,
- Task_token* this_blocker, Task_token* next_blocker)
- : symtab_(symtab), object_(object), sd_(sd), this_blocker_(this_blocker),
- next_blocker_(next_blocker)
+ Add_symbols(Symbol_table* symtab, Layout* layout, Object* object,
+ Read_symbols_data* sd, Task_token* this_blocker,
+ Task_token* next_blocker)
+ : symtab_(symtab), layout_(layout), object_(object), sd_(sd),
+ this_blocker_(this_blocker), next_blocker_(next_blocker)
{ }
~Add_symbols();
class Add_symbols_locker;
Symbol_table* symtab_;
+ Layout* layout_;
Object* object_;
- Read_symbols_data sd_;
+ Read_symbols_data* sd_;
Task_token* this_blocker_;
Task_token* next_blocker_;
};
switch (tobits * 16 + frombits)
{
case DEF * 16 + DEF:
- // Two definitions of the same symbol. We can't give an error
- // here, because we have not yet discarded linkonce and comdat
- // sections. FIXME.
+ // Two definitions of the same symbol.
+ fprintf(stderr, "%s: %s: multiple definition of %s\n",
+ program_name, object->name().c_str(), to->name());
+ // FIXME: Report locations. Record that we have seen an error.
return;
case WEAK_DEF * 16 + DEF: