summaryrefslogtreecommitdiff
path: root/arch/mips/arch_mips.cpp
diff options
context:
space:
mode:
authorAlexander Taylor <alex@vector35.com>2026-06-03 19:15:35 -0400
committerAlexander Taylor <alex@vector35.com>2026-06-06 12:32:32 -0400
commit6bc36d9f834900d8b9b15ecc6956aaa3d39bf153 (patch)
treeefb3b81646f995c968fa1c438866a9702ffe2940 /arch/mips/arch_mips.cpp
parentc1b0eb7bf58e7234d5930c1c2b4d0987b71c99d1 (diff)
Better MIPS n32 support.
Diffstat (limited to 'arch/mips/arch_mips.cpp')
-rw-r--r--arch/mips/arch_mips.cpp13
1 files changed, 11 insertions, 2 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);