Commit | Line | Data |
---|---|---|
bae7f79e ILT |
1 | // object.h -- support for an object file for linking in gold -*- C++ -*- |
2 | ||
3 | #ifndef GOLD_OBJECT_H | |
4 | #define GOLD_OBJECT_H | |
5 | ||
14bfc3f5 ILT |
6 | #include <cassert> |
7 | ||
bae7f79e | 8 | #include "elfcpp.h" |
bae7f79e | 9 | #include "fileread.h" |
14bfc3f5 ILT |
10 | #include "target.h" |
11 | #include "symtab.h" | |
bae7f79e ILT |
12 | |
13 | namespace gold | |
14 | { | |
15 | ||
16 | // Data to pass from read_symbols() to add_symbols(). | |
17 | ||
18 | struct Read_symbols_data | |
19 | { | |
20 | // Symbol data. | |
21 | File_view* symbols; | |
22 | // Size of symbol data in bytes. | |
23 | off_t symbols_size; | |
24 | // Symbol names. | |
25 | File_view* symbol_names; | |
26 | // Size of symbol name data in bytes. | |
27 | off_t symbol_names_size; | |
28 | }; | |
29 | ||
30 | // Object is an interface which represents either a 32-bit or a 64-bit | |
14bfc3f5 ILT |
31 | // input object. This can be a regular object file (ET_REL) or a |
32 | // shared object (ET_DYN). The actual instantiations are | |
33 | // Sized_object<32> and Sized_object<64> | |
bae7f79e ILT |
34 | |
35 | class Object | |
36 | { | |
37 | public: | |
38 | // NAME is the name of the object as we would report it to the user | |
39 | // (e.g., libfoo.a(bar.o) if this is in an archive. INPUT_FILE is | |
40 | // used to read the file. OFFSET is the offset within the input | |
41 | // file--0 for a .o or .so file, something else for a .a file. | |
14bfc3f5 ILT |
42 | Object(const std::string& name, Input_file* input_file, bool is_dynamic, |
43 | off_t offset = 0) | |
44 | : name_(name), input_file_(input_file), offset_(offset), | |
45 | is_dynamic_(is_dynamic), target_(NULL) | |
bae7f79e ILT |
46 | { } |
47 | ||
48 | virtual ~Object() | |
49 | { } | |
50 | ||
14bfc3f5 | 51 | // Return the name of the object as we would report it to the tuser. |
bae7f79e ILT |
52 | const std::string& |
53 | name() const | |
54 | { return this->name_; } | |
55 | ||
14bfc3f5 ILT |
56 | // Return whether this is a dynamic object. |
57 | bool | |
58 | is_dynamic() const | |
59 | { return this->is_dynamic_; } | |
60 | ||
bae7f79e ILT |
61 | // Read the symbol and relocation information. |
62 | Read_symbols_data | |
63 | read_symbols() | |
64 | { return this->do_read_symbols(); } | |
65 | ||
66 | // Add symbol information to the global symbol table. | |
67 | void | |
14bfc3f5 ILT |
68 | add_symbols(Symbol_table* symtab, Read_symbols_data rd) |
69 | { this->do_add_symbols(symtab, rd); } | |
70 | ||
71 | // Return the target structure associated with this object. | |
72 | Target* | |
73 | target() | |
74 | { return this->target_; } | |
75 | ||
76 | // Return the sized target structure associated with this object. | |
77 | // This is like the target method but it returns a pointer of | |
78 | // appropriate checked type. | |
79 | template<int size, bool big_endian> | |
80 | Sized_target<size, big_endian>* | |
81 | sized_target(); | |
bae7f79e ILT |
82 | |
83 | protected: | |
84 | // Read the symbols--implemented by child class. | |
85 | virtual Read_symbols_data | |
86 | do_read_symbols() = 0; | |
87 | ||
88 | // Add symbol information to the global symbol table--implemented by | |
89 | // child class. | |
90 | virtual void | |
14bfc3f5 | 91 | do_add_symbols(Symbol_table*, Read_symbols_data) = 0; |
bae7f79e ILT |
92 | |
93 | // Get the file. | |
94 | Input_file* | |
95 | input_file() const | |
96 | { return this->input_file_; } | |
97 | ||
98 | // Get the offset into the file. | |
99 | off_t | |
100 | offset() const | |
101 | { return this->offset_; } | |
102 | ||
103 | // Get a view into the underlying file. | |
104 | const unsigned char* | |
105 | get_view(off_t start, off_t size); | |
106 | ||
14bfc3f5 ILT |
107 | // Set the target. |
108 | void | |
109 | set_target(Target* target) | |
110 | { this->target_ = target; } | |
111 | ||
bae7f79e ILT |
112 | // Read data from the underlying file. |
113 | void | |
114 | read(off_t start, off_t size, void* p); | |
115 | ||
116 | // Get a lasting view into the underlying file. | |
117 | File_view* | |
118 | get_lasting_view(off_t start, off_t size); | |
119 | ||
120 | private: | |
121 | // This class may not be copied. | |
122 | Object(const Object&); | |
123 | Object& operator=(const Object&); | |
124 | ||
125 | // Name of object as printed to use. | |
126 | std::string name_; | |
127 | // For reading the file. | |
128 | Input_file* input_file_; | |
129 | // Offset within the file--0 for an object file, non-0 for an | |
130 | // archive. | |
131 | off_t offset_; | |
14bfc3f5 ILT |
132 | // Whether this is a dynamic object. |
133 | bool is_dynamic_; | |
134 | // Target functions--may be NULL if the target is not known. | |
135 | Target* target_; | |
bae7f79e ILT |
136 | }; |
137 | ||
14bfc3f5 ILT |
138 | // Implement sized_target inline for efficiency. This approach breaks |
139 | // static type checking, but is made safe using asserts. | |
140 | ||
141 | template<int size, bool big_endian> | |
142 | inline Sized_target<size, big_endian>* | |
143 | Object::sized_target() | |
144 | { | |
145 | assert(this->target_->get_size() == size); | |
146 | assert(this->target_->is_big_endian() ? big_endian : !big_endian); | |
147 | return static_cast<Sized_target<size, big_endian>*>(this->target_); | |
148 | } | |
149 | ||
150 | // A regular object file. This is size and endian specific. | |
bae7f79e ILT |
151 | |
152 | template<int size, bool big_endian> | |
153 | class Sized_object : public Object | |
154 | { | |
155 | public: | |
156 | Sized_object(const std::string& name, Input_file* input_file, off_t offset, | |
157 | const typename elfcpp::Ehdr<size, big_endian>&); | |
158 | ||
159 | ~Sized_object(); | |
160 | ||
161 | void | |
162 | setup(const typename elfcpp::Ehdr<size, big_endian>&); | |
163 | ||
164 | Read_symbols_data | |
165 | do_read_symbols(); | |
166 | ||
167 | void | |
14bfc3f5 ILT |
168 | do_add_symbols(Symbol_table*, Read_symbols_data); |
169 | ||
170 | Sized_target<size, big_endian>* | |
171 | sized_target() | |
172 | { return this->Object::sized_target<size, big_endian>(); } | |
bae7f79e ILT |
173 | |
174 | private: | |
175 | // This object may not be copied. | |
176 | Sized_object(const Sized_object&); | |
177 | Sized_object& operator=(const Sized_object&); | |
178 | ||
179 | // ELF file header EI_OSABI field. | |
180 | unsigned char osabi_; | |
181 | // ELF file header EI_ABIVERSION field. | |
182 | unsigned char abiversion_; | |
183 | // ELF file header e_machine field. | |
184 | elfcpp::Elf_Half machine_; | |
185 | // ELF file header e_flags field. | |
186 | unsigned int flags_; | |
bae7f79e ILT |
187 | // File offset of section header table. |
188 | off_t shoff_; | |
189 | // Number of input sections. | |
190 | unsigned int shnum_; | |
191 | // Offset of SHT_STRTAB section holding section names. | |
192 | unsigned int shstrndx_; | |
193 | // Index of SHT_SYMTAB section. | |
194 | unsigned int symtab_shnum_; | |
14bfc3f5 ILT |
195 | // The entries in the symbol table for the external symbols. |
196 | Symbol** symbols_; | |
bae7f79e ILT |
197 | }; |
198 | ||
199 | // Return an Object appropriate for the input file. P is BYTES long, | |
200 | // and holds the ELF header. | |
201 | ||
202 | extern Object* make_elf_object(const std::string& name, Input_file*, | |
203 | off_t offset, const unsigned char* p, | |
204 | off_t bytes); | |
205 | ||
206 | } // end namespace gold | |
207 | ||
208 | #endif // !defined(GOLD_OBJECT_H) |