1277218Sjfv// archive.h -- archive support for gold -*- C++ -*- 2277218Sjfv 3277218Sjfv// Copyright (C) 2006-2017 Free Software Foundation, Inc. 4277218Sjfv// Written by Ian Lance Taylor <iant@google.com>. 5277218Sjfv 6277218Sjfv// This file is part of gold. 7277218Sjfv 8277218Sjfv// This program is free software; you can redistribute it and/or modify 9277218Sjfv// it under the terms of the GNU General Public License as published by 10277218Sjfv// the Free Software Foundation; either version 3 of the License, or 11277218Sjfv// (at your option) any later version. 12277218Sjfv 13277218Sjfv// This program is distributed in the hope that it will be useful, 14277218Sjfv// but WITHOUT ANY WARRANTY; without even the implied warranty of 15277218Sjfv// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16277218Sjfv// GNU General Public License for more details. 17277218Sjfv 18277218Sjfv// You should have received a copy of the GNU General Public License 19277218Sjfv// along with this program; if not, write to the Free Software 20277218Sjfv// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21277218Sjfv// MA 02110-1301, USA. 22277218Sjfv 23277218Sjfv#ifndef GOLD_ARCHIVE_H 24277218Sjfv#define GOLD_ARCHIVE_H 25277218Sjfv 26277218Sjfv#include <string> 27277218Sjfv#include <vector> 28277218Sjfv 29277218Sjfv#include "fileread.h" 30277218Sjfv#include "workqueue.h" 31277218Sjfv 32277218Sjfvnamespace gold 33277218Sjfv{ 34285603Sbrueffer 35277218Sjfvclass Task; 36277218Sjfvclass Input_argument; 37277218Sjfvclass Input_file; 38277218Sjfvclass Input_objects; 39277218Sjfvclass Input_group; 40277218Sjfvclass Layout; 41277218Sjfvclass Symbol_table; 42277218Sjfvclass Object; 43277218Sjfvstruct Read_symbols_data; 44277218Sjfvclass Input_file_lib; 45277218Sjfvclass Incremental_archive_entry; 46277218Sjfv 47277218Sjfv// An entry in the archive map of offsets to members. 48277218Sjfvstruct Archive_member 49277218Sjfv{ 50277218Sjfv Archive_member() 51277218Sjfv : obj_(NULL), sd_(NULL), arg_serial_(0) 52277218Sjfv { } 53277218Sjfv Archive_member(Object* obj, Read_symbols_data* sd) 54277218Sjfv : obj_(obj), sd_(sd), arg_serial_(0) 55277218Sjfv { } 56277218Sjfv // The object file. 57277218Sjfv Object* obj_; 58277218Sjfv // The data to pass from read_symbols() to add_symbols(). 59277218Sjfv Read_symbols_data* sd_; 60277218Sjfv // The serial number of the file in the argument list. 61277218Sjfv unsigned int arg_serial_; 62277218Sjfv}; 63277218Sjfv 64277218Sjfv// This class serves as a base class for Archive and Lib_group objects. 65277218Sjfv 66277218Sjfvclass Library_base 67277218Sjfv{ 68277218Sjfv public: 69277218Sjfv Library_base(Task* task) 70277218Sjfv : task_(task), incremental_info_(NULL) 71277218Sjfv { } 72277218Sjfv 73277218Sjfv virtual 74277218Sjfv ~Library_base() 75277218Sjfv { } 76277218Sjfv 77277218Sjfv // The file name. 78277218Sjfv const std::string& 79277218Sjfv filename() const 80285603Sbrueffer { return this->do_filename(); } 81285603Sbrueffer 82277218Sjfv // The modification time of the archive file. 83285603Sbrueffer Timespec 84277218Sjfv get_mtime() 85277218Sjfv { return this->do_get_mtime(); } 86285603Sbrueffer 87277218Sjfv // When we see a symbol in an archive we might decide to include the member, 88277218Sjfv // not include the member or be undecided. This enum represents these 89277218Sjfv // possibilities. 90277218Sjfv 91277218Sjfv enum Should_include 92277218Sjfv { 93277218Sjfv SHOULD_INCLUDE_NO, 94277218Sjfv SHOULD_INCLUDE_YES, 95285603Sbrueffer SHOULD_INCLUDE_UNKNOWN 96277218Sjfv }; 97277218Sjfv 98285603Sbrueffer static Should_include 99277218Sjfv should_include_member(Symbol_table* symtab, Layout*, const char* sym_name, 100277218Sjfv Symbol** symp, std::string* why, char** tmpbufp, 101277218Sjfv size_t* tmpbuflen); 102277218Sjfv 103277218Sjfv // Store a pointer to the incremental link info for the library. 104277218Sjfv void 105277218Sjfv set_incremental_info(Incremental_archive_entry* info) 106277218Sjfv { this->incremental_info_ = info; } 107277218Sjfv 108277218Sjfv // Return the pointer to the incremental link info for the library. 109277218Sjfv Incremental_archive_entry* 110277218Sjfv incremental_info() const 111277218Sjfv { return this->incremental_info_; } 112277218Sjfv 113277218Sjfv // Abstract base class for processing unused symbols. 114277218Sjfv class Symbol_visitor_base 115277218Sjfv { 116277218Sjfv public: 117277218Sjfv Symbol_visitor_base() 118277218Sjfv { } 119277218Sjfv 120277218Sjfv virtual 121285603Sbrueffer ~Symbol_visitor_base() 122277218Sjfv { } 123277218Sjfv 124277218Sjfv // This function will be called for each unused global 125277218Sjfv // symbol in a library, with a pointer to the symbol name. 126277218Sjfv virtual void 127277218Sjfv visit(const char* /* name */) = 0; 128277218Sjfv }; 129277218Sjfv 130277218Sjfv // Iterator for unused global symbols in the library. 131277218Sjfv // Calls v->visit() for each global symbol defined 132277218Sjfv // in each unused library member, passing a pointer to 133277218Sjfv // the symbol name. 134277218Sjfv void 135277218Sjfv for_all_unused_symbols(Symbol_visitor_base* v) const 136277218Sjfv { this->do_for_all_unused_symbols(v); } 137285603Sbrueffer 138277218Sjfv protected: 139285603Sbrueffer // The task reading this archive. 140 Task *task_; 141 142 private: 143 // The file name. 144 virtual const std::string& 145 do_filename() const = 0; 146 147 // Return the modification time of the archive file. 148 virtual Timespec 149 do_get_mtime() = 0; 150 151 // Iterator for unused global symbols in the library. 152 virtual void 153 do_for_all_unused_symbols(Symbol_visitor_base* v) const = 0; 154 155 // The incremental link information for this archive. 156 Incremental_archive_entry* incremental_info_; 157}; 158 159// This class represents an archive--generally a libNAME.a file. 160// Archives have a symbol table and a list of objects. 161 162class Archive : public Library_base 163{ 164 public: 165 Archive(const std::string& name, Input_file* input_file, 166 bool is_thin_archive, Dirsearch* dirpath, Task* task); 167 168 // The length of the magic string at the start of an archive. 169 static const int sarmag = 8; 170 171 // The magic string at the start of an archive. 172 static const char armag[sarmag]; 173 static const char armagt[sarmag]; 174 175 // The string expected at the end of an archive member header. 176 static const char arfmag[2]; 177 178 // Name of 64-bit symbol table member. 179 static const char sym64name[7]; 180 181 // The name of the object. This is the name used on the command 182 // line; e.g., if "-lgcc" is on the command line, this will be 183 // "gcc". 184 const std::string& 185 name() const 186 { return this->name_; } 187 188 // The input file. 189 const Input_file* 190 input_file() const 191 { return this->input_file_; } 192 193 // Set up the archive: read the symbol map. 194 void 195 setup(); 196 197 // Get a reference to the underlying file. 198 File_read& 199 file() 200 { return this->input_file_->file(); } 201 202 const File_read& 203 file() const 204 { return this->input_file_->file(); } 205 206 // Lock the underlying file. 207 void 208 lock(const Task* t) 209 { this->input_file_->file().lock(t); } 210 211 // Unlock the underlying file. 212 void 213 unlock(const Task* t) 214 { this->input_file_->file().unlock(t); } 215 216 // Return whether the underlying file is locked. 217 bool 218 is_locked() const 219 { return this->input_file_->file().is_locked(); } 220 221 // Return the token, so that the task can be queued. 222 Task_token* 223 token() 224 { return this->input_file_->file().token(); } 225 226 // Release the underlying file. 227 void 228 release() 229 { this->input_file_->file().release(); } 230 231 // Clear uncached views in the underlying file. 232 void 233 clear_uncached_views() 234 { this->input_file_->file().clear_uncached_views(); } 235 236 // Whether this is a thin archive. 237 bool 238 is_thin_archive() const 239 { return this->is_thin_archive_; } 240 241 // Unlock any nested archives. 242 void 243 unlock_nested_archives(); 244 245 // Select members from the archive as needed and add them to the 246 // link. 247 bool 248 add_symbols(Symbol_table*, Layout*, Input_objects*, Mapfile*); 249 250 // Return whether the archive defines the symbol. 251 bool 252 defines_symbol(Symbol*) const; 253 254 // Dump statistical information to stderr. 255 static void 256 print_stats(); 257 258 // Return the number of members in the archive. 259 size_t 260 count_members(); 261 262 // Return the no-export flag. 263 bool 264 no_export() 265 { return this->no_export_; } 266 267 private: 268 Archive(const Archive&); 269 Archive& operator=(const Archive&); 270 271 // The file name. 272 const std::string& 273 do_filename() const 274 { return this->input_file_->filename(); } 275 276 // The modification time of the archive file. 277 Timespec 278 do_get_mtime() 279 { return this->file().get_mtime(); } 280 281 struct Archive_header; 282 283 // Total number of archives seen. 284 static unsigned int total_archives; 285 // Total number of archive members seen. 286 static unsigned int total_members; 287 // Number of archive members loaded. 288 static unsigned int total_members_loaded; 289 290 // Get a view into the underlying file. 291 const unsigned char* 292 get_view(off_t start, section_size_type size, bool aligned, bool cache) 293 { return this->input_file_->file().get_view(0, start, size, aligned, cache); } 294 295 // Read the archive symbol map. 296 template<int mapsize> 297 void 298 read_armap(off_t start, section_size_type size); 299 300 // Read an archive member header at OFF. CACHE is whether to cache 301 // the file view. Return the size of the member, and set *PNAME to 302 // the name. 303 off_t 304 read_header(off_t off, bool cache, std::string* pname, off_t* nested_off); 305 306 // Interpret an archive header HDR at OFF. Return the size of the 307 // member, and set *PNAME to the name. 308 off_t 309 interpret_header(const Archive_header* hdr, off_t off, std::string* pname, 310 off_t* nested_off) const; 311 312 // Get the file and offset for an archive member, which may be an 313 // external member of a thin archive. Set *INPUT_FILE to the 314 // file containing the actual member, *MEMOFF to the offset 315 // within that file (0 if not a nested archive), and *MEMBER_NAME 316 // to the name of the archive member. Return TRUE on success. 317 bool 318 get_file_and_offset(off_t off, Input_file** input_file, off_t* memoff, 319 off_t* memsize, std::string* member_name); 320 321 // Return an ELF object for the member at offset OFF. 322 Object* 323 get_elf_object_for_member(off_t off, bool*); 324 325 // Read the symbols from all the archive members in the link. 326 void 327 read_all_symbols(); 328 329 // Read the symbols from an archive member in the link. OFF is the file 330 // offset of the member header. 331 void 332 read_symbols(off_t off); 333 334 // Include all the archive members in the link. 335 bool 336 include_all_members(Symbol_table*, Layout*, Input_objects*, Mapfile*); 337 338 // Include an archive member in the link. 339 bool 340 include_member(Symbol_table*, Layout*, Input_objects*, off_t off, 341 Mapfile*, Symbol*, const char* why); 342 343 // Return whether we found this archive by searching a directory. 344 bool 345 searched_for() const 346 { return this->input_file_->will_search_for(); } 347 348 // Iterate over archive members. 349 class const_iterator; 350 351 const_iterator 352 begin(); 353 354 const_iterator 355 end(); 356 357 friend class const_iterator; 358 359 // Iterator for unused global symbols in the library. 360 void 361 do_for_all_unused_symbols(Symbol_visitor_base* v) const; 362 363 // An entry in the archive map of symbols to object files. 364 struct Armap_entry 365 { 366 // The offset to the symbol name in armap_names_. 367 off_t name_offset; 368 // The file offset to the object in the archive. 369 off_t file_offset; 370 }; 371 372 // A simple hash code for off_t values. 373 class Seen_hash 374 { 375 public: 376 size_t operator()(off_t val) const 377 { return static_cast<size_t>(val); } 378 }; 379 380 // For keeping track of open nested archives in a thin archive file. 381 typedef Unordered_map<std::string, Archive*> Nested_archive_table; 382 383 // Name of object as printed to user. 384 std::string name_; 385 // For reading the file. 386 Input_file* input_file_; 387 // The archive map. 388 std::vector<Armap_entry> armap_; 389 // The names in the archive map. 390 std::string armap_names_; 391 // The extended name table. 392 std::string extended_names_; 393 // Track which symbols in the archive map are for elements which are 394 // defined or which have already been included in the link. 395 std::vector<bool> armap_checked_; 396 // Track which elements have been included by offset. 397 Unordered_set<off_t, Seen_hash> seen_offsets_; 398 // Table of objects whose symbols have been pre-read. 399 std::map<off_t, Archive_member> members_; 400 // True if this is a thin archive. 401 const bool is_thin_archive_; 402 // True if we have included at least one object from this archive. 403 bool included_member_; 404 // Table of nested archives, indexed by filename. 405 Nested_archive_table nested_archives_; 406 // The directory search path. 407 Dirsearch* dirpath_; 408 // Number of members in this archive; 409 unsigned int num_members_; 410 // True if we exclude this library archive from automatic export. 411 bool no_export_; 412 // True if this library has been included as a --whole-archive. 413 bool included_all_members_; 414}; 415 416// This class is used to read an archive and pick out the desired 417// elements and add them to the link. 418 419class Add_archive_symbols : public Task 420{ 421 public: 422 Add_archive_symbols(Symbol_table* symtab, Layout* layout, 423 Input_objects* input_objects, Dirsearch* dirpath, 424 int dirindex, Mapfile* mapfile, 425 const Input_argument* input_argument, 426 Archive* archive, Input_group* input_group, 427 Task_token* this_blocker, 428 Task_token* next_blocker) 429 : symtab_(symtab), layout_(layout), input_objects_(input_objects), 430 dirpath_(dirpath), dirindex_(dirindex), mapfile_(mapfile), 431 input_argument_(input_argument), archive_(archive), 432 input_group_(input_group), this_blocker_(this_blocker), 433 next_blocker_(next_blocker) 434 { } 435 436 ~Add_archive_symbols(); 437 438 // The standard Task methods. 439 440 Task_token* 441 is_runnable(); 442 443 void 444 locks(Task_locker*); 445 446 void 447 run(Workqueue*); 448 449 std::string 450 get_name() const 451 { 452 if (this->archive_ == NULL) 453 return "Add_archive_symbols"; 454 return "Add_archive_symbols " + this->archive_->file().filename(); 455 } 456 457 private: 458 Symbol_table* symtab_; 459 Layout* layout_; 460 Input_objects* input_objects_; 461 Dirsearch* dirpath_; 462 int dirindex_; 463 Mapfile* mapfile_; 464 const Input_argument* input_argument_; 465 Archive* archive_; 466 Input_group* input_group_; 467 Task_token* this_blocker_; 468 Task_token* next_blocker_; 469}; 470 471// This class represents the files surrounded by a --start-lib ... --end-lib. 472 473class Lib_group : public Library_base 474{ 475 public: 476 Lib_group(const Input_file_lib* lib, Task* task); 477 478 // Select members from the lib group as needed and add them to the link. 479 void 480 add_symbols(Symbol_table*, Layout*, Input_objects*); 481 482 // Include a member of the lib group in the link. 483 void 484 include_member(Symbol_table*, Layout*, Input_objects*, const Archive_member&); 485 486 Archive_member* 487 get_member(int i) 488 { 489 return &this->members_[i]; 490 } 491 492 // Total number of archives seen. 493 static unsigned int total_lib_groups; 494 // Total number of archive members seen. 495 static unsigned int total_members; 496 // Number of archive members loaded. 497 static unsigned int total_members_loaded; 498 499 // Dump statistical information to stderr. 500 static void 501 print_stats(); 502 503 private: 504 // The file name. 505 const std::string& 506 do_filename() const; 507 508 // A Lib_group does not have a modification time, since there is no 509 // real library file. 510 Timespec 511 do_get_mtime() 512 { return Timespec(0, 0); } 513 514 // Iterator for unused global symbols in the library. 515 void 516 do_for_all_unused_symbols(Symbol_visitor_base*) const; 517 518 // Table of the objects in the group. 519 std::vector<Archive_member> members_; 520}; 521 522// This class is used to pick out the desired elements and add them to the link. 523 524class Add_lib_group_symbols : public Task 525{ 526 public: 527 Add_lib_group_symbols(Symbol_table* symtab, Layout* layout, 528 Input_objects* input_objects, 529 Lib_group* lib, Task_token* next_blocker) 530 : symtab_(symtab), layout_(layout), input_objects_(input_objects), 531 lib_(lib), readsyms_blocker_(NULL), this_blocker_(NULL), 532 next_blocker_(next_blocker) 533 { } 534 535 ~Add_lib_group_symbols(); 536 537 // The standard Task methods. 538 539 Task_token* 540 is_runnable(); 541 542 void 543 locks(Task_locker*); 544 545 void 546 run(Workqueue*); 547 548 // Set the blocker to use for this task. 549 void 550 set_blocker(Task_token* readsyms_blocker, Task_token* this_blocker) 551 { 552 gold_assert(this->readsyms_blocker_ == NULL && this->this_blocker_ == NULL); 553 this->readsyms_blocker_ = readsyms_blocker; 554 this->this_blocker_ = this_blocker; 555 } 556 557 std::string 558 get_name() const 559 { 560 return "Add_lib_group_symbols"; 561 } 562 563 private: 564 Symbol_table* symtab_; 565 Layout* layout_; 566 Input_objects* input_objects_; 567 Lib_group* lib_; 568 Task_token* readsyms_blocker_; 569 Task_token* this_blocker_; 570 Task_token* next_blocker_; 571}; 572 573} // End namespace gold. 574 575#endif // !defined(GOLD_ARCHIVE_H) 576