HIP: Heterogenous-computing Interface for Portability
elfio.hpp
1 /*
2 Copyright (C) 2001-2015 by Serge Lamikhov-Center
3 
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.
21 */
22 
23 #ifndef ELFIO_HPP
24 #define ELFIO_HPP
25 
26 #ifdef _MSC_VER
27 #pragma warning(push)
28 #pragma warning(disable : 4996)
29 #pragma warning(disable : 4355)
30 #pragma warning(disable : 4244)
31 #endif
32 
33 #include <string>
34 #include <iostream>
35 #include <fstream>
36 #include <algorithm>
37 #include <vector>
38 #include <deque>
39 #include <iterator>
40 #include <typeinfo>
41 
42 #include "elf_types.hpp"
43 #include "elfio_utils.hpp"
44 #include "elfio_header.hpp"
45 #include "elfio_section.hpp"
46 #include "elfio_segment.hpp"
47 #include "elfio_strings.hpp"
48 
49 #define ELFIO_HEADER_ACCESS_GET(TYPE, FNAME) \
50  TYPE get_##FNAME() const { return header->get_##FNAME(); }
51 
52 #define ELFIO_HEADER_ACCESS_GET_SET(TYPE, FNAME) \
53  TYPE get_##FNAME() const { return header->get_##FNAME(); } \
54  void set_##FNAME(TYPE val) { header->set_##FNAME(val); }
55 
56 namespace ELFIO {
57 
58 //------------------------------------------------------------------------------
59 class elfio {
60  public:
61  //------------------------------------------------------------------------------
62  elfio() : sections(this), segments(this) {
63  header = 0;
64  current_file_pos = 0;
65  create(ELFCLASS32, ELFDATA2LSB);
66  }
67 
68  //------------------------------------------------------------------------------
69  ~elfio() { clean(); }
70 
71  //------------------------------------------------------------------------------
72  void create(unsigned char file_class, unsigned char encoding) {
73  clean();
74  convertor.setup(encoding);
75  header = create_header(file_class, encoding);
76  create_mandatory_sections();
77  }
78 
79  //------------------------------------------------------------------------------
80  bool load(const std::string& file_name) {
81  std::ifstream stream;
82  stream.open(file_name.c_str(), std::ios::in | std::ios::binary);
83  if (!stream) {
84  return false;
85  }
86 
87  return load(stream);
88  }
89 
90  //------------------------------------------------------------------------------
91  bool load(std::istream& stream) {
92  clean();
93 
94  unsigned char e_ident[EI_NIDENT];
95 
96  // Read ELF file signature
97  stream.seekg(0);
98  stream.read(reinterpret_cast<char*>(&e_ident), sizeof(e_ident));
99 
100  // Is it ELF file?
101  if (stream.gcount() != sizeof(e_ident) || e_ident[EI_MAG0] != ELFMAG0 ||
102  e_ident[EI_MAG1] != ELFMAG1 || e_ident[EI_MAG2] != ELFMAG2 ||
103  e_ident[EI_MAG3] != ELFMAG3) {
104  return false;
105  }
106 
107  if ((e_ident[EI_CLASS] != ELFCLASS64) && (e_ident[EI_CLASS] != ELFCLASS32)) {
108  return false;
109  }
110 
111  convertor.setup(e_ident[EI_DATA]);
112 
113  header = create_header(e_ident[EI_CLASS], e_ident[EI_DATA]);
114  if (0 == header) {
115  return false;
116  }
117  if (!header->load(stream)) {
118  return false;
119  }
120 
121  load_sections(stream);
122  load_segments(stream);
123 
124  return true;
125  }
126 
127  //------------------------------------------------------------------------------
128  bool save(const std::string& file_name) {
129  std::ofstream f(file_name.c_str(), std::ios::out | std::ios::binary);
130 
131  if (!f) {
132  return false;
133  }
134 
135  bool is_still_good = true;
136 
137  // Define layout specific header fields
138  // The position of the segment table is fixed after the header.
139  // The position of the section table is variable and needs to be fixed
140  // before saving.
141  header->set_segments_num(segments.size());
142  header->set_segments_offset(segments.size() ? header->get_header_size() : 0);
143  header->set_sections_num(sections.size());
144  header->set_sections_offset(0);
145 
146  // Layout the first section right after the segment table
147  current_file_pos = header->get_header_size() +
148  header->get_segment_entry_size() * header->get_segments_num();
149 
150  is_still_good = layout_segments_and_their_sections();
151  is_still_good = is_still_good && layout_sections_without_segments();
152  is_still_good = is_still_good && layout_section_table();
153 
154  is_still_good = is_still_good && save_header(f);
155  is_still_good = is_still_good && save_sections(f);
156  is_still_good = is_still_good && save_segments(f);
157 
158  f.close();
159 
160  return is_still_good;
161  }
162 
163  //------------------------------------------------------------------------------
164  // ELF header access functions
165  ELFIO_HEADER_ACCESS_GET(unsigned char, class);
166  ELFIO_HEADER_ACCESS_GET(unsigned char, elf_version);
167  ELFIO_HEADER_ACCESS_GET(unsigned char, encoding);
168  ELFIO_HEADER_ACCESS_GET(Elf_Word, version);
169  ELFIO_HEADER_ACCESS_GET(Elf_Half, header_size);
170  ELFIO_HEADER_ACCESS_GET(Elf_Half, section_entry_size);
171  ELFIO_HEADER_ACCESS_GET(Elf_Half, segment_entry_size);
172 
173  ELFIO_HEADER_ACCESS_GET_SET(unsigned char, os_abi);
174  ELFIO_HEADER_ACCESS_GET_SET(unsigned char, abi_version);
175  ELFIO_HEADER_ACCESS_GET_SET(Elf_Half, type);
176  ELFIO_HEADER_ACCESS_GET_SET(Elf_Half, machine);
177  ELFIO_HEADER_ACCESS_GET_SET(Elf_Word, flags);
178  ELFIO_HEADER_ACCESS_GET_SET(Elf64_Addr, entry);
179  ELFIO_HEADER_ACCESS_GET_SET(Elf64_Off, sections_offset);
180  ELFIO_HEADER_ACCESS_GET_SET(Elf64_Off, segments_offset);
181  ELFIO_HEADER_ACCESS_GET_SET(Elf_Half, section_name_str_index);
182 
183  //------------------------------------------------------------------------------
184  const endianess_convertor& get_convertor() const { return convertor; }
185 
186  //------------------------------------------------------------------------------
187  Elf_Xword get_default_entry_size(Elf_Word section_type) const {
188  switch (section_type) {
189  case SHT_RELA:
190  if (header->get_class() == ELFCLASS64) {
191  return sizeof(Elf64_Rela);
192  } else {
193  return sizeof(Elf32_Rela);
194  }
195  case SHT_REL:
196  if (header->get_class() == ELFCLASS64) {
197  return sizeof(Elf64_Rel);
198  } else {
199  return sizeof(Elf32_Rel);
200  }
201  case SHT_SYMTAB:
202  if (header->get_class() == ELFCLASS64) {
203  return sizeof(Elf64_Sym);
204  } else {
205  return sizeof(Elf32_Sym);
206  }
207  case SHT_DYNAMIC:
208  if (header->get_class() == ELFCLASS64) {
209  return sizeof(Elf64_Dyn);
210  } else {
211  return sizeof(Elf32_Dyn);
212  }
213  default:
214  return 0;
215  }
216  }
217 
218  //------------------------------------------------------------------------------
219  private:
220  //------------------------------------------------------------------------------
221  void clean() {
222  delete header;
223  header = 0;
224 
225  std::vector<section*>::const_iterator it;
226  for (it = sections_.begin(); it != sections_.end(); ++it) {
227  delete *it;
228  }
229  sections_.clear();
230 
231  std::vector<segment*>::const_iterator it1;
232  for (it1 = segments_.begin(); it1 != segments_.end(); ++it1) {
233  delete *it1;
234  }
235  segments_.clear();
236  }
237 
238  //------------------------------------------------------------------------------
239  elf_header* create_header(unsigned char file_class, unsigned char encoding) {
240  elf_header* new_header = 0;
241 
242  if (file_class == ELFCLASS64) {
243  new_header = new elf_header_impl<Elf64_Ehdr>(&convertor, encoding);
244  } else if (file_class == ELFCLASS32) {
245  new_header = new elf_header_impl<Elf32_Ehdr>(&convertor, encoding);
246  } else {
247  return 0;
248  }
249 
250  return new_header;
251  }
252 
253  //------------------------------------------------------------------------------
254  section* create_section() {
255  section* new_section;
256  unsigned char file_class = get_class();
257 
258  if (file_class == ELFCLASS64) {
259  new_section = new section_impl<Elf64_Shdr>(&convertor);
260  } else if (file_class == ELFCLASS32) {
261  new_section = new section_impl<Elf32_Shdr>(&convertor);
262  } else {
263  return 0;
264  }
265 
266  new_section->set_index((Elf_Half)sections_.size());
267  sections_.push_back(new_section);
268 
269  return new_section;
270  }
271 
272 
273  //------------------------------------------------------------------------------
274  segment* create_segment() {
275  segment* new_segment;
276  unsigned char file_class = header->get_class();
277 
278  if (file_class == ELFCLASS64) {
279  new_segment = new segment_impl<Elf64_Phdr>(&convertor);
280  } else if (file_class == ELFCLASS32) {
281  new_segment = new segment_impl<Elf32_Phdr>(&convertor);
282  } else {
283  return 0;
284  }
285 
286  new_segment->set_index((Elf_Half)segments_.size());
287  segments_.push_back(new_segment);
288 
289  return new_segment;
290  }
291 
292  //------------------------------------------------------------------------------
293  void create_mandatory_sections() {
294  // Create null section without calling to 'add_section' as no string
295  // section containing section names exists yet
296  section* sec0 = create_section();
297  sec0->set_index(0);
298  sec0->set_name("");
299  sec0->set_name_string_offset(0);
300 
301  set_section_name_str_index(1);
302  section* shstrtab = sections.add(".shstrtab");
303  shstrtab->set_type(SHT_STRTAB);
304  shstrtab->set_addr_align(1);
305  }
306 
307  //------------------------------------------------------------------------------
308  Elf_Half load_sections(std::istream& stream) {
309  Elf_Half entry_size = header->get_section_entry_size();
310  Elf_Half num = header->get_sections_num();
311  Elf64_Off offset = header->get_sections_offset();
312 
313  for (Elf_Half i = 0; i < num; ++i) {
314  section* sec = create_section();
315  sec->load(stream, (std::streamoff)offset + i * entry_size);
316  sec->set_index(i);
317  // To mark that the section is not permitted to reassign address
318  // during layout calculation
319  sec->set_address(sec->get_address());
320  }
321 
322  Elf_Half shstrndx = get_section_name_str_index();
323 
324  if (SHN_UNDEF != shstrndx) {
325  string_section_accessor str_reader(sections[shstrndx]);
326  for (Elf_Half i = 0; i < num; ++i) {
327  Elf_Word offset = sections[i]->get_name_string_offset();
328  const char* p = str_reader.get_string(offset);
329  if (p != 0) {
330  sections[i]->set_name(p);
331  }
332  }
333  }
334 
335  return num;
336  }
337 
338  //------------------------------------------------------------------------------
339  bool load_segments(std::istream& stream) {
340  Elf_Half entry_size = header->get_segment_entry_size();
341  Elf_Half num = header->get_segments_num();
342  Elf64_Off offset = header->get_segments_offset();
343 
344  for (Elf_Half i = 0; i < num; ++i) {
345  segment* seg;
346  unsigned char file_class = header->get_class();
347 
348  if (file_class == ELFCLASS64) {
349  seg = new segment_impl<Elf64_Phdr>(&convertor);
350  } else if (file_class == ELFCLASS32) {
351  seg = new segment_impl<Elf32_Phdr>(&convertor);
352  } else {
353  return false;
354  }
355 
356  seg->load(stream, (std::streamoff)offset + i * entry_size);
357  seg->set_index(i);
358 
359  // Add sections to the segments (similar to readelfs algorithm)
360  Elf64_Off segBaseOffset = seg->get_offset();
361  Elf64_Off segEndOffset = segBaseOffset + seg->get_file_size();
362  Elf64_Off segVBaseAddr = seg->get_virtual_address();
363  Elf64_Off segVEndAddr = segVBaseAddr + seg->get_memory_size();
364  for (Elf_Half j = 0; j < sections.size(); ++j) {
365  const section* psec = sections[j];
366 
367  // SHF_ALLOC sections are matched based on the virtual address
368  // otherwise the file offset is matched
369  if (psec->get_flags() & SHF_ALLOC
370  ? (segVBaseAddr <= psec->get_address() &&
371  psec->get_address() + psec->get_size() <= segVEndAddr)
372  : (segBaseOffset <= psec->get_offset() &&
373  psec->get_offset() + psec->get_size() <= segEndOffset)) {
374  seg->add_section_index(psec->get_index(), psec->get_addr_align());
375  }
376  }
377 
378  // Add section into the segments' container
379  segments_.push_back(seg);
380  }
381 
382  return true;
383  }
384 
385  //------------------------------------------------------------------------------
386  bool save_header(std::ofstream& f) { return header->save(f); }
387 
388  //------------------------------------------------------------------------------
389  bool save_sections(std::ofstream& f) {
390  for (unsigned int i = 0; i < sections_.size(); ++i) {
391  section* sec = sections_.at(i);
392 
393  std::streampos headerPosition = (std::streamoff)header->get_sections_offset() +
394  header->get_section_entry_size() * sec->get_index();
395 
396  sec->save(f, headerPosition, sec->get_offset());
397  }
398  return true;
399  }
400 
401  //------------------------------------------------------------------------------
402  bool save_segments(std::ofstream& f) {
403  for (unsigned int i = 0; i < segments_.size(); ++i) {
404  segment* seg = segments_.at(i);
405 
406  std::streampos headerPosition =
407  header->get_segments_offset() + header->get_segment_entry_size() * seg->get_index();
408 
409  seg->save(f, headerPosition, seg->get_offset());
410  }
411  return true;
412  }
413 
414  //------------------------------------------------------------------------------
415  bool is_section_without_segment(unsigned int section_index) {
416  bool found = false;
417 
418  for (unsigned int j = 0; !found && (j < segments.size()); ++j) {
419  for (unsigned int k = 0; !found && (k < segments[j]->get_sections_num()); ++k) {
420  found = segments[j]->get_section_index_at(k) == section_index;
421  }
422  }
423 
424  return !found;
425  }
426 
427  //------------------------------------------------------------------------------
428  bool is_subsequence_of(segment* seg1, segment* seg2) {
429  // Return 'true' if sections of seg1 are a subset of sections in seg2
430  const std::vector<Elf_Half>& sections1 = seg1->get_sections();
431  const std::vector<Elf_Half>& sections2 = seg2->get_sections();
432 
433  bool found = false;
434  if (sections1.size() < sections2.size()) {
435  found = std::includes(sections2.begin(), sections2.end(), sections1.begin(),
436  sections1.end());
437  }
438 
439  return found;
440  }
441 
442  //------------------------------------------------------------------------------
443  std::vector<segment*> get_ordered_segments() {
444  std::vector<segment*> res;
445  std::deque<segment*> worklist;
446 
447  res.reserve(segments.size());
448  std::copy(segments_.begin(), segments_.end(), std::back_inserter(worklist));
449 
450  // Bring the segments which start at address 0 to the front
451  size_t nextSlot = 0;
452  for (size_t i = 0; i < worklist.size(); ++i) {
453  if (i != nextSlot && worklist[i]->is_offset_initialized() &&
454  worklist[i]->get_offset() == 0) {
455  std::swap(worklist[i], worklist[nextSlot]);
456  ++nextSlot;
457  }
458  }
459 
460  while (!worklist.empty()) {
461  segment* seg = worklist.front();
462  worklist.pop_front();
463 
464  size_t i = 0;
465  for (; i < worklist.size(); ++i) {
466  if (is_subsequence_of(seg, worklist[i])) {
467  break;
468  }
469  }
470 
471  if (i < worklist.size())
472  worklist.push_back(seg);
473  else
474  res.push_back(seg);
475  }
476 
477  return res;
478  }
479 
480 
481  //------------------------------------------------------------------------------
482  bool layout_sections_without_segments() {
483  for (unsigned int i = 0; i < sections_.size(); ++i) {
484  if (is_section_without_segment(i)) {
485  section* sec = sections_[i];
486 
487  Elf_Xword section_align = sec->get_addr_align();
488  if (section_align > 1 && current_file_pos % section_align != 0) {
489  current_file_pos += section_align - current_file_pos % section_align;
490  }
491 
492  if (0 != sec->get_index()) sec->set_offset(current_file_pos);
493 
494  if (SHT_NOBITS != sec->get_type() && SHT_NULL != sec->get_type()) {
495  current_file_pos += sec->get_size();
496  }
497  }
498  }
499 
500  return true;
501  }
502 
503 
504  //------------------------------------------------------------------------------
505  bool layout_segments_and_their_sections() {
506  std::vector<segment*> worklist;
507  std::vector<bool> section_generated(sections.size(), false);
508 
509  // Get segments in a order in where segments which contain a
510  // sub sequence of other segments are located at the end
511  worklist = get_ordered_segments();
512 
513  for (unsigned int i = 0; i < worklist.size(); ++i) {
514  Elf_Xword segment_memory = 0;
515  Elf_Xword segment_filesize = 0;
516  Elf_Xword seg_start_pos = current_file_pos;
517  segment* seg = worklist[i];
518 
519  // Special case: PHDR segment
520  // This segment contains the program headers but no sections
521  if (seg->get_type() == PT_PHDR && seg->get_sections_num() == 0) {
522  seg_start_pos = header->get_segments_offset();
523  segment_memory = segment_filesize =
524  header->get_segment_entry_size() * header->get_segments_num();
525  }
526  // Special case:
527  // Segments which start with the NULL section and have further sections
528  else if (seg->get_sections_num() > 1 &&
529  sections[seg->get_section_index_at(0)]->get_type() == SHT_NULL) {
530  seg_start_pos = 0;
531  if (seg->get_sections_num()) {
532  segment_memory = segment_filesize = current_file_pos;
533  }
534  }
535  // New segments with not generated sections
536  // have to be aligned
537  else if (seg->get_sections_num() && !section_generated[seg->get_section_index_at(0)]) {
538  Elf64_Off cur_page_alignment = current_file_pos % seg->get_align();
539  Elf64_Off req_page_alignment = seg->get_virtual_address() % seg->get_align();
540  Elf64_Off error = req_page_alignment - cur_page_alignment;
541 
542  current_file_pos += (seg->get_align() + error) % seg->get_align();
543  seg_start_pos = current_file_pos;
544  } else if (seg->get_sections_num()) {
545  seg_start_pos = sections[seg->get_section_index_at(0)]->get_offset();
546  }
547 
548  // Write segment's data
549  for (unsigned int j = 0; j < seg->get_sections_num(); ++j) {
550  Elf_Half index = seg->get_section_index_at(j);
551 
552  section* sec = sections[index];
553 
554  // The NULL section is always generated
555  if (SHT_NULL == sec->get_type()) {
556  section_generated[index] = true;
557  continue;
558  }
559 
560  Elf_Xword secAlign = 0;
561  // Fix up the alignment
562  if (!section_generated[index] && sec->is_address_initialized() &&
563  SHT_NOBITS != sec->get_type() && SHT_NULL != sec->get_type()) {
564  // Align the sections based on the virtual addresses
565  // when possible (this is what matters for execution)
566  Elf64_Off req_offset = sec->get_address() - seg->get_virtual_address();
567  Elf64_Off cur_offset = current_file_pos - seg_start_pos;
568  secAlign = req_offset - cur_offset;
569  } else if (!section_generated[index]) {
570  // If no address has been specified then only the section
571  // alignment constraint has to be matched
572  Elf_Xword align = sec->get_addr_align();
573  if (align == 0) {
574  align = 1;
575  }
576  Elf64_Off error = current_file_pos % align;
577  secAlign = (align - error) % align;
578  } else {
579  // Alignment for already generated sections
580  secAlign = sec->get_offset() - seg_start_pos - segment_filesize;
581  }
582 
583  // Determine the segment file and memory sizes
584  // Special case .tbss section (NOBITS) in non TLS segment
585  if ((sec->get_flags() & SHF_ALLOC) &&
586  !((sec->get_flags() & SHF_TLS) && (seg->get_type() != PT_TLS) &&
587  (SHT_NOBITS == sec->get_type())))
588  segment_memory += sec->get_size() + secAlign;
589  if (SHT_NOBITS != sec->get_type() && SHT_NULL != sec->get_type())
590  segment_filesize += sec->get_size() + secAlign;
591 
592  // Nothing to be done when generating nested segments
593  if (section_generated[index]) {
594  continue;
595  }
596 
597  current_file_pos += secAlign;
598 
599  // Set the section addresses when missing
600  if (!sec->is_address_initialized())
601  sec->set_address(seg->get_virtual_address() + current_file_pos - seg_start_pos);
602 
603  if (0 != sec->get_index()) sec->set_offset(current_file_pos);
604 
605  if (SHT_NOBITS != sec->get_type() && SHT_NULL != sec->get_type())
606  current_file_pos += sec->get_size();
607  section_generated[index] = true;
608  }
609 
610  seg->set_file_size(segment_filesize);
611  seg->set_memory_size(segment_memory);
612  seg->set_offset(seg_start_pos);
613  }
614 
615  return true;
616  }
617 
618  //------------------------------------------------------------------------------
619  bool layout_section_table() {
620  // Simply place the section table at the end for now
621  Elf64_Off alignmentError = current_file_pos % 4;
622  current_file_pos += (4 - alignmentError) % 4;
623  header->set_sections_offset(current_file_pos);
624  return true;
625  }
626 
627 
628  //------------------------------------------------------------------------------
629  public:
630  friend class Sections;
631  class Sections {
632  public:
633  //------------------------------------------------------------------------------
634  Sections(elfio* parent_) : parent(parent_) {}
635 
636  //------------------------------------------------------------------------------
637  Elf_Half size() const { return (Elf_Half)parent->sections_.size(); }
638 
639  //------------------------------------------------------------------------------
640  section* operator[](unsigned int index) const {
641  section* sec = 0;
642 
643  if (index < parent->sections_.size()) {
644  sec = parent->sections_[index];
645  }
646 
647  return sec;
648  }
649 
650  //------------------------------------------------------------------------------
651  section* operator[](const std::string& name) const {
652  section* sec = 0;
653 
654  std::vector<section*>::const_iterator it;
655  for (it = parent->sections_.begin(); it != parent->sections_.end(); ++it) {
656  if ((*it)->get_name() == name) {
657  sec = *it;
658  break;
659  }
660  }
661 
662  return sec;
663  }
664 
665  //------------------------------------------------------------------------------
666  section* add(const std::string& name) {
667  section* new_section = parent->create_section();
668  new_section->set_name(name);
669 
670  Elf_Half str_index = parent->get_section_name_str_index();
671  section* string_table(parent->sections_[str_index]);
672  string_section_accessor str_writer(string_table);
673  Elf_Word pos = str_writer.add_string(name);
674  new_section->set_name_string_offset(pos);
675 
676  return new_section;
677  }
678 
679  //------------------------------------------------------------------------------
680  std::vector<section*>::iterator begin() { return parent->sections_.begin(); }
681 
682  //------------------------------------------------------------------------------
683  std::vector<section*>::iterator end() { return parent->sections_.end(); }
684 
685  //------------------------------------------------------------------------------
686  private:
687  elfio* parent;
688  } sections;
689 
690  //------------------------------------------------------------------------------
691  public:
692  friend class Segments;
693  class Segments {
694  public:
695  //------------------------------------------------------------------------------
696  Segments(elfio* parent_) : parent(parent_) {}
697 
698  //------------------------------------------------------------------------------
699  Elf_Half size() const { return (Elf_Half)parent->segments_.size(); }
700 
701  //------------------------------------------------------------------------------
702  segment* operator[](unsigned int index) const { return parent->segments_[index]; }
703 
704 
705  //------------------------------------------------------------------------------
706  segment* add() { return parent->create_segment(); }
707 
708  //------------------------------------------------------------------------------
709  std::vector<segment*>::iterator begin() { return parent->segments_.begin(); }
710 
711  //------------------------------------------------------------------------------
712  std::vector<segment*>::iterator end() { return parent->segments_.end(); }
713 
714  //------------------------------------------------------------------------------
715  private:
716  elfio* parent;
717  } segments;
718 
719  //------------------------------------------------------------------------------
720  private:
721  elf_header* header;
722  std::vector<section*> sections_;
723  std::vector<segment*> segments_;
724  endianess_convertor convertor;
725 
726  Elf_Xword current_file_pos;
727 };
728 
729 } // namespace ELFIO
730 
731 #include "elfio_symbols.hpp"
732 #include "elfio_note.hpp"
733 #include "elfio_relocation.hpp"
734 #include "elfio_dynamic.hpp"
735 
736 #ifdef _MSC_VER
737 #pragma warning(pop)
738 #endif
739 
740 #endif // ELFIO_HPP
ELFIO::Elf64_Sym
Definition: elf_types.hpp:680
ELFIO::string_section_accessor
Definition: elfio_strings.hpp:33
ELFIO::elf_header_impl
Definition: elfio_header.hpp:75
ELFIO::endianess_convertor
Definition: elfio_utils.hpp:51
ELFIO::section_impl
Definition: elfio_section.hpp:67
ELFIO::Elf64_Rel
Definition: elf_types.hpp:709
ELFIO::segment_impl
Definition: elfio_segment.hpp:67
ELFIO::Elf32_Sym
Definition: elf_types.hpp:671
ELFIO::elfio::Sections
Definition: elfio.hpp:631
ELFIO::elf_header
Definition: elfio_header.hpp:30
ELFIO::elfio
Definition: elfio.hpp:59
ELFIO::elfio::Segments
Definition: elfio.hpp:693
ELFIO::Elf64_Rela
Definition: elf_types.hpp:714
ELFIO::Elf32_Rela
Definition: elf_types.hpp:703
ELFIO::Elf32_Dyn
Definition: elf_types.hpp:730
ELFIO::section
Definition: elfio_section.hpp:31
ELFIO::Elf64_Dyn
Definition: elf_types.hpp:738
ELFIO::segment
Definition: elfio_segment.hpp:31
ELFIO::Elf32_Rel
Definition: elf_types.hpp:698