]>
Commit | Line | Data |
---|---|---|
f6ce93d6 ILT |
1 | // dynobj.h -- dynamic object support for gold -*- C++ -*- |
2 | ||
3 | #ifndef GOLD_DYNOBJ_H | |
4 | #define GOLD_DYNOBJ_H | |
5 | ||
dbe717ef ILT |
6 | #include <vector> |
7 | ||
f6ce93d6 ILT |
8 | #include "object.h" |
9 | ||
10 | namespace gold | |
11 | { | |
12 | ||
13 | // A dynamic object (ET_DYN). This is an abstract base class itself. | |
14 | // The implementations is the template class Sized_dynobj. | |
15 | ||
16 | class Dynobj : public Object | |
17 | { | |
18 | public: | |
19 | Dynobj(const std::string& name, Input_file* input_file, off_t offset = 0) | |
a3ad94ed | 20 | : Object(name, input_file, true, offset), soname_() |
f6ce93d6 | 21 | { } |
a3ad94ed ILT |
22 | |
23 | // Return the name to use in a DT_NEEDED entry for this object. | |
24 | const char* | |
25 | soname() const; | |
26 | ||
27 | // Create a standard ELF hash table, setting *PPHASH and *PHASHLEN. | |
28 | // DYNSYMS is the global dynamic symbols. LOCAL_DYNSYM_COUNT is the | |
29 | // number of local dynamic symbols, which is the index of the first | |
30 | // dynamic gobal symbol. | |
31 | static void | |
32 | create_elf_hash_table(const Target*, const std::vector<Symbol*>& dynsyms, | |
33 | unsigned int local_dynsym_count, | |
34 | unsigned char** pphash, | |
35 | unsigned int* phashlen); | |
36 | ||
37 | // Create a GNU hash table, setting *PPHASH and *PHASHLEN. DYNSYMS | |
38 | // is the global dynamic symbols. LOCAL_DYNSYM_COUNT is the number | |
39 | // of local dynamic symbols, which is the index of the first dynamic | |
40 | // gobal symbol. | |
41 | static void | |
42 | create_gnu_hash_table(const Target*, const std::vector<Symbol*>& dynsyms, | |
43 | unsigned int local_dynsym_count, | |
44 | unsigned char** pphash, unsigned int* phashlen); | |
45 | ||
46 | protected: | |
47 | // Set the DT_SONAME string. | |
48 | void | |
49 | set_soname_string(const char* s) | |
50 | { this->soname_.assign(s); } | |
51 | ||
52 | private: | |
53 | // Compute the ELF hash code for a string. | |
54 | static uint32_t | |
55 | elf_hash(const char*); | |
56 | ||
57 | // Compute the GNU hash code for a string. | |
58 | static uint32_t | |
59 | gnu_hash(const char*); | |
60 | ||
61 | // Compute the number of hash buckets to use. | |
62 | static unsigned int | |
63 | compute_bucket_count(const std::vector<uint32_t>& hashcodes, | |
64 | bool for_gnu_hash_table); | |
65 | ||
66 | // Sized version of create_elf_hash_table. | |
67 | template<bool big_endian> | |
68 | static void | |
69 | sized_create_elf_hash_table(const std::vector<uint32_t>& bucket, | |
70 | const std::vector<uint32_t>& chain, | |
71 | unsigned char* phash, | |
72 | unsigned int hashlen); | |
73 | ||
74 | // Sized version of create_gnu_hash_table. | |
75 | template<int size, bool big_endian> | |
76 | static void | |
77 | sized_create_gnu_hash_table(const std::vector<Symbol*>& hashed_dynsyms, | |
78 | const std::vector<uint32_t>& dynsym_hashvals, | |
79 | unsigned int unhashed_dynsym_count, | |
80 | unsigned char** pphash, | |
81 | unsigned int* phashlen); | |
82 | ||
83 | // The DT_SONAME name, if any. | |
84 | std::string soname_; | |
f6ce93d6 ILT |
85 | }; |
86 | ||
87 | // A dynamic object, size and endian specific version. | |
88 | ||
89 | template<int size, bool big_endian> | |
90 | class Sized_dynobj : public Dynobj | |
91 | { | |
92 | public: | |
93 | Sized_dynobj(const std::string& name, Input_file* input_file, off_t offset, | |
94 | const typename elfcpp::Ehdr<size, big_endian>&); | |
95 | ||
dbe717ef ILT |
96 | // Set up the object file based on the ELF header. |
97 | void | |
98 | setup(const typename elfcpp::Ehdr<size, big_endian>&); | |
99 | ||
f6ce93d6 ILT |
100 | // Read the symbols. |
101 | void | |
102 | do_read_symbols(Read_symbols_data*); | |
103 | ||
104 | // Lay out the input sections. | |
105 | void | |
106 | do_layout(const General_options&, Symbol_table*, Layout*, | |
107 | Read_symbols_data*); | |
108 | ||
109 | // Add the symbols to the symbol table. | |
110 | void | |
111 | do_add_symbols(Symbol_table*, Read_symbols_data*); | |
112 | ||
dbe717ef ILT |
113 | // Get the name of a section. |
114 | std::string | |
115 | do_section_name(unsigned int shndx) | |
116 | { return this->elf_file_.section_name(shndx); } | |
117 | ||
f6ce93d6 ILT |
118 | // Return a view of the contents of a section. Set *PLEN to the |
119 | // size. | |
dbe717ef ILT |
120 | Object::Location |
121 | do_section_contents(unsigned int shndx) | |
122 | { return this->elf_file_.section_contents(shndx); } | |
f6ce93d6 | 123 | |
a3ad94ed ILT |
124 | // Return section flags. |
125 | uint64_t | |
126 | do_section_flags(unsigned int shndx) | |
127 | { return this->elf_file_.section_flags(shndx); } | |
128 | ||
dbe717ef ILT |
129 | private: |
130 | // For convenience. | |
131 | typedef Sized_dynobj<size, big_endian> This; | |
132 | static const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size; | |
133 | static const int sym_size = elfcpp::Elf_sizes<size>::sym_size; | |
134 | static const int dyn_size = elfcpp::Elf_sizes<size>::dyn_size; | |
135 | typedef elfcpp::Shdr<size, big_endian> Shdr; | |
136 | typedef elfcpp::Dyn<size, big_endian> Dyn; | |
137 | ||
138 | // Find the dynamic symbol table and the version sections, given the | |
139 | // section headers. | |
140 | void | |
141 | find_dynsym_sections(const unsigned char* pshdrs, | |
142 | unsigned int* pdynshm_shndx, | |
143 | unsigned int* pversym_shndx, | |
144 | unsigned int* pverdef_shndx, | |
145 | unsigned int* pverneed_shndx, | |
146 | unsigned int* pdynamic_shndx); | |
147 | ||
148 | // Read the dynamic symbol section SHNDX. | |
149 | void | |
150 | read_dynsym_section(const unsigned char* pshdrs, unsigned int shndx, | |
151 | elfcpp::SHT type, unsigned int link, | |
152 | File_view** view, off_t* view_size, | |
153 | unsigned int* view_info); | |
154 | ||
155 | // Set the SONAME from the SHT_DYNAMIC section at DYNAMIC_SHNDX. | |
156 | // The STRTAB parameters may have the relevant string table. | |
157 | void | |
158 | set_soname(const unsigned char* pshdrs, unsigned int dynamic_shndx, | |
159 | unsigned int strtab_shndx, const unsigned char* strtabu, | |
160 | off_t strtab_size); | |
161 | ||
162 | // Mapping from version number to version name. | |
163 | typedef std::vector<const char*> Version_map; | |
164 | ||
165 | // Create the version map. | |
166 | void | |
167 | make_version_map(Read_symbols_data* sd, Version_map*) const; | |
168 | ||
169 | // Add an entry to the version map. | |
170 | void | |
171 | set_version_map(Version_map*, unsigned int ndx, const char* name) const; | |
172 | ||
173 | // General access to the ELF file. | |
174 | elfcpp::Elf_file<size, big_endian, Object> elf_file_; | |
f6ce93d6 ILT |
175 | }; |
176 | ||
177 | } // End namespace gold. | |
178 | ||
179 | #endif // !defined(GOLD_DYNOBJ_H) |