29 #ifndef COFFI_STRINGS_HPP
30 #define COFFI_STRINGS_HPP
44 coffi_strings() : strings_{0}, strings_reserved_{0} { clean_strings(); }
58 uint32_t get_strings_size()
const
63 return *
reinterpret_cast<uint32_t*
>(strings_);
67 void set_strings_size(uint32_t value)
72 *
reinterpret_cast<uint32_t*
>(strings_) = value;
79 return string_to_name_internal(str,
false);
86 return string_to_name_internal(str,
true);
93 return name_to_string_internal(name, str,
false);
100 return name_to_string_internal(name, str,
true);
104 virtual const char* get_strings()
const {
return strings_; }
107 virtual void set_strings(
const char* str, uint32_t size)
109 char* new_strings =
new char[size];
111 std::copy(str, str + size, new_strings);
113 strings_ = new_strings;
114 strings_reserved_ = size;
115 set_strings_size(size);
127 strings_ =
new char[4];
128 strings_reserved_ = 4;
133 bool load_strings(std::istream& stream,
const coff_header* header)
137 if (header->get_symbol_table_offset() == 0) {
141 uint32_t strings_offset =
142 header->get_symbol_table_offset() +
143 header->get_symbols_count() *
sizeof(symbol_record);
144 stream.seekg(strings_offset);
145 stream.read(strings_, 4);
146 char* new_strings =
new char[get_strings_size()];
150 strings_reserved_ = get_strings_size();
151 stream.seekg(strings_offset);
152 stream.read(new_strings, get_strings_size());
153 if (stream.gcount() !=
154 static_cast<std::streamsize
>(get_strings_size())) {
158 strings_ = new_strings;
163 void save_strings(std::ostream& stream)
const
165 if (strings_ && get_strings_size() > 4) {
166 stream.write(strings_, get_strings_size());
171 virtual std::string string_to_name_internal(
const char* str,
172 bool is_section)
const
176 if (*(uint32_t*)str == 0 && strings_) {
177 uint32_t off = *(uint32_t*)(str +
sizeof(uint32_t));
178 ret = strings_ + off;
180 else if (is_section && str[0] ==
'/') {
181 int32_t off = std::atol(str + 1);
182 ret = strings_ + off;
188 ret = std::string(dst);
196 name_to_string_internal(
const std::string& name,
char* str,
bool is_section)
198 size_t size = name.size();
201 uint32_t offset = get_strings_size();
202 if (get_strings_size() + size > strings_reserved_) {
203 uint32_t new_strings_reserved =
204 2 * (strings_reserved_ + narrow_cast<uint32_t>(size));
205 char* new_strings =
new char[new_strings_reserved];
211 strings_reserved_ = new_strings_reserved;
212 std::copy(strings_, strings_ + get_strings_size(),
215 strings_ = new_strings;
218 std::copy(name.c_str(), name.c_str() + size,
219 strings_ + get_strings_size());
220 set_strings_size(get_strings_size() + narrow_cast<uint32_t>(size));
223 std::string s = std::to_string(offset);
228 *((uint32_t*)str + 1) = offset;
233 std::copy(name.begin(), name.end(), str);
239 uint32_t strings_reserved_;
Class for accessing the strings table.
virtual std::string string_to_name(const char *str) const
Converts an 8-bytes symbol short name into a full name, eventually by looking into the strings table.
coffi_strings(const coffi_strings &)=delete
Discards the copy constructor.
virtual void name_to_string(const std::string &name, char *str)
Converts symbol full name into an 8-bytes short name, eventually creating an entry in the strings tab...
virtual void name_to_section_string(const std::string &name, char *str)
Converts section full name into an 8-bytes short name, eventually creating an entry in the strings ta...
virtual std::string section_string_to_name(const char *str) const
Converts an 8-bytes section short name into a full name, eventually by looking into the strings table...
Interface for accessing to the string table.
#define COFFI_NAME_SIZE
COFF symbol names size.