diff options
Diffstat (limited to 'gold/archive.h')
-rw-r--r-- | gold/archive.h | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/gold/archive.h b/gold/archive.h new file mode 100644 index 000000000000..193a9e2de820 --- /dev/null +++ b/gold/archive.h @@ -0,0 +1,162 @@ +// archive.h -- archive support for gold -*- C++ -*- + +#ifndef GOLD_ARCHIVE_H +#define GOLD_ARCHIVE_H + +#include <string> +#include <vector> + +#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) + { return this->input_file_->file().get_view(start, 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); + + // 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_entry> 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<bool> 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) |