summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Eskeldson <jonathan.eskeldson@zetier.com>2026-05-12 20:44:43 -0700
committerAlexander Taylor <alex@vector35.com>2026-06-06 12:32:32 -0400
commitc1b0eb7bf58e7234d5930c1c2b4d0987b71c99d1 (patch)
treeba17db2ea3bceaf31dcbaa9d46a8f5e9edbbdb63
parent40172b3fa453062eddddf362a84cc5b7a7b730f3 (diff)
Add little-endian octeon mips arch
-rw-r--r--arch/mips/arch_mips.cpp25
-rw-r--r--platform/linux/platform_linux.cpp9
2 files changed, 31 insertions, 3 deletions
diff --git a/arch/mips/arch_mips.cpp b/arch/mips/arch_mips.cpp
index 85e545f6..ea7c2fca 100644
--- a/arch/mips/arch_mips.cpp
+++ b/arch/mips/arch_mips.cpp
@@ -3674,6 +3674,21 @@ static Ref<Platform> ElfFlagsRecognize(BinaryView* view, Metadata* metadata)
if (!flagsMetadata || !flagsMetadata->IsUnsignedInteger())
return nullptr;
+ Ref<Metadata> endiannessMetadata = metadata->Get("EI_DATA");
+ if (!endiannessMetadata || !endiannessMetadata->IsUnsignedInteger())
+ return nullptr;
+
+ uint64_t endiannessValue = endiannessMetadata->GetUnsignedInteger();
+ BNEndianness endianness;
+ if (endiannessValue == 1)
+ endianness = LittleEndian;
+ else if (endiannessValue == 2)
+ endianness = BigEndian;
+ else {
+ LogError("ELF endianness value 0x%" PRIx64 " doesn't map to valid value", endiannessValue);
+ return nullptr;
+ }
+
uint64_t flagsValue = flagsMetadata->GetUnsignedInteger();
uint8_t machineVariant = (flagsValue >> 16) & 0xff;
@@ -3683,7 +3698,7 @@ static Ref<Platform> ElfFlagsRecognize(BinaryView* view, Metadata* metadata)
case 0x8d: // EF_MIPS_MACH_OCTEON2
case 0x8e: // EF_MIPS_MACH_OCTEON3
LogInfo("ELF flags 0x%08" PRIx64 " machine variant 0x%02x: using cavium architecture", flagsValue, machineVariant);
- return Platform::GetByName("linux-cnmips64");
+ return Platform::GetByName(endianness == BigEndian ? "linux-cnmips64" : "linux-cnmipsel64");
case 0x92: // E_MIPS_MACH_5900
LogInfo("ELF flags 0x%08" PRIx64 " machine variant 0x%02x: using R5900 architecture", flagsValue, machineVariant);
return Platform::GetByName("r5900l");
@@ -3715,6 +3730,7 @@ extern "C"
Architecture* mips64el = new MipsArchitecture("mipsel64", MIPS_64, LittleEndian, 64);
Architecture* mips64eb = new MipsArchitecture("mips64", MIPS_64, BigEndian, 64);
Architecture* cnmips64eb = new MipsArchitecture("cavium-mips64", MIPS_64, BigEndian, 64, DECOMPOSE_FLAGS_CAVIUM);
+ Architecture* cnmips64el = new MipsArchitecture("cavium-mipsel64", MIPS_64, LittleEndian, 64, DECOMPOSE_FLAGS_CAVIUM);
Architecture* r5900l = new MipsArchitecture("r5900l", MIPS_R5900, LittleEndian, 32);
// R5900 should only be Little-Endian, so until someone complains, I'm leaving the Big-Endian variant disabled.
// Architecture* r5900b = new MipsArchitecture("r5900b", MIPS_R5900, BigEndian, 32);
@@ -3728,6 +3744,7 @@ extern "C"
Architecture::Register(mips64el);
Architecture::Register(mips64eb);
Architecture::Register(cnmips64eb);
+ Architecture::Register(cnmips64el);
/* calling conventions */
MipsO32CallingConvention* o32LE = new MipsO32CallingConvention(mipsel);
@@ -3735,6 +3752,7 @@ extern "C"
MipsN64CallingConvention* n64LE = new MipsN64CallingConvention(mips64el);
MipsN64CallingConvention* n64BE = new MipsN64CallingConvention(mips64eb);
MipsN64CallingConvention* n64BEc = new MipsN64CallingConvention(cnmips64eb);
+ MipsN64CallingConvention* n64LEc = new MipsN64CallingConvention(cnmips64el);
MipsPS2CallingConvention* ps2LE = new MipsPS2CallingConvention(r5900l);
// MipsPS2CallingConvention* ps2BE = new MipsPS2CallingConvention(r5900b);
@@ -3752,6 +3770,8 @@ extern "C"
mips64eb->SetDefaultCallingConvention(n64BE);
cnmips64eb->RegisterCallingConvention(n64BEc);
cnmips64eb->SetDefaultCallingConvention(n64BEc);
+ cnmips64el->RegisterCallingConvention(n64LEc);
+ cnmips64el->SetDefaultCallingConvention(n64LEc);
r5900l->RegisterCallingConvention(ps2LE);
r5900l->SetDefaultCallingConvention(ps2LE);
// r5900b->RegisterCallingConvention(ps2BE);
@@ -3779,6 +3799,7 @@ extern "C"
mips64el->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(mips64el));
mips64eb->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(mips64eb));
cnmips64eb->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(cnmips64eb));
+ cnmips64el->RegisterCallingConvention(new MipsLinuxRtlResolveCallingConvention(cnmips64el));
/* function recognizers */
mipsel->RegisterFunctionRecognizer(new MipsImportedFunctionRecognizer());
@@ -3788,6 +3809,7 @@ extern "C"
mips64el->RegisterFunctionRecognizer(new MipsImportedFunctionRecognizer());
mips64eb->RegisterFunctionRecognizer(new MipsImportedFunctionRecognizer());
cnmips64eb->RegisterFunctionRecognizer(new MipsImportedFunctionRecognizer());
+ cnmips64el->RegisterFunctionRecognizer(new MipsImportedFunctionRecognizer());
mipseb->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
mipsel->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
@@ -3798,6 +3820,7 @@ extern "C"
r5900l->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
// r5900b->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
cnmips64eb->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
+ cnmips64el->RegisterRelocationHandler("ELF", new MipsElfRelocationHandler());
// Register the architectures with the binary format parsers so that they know when to use
// these architectures for disassembling an executable file
diff --git a/platform/linux/platform_linux.cpp b/platform/linux/platform_linux.cpp
index 7743daa9..f2902068 100644
--- a/platform/linux/platform_linux.cpp
+++ b/platform/linux/platform_linux.cpp
@@ -545,9 +545,10 @@ extern "C"
Ref<Architecture> mips3eb = Architecture::GetByName("mips3");
Ref<Architecture> mips64eb = Architecture::GetByName("mips64");
Ref<Architecture> cnmips64eb = Architecture::GetByName("cavium-mips64");
- if (mipsel && mipseb && mips64eb && cnmips64eb && mips3el && mips3eb)
+ Ref<Architecture> cnmips64el = Architecture::GetByName("cavium-mipsel64");
+ if (mipsel && mipseb && mips64eb && cnmips64eb && cnmips64el && mips3el && mips3eb)
{
- Ref<Platform> platformLE, platformBE, platformBE64, platformBE64cn, platform3LE, platform3BE;
+ Ref<Platform> platformLE, platformBE, platformBE64, platformBE64cn, platformLE64cn, platform3LE, platform3BE;
platformLE = new LinuxMipsPlatform(mipsel, "linux-mipsel");
platformBE = new LinuxMipsPlatform(mipseb, "linux-mips");
@@ -555,12 +556,14 @@ extern "C"
platform3BE = new LinuxMipsPlatform(mips3eb, "linux-mips3");
platformBE64 = new LinuxMips64Platform(mips64eb, "linux-mips64");
platformBE64cn = new LinuxMips64Platform(cnmips64eb, "linux-cnmips64");
+ platformLE64cn = new LinuxMips64Platform(cnmips64el, "linux-cnmipsel64");
Platform::Register("linux", platformLE);
Platform::Register("linux", platformBE);
Platform::Register("linux", platform3LE);
Platform::Register("linux", platform3BE);
Platform::Register("linux", platformBE64);
Platform::Register("linux", platformBE64cn);
+ Platform::Register("linux", platformLE64cn);
// Linux binaries sometimes have an OS identifier of zero, even though 3 is the correct one
BinaryViewType::RegisterPlatform("ELF", 0, platformLE);
BinaryViewType::RegisterPlatform("ELF", 0, platformBE);
@@ -568,12 +571,14 @@ extern "C"
BinaryViewType::RegisterPlatform("ELF", 0, platform3BE);
BinaryViewType::RegisterPlatform("ELF", 0, platformBE64);
BinaryViewType::RegisterPlatform("ELF", 0, platformBE64cn);
+ BinaryViewType::RegisterPlatform("ELF", 0, platformLE64cn);
BinaryViewType::RegisterPlatform("ELF", 3, platformLE);
BinaryViewType::RegisterPlatform("ELF", 3, platformBE);
BinaryViewType::RegisterPlatform("ELF", 3, platform3LE);
BinaryViewType::RegisterPlatform("ELF", 3, platform3BE);
BinaryViewType::RegisterPlatform("ELF", 3, platformBE64);
BinaryViewType::RegisterPlatform("ELF", 3, platformBE64cn);
+ BinaryViewType::RegisterPlatform("ELF", 3, platformLE64cn);
}
Ref<Architecture> rv32 = Architecture::GetByName("rv32gc");