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