diff --git a/include/arch/arch_mips32.hpp b/include/arch/arch_mips32.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0d1bf435208f29204bc7bb2480f9966bf81feff8 --- /dev/null +++ b/include/arch/arch_mips32.hpp @@ -0,0 +1,33 @@ +#ifndef ARCHMIPS32_HPP +#define ARCHMIPS32_HPP + +class ZiprArchitectureHelperMIPS32_t : public ZiprArchitectureHelperBase_t +{ + public: + ZiprArchitectureHelperMIPS32_t(Zipr_SDK::Zipr_t* p_zipr_obj) : ZiprArchitectureHelperBase_t(p_zipr_obj) + { + } + + virtual IRDB_SDK::Instruction_t* createNewJumpInstruction(IRDB_SDK::FileIR_t *p_firp, IRDB_SDK::Instruction_t* p_existing) override + { + // bytes = 0b00000000 0b00000000 0b00000000 0b00010000 + // jump always with 26bit offset + const auto bits =string("\x10\x00\x00\x000",4); + auto ret=IRDB_SDK::addNewDataBits(p_firp, p_existing, bits); + const auto d=IRDB_SDK::DecodedInstruction_t::factory(ret); + assert(d->valid()); + return ret; + } + + virtual IRDB_SDK::Instruction_t* createNewHaltInstruction(IRDB_SDK::FileIR_t *p_firp, IRDB_SDK::Instruction_t* p_existing) override + { + // 0b00000000 0b00000000 0b00000000 0b00110100 + // teq $0, $0, 0 --> trap always (as $0 is always 0) + const auto bits = string("\x00\x00\x00\x34",4); + auto ret = IRDB_SDK::addNewDataBits(p_firp, p_existing, bits); + const auto d = IRDB_SDK::DecodedInstruction_t::factory(ret); + assert(d->valid()); + return ret; + } +}; +#endif diff --git a/include/patcher/patcher_mips32.hpp b/include/patcher/patcher_mips32.hpp new file mode 100644 index 0000000000000000000000000000000000000000..b3e637411fd0c2336f73aac14be0f9fb2da49757 --- /dev/null +++ b/include/patcher/patcher_mips32.hpp @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (c) 2014 Zephyr Software LLC. All rights reserved. + * + * This software is furnished under a license and/or other restrictive + * terms and may be used and copied only in accordance with such terms + * and the inclusion of the above copyright notice. This software or + * any other copies thereof may not be provided or otherwise made + * available to any other person without the express written consent + * of an authorized representative of Zephyr Software LCC. Title to, + * ownership of, and all rights in the software is retained by + * Zephyr Software LCC. + * + * Zephyr Software LLC. Proprietary Information + * + * Unless otherwise specified, the information contained in this + * directory, following this legend, and/or referenced herein is + * Zephyr Software LLC. (Zephyr) Proprietary Information. + * + * CONTACT + * + * For technical assistance, contact Zephyr Software LCC. at: + * + * + * Zephyr Software, LLC + * 2040 Tremont Rd + * Charlottesville, VA 22911 + * + * E-mail: jwd@zephyr-software.com + **************************************************************************/ + + + +#ifndef PATCHER_MIPS32 +#define PATCHER_MIPS32 + +class ZiprPatcherMIPS32_t : public ZiprPatcherBase_t +{ + // data + zipr::ZiprImpl_t* m_parent; + IRDB_SDK::FileIR_t* m_firp; + Zipr_SDK::MemorySpace_t &memory_space; + + std::map<RangeAddress_t, RangeAddress_t> redirect_map; + + public: + + ZiprPatcherMIPS32_t(Zipr_SDK::Zipr_t* p_parent); + void ApplyNopToPatch(RangeAddress_t addr) override; + void ApplyPatch(RangeAddress_t from_addr, RangeAddress_t to_addr) override; + void PatchJump(RangeAddress_t at_addr, RangeAddress_t to_addr) override; + void PatchCall(RangeAddress_t at_addr, RangeAddress_t to_addr) override; + void CallToNop(RangeAddress_t at_addr) override; + + +}; +#endif diff --git a/include/pinner/pinner_mips32.hpp b/include/pinner/pinner_mips32.hpp new file mode 100644 index 0000000000000000000000000000000000000000..8176807bc21ad2baa08f50fe58e16b1c37436c0f --- /dev/null +++ b/include/pinner/pinner_mips32.hpp @@ -0,0 +1,22 @@ +#ifndef ZIPR_PINNER_MIPS32 +#define ZIPR_PINNER_MIPS32 + +class ZiprPinnerMIPS32_t : public ZiprPinnerBase_t +{ + public: + ZiprPinnerMIPS32_t(Zipr_SDK::Zipr_t* p_parent); + virtual void doPinning() override; + + private: + zipr::ZiprImpl_t* m_parent; + IRDB_SDK::FileIR_t* m_firp; + Zipr_SDK::MemorySpace_t &memory_space; + Zipr_SDK::DollopManager_t &m_dollop_mgr; + Zipr_SDK::PlacementQueue_t &placement_queue; + + + +}; + + +#endif diff --git a/include/sizer/sizer_mips32.hpp b/include/sizer/sizer_mips32.hpp new file mode 100644 index 0000000000000000000000000000000000000000..6c22a626b110a4705546c42673ea2e9583e5bb77 --- /dev/null +++ b/include/sizer/sizer_mips32.hpp @@ -0,0 +1,15 @@ +#ifndef SIZERMIPS32_HPP +#define SIZERMIPS32_HPP + +class ZiprSizerMIPS32_t : public ZiprSizerBase_t +{ + private: + RangeAddress_t TBZPlopDollopEntryWithTarget (Zipr_SDK::DollopEntry_t *entry, RangeAddress_t override_place, RangeAddress_t override_target) const; + RangeAddress_t DefaultPlopDollopEntryWithTarget(Zipr_SDK::DollopEntry_t *entry, RangeAddress_t override_place, RangeAddress_t override_target) const; + + public: + ZiprSizerMIPS32_t(Zipr_SDK::Zipr_t* p_zipr_obj); + size_t DetermineInsnSize(IRDB_SDK::Instruction_t*, bool account_for_jump = true) const override; + virtual RangeAddress_t PlopDollopEntryWithTarget(Zipr_SDK::DollopEntry_t *entry, RangeAddress_t override_place, RangeAddress_t override_target) const override; +}; +#endif diff --git a/src/SConscript b/src/SConscript index 73bef2a6f57ae86b57f00a1d6e2d3a73a38dad69..ae89b03c2bb30b31b32dbcca1738006d640ce5dd 100644 --- a/src/SConscript +++ b/src/SConscript @@ -28,16 +28,19 @@ files= ''' arch_base.cpp pinner_arm64.cpp pinner_arm32.cpp + pinner_mips32.cpp pinner_base.cpp pinner_x86.cpp patcher_arm64.cpp patcher_arm32.cpp + patcher_mips32.cpp patcher_base.cpp patcher_x86.cpp sizer_base.cpp sizer_x86.cpp sizer_arm64.cpp sizer_arm32.cpp + sizer_mips32.cpp range.cpp ''' diff --git a/src/arch_base.cpp b/src/arch_base.cpp index 5c724289efde676fc3dc01934d2963fc691b7ba3..0d2a34906012b1265f66c32b7b738e55caddcad1 100644 --- a/src/arch_base.cpp +++ b/src/arch_base.cpp @@ -7,6 +7,7 @@ namespace zipr #include <arch/arch_x86.hpp> #include <arch/arch_arm64.hpp> #include <arch/arch_arm32.hpp> +#include <arch/arch_mips32.hpp> } #include <memory> @@ -25,10 +26,11 @@ ZiprArchitectureHelperBase_t::ZiprArchitectureHelperBase_t(Zipr_SDK::Zipr_t* p_z unique_ptr<ZiprArchitectureHelperBase_t> ZiprArchitectureHelperBase_t::factory(Zipr_SDK::Zipr_t* p_zipr_obj) { auto l_firp=p_zipr_obj->getFileIR(); - auto ret= l_firp->getArchitecture()->getMachineType() == admtX86_64 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperX86_t (p_zipr_obj) : - l_firp->getArchitecture()->getMachineType() == admtI386 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperX86_t (p_zipr_obj) : - l_firp->getArchitecture()->getMachineType() == admtAarch64 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperARM64_t(p_zipr_obj) : - l_firp->getArchitecture()->getMachineType() == admtArm32 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperARM32_t(p_zipr_obj) : + auto ret= l_firp->getArchitecture()->getMachineType() == admtX86_64 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperX86_t (p_zipr_obj) : + l_firp->getArchitecture()->getMachineType() == admtI386 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperX86_t (p_zipr_obj) : + l_firp->getArchitecture()->getMachineType() == admtAarch64 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperARM64_t(p_zipr_obj) : + l_firp->getArchitecture()->getMachineType() == admtArm32 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperARM32_t(p_zipr_obj) : + l_firp->getArchitecture()->getMachineType() == admtMips32 ? (ZiprArchitectureHelperBase_t*)new ZiprArchitectureHelperMIPS32_t(p_zipr_obj) : throw domain_error("Cannot init architecture"); return unique_ptr<ZiprArchitectureHelperBase_t>(ret); diff --git a/src/elfwrite.cpp b/src/elfwrite.cpp index 183bd97790f4638d676fca45495305c687abd269..859e48c74998373cf5de9f3330b100ac1569b43b 100644 --- a/src/elfwrite.cpp +++ b/src/elfwrite.cpp @@ -13,6 +13,7 @@ #include <string> // std::string, std::to_string #include <fstream> #include <elf.h> +#include <endian.h> #include "elfio/elfio.hpp" #include "elfio/elfio_dump.hpp" @@ -22,6 +23,609 @@ using namespace std; using namespace zipr; using namespace ELFIO; +template<class T_Elf_Ehdr, class T_Elf_Shdr> +static inline void host_to_shdr(const T_Elf_Ehdr& ehdr, T_Elf_Shdr& shdr) +{ +#if 0 + struct Elf64_Shdr + { + Elf64_Word sh_name + Elf64_Word sh_type + Elf64_Xword sh_flags + Elf64_Addr sh_addr + Elf64_Off sh_offset + Elf64_Xword sh_size + Elf64_Word sh_link + Elf64_Word sh_info + Elf64_Xword sh_addralign + Elf64_Xword sh_entsize + } + + steruct Elf32_Shdr + { + Elf32_Word sh_name + Elf32_Word sh_type + Elf32_Word sh_flags + Elf32_Addr sh_addr + Elf32_Off sh_offset + Elf32_Word sh_size + Elf32_Word sh_link + Elf32_Word sh_info + Elf32_Word sh_addralign + Elf32_Word sh_entsize + } +#endif + + + if(ehdr.e_ident[5]==1) // little endian elf file + { + shdr.sh_name = htole32(shdr.sh_name); + shdr.sh_type = htole32(shdr.sh_type); + shdr.sh_link = htole32(shdr.sh_link); + shdr.sh_info = htole32(shdr.sh_info); + if(sizeof(ehdr.e_entry)==4) // 32-bit header + { + shdr.sh_flags = htole32(shdr.sh_flags); + shdr.sh_size = htole32(shdr.sh_size); + shdr.sh_addr = htole32(shdr.sh_addr); + shdr.sh_offset = htole32(shdr.sh_offset); + shdr.sh_addralign = htole32(shdr.sh_addralign); + shdr.sh_entsize = htole32(shdr.sh_entsize); + } + else if(sizeof(ehdr.e_entry)==8) // 64-bit header + { + shdr.sh_flags = htole64(shdr.sh_flags); + shdr.sh_size = htole64(shdr.sh_size); + shdr.sh_addr = htole64(shdr.sh_addr); + shdr.sh_offset = htole64(shdr.sh_offset); + shdr.sh_addralign = htole64(shdr.sh_addralign); + shdr.sh_entsize = htole64(shdr.sh_entsize); + } + else + { + assert(0); + } + + } + else if(ehdr.e_ident[5]==2) // big endian elf file + { + shdr.sh_name = htobe32(shdr.sh_name); + shdr.sh_type = htobe32(shdr.sh_type); + shdr.sh_link = htobe32(shdr.sh_link); + shdr.sh_info = htobe32(shdr.sh_info); + if(sizeof(ehdr.e_entry)==4) // 32-bit header + { + shdr.sh_flags = htobe32(shdr.sh_flags); + shdr.sh_size = htobe32(shdr.sh_size); + shdr.sh_addr = htobe32(shdr.sh_addr); + shdr.sh_offset = htobe32(shdr.sh_offset); + shdr.sh_addralign = htobe32(shdr.sh_addralign); + shdr.sh_entsize = htobe32(shdr.sh_entsize); + } + else if(sizeof(ehdr.e_entry)==8) // 64-bit header + { + shdr.sh_flags = htobe64(shdr.sh_flags); + shdr.sh_size = htobe64(shdr.sh_size); + shdr.sh_addr = htobe64(shdr.sh_addr); + shdr.sh_offset = htobe64(shdr.sh_offset); + shdr.sh_addralign = htobe64(shdr.sh_addralign); + shdr.sh_entsize = htobe64(shdr.sh_entsize); + } + else + { + assert(0); + } + } + else + { + assert(0); + } + +} + +template<class T_Elf_Ehdr, class T_Elf_Shdr> +static inline void shdr_to_host(const T_Elf_Ehdr& ehdr, T_Elf_Shdr& shdr) +{ + +#if 0 + struct Elf64_Shdr + { + Elf64_Word sh_name + Elf64_Word sh_type + Elf64_Xword sh_flags + Elf64_Addr sh_addr + Elf64_Off sh_offset + Elf64_Xword sh_size + Elf64_Word sh_link + Elf64_Word sh_info + Elf64_Xword sh_addralign + Elf64_Xword sh_entsize + } + + steruct Elf32_Shdr + { + Elf32_Word sh_name + Elf32_Word sh_type + Elf32_Word sh_flags + Elf32_Addr sh_addr + Elf32_Off sh_offset + Elf32_Word sh_size + Elf32_Word sh_link + Elf32_Word sh_info + Elf32_Word sh_addralign + Elf32_Word sh_entsize + } +#endif + + + if(ehdr.e_ident[5]==1) // little endian elf file + { + shdr.sh_name = le32toh(shdr.sh_name); + shdr.sh_type = le32toh(shdr.sh_type); + shdr.sh_link = le32toh(shdr.sh_link); + shdr.sh_info = le32toh(shdr.sh_info); + if(sizeof(ehdr.e_entry)==4) // 32-bit header + { + shdr.sh_flags = le32toh(shdr.sh_flags); + shdr.sh_size = le32toh(shdr.sh_size); + shdr.sh_addr = le32toh(shdr.sh_addr); + shdr.sh_offset = le32toh(shdr.sh_offset); + shdr.sh_addralign = le32toh(shdr.sh_addralign); + shdr.sh_entsize = le32toh(shdr.sh_entsize); + } + else if(sizeof(ehdr.e_entry)==8) // 64-bit header + { + shdr.sh_flags = le64toh(shdr.sh_flags); + shdr.sh_size = le64toh(shdr.sh_size); + shdr.sh_addr = le64toh(shdr.sh_addr); + shdr.sh_offset = le64toh(shdr.sh_offset); + shdr.sh_addralign = le64toh(shdr.sh_addralign); + shdr.sh_entsize = le64toh(shdr.sh_entsize); + } + else + { + assert(0); + } + + } + else if(ehdr.e_ident[5]==2) // big endian elf file + { + shdr.sh_name = be32toh(shdr.sh_name); + shdr.sh_type = be32toh(shdr.sh_type); + shdr.sh_link = be32toh(shdr.sh_link); + shdr.sh_info = be32toh(shdr.sh_info); + if(sizeof(ehdr.e_entry)==4) // 32-bit header + { + shdr.sh_flags = be32toh(shdr.sh_flags); + shdr.sh_size = be32toh(shdr.sh_size); + shdr.sh_addr = be32toh(shdr.sh_addr); + shdr.sh_offset = be32toh(shdr.sh_offset); + shdr.sh_addralign = be32toh(shdr.sh_addralign); + shdr.sh_entsize = be32toh(shdr.sh_entsize); + } + else if(sizeof(ehdr.e_entry)==8) // 64-bit header + { + shdr.sh_flags = be64toh(shdr.sh_flags); + shdr.sh_size = be64toh(shdr.sh_size); + shdr.sh_addr = be64toh(shdr.sh_addr); + shdr.sh_offset = be64toh(shdr.sh_offset); + shdr.sh_addralign = be64toh(shdr.sh_addralign); + shdr.sh_entsize = be64toh(shdr.sh_entsize); + } + else + { + assert(0); + } + } + else + { + assert(0); + } + +} + +template<class T_Elf_Ehdr, class T_Elf_Phdr> +static inline void phdr_to_host(const T_Elf_Ehdr& ehdr, T_Elf_Phdr& phdr) +{ + +#if 0 + + 64-bit: + + struct { + Elf64_Word p_type; size=4 + Elf64_Word p_flags; size=4 + Elf64_Off p_offset; size=8 + Elf64_Addr p_vaddr; size=8 + Elf64_Addr p_paddr; size=8 + Elf64_Xword p_filesz; size=8 + Elf64_Xword p_memsz; size=8 + Elf64_Xword p_align; size=8 + } + + 32-bit: + + struct { + Elf32_Word p_type; 4 + Elf32_Off p_offset; 4 + Elf32_Addr p_vaddr; 4 + Elf32_Addr p_paddr; 4 + Elf32_Word p_filesz; 4 + Elf32_Word p_memsz; 4 + Elf32_Word p_flags; 4 + Elf32_Word p_align; 4 + } +#endif + + + if(ehdr.e_ident[5]==1) // little endian elf file + { + phdr.p_flags = le32toh(phdr.p_flags); + if(sizeof(ehdr.e_entry)==4) // 32-bit header + { + phdr.p_offset = le32toh(phdr.p_offset); + phdr.p_vaddr = le32toh(phdr.p_vaddr); + phdr.p_paddr = le32toh(phdr.p_paddr); + phdr.p_filesz = le32toh(phdr.p_filesz); + phdr.p_memsz = le32toh(phdr.p_memsz); + phdr.p_align = le32toh(phdr.p_align); + } + else if(sizeof(ehdr.e_entry)==8) // 64-bit header + { + phdr.p_offset = le64toh(phdr.p_offset); + phdr.p_vaddr = le64toh(phdr.p_vaddr); + phdr.p_paddr = le64toh(phdr.p_paddr); + phdr.p_filesz = le64toh(phdr.p_filesz); + phdr.p_memsz = le64toh(phdr.p_memsz); + phdr.p_align = le64toh(phdr.p_align); + } + else + { + assert(0); + } + + } + else if(ehdr.e_ident[5]==2) // big endian elf file + { + phdr.p_type = be32toh(phdr.p_type); + phdr.p_flags = be32toh(phdr.p_flags); + if(sizeof(ehdr.e_entry)==4) // 32-bit header + { + phdr.p_offset = be32toh(phdr.p_offset); + phdr.p_vaddr = be32toh(phdr.p_vaddr); + phdr.p_paddr = be32toh(phdr.p_paddr); + phdr.p_filesz = be32toh(phdr.p_filesz); + phdr.p_memsz = be32toh(phdr.p_memsz); + phdr.p_align = be32toh(phdr.p_align); + } + else if(sizeof(ehdr.e_entry)==8) // 64-bit header + { + phdr.p_offset = be64toh(phdr.p_offset); + phdr.p_vaddr = be64toh(phdr.p_vaddr); + phdr.p_paddr = be64toh(phdr.p_paddr); + phdr.p_filesz = be64toh(phdr.p_filesz); + phdr.p_memsz = be64toh(phdr.p_memsz); + phdr.p_align = be64toh(phdr.p_align); + } + else + { + assert(0); + } + + } + else + { + assert(0); + } + +} + +template<class T_Elf_Ehdr, class T_Elf_Phdr> +static inline void host_to_phdr(const T_Elf_Ehdr& ehdr, T_Elf_Phdr& phdr) +{ + +#if 0 + + 64-bit: + + struct { + Elf64_Word p_type; size=4 + Elf64_Word p_flags; size=4 + Elf64_Off p_offset; size=8 + Elf64_Addr p_vaddr; size=8 + Elf64_Addr p_paddr; size=8 + Elf64_Xword p_filesz; size=8 + Elf64_Xword p_memsz; size=8 + Elf64_Xword p_align; size=8 + } + + 32-bit: + + struct { + Elf32_Word p_type; 4 + Elf32_Off p_offset; 4 + Elf32_Addr p_vaddr; 4 + Elf32_Addr p_paddr; 4 + Elf32_Word p_filesz; 4 + Elf32_Word p_memsz; 4 + Elf32_Word p_flags; 4 + Elf32_Word p_align; 4 + } +#endif + + + if(ehdr.e_ident[5]==1) // little endian elf file + { + phdr.p_flags = htole32(phdr.p_flags); + if(sizeof(ehdr.e_entry)==4) // 32-bit header + { + phdr.p_offset = htole32(phdr.p_offset); + phdr.p_vaddr = htole32(phdr.p_vaddr); + phdr.p_paddr = htole32(phdr.p_paddr); + phdr.p_filesz = htole32(phdr.p_filesz); + phdr.p_memsz = htole32(phdr.p_memsz); + phdr.p_align = htole32(phdr.p_align); + } + else if(sizeof(ehdr.e_entry)==8) // 64-bit header + { + phdr.p_offset = htole64(phdr.p_offset); + phdr.p_vaddr = htole64(phdr.p_vaddr); + phdr.p_paddr = htole64(phdr.p_paddr); + phdr.p_filesz = htole64(phdr.p_filesz); + phdr.p_memsz = htole64(phdr.p_memsz); + phdr.p_align = htole64(phdr.p_align); + } + else + { + assert(0); + } + + } + else if(ehdr.e_ident[5]==2) // big endian elf file + { + phdr.p_type = htobe32(phdr.p_type); + phdr.p_flags = htobe32(phdr.p_flags); + if(sizeof(ehdr.e_entry)==4) // 32-bit header + { + phdr.p_offset = htobe32(phdr.p_offset); + phdr.p_vaddr = htobe32(phdr.p_vaddr); + phdr.p_paddr = htobe32(phdr.p_paddr); + phdr.p_filesz = htobe32(phdr.p_filesz); + phdr.p_memsz = htobe32(phdr.p_memsz); + phdr.p_align = htobe32(phdr.p_align); + } + else if(sizeof(ehdr.e_entry)==8) // 64-bit header + { + phdr.p_offset = htobe64(phdr.p_offset); + phdr.p_vaddr = htobe64(phdr.p_vaddr); + phdr.p_paddr = htobe64(phdr.p_paddr); + phdr.p_filesz = htobe64(phdr.p_filesz); + phdr.p_memsz = htobe64(phdr.p_memsz); + phdr.p_align = htobe64(phdr.p_align); + } + else + { + assert(0); + } + + } + else + { + assert(0); + } + +} + +template<class T_Elf_Ehdr> +static inline void ehdr_to_host(T_Elf_Ehdr& ehdr) +{ +#if 0 +struct Elf32_Ehdr { + unsigned char e_ident[16]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} +struct Elf64_Ehdr { + unsigned char e_ident[16]; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; +} +#endif + + if(ehdr.e_ident[5]==1) // little endian elf file + { + ehdr.e_type = le16toh(ehdr.e_type); + ehdr.e_machine = le16toh(ehdr.e_machine); + ehdr.e_version = le32toh(ehdr.e_version); + ehdr.e_flags = le32toh(ehdr.e_flags); + ehdr.e_ehsize = le16toh(ehdr.e_ehsize); + ehdr.e_phentsize = le16toh(ehdr.e_phentsize); + ehdr.e_phnum = le16toh(ehdr.e_phnum); + ehdr.e_shentsize = le16toh(ehdr.e_shentsize); + ehdr.e_shnum = le16toh(ehdr.e_shnum); + ehdr.e_shstrndx = le16toh(ehdr.e_shstrndx); + + if(sizeof(ehdr.e_entry)==4) // 32-bit header + { + ehdr.e_entry = le32toh(ehdr.e_entry); + ehdr.e_phoff = le32toh(ehdr.e_phoff); + ehdr.e_shoff = le32toh(ehdr.e_shoff); + } + else if(sizeof(ehdr.e_entry)==8) // 64-bit header + { + ehdr.e_entry = le64toh(ehdr.e_entry); + ehdr.e_phoff = le64toh(ehdr.e_phoff); + ehdr.e_shoff = le64toh(ehdr.e_shoff); + } + else + { + assert(0); + } + + } + else if(ehdr.e_ident[5]==2) // big endian elf file + { + ehdr.e_type = be16toh(ehdr.e_type); + ehdr.e_machine = be16toh(ehdr.e_machine); + ehdr.e_version = be32toh(ehdr.e_version); + ehdr.e_flags = be16toh(ehdr.e_flags); + ehdr.e_ehsize = be32toh(ehdr.e_ehsize); + ehdr.e_phentsize = be16toh(ehdr.e_phentsize); + ehdr.e_phnum = be16toh(ehdr.e_phnum); + ehdr.e_shentsize = be16toh(ehdr.e_shentsize); + ehdr.e_shnum = be16toh(ehdr.e_shnum); + ehdr.e_shstrndx = be16toh(ehdr.e_shstrndx); + + if(sizeof(ehdr.e_entry)==4) //32-bit header + { + ehdr.e_entry = be32toh(ehdr.e_entry); + ehdr.e_phoff = be32toh(ehdr.e_phoff); + ehdr.e_shoff = be32toh(ehdr.e_shoff); + } + else if(sizeof(ehdr.e_entry)==8) // 64-bit header + { + ehdr.e_entry = be64toh(ehdr.e_entry); + ehdr.e_phoff = be64toh(ehdr.e_phoff); + ehdr.e_shoff = be64toh(ehdr.e_shoff); + } + else + { + assert(0); + } + + } + else + { + assert(0); + } +} + +template<class T_Elf_Ehdr> +static inline void host_to_ehdr(T_Elf_Ehdr& ehdr) +{ +#if 0 +struct Elf32_Ehdr { + unsigned char e_ident[16]; + Elf32_Half e_type; + Elf32_Half e_machine; + Elf32_Word e_version; + Elf32_Addr e_entry; + Elf32_Off e_phoff; + Elf32_Off e_shoff; + Elf32_Word e_flags; + Elf32_Half e_ehsize; + Elf32_Half e_phentsize; + Elf32_Half e_phnum; + Elf32_Half e_shentsize; + Elf32_Half e_shnum; + Elf32_Half e_shstrndx; +} +struct Elf64_Ehdr { + unsigned char e_ident[16]; + Elf64_Half e_type; + Elf64_Half e_machine; + Elf64_Word e_version; + Elf64_Addr e_entry; + Elf64_Off e_phoff; + Elf64_Off e_shoff; + Elf64_Word e_flags; + Elf64_Half e_ehsize; + Elf64_Half e_phentsize; + Elf64_Half e_phnum; + Elf64_Half e_shentsize; + Elf64_Half e_shnum; + Elf64_Half e_shstrndx; +} +#endif + if(ehdr.e_ident[5]==1) // little endian elf file + { + ehdr.e_type = htole16(ehdr.e_type); + ehdr.e_machine = htole16(ehdr.e_machine); + ehdr.e_version = htole32(ehdr.e_version); + ehdr.e_flags = htole32(ehdr.e_flags); + ehdr.e_ehsize = htole16(ehdr.e_ehsize); + ehdr.e_phentsize = htole16(ehdr.e_phentsize); + ehdr.e_phnum = htole16(ehdr.e_phnum); + ehdr.e_shentsize = htole16(ehdr.e_shentsize); + ehdr.e_shnum = htole16(ehdr.e_shnum); + ehdr.e_shstrndx = htole16(ehdr.e_shstrndx); + + if(sizeof(ehdr.e_entry)==4) // 32-bit header + { + ehdr.e_entry = htole32(ehdr.e_entry); + ehdr.e_phoff = htole32(ehdr.e_phoff); + ehdr.e_shoff = htole32(ehdr.e_shoff); + } + else if(sizeof(ehdr.e_entry)==8) // 64-bit header + { + ehdr.e_entry = htole64(ehdr.e_entry); + ehdr.e_phoff = htole64(ehdr.e_phoff); + ehdr.e_shoff = htole64(ehdr.e_shoff); + } + else + { + assert(0); + } + + } + else if(ehdr.e_ident[5]==2) // big endian elf file + { + ehdr.e_type = htobe16(ehdr.e_type); + ehdr.e_machine = htobe16(ehdr.e_machine); + ehdr.e_version = htobe32(ehdr.e_version); + ehdr.e_flags = htobe32(ehdr.e_flags); + ehdr.e_ehsize = htobe16(ehdr.e_ehsize); + ehdr.e_phentsize = htobe16(ehdr.e_phentsize); + ehdr.e_phnum = htobe16(ehdr.e_phnum); + ehdr.e_shentsize = htobe16(ehdr.e_shentsize); + ehdr.e_shnum = htobe16(ehdr.e_shnum); + ehdr.e_shstrndx = htobe16(ehdr.e_shstrndx); + + if(sizeof(ehdr.e_entry)==4) //32-bit header + { + ehdr.e_entry = htobe32(ehdr.e_entry); + ehdr.e_phoff = htobe32(ehdr.e_phoff); + ehdr.e_shoff = htobe32(ehdr.e_shoff); + } + else if(sizeof(ehdr.e_entry)==8) // 64-bit header + { + ehdr.e_entry = htobe64(ehdr.e_entry); + ehdr.e_phoff = htobe64(ehdr.e_phoff); + ehdr.e_shoff = htobe64(ehdr.e_shoff); + } + else + { + assert(0); + } + + } + else + { + assert(0); + } +} static inline uintptr_t page_round_down(uintptr_t x) { @@ -240,6 +844,7 @@ void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr, T_Elf_Shdr, T_Elf_Sym, T_El fseek(fin,0,SEEK_SET); auto res=fread(&ehdr,sizeof(ehdr), 1, fin); assert(res==1); + ehdr_to_host(ehdr); }; template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> @@ -251,6 +856,7 @@ void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr, T_Elf_Sym, T_Elf { auto res=fread(&phdrs[i], sizeof(phdrs[i]), 1, fin); assert(res==1); + phdr_to_host(ehdr,phdrs[i]); } }; @@ -808,12 +1414,21 @@ filesz before we start writing out the elf. See "trim_last_seg_filesz" // write the header. fseek(fout,0,SEEK_SET); - fwrite(&new_ehdr, sizeof(new_ehdr), 1, fout); + auto new_ehdr_endian_correct = new_ehdr; + host_to_ehdr(new_ehdr_endian_correct); + fwrite(&new_ehdr_endian_correct, sizeof(new_ehdr), 1, fout); // write the phdrs, which may be part of a segment written above. - std::cout<<"Writing segment headers at "<<std::hex<<new_ehdr.e_phoff - <<", size="<<new_phdrs.size()*sizeof(new_phdrs[0])<<std::endl; + cout << "Writing segment headers at " << hex << new_ehdr.e_phoff << ", size=" << new_phdrs.size()*sizeof(new_phdrs[0]) << endl; fseek(fout,new_ehdr.e_phoff,SEEK_SET); - fwrite(new_phdrs.data(), sizeof(new_phdrs[0]), new_phdrs.size(), fout); + + // doesn't account for endian issues +// fwrite(new_phdrs.data(), sizeof(new_phdrs[0]), new_phdrs.size(), fout); + for(auto phdr : new_phdrs) + { + host_to_phdr(ehdr,phdr); + fwrite(&phdr, sizeof(new_phdrs[0]), 1, fout); + + } } template <class T_Elf_Ehdr, class T_Elf_Phdr, class T_Elf_Addr, class T_Elf_Shdr, class T_Elf_Sym, class T_Elf_Rel, class T_Elf_Rela, class T_Elf_Dyn> @@ -1001,7 +1616,14 @@ void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr,T_Elf_Sym, T_Elf_ long shdr_file_pos=ftell(fout); cout<<"Writing section headers at filepos="<<hex<<shdr_file_pos<<endl; - fwrite(shdrs.data(), sizeof(T_Elf_Shdr), shdrs.size(), fout); + // doesn't account for endianness +// fwrite(shdrs.data(), sizeof(T_Elf_Shdr), shdrs.size(), fout); + for(auto shdr : shdrs) + { + host_to_shdr(ehdr,shdr); + fwrite(&shdrs, sizeof(T_Elf_Shdr), 1, fout); + + } new_ehdr.e_shentsize=sizeof(T_Elf_Shdr); new_ehdr.e_shnum=shdrs.size(); @@ -1010,7 +1632,9 @@ void ElfWriterImpl<T_Elf_Ehdr,T_Elf_Phdr,T_Elf_Addr,T_Elf_Shdr,T_Elf_Sym, T_Elf_ // rewrite the file header so that sections are listed. fseek(fout,0,SEEK_SET); - fwrite(&new_ehdr, sizeof(new_ehdr),1,fout); + auto endian_ehdr = new_ehdr; + host_to_ehdr(endian_ehdr); + fwrite(&endian_ehdr, sizeof(new_ehdr),1,fout); } // explicit instantation of methods for 32- and 64-bit classes. diff --git a/src/patcher_base.cpp b/src/patcher_base.cpp index 9a0f32f5eaafe3d2e42ace89ed3738e937ff3d79..8d71802cd51da1a3485cbd687d87435794ad51b9 100644 --- a/src/patcher_base.cpp +++ b/src/patcher_base.cpp @@ -32,6 +32,7 @@ namespace zipr { +#include "patcher/patcher_mips32.hpp" #include "patcher/patcher_arm32.hpp" #include "patcher/patcher_arm64.hpp" #include "patcher/patcher_x86.hpp" @@ -58,10 +59,11 @@ using namespace zipr; unique_ptr<ZiprPatcherBase_t> ZiprPatcherBase_t::factory(Zipr_SDK::Zipr_t* p_parent) { auto l_firp=p_parent->getFileIR(); - auto ret= l_firp->getArchitecture()->getMachineType() == admtX86_64 ? (ZiprPatcherBase_t*)new ZiprPatcherX86_t (p_parent) : - l_firp->getArchitecture()->getMachineType() == admtI386 ? (ZiprPatcherBase_t*)new ZiprPatcherX86_t (p_parent) : - l_firp->getArchitecture()->getMachineType() == admtAarch64 ? (ZiprPatcherBase_t*)new ZiprPatcherARM64_t(p_parent) : - l_firp->getArchitecture()->getMachineType() == admtArm32 ? (ZiprPatcherBase_t*)new ZiprPatcherARM32_t(p_parent) : + auto ret= l_firp->getArchitecture()->getMachineType() == admtX86_64 ? (ZiprPatcherBase_t*)new ZiprPatcherX86_t (p_parent) : + l_firp->getArchitecture()->getMachineType() == admtI386 ? (ZiprPatcherBase_t*)new ZiprPatcherX86_t (p_parent) : + l_firp->getArchitecture()->getMachineType() == admtAarch64 ? (ZiprPatcherBase_t*)new ZiprPatcherARM64_t(p_parent) : + l_firp->getArchitecture()->getMachineType() == admtArm32 ? (ZiprPatcherBase_t*)new ZiprPatcherARM32_t(p_parent) : + l_firp->getArchitecture()->getMachineType() == admtMips32 ? (ZiprPatcherBase_t*)new ZiprPatcherMIPS32_t(p_parent) : throw domain_error("Cannot init architecture"); return unique_ptr<ZiprPatcherBase_t>(ret); diff --git a/src/patcher_mips32.cpp b/src/patcher_mips32.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ec147ecd4eb9537d2dc08830bf86433560e70c17 --- /dev/null +++ b/src/patcher_mips32.cpp @@ -0,0 +1,122 @@ +/*************************************************************************** + * Copyright (c) 2014 Zephyr Software LLC. All rights reserved. + * + * This software is furnished under a license and/or other restrictive + * terms and may be used and copied only in accordance with such terms + * and the inclusion of the above copyright notice. This software or + * any other copies thereof may not be provided or otherwise made + * available to any other person without the express written consent + * of an authorized representative of Zephyr Software LCC. Title to, + * ownership of, and all rights in the software is retained by + * Zephyr Software LCC. + * + * Zephyr Software LLC. Proprietary Information + * + * Unless otherwise specified, the information contained in this + * directory, following this legend, and/or referenced herein is + * Zephyr Software LLC. (Zephyr) Proprietary Information. + * + * CONTACT + * + * For technical assistance, contact Zephyr Software LCC. at: + * + * + * Zephyr Software, LLC + * 2040 Tremont Rd + * Charlottesville, VA 22911 + * + * E-mail: jwd@zephyr-software.com + **************************************************************************/ + +#include <zipr_all.h> +namespace zipr +{ +#include "patcher/patcher_mips32.hpp" +} +#include <irdb-core> +#include <iostream> +#include <stdlib.h> +#include <string.h> +#include <map> +#include <assert.h> +#include <sys/mman.h> +#include <ctype.h> +#include <iostream> // std::cout +#include <string> // std::string, std::to_string +#include <fstream> + +#define ALLOF(a) begin(a),end(a) + +using namespace IRDB_SDK; +using namespace std; +using namespace zipr; + +ZiprPatcherMIPS32_t::ZiprPatcherMIPS32_t(Zipr_SDK::Zipr_t* p_parent) : + m_parent(dynamic_cast<zipr::ZiprImpl_t*>(p_parent)), // upcast to ZiprImpl + m_firp(p_parent->getFileIR()), + memory_space(*p_parent->getMemorySpace()) + +{ +} + +void ZiprPatcherMIPS32_t::ApplyNopToPatch(RangeAddress_t addr) +{ assert(0); } + +void ZiprPatcherMIPS32_t::ApplyPatch(RangeAddress_t from_addr, RangeAddress_t to_addr) +{ + const auto first_byte = (uint8_t)memory_space[from_addr+0]; + const auto new_offset = (int32_t)((to_addr) - (from_addr+8)) >> 2; + + // A Branch in binary is: op= 000010 imm26=0000 00000000 00000000 00000000 + // it includes a 26-bit immediate, which is +/- 128mb, which should be a good enough "jump anywhere" + // for now. + const auto mask6 = (0b111111); + const auto is_uncond_branch = ((first_byte >> 2) & mask6) == (0b000010); // jump branch + + if(is_uncond_branch) + { + cout<<"Applying uncond branch patch from "<<hex<<from_addr<<" to "<<to_addr<<endl; + const auto non_imm_bits = 32U-26U; // 32 bits - imm26 + // assert there's no overflow. + assert((int64_t)(new_offset << non_imm_bits) == ((int64_t)new_offset) << non_imm_bits); + // or in opcode for first byte. set remaining bytes. + const auto mask26 = ((1<<26)-1); + const auto trimmed_offset = new_offset & mask26; + memory_space[from_addr+3] = (trimmed_offset>> 0)&0xff; + memory_space[from_addr+2] = (trimmed_offset>> 8)&0xff; + memory_space[from_addr+1] = (trimmed_offset>>16)&0xff; + memory_space[from_addr+0] |= (trimmed_offset>>24)&0x02; + } + else + { + cout<<"Applying cond branch patch from "<<hex<<from_addr<<" to "<<to_addr<<endl; + const auto non_imm_bits = 32U-24U; // 32 bits - imm24 + // assert there's no overflow. + assert((int64_t)(new_offset << non_imm_bits) == ((int64_t)new_offset) << non_imm_bits); + // or in opcode for first byte. set remaining bytes. + const auto mask24 = ((1<<24)-1); + const auto trimmed_offset = new_offset & mask24; + memory_space[from_addr+3] = (trimmed_offset>> 0)&0xff; + memory_space[from_addr+2] = (trimmed_offset>> 8)&0xff; + memory_space[from_addr+1] = (trimmed_offset>>16)&0xff; + memory_space[from_addr+0] |= (trimmed_offset>>24)&0x02; + } + +} + +void ZiprPatcherMIPS32_t::PatchJump(RangeAddress_t at_addr, RangeAddress_t to_addr) +{ + return this->ApplyPatch(at_addr,to_addr); +} +void ZiprPatcherMIPS32_t::PatchCall(RangeAddress_t at_addr, RangeAddress_t to_addr) +{ + assert(0); +} + + +void ZiprPatcherMIPS32_t::CallToNop(RangeAddress_t at_addr) +{ + assert(0); +} + + diff --git a/src/pinner_base.cpp b/src/pinner_base.cpp index e14dd0215035ca146d9239b4e80b13994977064f..7f79d9759a5e98b042136f793cd56f9b10d43b2b 100644 --- a/src/pinner_base.cpp +++ b/src/pinner_base.cpp @@ -3,8 +3,9 @@ namespace zipr { #include <pinner/pinner_x86.hpp> -#include <pinner/pinner_arm32.hpp> #include <pinner/pinner_arm64.hpp> +#include <pinner/pinner_arm32.hpp> +#include <pinner/pinner_mips32.hpp> } #include <memory> @@ -14,10 +15,11 @@ using namespace zipr; unique_ptr<ZiprPinnerBase_t> ZiprPinnerBase_t::factory(Zipr_SDK::Zipr_t *p_parent) { - auto ret= p_parent->getFileIR()->getArchitecture()->getMachineType() == admtX86_64 ? (ZiprPinnerBase_t*)new ZiprPinnerX86_t (p_parent) : - p_parent->getFileIR()->getArchitecture()->getMachineType() == admtI386 ? (ZiprPinnerBase_t*)new ZiprPinnerX86_t (p_parent) : - p_parent->getFileIR()->getArchitecture()->getMachineType() == admtAarch64 ? (ZiprPinnerBase_t*)new ZiprPinnerARM64_t(p_parent) : - p_parent->getFileIR()->getArchitecture()->getMachineType() == admtArm32 ? (ZiprPinnerBase_t*)new ZiprPinnerARM32_t(p_parent) : + auto ret= p_parent->getFileIR()->getArchitecture()->getMachineType() == admtX86_64 ? (ZiprPinnerBase_t*)new ZiprPinnerX86_t (p_parent) : + p_parent->getFileIR()->getArchitecture()->getMachineType() == admtI386 ? (ZiprPinnerBase_t*)new ZiprPinnerX86_t (p_parent) : + p_parent->getFileIR()->getArchitecture()->getMachineType() == admtAarch64 ? (ZiprPinnerBase_t*)new ZiprPinnerARM64_t(p_parent) : + p_parent->getFileIR()->getArchitecture()->getMachineType() == admtArm32 ? (ZiprPinnerBase_t*)new ZiprPinnerARM32_t(p_parent) : + p_parent->getFileIR()->getArchitecture()->getMachineType() == admtMips32 ? (ZiprPinnerBase_t*)new ZiprPinnerMIPS32_t(p_parent) : throw domain_error("Cannot init architecture"); return unique_ptr<ZiprPinnerBase_t>(ret); diff --git a/src/pinner_mips32.cpp b/src/pinner_mips32.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f006e3a6b6fe7c5af356332cb6b03b432e67611c --- /dev/null +++ b/src/pinner_mips32.cpp @@ -0,0 +1,63 @@ +#include <zipr_all.h> + +namespace zipr +{ +#include <pinner/pinner_mips32.hpp> +} +#include <memory> + +using namespace std; +using namespace IRDB_SDK; +using namespace zipr; + +ZiprPinnerMIPS32_t::ZiprPinnerMIPS32_t(Zipr_SDK::Zipr_t* p_parent) : + m_parent(dynamic_cast<zipr::ZiprImpl_t*>(p_parent)), // upcast to ZiprImpl + m_firp(p_parent->getFileIR()), + memory_space(*m_parent->getMemorySpace()), + m_dollop_mgr(*p_parent->getDollopManager()), + placement_queue(*p_parent->getPlacementQueue()) + +{ +} + +void ZiprPinnerMIPS32_t::doPinning() +{ + + + // deal with unpinned IBTs by putting them in the placement queue. + for(auto &insn : m_firp->getInstructions()) + { + if(insn->getIndirectBranchTargetAddress()==nullptr) + continue; + + if(insn->getIndirectBranchTargetAddress()->getVirtualOffset()==0) + { + // Unpinned IBT. Create dollop and add it to placement + // queue straight away--there are no pinning considerations. + auto newDoll=m_dollop_mgr.addNewDollops(insn); + placement_queue.insert({newDoll, 0}); + continue; + } + + auto ibta_addr=(RangeAddress_t)insn-> getIndirectBranchTargetAddress()-> getVirtualOffset(); + + // put unconditional branch with 24-bit offset in memory + // 1110 1010 0000 0000 0000 0000 0000 0000 + uint8_t bytes[]={'\x18','\x00','\x00','\x00'}; + for(auto i=0U;i<sizeof(bytes);i++) + { + const auto ibta_byte_addr = ibta_addr+i; + if(memory_space.find(ibta_byte_addr) != memory_space.end() ) + { + cout << "Byte is marked as both code and data at: " << hex << ibta_byte_addr << endl; + exit(10); + } + memory_space[ibta_byte_addr]=bytes[i]; + memory_space.splitFreeRange(ibta_byte_addr); + } + // insert a patch to patch the branch later. + const auto patch=Patch_t(ibta_addr, UnresolvedType_t::UncondJump_rel26); + const auto uu=UnresolvedUnpinned_t(insn); + m_parent->AddPatch(uu,patch); + } +} diff --git a/src/sizer_base.cpp b/src/sizer_base.cpp index 792eba582db34d0368dde30968f7423a3e379581..31b53db04369ed071bf0ca2ea1f2ebc97552ad8b 100644 --- a/src/sizer_base.cpp +++ b/src/sizer_base.cpp @@ -7,6 +7,7 @@ namespace zipr #include <sizer/sizer_x86.hpp> #include <sizer/sizer_arm64.hpp> #include <sizer/sizer_arm32.hpp> +#include <sizer/sizer_mips32.hpp> } #include <memory> @@ -18,10 +19,11 @@ using namespace zipr; unique_ptr<ZiprSizerBase_t> ZiprSizerBase_t::factory(Zipr_SDK::Zipr_t* p_zipr_obj) { auto l_firp=p_zipr_obj->getFileIR(); - auto ret= l_firp->getArchitecture()->getMachineType() == admtX86_64 ? (ZiprSizerBase_t*)new ZiprSizerX86_t (p_zipr_obj) : - l_firp->getArchitecture()->getMachineType() == admtI386 ? (ZiprSizerBase_t*)new ZiprSizerX86_t (p_zipr_obj) : - l_firp->getArchitecture()->getMachineType() == admtAarch64 ? (ZiprSizerBase_t*)new ZiprSizerARM64_t(p_zipr_obj) : - l_firp->getArchitecture()->getMachineType() == admtArm32 ? (ZiprSizerBase_t*)new ZiprSizerARM32_t(p_zipr_obj) : + auto ret= l_firp->getArchitecture()->getMachineType() == admtX86_64 ? (ZiprSizerBase_t*)new ZiprSizerX86_t (p_zipr_obj) : + l_firp->getArchitecture()->getMachineType() == admtI386 ? (ZiprSizerBase_t*)new ZiprSizerX86_t (p_zipr_obj) : + l_firp->getArchitecture()->getMachineType() == admtAarch64 ? (ZiprSizerBase_t*)new ZiprSizerARM64_t(p_zipr_obj) : + l_firp->getArchitecture()->getMachineType() == admtArm32 ? (ZiprSizerBase_t*)new ZiprSizerARM32_t(p_zipr_obj) : + l_firp->getArchitecture()->getMachineType() == admtMips32 ? (ZiprSizerBase_t*)new ZiprSizerMIPS32_t(p_zipr_obj) : throw domain_error("Cannot init architecture"); return unique_ptr<ZiprSizerBase_t>(ret); diff --git a/src/sizer_mips32.cpp b/src/sizer_mips32.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c29d5fbbda1247b6558b52cfee93df2d9eb2a470 --- /dev/null +++ b/src/sizer_mips32.cpp @@ -0,0 +1,40 @@ +#include <zipr_all.h> + +namespace zipr +{ +#include <sizer/sizer_mips32.hpp> +} + + +using namespace zipr ; +using namespace IRDB_SDK; + + +ZiprSizerMIPS32_t::ZiprSizerMIPS32_t(Zipr_SDK::Zipr_t* p_zipr_obj) : ZiprSizerBase_t(p_zipr_obj,4,4,4,4,4) +{ +} + +size_t ZiprSizerMIPS32_t::DetermineInsnSize(Instruction_t* insn, bool account_for_jump) const +{ + // need 4 bytes for insn, plus 4 bytes for a jump + const auto size = 4u; + const auto jmp_size = account_for_jump ? 4 : 0; + return size + jmp_size; +} + +RangeAddress_t ZiprSizerMIPS32_t::PlopDollopEntryWithTarget( + Zipr_SDK::DollopEntry_t *entry, + RangeAddress_t override_place, + RangeAddress_t override_target) const +{ + const auto addr = (override_place == 0) ? entry->getPlace() : override_place; + const auto target_addr = (override_target == 0) ? entry->getTargetDollop()->getPlace() : override_target; + const auto insn = entry->getInstruction(); + + // plop instruction an d make it target the right address. + memory_space.PlopBytes(addr, insn->getDataBits().c_str(), 4); + m_zipr_obj.GetPatcher()->ApplyPatch(addr, target_addr); + + return addr+4; +} +