mirror of
https://github.com/serge1/ELFIO.git
synced 2024-12-26 18:15:40 +00:00
Version Requirements accessor (reader) was added
This commit is contained in:
parent
89a6dfb4c1
commit
7ba15e0549
@ -550,7 +550,6 @@ constexpr unsigned char STB_MULTIDEF = 13;
|
||||
constexpr unsigned char STB_LOPROC = 13;
|
||||
constexpr unsigned char STB_HIPROC = 15;
|
||||
|
||||
|
||||
// Values of note segment descriptor types for core files
|
||||
constexpr Elf_Word NT_PRSTATUS = 1; // Contains copy of prstatus struct
|
||||
constexpr Elf_Word NT_FPREGSET = 2; // Contains copy of fpregset struct
|
||||
@ -568,7 +567,7 @@ constexpr Elf_Word NT_LWPSTATUS = 16; // Has a struct lwpstatus_t
|
||||
constexpr Elf_Word NT_LWPSINFO = 17; // Has a struct lwpsinfo_t
|
||||
constexpr Elf_Word NT_WIN32PSTATUS = 18; // Has a struct win32_pstatus
|
||||
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
|
||||
// Note name must be "LINUX"
|
||||
constexpr Elf_Word NT_PRXFPREG = 0x46e62b7f; // Contains a user_xfpregs_struct;
|
||||
@ -1056,6 +1055,24 @@ struct Elf64_Dyn
|
||||
} d_un;
|
||||
};
|
||||
|
||||
struct Elfxx_Verneed
|
||||
{
|
||||
Elf_Half vn_version;
|
||||
Elf_Half vn_cnt;
|
||||
Elf_Word vn_file;
|
||||
Elf_Word vn_aux;
|
||||
Elf_Word vn_next;
|
||||
};
|
||||
|
||||
struct Elfxx_Vernaux
|
||||
{
|
||||
Elf_Word vna_hash;
|
||||
Elf_Half vna_flags;
|
||||
Elf_Half vna_other;
|
||||
Elf_Word vna_name;
|
||||
Elf_Word vna_next;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // namespace ELFIO
|
||||
#endif
|
||||
|
@ -1050,6 +1050,7 @@ class elfio
|
||||
#include <elfio/elfio_dynamic.hpp>
|
||||
#include <elfio/elfio_array.hpp>
|
||||
#include <elfio/elfio_modinfo.hpp>
|
||||
#include <elfio/elfio_versym.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( pop )
|
||||
|
153
elfio/elfio_versym.hpp
Normal file
153
elfio/elfio_versym.hpp
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
Copyright (C) 2001-present by Serge Lamikhov-Center
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef ELFIO_VERSYM_HPP
|
||||
#define ELFIO_VERSYM_HPP
|
||||
|
||||
namespace ELFIO {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template <class S> class versym_section_accessor_template
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
versym_section_accessor_template( S* section ) : versym_section( section )
|
||||
{
|
||||
if ( section ) {
|
||||
entries_num = section->get_size() / sizeof( Elf_Half );
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Word get_entries_num() const
|
||||
{
|
||||
if ( versym_section ) {
|
||||
return entries_num;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool get_entry( Elf_Word no, Elf_Half& value ) const
|
||||
{
|
||||
if ( versym_section && ( no < get_entries_num() ) ) {
|
||||
value = ( (Elf_Half*)versym_section->get_data() )[no];
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
S* versym_section;
|
||||
Elf_Word entries_num;
|
||||
};
|
||||
|
||||
using versym_section_accessor = versym_section_accessor_template<section>;
|
||||
using const_versym_section_accessor =
|
||||
versym_section_accessor_template<const section>;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template <class S> class versym_r_section_accessor_template
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
versym_r_section_accessor_template( const elfio& elf_file,
|
||||
S* versym_r_section )
|
||||
: elf_file( elf_file ), versym_r_section( versym_r_section ),
|
||||
entries_num( 0 )
|
||||
{
|
||||
// Find .dynamic section
|
||||
const section* dynamic_section = elf_file.sections[".dynamic"];
|
||||
|
||||
if ( dynamic_section == nullptr ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const_dynamic_section_accessor dynamic_section_acc( elf_file,
|
||||
dynamic_section );
|
||||
Elf_Xword dyn_sec_num = dynamic_section_acc.get_entries_num();
|
||||
for ( Elf_Xword i = 0; i < dyn_sec_num; ++i ) {
|
||||
Elf_Xword tag;
|
||||
Elf_Xword value;
|
||||
std::string str;
|
||||
|
||||
if ( dynamic_section_acc.get_entry( i, tag, value, str ) &&
|
||||
tag == DT_VERNEEDNUM ) {
|
||||
entries_num = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Word get_entries_num() const { return entries_num; }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool 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 ) const
|
||||
{
|
||||
if ( versym_r_section == nullptr || ( no >= get_entries_num() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const_string_section_accessor string_section_acc(
|
||||
elf_file.sections[versym_r_section->get_link()] );
|
||||
|
||||
Elfxx_Verneed* verneed = (Elfxx_Verneed*)versym_r_section->get_data();
|
||||
Elfxx_Vernaux* veraux =
|
||||
(Elfxx_Vernaux*)( (char*)verneed + verneed->vn_aux );
|
||||
for ( Elf_Word i = 0; i < no; ++i ) {
|
||||
verneed = (Elfxx_Verneed*)( (char*)verneed + verneed->vn_next );
|
||||
veraux = (Elfxx_Vernaux*)( (char*)verneed + verneed->vn_aux );
|
||||
}
|
||||
|
||||
version = verneed->vn_version;
|
||||
file_name = string_section_acc.get_string( verneed->vn_file );
|
||||
hash = veraux->vna_hash;
|
||||
flags = veraux->vna_flags;
|
||||
other = veraux->vna_other;
|
||||
dep_name = string_section_acc.get_string( veraux->vna_name );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
const elfio& elf_file;
|
||||
S* versym_r_section;
|
||||
Elf_Word entries_num;
|
||||
};
|
||||
|
||||
using versym_r_section_accessor = versym_r_section_accessor_template<section>;
|
||||
using const_versym_r_section_accessor =
|
||||
versym_r_section_accessor_template<const section>;
|
||||
|
||||
} // namespace ELFIO
|
||||
|
||||
#endif // ELFIO_VERSYM_HPP
|
@ -364,46 +364,64 @@ BOOST_AUTO_TEST_CASE( gnu_version_64_le )
|
||||
|
||||
BOOST_REQUIRE_EQUAL( reader.load( "elf_examples/hello_64" ), true );
|
||||
|
||||
std::string name;
|
||||
Elf64_Addr value;
|
||||
Elf_Xword size;
|
||||
unsigned char bind;
|
||||
unsigned char type;
|
||||
Elf_Half section_index;
|
||||
unsigned char other;
|
||||
section* symsec = reader.sections[".dynsym"];
|
||||
const_symbol_section_accessor dynsym( reader, symsec );
|
||||
std::string name;
|
||||
Elf64_Addr value;
|
||||
Elf_Xword size;
|
||||
unsigned char bind;
|
||||
unsigned char type;
|
||||
Elf_Half section_index;
|
||||
unsigned char other;
|
||||
|
||||
section* versec = reader.sections[".gnu.version"];
|
||||
const_array_section_accessor<Elf64_Half> vers( reader, versec );
|
||||
section* dynsym = reader.sections[".dynsym"];
|
||||
const_symbol_section_accessor dynsym_acc( reader, dynsym );
|
||||
|
||||
section* verneed = reader.sections[".gnu.version_r"];
|
||||
const_array_section_accessor<Elf64_Half> vern( reader, verneed );
|
||||
section* gnu_version = reader.sections[".gnu.version"];
|
||||
const_versym_section_accessor gnu_version_arr( gnu_version );
|
||||
|
||||
section* gnu_version_r = reader.sections[".gnu.version_r"];
|
||||
const_versym_r_section_accessor gnu_version_r_arr( reader, gnu_version_r );
|
||||
|
||||
section* dynstr = reader.sections[".dynstr"];
|
||||
|
||||
BOOST_CHECK_EQUAL( versec->get_link(), symsec->get_index() );
|
||||
BOOST_CHECK_EQUAL( verneed->get_link(), dynstr->get_index() );
|
||||
BOOST_CHECK_EQUAL( gnu_version->get_link(), dynsym->get_index() );
|
||||
BOOST_CHECK_EQUAL( gnu_version_r->get_link(), dynstr->get_index() );
|
||||
|
||||
for ( int i = 0; i < dynsym.get_symbols_num(); i++ ) {
|
||||
BOOST_REQUIRE_EQUAL( dynsym.get_symbol( i, name, value, size, bind,
|
||||
type, section_index, other ),
|
||||
BOOST_CHECK_EQUAL( dynsym_acc.get_symbols_num(),
|
||||
gnu_version_arr.get_entries_num() );
|
||||
|
||||
for ( Elf64_Word i = 0; i < dynsym_acc.get_symbols_num(); i++ ) {
|
||||
BOOST_REQUIRE_EQUAL( dynsym_acc.get_symbol( i, name, value, size, bind,
|
||||
type, section_index,
|
||||
other ),
|
||||
true );
|
||||
|
||||
Elf64_Addr verindex = 0;
|
||||
|
||||
vers.get_entry( i, verindex );
|
||||
BOOST_CHECK_EQUAL( verindex, ( i / 2 ) * 2 );
|
||||
|
||||
const char* ptr = verneed->get_data();
|
||||
if ( verindex > 1 ) {
|
||||
Elf64_Addr value = 0;
|
||||
vern.get_entry( verindex * 8, value );
|
||||
// std::cout << value << std::endl;
|
||||
}
|
||||
Elf64_Half verindex = 0;
|
||||
gnu_version_arr.get_entry( i, verindex );
|
||||
if ( i < 2 )
|
||||
BOOST_CHECK_EQUAL( 0, verindex );
|
||||
else
|
||||
BOOST_CHECK_EQUAL( 2, verindex );
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL( gnu_version_r_arr.get_entries_num(), 1 );
|
||||
|
||||
Elf_Half version;
|
||||
std::string file_name;
|
||||
Elf_Word hash;
|
||||
Elf_Half flags;
|
||||
Elf_Half vna_other;
|
||||
std::string dep_name;
|
||||
gnu_version_r_arr.get_entry( 0, version, file_name, hash, flags, vna_other,
|
||||
dep_name );
|
||||
BOOST_CHECK_EQUAL( version, 1 );
|
||||
BOOST_CHECK_EQUAL( file_name, "libc.so.6" );
|
||||
BOOST_CHECK_EQUAL( hash, 0x09691a75 );
|
||||
BOOST_CHECK_EQUAL( flags, 0 );
|
||||
BOOST_CHECK_EQUAL( vna_other, 2 );
|
||||
BOOST_CHECK_EQUAL( dep_name, "GLIBC_2.2.5" );
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_AUTO_TEST_CASE( move_constructor_and_assignment )
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user