diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d020756 --- /dev/null +++ b/Makefile @@ -0,0 +1,27 @@ +LIB_DIR=lib +TARGET=$(LIB_DIR)/libdwarfinterpret.so +SRC=src/DwarfInterpret.cpp + +INCLUDE_DIR=include + +CXX=g++ +CXXFLAGS=-Wall -Wextra -O2 --std=c++14 +CXXLIBS=-ldwarfpp -ldwarf -lelf -lc++fileno +CXXINCLUDE=-I$(INCLUDE_DIR) + + +OBJS = $(SRC:.cpp=.o) + +############################################################################### + +all: $(TARGET) + +$(TARGET): $(OBJS) + mkdir -p "$$(dirname "$@")" + $(CXX) $(CXXFLAGS) $(CXXLIBS) $(CXXINCLUDE) $^ -shared -o "$@" + +%.o: %.cpp + $(CXX) $(CXXFLAGS) $(CXXINCLUDE) -fPIC -c "$<" -o "$@" + +clean: + rm -f $(OBJS) $(TARGET) diff --git a/include/DwarfInterpret.hpp b/include/DwarfInterpret.hpp new file mode 100644 index 0000000..2f68908 --- /dev/null +++ b/include/DwarfInterpret.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include +#include + +#include + +class DwarfInterpret { + /** Singleton class holding a Dwarf interpret. + * Must be first instanciated with the path to the binary being run, with a + * call to `instanciate`, and can afterwards be accessed with calls to + * `acquire`. + */ + + public: + class NotInstanciated: public std::exception {}; + class AlreadyInstanciated: public std::exception {}; + + DwarfInterpret(DwarfInterpret const&) = delete; + void operator=(DwarfInterpret const&) = delete; + + static DwarfInterpret& acquire(); + static DwarfInterpret& instanciate(const std::string& elf_path); + + private: + DwarfInterpret(const std::string& elf_path); + + private: // members + static std::unique_ptr instance; + + dwarf::core::root_die root_die; + int elf_machine; + + friend class std::unique_ptr; +}; diff --git a/src/DwarfInterpret.cpp b/src/DwarfInterpret.cpp new file mode 100644 index 0000000..fe2d2bd --- /dev/null +++ b/src/DwarfInterpret.cpp @@ -0,0 +1,39 @@ +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +DwarfInterpret::DwarfInterpret(const std::string& elf_path) + : root_die(fileno(std::ifstream(elf_path))) +{ + //std::ifstream file_in(elf_path); + //root_die = dwarf::core::root_die(fileno(file_in)); + // FIXME this ^ deserves some checks. But this looks tedious. + + GElf_Ehdr ehdr; + GElf_Ehdr *ret = gelf_getehdr(root_die.get_elf(), &ehdr); + assert(ret != 0); + elf_machine = ehdr.e_machine; +} + +DwarfInterpret& DwarfInterpret::acquire() { + if(DwarfInterpret::instance == nullptr) + throw NotInstanciated(); + return *(DwarfInterpret::instance); +} + +DwarfInterpret& DwarfInterpret::instanciate(const std::string& elf_path) { + if(DwarfInterpret::instance != nullptr) + throw AlreadyInstanciated(); + DwarfInterpret::instance = std::unique_ptr( + new DwarfInterpret(elf_path)); + return *(DwarfInterpret::instance); +}