diff options
author | Ian Lance Taylor <iant@google.com> | 2006-11-06 22:46:08 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@google.com> | 2006-11-06 22:46:08 +0000 |
commit | f6ce93d6e999d1a0c450c5e71c5b3468e6217f0a (patch) | |
tree | 945ecd482d35d1c2a590645ef3d5f41fb83dcc4b /gold/object.h | |
parent | 8d9455b422d98d97f090923445aa2680e6882f20 (diff) | |
download | gdb-f6ce93d6e999d1a0c450c5e71c5b3468e6217f0a.zip gdb-f6ce93d6e999d1a0c450c5e71c5b3468e6217f0a.tar.gz gdb-f6ce93d6e999d1a0c450c5e71c5b3468e6217f0a.tar.bz2 |
Split Object into Dynobj and Relobj, incorporate elfcpp swapping changes.
Diffstat (limited to 'gold/object.h')
-rw-r--r-- | gold/object.h | 276 |
1 files changed, 159 insertions, 117 deletions
diff --git a/gold/object.h b/gold/object.h index 9b23de9..e1f56d2 100644 --- a/gold/object.h +++ b/gold/object.h @@ -4,14 +4,12 @@ #define GOLD_OBJECT_H #include <cassert> -#include <list> #include <string> #include <vector> #include "elfcpp.h" #include "fileread.h" #include "target.h" -#include "symtab.h" namespace gold { @@ -21,6 +19,7 @@ class Stringpool; class Layout; class Output_section; class Output_file; +class Dynobj; // Data to pass from read_symbols() to add_symbols(). @@ -71,10 +70,9 @@ struct Read_relocs_data File_view* local_symbols; }; -// Object is an interface which represents either a 32-bit or a 64-bit -// input object. This can be a regular object file (ET_REL) or a -// shared object (ET_DYN). The actual instantiations are -// Sized_object<32> and Sized_object<64> +// Object is an abstract base class which represents either a 32-bit +// or a 64-bit input object. This can be a regular object file +// (ET_REL) or a shared object (ET_DYN). class Object { @@ -86,8 +84,7 @@ class Object Object(const std::string& name, Input_file* input_file, bool is_dynamic, off_t offset = 0) : name_(name), input_file_(input_file), offset_(offset), - shnum_(0), is_dynamic_(is_dynamic), target_(NULL), - map_to_output_() + is_dynamic_(is_dynamic), target_(NULL) { } virtual ~Object() @@ -138,14 +135,124 @@ class Object // Pass sections which should be included in the link to the Layout // object, and record where the sections go in the output file. void - layout(Layout* lay, Read_symbols_data* sd) - { this->do_layout(lay, sd); } + layout(const General_options& options, Symbol_table* symtab, + Layout* layout, Read_symbols_data* sd) + { this->do_layout(options, symtab, layout, sd); } // Add symbol information to the global symbol table. void add_symbols(Symbol_table* symtab, Read_symbols_data* sd) { this->do_add_symbols(symtab, sd); } + // Return a view of the contents of a section. Set *PLEN to the + // size. + const unsigned char* + section_contents(unsigned int shnum, off_t* plen) + { return this->do_section_contents(shnum, plen); } + + // Return the name of a section given a section index. This is only + // used for error messages. + std::string + section_name(unsigned int shnum) + { return this->do_section_name(shnum); } + + protected: + // Read the symbols--implemented by child class. + virtual void + do_read_symbols(Read_symbols_data*) = 0; + + // Lay out sections--implemented by child class. + virtual void + do_layout(const General_options&, Symbol_table*, Layout*, + Read_symbols_data*) = 0; + + // Add symbol information to the global symbol table--implemented by + // child class. + virtual void + do_add_symbols(Symbol_table*, Read_symbols_data*) = 0; + + // Return a view of the contents of a section. Set *PLEN to the + // size. Implemented by child class. + virtual const unsigned char* + do_section_contents(unsigned int shnum, off_t* plen) = 0; + + // Get the name of a section--implemented by child class. + virtual std::string + do_section_name(unsigned int shnum) = 0; + + // Get the file. + Input_file* + input_file() const + { return this->input_file_; } + + // Get the offset into the file. + off_t + offset() const + { return this->offset_; } + + // 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 + this->offset_, size); } + + // Get a lasting view into the underlying file. + File_view* + get_lasting_view(off_t start, off_t size) + { + return this->input_file_->file().get_lasting_view(start + this->offset_, + size); + } + + // Read data from the underlying file. + void + read(off_t start, off_t size, void* p) + { this->input_file_->file().read(start + this->offset_, size, p); } + + // Set the target. + void + set_target(Target* target) + { this->target_ = target; } + + private: + // This class may not be copied. + Object(const Object&); + Object& operator=(const Object&); + + // Name of object as printed to user. + std::string name_; + // For reading the file. + Input_file* input_file_; + // Offset within the file--0 for an object file, non-0 for an + // archive. + off_t offset_; + // Whether this is a dynamic object. + bool is_dynamic_; + // Target functions--may be NULL if the target is not known. + Target* target_; +}; + +// Implement sized_target inline for efficiency. This approach breaks +// static type checking, but is made safe using asserts. + +template<int size, bool big_endian> +inline Sized_target<size, big_endian>* +Object::sized_target(ACCEPT_SIZE_ENDIAN_ONLY) +{ + assert(this->target_->get_size() == size); + assert(this->target_->is_big_endian() ? big_endian : !big_endian); + return static_cast<Sized_target<size, big_endian>*>(this->target_); +} + +// A regular object (ET_REL). This is an abstract base class itself. +// The implementations is the template class Sized_relobj. + +class Relobj : public Object +{ + public: + Relobj(const std::string& name, Input_file* input_file, off_t offset = 0) + : Object(name, input_file, false, offset) + { } + // Read the relocs. void read_relocs(Read_relocs_data* rd) @@ -192,12 +299,6 @@ class Object this->map_to_output_[shndx].offset = off; } - // Return the name of a section given a section index. This is only - // used for error messages. - std::string - section_name(unsigned int shnum) - { return this->do_section_name(shnum); } - protected: // What we need to know to map an input section to an output // section. We keep an array of these, one for each input section, @@ -211,15 +312,6 @@ class Object off_t offset; }; - // Read the symbols--implemented by child class. - virtual void - do_read_symbols(Read_symbols_data*) = 0; - - // Add symbol information to the global symbol table--implemented by - // child class. - virtual void - do_add_symbols(Symbol_table*, Read_symbols_data*) = 0; - // Read the relocs--implemented by child class. virtual void do_read_relocs(Read_relocs_data*) = 0; @@ -229,10 +321,6 @@ class Object do_scan_relocs(const General_options&, Symbol_table*, Layout*, Read_relocs_data*) = 0; - // Lay out sections--implemented by child class. - virtual void - do_layout(Layout*, Read_symbols_data*) = 0; - // Finalize local symbols--implemented by child class. virtual off_t do_finalize_local_symbols(off_t, Stringpool*) = 0; @@ -243,25 +331,6 @@ class Object do_relocate(const General_options& options, const Symbol_table* symtab, const Layout*, Output_file* of) = 0; - // Get the name of a section--implemented by child class. - virtual std::string - do_section_name(unsigned int shnum) = 0; - - // Get the file. - Input_file* - input_file() const - { return this->input_file_; } - - // Get the offset into the file. - off_t - offset() const - { return this->offset_; } - - // 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 + this->offset_, size); } - // Get the number of sections. unsigned int shnum() const @@ -272,66 +341,21 @@ class Object set_shnum(int shnum) { this->shnum_ = shnum; } - // Set the target. - void - set_target(Target* target) - { this->target_ = target; } - - // Read data from the underlying file. - void - read(off_t start, off_t size, void* p) - { this->input_file_->file().read(start + this->offset_, size, p); } - - // Get a lasting view into the underlying file. - File_view* - get_lasting_view(off_t start, off_t size) - { - return this->input_file_->file().get_lasting_view(start + this->offset_, - size); - } - // Return the vector mapping input sections to output sections. std::vector<Map_to_output>& map_to_output() { return this->map_to_output_; } private: - // This class may not be copied. - Object(const Object&); - Object& operator=(const Object&); - - // Name of object as printed to user. - std::string name_; - // For reading the file. - Input_file* input_file_; - // Offset within the file--0 for an object file, non-0 for an - // archive. - off_t offset_; // Number of input sections. unsigned int shnum_; - // Whether this is a dynamic object. - bool is_dynamic_; - // Target functions--may be NULL if the target is not known. - Target* target_; // Mapping from input sections to output section. std::vector<Map_to_output> map_to_output_; }; -// Implement sized_target inline for efficiency. This approach breaks -// static type checking, but is made safe using asserts. - -template<int size, bool big_endian> -inline Sized_target<size, big_endian>* -Object::sized_target(ACCEPT_SIZE_ENDIAN_ONLY) -{ - assert(this->target_->get_size() == size); - assert(this->target_->is_big_endian() ? big_endian : !big_endian); - return static_cast<Sized_target<size, big_endian>*>(this->target_); -} - // Implement Object::output_section inline for efficiency. inline Output_section* -Object::output_section(unsigned int shnum, off_t* poff) +Relobj::output_section(unsigned int shnum, off_t* poff) { assert(shnum < this->map_to_output_.size()); const Map_to_output& mo(this->map_to_output_[shnum]); @@ -342,13 +366,13 @@ Object::output_section(unsigned int shnum, off_t* poff) // A regular object file. This is size and endian specific. template<int size, bool big_endian> -class Sized_object : public Object +class Sized_relobj : public Relobj { public: - Sized_object(const std::string& name, Input_file* input_file, off_t offset, + Sized_relobj(const std::string& name, Input_file* input_file, off_t offset, const typename elfcpp::Ehdr<size, big_endian>&); - ~Sized_object(); + ~Sized_relobj(); // Set up the object file based on the ELF header. void @@ -373,7 +397,8 @@ class Sized_object : public Object // Lay out the input sections. void - do_layout(Layout*, Read_symbols_data*); + do_layout(const General_options&, Symbol_table*, Layout*, + Read_symbols_data*); // Finalize the local symbols. off_t @@ -388,6 +413,11 @@ class Sized_object : public Object std::string do_section_name(unsigned int shnum); + // Return a view of the contents of a section. Set *PLEN to the + // size. + const unsigned char* + do_section_contents(unsigned int shnum, off_t* plen); + // Return the appropriate Sized_target structure. Sized_target<size, big_endian>* sized_target() @@ -398,12 +428,8 @@ class Sized_object : public Object } private: - // This object may not be copied. - Sized_object(const Sized_object&); - Sized_object& operator=(const Sized_object&); - // For convenience. - typedef Sized_object<size, big_endian> This; + typedef Sized_relobj<size, big_endian> This; static const int ehdr_size = elfcpp::Elf_sizes<size>::ehdr_size; static const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size; static const int sym_size = elfcpp::Elf_sizes<size>::sym_size; @@ -477,11 +503,16 @@ class Input_objects { public: Input_objects() - : object_list_(), target_(NULL), any_dynamic_(false) + : relobj_list_(), target_(NULL) { } - // The type of the list of input objects. - typedef std::list<Object*> Object_list; + // The type of the list of input relocateable objects. + typedef std::vector<Relobj*> Relobj_list; + typedef Relobj_list::const_iterator Relobj_iterator; + + // The type of the list of input dynamic objects. + typedef std::vector<Dynobj*> Dynobj_list; + typedef Dynobj_list::const_iterator Dynobj_iterator; // Add an object to the list. void @@ -492,27 +523,38 @@ class Input_objects target() const { return this->target_; } - // Iterate over all objects. - Object_list::const_iterator - begin() const - { return this->object_list_.begin(); } + // Iterate over all regular objects. + + Relobj_iterator + relobj_begin() const + { return this->relobj_list_.begin(); } + + Relobj_iterator + relobj_end() const + { return this->relobj_list_.end(); } + + // Iterate over all dynamic objects. + + Dynobj_iterator + dynobj_begin() const + { return this->dynobj_list_.begin(); } - Object_list::const_iterator - end() const - { return this->object_list_.end(); } + Dynobj_iterator + dynobj_end() const + { return this->dynobj_list_.end(); } // Return whether we have seen any dynamic objects. bool any_dynamic() const - { return this->any_dynamic_; } + { return !this->dynobj_list_.empty(); } private: Input_objects(const Input_objects&); Input_objects& operator=(const Input_objects&); - Object_list object_list_; + Relobj_list relobj_list_; + Dynobj_list dynobj_list_; Target* target_; - bool any_dynamic_; }; // Some of the information we pass to the relocation routines. We @@ -528,7 +570,7 @@ struct Relocate_info // Layout. const Layout* layout; // Object being relocated. - Sized_object<size, big_endian>* object; + Sized_relobj<size, big_endian>* object; // Number of local symbols. unsigned int local_symbol_count; // Values of local symbols. |