mirror of
https://github.com/serge1/ELFIO.git
synced 2025-01-29 21:32:44 +00:00
Add .modinfo section accessor
This commit is contained in:
parent
4862d525e7
commit
b4c245f5a8
2
.gitignore
vendored
2
.gitignore
vendored
@ -45,6 +45,8 @@ tests/elf_examples/ppc-32bit-testcopy*.elf
|
||||
tests/elf_examples/null_section_inside_segment*
|
||||
tests/elf_examples/segment_containing_no_section*
|
||||
tests/elf_examples/test_symbols_order.elf
|
||||
tests/elf_examples/zavl_gen.ko
|
||||
|
||||
examples/writer/hello_x86_64
|
||||
examples/write_obj/hello
|
||||
|
||||
|
@ -946,6 +946,7 @@ class elfio
|
||||
#include <elfio/elfio_note.hpp>
|
||||
#include <elfio/elfio_relocation.hpp>
|
||||
#include <elfio/elfio_dynamic.hpp>
|
||||
#include <elfio/elfio_modinfo.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( pop )
|
||||
|
126
elfio/elfio_modinfo.hpp
Normal file
126
elfio/elfio_modinfo.hpp
Normal file
@ -0,0 +1,126 @@
|
||||
/*
|
||||
Copyright (C) 2001-2020 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_MODINFO_HPP
|
||||
#define ELFIO_MODINFO_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace ELFIO {
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
template <class S> class modinfo_section_accessor_template
|
||||
{
|
||||
public:
|
||||
//------------------------------------------------------------------------------
|
||||
modinfo_section_accessor_template( S* section_ )
|
||||
: modinfo_section( section_ )
|
||||
{
|
||||
process_section();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Word get_attribute_num() const { return content.size(); }
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool
|
||||
get_attribute( Elf_Word no, std::string& field, std::string& value ) const
|
||||
{
|
||||
if ( no < content.size() ) {
|
||||
field = content[no].first;
|
||||
value = content[no].second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
bool get_attribute( std::string field_name, std::string& value ) const
|
||||
{
|
||||
for ( auto i = content.begin(); i != content.end(); i++ ) {
|
||||
if ( field_name == i->first ) {
|
||||
value = i->second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Elf_Word add_attribute( std::string field_name, std::string value )
|
||||
{
|
||||
Elf_Word current_position = 0;
|
||||
|
||||
if ( modinfo_section ) {
|
||||
// Strings are addeded to the end of the current section data
|
||||
current_position = (Elf_Word)modinfo_section->get_size();
|
||||
|
||||
std::string attribute = field_name + "=" + value;
|
||||
|
||||
modinfo_section->append_data( attribute + '\0' );
|
||||
content.push_back(
|
||||
std::pair<std::string, std::string>( field_name, value ) );
|
||||
}
|
||||
|
||||
return current_position;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
void process_section()
|
||||
{
|
||||
const char* pdata = modinfo_section->get_data();
|
||||
if ( pdata ) {
|
||||
ELFIO::Elf_Xword i = 0;
|
||||
while ( i < modinfo_section->get_size() ) {
|
||||
while ( i < modinfo_section->get_size() && !pdata[i] )
|
||||
i++;
|
||||
if ( i < modinfo_section->get_size() ) {
|
||||
std::string info = pdata + i;
|
||||
size_t loc = info.find( '=' );
|
||||
std::pair<std::string, std::string> attribute(
|
||||
info.substr( 0, loc ), info.substr( loc + 1 ) );
|
||||
|
||||
content.push_back( attribute );
|
||||
|
||||
i += info.length();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
private:
|
||||
S* modinfo_section;
|
||||
std::vector<std::pair<std::string, std::string>> content;
|
||||
};
|
||||
|
||||
using modinfo_section_accessor = modinfo_section_accessor_template<section>;
|
||||
using const_modinfo_section_accessor =
|
||||
modinfo_section_accessor_template<const section>;
|
||||
|
||||
} // namespace ELFIO
|
||||
|
||||
#endif // ELFIO_MODINFO_HPP
|
122
tests/ELFIOTest2.cpp
Normal file
122
tests/ELFIOTest2.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
#ifdef _MSC_VER
|
||||
#define _SCL_SECURE_NO_WARNINGS
|
||||
#define ELFIO_NO_INTTYPES
|
||||
#endif
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/test/tools/output_test_stream.hpp>
|
||||
using boost::test_tools::output_test_stream;
|
||||
|
||||
#include <elfio/elfio.hpp>
|
||||
|
||||
using namespace ELFIO;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_AUTO_TEST_CASE( modinfo_read )
|
||||
{
|
||||
elfio reader;
|
||||
BOOST_REQUIRE_EQUAL( reader.load( "elf_examples/zavl.ko" ), true );
|
||||
|
||||
section* modinfo_sec = reader.sections[".modinfo"];
|
||||
BOOST_REQUIRE_NE( modinfo_sec, nullptr );
|
||||
|
||||
const_modinfo_section_accessor modinfo( modinfo_sec );
|
||||
BOOST_REQUIRE_EQUAL( modinfo.get_attribute_num(), 9 );
|
||||
|
||||
struct
|
||||
{
|
||||
std::string field;
|
||||
std::string value;
|
||||
} attributes[] = { { "version", "0.8.3-1ubuntu12.1" },
|
||||
{ "license", "CDDL" },
|
||||
{ "author", "OpenZFS on Linux" },
|
||||
{ "description", "Generic AVL tree implementation" },
|
||||
{ "srcversion", "98E85778E754CF75DEF9E8E" },
|
||||
{ "depends", "spl" },
|
||||
{ "retpoline", "Y" },
|
||||
{ "name", "zavl" },
|
||||
{ "vermagic", "5.4.0-42-generic SMP mod_unload " } };
|
||||
|
||||
for ( auto i = 0; i < sizeof( attributes ) / sizeof( attributes[0] );
|
||||
i++ ) {
|
||||
std::string field;
|
||||
std::string value;
|
||||
modinfo.get_attribute( i, field, value );
|
||||
|
||||
BOOST_CHECK_EQUAL( field, attributes[i].field );
|
||||
BOOST_CHECK_EQUAL( value, attributes[i].value );
|
||||
}
|
||||
|
||||
for ( auto i = 0; i < sizeof( attributes ) / sizeof( attributes[0] );
|
||||
i++ ) {
|
||||
std::string field = attributes[i].field;
|
||||
std::string value;
|
||||
modinfo.get_attribute( field, value );
|
||||
|
||||
BOOST_CHECK_EQUAL( value, attributes[i].value );
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
BOOST_AUTO_TEST_CASE( modinfo_write )
|
||||
{
|
||||
elfio writer;
|
||||
BOOST_REQUIRE_EQUAL( writer.load( "elf_examples/zavl.ko" ), true );
|
||||
|
||||
section* modinfo_sec = writer.sections[".modinfo"];
|
||||
BOOST_REQUIRE_NE( modinfo_sec, nullptr );
|
||||
|
||||
modinfo_section_accessor modinfo( modinfo_sec );
|
||||
BOOST_REQUIRE_EQUAL( modinfo.get_attribute_num(), 9 );
|
||||
|
||||
modinfo.add_attribute( "test1", "value1" );
|
||||
modinfo.add_attribute( "test2", "value2" );
|
||||
|
||||
BOOST_REQUIRE_EQUAL( modinfo.get_attribute_num(), 11 );
|
||||
|
||||
BOOST_REQUIRE_EQUAL( writer.save( "elf_examples/zavl_gen.ko" ), true );
|
||||
|
||||
elfio reader;
|
||||
BOOST_REQUIRE_EQUAL( reader.load( "elf_examples/zavl_gen.ko" ), true );
|
||||
|
||||
modinfo_sec = reader.sections[".modinfo"];
|
||||
BOOST_REQUIRE_NE( modinfo_sec, nullptr );
|
||||
|
||||
const_modinfo_section_accessor modinfo1( modinfo_sec );
|
||||
BOOST_REQUIRE_EQUAL( modinfo1.get_attribute_num(), 11 );
|
||||
|
||||
struct
|
||||
{
|
||||
std::string field;
|
||||
std::string value;
|
||||
} attributes[] = { { "version", "0.8.3-1ubuntu12.1" },
|
||||
{ "license", "CDDL" },
|
||||
{ "author", "OpenZFS on Linux" },
|
||||
{ "description", "Generic AVL tree implementation" },
|
||||
{ "srcversion", "98E85778E754CF75DEF9E8E" },
|
||||
{ "depends", "spl" },
|
||||
{ "retpoline", "Y" },
|
||||
{ "name", "zavl" },
|
||||
{ "vermagic", "5.4.0-42-generic SMP mod_unload " },
|
||||
{ "test1", "value1" },
|
||||
{ "test2", "value2" } };
|
||||
|
||||
for ( auto i = 0; i < sizeof( attributes ) / sizeof( attributes[0] );
|
||||
i++ ) {
|
||||
std::string field;
|
||||
std::string value;
|
||||
modinfo.get_attribute( i, field, value );
|
||||
|
||||
BOOST_CHECK_EQUAL( field, attributes[i].field );
|
||||
BOOST_CHECK_EQUAL( value, attributes[i].value );
|
||||
}
|
||||
|
||||
for ( auto i = 0; i < sizeof( attributes ) / sizeof( attributes[0] );
|
||||
i++ ) {
|
||||
std::string field = attributes[i].field;
|
||||
std::string value;
|
||||
modinfo.get_attribute( field, value );
|
||||
|
||||
BOOST_CHECK_EQUAL( value, attributes[i].value );
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/..
|
||||
bin_PROGRAMS = ELFIOTest
|
||||
ELFIOTest_SOURCES = ELFIOTest.cpp ELFIOTest1.cpp
|
||||
ELFIOTest_SOURCES = ELFIOTest.cpp ELFIOTest1.cpp ELFIOTest2.cpp
|
||||
|
||||
TESTS=runELFtests
|
||||
|
@ -101,7 +101,8 @@ CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__installdirs = "$(DESTDIR)$(bindir)"
|
||||
PROGRAMS = $(bin_PROGRAMS)
|
||||
am_ELFIOTest_OBJECTS = ELFIOTest.$(OBJEXT) ELFIOTest1.$(OBJEXT)
|
||||
am_ELFIOTest_OBJECTS = ELFIOTest.$(OBJEXT) ELFIOTest1.$(OBJEXT) \
|
||||
ELFIOTest2.$(OBJEXT)
|
||||
ELFIOTest_OBJECTS = $(am_ELFIOTest_OBJECTS)
|
||||
ELFIOTest_LDADD = $(LDADD)
|
||||
AM_V_P = $(am__v_P_@AM_V@)
|
||||
@ -120,7 +121,7 @@ DEFAULT_INCLUDES = -I.@am__isrc@
|
||||
depcomp = $(SHELL) $(top_srcdir)/../depcomp
|
||||
am__maybe_remake_depfiles = depfiles
|
||||
am__depfiles_remade = ./$(DEPDIR)/ELFIOTest.Po \
|
||||
./$(DEPDIR)/ELFIOTest1.Po
|
||||
./$(DEPDIR)/ELFIOTest1.Po ./$(DEPDIR)/ELFIOTest2.Po
|
||||
am__mv = mv -f
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
@ -472,7 +473,7 @@ top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/..
|
||||
ELFIOTest_SOURCES = ELFIOTest.cpp ELFIOTest1.cpp
|
||||
ELFIOTest_SOURCES = ELFIOTest.cpp ELFIOTest1.cpp ELFIOTest2.cpp
|
||||
TESTS = runELFtests
|
||||
all: all-am
|
||||
|
||||
@ -566,6 +567,7 @@ distclean-compile:
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ELFIOTest.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ELFIOTest1.Po@am__quote@ # am--include-marker
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ELFIOTest2.Po@am__quote@ # am--include-marker
|
||||
|
||||
$(am__depfiles_remade):
|
||||
@$(MKDIR_P) $(@D)
|
||||
@ -1024,6 +1026,7 @@ distclean: distclean-am
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -f ./$(DEPDIR)/ELFIOTest.Po
|
||||
-rm -f ./$(DEPDIR)/ELFIOTest1.Po
|
||||
-rm -f ./$(DEPDIR)/ELFIOTest2.Po
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-tags
|
||||
@ -1073,6 +1076,7 @@ maintainer-clean: maintainer-clean-am
|
||||
-rm -rf $(top_srcdir)/autom4te.cache
|
||||
-rm -f ./$(DEPDIR)/ELFIOTest.Po
|
||||
-rm -f ./$(DEPDIR)/ELFIOTest1.Po
|
||||
-rm -f ./$(DEPDIR)/ELFIOTest2.Po
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
|
BIN
tests/elf_examples/zavl.ko
Normal file
BIN
tests/elf_examples/zavl.ko
Normal file
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user