Commit | Line | Data |
---|---|---|
14bfc3f5 ILT |
1 | // stringpool.h -- a string pool for gold -*- C++ -*- |
2 | ||
3 | #include <string> | |
4 | #include <list> | |
5 | ||
6 | // Stringpool | |
7 | // Manage a pool of unique strings. | |
8 | ||
9 | #ifndef GOLD_STRINGPOOL_H | |
10 | #define GOLD_STRINGPOOL_H | |
11 | ||
12 | namespace gold | |
13 | { | |
14 | ||
61ba1cf9 ILT |
15 | class Output_file; |
16 | ||
14bfc3f5 ILT |
17 | class Stringpool |
18 | { | |
19 | public: | |
f0641a0b ILT |
20 | // The type of a key into the stringpool. A key value will always |
21 | // be the same during any run of the linker. The string pointers | |
22 | // may change when using address space randomization. We use key | |
23 | // values in order to get repeatable runs when the value is inserted | |
24 | // into an unordered hash table. Zero is never a valid key. | |
25 | typedef size_t Key; | |
26 | ||
14bfc3f5 ILT |
27 | Stringpool(); |
28 | ||
29 | ~Stringpool(); | |
30 | ||
31 | // Add a string to the pool. This returns a canonical permanent | |
f0641a0b ILT |
32 | // pointer to the string. If PKEY is not NULL, this sets *PKEY to |
33 | // the key for the string. | |
61ba1cf9 | 34 | const char* |
f0641a0b | 35 | add(const char*, Key* pkey); |
14bfc3f5 | 36 | |
61ba1cf9 | 37 | const char* |
f0641a0b ILT |
38 | add(const std::string& s, Key* pkey) |
39 | { return this->add(s.c_str(), pkey); } | |
14bfc3f5 ILT |
40 | |
41 | // Add the prefix of a string to the pool. | |
61ba1cf9 | 42 | const char* |
f0641a0b | 43 | add(const char *, size_t, Key* pkey); |
61ba1cf9 ILT |
44 | |
45 | // If a string is present, return the canonical string. Otherwise, | |
f0641a0b | 46 | // return NULL. If PKEY is not NULL, set *PKEY to the key. |
61ba1cf9 | 47 | const char* |
f0641a0b | 48 | find(const char*, Key* pkey) const; |
61ba1cf9 ILT |
49 | |
50 | // Turn the stringpool into an ELF strtab: determine the offsets of | |
51 | // all the strings. | |
52 | void | |
53 | set_string_offsets(); | |
54 | ||
f0641a0b | 55 | // Get the offset of a string in an ELF strtab. |
61ba1cf9 ILT |
56 | off_t |
57 | get_offset(const char*) const; | |
58 | ||
59 | off_t | |
60 | get_offset(const std::string& s) const | |
61 | { return this->get_offset(s.c_str()); } | |
62 | ||
63 | // Get the size of the ELF strtab. | |
64 | off_t | |
65 | get_strtab_size() const | |
a3ad94ed ILT |
66 | { |
67 | gold_assert(this->strtab_size_ != 0); | |
68 | return this->strtab_size_; | |
69 | } | |
61ba1cf9 ILT |
70 | |
71 | // Write the strtab into the output file at the specified offset. | |
72 | void | |
73 | write(Output_file*, off_t offset); | |
14bfc3f5 ILT |
74 | |
75 | private: | |
76 | Stringpool(const Stringpool&); | |
77 | Stringpool& operator=(const Stringpool&); | |
78 | ||
61ba1cf9 ILT |
79 | // We store the actual data in a list of these buffers. |
80 | struct Stringdata | |
14bfc3f5 ILT |
81 | { |
82 | // Length of data in buffer. | |
83 | size_t len; | |
84 | // Allocated size of buffer. | |
85 | size_t alc; | |
f0641a0b ILT |
86 | // Buffer index. |
87 | unsigned int index; | |
14bfc3f5 ILT |
88 | // Buffer. |
89 | char data[1]; | |
90 | }; | |
91 | ||
61ba1cf9 ILT |
92 | // Copy a string into the buffers, returning a canonical string. |
93 | const char* | |
f0641a0b | 94 | add_string(const char*, Key*); |
14bfc3f5 ILT |
95 | |
96 | struct Stringpool_hash | |
97 | { | |
98 | size_t | |
99 | operator()(const char*) const; | |
100 | }; | |
101 | ||
102 | struct Stringpool_eq | |
103 | { | |
104 | bool | |
105 | operator()(const char* p1, const char* p2) const | |
106 | { return strcmp(p1, p2) == 0; } | |
107 | }; | |
108 | ||
61ba1cf9 ILT |
109 | // Return whether s1 is a suffix of s2. |
110 | static bool is_suffix(const char* s1, const char* s2); | |
111 | ||
f0641a0b ILT |
112 | // The hash table is a map from string names to a pair of Key and |
113 | // ELF strtab offsets. We only use the offsets if we turn this into | |
114 | // an ELF strtab section. | |
115 | ||
116 | typedef std::pair<Key, off_t> Val; | |
61ba1cf9 | 117 | |
274e99f9 | 118 | #ifdef HAVE_TR1_UNORDERED_SET |
f0641a0b | 119 | typedef Unordered_map<const char*, Val, Stringpool_hash, |
61ba1cf9 | 120 | Stringpool_eq, |
f0641a0b | 121 | std::allocator<std::pair<const char* const, Val> >, |
14bfc3f5 | 122 | true> String_set_type; |
274e99f9 | 123 | #else |
f0641a0b | 124 | typedef Unordered_map<const char*, Val, Stringpool_hash, |
61ba1cf9 | 125 | Stringpool_eq> String_set_type; |
274e99f9 ILT |
126 | #endif |
127 | ||
61ba1cf9 ILT |
128 | // Comparison routine used when sorting into an ELF strtab. |
129 | ||
130 | struct Stringpool_sort_comparison | |
131 | { | |
132 | bool | |
133 | operator()(String_set_type::iterator, | |
134 | String_set_type::iterator) const; | |
135 | }; | |
136 | ||
f0641a0b ILT |
137 | // List of Stringdata structures. |
138 | typedef std::list<Stringdata*> Stringdata_list; | |
139 | ||
140 | // Mapping from const char* to namepool entry. | |
14bfc3f5 | 141 | String_set_type string_set_; |
f0641a0b ILT |
142 | // List of buffers. |
143 | Stringdata_list strings_; | |
144 | // Size of ELF strtab. | |
61ba1cf9 | 145 | off_t strtab_size_; |
f0641a0b ILT |
146 | // Next Stringdata index. |
147 | unsigned int next_index_; | |
14bfc3f5 ILT |
148 | }; |
149 | ||
150 | } // End namespace gold. | |
151 | ||
152 | #endif // !defined(GOLD_STRINGPOOL_H) |