29 #ifndef COFFI_SECTION_HPP
30 #define COFFI_SECTION_HPP
38 #if defined(__has_include) && __has_include(<gsl/narrow>)
40 using gsl::narrow_cast;
43 #define narrow_cast static_cast
58 COFFI_GET_SET_ACCESS_DECL(uint32_t, index);
59 COFFI_GET_SET_ACCESS_DECL(uint32_t, virtual_size);
60 COFFI_GET_SET_ACCESS_DECL(uint32_t, physical_address);
61 COFFI_GET_SET_ACCESS_DECL(uint32_t, virtual_address);
62 COFFI_GET_SET_ACCESS_DECL(uint32_t, data_size);
63 COFFI_GET_SET_ACCESS_DECL(uint32_t, data_offset);
64 COFFI_GET_SET_ACCESS_DECL(uint32_t, reloc_offset);
65 COFFI_GET_SET_ACCESS_DECL(uint32_t, line_num_offset);
66 COFFI_GET_SET_ACCESS_DECL(uint32_t, reloc_count);
67 COFFI_GET_SET_ACCESS_DECL(uint32_t, line_num_count);
68 COFFI_GET_SET_ACCESS_DECL(uint32_t, flags);
69 COFFI_GET_SET_ACCESS_DECL(uint16_t, page_number);
70 COFFI_GET_SET_ACCESS_DECL(uint32_t, alignment);
72 COFFI_GET_SIZEOF_DECL();
75 virtual const std::string& get_name()
const = 0;
76 virtual void set_name(
const std::string& name) = 0;
77 virtual const char* get_data()
const = 0;
78 virtual void set_data(
const char* data, uint32_t size) = 0;
79 virtual void set_data(
const std::string& data) = 0;
80 virtual void append_data(
const char* data, uint32_t size) = 0;
81 virtual void append_data(
const std::string& data) = 0;
84 virtual bool load(std::istream& stream, std::streampos header_offset) = 0;
85 virtual void save_header(std::ostream& stream) = 0;
86 virtual void save_data(std::ostream& stream) = 0;
87 virtual void save_relocations(std::ostream& stream) = 0;
88 virtual uint32_t get_relocations_filesize() = 0;
89 virtual void save_line_numbers(std::ostream& stream) = 0;
90 virtual uint32_t get_line_numbers_filesize() = 0;
93 virtual const std::vector<relocation>& get_relocations()
const = 0;
111 std::fill_n(
reinterpret_cast<char*
>(&header),
sizeof(header),
'\0');
130 COFFI_GET_SET_ACCESS(uint32_t, virtual_address);
131 COFFI_GET_SET_ACCESS(uint32_t, data_offset);
132 COFFI_GET_SET_ACCESS(uint32_t, reloc_offset);
133 COFFI_GET_SET_ACCESS(uint32_t, reloc_count);
134 COFFI_GET_SET_ACCESS(uint32_t, line_num_count);
135 COFFI_GET_SET_ACCESS(uint32_t, flags);
141 uint32_t get_index()
const {
return index; }
144 void set_index(uint32_t value) { index = value; }
147 const std::string& get_name()
const {
return name; }
150 void set_name(
const std::string& value)
156 const char* get_data()
const {
return data_; }
159 void set_data(
const char* data, uint32_t size)
166 data_ =
new char[size];
168 data_reserved_ = size;
169 std::copy(data, data + size, data_);
175 set_data_size(data_reserved_);
179 void set_data(
const std::string& data)
181 set_data(data.c_str(), (uint32_t)data.size());
185 virtual void append_data(
const char* data, uint32_t size)
188 set_data(data, size);
190 if (get_data_size() + size <= data_reserved_) {
191 std::copy(data, data + size, data_ + get_data_size());
194 uint32_t new_data_size = 2 * (data_reserved_ + size);
195 char* new_data =
new char[new_data_size];
200 data_reserved_ = new_data_size;
201 std::copy(data_, data_ + get_data_size(), new_data);
202 std::copy(data, data + size, new_data + get_data_size());
207 set_data_size(get_data_size() + size);
211 virtual void append_data(
const std::string& data)
213 append_data(data.c_str(), (uint32_t)data.size());
217 virtual const std::vector<relocation>& get_relocations()
const
223 virtual void add_relocation_entry(
const rel_entry_generic* entry)
225 relocation r{stn_, sym_, arch_};
226 r.set_type(entry->type);
227 r.set_virtual_address(entry->virtual_address);
228 r.set_symbol(entry->symbol_table_index);
229 relocations.push_back(r);
230 set_reloc_count(narrow_cast<uint32_t>(relocations.size()));
234 bool load(std::istream& stream, std::streampos header_offset)
236 std::fill_n(
reinterpret_cast<char*
>(&header),
sizeof(header),
'\0');
237 stream.seekg(header_offset);
238 stream.read(
reinterpret_cast<char*
>(&header),
sizeof(header));
244 ((get_flags() & CEVA_UNINITIALIZED_DATA) ==
245 CEVA_UNINITIALIZED_DATA);
247 data_reserved_ = get_data_size();
248 if ((get_data_offset() != 0) && (data_reserved_ != 0)) {
249 data_ =
new char[data_reserved_];
253 stream.seekg(get_data_offset());
254 stream.read(data_, data_reserved_);
259 if (get_reloc_count() != 0) {
260 stream.seekg(get_reloc_offset());
261 for (uint32_t i = 0; i < get_reloc_count(); ++i) {
262 relocation rel{stn_, sym_, arch_};
264 relocations.push_back(rel);
269 if (get_line_num_count() != 0) {
270 stream.seekg(get_line_num_offset());
271 for (uint32_t i = 0; i < get_line_num_count(); ++i) {
273 stream.read(
reinterpret_cast<char*
>(&lnum),
274 sizeof(line_number));
275 line_numbers.push_back(lnum);
282 virtual void save_header(std::ostream& stream)
284 stream.write(
reinterpret_cast<char*
>(&header),
sizeof(header));
288 virtual void save_data(std::ostream& stream)
290 if (!data_ || get_data_offset() == 0) {
293 stream.write(data_, get_data_size());
297 virtual void save_relocations(std::ostream& stream)
299 for (
auto entry : relocations) {
305 virtual uint32_t get_relocations_filesize()
307 relocation rel{stn_, sym_, arch_};
308 return rel.get_sizeof() * narrow_cast<uint32_t>(relocations.size());
312 virtual void save_line_numbers(std::ostream& stream)
314 for (
auto lnum : line_numbers) {
315 stream.write(
reinterpret_cast<char*
>(&lnum),
sizeof(line_number));
320 virtual uint32_t get_line_numbers_filesize()
322 return sizeof(line_number) * narrow_cast<uint32_t>(line_numbers.size());
338 uint32_t get_bit_number(uint32_t v)
347 for (uint32_t i = 0; i < 32; i++) {
360 uint32_t data_reserved_;
361 string_to_name_provider* stn_;
362 symbol_provider* sym_;
363 architecture_provider* arch_;
365 std::vector<relocation> relocations;
366 std::vector<line_number> line_numbers;
383 COFFI_GET_SET_ACCESS(uint32_t, virtual_size);
384 COFFI_GET_SET_ACCESS(uint32_t, data_size);
385 COFFI_GET_SET_ACCESS_NONE(uint32_t, physical_address);
386 COFFI_GET_SET_ACCESS(uint32_t, line_num_offset);
387 COFFI_GET_SET_ACCESS_NONE(uint16_t, page_number);
391 uint32_t get_alignment()
const
393 return 1 << (((get_flags() >> 20) & 0xF) - 1);
397 void set_alignment(uint32_t value)
399 set_flags((get_flags() & ~0xF00000) |
400 ((get_bit_number(value) & 0xF) << 20));
418 COFFI_GET_SET_ACCESS_NONE(uint32_t, virtual_size);
419 COFFI_GET_SET_ACCESS(uint32_t, physical_address);
420 COFFI_GET_SET_ACCESS_NONE(uint32_t, line_num_offset);
421 COFFI_GET_SET_ACCESS(uint16_t, page_number);
425 uint32_t get_data_size()
const
427 auto sec_type = get_flags() & 0x1F;
428 bool is_allocated = (sec_type == STYP_REG) || (sec_type == STYP_NOLOAD);
430 return header.data_size * arch_->get_addressable_unit();
433 return header.data_size;
438 void set_data_size(uint32_t value)
440 auto sec_type = get_flags() & 0x1F;
441 bool is_allocated = (sec_type == STYP_REG) || (sec_type == STYP_NOLOAD);
443 header.data_size = value / arch_->get_addressable_unit();
446 header.data_size = value;
451 uint32_t get_alignment()
const {
return 1 << ((get_flags() >> 8) & 0xF); }
454 void set_alignment(uint32_t value)
456 set_flags((get_flags() & ~0xF00) |
457 ((get_bit_number(value) & 0xF) << 8));
484 for (
auto sec : *
this) {
498 return std::vector<section*>::operator[](i);
506 return std::vector<section*>::operator[](i);
526 if (sec->get_name() == name) {
Interface for architecture information.
virtual coffi_architecture_t get_architecture() const =0
Returns the coffi object architecture.
Class for accessing a COFF section, for the Texas Instruments format.
Template class for accessing a COFF section, depends on the underlying section header format.
section_impl_tmpl(const section_impl_tmpl &)=delete
Discards the copy constructor.
Class for accessing a COFF section, for the PE format.
Interface class for accessing a COFF section, for all the COFF architectures.
const section * operator[](size_t i) const
Subscript operator, finds a section by its index.
const section * operator[](const std::string &name) const
Subscript operator, finds a section by its symbolic name.
section * operator[](const std::string &name)
Subscript operator, finds a section by its symbolic name.
section * operator[](size_t i)
Subscript operator, finds a section by its index.
sections(const sections &)=delete
Discards the copy constructor.
Interface for accessing to the string table.
virtual void name_to_section_string(const std::string &name, char *str)=0
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 =0
Converts an 8-bytes section short name into a full name, eventually by looking into the strings table...
Interface for accessing to the symbol table.
COFFI library classes for the COFF relocation entries.
@ COFFI_ARCHITECTURE_CEVA
CEVA Inc.
Structure capable of storing all the architecture-specific relocation entry structures.