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 | |
66 | { return this->strtab_size_; } | |
67 | ||
68 | // Write the strtab into the output file at the specified offset. | |
69 | void | |
70 | write(Output_file*, off_t offset); | |
14bfc3f5 ILT |
71 | |
72 | private: | |
73 | Stringpool(const Stringpool&); | |
74 | Stringpool& operator=(const Stringpool&); | |
75 | ||
61ba1cf9 ILT |
76 | // We store the actual data in a list of these buffers. |
77 | struct Stringdata | |
14bfc3f5 ILT |
78 | { |
79 | // Length of data in buffer. | |
80 | size_t len; | |
81 | // Allocated size of buffer. | |
82 | size_t alc; | |
f0641a0b ILT |
83 | // Buffer index. |
84 | unsigned int index; | |
14bfc3f5 ILT |
85 | // Buffer. |
86 | char data[1]; | |
87 | }; | |
88 | ||
61ba1cf9 ILT |
89 | // Copy a string into the buffers, returning a canonical string. |
90 | const char* | |
f0641a0b | 91 | add_string(const char*, Key*); |
14bfc3f5 ILT |
92 | |
93 | struct Stringpool_hash | |
94 | { | |
95 | size_t | |
96 | operator()(const char*) const; | |
97 | }; | |
98 | ||
99 | struct Stringpool_eq | |
100 | { | |
101 | bool | |
102 | operator()(const char* p1, const char* p2) const | |
103 | { return strcmp(p1, p2) == 0; } | |
104 | }; | |
105 | ||
61ba1cf9 ILT |
106 | // Return whether s1 is a suffix of s2. |
107 | static bool is_suffix(const char* s1, const char* s2); | |
108 | ||
f0641a0b ILT |
109 | // The hash table is a map from string names to a pair of Key and |
110 | // ELF strtab offsets. We only use the offsets if we turn this into | |
111 | // an ELF strtab section. | |
112 | ||
113 | typedef std::pair<Key, off_t> Val; | |
61ba1cf9 | 114 | |
274e99f9 | 115 | #ifdef HAVE_TR1_UNORDERED_SET |
f0641a0b | 116 | typedef Unordered_map<const char*, Val, Stringpool_hash, |
61ba1cf9 | 117 | Stringpool_eq, |
f0641a0b | 118 | std::allocator<std::pair<const char* const, Val> >, |
14bfc3f5 | 119 | true> String_set_type; |
274e99f9 | 120 | #else |
f0641a0b | 121 | typedef Unordered_map<const char*, Val, Stringpool_hash, |
61ba1cf9 | 122 | Stringpool_eq> String_set_type; |
274e99f9 ILT |
123 | #endif |
124 | ||
61ba1cf9 ILT |
125 | // Comparison routine used when sorting into an ELF strtab. |
126 | ||
127 | struct Stringpool_sort_comparison | |
128 | { | |
129 | bool | |
130 | operator()(String_set_type::iterator, | |
131 | String_set_type::iterator) const; | |
132 | }; | |
133 | ||
f0641a0b ILT |
134 | // List of Stringdata structures. |
135 | typedef std::list<Stringdata*> Stringdata_list; | |
136 | ||
137 | // Mapping from const char* to namepool entry. | |
14bfc3f5 | 138 | String_set_type string_set_; |
f0641a0b ILT |
139 | // List of buffers. |
140 | Stringdata_list strings_; | |
141 | // Size of ELF strtab. | |
61ba1cf9 | 142 | off_t strtab_size_; |
f0641a0b ILT |
143 | // Next Stringdata index. |
144 | unsigned int next_index_; | |
14bfc3f5 ILT |
145 | }; |
146 | ||
147 | } // End namespace gold. | |
148 | ||
149 | #endif // !defined(GOLD_STRINGPOOL_H) |