archive.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575
  1. // archive.h -- archive support for gold -*- C++ -*-
  2. // Copyright (C) 2006-2022 Free Software Foundation, Inc.
  3. // Written by Ian Lance Taylor <iant@google.com>.
  4. // This file is part of gold.
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 3 of the License, or
  8. // (at your option) any later version.
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software
  15. // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
  16. // MA 02110-1301, USA.
  17. #ifndef GOLD_ARCHIVE_H
  18. #define GOLD_ARCHIVE_H
  19. #include <string>
  20. #include <vector>
  21. #include "fileread.h"
  22. #include "workqueue.h"
  23. namespace gold
  24. {
  25. class Task;
  26. class Input_argument;
  27. class Input_file;
  28. class Input_objects;
  29. class Input_group;
  30. class Layout;
  31. class Symbol_table;
  32. class Object;
  33. struct Read_symbols_data;
  34. class Input_file_lib;
  35. class Incremental_archive_entry;
  36. // An entry in the archive map of offsets to members.
  37. struct Archive_member
  38. {
  39. Archive_member()
  40. : obj_(NULL), sd_(NULL), arg_serial_(0)
  41. { }
  42. Archive_member(Object* obj, Read_symbols_data* sd)
  43. : obj_(obj), sd_(sd), arg_serial_(0)
  44. { }
  45. // The object file.
  46. Object* obj_;
  47. // The data to pass from read_symbols() to add_symbols().
  48. Read_symbols_data* sd_;
  49. // The serial number of the file in the argument list.
  50. unsigned int arg_serial_;
  51. };
  52. // This class serves as a base class for Archive and Lib_group objects.
  53. class Library_base
  54. {
  55. public:
  56. Library_base(Task* task)
  57. : task_(task), incremental_info_(NULL)
  58. { }
  59. virtual
  60. ~Library_base()
  61. { }
  62. // The file name.
  63. const std::string&
  64. filename() const
  65. { return this->do_filename(); }
  66. // The modification time of the archive file.
  67. Timespec
  68. get_mtime()
  69. { return this->do_get_mtime(); }
  70. // When we see a symbol in an archive we might decide to include the member,
  71. // not include the member or be undecided. This enum represents these
  72. // possibilities.
  73. enum Should_include
  74. {
  75. SHOULD_INCLUDE_NO,
  76. SHOULD_INCLUDE_YES,
  77. SHOULD_INCLUDE_UNKNOWN
  78. };
  79. static Should_include
  80. should_include_member(Symbol_table* symtab, Layout*, const char* sym_name,
  81. Symbol** symp, std::string* why, char** tmpbufp,
  82. size_t* tmpbuflen);
  83. // Store a pointer to the incremental link info for the library.
  84. void
  85. set_incremental_info(Incremental_archive_entry* info)
  86. { this->incremental_info_ = info; }
  87. // Return the pointer to the incremental link info for the library.
  88. Incremental_archive_entry*
  89. incremental_info() const
  90. { return this->incremental_info_; }
  91. // Abstract base class for processing unused symbols.
  92. class Symbol_visitor_base
  93. {
  94. public:
  95. Symbol_visitor_base()
  96. { }
  97. virtual
  98. ~Symbol_visitor_base()
  99. { }
  100. // This function will be called for each unused global
  101. // symbol in a library, with a pointer to the symbol name.
  102. virtual void
  103. visit(const char* /* name */) = 0;
  104. };
  105. // Iterator for unused global symbols in the library.
  106. // Calls v->visit() for each global symbol defined
  107. // in each unused library member, passing a pointer to
  108. // the symbol name.
  109. void
  110. for_all_unused_symbols(Symbol_visitor_base* v) const
  111. { this->do_for_all_unused_symbols(v); }
  112. protected:
  113. // The task reading this archive.
  114. Task *task_;
  115. private:
  116. // The file name.
  117. virtual const std::string&
  118. do_filename() const = 0;
  119. // Return the modification time of the archive file.
  120. virtual Timespec
  121. do_get_mtime() = 0;
  122. // Iterator for unused global symbols in the library.
  123. virtual void
  124. do_for_all_unused_symbols(Symbol_visitor_base* v) const = 0;
  125. // The incremental link information for this archive.
  126. Incremental_archive_entry* incremental_info_;
  127. };
  128. // This class represents an archive--generally a libNAME.a file.
  129. // Archives have a symbol table and a list of objects.
  130. class Archive : public Library_base
  131. {
  132. public:
  133. Archive(const std::string& name, Input_file* input_file,
  134. bool is_thin_archive, Dirsearch* dirpath, Task* task);
  135. // The length of the magic string at the start of an archive.
  136. static const int sarmag = 8;
  137. // The magic string at the start of an archive.
  138. static const char armag[sarmag];
  139. static const char armagt[sarmag];
  140. // The string expected at the end of an archive member header.
  141. static const char arfmag[2];
  142. // Name of 64-bit symbol table member.
  143. static const char sym64name[7];
  144. // The name of the object. This is the name used on the command
  145. // line; e.g., if "-lgcc" is on the command line, this will be
  146. // "gcc".
  147. const std::string&
  148. name() const
  149. { return this->name_; }
  150. // The input file.
  151. const Input_file*
  152. input_file() const
  153. { return this->input_file_; }
  154. // Set up the archive: read the symbol map.
  155. void
  156. setup();
  157. // Get a reference to the underlying file.
  158. File_read&
  159. file()
  160. { return this->input_file_->file(); }
  161. const File_read&
  162. file() const
  163. { return this->input_file_->file(); }
  164. // Lock the underlying file.
  165. void
  166. lock(const Task* t)
  167. { this->input_file_->file().lock(t); }
  168. // Unlock the underlying file.
  169. void
  170. unlock(const Task* t)
  171. { this->input_file_->file().unlock(t); }
  172. // Return whether the underlying file is locked.
  173. bool
  174. is_locked() const
  175. { return this->input_file_->file().is_locked(); }
  176. // Return the token, so that the task can be queued.
  177. Task_token*
  178. token()
  179. { return this->input_file_->file().token(); }
  180. // Release the underlying file.
  181. void
  182. release()
  183. { this->input_file_->file().release(); }
  184. // Clear uncached views in the underlying file.
  185. void
  186. clear_uncached_views()
  187. { this->input_file_->file().clear_uncached_views(); }
  188. // Whether this is a thin archive.
  189. bool
  190. is_thin_archive() const
  191. { return this->is_thin_archive_; }
  192. // Unlock any nested archives.
  193. void
  194. unlock_nested_archives();
  195. // Select members from the archive as needed and add them to the
  196. // link.
  197. bool
  198. add_symbols(Symbol_table*, Layout*, Input_objects*, Mapfile*);
  199. // Return whether the archive defines the symbol.
  200. bool
  201. defines_symbol(Symbol*) const;
  202. // Dump statistical information to stderr.
  203. static void
  204. print_stats();
  205. // Return the number of members in the archive.
  206. size_t
  207. count_members();
  208. // Return the no-export flag.
  209. bool
  210. no_export()
  211. { return this->no_export_; }
  212. private:
  213. Archive(const Archive&);
  214. Archive& operator=(const Archive&);
  215. // The file name.
  216. const std::string&
  217. do_filename() const
  218. { return this->input_file_->filename(); }
  219. // The modification time of the archive file.
  220. Timespec
  221. do_get_mtime()
  222. { return this->file().get_mtime(); }
  223. struct Archive_header;
  224. // Total number of archives seen.
  225. static unsigned int total_archives;
  226. // Total number of archive members seen.
  227. static unsigned int total_members;
  228. // Number of archive members loaded.
  229. static unsigned int total_members_loaded;
  230. // Get a view into the underlying file.
  231. const unsigned char*
  232. get_view(off_t start, section_size_type size, bool aligned, bool cache)
  233. { return this->input_file_->file().get_view(0, start, size, aligned, cache); }
  234. // Read the archive symbol map.
  235. template<int mapsize>
  236. void
  237. read_armap(off_t start, section_size_type size);
  238. // Read an archive member header at OFF. CACHE is whether to cache
  239. // the file view. Return the size of the member, and set *PNAME to
  240. // the name.
  241. off_t
  242. read_header(off_t off, bool cache, std::string* pname, off_t* nested_off);
  243. // Interpret an archive header HDR at OFF. Return the size of the
  244. // member, and set *PNAME to the name.
  245. off_t
  246. interpret_header(const Archive_header* hdr, off_t off, std::string* pname,
  247. off_t* nested_off) const;
  248. // Get the file and offset for an archive member, which may be an
  249. // external member of a thin archive. Set *INPUT_FILE to the
  250. // file containing the actual member, *MEMOFF to the offset
  251. // within that file (0 if not a nested archive), and *MEMBER_NAME
  252. // to the name of the archive member. Return TRUE on success.
  253. bool
  254. get_file_and_offset(off_t off, Input_file** input_file, off_t* memoff,
  255. off_t* memsize, std::string* member_name);
  256. // Return an ELF object for the member at offset OFF.
  257. Object*
  258. get_elf_object_for_member(off_t off, bool*);
  259. // Read the symbols from all the archive members in the link.
  260. void
  261. read_all_symbols();
  262. // Read the symbols from an archive member in the link. OFF is the file
  263. // offset of the member header.
  264. void
  265. read_symbols(off_t off);
  266. // Include all the archive members in the link.
  267. bool
  268. include_all_members(Symbol_table*, Layout*, Input_objects*, Mapfile*);
  269. // Include an archive member in the link.
  270. bool
  271. include_member(Symbol_table*, Layout*, Input_objects*, off_t off,
  272. Mapfile*, Symbol*, const char* why);
  273. // Return whether we found this archive by searching a directory.
  274. bool
  275. searched_for() const
  276. { return this->input_file_->will_search_for(); }
  277. // Iterate over archive members.
  278. class const_iterator;
  279. const_iterator
  280. begin();
  281. const_iterator
  282. end();
  283. friend class const_iterator;
  284. // Iterator for unused global symbols in the library.
  285. void
  286. do_for_all_unused_symbols(Symbol_visitor_base* v) const;
  287. // An entry in the archive map of symbols to object files.
  288. struct Armap_entry
  289. {
  290. // The offset to the symbol name in armap_names_.
  291. off_t name_offset;
  292. // The file offset to the object in the archive.
  293. off_t file_offset;
  294. };
  295. // A simple hash code for off_t values.
  296. class Seen_hash
  297. {
  298. public:
  299. size_t operator()(off_t val) const
  300. { return static_cast<size_t>(val); }
  301. };
  302. // For keeping track of open nested archives in a thin archive file.
  303. typedef Unordered_map<std::string, Archive*> Nested_archive_table;
  304. // Name of object as printed to user.
  305. std::string name_;
  306. // For reading the file.
  307. Input_file* input_file_;
  308. // The archive map.
  309. std::vector<Armap_entry> armap_;
  310. // The names in the archive map.
  311. std::string armap_names_;
  312. // The extended name table.
  313. std::string extended_names_;
  314. // Track which symbols in the archive map are for elements which are
  315. // defined or which have already been included in the link.
  316. std::vector<bool> armap_checked_;
  317. // Track which elements have been included by offset.
  318. Unordered_set<off_t, Seen_hash> seen_offsets_;
  319. // Table of objects whose symbols have been pre-read.
  320. std::map<off_t, Archive_member> members_;
  321. // True if this is a thin archive.
  322. const bool is_thin_archive_;
  323. // True if we have included at least one object from this archive.
  324. bool included_member_;
  325. // Table of nested archives, indexed by filename.
  326. Nested_archive_table nested_archives_;
  327. // The directory search path.
  328. Dirsearch* dirpath_;
  329. // Number of members in this archive;
  330. unsigned int num_members_;
  331. // True if we exclude this library archive from automatic export.
  332. bool no_export_;
  333. // True if this library has been included as a --whole-archive.
  334. bool included_all_members_;
  335. };
  336. // This class is used to read an archive and pick out the desired
  337. // elements and add them to the link.
  338. class Add_archive_symbols : public Task
  339. {
  340. public:
  341. Add_archive_symbols(Symbol_table* symtab, Layout* layout,
  342. Input_objects* input_objects, Dirsearch* dirpath,
  343. int dirindex, Mapfile* mapfile,
  344. const Input_argument* input_argument,
  345. Archive* archive, Input_group* input_group,
  346. Task_token* this_blocker,
  347. Task_token* next_blocker)
  348. : symtab_(symtab), layout_(layout), input_objects_(input_objects),
  349. dirpath_(dirpath), dirindex_(dirindex), mapfile_(mapfile),
  350. input_argument_(input_argument), archive_(archive),
  351. input_group_(input_group), this_blocker_(this_blocker),
  352. next_blocker_(next_blocker)
  353. { }
  354. ~Add_archive_symbols();
  355. // The standard Task methods.
  356. Task_token*
  357. is_runnable();
  358. void
  359. locks(Task_locker*);
  360. void
  361. run(Workqueue*);
  362. std::string
  363. get_name() const
  364. {
  365. if (this->archive_ == NULL)
  366. return "Add_archive_symbols";
  367. return "Add_archive_symbols " + this->archive_->file().filename();
  368. }
  369. private:
  370. Symbol_table* symtab_;
  371. Layout* layout_;
  372. Input_objects* input_objects_;
  373. Dirsearch* dirpath_;
  374. int dirindex_;
  375. Mapfile* mapfile_;
  376. const Input_argument* input_argument_;
  377. Archive* archive_;
  378. Input_group* input_group_;
  379. Task_token* this_blocker_;
  380. Task_token* next_blocker_;
  381. };
  382. // This class represents the files surrounded by a --start-lib ... --end-lib.
  383. class Lib_group : public Library_base
  384. {
  385. public:
  386. Lib_group(const Input_file_lib* lib, Task* task);
  387. // Select members from the lib group as needed and add them to the link.
  388. void
  389. add_symbols(Symbol_table*, Layout*, Input_objects*);
  390. // Include a member of the lib group in the link.
  391. void
  392. include_member(Symbol_table*, Layout*, Input_objects*, const Archive_member&);
  393. Archive_member*
  394. get_member(int i)
  395. {
  396. return &this->members_[i];
  397. }
  398. // Total number of archives seen.
  399. static unsigned int total_lib_groups;
  400. // Total number of archive members seen.
  401. static unsigned int total_members;
  402. // Number of archive members loaded.
  403. static unsigned int total_members_loaded;
  404. // Dump statistical information to stderr.
  405. static void
  406. print_stats();
  407. private:
  408. // The file name.
  409. const std::string&
  410. do_filename() const;
  411. // A Lib_group does not have a modification time, since there is no
  412. // real library file.
  413. Timespec
  414. do_get_mtime()
  415. { return Timespec(0, 0); }
  416. // Iterator for unused global symbols in the library.
  417. void
  418. do_for_all_unused_symbols(Symbol_visitor_base*) const;
  419. // Table of the objects in the group.
  420. std::vector<Archive_member> members_;
  421. };
  422. // This class is used to pick out the desired elements and add them to the link.
  423. class Add_lib_group_symbols : public Task
  424. {
  425. public:
  426. Add_lib_group_symbols(Symbol_table* symtab, Layout* layout,
  427. Input_objects* input_objects,
  428. Lib_group* lib, Task_token* next_blocker)
  429. : symtab_(symtab), layout_(layout), input_objects_(input_objects),
  430. lib_(lib), readsyms_blocker_(NULL), this_blocker_(NULL),
  431. next_blocker_(next_blocker)
  432. { }
  433. ~Add_lib_group_symbols();
  434. // The standard Task methods.
  435. Task_token*
  436. is_runnable();
  437. void
  438. locks(Task_locker*);
  439. void
  440. run(Workqueue*);
  441. // Set the blocker to use for this task.
  442. void
  443. set_blocker(Task_token* readsyms_blocker, Task_token* this_blocker)
  444. {
  445. gold_assert(this->readsyms_blocker_ == NULL && this->this_blocker_ == NULL);
  446. this->readsyms_blocker_ = readsyms_blocker;
  447. this->this_blocker_ = this_blocker;
  448. }
  449. std::string
  450. get_name() const
  451. {
  452. return "Add_lib_group_symbols";
  453. }
  454. private:
  455. Symbol_table* symtab_;
  456. Layout* layout_;
  457. Input_objects* input_objects_;
  458. Lib_group* lib_;
  459. Task_token* readsyms_blocker_;
  460. Task_token* this_blocker_;
  461. Task_token* next_blocker_;
  462. };
  463. } // End namespace gold.
  464. #endif // !defined(GOLD_ARCHIVE_H)