1// readsyms.cc -- read input file symbols 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 <cstring> 26 27#include "elfcpp.h" 28#include "options.h" 29#include "dirsearch.h" 30#include "symtab.h" 31#include "object.h" 32#include "archive.h" 33#include "script.h" 34#include "readsyms.h" 35#include "plugin.h" 36#include "layout.h" 37#include "incremental.h" 38 39namespace gold 40{ 41 42// If we fail to open the object, then we won't create an Add_symbols 43// task. However, we still need to unblock the token, or else the 44// link won't proceed to generate more error messages. We can only 45// unblock tokens when the workqueue lock is held, so we need a dummy 46// task to do that. The dummy task has to maintain the right sequence 47// of blocks, so we need both this_blocker and next_blocker. 48 49class Unblock_token : public Task 50{ 51 public: 52 Unblock_token(Task_token* this_blocker, Task_token* next_blocker) 53 : this_blocker_(this_blocker), next_blocker_(next_blocker) 54 { } 55 56 ~Unblock_token() 57 { 58 if (this->this_blocker_ != NULL) 59 delete this->this_blocker_; 60 } 61 62 Task_token* 63 is_runnable() 64 { 65 if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked()) 66 return this->this_blocker_; 67 return NULL; 68 } 69 70 void 71 locks(Task_locker* tl) 72 { tl->add(this, this->next_blocker_); } 73 74 void 75 run(Workqueue*) 76 { } 77 78 std::string 79 get_name() const 80 { return "Unblock_token"; } 81 82 private: 83 Task_token* this_blocker_; 84 Task_token* next_blocker_; 85}; 86 87// Class read_symbols. 88 89Read_symbols::~Read_symbols() 90{ 91 // The this_blocker_ and next_blocker_ pointers are passed on to the 92 // Add_symbols task. 93} 94 95// If appropriate, issue a warning about skipping an incompatible 96// file. 97 98void 99Read_symbols::incompatible_warning(const Input_argument* input_argument, 100 const Input_file* input_file) 101{ 102 if (parameters->options().warn_search_mismatch()) 103 gold_warning("skipping incompatible %s while searching for %s", 104 input_file->filename().c_str(), 105 input_argument->file().name()); 106} 107 108// Requeue a Read_symbols task to search for the next object with the 109// same name. 110 111void 112Read_symbols::requeue(Workqueue* workqueue, Input_objects* input_objects, 113 Symbol_table* symtab, Layout* layout, Dirsearch* dirpath, 114 int dirindex, Mapfile* mapfile, 115 const Input_argument* input_argument, 116 Input_group* input_group, Task_token* next_blocker) 117{ 118 // Bump the directory search index. 119 ++dirindex; 120 121 // We don't need to worry about this_blocker, since we already 122 // reached it. However, we are removing the blocker on next_blocker 123 // because the calling task is completing. So we need to add a new 124 // blocker. Since next_blocker may be shared by several tasks, we 125 // need to increment the count with the workqueue lock held. 126 workqueue->add_blocker(next_blocker); 127 128 workqueue->queue(new Read_symbols(input_objects, symtab, layout, dirpath, 129 dirindex, mapfile, input_argument, 130 input_group, NULL, NULL, next_blocker)); 131} 132 133// Return whether a Read_symbols task is runnable. We can read an 134// ordinary input file immediately. For an archive specified using 135// -l, we have to wait until the search path is complete. 136 137Task_token* 138Read_symbols::is_runnable() 139{ 140 if (this->input_argument_->is_file() 141 && this->input_argument_->file().may_need_search() 142 && this->dirpath_->token()->is_blocked()) 143 return this->dirpath_->token(); 144 145 return NULL; 146} 147 148// Return a Task_locker for a Read_symbols task. We don't need any 149// locks here. 150 151void 152Read_symbols::locks(Task_locker* tl) 153{ 154 if (this->member_ != NULL) 155 tl->add(this, this->next_blocker_); 156} 157 158// Run a Read_symbols task. 159 160void 161Read_symbols::run(Workqueue* workqueue) 162{ 163 // If we didn't queue a new task, then we need to explicitly unblock 164 // the token. 165 if (!this->do_read_symbols(workqueue)) 166 workqueue->queue_soon(new Unblock_token(this->this_blocker_, 167 this->next_blocker_)); 168} 169 170// Handle a whole lib group. Other then collecting statisticts, this just 171// mimics what we do for regular object files in the command line. 172 173bool 174Read_symbols::do_whole_lib_group(Workqueue* workqueue) 175{ 176 const Input_file_lib* lib_group = this->input_argument_->lib(); 177 178 ++Lib_group::total_lib_groups; 179 180 Task_token* this_blocker = this->this_blocker_; 181 for (Input_file_lib::const_iterator i = lib_group->begin(); 182 i != lib_group->end(); 183 ++i) 184 { 185 ++Lib_group::total_members; 186 ++Lib_group::total_members_loaded; 187 188 const Input_argument* arg = &*i; 189 190 Task_token* next_blocker; 191 if (i != lib_group->end() - 1) 192 { 193 next_blocker = new Task_token(true); 194 next_blocker->add_blocker(); 195 } 196 else 197 next_blocker = this->next_blocker_; 198 199 workqueue->queue_soon(new Read_symbols(this->input_objects_, 200 this->symtab_, this->layout_, 201 this->dirpath_, this->dirindex_, 202 this->mapfile_, arg, NULL, 203 NULL, this_blocker, next_blocker)); 204 this_blocker = next_blocker; 205 } 206 207 return true; 208} 209 210// Handle a lib group. We set Read_symbols Tasks as usual, but have them 211// just record the symbol data instead of adding the objects. We also start 212// a Add_lib_group_symbols Task which runs after we've read all the symbols. 213// In that task we process the members in a loop until we are done. 214 215bool 216Read_symbols::do_lib_group(Workqueue* workqueue) 217{ 218 const Input_file_lib* lib_group = this->input_argument_->lib(); 219 220 if (lib_group->options().whole_archive()) 221 return this->do_whole_lib_group(workqueue); 222 223 Lib_group* lib = new Lib_group(lib_group, this); 224 225 Add_lib_group_symbols* add_lib_group_symbols = 226 new Add_lib_group_symbols(this->symtab_, this->layout_, 227 this->input_objects_, 228 lib, this->next_blocker_); 229 230 231 Task_token* next_blocker = new Task_token(true); 232 int j = 0; 233 for (Input_file_lib::const_iterator i = lib_group->begin(); 234 i != lib_group->end(); 235 ++i, ++j) 236 { 237 const Input_argument* arg = &*i; 238 Archive_member* m = lib->get_member(j); 239 240 next_blocker->add_blocker(); 241 242 // Since this Read_symbols will not create an Add_symbols, 243 // just pass NULL as this_blocker. 244 workqueue->queue_soon(new Read_symbols(this->input_objects_, 245 this->symtab_, this->layout_, 246 this->dirpath_, this->dirindex_, 247 this->mapfile_, arg, NULL, 248 m, NULL, next_blocker)); 249 } 250 251 add_lib_group_symbols->set_blocker(next_blocker, this->this_blocker_); 252 workqueue->queue_soon(add_lib_group_symbols); 253 254 return true; 255} 256 257// Open the file and read the symbols. Return true if a new task was 258// queued, false if that could not happen due to some error. 259 260bool 261Read_symbols::do_read_symbols(Workqueue* workqueue) 262{ 263 if (this->input_argument_->is_group()) 264 { 265 gold_assert(this->input_group_ == NULL); 266 this->do_group(workqueue); 267 return true; 268 } 269 270 if (this->input_argument_->is_lib()) 271 return this->do_lib_group(workqueue); 272 273 Input_file* input_file = new Input_file(&this->input_argument_->file()); 274 if (!input_file->open(*this->dirpath_, this, &this->dirindex_)) 275 return false; 276 277 // Read enough of the file to pick up the entire ELF header. 278 279 off_t filesize = input_file->file().filesize(); 280 281 if (filesize == 0) 282 { 283 gold_error(_("%s: file is empty"), 284 input_file->file().filename().c_str()); 285 return false; 286 } 287 288 const unsigned char* ehdr; 289 int read_size; 290 bool is_elf = is_elf_object(input_file, 0, &ehdr, &read_size); 291 292 if (read_size >= Archive::sarmag) 293 { 294 bool is_thin_archive 295 = memcmp(ehdr, Archive::armagt, Archive::sarmag) == 0; 296 if (is_thin_archive 297 || memcmp(ehdr, Archive::armag, Archive::sarmag) == 0) 298 { 299 // This is an archive. 300 Archive* arch = new Archive(this->input_argument_->file().name(), 301 input_file, is_thin_archive, 302 this->dirpath_, this); 303 arch->setup(); 304 305 // Unlock the archive so it can be used in the next task. 306 arch->unlock(this); 307 308 workqueue->queue_next(new Add_archive_symbols(this->symtab_, 309 this->layout_, 310 this->input_objects_, 311 this->dirpath_, 312 this->dirindex_, 313 this->mapfile_, 314 this->input_argument_, 315 arch, 316 this->input_group_, 317 this->this_blocker_, 318 this->next_blocker_)); 319 return true; 320 } 321 } 322 323 if (parameters->options().has_plugins()) 324 { 325 Pluginobj* obj = parameters->options().plugins()->claim_file(input_file, 326 0, filesize); 327 if (obj != NULL) 328 { 329 // The input file was claimed by a plugin, and its symbols 330 // have been provided by the plugin. 331 332 // We are done with the file at this point, so unlock it. 333 obj->unlock(this); 334 335 if (this->member_ != NULL) 336 { 337 this->member_->sd_ = NULL; 338 this->member_->obj_ = obj; 339 return true; 340 } 341 342 workqueue->queue_next(new Add_symbols(this->input_objects_, 343 this->symtab_, 344 this->layout_, 345 this->dirpath_, 346 this->dirindex_, 347 this->mapfile_, 348 this->input_argument_, 349 obj, 350 NULL, 351 this->this_blocker_, 352 this->next_blocker_)); 353 return true; 354 } 355 } 356 357 if (is_elf) 358 { 359 // This is an ELF object. 360 361 bool unconfigured = false; 362 bool* punconfigured = (input_file->will_search_for() 363 ? &unconfigured 364 : NULL); 365 Object* obj = make_elf_object(input_file->filename(), 366 input_file, 0, ehdr, read_size, 367 punconfigured); 368 if (obj == NULL) 369 { 370 if (unconfigured) 371 { 372 Read_symbols::incompatible_warning(this->input_argument_, 373 input_file); 374 input_file->file().release(); 375 input_file->file().unlock(this); 376 delete input_file; 377 ++this->dirindex_; 378 return this->do_read_symbols(workqueue); 379 } 380 return false; 381 } 382 383 Read_symbols_data* sd = new Read_symbols_data; 384 obj->read_symbols(sd); 385 386 // Opening the file locked it, so now we need to unlock it. We 387 // need to unlock it before queuing the Add_symbols task, 388 // because the workqueue doesn't know about our lock on the 389 // file. If we queue the Add_symbols task first, it will be 390 // stuck on the end of the file lock, but since the workqueue 391 // doesn't know about that lock, it will never release the 392 // Add_symbols task. 393 394 input_file->file().unlock(this); 395 396 if (this->member_ != NULL) 397 { 398 this->member_->sd_ = sd; 399 this->member_->obj_ = obj; 400 return true; 401 } 402 403 // We use queue_next because everything is cached for this 404 // task to run right away if possible. 405 406 workqueue->queue_next(new Add_symbols(this->input_objects_, 407 this->symtab_, this->layout_, 408 this->dirpath_, 409 this->dirindex_, 410 this->mapfile_, 411 this->input_argument_, 412 obj, 413 sd, 414 this->this_blocker_, 415 this->next_blocker_)); 416 417 return true; 418 } 419 420 // Queue up a task to try to parse this file as a script. We use a 421 // separate task so that the script will be read in order with other 422 // objects named on the command line. Also so that we don't try to 423 // read multiple scripts simultaneously, which could lead to 424 // unpredictable changes to the General_options structure. 425 426 workqueue->queue_soon(new Read_script(this->symtab_, 427 this->layout_, 428 this->dirpath_, 429 this->dirindex_, 430 this->input_objects_, 431 this->mapfile_, 432 this->input_group_, 433 this->input_argument_, 434 input_file, 435 this->this_blocker_, 436 this->next_blocker_)); 437 return true; 438} 439 440// Handle a group. We need to walk through the arguments over and 441// over until we don't see any new undefined symbols. We do this by 442// setting off Read_symbols Tasks as usual, but recording the archive 443// entries instead of deleting them. We also start a Finish_group 444// Task which runs after we've read all the symbols. In that task we 445// process the archives in a loop until we are done. 446 447void 448Read_symbols::do_group(Workqueue* workqueue) 449{ 450 Input_group* input_group = new Input_group(); 451 452 const Input_file_group* group = this->input_argument_->group(); 453 Task_token* this_blocker = this->this_blocker_; 454 455 Finish_group* finish_group = new Finish_group(this->input_objects_, 456 this->symtab_, 457 this->layout_, 458 this->mapfile_, 459 input_group, 460 this->next_blocker_); 461 462 Task_token* next_blocker = new Task_token(true); 463 next_blocker->add_blocker(); 464 workqueue->queue_soon(new Start_group(this->symtab_, finish_group, 465 this_blocker, next_blocker)); 466 this_blocker = next_blocker; 467 468 for (Input_file_group::const_iterator p = group->begin(); 469 p != group->end(); 470 ++p) 471 { 472 const Input_argument* arg = &*p; 473 gold_assert(arg->is_file()); 474 475 next_blocker = new Task_token(true); 476 next_blocker->add_blocker(); 477 workqueue->queue_soon(new Read_symbols(this->input_objects_, 478 this->symtab_, this->layout_, 479 this->dirpath_, this->dirindex_, 480 this->mapfile_, arg, input_group, 481 NULL, this_blocker, next_blocker)); 482 this_blocker = next_blocker; 483 } 484 485 finish_group->set_blocker(this_blocker); 486 487 workqueue->queue_soon(finish_group); 488} 489 490// Return a debugging name for a Read_symbols task. 491 492std::string 493Read_symbols::get_name() const 494{ 495 if (this->input_argument_->is_group()) 496 { 497 std::string ret("Read_symbols group ("); 498 bool add_space = false; 499 const Input_file_group* group = this->input_argument_->group(); 500 for (Input_file_group::const_iterator p = group->begin(); 501 p != group->end(); 502 ++p) 503 { 504 if (add_space) 505 ret += ' '; 506 ret += p->file().name(); 507 add_space = true; 508 } 509 return ret + ')'; 510 } 511 else if (this->input_argument_->is_lib()) 512 { 513 std::string ret("Read_symbols lib ("); 514 bool add_space = false; 515 const Input_file_lib* lib = this->input_argument_->lib(); 516 for (Input_file_lib::const_iterator p = lib->begin(); 517 p != lib->end(); 518 ++p) 519 { 520 if (add_space) 521 ret += ' '; 522 ret += p->file().name(); 523 add_space = true; 524 } 525 return ret + ')'; 526 } 527 else 528 { 529 std::string ret("Read_symbols "); 530 if (this->input_argument_->file().is_lib()) 531 ret += "-l"; 532 else if (this->input_argument_->file().is_searched_file()) 533 ret += "-l:"; 534 ret += this->input_argument_->file().name(); 535 return ret; 536 } 537} 538 539// Class Add_symbols. 540 541Add_symbols::~Add_symbols() 542{ 543 if (this->this_blocker_ != NULL) 544 delete this->this_blocker_; 545 // next_blocker_ is deleted by the task associated with the next 546 // input file. 547} 548 549// We are blocked by this_blocker_. We block next_blocker_. We also 550// lock the file. 551 552Task_token* 553Add_symbols::is_runnable() 554{ 555 if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked()) 556 return this->this_blocker_; 557 if (this->object_->is_locked()) 558 return this->object_->token(); 559 return NULL; 560} 561 562void 563Add_symbols::locks(Task_locker* tl) 564{ 565 tl->add(this, this->next_blocker_); 566 tl->add(this, this->object_->token()); 567} 568 569// Add the symbols in the object to the symbol table. 570 571void 572Add_symbols::run(Workqueue*) 573{ 574 Pluginobj* pluginobj = this->object_->pluginobj(); 575 if (pluginobj != NULL) 576 { 577 this->object_->add_symbols(this->symtab_, this->sd_, this->layout_); 578 return; 579 } 580 581 if (!this->input_objects_->add_object(this->object_)) 582 { 583 delete this->sd_; 584 this->sd_ = NULL; 585 this->object_->release(); 586 delete this->object_; 587 } 588 else 589 { 590 Incremental_inputs* incremental_inputs = 591 this->layout_->incremental_inputs(); 592 if (incremental_inputs != NULL) 593 incremental_inputs->report_object(this->object_, NULL); 594 this->object_->layout(this->symtab_, this->layout_, this->sd_); 595 this->object_->add_symbols(this->symtab_, this->sd_, this->layout_); 596 delete this->sd_; 597 this->sd_ = NULL; 598 this->object_->release(); 599 } 600} 601 602// Class Input_group. 603 604// When we delete an Input_group we can delete the archive 605// information. 606 607Input_group::~Input_group() 608{ 609 for (Input_group::const_iterator p = this->begin(); 610 p != this->end(); 611 ++p) 612 delete *p; 613} 614 615// Class Start_group. 616 617Start_group::~Start_group() 618{ 619 if (this->this_blocker_ != NULL) 620 delete this->this_blocker_; 621 // next_blocker_ is deleted by the task associated with the first 622 // file in the group. 623} 624 625// We need to wait for THIS_BLOCKER_ and unblock NEXT_BLOCKER_. 626 627Task_token* 628Start_group::is_runnable() 629{ 630 if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked()) 631 return this->this_blocker_; 632 return NULL; 633} 634 635void 636Start_group::locks(Task_locker* tl) 637{ 638 tl->add(this, this->next_blocker_); 639} 640 641// Store the number of undefined symbols we see now. 642 643void 644Start_group::run(Workqueue*) 645{ 646 this->finish_group_->set_saw_undefined(this->symtab_->saw_undefined()); 647} 648 649// Class Finish_group. 650 651Finish_group::~Finish_group() 652{ 653 if (this->this_blocker_ != NULL) 654 delete this->this_blocker_; 655 // next_blocker_ is deleted by the task associated with the next 656 // input file following the group. 657} 658 659// We need to wait for THIS_BLOCKER_ and unblock NEXT_BLOCKER_. 660 661Task_token* 662Finish_group::is_runnable() 663{ 664 if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked()) 665 return this->this_blocker_; 666 return NULL; 667} 668 669void 670Finish_group::locks(Task_locker* tl) 671{ 672 tl->add(this, this->next_blocker_); 673} 674 675// Loop over the archives until there are no new undefined symbols. 676 677void 678Finish_group::run(Workqueue*) 679{ 680 size_t saw_undefined = this->saw_undefined_; 681 while (saw_undefined != this->symtab_->saw_undefined()) 682 { 683 saw_undefined = this->symtab_->saw_undefined(); 684 685 for (Input_group::const_iterator p = this->input_group_->begin(); 686 p != this->input_group_->end(); 687 ++p) 688 { 689 Task_lock_obj<Archive> tl(this, *p); 690 691 (*p)->add_symbols(this->symtab_, this->layout_, 692 this->input_objects_, this->mapfile_); 693 } 694 } 695 696 // Now that we're done with the archives, record the incremental 697 // layout information. 698 for (Input_group::const_iterator p = this->input_group_->begin(); 699 p != this->input_group_->end(); 700 ++p) 701 { 702 // For an incremental link, finish recording the layout information. 703 Incremental_inputs* incremental_inputs = 704 this->layout_->incremental_inputs(); 705 if (incremental_inputs != NULL) 706 incremental_inputs->report_archive_end(*p); 707 } 708 709 if (parameters->options().has_plugins()) 710 parameters->options().plugins()->save_input_group(this->input_group_); 711 else 712 delete this->input_group_; 713} 714 715// Class Read_script 716 717Read_script::~Read_script() 718{ 719 if (this->this_blocker_ != NULL) 720 delete this->this_blocker_; 721 // next_blocker_ is deleted by the task associated with the next 722 // input file. 723} 724 725// We are blocked by this_blocker_. 726 727Task_token* 728Read_script::is_runnable() 729{ 730 if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked()) 731 return this->this_blocker_; 732 return NULL; 733} 734 735// We don't unlock next_blocker_ here. If the script names any input 736// files, then the last file will be responsible for unlocking it. 737 738void 739Read_script::locks(Task_locker*) 740{ 741} 742 743// Read the script, if it is a script. 744 745void 746Read_script::run(Workqueue* workqueue) 747{ 748 bool used_next_blocker; 749 if (!read_input_script(workqueue, this->symtab_, this->layout_, 750 this->dirpath_, this->dirindex_, this->input_objects_, 751 this->mapfile_, this->input_group_, 752 this->input_argument_, this->input_file_, 753 this->next_blocker_, &used_next_blocker)) 754 { 755 // Here we have to handle any other input file types we need. 756 gold_error(_("%s: not an object or archive"), 757 this->input_file_->file().filename().c_str()); 758 } 759 760 if (!used_next_blocker) 761 { 762 // Queue up a task to unlock next_blocker. We can't just unlock 763 // it here, as we don't hold the workqueue lock. 764 workqueue->queue_soon(new Unblock_token(NULL, this->next_blocker_)); 765 } 766} 767 768// Return a debugging name for a Read_script task. 769 770std::string 771Read_script::get_name() const 772{ 773 std::string ret("Read_script "); 774 if (this->input_argument_->file().is_lib()) 775 ret += "-l"; 776 else if (this->input_argument_->file().is_searched_file()) 777 ret += "-l:"; 778 ret += this->input_argument_->file().name(); 779 return ret; 780} 781 782} // End namespace gold. 783