// archive.h -- archive support for gold -*- C++ -*- #ifndef GOLD_ARCHIVE_H #define GOLD_ARCHIVE_H #include #include #include "workqueue.h" namespace gold { class General_options; class Input_file; class Input_objects; class Input_group; class Layout; class Symbol_table; // This class represents an archive--generally a libNAME.a file. // Archives have a symbol table and a list of objects. class Archive { public: Archive(const std::string& name, Input_file* input_file) : name_(name), input_file_(input_file), armap_(), extended_names_() { } // The length of the magic string at the start of an archive. static const int sarmag = 8; // The magic string at the start of an archive. static const char armag[sarmag]; // The string expected at the end of an archive member header. static const char arfmag[2]; // The name of the object. const std::string& name() const { return this->name_; } // Set up the archive: read the symbol map. void setup(); // Get a reference to the underlying file. File_read& file() { return this->input_file_->file(); } // Lock the underlying file. void lock() { this->input_file_->file().lock(); } // Unlock the underlying file. void unlock() { this->input_file_->file().unlock(); } // Return whether the underlying file is locked. bool is_locked() const { return this->input_file_->file().is_locked(); } // Select members from the archive as needed and add them to the // link. void add_symbols(const General_options&, Symbol_table*, Layout*, Input_objects*); private: Archive(const Archive&); Archive& operator=(const Archive&); struct Archive_header; // Get a view into the underlying file. const unsigned char* get_view(off_t start, off_t size, off_t* pbytes = NULL) { return this->input_file_->file().get_view(start, size, pbytes); } // Read the archive symbol map. void read_armap(off_t start, off_t size); // Read an archive member header at OFF. Return the size of the // member, and set *PNAME to the name. off_t read_header(off_t off, std::string* pname); // Interpret an archive header HDR at OFF. Return the size of the // member, and set *PNAME to the name. off_t interpret_header(const Archive_header* hdr, off_t off, std::string* pname); // Include all the archive members in the link. void include_all_members(const General_options&, Symbol_table*, Layout*, Input_objects*); // Include an archive member in the link. void include_member(const General_options&, Symbol_table*, Layout*, Input_objects*, off_t off); // An entry in the archive map of symbols to object files. struct Armap_entry { // The symbol name. const char* name; // The offset to the file. off_t offset; }; // Name of object as printed to user. std::string name_; // For reading the file. Input_file* input_file_; // The archive map. std::vector armap_; // The extended name table. std::string extended_names_; // Track which symbols in the archive map are for elements which // have already been included in the link. std::vector seen_; }; // This class is used to read an archive and pick out the desired // elements and add them to the link. class Add_archive_symbols : public Task { public: Add_archive_symbols(const General_options& options, Symbol_table* symtab, Layout* layout, Input_objects* input_objects, Archive* archive, Input_group* input_group, Task_token* this_blocker, Task_token* next_blocker) : options_(options), symtab_(symtab), layout_(layout), input_objects_(input_objects), archive_(archive), input_group_(input_group), this_blocker_(this_blocker), next_blocker_(next_blocker) { } ~Add_archive_symbols(); // The standard Task methods. Is_runnable_type is_runnable(Workqueue*); Task_locker* locks(Workqueue*); void run(Workqueue*); private: class Add_archive_symbols_locker; const General_options& options_; Symbol_table* symtab_; Layout* layout_; Input_objects* input_objects_; Archive* archive_; Input_group* input_group_; Task_token* this_blocker_; Task_token* next_blocker_; }; } // End namespace gold. #endif // !defined(GOLD_ARCHIVE_H)