• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef ELFIO_VERSYM_HPP
24 #define ELFIO_VERSYM_HPP
25 
26 namespace ELFIO {
27 
28 //------------------------------------------------------------------------------
29 template <class S> class versym_section_accessor_template
30 {
31   public:
32     //------------------------------------------------------------------------------
versym_section_accessor_template(S * section)33     explicit versym_section_accessor_template( S* section )
34         : versym_section( section )
35     {
36         if ( section != nullptr ) {
37             entries_num = decltype( entries_num )( section->get_size() /
38                                                    sizeof( Elf_Half ) );
39         }
40     }
41 
42     //------------------------------------------------------------------------------
get_entries_num() const43     Elf_Word get_entries_num() const
44     {
45         if ( versym_section ) {
46             return entries_num;
47         }
48         return 0;
49     }
50 
51     //------------------------------------------------------------------------------
get_entry(Elf_Word no,Elf_Half & value) const52     bool get_entry( Elf_Word no, Elf_Half& value ) const
53     {
54         if ( versym_section && ( no < get_entries_num() ) ) {
55             value = ( (Elf_Half*)versym_section->get_data() )[no];
56             return true;
57         }
58 
59         return false;
60     }
61 
62     //------------------------------------------------------------------------------
modify_entry(Elf_Word no,Elf_Half value)63     bool modify_entry( Elf_Word no, Elf_Half value )
64     {
65         if ( versym_section && ( no < get_entries_num() ) ) {
66             ( (Elf_Half*)versym_section->get_data() )[no] = value;
67             return true;
68         }
69 
70         return false;
71     }
72 
73     //------------------------------------------------------------------------------
add_entry(Elf_Half value)74     bool add_entry( Elf_Half value )
75     {
76         if ( !versym_section ) {
77             return false;
78         }
79 
80         versym_section->append_data( (const char*)&value, sizeof( Elf_Half ) );
81         ++entries_num;
82 
83         return true;
84     }
85 
86     //------------------------------------------------------------------------------
87   private:
88     S*       versym_section = nullptr;
89     Elf_Word entries_num    = 0;
90 };
91 
92 using versym_section_accessor = versym_section_accessor_template<section>;
93 using const_versym_section_accessor =
94     versym_section_accessor_template<const section>;
95 
96 //------------------------------------------------------------------------------
97 template <class S> class versym_r_section_accessor_template
98 {
99   public:
100     //------------------------------------------------------------------------------
versym_r_section_accessor_template(const elfio & elf_file,S * versym_r_section)101     versym_r_section_accessor_template( const elfio& elf_file,
102                                         S*           versym_r_section )
103         : elf_file( elf_file ), versym_r_section( versym_r_section ),
104           entries_num( 0 )
105     {
106         // Find .dynamic section
107         const section* dynamic_section = elf_file.sections[".dynamic"];
108 
109         if ( dynamic_section == nullptr ) {
110             return;
111         }
112 
113         const_dynamic_section_accessor dynamic_section_acc( elf_file,
114                                                             dynamic_section );
115         Elf_Xword dyn_sec_num = dynamic_section_acc.get_entries_num();
116         for ( Elf_Xword i = 0; i < dyn_sec_num; ++i ) {
117             Elf_Xword   tag;
118             Elf_Xword   value;
119             std::string str;
120 
121             if ( dynamic_section_acc.get_entry( i, tag, value, str ) &&
122                  tag == DT_VERNEEDNUM ) {
123                 entries_num = (Elf_Word)value;
124                 break;
125             }
126         }
127     }
128 
129     //------------------------------------------------------------------------------
get_entries_num() const130     Elf_Word get_entries_num() const { return entries_num; }
131 
132     //------------------------------------------------------------------------------
get_entry(Elf_Word no,Elf_Half & version,std::string & file_name,Elf_Word & hash,Elf_Half & flags,Elf_Half & other,std::string & dep_name) const133     bool get_entry( Elf_Word     no,
134                     Elf_Half&    version,
135                     std::string& file_name,
136                     Elf_Word&    hash,
137                     Elf_Half&    flags,
138                     Elf_Half&    other,
139                     std::string& dep_name ) const
140     {
141         if ( versym_r_section == nullptr || ( no >= get_entries_num() ) ) {
142             return false;
143         }
144 
145         const_string_section_accessor string_section_acc(
146             elf_file.sections[versym_r_section->get_link()] );
147 
148         Elfxx_Verneed* verneed = (Elfxx_Verneed*)versym_r_section->get_data();
149         Elfxx_Vernaux* veraux =
150             (Elfxx_Vernaux*)( (char*)verneed + verneed->vn_aux );
151         for ( Elf_Word i = 0; i < no; ++i ) {
152             verneed = (Elfxx_Verneed*)( (char*)verneed + verneed->vn_next );
153             veraux  = (Elfxx_Vernaux*)( (char*)verneed + verneed->vn_aux );
154         }
155 
156         version   = verneed->vn_version;
157         file_name = string_section_acc.get_string( verneed->vn_file );
158         hash      = veraux->vna_hash;
159         flags     = veraux->vna_flags;
160         other     = veraux->vna_other;
161         dep_name  = string_section_acc.get_string( veraux->vna_name );
162 
163         return true;
164     }
165 
166     //------------------------------------------------------------------------------
167   private:
168     const elfio& elf_file;
169     S*           versym_r_section = nullptr;
170     Elf_Word     entries_num      = 0;
171 };
172 
173 using versym_r_section_accessor = versym_r_section_accessor_template<section>;
174 using const_versym_r_section_accessor =
175     versym_r_section_accessor_template<const section>;
176 
177 } // namespace ELFIO
178 
179 #endif // ELFIO_VERSYM_HPP
180