summaryrefslogtreecommitdiff
path: root/platform/linux/platform_linux.cpp
diff options
context:
space:
mode:
authorMichael Krasnitski <michael.krasnitski@gmail.com>2025-08-19 11:43:14 -0400
committerBrandon Miller <brandon@vector35.com>2026-01-30 14:29:58 -0500
commitd634a5d6527f7ec203907f17cde8d0d807028fe3 (patch)
treee5711babca39401516387333a65275a747224b5c /platform/linux/platform_linux.cpp
parentc674599c102adee1882ccb6778e9c819dfccd305 (diff)
Add basic linux-ilp32 platform support
Diffstat (limited to 'platform/linux/platform_linux.cpp')
-rw-r--r--platform/linux/platform_linux.cpp64
1 files changed, 59 insertions, 5 deletions
diff --git a/platform/linux/platform_linux.cpp b/platform/linux/platform_linux.cpp
index 9614547a..796df353 100644
--- a/platform/linux/platform_linux.cpp
+++ b/platform/linux/platform_linux.cpp
@@ -4,7 +4,9 @@ using namespace BinaryNinja;
using namespace std;
Ref<Platform> g_linuxX32;
+Ref<Platform> g_linuxIlp32;
#define EM_X86_64 62 // AMD x86-64 architecture
+#define EM_AARCH64 183 // ARM64 architecture
class LinuxX86Platform: public Platform
{
@@ -199,6 +201,50 @@ public:
}
};
+class LinuxIlp32Platform: public Platform
+{
+ public:
+ LinuxIlp32Platform(Architecture* arch): Platform(arch, "linux-ilp32")
+ {
+ Ref<CallingConvention> cc;
+
+ cc = arch->GetCallingConventionByName("cdecl");
+ if (cc)
+ {
+ RegisterDefaultCallingConvention(cc);
+ RegisterCdeclCallingConvention(cc);
+ RegisterFastcallCallingConvention(cc);
+ RegisterStdcallCallingConvention(cc);
+ }
+
+ cc = arch->GetCallingConventionByName("linux-syscall");
+ if (cc)
+ SetSystemCallConvention(cc);
+ }
+
+ virtual size_t GetAddressSize() const override
+ {
+ return 4;
+ }
+
+ static Ref<Platform> Recognize(BinaryView* view, Metadata* metadata)
+ {
+ Ref<Metadata> fileClass = metadata->Get("EI_CLASS");
+
+ if (!fileClass || !fileClass->IsUnsignedInteger())
+ return nullptr;
+
+ Ref<Metadata> machine = metadata->Get("e_machine");
+ if (!machine || !machine->IsUnsignedInteger())
+ return nullptr;
+
+ if (fileClass->GetUnsignedInteger() == 1 && machine->GetUnsignedInteger() == EM_AARCH64)
+ return g_linuxIlp32;
+
+ return nullptr;
+ }
+};
+
class LinuxMipsPlatform: public Platform
{
@@ -429,13 +475,21 @@ extern "C"
Ref<Architecture> arm64 = Architecture::GetByName("aarch64");
if (arm64)
{
- Ref<Platform> platform;
+ Ref<Platform> arm64_platform = new LinuxArm64Platform(arm64);
+ g_linuxIlp32 = new LinuxIlp32Platform(arm64);
+
+ Platform::Register("linux", arm64_platform);
+ Platform::Register("linux", g_linuxIlp32);
- platform = new LinuxArm64Platform(arm64);
- Platform::Register("linux", platform);
// Linux binaries sometimes have an OS identifier of zero, even though 3 is the correct one
- BinaryViewType::RegisterPlatform("ELF", 0, platform);
- BinaryViewType::RegisterPlatform("ELF", 3, platform);
+ BinaryViewType::RegisterPlatform("ELF", 0, arm64_platform);
+ BinaryViewType::RegisterPlatform("ELF", 3, arm64_platform);
+
+ Ref<BinaryViewType> elf = BinaryViewType::GetByName("ELF");
+ if (elf) {
+ elf->RegisterPlatformRecognizer(EM_AARCH64, LittleEndian, LinuxIlp32Platform::Recognize);
+ elf->RegisterPlatformRecognizer(EM_AARCH64, BigEndian, LinuxIlp32Platform::Recognize);
+ }
}
Ref<Architecture> ppc = Architecture::GetByName("ppc");