1/*
2Copyright (C) 2001-present by Serge Lamikhov-Center
3
4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20THE SOFTWARE.
21*/
22
23#include <stdio.h>
24#include <string.h>
25
26#include <elfio/elf_types.hpp>
27#include "elfio_c_wrapper.h"
28
29int main( int argc, char* argv[] )
30{
31    pelfio_t pelfio = elfio_new();
32    bool     ret;
33
34    if ( argc == 1 )
35        ret = elfio_load( pelfio, argv[0] );
36    else
37        ret = elfio_load( pelfio, argv[1] );
38
39    if ( !ret ) {
40        printf( "Can't load ELF file\n" );
41        return 1;
42    }
43
44    char msg[128];
45    ret = elfio_validate( pelfio, msg, 128 );
46
47    if ( !ret ) {
48        printf( "Validation errors:\n" );
49        printf( "%s\n", msg );
50        return 2;
51    }
52
53    //-----------------------------------------------------------------------------
54    // elfio
55    //-----------------------------------------------------------------------------
56    printf( "Header size   : %d\n", elfio_get_header_size( pelfio ) );
57    printf( "Version       : %d\n", elfio_get_version( pelfio ) );
58    printf( "Section Entry : %d\n", elfio_get_section_entry_size( pelfio ) );
59    printf( "Segment Entry : %d\n", elfio_get_segment_entry_size( pelfio ) );
60
61    /* Uncomment a printf block of the interest */
62
63    //-----------------------------------------------------------------------------
64    // section
65    //-----------------------------------------------------------------------------
66    int secno = elfio_get_sections_num( pelfio );
67    printf( "Sections No   : %d\n", secno );
68
69    for ( int i = 0; i < secno; i++ ) {
70        psection_t psection = elfio_get_section_by_index( pelfio, i );
71        char       buff[128];
72        elfio_section_get_name( psection, buff, 100 );
73        // printf( "    [%02d] %s\n", i, buff );
74        // printf( "        %08lx : %08lx\n",
75        //         elfio_section_get_address( psection ),
76        //         elfio_section_get_size( psection ) );
77    }
78
79    //-----------------------------------------------------------------------------
80    // segment
81    //-----------------------------------------------------------------------------
82    int segno = elfio_get_segments_num( pelfio );
83    printf( "Segments No   : %d\n", segno );
84
85    for ( int i = 0; i < segno; i++ ) {
86        psegment_t psegment = elfio_get_segment_by_index( pelfio, i );
87        elfio_segment_get_file_size( psegment );
88        // printf( "    [%02d] %08lx : %08lx : %08lx\n", i,
89        //         elfio_segment_get_virtual_address( psegment ),
90        //         elfio_segment_get_memory_size( psegment ),
91        //         elfio_segment_get_file_size( psegment ) );
92    }
93
94    //-----------------------------------------------------------------------------
95    // symbol
96    //-----------------------------------------------------------------------------
97    psection_t psection = elfio_get_section_by_name( pelfio, ".symtab" );
98    psymbol_t  psymbols = elfio_symbol_section_accessor_new( pelfio, psection );
99    Elf_Xword  symno    = elfio_symbol_get_symbols_num( psymbols );
100    for ( int i = 0; i < symno; i++ ) {
101        char          name[128];
102        Elf64_Addr    value;
103        Elf_Xword     size;
104        unsigned char bind;
105        unsigned char type;
106        Elf_Half      section_index;
107        unsigned char other;
108        elfio_symbol_get_symbol( psymbols, i, name, 128, &value, &size, &bind,
109                                 &type, &section_index, &other );
110        // printf( "[%4d] %10lu, %4lu %s\n", i, value, size, name );
111    }
112    elfio_symbol_section_accessor_delete( psymbols );
113
114    //-----------------------------------------------------------------------------
115    // relocation
116    //-----------------------------------------------------------------------------
117    psection = elfio_get_section_by_name( pelfio, ".rela.dyn" );
118    prelocation_t preloc =
119        elfio_relocation_section_accessor_new( pelfio, psection );
120    Elf_Xword relno = elfio_relocation_get_entries_num( preloc );
121    for ( int i = 0; i < relno; i++ ) {
122        Elf64_Addr offset;
123        Elf_Word   symbol;
124        Elf_Word   type;
125        Elf_Sxword addend;
126        elfio_relocation_get_entry( preloc, i, &offset, &symbol, &type,
127                                    &addend );
128        // printf( "[%4d] %16lx, %08x %08x %16lx\n", i, offset, symbol, type, addend );
129    }
130    elfio_relocation_section_accessor_delete( preloc );
131
132    //-----------------------------------------------------------------------------
133    // string
134    //-----------------------------------------------------------------------------
135    psection            = elfio_get_section_by_name( pelfio, ".strtab" );
136    pstring_t   pstring = elfio_string_section_accessor_new( psection );
137    Elf_Word    pos     = 0;
138    const char* str     = elfio_string_get_string( pstring, pos );
139    while ( str ) {
140        pos += (Elf_Word)strlen( str ) + 1;
141        str = elfio_string_get_string( pstring, pos );
142        // printf( "%s\n", str );
143    }
144    elfio_string_section_accessor_delete( pstring );
145
146    //-----------------------------------------------------------------------------
147    // note
148    //-----------------------------------------------------------------------------
149    psection       = elfio_get_section_by_name( pelfio, ".note.gnu.build-id" );
150    pnote_t pnote  = elfio_note_section_accessor_new( pelfio, psection );
151    int     noteno = elfio_note_get_notes_num( pnote );
152    for ( int i = 0; i < noteno; i++ ) {
153        Elf_Word type;
154        char     name[128];
155        int      name_len = 128;
156        char*    desc;
157        Elf_Word descSize = 128;
158        elfio_note_get_note( pnote, i, &type, name, name_len, (void**)&desc,
159                             &descSize );
160        // printf( "[%4d] %s %08x\n", i, name, descSize );
161    }
162    elfio_note_section_accessor_delete( pnote );
163
164    //-----------------------------------------------------------------------------
165    // dynamic
166    //-----------------------------------------------------------------------------
167    psection = elfio_get_section_by_name( pelfio, ".dynamic" );
168    pdynamic_t pdynamic =
169        elfio_dynamic_section_accessor_new( pelfio, psection );
170    Elf_Xword dynno = elfio_dynamic_get_entries_num( pdynamic );
171    for ( int i = 0; i < dynno; i++ ) {
172        Elf_Xword tag;
173        Elf_Xword value;
174        char      str[128];
175        elfio_dynamic_get_entry( pdynamic, i, &tag, &value, str, 128 );
176        // printf( "[%4d] %16lx %16lx %s\n", i, tag, value, str );
177    }
178    elfio_dynamic_section_accessor_delete( pdynamic );
179
180    //-----------------------------------------------------------------------------
181    // array
182    //-----------------------------------------------------------------------------
183    psection = elfio_get_section_by_name( pelfio, ".init_array" );
184    if ( psection != 0 ) {
185        parray_t  parray = elfio_array_section_accessor_new( pelfio, psection );
186        Elf_Xword arrno  = elfio_array_get_entries_num( parray );
187        for ( int i = 0; i < arrno; i++ ) {
188            Elf64_Addr addr;
189            elfio_array_get_entry( parray, i, &addr );
190            // printf( "[%4d] %16lx\n", i, addr );
191        }
192        elfio_array_section_accessor_delete( parray );
193    }
194
195    elfio_delete( pelfio );
196
197    return 0;
198}
199