1 // archive.cc -- archive support for gold 2 3 // Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 4 // Written by Ian Lance Taylor <iant@google.com>. 5 6 // This file is part of gold. 7 8 // This program is free software; you can redistribute it and/or modify 9 // it under the terms of the GNU General Public License as published by 10 // the Free Software Foundation; either version 3 of the License, or 11 // (at your option) any later version. 12 13 // This program is distributed in the hope that it will be useful, 14 // but WITHOUT ANY WARRANTY; without even the implied warranty of 15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 // GNU General Public License for more details. 17 18 // You should have received a copy of the GNU General Public License 19 // along with this program; if not, write to the Free Software 20 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21 // MA 02110-1301, USA. 22 23 #include "gold.h" 24 25 #include <cerrno> 26 #include <cstring> 27 #include <climits> 28 #include <vector> 29 #include "libiberty.h" 30 #include "filenames.h" 31 32 #include "elfcpp.h" 33 #include "options.h" 34 #include "mapfile.h" 35 #include "fileread.h" 36 #include "readsyms.h" 37 #include "symtab.h" 38 #include "object.h" 39 #include "layout.h" 40 #include "archive.h" 41 #include "plugin.h" 42 #include "incremental.h" 43 44 namespace gold 45 { 46 47 // The header of an entry in the archive. This is all readable text, 48 // padded with spaces where necesary. If the contents of an archive 49 // are all text file, the entire archive is readable. 50 51 struct Archive::Archive_header 52 { 53 // The entry name. 54 char ar_name[16]; 55 // The file modification time. 56 char ar_date[12]; 57 // The user's UID in decimal. 58 char ar_uid[6]; 59 // The user's GID in decimal. 60 char ar_gid[6]; 61 // The file mode in octal. 62 char ar_mode[8]; 63 // The file size in decimal. 64 char ar_size[10]; 65 // The final magic code. 66 char ar_fmag[2]; 67 }; 68 69 // Class Archive static variables. 70 unsigned int Archive::total_archives; 71 unsigned int Archive::total_members; 72 unsigned int Archive::total_members_loaded; 73 74 // Archive methods. 75 76 const char Archive::armag[sarmag] = 77 { 78 '!', '<', 'a', 'r', 'c', 'h', '>', '\n' 79 }; 80 81 const char Archive::armagt[sarmag] = 82 { 83 '!', '<', 't', 'h', 'i', 'n', '>', '\n' 84 }; 85 86 const char Archive::arfmag[2] = { '`', '\n' }; 87 88 Archive::Archive(const std::string& name, Input_file* input_file, 89 bool is_thin_archive, Dirsearch* dirpath, Task* task) 90 : name_(name), input_file_(input_file), armap_(), armap_names_(), 91 extended_names_(), armap_checked_(), seen_offsets_(), members_(), 92 is_thin_archive_(is_thin_archive), included_member_(false), 93 nested_archives_(), dirpath_(dirpath), task_(task), num_members_(0), 94 incremental_info_(NULL) 95 { 96 this->no_export_ = 97 parameters->options().check_excluded_libs(input_file->found_name()); 98 } 99 100 // Set up the archive: read the symbol map and the extended name 101 // table. 102 103 void 104 Archive::setup() 105 { 106 // We need to ignore empty archives. 107 if (this->input_file_->file().filesize() == sarmag) 108 return; 109 110 // The first member of the archive should be the symbol table. 111 std::string armap_name; 112 section_size_type armap_size = 113 convert_to_section_size_type(this->read_header(sarmag, false, 114 &armap_name, NULL)); 115 off_t off = sarmag; 116 if (armap_name.empty()) 117 { 118 this->read_armap(sarmag + sizeof(Archive_header), armap_size); 119 off = sarmag + sizeof(Archive_header) + armap_size; 120 } 121 else if (!this->input_file_->options().whole_archive()) 122 gold_error(_("%s: no archive symbol table (run ranlib)"), 123 this->name().c_str()); 124 125 // See if there is an extended name table. We cache these views 126 // because it is likely that we will want to read the following 127 // header in the add_symbols routine. 128 if ((off & 1) != 0) 129 ++off; 130 std::string xname; 131 section_size_type extended_size = 132 convert_to_section_size_type(this->read_header(off, true, &xname, NULL)); 133 if (xname == "/") 134 { 135 const unsigned char* p = this->get_view(off + sizeof(Archive_header), 136 extended_size, false, true); 137 const char* px = reinterpret_cast<const char*>(p); 138 this->extended_names_.assign(px, extended_size); 139 } 140 bool preread_syms = (parameters->options().threads() 141 && parameters->options().preread_archive_symbols()); 142 #ifndef ENABLE_THREADS 143 preread_syms = false; 144 #else 145 if (parameters->options().has_plugins()) 146 preread_syms = false; 147 #endif 148 if (preread_syms) 149 this->read_all_symbols(); 150 } 151 152 // Unlock any nested archives. 153 154 void 155 Archive::unlock_nested_archives() 156 { 157 for (Nested_archive_table::iterator p = this->nested_archives_.begin(); 158 p != this->nested_archives_.end(); 159 ++p) 160 { 161 p->second->unlock(this->task_); 162 } 163 } 164 165 // Read the archive symbol map. 166 167 void 168 Archive::read_armap(off_t start, section_size_type size) 169 { 170 // To count the total number of archive members, we'll just count 171 // the number of times the file offset changes. Since most archives 172 // group the symbols in the armap by object, this ought to give us 173 // an accurate count. 174 off_t last_seen_offset = -1; 175 176 // Read in the entire armap. 177 const unsigned char* p = this->get_view(start, size, true, false); 178 179 // Numbers in the armap are always big-endian. 180 const elfcpp::Elf_Word* pword = reinterpret_cast<const elfcpp::Elf_Word*>(p); 181 unsigned int nsyms = elfcpp::Swap<32, true>::readval(pword); 182 ++pword; 183 184 // Note that the addition is in units of sizeof(elfcpp::Elf_Word). 185 const char* pnames = reinterpret_cast<const char*>(pword + nsyms); 186 section_size_type names_size = 187 reinterpret_cast<const char*>(p) + size - pnames; 188 this->armap_names_.assign(pnames, names_size); 189 190 this->armap_.resize(nsyms); 191 192 section_offset_type name_offset = 0; 193 for (unsigned int i = 0; i < nsyms; ++i) 194 { 195 this->armap_[i].name_offset = name_offset; 196 this->armap_[i].file_offset = elfcpp::Swap<32, true>::readval(pword); 197 name_offset += strlen(pnames + name_offset) + 1; 198 ++pword; 199 if (this->armap_[i].file_offset != last_seen_offset) 200 { 201 last_seen_offset = this->armap_[i].file_offset; 202 ++this->num_members_; 203 } 204 } 205 206 if (static_cast<section_size_type>(name_offset) > names_size) 207 gold_error(_("%s: bad archive symbol table names"), 208 this->name().c_str()); 209 210 // This array keeps track of which symbols are for archive elements 211 // which we have already included in the link. 212 this->armap_checked_.resize(nsyms); 213 } 214 215 // Read the header of an archive member at OFF. Fail if something 216 // goes wrong. Return the size of the member. Set *PNAME to the name 217 // of the member. 218 219 off_t 220 Archive::read_header(off_t off, bool cache, std::string* pname, 221 off_t* nested_off) 222 { 223 const unsigned char* p = this->get_view(off, sizeof(Archive_header), true, 224 cache); 225 const Archive_header* hdr = reinterpret_cast<const Archive_header*>(p); 226 return this->interpret_header(hdr, off, pname, nested_off); 227 } 228 229 // Interpret the header of HDR, the header of the archive member at 230 // file offset OFF. Fail if something goes wrong. Return the size of 231 // the member. Set *PNAME to the name of the member. 232 233 off_t 234 Archive::interpret_header(const Archive_header* hdr, off_t off, 235 std::string* pname, off_t* nested_off) const 236 { 237 if (memcmp(hdr->ar_fmag, arfmag, sizeof arfmag) != 0) 238 { 239 gold_error(_("%s: malformed archive header at %zu"), 240 this->name().c_str(), static_cast<size_t>(off)); 241 return this->input_file_->file().filesize() - off; 242 } 243 244 const int size_string_size = sizeof hdr->ar_size; 245 char size_string[size_string_size + 1]; 246 memcpy(size_string, hdr->ar_size, size_string_size); 247 char* ps = size_string + size_string_size; 248 while (ps[-1] == ' ') 249 --ps; 250 *ps = '\0'; 251 252 errno = 0; 253 char* end; 254 off_t member_size = strtol(size_string, &end, 10); 255 if (*end != '\0' 256 || member_size < 0 257 || (member_size == LONG_MAX && errno == ERANGE)) 258 { 259 gold_error(_("%s: malformed archive header size at %zu"), 260 this->name().c_str(), static_cast<size_t>(off)); 261 return this->input_file_->file().filesize() - off; 262 } 263 264 if (hdr->ar_name[0] != '/') 265 { 266 const char* name_end = strchr(hdr->ar_name, '/'); 267 if (name_end == NULL 268 || name_end - hdr->ar_name >= static_cast<int>(sizeof hdr->ar_name)) 269 { 270 gold_error(_("%s: malformed archive header name at %zu"), 271 this->name().c_str(), static_cast<size_t>(off)); 272 return this->input_file_->file().filesize() - off; 273 } 274 pname->assign(hdr->ar_name, name_end - hdr->ar_name); 275 if (nested_off != NULL) 276 *nested_off = 0; 277 } 278 else if (hdr->ar_name[1] == ' ') 279 { 280 // This is the symbol table. 281 if (!pname->empty()) 282 pname->clear(); 283 } 284 else if (hdr->ar_name[1] == '/') 285 { 286 // This is the extended name table. 287 pname->assign(1, '/'); 288 } 289 else 290 { 291 errno = 0; 292 long x = strtol(hdr->ar_name + 1, &end, 10); 293 long y = 0; 294 if (*end == ':') 295 y = strtol(end + 1, &end, 10); 296 if (*end != ' ' 297 || x < 0 298 || (x == LONG_MAX && errno == ERANGE) 299 || static_cast<size_t>(x) >= this->extended_names_.size()) 300 { 301 gold_error(_("%s: bad extended name index at %zu"), 302 this->name().c_str(), static_cast<size_t>(off)); 303 return this->input_file_->file().filesize() - off; 304 } 305 306 const char* name = this->extended_names_.data() + x; 307 const char* name_end = strchr(name, '\n'); 308 if (static_cast<size_t>(name_end - name) > this->extended_names_.size() 309 || name_end[-1] != '/') 310 { 311 gold_error(_("%s: bad extended name entry at header %zu"), 312 this->name().c_str(), static_cast<size_t>(off)); 313 return this->input_file_->file().filesize() - off; 314 } 315 pname->assign(name, name_end - 1 - name); 316 if (nested_off != NULL) 317 *nested_off = y; 318 } 319 320 return member_size; 321 } 322 323 // An archive member iterator. 324 325 class Archive::const_iterator 326 { 327 public: 328 // The header of an archive member. This is what this iterator 329 // points to. 330 struct Header 331 { 332 // The name of the member. 333 std::string name; 334 // The file offset of the member. 335 off_t off; 336 // The file offset of a nested archive member. 337 off_t nested_off; 338 // The size of the member. 339 off_t size; 340 }; 341 342 const_iterator(Archive* archive, off_t off) 343 : archive_(archive), off_(off) 344 { this->read_next_header(); } 345 346 const Header& 347 operator*() const 348 { return this->header_; } 349 350 const Header* 351 operator->() const 352 { return &this->header_; } 353 354 const_iterator& 355 operator++() 356 { 357 if (this->off_ == this->archive_->file().filesize()) 358 return *this; 359 this->off_ += sizeof(Archive_header); 360 if (!this->archive_->is_thin_archive()) 361 this->off_ += this->header_.size; 362 if ((this->off_ & 1) != 0) 363 ++this->off_; 364 this->read_next_header(); 365 return *this; 366 } 367 368 const_iterator 369 operator++(int) 370 { 371 const_iterator ret = *this; 372 ++*this; 373 return ret; 374 } 375 376 bool 377 operator==(const const_iterator p) const 378 { return this->off_ == p->off; } 379 380 bool 381 operator!=(const const_iterator p) const 382 { return this->off_ != p->off; } 383 384 private: 385 void 386 read_next_header(); 387 388 // The underlying archive. 389 Archive* archive_; 390 // The current offset in the file. 391 off_t off_; 392 // The current archive header. 393 Header header_; 394 }; 395 396 // Read the next archive header. 397 398 void 399 Archive::const_iterator::read_next_header() 400 { 401 off_t filesize = this->archive_->file().filesize(); 402 while (true) 403 { 404 if (filesize - this->off_ < static_cast<off_t>(sizeof(Archive_header))) 405 { 406 if (filesize != this->off_) 407 { 408 gold_error(_("%s: short archive header at %zu"), 409 this->archive_->filename().c_str(), 410 static_cast<size_t>(this->off_)); 411 this->off_ = filesize; 412 } 413 this->header_.off = filesize; 414 return; 415 } 416 417 unsigned char buf[sizeof(Archive_header)]; 418 this->archive_->file().read(this->off_, sizeof(Archive_header), buf); 419 420 const Archive_header* hdr = reinterpret_cast<const Archive_header*>(buf); 421 this->header_.size = 422 this->archive_->interpret_header(hdr, this->off_, &this->header_.name, 423 &this->header_.nested_off); 424 this->header_.off = this->off_; 425 426 // Skip special members. 427 if (!this->header_.name.empty() && this->header_.name != "/") 428 return; 429 430 this->off_ += sizeof(Archive_header) + this->header_.size; 431 if ((this->off_ & 1) != 0) 432 ++this->off_; 433 } 434 } 435 436 // Initial iterator. 437 438 Archive::const_iterator 439 Archive::begin() 440 { 441 return Archive::const_iterator(this, sarmag); 442 } 443 444 // Final iterator. 445 446 Archive::const_iterator 447 Archive::end() 448 { 449 return Archive::const_iterator(this, this->input_file_->file().filesize()); 450 } 451 452 // Get the file and offset for an archive member, which may be an 453 // external member of a thin archive. Set *INPUT_FILE to the 454 // file containing the actual member, *MEMOFF to the offset 455 // within that file (0 if not a nested archive), and *MEMBER_NAME 456 // to the name of the archive member. Return TRUE on success. 457 458 bool 459 Archive::get_file_and_offset(off_t off, Input_file** input_file, off_t* memoff, 460 off_t* memsize, std::string* member_name) 461 { 462 off_t nested_off; 463 464 *memsize = this->read_header(off, false, member_name, &nested_off); 465 466 *input_file = this->input_file_; 467 *memoff = off + static_cast<off_t>(sizeof(Archive_header)); 468 469 if (!this->is_thin_archive_) 470 return true; 471 472 // Adjust a relative pathname so that it is relative 473 // to the directory containing the archive. 474 if (!IS_ABSOLUTE_PATH(member_name->c_str())) 475 { 476 const char* arch_path = this->filename().c_str(); 477 const char* basename = lbasename(arch_path); 478 if (basename > arch_path) 479 member_name->replace(0, 0, 480 this->filename().substr(0, basename - arch_path)); 481 } 482 483 if (nested_off > 0) 484 { 485 // This is a member of a nested archive. Open the containing 486 // archive if we don't already have it open, then do a recursive 487 // call to include the member from that archive. 488 Archive* arch; 489 Nested_archive_table::const_iterator p = 490 this->nested_archives_.find(*member_name); 491 if (p != this->nested_archives_.end()) 492 arch = p->second; 493 else 494 { 495 Input_file_argument* input_file_arg = 496 new Input_file_argument(member_name->c_str(), 497 Input_file_argument::INPUT_FILE_TYPE_FILE, 498 "", false, parameters->options()); 499 *input_file = new Input_file(input_file_arg); 500 int dummy = 0; 501 if (!(*input_file)->open(*this->dirpath_, this->task_, &dummy)) 502 return false; 503 arch = new Archive(*member_name, *input_file, false, this->dirpath_, 504 this->task_); 505 arch->setup(); 506 std::pair<Nested_archive_table::iterator, bool> ins = 507 this->nested_archives_.insert(std::make_pair(*member_name, arch)); 508 gold_assert(ins.second); 509 } 510 return arch->get_file_and_offset(nested_off, input_file, memoff, 511 memsize, member_name); 512 } 513 514 // This is an external member of a thin archive. Open the 515 // file as a regular relocatable object file. 516 Input_file_argument* input_file_arg = 517 new Input_file_argument(member_name->c_str(), 518 Input_file_argument::INPUT_FILE_TYPE_FILE, 519 "", false, this->input_file_->options()); 520 *input_file = new Input_file(input_file_arg); 521 int dummy = 0; 522 if (!(*input_file)->open(*this->dirpath_, this->task_, &dummy)) 523 return false; 524 525 *memoff = 0; 526 *memsize = (*input_file)->file().filesize(); 527 return true; 528 } 529 530 // Return an ELF object for the member at offset OFF. If the ELF 531 // object has an unsupported target type, set *PUNCONFIGURED to true 532 // and return NULL. 533 534 Object* 535 Archive::get_elf_object_for_member(off_t off, bool* punconfigured) 536 { 537 *punconfigured = false; 538 539 Input_file* input_file; 540 off_t memoff; 541 off_t memsize; 542 std::string member_name; 543 if (!this->get_file_and_offset(off, &input_file, &memoff, &memsize, 544 &member_name)) 545 return NULL; 546 547 if (parameters->options().has_plugins()) 548 { 549 Object* obj = parameters->options().plugins()->claim_file(input_file, 550 memoff, 551 memsize); 552 if (obj != NULL) 553 { 554 // The input file was claimed by a plugin, and its symbols 555 // have been provided by the plugin. 556 return obj; 557 } 558 } 559 560 const unsigned char* ehdr; 561 int read_size; 562 if (!is_elf_object(input_file, memoff, &ehdr, &read_size)) 563 { 564 gold_error(_("%s: member at %zu is not an ELF object"), 565 this->name().c_str(), static_cast<size_t>(off)); 566 return NULL; 567 } 568 569 Object* obj = make_elf_object((std::string(this->input_file_->filename()) 570 + "(" + member_name + ")"), 571 input_file, memoff, ehdr, read_size, 572 punconfigured); 573 if (obj == NULL) 574 return NULL; 575 obj->set_no_export(this->no_export()); 576 return obj; 577 } 578 579 // Read the symbols from all the archive members in the link. 580 581 void 582 Archive::read_all_symbols() 583 { 584 for (Archive::const_iterator p = this->begin(); 585 p != this->end(); 586 ++p) 587 this->read_symbols(p->off); 588 } 589 590 // Read the symbols from an archive member in the link. OFF is the file 591 // offset of the member header. 592 593 void 594 Archive::read_symbols(off_t off) 595 { 596 bool dummy; 597 Object* obj = this->get_elf_object_for_member(off, &dummy); 598 599 if (obj == NULL) 600 return; 601 602 Read_symbols_data* sd = new Read_symbols_data; 603 obj->read_symbols(sd); 604 Archive_member member(obj, sd); 605 this->members_[off] = member; 606 } 607 608 Archive::Should_include 609 Archive::should_include_member(Symbol_table* symtab, Layout* layout, 610 const char* sym_name, Symbol** symp, 611 std::string* why, char** tmpbufp, 612 size_t* tmpbuflen) 613 { 614 // In an object file, and therefore in an archive map, an 615 // '@' in the name separates the symbol name from the 616 // version name. If there are two '@' characters, this is 617 // the default version. 618 char* tmpbuf = *tmpbufp; 619 const char* ver = strchr(sym_name, '@'); 620 bool def = false; 621 if (ver != NULL) 622 { 623 size_t symlen = ver - sym_name; 624 if (symlen + 1 > *tmpbuflen) 625 { 626 tmpbuf = static_cast<char*>(xrealloc(tmpbuf, symlen + 1)); 627 *tmpbufp = tmpbuf; 628 *tmpbuflen = symlen + 1; 629 } 630 memcpy(tmpbuf, sym_name, symlen); 631 tmpbuf[symlen] = '\0'; 632 sym_name = tmpbuf; 633 634 ++ver; 635 if (*ver == '@') 636 { 637 ++ver; 638 def = true; 639 } 640 } 641 642 Symbol* sym = symtab->lookup(sym_name, ver); 643 if (def 644 && ver != NULL 645 && (sym == NULL 646 || !sym->is_undefined() 647 || sym->binding() == elfcpp::STB_WEAK)) 648 sym = symtab->lookup(sym_name, NULL); 649 650 *symp = sym; 651 652 if (sym == NULL) 653 { 654 // Check whether the symbol was named in a -u option. 655 if (parameters->options().is_undefined(sym_name)) 656 { 657 *why = "-u "; 658 *why += sym_name; 659 } 660 else if (layout->script_options()->is_referenced(sym_name)) 661 { 662 size_t alc = 100 + strlen(sym_name); 663 char* buf = new char[alc]; 664 snprintf(buf, alc, _("script or expression reference to %s"), 665 sym_name); 666 *why = buf; 667 delete[] buf; 668 } 669 else 670 return Archive::SHOULD_INCLUDE_UNKNOWN; 671 } 672 else if (!sym->is_undefined()) 673 return Archive::SHOULD_INCLUDE_NO; 674 // PR 12001: Do not include an archive when the undefined 675 // symbol has actually been defined on the command line. 676 else if (layout->script_options()->is_pending_assignment(sym_name)) 677 return Archive::SHOULD_INCLUDE_NO; 678 else if (sym->binding() == elfcpp::STB_WEAK) 679 return Archive::SHOULD_INCLUDE_UNKNOWN; 680 681 return Archive::SHOULD_INCLUDE_YES; 682 } 683 684 // Select members from the archive and add them to the link. We walk 685 // through the elements in the archive map, and look each one up in 686 // the symbol table. If it exists as a strong undefined symbol, we 687 // pull in the corresponding element. We have to do this in a loop, 688 // since pulling in one element may create new undefined symbols which 689 // may be satisfied by other objects in the archive. Return true in 690 // the normal case, false if the first member we tried to add from 691 // this archive had an incompatible target. 692 693 bool 694 Archive::add_symbols(Symbol_table* symtab, Layout* layout, 695 Input_objects* input_objects, Mapfile* mapfile) 696 { 697 ++Archive::total_archives; 698 699 if (this->input_file_->options().whole_archive()) 700 return this->include_all_members(symtab, layout, input_objects, 701 mapfile); 702 703 Archive::total_members += this->num_members_; 704 705 input_objects->archive_start(this); 706 707 const size_t armap_size = this->armap_.size(); 708 709 // This is a quick optimization, since we usually see many symbols 710 // in a row with the same offset. last_seen_offset holds the last 711 // offset we saw that was present in the seen_offsets_ set. 712 off_t last_seen_offset = -1; 713 714 // Track which symbols in the symbol table we've already found to be 715 // defined. 716 717 char* tmpbuf = NULL; 718 size_t tmpbuflen = 0; 719 bool added_new_object; 720 do 721 { 722 added_new_object = false; 723 for (size_t i = 0; i < armap_size; ++i) 724 { 725 if (this->armap_checked_[i]) 726 continue; 727 if (this->armap_[i].file_offset == last_seen_offset) 728 { 729 this->armap_checked_[i] = true; 730 continue; 731 } 732 if (this->seen_offsets_.find(this->armap_[i].file_offset) 733 != this->seen_offsets_.end()) 734 { 735 this->armap_checked_[i] = true; 736 last_seen_offset = this->armap_[i].file_offset; 737 continue; 738 } 739 740 const char* sym_name = (this->armap_names_.data() 741 + this->armap_[i].name_offset); 742 743 Symbol* sym; 744 std::string why; 745 Archive::Should_include t = 746 Archive::should_include_member(symtab, layout, sym_name, &sym, 747 &why, &tmpbuf, &tmpbuflen); 748 749 if (t == Archive::SHOULD_INCLUDE_NO 750 || t == Archive::SHOULD_INCLUDE_YES) 751 this->armap_checked_[i] = true; 752 753 if (t != Archive::SHOULD_INCLUDE_YES) 754 continue; 755 756 // We want to include this object in the link. 757 last_seen_offset = this->armap_[i].file_offset; 758 this->seen_offsets_.insert(last_seen_offset); 759 760 if (!this->include_member(symtab, layout, input_objects, 761 last_seen_offset, mapfile, sym, 762 why.c_str())) 763 { 764 if (tmpbuf != NULL) 765 free(tmpbuf); 766 return false; 767 } 768 769 added_new_object = true; 770 } 771 } 772 while (added_new_object); 773 774 if (tmpbuf != NULL) 775 free(tmpbuf); 776 777 input_objects->archive_stop(this); 778 779 return true; 780 } 781 782 // Return whether the archive includes a member which defines the 783 // symbol SYM. 784 785 bool 786 Archive::defines_symbol(Symbol* sym) const 787 { 788 const char* symname = sym->name(); 789 size_t symname_len = strlen(symname); 790 size_t armap_size = this->armap_.size(); 791 for (size_t i = 0; i < armap_size; ++i) 792 { 793 if (this->armap_checked_[i]) 794 continue; 795 const char* archive_symname = (this->armap_names_.data() 796 + this->armap_[i].name_offset); 797 if (strncmp(archive_symname, symname, symname_len) != 0) 798 continue; 799 char c = archive_symname[symname_len]; 800 if (c == '\0' && sym->version() == NULL) 801 return true; 802 if (c == '@') 803 { 804 const char* ver = archive_symname + symname_len + 1; 805 if (*ver == '@') 806 { 807 if (sym->version() == NULL) 808 return true; 809 ++ver; 810 } 811 if (sym->version() != NULL && strcmp(sym->version(), ver) == 0) 812 return true; 813 } 814 } 815 return false; 816 } 817 818 // Include all the archive members in the link. This is for --whole-archive. 819 820 bool 821 Archive::include_all_members(Symbol_table* symtab, Layout* layout, 822 Input_objects* input_objects, Mapfile* mapfile) 823 { 824 input_objects->archive_start(this); 825 826 if (this->members_.size() > 0) 827 { 828 std::map<off_t, Archive_member>::const_iterator p; 829 for (p = this->members_.begin(); 830 p != this->members_.end(); 831 ++p) 832 { 833 if (!this->include_member(symtab, layout, input_objects, p->first, 834 mapfile, NULL, "--whole-archive")) 835 return false; 836 ++Archive::total_members; 837 } 838 } 839 else 840 { 841 for (Archive::const_iterator p = this->begin(); 842 p != this->end(); 843 ++p) 844 { 845 if (!this->include_member(symtab, layout, input_objects, p->off, 846 mapfile, NULL, "--whole-archive")) 847 return false; 848 ++Archive::total_members; 849 } 850 } 851 852 input_objects->archive_stop(this); 853 854 return true; 855 } 856 857 // Return the number of members in the archive. This is only used for 858 // reports. 859 860 size_t 861 Archive::count_members() 862 { 863 size_t ret = 0; 864 for (Archive::const_iterator p = this->begin(); 865 p != this->end(); 866 ++p) 867 ++ret; 868 return ret; 869 } 870 871 // Include an archive member in the link. OFF is the file offset of 872 // the member header. WHY is the reason we are including this member. 873 // Return true if we added the member or if we had an error, return 874 // false if this was the first member we tried to add from this 875 // archive and it had an incompatible format. 876 877 bool 878 Archive::include_member(Symbol_table* symtab, Layout* layout, 879 Input_objects* input_objects, off_t off, 880 Mapfile* mapfile, Symbol* sym, const char* why) 881 { 882 ++Archive::total_members_loaded; 883 884 std::map<off_t, Archive_member>::const_iterator p = this->members_.find(off); 885 if (p != this->members_.end()) 886 { 887 Object* obj = p->second.obj_; 888 889 Read_symbols_data* sd = p->second.sd_; 890 if (mapfile != NULL) 891 mapfile->report_include_archive_member(obj->name(), sym, why); 892 if (input_objects->add_object(obj)) 893 { 894 obj->layout(symtab, layout, sd); 895 obj->add_symbols(symtab, sd, layout); 896 this->included_member_ = true; 897 } 898 delete sd; 899 return true; 900 } 901 902 bool unconfigured; 903 Object* obj = this->get_elf_object_for_member(off, &unconfigured); 904 905 if (!this->included_member_ 906 && this->searched_for() 907 && obj == NULL 908 && unconfigured) 909 return false; 910 911 if (obj == NULL) 912 return true; 913 914 if (mapfile != NULL) 915 mapfile->report_include_archive_member(obj->name(), sym, why); 916 917 Pluginobj* pluginobj = obj->pluginobj(); 918 if (pluginobj != NULL) 919 { 920 pluginobj->add_symbols(symtab, NULL, layout); 921 this->included_member_ = true; 922 return true; 923 } 924 925 if (!input_objects->add_object(obj)) 926 { 927 // If this is an external member of a thin archive, unlock the 928 // file. 929 if (obj->offset() == 0) 930 obj->unlock(this->task_); 931 delete obj; 932 } 933 else 934 { 935 { 936 if (layout->incremental_inputs() != NULL) 937 layout->incremental_inputs()->report_object(obj, this); 938 Read_symbols_data sd; 939 obj->read_symbols(&sd); 940 obj->layout(symtab, layout, &sd); 941 obj->add_symbols(symtab, &sd, layout); 942 } 943 944 // If this is an external member of a thin archive, unlock the file 945 // for the next task. 946 if (obj->offset() == 0) 947 obj->unlock(this->task_); 948 949 this->included_member_ = true; 950 } 951 952 return true; 953 } 954 955 // Print statistical information to stderr. This is used for --stats. 956 957 void 958 Archive::print_stats() 959 { 960 fprintf(stderr, _("%s: archive libraries: %u\n"), 961 program_name, Archive::total_archives); 962 fprintf(stderr, _("%s: total archive members: %u\n"), 963 program_name, Archive::total_members); 964 fprintf(stderr, _("%s: loaded archive members: %u\n"), 965 program_name, Archive::total_members_loaded); 966 } 967 968 // Add_archive_symbols methods. 969 970 Add_archive_symbols::~Add_archive_symbols() 971 { 972 if (this->this_blocker_ != NULL) 973 delete this->this_blocker_; 974 // next_blocker_ is deleted by the task associated with the next 975 // input file. 976 } 977 978 // Return whether we can add the archive symbols. We are blocked by 979 // this_blocker_. We block next_blocker_. We also lock the file. 980 981 Task_token* 982 Add_archive_symbols::is_runnable() 983 { 984 if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked()) 985 return this->this_blocker_; 986 return NULL; 987 } 988 989 void 990 Add_archive_symbols::locks(Task_locker* tl) 991 { 992 tl->add(this, this->next_blocker_); 993 tl->add(this, this->archive_->token()); 994 } 995 996 void 997 Add_archive_symbols::run(Workqueue* workqueue) 998 { 999 // For an incremental link, begin recording layout information. 1000 Incremental_inputs* incremental_inputs = this->layout_->incremental_inputs(); 1001 if (incremental_inputs != NULL) 1002 incremental_inputs->report_archive_begin(this->archive_); 1003 1004 bool added = this->archive_->add_symbols(this->symtab_, this->layout_, 1005 this->input_objects_, 1006 this->mapfile_); 1007 this->archive_->unlock_nested_archives(); 1008 1009 this->archive_->release(); 1010 this->archive_->clear_uncached_views(); 1011 1012 if (!added) 1013 { 1014 // This archive holds object files which are incompatible with 1015 // our output file. 1016 Read_symbols::incompatible_warning(this->input_argument_, 1017 this->archive_->input_file()); 1018 Read_symbols::requeue(workqueue, this->input_objects_, this->symtab_, 1019 this->layout_, this->dirpath_, this->dirindex_, 1020 this->mapfile_, this->input_argument_, 1021 this->input_group_, this->next_blocker_); 1022 delete this->archive_; 1023 return; 1024 } 1025 1026 if (this->input_group_ != NULL) 1027 this->input_group_->add_archive(this->archive_); 1028 else 1029 { 1030 // For an incremental link, finish recording the layout information. 1031 Incremental_inputs* incremental_inputs = this->layout_->incremental_inputs(); 1032 if (incremental_inputs != NULL) 1033 incremental_inputs->report_archive_end(this->archive_); 1034 1035 if (!parameters->options().has_plugins() 1036 || this->archive_->input_file()->options().whole_archive()) 1037 { 1038 // We no longer need to know about this archive. 1039 delete this->archive_; 1040 } 1041 else 1042 { 1043 // The plugin interface may want to rescan this archive. 1044 parameters->options().plugins()->save_archive(this->archive_); 1045 } 1046 1047 this->archive_ = NULL; 1048 } 1049 } 1050 1051 // Class Lib_group static variables. 1052 unsigned int Lib_group::total_lib_groups; 1053 unsigned int Lib_group::total_members; 1054 unsigned int Lib_group::total_members_loaded; 1055 1056 Lib_group::Lib_group(const Input_file_lib* lib, Task* task) 1057 : lib_(lib), task_(task), members_() 1058 { 1059 this->members_.resize(lib->size()); 1060 } 1061 1062 // Select members from the lib group and add them to the link. We walk 1063 // through the the members, and check if each one up should be included. 1064 // If the object says it should be included, we do so. We have to do 1065 // this in a loop, since including one member may create new undefined 1066 // symbols which may be satisfied by other members. 1067 1068 void 1069 Lib_group::add_symbols(Symbol_table* symtab, Layout* layout, 1070 Input_objects* input_objects) 1071 { 1072 ++Lib_group::total_lib_groups; 1073 1074 Lib_group::total_members += this->members_.size(); 1075 1076 bool added_new_object; 1077 do 1078 { 1079 added_new_object = false; 1080 unsigned int i = 0; 1081 while (i < this->members_.size()) 1082 { 1083 const Archive_member& member = this->members_[i]; 1084 Object* obj = member.obj_; 1085 std::string why; 1086 1087 // Skip files with no symbols. Plugin objects have 1088 // member.sd_ == NULL. 1089 if (obj != NULL 1090 && (member.sd_ == NULL || member.sd_->symbol_names != NULL)) 1091 { 1092 Archive::Should_include t = obj->should_include_member(symtab, 1093 layout, 1094 member.sd_, 1095 &why); 1096 1097 if (t != Archive::SHOULD_INCLUDE_YES) 1098 { 1099 ++i; 1100 continue; 1101 } 1102 1103 this->include_member(symtab, layout, input_objects, member); 1104 1105 added_new_object = true; 1106 } 1107 else 1108 { 1109 if (member.sd_ != NULL) 1110 { 1111 // The file must be locked in order to destroy the views 1112 // associated with it. 1113 gold_assert(obj != NULL); 1114 obj->lock(this->task_); 1115 delete member.sd_; 1116 obj->unlock(this->task_); 1117 } 1118 } 1119 1120 this->members_[i] = this->members_.back(); 1121 this->members_.pop_back(); 1122 } 1123 } 1124 while (added_new_object); 1125 } 1126 1127 // Include a lib group member in the link. 1128 1129 void 1130 Lib_group::include_member(Symbol_table* symtab, Layout* layout, 1131 Input_objects* input_objects, 1132 const Archive_member& member) 1133 { 1134 ++Lib_group::total_members_loaded; 1135 1136 Object* obj = member.obj_; 1137 gold_assert(obj != NULL); 1138 1139 Pluginobj* pluginobj = obj->pluginobj(); 1140 if (pluginobj != NULL) 1141 { 1142 pluginobj->add_symbols(symtab, NULL, layout); 1143 return; 1144 } 1145 1146 Read_symbols_data* sd = member.sd_; 1147 gold_assert(sd != NULL); 1148 obj->lock(this->task_); 1149 if (input_objects->add_object(obj)) 1150 { 1151 // FIXME: Record incremental link info for --start-lib/--end-lib. 1152 if (layout->incremental_inputs() != NULL) 1153 layout->incremental_inputs()->report_object(obj, NULL); 1154 obj->layout(symtab, layout, sd); 1155 obj->add_symbols(symtab, sd, layout); 1156 } 1157 delete sd; 1158 // Unlock the file for the next task. 1159 obj->unlock(this->task_); 1160 } 1161 1162 // Print statistical information to stderr. This is used for --stats. 1163 1164 void 1165 Lib_group::print_stats() 1166 { 1167 fprintf(stderr, _("%s: lib groups: %u\n"), 1168 program_name, Lib_group::total_lib_groups); 1169 fprintf(stderr, _("%s: total lib groups members: %u\n"), 1170 program_name, Lib_group::total_members); 1171 fprintf(stderr, _("%s: loaded lib groups members: %u\n"), 1172 program_name, Lib_group::total_members_loaded); 1173 } 1174 1175 Task_token* 1176 Add_lib_group_symbols::is_runnable() 1177 { 1178 if (this->readsyms_blocker_ != NULL && this->readsyms_blocker_->is_blocked()) 1179 return this->readsyms_blocker_; 1180 if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked()) 1181 return this->this_blocker_; 1182 return NULL; 1183 } 1184 1185 void 1186 Add_lib_group_symbols::locks(Task_locker* tl) 1187 { 1188 tl->add(this, this->next_blocker_); 1189 } 1190 1191 void 1192 Add_lib_group_symbols::run(Workqueue*) 1193 { 1194 this->lib_->add_symbols(this->symtab_, this->layout_, this->input_objects_); 1195 1196 // FIXME: Record incremental link info for --start_lib/--end_lib. 1197 } 1198 1199 Add_lib_group_symbols::~Add_lib_group_symbols() 1200 { 1201 if (this->this_blocker_ != NULL) 1202 delete this->this_blocker_; 1203 // next_blocker_ is deleted by the task associated with the next 1204 // input file. 1205 } 1206 1207 } // End namespace gold. 1208