HIP: Heterogenous-computing Interface for Portability
elfio_dynamic.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_DYNAMIC_HPP
24 #define ELFIO_DYNAMIC_HPP
25 
26 namespace ELFIO {
27 
28 //------------------------------------------------------------------------------
30  public:
31  //------------------------------------------------------------------------------
32  dynamic_section_accessor(const elfio& elf_file_, section* section_)
33  : elf_file(elf_file_), dynamic_section(section_) {}
34 
35  //------------------------------------------------------------------------------
36  Elf_Xword get_entries_num() const {
37  Elf_Xword nRet = 0;
38 
39  if (0 != dynamic_section->get_entry_size()) {
40  nRet = dynamic_section->get_size() / dynamic_section->get_entry_size();
41  }
42 
43  return nRet;
44  }
45 
46  //------------------------------------------------------------------------------
47  bool get_entry(Elf_Xword index, Elf_Xword& tag, Elf_Xword& value, std::string& str) const {
48  if (index >= get_entries_num()) { // Is index valid
49  return false;
50  }
51 
52  if (elf_file.get_class() == ELFCLASS32) {
53  generic_get_entry_dyn<Elf32_Dyn>(index, tag, value);
54  } else {
55  generic_get_entry_dyn<Elf64_Dyn>(index, tag, value);
56  }
57 
58  // If the tag may have a string table reference, prepare the string
59  if (tag == DT_NEEDED || tag == DT_SONAME || tag == DT_RPATH || tag == DT_RUNPATH) {
60  string_section_accessor strsec = elf_file.sections[get_string_table_index()];
61  const char* result = strsec.get_string(value);
62  if (0 == result) {
63  str.clear();
64  return false;
65  }
66  str = result;
67  } else {
68  str.clear();
69  }
70 
71  return true;
72  }
73 
74  //------------------------------------------------------------------------------
75  void add_entry(Elf_Xword& tag, Elf_Xword& value) {
76  if (elf_file.get_class() == ELFCLASS32) {
77  generic_add_entry<Elf32_Dyn>(tag, value);
78  } else {
79  generic_add_entry<Elf64_Dyn>(tag, value);
80  }
81  }
82 
83  //------------------------------------------------------------------------------
84  void add_entry(Elf_Xword& tag, std::string& str) {
85  string_section_accessor strsec = elf_file.sections[get_string_table_index()];
86  Elf_Xword value = strsec.add_string(str);
87  add_entry(tag, value);
88  }
89 
90  //------------------------------------------------------------------------------
91  private:
92  //------------------------------------------------------------------------------
93  Elf_Half get_string_table_index() const { return (Elf_Half)dynamic_section->get_link(); }
94 
95  //------------------------------------------------------------------------------
96  template <class T>
97  void generic_get_entry_dyn(Elf_Xword index, Elf_Xword& tag, Elf_Xword& value) const {
98  const endianess_convertor& convertor = elf_file.get_convertor();
99 
100  // Check unusual case when dynamic section has no data
101  if (dynamic_section->get_data() == 0 ||
102  (index + 1) * dynamic_section->get_entry_size() > dynamic_section->get_size()) {
103  tag = DT_NULL;
104  value = 0;
105  return;
106  }
107 
108  const T* pEntry = reinterpret_cast<const T*>(dynamic_section->get_data() +
109  index * dynamic_section->get_entry_size());
110  tag = convertor(pEntry->d_tag);
111  switch (tag) {
112  case DT_NULL:
113  case DT_SYMBOLIC:
114  case DT_TEXTREL:
115  case DT_BIND_NOW:
116  value = 0;
117  break;
118  case DT_NEEDED:
119  case DT_PLTRELSZ:
120  case DT_RELASZ:
121  case DT_RELAENT:
122  case DT_STRSZ:
123  case DT_SYMENT:
124  case DT_SONAME:
125  case DT_RPATH:
126  case DT_RELSZ:
127  case DT_RELENT:
128  case DT_PLTREL:
129  case DT_INIT_ARRAYSZ:
130  case DT_FINI_ARRAYSZ:
131  case DT_RUNPATH:
132  case DT_FLAGS:
133  case DT_PREINIT_ARRAYSZ:
134  value = convertor(pEntry->d_un.d_val);
135  break;
136  case DT_PLTGOT:
137  case DT_HASH:
138  case DT_STRTAB:
139  case DT_SYMTAB:
140  case DT_RELA:
141  case DT_INIT:
142  case DT_FINI:
143  case DT_REL:
144  case DT_DEBUG:
145  case DT_JMPREL:
146  case DT_INIT_ARRAY:
147  case DT_FINI_ARRAY:
148  case DT_PREINIT_ARRAY:
149  default:
150  value = convertor(pEntry->d_un.d_ptr);
151  break;
152  }
153  }
154 
155  //------------------------------------------------------------------------------
156  template <class T>
157  void generic_add_entry(Elf_Xword tag, Elf_Xword value) {
158  const endianess_convertor& convertor = elf_file.get_convertor();
159 
160  T entry;
161 
162  switch (tag) {
163  case DT_NULL:
164  case DT_SYMBOLIC:
165  case DT_TEXTREL:
166  case DT_BIND_NOW:
167  value = 0;
168  case DT_NEEDED:
169  case DT_PLTRELSZ:
170  case DT_RELASZ:
171  case DT_RELAENT:
172  case DT_STRSZ:
173  case DT_SYMENT:
174  case DT_SONAME:
175  case DT_RPATH:
176  case DT_RELSZ:
177  case DT_RELENT:
178  case DT_PLTREL:
179  case DT_INIT_ARRAYSZ:
180  case DT_FINI_ARRAYSZ:
181  case DT_RUNPATH:
182  case DT_FLAGS:
183  case DT_PREINIT_ARRAYSZ:
184  entry.d_un.d_val = convertor(value);
185  break;
186  case DT_PLTGOT:
187  case DT_HASH:
188  case DT_STRTAB:
189  case DT_SYMTAB:
190  case DT_RELA:
191  case DT_INIT:
192  case DT_FINI:
193  case DT_REL:
194  case DT_DEBUG:
195  case DT_JMPREL:
196  case DT_INIT_ARRAY:
197  case DT_FINI_ARRAY:
198  case DT_PREINIT_ARRAY:
199  default:
200  entry.d_un.d_ptr = convertor(value);
201  break;
202  }
203 
204  entry.d_tag = convertor(tag);
205 
206  dynamic_section->append_data(reinterpret_cast<char*>(&entry), sizeof(entry));
207  }
208 
209  //------------------------------------------------------------------------------
210  private:
211  const elfio& elf_file;
212  section* dynamic_section;
213 };
214 
215 } // namespace ELFIO
216 
217 #endif // ELFIO_DYNAMIC_HPP
ELFIO::string_section_accessor
Definition: elfio_strings.hpp:33
ELFIO::endianess_convertor
Definition: elfio_utils.hpp:51
ELFIO::dynamic_section_accessor
Definition: elfio_dynamic.hpp:29
ELFIO::elfio
Definition: elfio.hpp:59
ELFIO::section
Definition: elfio_section.hpp:31