diff options
author | Ian Lance Taylor <iant@google.com> | 2006-10-06 20:40:16 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@google.com> | 2006-10-06 20:40:16 +0000 |
commit | 12e14209f0834b6d3d9884a586b558c32eb2607c (patch) | |
tree | 04db4beba9abf0d2bb6f91c383a4ac4d76cf7541 /gold | |
parent | 33423b7ffed87b140d924bc06ff35d353bfc4871 (diff) | |
download | binutils-12e14209f0834b6d3d9884a586b558c32eb2607c.tar.gz binutils-12e14209f0834b6d3d9884a586b558c32eb2607c.tar.bz2 binutils-12e14209f0834b6d3d9884a586b558c32eb2607c.zip |
Lay out object file sections when we add the symbols to the symbol
table.
Diffstat (limited to 'gold')
-rw-r--r-- | gold/archive.cc | 18 | ||||
-rw-r--r-- | gold/archive.h | 14 | ||||
-rw-r--r-- | gold/gold.cc | 11 | ||||
-rw-r--r-- | gold/layout.cc | 20 | ||||
-rw-r--r-- | gold/layout.h | 8 | ||||
-rw-r--r-- | gold/object.cc | 167 | ||||
-rw-r--r-- | gold/object.h | 42 | ||||
-rw-r--r-- | gold/po/gold.pot | 80 | ||||
-rw-r--r-- | gold/readsyms.cc | 10 | ||||
-rw-r--r-- | gold/readsyms.h | 19 | ||||
-rw-r--r-- | gold/resolve.cc | 7 |
11 files changed, 213 insertions, 183 deletions
diff --git a/gold/archive.cc b/gold/archive.cc index 60193252041..86396439678 100644 --- a/gold/archive.cc +++ b/gold/archive.cc @@ -218,7 +218,8 @@ Archive::read_header(off_t off, std::string* pname) // 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; @@ -253,7 +254,7 @@ Archive::add_symbols(Symbol_table* symtab, Input_objects* input_objects) // 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; } } @@ -264,8 +265,8 @@ Archive::add_symbols(Symbol_table* symtab, Input_objects* input_objects) // 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); @@ -305,8 +306,10 @@ Archive::include_member(Symbol_table* symtab, Input_objects* input_objects, 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. @@ -354,7 +357,8 @@ Add_archive_symbols::locks(Workqueue* workqueue) 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. diff --git a/gold/archive.h b/gold/archive.h index 14d1c3b3f5b..b2d4c46550f 100644 --- a/gold/archive.h +++ b/gold/archive.h @@ -13,6 +13,7 @@ namespace gold class Input_file; class Input_objects; +class Layout; class Symbol_table; // 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 // link. void - add_symbols(Symbol_table*, Input_objects*); + add_symbols(Symbol_table*, Layout*, Input_objects*); private: Archive(const Archive&); @@ -81,7 +82,7 @@ class 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 @@ -108,11 +109,13 @@ class Archive 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(); @@ -132,6 +135,7 @@ class Add_archive_symbols : public Task class Add_archive_symbols_locker; Symbol_table* symtab_; + Layout* layout_; Input_objects* input_objects_; Archive* archive_; Task_token* this_blocker_; diff --git a/gold/gold.cc b/gold/gold.cc index f403910a7e7..6874e1b84e8 100644 --- a/gold/gold.cc +++ b/gold/gold.cc @@ -70,7 +70,7 @@ queue_initial_tasks(const General_options& options, 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); @@ -86,13 +86,13 @@ queue_initial_tasks(const General_options& options, { 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)); } @@ -170,6 +170,9 @@ main(int argc, char** argv) // 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()); @@ -177,7 +180,7 @@ main(int argc, char** argv) // 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(); diff --git a/gold/layout.cc b/gold/layout.cc index 2448bf8362b..61b6895682c 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -45,15 +45,8 @@ Layout_task::locks(Workqueue*) 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. @@ -62,7 +55,7 @@ Layout_task::run(Workqueue* workqueue) // 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. @@ -72,13 +65,6 @@ Layout::Layout(const General_options& options) 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. segment_list_.reserve(12); diff --git a/gold/layout.h b/gold/layout.h index 930d2b9c6c0..028d714e6a3 100644 --- a/gold/layout.h +++ b/gold/layout.h @@ -37,9 +37,10 @@ class Layout_task : public Task 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(); @@ -62,6 +63,7 @@ class Layout_task : public Task const General_options& options_; const Input_objects* input_objects_; Symbol_table* symtab_; + Layout* layout_; Task_token* this_blocker_; }; @@ -72,10 +74,6 @@ class Layout 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 diff --git a/gold/object.cc b/gold/object.cc index 6186f6576b4..d8658e920c9 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -44,6 +44,7 @@ Sized_object<size, big_endian>::Sized_object( 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), @@ -105,6 +106,7 @@ Sized_object<size, big_endian>::setup( 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) @@ -122,12 +124,19 @@ Sized_object<size, big_endian>::setup( 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) @@ -135,29 +144,40 @@ Sized_object<size, big_endian>::setup( 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. @@ -191,49 +211,10 @@ Sized_object<size, big_endian>::do_read_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 @@ -377,24 +358,18 @@ Sized_object<size, big_endian>::include_linkonce_section( 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()); @@ -403,11 +378,11 @@ Sized_object<size, big_endian>::do_layout(Layout* layout) // 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"), @@ -445,9 +420,51 @@ Sized_object<size, big_endian>::do_layout(Layout* layout) 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 diff --git a/gold/object.h b/gold/object.h index cea0f06a8f7..dfcb94410d1 100644 --- a/gold/object.h +++ b/gold/object.h @@ -23,6 +23,12 @@ class Output_file; 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. @@ -93,20 +99,20 @@ class Object 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 @@ -144,17 +150,17 @@ class Object 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 @@ -258,16 +264,16 @@ class Sized_object : public Object 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 @@ -337,6 +343,8 @@ class Sized_object : public Object 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. diff --git a/gold/po/gold.pot b/gold/po/gold.pot index 83ad0260543..48bc987867a 100644 --- a/gold/po/gold.pot +++ b/gold/po/gold.pot @@ -8,7 +8,7 @@ msgid "" 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" @@ -51,7 +51,7 @@ msgstr "" 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 "" @@ -149,113 +149,113 @@ 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 "" @@ -326,44 +326,44 @@ 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 "" @@ -388,22 +388,22 @@ 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 "" diff --git a/gold/readsyms.cc b/gold/readsyms.cc index ee0e0638c62..adc8fac6e91 100644 --- a/gold/readsyms.cc +++ b/gold/readsyms.cc @@ -74,8 +74,10 @@ Read_symbols::run(Workqueue* workqueue) 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_)); @@ -94,6 +96,7 @@ Read_symbols::run(Workqueue* workqueue) 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_, @@ -155,7 +158,10 @@ Add_symbols::locks(Workqueue* workqueue) 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. diff --git a/gold/readsyms.h b/gold/readsyms.h index 46d73c88732..2077d473fe0 100644 --- a/gold/readsyms.h +++ b/gold/readsyms.h @@ -29,12 +29,12 @@ class Read_symbols : public Task // 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(); @@ -54,6 +54,7 @@ class Read_symbols : public Task const General_options& options_; Input_objects* input_objects_; Symbol_table* symtab_; + Layout* layout_; const Dirsearch& dirpath_; const Input_argument& input_; 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 // 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(); @@ -93,8 +95,9 @@ private: 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_; }; diff --git a/gold/resolve.cc b/gold/resolve.cc index 98e93f0737b..6b8199cd8f2 100644 --- a/gold/resolve.cc +++ b/gold/resolve.cc @@ -184,9 +184,10 @@ Symbol_table::resolve(Sized_symbol<size>* to, 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: |