HIP: Heterogenous-computing Interface for Portability
elfio_note.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_NOTE_HPP
24 #define ELFIO_NOTE_HPP
25 
26 namespace ELFIO {
27 
28 //------------------------------------------------------------------------------
29 // There are discrepancies in documentations. SCO documentation
30 // (http://www.sco.com/developers/gabi/latest/ch5.pheader.html#note_section)
31 // requires 8 byte entries alignment for 64-bit ELF file,
32 // but Oracle's definition uses the same structure
33 // for 32-bit and 64-bit formats.
34 // (https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-18048.html)
35 //
36 // It looks like EM_X86_64 Linux implementation is similar to Oracle's
37 // definition. Therefore, the same alignment works for both formats
38 //------------------------------------------------------------------------------
39 
40 //------------------------------------------------------------------------------
42  public:
43  //------------------------------------------------------------------------------
44  note_section_accessor(const elfio& elf_file_, section* section_)
45  : elf_file(elf_file_), note_section(section_) {
46  process_section();
47  }
48 
49  //------------------------------------------------------------------------------
50  Elf_Word get_notes_num() const { return (Elf_Word)note_start_positions.size(); }
51 
52  //------------------------------------------------------------------------------
53  bool get_note(Elf_Word index, Elf_Word& type, std::string& name, void*& desc,
54  Elf_Word& descSize) const {
55  if (index >= note_section->get_size()) {
56  return false;
57  }
58 
59  const char* pData = note_section->get_data() + note_start_positions[index];
60  int align = sizeof(Elf_Word);
61 
62  const endianess_convertor& convertor = elf_file.get_convertor();
63  type = convertor(*(Elf_Word*)(pData + 2 * align));
64  Elf_Word namesz = convertor(*(Elf_Word*)(pData));
65  descSize = convertor(*(Elf_Word*)(pData + sizeof(namesz)));
66  Elf_Word max_name_size = note_section->get_size() - note_start_positions[index];
67  if (namesz > max_name_size || namesz + descSize > max_name_size) {
68  return false;
69  }
70  name.assign(pData + 3 * align, namesz - 1);
71  if (0 == descSize) {
72  desc = 0;
73  } else {
74  desc = const_cast<char*>(pData + 3 * align + ((namesz + align - 1) / align) * align);
75  }
76 
77  return true;
78  }
79 
80  //------------------------------------------------------------------------------
81  void add_note(Elf_Word type, const std::string& name, const void* desc, Elf_Word descSize) {
82  const endianess_convertor& convertor = elf_file.get_convertor();
83 
84  int align = sizeof(Elf_Word);
85  Elf_Word nameLen = (Elf_Word)name.size() + 1;
86  Elf_Word nameLenConv = convertor(nameLen);
87  std::string buffer(reinterpret_cast<char*>(&nameLenConv), align);
88  Elf_Word descSizeConv = convertor(descSize);
89  buffer.append(reinterpret_cast<char*>(&descSizeConv), align);
90  type = convertor(type);
91  buffer.append(reinterpret_cast<char*>(&type), align);
92  buffer.append(name);
93  buffer.append(1, '\x00');
94  const char pad[] = {'\0', '\0', '\0', '\0'};
95  if (nameLen % align != 0) {
96  buffer.append(pad, align - nameLen % align);
97  }
98  if (desc != 0 && descSize != 0) {
99  buffer.append(reinterpret_cast<const char*>(desc), descSize);
100  if (descSize % align != 0) {
101  buffer.append(pad, align - descSize % align);
102  }
103  }
104 
105  note_start_positions.push_back(note_section->get_size());
106  note_section->append_data(buffer);
107  }
108 
109  private:
110  //------------------------------------------------------------------------------
111  void process_section() {
112  const endianess_convertor& convertor = elf_file.get_convertor();
113  const char* data = note_section->get_data();
114  Elf_Xword size = note_section->get_size();
115  Elf_Xword current = 0;
116 
117  note_start_positions.clear();
118 
119  // Is it empty?
120  if (0 == data || 0 == size) {
121  return;
122  }
123 
124  int align = sizeof(Elf_Word);
125  while (current + 3 * align <= size) {
126  note_start_positions.push_back(current);
127  Elf_Word namesz = convertor(*(Elf_Word*)(data + current));
128  Elf_Word descsz = convertor(*(Elf_Word*)(data + current + sizeof(namesz)));
129 
130  current += 3 * sizeof(Elf_Word) + ((namesz + align - 1) / align) * align +
131  ((descsz + align - 1) / align) * align;
132  }
133  }
134 
135  //------------------------------------------------------------------------------
136  private:
137  const elfio& elf_file;
138  section* note_section;
139  std::vector<Elf_Xword> note_start_positions;
140 };
141 
142 } // namespace ELFIO
143 
144 #endif // ELFIO_NOTE_HPP
ELFIO::endianess_convertor
Definition: elfio_utils.hpp:51
ELFIO::elfio
Definition: elfio.hpp:59
ELFIO::section
Definition: elfio_section.hpp:31
ELFIO::note_section_accessor
Definition: elfio_note.hpp:41