1 /*
2 Copyright (C) 2001-present 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 #ifdef _MSC_VER
24 #define _CRT_SECURE_NO_WARNINGS
25 #endif
26 
27 #include <elfio/elfio.hpp>
28 #include <cstring>
29 
30 using namespace ELFIO;
31 
32 #include "elfio_c_wrapper.h"
33 
34 //-----------------------------------------------------------------------------
35 // elfio
36 //-----------------------------------------------------------------------------
elfio_new()37 pelfio_t elfio_new() { return new ( std::nothrow ) elfio; }
38 
elfio_delete( pelfio_t pelfio )39 void elfio_delete( pelfio_t pelfio ) { delete (elfio*)pelfio; }
40 
elfio_create( pelfio_t pelfio, unsigned char file_class, unsigned char encoding )41 void elfio_create( pelfio_t      pelfio,
42                    unsigned char file_class,
43                    unsigned char encoding )
44 {
45     pelfio->create( file_class, encoding );
46 }
47 
elfio_load( pelfio_t pelfio, const char* file_name )48 bool elfio_load( pelfio_t pelfio, const char* file_name )
49 {
50     return pelfio->load( file_name );
51 }
52 
elfio_save( pelfio_t pelfio, const char* file_name )53 bool elfio_save( pelfio_t pelfio, const char* file_name )
54 {
55     return pelfio->save( file_name );
56 }
57 
58 ELFIO_C_HEADER_ACCESS_GET_IMPL( unsigned char, class );
59 ELFIO_C_HEADER_ACCESS_GET_IMPL( unsigned char, elf_version );
60 ELFIO_C_HEADER_ACCESS_GET_IMPL( unsigned char, encoding );
61 ELFIO_C_HEADER_ACCESS_GET_IMPL( Elf_Word, version );
62 ELFIO_C_HEADER_ACCESS_GET_IMPL( Elf_Half, header_size );
63 ELFIO_C_HEADER_ACCESS_GET_IMPL( Elf_Half, section_entry_size );
64 ELFIO_C_HEADER_ACCESS_GET_IMPL( Elf_Half, segment_entry_size );
65 
66 ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( unsigned char, os_abi );
67 ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( unsigned char, abi_version );
68 ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( Elf_Half, type );
69 ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( Elf_Half, machine );
70 ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( Elf_Word, flags );
71 ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( Elf64_Addr, entry );
72 ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( Elf64_Off, sections_offset );
73 ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( Elf64_Off, segments_offset );
74 ELFIO_C_HEADER_ACCESS_GET_SET_IMPL( Elf_Half, section_name_str_index );
75 
elfio_get_sections_num( pelfio_t pelfio )76 Elf_Half elfio_get_sections_num( pelfio_t pelfio )
77 {
78     return pelfio->sections.size();
79 }
80 
elfio_get_section_by_index( pelfio_t pelfio, int index )81 psection_t elfio_get_section_by_index( pelfio_t pelfio, int index )
82 {
83     return pelfio->sections[index];
84 }
85 
elfio_get_section_by_name( pelfio_t pelfio, char* name )86 psection_t elfio_get_section_by_name( pelfio_t pelfio, char* name )
87 {
88     return pelfio->sections[name];
89 }
90 
elfio_add_section( pelfio_t pelfio, char* name )91 psection_t elfio_add_section( pelfio_t pelfio, char* name )
92 {
93     return pelfio->sections.add( name );
94 }
95 
elfio_get_segments_num( pelfio_t pelfio )96 Elf_Half elfio_get_segments_num( pelfio_t pelfio )
97 {
98     return pelfio->segments.size();
99 }
100 
elfio_get_segment_by_index( pelfio_t pelfio, int index )101 psegment_t elfio_get_segment_by_index( pelfio_t pelfio, int index )
102 {
103     return pelfio->segments[index];
104 }
105 
elfio_add_segment( pelfio_t pelfio )106 psegment_t elfio_add_segment( pelfio_t pelfio )
107 {
108     return pelfio->segments.add();
109 }
110 
elfio_validate( pelfio_t pelfio, char* msg, int msg_len )111 bool elfio_validate( pelfio_t pelfio, char* msg, int msg_len )
112 {
113     std::string error = pelfio->validate();
114 
115     if ( msg != nullptr && msg_len > 0 ) {
116         strncpy( msg, error.c_str(), (size_t)msg_len - 1 );
117     }
118 
119     return error.empty();
120 }
121 
122 //-----------------------------------------------------------------------------
123 // section
124 //-----------------------------------------------------------------------------
125 ELFIO_C_GET_ACCESS_IMPL( section, Elf_Half, index );
126 ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf_Word, type );
127 ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf_Xword, flags );
128 ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf_Word, info );
129 ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf_Word, link );
130 ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf_Xword, addr_align );
131 ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf_Xword, entry_size );
132 ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf64_Addr, address );
133 ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf_Xword, size );
134 ELFIO_C_GET_SET_ACCESS_IMPL( section, Elf_Word, name_string_offset );
135 ELFIO_C_GET_ACCESS_IMPL( section, Elf64_Off, offset );
136 
elfio_section_get_name( psection_t psection, char* buffer, int len )137 void elfio_section_get_name( psection_t psection, char* buffer, int len )
138 {
139     strncpy( buffer, psection->get_name().c_str(), (size_t)len - 1 );
140 }
141 
elfio_section_set_name( psection_t psection, char* buffer )142 void elfio_section_set_name( psection_t psection, char* buffer )
143 {
144     psection->set_name( buffer );
145 }
146 
elfio_section_get_data( psection_t psection )147 char* elfio_section_get_data( psection_t psection )
148 {
149     return (char*)psection->get_data();
150 }
151 
elfio_section_set_data( psection_t psection, const char* pData, Elf_Word size )152 void elfio_section_set_data( psection_t  psection,
153                              const char* pData,
154                              Elf_Word    size )
155 {
156     psection->set_data( pData, size );
157 }
158 
elfio_section_append_data( psection_t psection, const char* pData, Elf_Word size )159 void elfio_section_append_data( psection_t  psection,
160                                 const char* pData,
161                                 Elf_Word    size )
162 {
163     psection->append_data( pData, size );
164 }
165 
166 //-----------------------------------------------------------------------------
167 // segment
168 //-----------------------------------------------------------------------------
169 ELFIO_C_GET_ACCESS_IMPL( segment, Elf_Half, index );
170 ELFIO_C_GET_SET_ACCESS_IMPL( segment, Elf_Word, type );
171 ELFIO_C_GET_SET_ACCESS_IMPL( segment, Elf_Word, flags );
172 ELFIO_C_GET_SET_ACCESS_IMPL( segment, Elf_Xword, align );
173 ELFIO_C_GET_SET_ACCESS_IMPL( segment, Elf_Xword, memory_size );
174 ELFIO_C_GET_SET_ACCESS_IMPL( segment, Elf64_Addr, virtual_address );
175 ELFIO_C_GET_SET_ACCESS_IMPL( segment, Elf64_Addr, physical_address );
176 ELFIO_C_GET_SET_ACCESS_IMPL( segment, Elf_Xword, file_size );
177 ELFIO_C_GET_ACCESS_IMPL( segment, Elf64_Off, offset );
178 
elfio_segment_get_data( psegment_t psegment )179 char* elfio_segment_get_data( psegment_t psegment )
180 {
181     return (char*)psegment->get_data();
182 }
183 
elfio_segment_add_section_index( psegment_t psegment, Elf_Half index, Elf_Xword addr_align )184 Elf_Half elfio_segment_add_section_index( psegment_t psegment,
185                                           Elf_Half   index,
186                                           Elf_Xword  addr_align )
187 {
188     return psegment->add_section_index( index, addr_align );
189 }
190 
elfio_segment_get_sections_num( psegment_t psegment )191 Elf_Half elfio_segment_get_sections_num( psegment_t psegment )
192 {
193     return psegment->get_sections_num();
194 }
195 
elfio_segment_get_section_index_at( psegment_t psegment, Elf_Half num )196 Elf_Half elfio_segment_get_section_index_at( psegment_t psegment, Elf_Half num )
197 {
198     return psegment->get_section_index_at( num );
199 }
200 
elfio_segment_is_offset_initialized( psegment_t psegment )201 bool elfio_segment_is_offset_initialized( psegment_t psegment )
202 {
203     return psegment->is_offset_initialized();
204 }
205 
206 //-----------------------------------------------------------------------------
207 // symbol
208 //-----------------------------------------------------------------------------
elfio_symbol_section_accessor_new( pelfio_t pelfio, psection_t psection )209 psymbol_t elfio_symbol_section_accessor_new( pelfio_t   pelfio,
210                                              psection_t psection )
211 {
212     return new ( std::nothrow ) symbol_section_accessor( *pelfio, psection );
213 }
214 
elfio_symbol_section_accessor_delete( psymbol_t psymbol )215 void elfio_symbol_section_accessor_delete( psymbol_t psymbol )
216 {
217     delete psymbol;
218 }
219 
elfio_symbol_get_symbols_num( psymbol_t psymbol )220 Elf_Xword elfio_symbol_get_symbols_num( psymbol_t psymbol )
221 {
222     return psymbol->get_symbols_num();
223 }
224 
elfio_symbol_get_symbol( psymbol_t psymbol, Elf_Xword index, char* name, int name_len, Elf64_Addr* value, Elf_Xword* size, unsigned char* bind, unsigned char* type, Elf_Half* section_index, unsigned char* other )225 bool elfio_symbol_get_symbol( psymbol_t      psymbol,
226                               Elf_Xword      index,
227                               char*          name,
228                               int            name_len,
229                               Elf64_Addr*    value,
230                               Elf_Xword*     size,
231                               unsigned char* bind,
232                               unsigned char* type,
233                               Elf_Half*      section_index,
234                               unsigned char* other )
235 {
236     std::string name_param;
237     bool ret = psymbol->get_symbol( index, name_param, *value, *size, *bind,
238                                     *type, *section_index, *other );
239     strncpy( name, name_param.c_str(), (size_t)name_len - 1 );
240 
241     return ret;
242 }
243 
elfio_symbol_add_symbol( psymbol_t psymbol, Elf_Word name, Elf64_Addr value, Elf_Xword size, unsigned char info, unsigned char other, Elf_Half shndx )244 Elf_Word elfio_symbol_add_symbol( psymbol_t     psymbol,
245                                   Elf_Word      name,
246                                   Elf64_Addr    value,
247                                   Elf_Xword     size,
248                                   unsigned char info,
249                                   unsigned char other,
250                                   Elf_Half      shndx )
251 {
252     return psymbol->add_symbol( name, value, size, info, other, shndx );
253 }
254 
elfio_symbol_arrange_local_symbols( psymbol_t psymbol, void ( *func )( Elf_Xword first, Elf_Xword second ) )255 Elf_Xword elfio_symbol_arrange_local_symbols(
256     psymbol_t psymbol, void ( *func )( Elf_Xword first, Elf_Xword second ) )
257 {
258     return psymbol->arrange_local_symbols( func );
259 }
260 
261 //-----------------------------------------------------------------------------
262 // relocation
263 //-----------------------------------------------------------------------------
elfio_relocation_section_accessor_new( pelfio_t pelfio, psection_t psection )264 prelocation_t elfio_relocation_section_accessor_new( pelfio_t   pelfio,
265                                                      psection_t psection )
266 {
267     return new ( std::nothrow )
268         relocation_section_accessor( *pelfio, psection );
269 }
270 
elfio_relocation_section_accessor_delete( prelocation_t prelocation )271 void elfio_relocation_section_accessor_delete( prelocation_t prelocation )
272 {
273     delete prelocation;
274 }
275 
elfio_relocation_get_entries_num( prelocation_t prelocation )276 Elf_Xword elfio_relocation_get_entries_num( prelocation_t prelocation )
277 {
278     return prelocation->get_entries_num();
279 }
280 
elfio_relocation_get_entry( prelocation_t prelocation, Elf_Xword index, Elf64_Addr* offset, Elf_Word* symbol, Elf_Word* type, Elf_Sxword* addend )281 bool elfio_relocation_get_entry( prelocation_t prelocation,
282                                  Elf_Xword     index,
283                                  Elf64_Addr*   offset,
284                                  Elf_Word*     symbol,
285                                  Elf_Word*     type,
286                                  Elf_Sxword*   addend )
287 {
288     return prelocation->get_entry( index, *offset, *symbol, *type, *addend );
289 }
290 
elfio_relocation_set_entry( prelocation_t prelocation, Elf_Xword index, Elf64_Addr offset, Elf_Word symbol, Elf_Word type, Elf_Sxword addend )291 bool elfio_relocation_set_entry( prelocation_t prelocation,
292                                  Elf_Xword     index,
293                                  Elf64_Addr    offset,
294                                  Elf_Word      symbol,
295                                  Elf_Word      type,
296                                  Elf_Sxword    addend )
297 {
298     return prelocation->set_entry( index, offset, symbol, type, addend );
299 }
300 
elfio_relocation_add_entry( prelocation_t prelocation, Elf64_Addr offset, Elf_Word symbol, unsigned char type, Elf_Sxword addend )301 void elfio_relocation_add_entry( prelocation_t prelocation,
302                                  Elf64_Addr    offset,
303                                  Elf_Word      symbol,
304                                  unsigned char type,
305                                  Elf_Sxword    addend )
306 {
307     return prelocation->add_entry( offset, symbol, type, addend );
308 }
309 
elfio_relocation_swap_symbols( prelocation_t prelocation, Elf_Xword first, Elf_Xword second )310 void elfio_relocation_swap_symbols( prelocation_t prelocation,
311                                     Elf_Xword     first,
312                                     Elf_Xword     second )
313 {
314     prelocation->swap_symbols( first, second );
315 }
316 
317 //-----------------------------------------------------------------------------
318 // string
319 //-----------------------------------------------------------------------------
elfio_string_section_accessor_new( psection_t psection )320 pstring_t elfio_string_section_accessor_new( psection_t psection )
321 {
322     return new ( std::nothrow ) string_section_accessor( psection );
323 }
324 
elfio_string_section_accessor_delete( pstring_t pstring )325 void elfio_string_section_accessor_delete( pstring_t pstring )
326 {
327     delete pstring;
328 }
329 
elfio_string_get_string( pstring_t pstring, Elf_Word index )330 const char* elfio_string_get_string( pstring_t pstring, Elf_Word index )
331 {
332     return pstring->get_string( index );
333 }
334 
elfio_string_add_string( pstring_t pstring, char* str )335 Elf_Word elfio_string_add_string( pstring_t pstring, char* str )
336 {
337     return pstring->add_string( str );
338 }
339 
340 //-----------------------------------------------------------------------------
341 // note
342 //-----------------------------------------------------------------------------
elfio_note_section_accessor_new( pelfio_t pelfio, psection_t psection )343 pnote_t elfio_note_section_accessor_new( pelfio_t pelfio, psection_t psection )
344 {
345     return new ( std::nothrow ) note_section_accessor( *pelfio, psection );
346 }
347 
elfio_note_section_accessor_delete( pnote_t pnote )348 void elfio_note_section_accessor_delete( pnote_t pnote ) { delete pnote; }
349 
elfio_note_get_notes_num( pnote_t pnote )350 Elf_Word elfio_note_get_notes_num( pnote_t pnote )
351 {
352     return pnote->get_notes_num();
353 }
354 
elfio_note_get_note( pnote_t pnote, Elf_Word index, Elf_Word* type, char* name, int name_len, void** desc, Elf_Word* descSize )355 bool elfio_note_get_note( pnote_t   pnote,
356                           Elf_Word  index,
357                           Elf_Word* type,
358                           char*     name,
359                           int       name_len,
360                           void**    desc,
361                           Elf_Word* descSize )
362 {
363     std::string name_str;
364     bool ret = pnote->get_note( index, *type, name_str, *desc, *descSize );
365     strncpy( name, name_str.c_str(), (size_t)name_len - 1 );
366 
367     return ret;
368 }
369 
elfio_note_add_note( pnote_t pnote, Elf_Word type, const char* name, const void* desc, Elf_Word descSize )370 void elfio_note_add_note( pnote_t     pnote,
371                           Elf_Word    type,
372                           const char* name,
373                           const void* desc,
374                           Elf_Word    descSize )
375 {
376     pnote->add_note( type, name, desc, descSize );
377 }
378 
379 //-----------------------------------------------------------------------------
380 // modinfo
381 //-----------------------------------------------------------------------------
elfio_modinfo_section_accessor_new( psection_t psection )382 pmodinfo_t elfio_modinfo_section_accessor_new( psection_t psection )
383 {
384     return new ( std::nothrow ) modinfo_section_accessor( psection );
385 }
386 
elfio_modinfo_section_accessor_delete( pmodinfo_t pmodinfo )387 void elfio_modinfo_section_accessor_delete( pmodinfo_t pmodinfo )
388 {
389     delete pmodinfo;
390 }
391 
elfio_modinfo_get_attribute_num( pmodinfo_t pmodinfo )392 Elf_Word elfio_modinfo_get_attribute_num( pmodinfo_t pmodinfo )
393 {
394     return pmodinfo->get_attribute_num();
395 }
396 
elfio_modinfo_get_attribute( pmodinfo_t pmodinfo, Elf_Word no, char* field, int field_len, char* value, int value_len )397 bool elfio_modinfo_get_attribute( pmodinfo_t pmodinfo,
398                                   Elf_Word   no,
399                                   char*      field,
400                                   int        field_len,
401                                   char*      value,
402                                   int        value_len )
403 {
404     std::string field_str;
405     std::string value_str;
406     bool        ret = pmodinfo->get_attribute( no, field_str, value_str );
407     strncpy( field, field_str.c_str(), (size_t)field_len - 1 );
408     strncpy( value, value_str.c_str(), (size_t)value_len - 1 );
409 
410     return ret;
411 }
412 
elfio_modinfo_get_attribute_by_name( pmodinfo_t pmodinfo, char* field_name, char* value, int value_len )413 bool elfio_modinfo_get_attribute_by_name( pmodinfo_t pmodinfo,
414                                           char*      field_name,
415                                           char*      value,
416                                           int        value_len )
417 {
418     std::string value_str;
419     bool        ret = pmodinfo->get_attribute( value_str, value_str );
420     strncpy( value, value_str.c_str(), (size_t)value_len - 1 );
421 
422     return ret;
423 }
424 
425 Elf_Word
elfio_modinfo_add_attribute( pmodinfo_t pmodinfo, char* field, char* value )426 elfio_modinfo_add_attribute( pmodinfo_t pmodinfo, char* field, char* value )
427 {
428     return pmodinfo->add_attribute( field, value );
429 }
430 
431 //-----------------------------------------------------------------------------
432 // dynamic
433 //-----------------------------------------------------------------------------
elfio_dynamic_section_accessor_new( pelfio_t pelfio, psection_t psection )434 pdynamic_t elfio_dynamic_section_accessor_new( pelfio_t   pelfio,
435                                                psection_t psection )
436 {
437     return new ( std::nothrow ) dynamic_section_accessor( *pelfio, psection );
438 }
439 
elfio_dynamic_section_accessor_delete( pdynamic_t pdynamic )440 void elfio_dynamic_section_accessor_delete( pdynamic_t pdynamic )
441 {
442     delete pdynamic;
443 }
444 
elfio_dynamic_get_entries_num( pdynamic_t pdynamic )445 Elf_Xword elfio_dynamic_get_entries_num( pdynamic_t pdynamic )
446 {
447     return pdynamic->get_entries_num();
448 }
449 
elfio_dynamic_get_entry( pdynamic_t pdynamic, Elf_Xword index, Elf_Xword* tag, Elf_Xword* value, char* str, int str_len )450 bool elfio_dynamic_get_entry( pdynamic_t pdynamic,
451                               Elf_Xword  index,
452                               Elf_Xword* tag,
453                               Elf_Xword* value,
454                               char*      str,
455                               int        str_len )
456 {
457     std::string str_str;
458     bool        ret = pdynamic->get_entry( index, *tag, *value, str_str );
459     strncpy( str, str_str.c_str(), (size_t)str_len - 1 );
460 
461     return ret;
462 }
463 
elfio_dynamic_add_entry( pdynamic_t pdynamic, Elf_Xword tag, Elf_Xword value )464 void elfio_dynamic_add_entry( pdynamic_t pdynamic,
465                               Elf_Xword  tag,
466                               Elf_Xword  value )
467 {
468     pdynamic->add_entry( tag, value );
469 }
470 
471 //-----------------------------------------------------------------------------
472 // array
473 //-----------------------------------------------------------------------------
elfio_array_section_accessor_new( pelfio_t pelfio, psection_t psection )474 parray_t elfio_array_section_accessor_new( pelfio_t   pelfio,
475                                            psection_t psection )
476 {
477     return new ( std::nothrow )
478         array_section_accessor<Elf64_Word>( *pelfio, psection );
479 }
480 
elfio_array_section_accessor_delete( parray_t parray )481 void elfio_array_section_accessor_delete( parray_t parray ) { delete parray; }
482 
elfio_array_get_entries_num( parray_t parray )483 Elf_Xword elfio_array_get_entries_num( parray_t parray )
484 {
485     return parray->get_entries_num();
486 }
487 
elfio_array_get_entry( parray_t parray, Elf_Xword index, Elf64_Addr* paddress )488 bool elfio_array_get_entry( parray_t    parray,
489                             Elf_Xword   index,
490                             Elf64_Addr* paddress )
491 {
492     bool ret = parray->get_entry( index, *paddress );
493 
494     return ret;
495 }
496 
elfio_array_add_entry( parray_t parray, Elf64_Addr address )497 void elfio_array_add_entry( parray_t parray, Elf64_Addr address )
498 {
499     parray->add_entry( address );
500 }
501