diff options
Diffstat (limited to 'src/boost/libs/dll/test/structures_tests.cpp')
-rw-r--r-- | src/boost/libs/dll/test/structures_tests.cpp | 345 |
1 files changed, 345 insertions, 0 deletions
diff --git a/src/boost/libs/dll/test/structures_tests.cpp b/src/boost/libs/dll/test/structures_tests.cpp new file mode 100644 index 00000000..1598dc73 --- /dev/null +++ b/src/boost/libs/dll/test/structures_tests.cpp @@ -0,0 +1,345 @@ +// 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(); +} + |