123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- // Copyright 2014 Renato Tegon Forti, Antony Polukhin.
- // Copyright 2015-2019 Antony Polukhin.
- //
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE_1_0.txt
- // or copy at http://www.boost.org/LICENSE_1_0.txt)
- // For more information, see http://www.boost.org
- #include <boost/dll/detail/elf_info.hpp>
- #include <boost/dll/detail/pe_info.hpp>
- #include <boost/dll/detail/macho_info.hpp>
- #include <boost/static_assert.hpp>
- #include <boost/core/lightweight_test.hpp>
- #include <boost/predef/os.h>
- #if BOOST_OS_WINDOWS
- # include <windows.h>
- #elif BOOST_OS_MACOS || BOOST_OS_IOS
- # include <mach-o/loader.h>
- # include <mach-o/nlist.h>
- #elif BOOST_OS_QNX
- // QNX's copy of <elf.h> and <link.h> reside in sys folder
- # include <sys/elf.h>
- #else
- #include <elf.h>
- #endif
- namespace dd = boost::dll::detail;
- template <class T1, class T2>
- inline std::size_t get_offset(const T1& v1, const T2& v2) {
- const unsigned char* p1 = reinterpret_cast<const unsigned char*>(&v1);
- const unsigned char* p2 = reinterpret_cast<const unsigned char*>(&v2);
- if (p1 < p2) {
- return static_cast<std::size_t>(p2 - p1);
- }
- return static_cast<std::size_t>(p1 - p2);
- }
- #define CHECK_FIELD(Field) \
- BOOST_STATIC_ASSERT(sizeof(v1.Field) == sizeof(v2.Field)); \
- BOOST_TEST(get_offset(v1, v1.Field) == get_offset(v2, v2.Field)) \
- /**/
- // ELF structures
- template <class T1, class T2>
- void elf_header_checks(const T1& v1, const T2& v2) {
- BOOST_STATIC_ASSERT(sizeof(T1) == sizeof(T2));
- CHECK_FIELD(e_ident);
- CHECK_FIELD(e_type);
- CHECK_FIELD(e_machine);
- CHECK_FIELD(e_version);
- CHECK_FIELD(e_entry);
- CHECK_FIELD(e_phoff);
- CHECK_FIELD(e_shoff);
- CHECK_FIELD(e_flags);
- CHECK_FIELD(e_ehsize);
- CHECK_FIELD(e_phentsize);
- CHECK_FIELD(e_phnum);
- CHECK_FIELD(e_shentsize);
- CHECK_FIELD(e_shnum);
- CHECK_FIELD(e_shstrndx);
- }
- template <class T1, class T2>
- void elf_sheader_checks(const T1& v1, const T2& v2) {
- BOOST_STATIC_ASSERT(sizeof(T1) == sizeof(T2));
- CHECK_FIELD(sh_name);
- CHECK_FIELD(sh_type);
- CHECK_FIELD(sh_flags);
- CHECK_FIELD(sh_addr);
- CHECK_FIELD(sh_offset);
- CHECK_FIELD(sh_size);
- CHECK_FIELD(sh_link);
- CHECK_FIELD(sh_info);
- CHECK_FIELD(sh_addralign);
- CHECK_FIELD(sh_entsize);
- }
- template <class T1, class T2>
- void elf_sym_header_checks(const T1& v1, const T2& v2) {
- BOOST_STATIC_ASSERT(sizeof(T1) == sizeof(T2));
- CHECK_FIELD(st_name);
- CHECK_FIELD(st_value);
- CHECK_FIELD(st_size);
- CHECK_FIELD(st_info);
- CHECK_FIELD(st_other);
- CHECK_FIELD(st_shndx);
- }
- // PE structures
- template <class T>
- void generic_header_check(const T& v1, const dd::IMAGE_DOS_HEADER_& v2) {
- BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
- CHECK_FIELD(e_magic);
- CHECK_FIELD(e_cblp);
- CHECK_FIELD(e_cp);
- CHECK_FIELD(e_crlc);
- CHECK_FIELD(e_cparhdr);
- CHECK_FIELD(e_minalloc);
- CHECK_FIELD(e_maxalloc);
- CHECK_FIELD(e_ss);
- CHECK_FIELD(e_sp);
- CHECK_FIELD(e_csum);
- CHECK_FIELD(e_ip);
- CHECK_FIELD(e_cs);
- CHECK_FIELD(e_lfarlc);
- CHECK_FIELD(e_ovno);
- CHECK_FIELD(e_res);
- CHECK_FIELD(e_oemid);
- CHECK_FIELD(e_oeminfo);
- CHECK_FIELD(e_res2);
- CHECK_FIELD(e_lfanew);
- }
- template <class T>
- void generic_header_check(const T& v1, const dd::IMAGE_FILE_HEADER_& v2) {
- BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
- CHECK_FIELD(Machine);
- CHECK_FIELD(NumberOfSections);
- CHECK_FIELD(TimeDateStamp);
- CHECK_FIELD(PointerToSymbolTable);
- CHECK_FIELD(NumberOfSymbols);
- CHECK_FIELD(SizeOfOptionalHeader);
- CHECK_FIELD(Characteristics);
- }
- template <class T>
- void generic_header_check(const T& v1, const dd::IMAGE_DATA_DIRECTORY_& v2) {
- BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
- CHECK_FIELD(VirtualAddress);
- CHECK_FIELD(Size);
- }
- template <class T>
- void generic_header_check(const T& v1, const dd::IMAGE_EXPORT_DIRECTORY_& v2) {
- BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
-
- CHECK_FIELD(Characteristics);
- CHECK_FIELD(TimeDateStamp);
- CHECK_FIELD(MajorVersion);
- CHECK_FIELD(MinorVersion);
- CHECK_FIELD(Name);
- CHECK_FIELD(Base);
- CHECK_FIELD(NumberOfFunctions);
- CHECK_FIELD(NumberOfNames);
- CHECK_FIELD(AddressOfFunctions);
- CHECK_FIELD(AddressOfNames);
- CHECK_FIELD(AddressOfNameOrdinals);
- }
- template <class T>
- void generic_header_check(const T& v1, const dd::IMAGE_SECTION_HEADER_& v2) {
- BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
-
- CHECK_FIELD(Name);
- CHECK_FIELD(VirtualAddress);
- CHECK_FIELD(SizeOfRawData);
- CHECK_FIELD(PointerToRawData);
- CHECK_FIELD(PointerToRelocations);
- CHECK_FIELD(PointerToLinenumbers);
- CHECK_FIELD(NumberOfRelocations);
- CHECK_FIELD(NumberOfLinenumbers);
- CHECK_FIELD(Characteristics);
- }
- template <class T, class AddrT>
- void generic_header_check(const T& v1, const dd::IMAGE_OPTIONAL_HEADER_template<AddrT>& v2) {
- BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
-
- CHECK_FIELD(Magic);
- CHECK_FIELD(MajorLinkerVersion);
- CHECK_FIELD(MinorLinkerVersion);
- CHECK_FIELD(SizeOfCode);
- CHECK_FIELD(SizeOfInitializedData);
- CHECK_FIELD(SizeOfUninitializedData);
- CHECK_FIELD(AddressOfEntryPoint);
- CHECK_FIELD(ImageBase);
- CHECK_FIELD(SectionAlignment);
- CHECK_FIELD(FileAlignment);
- CHECK_FIELD(MajorOperatingSystemVersion);
- CHECK_FIELD(MinorOperatingSystemVersion);
- CHECK_FIELD(MajorImageVersion);
- CHECK_FIELD(MinorImageVersion);
- CHECK_FIELD(MajorSubsystemVersion);
- CHECK_FIELD(MinorSubsystemVersion);
- CHECK_FIELD(Win32VersionValue);
- CHECK_FIELD(SizeOfImage);
- CHECK_FIELD(SizeOfHeaders);
- CHECK_FIELD(CheckSum);
- CHECK_FIELD(Subsystem);
- CHECK_FIELD(DllCharacteristics);
- CHECK_FIELD(SizeOfStackReserve);
- CHECK_FIELD(SizeOfStackCommit);
- CHECK_FIELD(SizeOfHeapReserve);
- CHECK_FIELD(SizeOfHeapCommit);
- CHECK_FIELD(LoaderFlags);
- CHECK_FIELD(NumberOfRvaAndSizes);
- CHECK_FIELD(DataDirectory);
- }
- template <class T, class AddrT>
- void generic_header_check(const T& v1, const dd::IMAGE_NT_HEADERS_template<AddrT>& v2) {
- BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
- CHECK_FIELD(Signature);
- CHECK_FIELD(FileHeader);
- CHECK_FIELD(OptionalHeader);
- }
- template <class T, class AddrT>
- void generic_header_check(const T& v1, const dd::mach_header_template<AddrT>& v2) {
- BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
- CHECK_FIELD(magic);
- CHECK_FIELD(cputype);
- CHECK_FIELD(cpusubtype);
- CHECK_FIELD(filetype);
- CHECK_FIELD(ncmds);
- CHECK_FIELD(sizeofcmds);
- //CHECK_FIELD(flags);
- }
- template <class T, class AddrT>
- void generic_header_check(const T& v1, const dd::segment_command_template<AddrT>& v2) {
- BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
- CHECK_FIELD(cmd);
- CHECK_FIELD(cmdsize);
- CHECK_FIELD(segname);
- CHECK_FIELD(vmaddr);
- CHECK_FIELD(vmsize);
- CHECK_FIELD(fileoff);
- CHECK_FIELD(filesize);
- CHECK_FIELD(maxprot);
- CHECK_FIELD(initprot);
- CHECK_FIELD(nsects);
- CHECK_FIELD(flags);
- }
- template <class T, class AddrT>
- void generic_header_check(const T& v1, const dd::section_template<AddrT>& v2) {
- BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
- CHECK_FIELD(sectname);
- CHECK_FIELD(segname);
- CHECK_FIELD(addr);
- CHECK_FIELD(size);
- CHECK_FIELD(offset);
- CHECK_FIELD(align);
- CHECK_FIELD(reloff);
- CHECK_FIELD(nreloc);
- CHECK_FIELD(flags);
- //CHECK_FIELD(reserved vs reserveed1&reserved2);
- }
- template <class T>
- void generic_header_check(const T& v1, const dd::symtab_command_& v2) {
- BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
-
- CHECK_FIELD(cmd);
- CHECK_FIELD(cmdsize);
- CHECK_FIELD(symoff);
- CHECK_FIELD(nsyms);
- CHECK_FIELD(stroff);
- CHECK_FIELD(strsize);
- }
- template <class T, class AddrT>
- void generic_header_check(const T& v1, const dd::nlist_template<AddrT>& v2) {
- BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
-
- //CHECK_FIELD(n_strx);
- CHECK_FIELD(n_type);
- CHECK_FIELD(n_sect);
- CHECK_FIELD(n_desc);
- CHECK_FIELD(n_value);
- }
- template <class T>
- void generic_header_check(const T& v1, const dd::load_command_& v2) {
- BOOST_STATIC_ASSERT(sizeof(v1) == sizeof(v2));
-
- CHECK_FIELD(cmd);
- CHECK_FIELD(cmdsize);
- }
- // Unit Tests
- int main(int /*argc*/, char* /*argv*/[]) {
- #if BOOST_OS_WINDOWS
- generic_header_check(::IMAGE_DOS_HEADER(), dd::IMAGE_DOS_HEADER_());
- generic_header_check(::IMAGE_FILE_HEADER(), dd::IMAGE_FILE_HEADER_());
- generic_header_check(::IMAGE_DATA_DIRECTORY(), dd::IMAGE_DATA_DIRECTORY_());
- generic_header_check(::IMAGE_EXPORT_DIRECTORY(), dd::IMAGE_EXPORT_DIRECTORY_());
- generic_header_check(::IMAGE_SECTION_HEADER(), dd::IMAGE_SECTION_HEADER_());
- generic_header_check(::IMAGE_OPTIONAL_HEADER32(), dd::IMAGE_OPTIONAL_HEADER32_());
- generic_header_check(::IMAGE_OPTIONAL_HEADER64(), dd::IMAGE_OPTIONAL_HEADER64_());
- generic_header_check(::IMAGE_NT_HEADERS32(), dd::IMAGE_NT_HEADERS32_());
- generic_header_check(::IMAGE_NT_HEADERS64(), dd::IMAGE_NT_HEADERS64_());
- #elif BOOST_OS_MACOS || BOOST_OS_IOS
- generic_header_check(::mach_header(), dd::mach_header_32_());
- generic_header_check(::mach_header_64(), dd::mach_header_64_());
- generic_header_check(::segment_command(), dd::segment_command_32_());
- generic_header_check(::segment_command_64(), dd::segment_command_64_());
- generic_header_check(::section(), dd::section_32_());
- generic_header_check(::section_64(), dd::section_64_());
- generic_header_check(::load_command(), dd::load_command_());
- generic_header_check(::symtab_command(), dd::symtab_command_());
- struct ::nlist nl32_var;
- generic_header_check(nl32_var, dd::nlist_32_());
- struct ::nlist_64 nl64_var;
- generic_header_check(nl64_var, dd::nlist_64_());
- #else
- elf_header_checks(::Elf32_Ehdr(), dd::Elf32_Ehdr_());
- elf_header_checks(::Elf64_Ehdr(), dd::Elf64_Ehdr_());
- elf_sheader_checks(::Elf32_Shdr(), dd::Elf32_Shdr_());
- elf_sheader_checks(::Elf64_Shdr(), dd::Elf64_Shdr_());
- elf_sym_header_checks(::Elf32_Sym(), dd::Elf32_Sym_());
- elf_sym_header_checks(::Elf64_Sym(), dd::Elf64_Sym_());
- #endif
- return boost::report_errors();
- }
|