diff options
| -rw-r--r-- | arch/mips/arch_mips.cpp | 13 | ||||
| -rw-r--r-- | platform/linux/platform_linux.cpp | 25 |
2 files changed, 32 insertions, 6 deletions
diff --git a/arch/mips/arch_mips.cpp b/arch/mips/arch_mips.cpp index ea7c2fca..bb1873f2 100644 --- a/arch/mips/arch_mips.cpp +++ b/arch/mips/arch_mips.cpp @@ -20,6 +20,7 @@ using namespace std; #endif #define E_MIPS_MACH_5900 0x00920000 +#define EF_MIPS_ABI2 0x00000020 uint32_t bswap32(uint32_t x) { @@ -2867,7 +2868,7 @@ public: class MipsN64CallingConvention: public CallingConvention { public: - MipsN64CallingConvention(Architecture* arch): CallingConvention(arch, "n64") + MipsN64CallingConvention(Architecture* arch, const std::string& name = "n64"): CallingConvention(arch, name) { } @@ -3690,6 +3691,9 @@ static Ref<Platform> ElfFlagsRecognize(BinaryView* view, Metadata* metadata) } uint64_t flagsValue = flagsMetadata->GetUnsignedInteger(); + if (flagsValue & EF_MIPS_ABI2) + return Platform::GetByName(endianness == BigEndian ? "linux-mipsn32" : "linux-mipsn32el"); + uint8_t machineVariant = (flagsValue >> 16) & 0xff; switch (machineVariant) @@ -3749,6 +3753,8 @@ extern "C" /* calling conventions */ MipsO32CallingConvention* o32LE = new MipsO32CallingConvention(mipsel); MipsO32CallingConvention* o32BE = new MipsO32CallingConvention(mipseb); + MipsN64CallingConvention* n32LE = new MipsN64CallingConvention(mips64el, "n32"); + MipsN64CallingConvention* n32BE = new MipsN64CallingConvention(mips64eb, "n32"); MipsN64CallingConvention* n64LE = new MipsN64CallingConvention(mips64el); MipsN64CallingConvention* n64BE = new MipsN64CallingConvention(mips64eb); MipsN64CallingConvention* n64BEc = new MipsN64CallingConvention(cnmips64eb); @@ -3764,6 +3770,8 @@ extern "C" mips3->SetDefaultCallingConvention(o32BE); mips3el->RegisterCallingConvention(o32LE); mips3el->SetDefaultCallingConvention(o32LE); + mips64el->RegisterCallingConvention(n32LE); + mips64eb->RegisterCallingConvention(n32BE); mips64el->RegisterCallingConvention(n64LE); mips64el->SetDefaultCallingConvention(n64LE); mips64eb->RegisterCallingConvention(n64BE); @@ -3842,7 +3850,8 @@ extern "C" { elf->RegisterPlatformRecognizer(ARCH_ID_MIPS64, LittleEndian, ElfFlagsRecognize); elf->RegisterPlatformRecognizer(ARCH_ID_MIPS64, BigEndian, ElfFlagsRecognize); - elf->RegisterPlatformRecognizer(ARCH_ID_MIPS32, LittleEndian, ElfFlagsRecognize); // R5900 + elf->RegisterPlatformRecognizer(ARCH_ID_MIPS32, LittleEndian, ElfFlagsRecognize); // n32, R5900 + elf->RegisterPlatformRecognizer(ARCH_ID_MIPS32, BigEndian, ElfFlagsRecognize); // n32 } BinaryViewType::RegisterArchitecture("PE", 0x166, LittleEndian, mipsel); diff --git a/platform/linux/platform_linux.cpp b/platform/linux/platform_linux.cpp index f2902068..ff8134f7 100644 --- a/platform/linux/platform_linux.cpp +++ b/platform/linux/platform_linux.cpp @@ -275,12 +275,16 @@ public: class LinuxMips64Platform: public Platform { +private: + size_t m_addressSize; + public: - LinuxMips64Platform(Architecture* arch, const std::string& name): Platform(arch, name) + LinuxMips64Platform(Architecture* arch, const std::string& name, const std::string& callingConventionName = "n64", size_t addressSize = 0): + Platform(arch, name), m_addressSize(addressSize) { Ref<CallingConvention> cc; - cc = arch->GetCallingConventionByName("n64"); + cc = arch->GetCallingConventionByName(callingConventionName); if (cc) { RegisterDefaultCallingConvention(cc); @@ -293,6 +297,13 @@ public: if (cc) SetSystemCallConvention(cc); } + + virtual size_t GetAddressSize() const override + { + if (m_addressSize) + return m_addressSize; + return GetArchitecture()->GetAddressSize(); + } }; @@ -543,17 +554,21 @@ extern "C" Ref<Architecture> mipseb = Architecture::GetByName("mips32"); Ref<Architecture> mips3el = Architecture::GetByName("mipsel3"); Ref<Architecture> mips3eb = Architecture::GetByName("mips3"); + Ref<Architecture> mips64el = Architecture::GetByName("mipsel64"); Ref<Architecture> mips64eb = Architecture::GetByName("mips64"); Ref<Architecture> cnmips64eb = Architecture::GetByName("cavium-mips64"); Ref<Architecture> cnmips64el = Architecture::GetByName("cavium-mipsel64"); - if (mipsel && mipseb && mips64eb && cnmips64eb && cnmips64el && mips3el && mips3eb) + if (mipsel && mipseb && mips64el && mips64eb && cnmips64eb && cnmips64el && mips3el && mips3eb) { - Ref<Platform> platformLE, platformBE, platformBE64, platformBE64cn, platformLE64cn, platform3LE, platform3BE; + Ref<Platform> platformLE, platformBE, platformBE64, platformBE64cn, platformLE64cn, platform3LE, platform3BE, + platformN32LE, platformN32BE; platformLE = new LinuxMipsPlatform(mipsel, "linux-mipsel"); platformBE = new LinuxMipsPlatform(mipseb, "linux-mips"); platform3LE = new LinuxMipsPlatform(mips3el, "linux-mipsel3"); platform3BE = new LinuxMipsPlatform(mips3eb, "linux-mips3"); + platformN32LE = new LinuxMips64Platform(mips64el, "linux-mipsn32el", "n32", 4); + platformN32BE = new LinuxMips64Platform(mips64eb, "linux-mipsn32", "n32", 4); platformBE64 = new LinuxMips64Platform(mips64eb, "linux-mips64"); platformBE64cn = new LinuxMips64Platform(cnmips64eb, "linux-cnmips64"); platformLE64cn = new LinuxMips64Platform(cnmips64el, "linux-cnmipsel64"); @@ -561,6 +576,8 @@ extern "C" Platform::Register("linux", platformBE); Platform::Register("linux", platform3LE); Platform::Register("linux", platform3BE); + Platform::Register("linux", platformN32LE); + Platform::Register("linux", platformN32BE); Platform::Register("linux", platformBE64); Platform::Register("linux", platformBE64cn); Platform::Register("linux", platformLE64cn); |
