summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorBrandon Miller <brandon@vector35.com>2025-05-28 08:33:30 -0400
committerBrandon Miller <brandon@vector35.com>2025-05-28 08:33:30 -0400
commit6e4c00a80fa86bcfefba9630a1ea8e2a47bef2de (patch)
tree94f891149263fe089d747c4baba7d20a80a7750b /platform
parentb13d50bac18c341b98e6a3002ac9f17f6c8a8df4 (diff)
Support for Linux x86-64 x32 ABI
Diffstat (limited to 'platform')
-rw-r--r--platform/linux/platform_linux.cpp63
1 files changed, 58 insertions, 5 deletions
diff --git a/platform/linux/platform_linux.cpp b/platform/linux/platform_linux.cpp
index 0102fa42..20a258d6 100644
--- a/platform/linux/platform_linux.cpp
+++ b/platform/linux/platform_linux.cpp
@@ -3,6 +3,8 @@
using namespace BinaryNinja;
using namespace std;
+Ref<Platform> g_linuxX32;
+#define EM_X86_64 62 // AMD x86-64 architecture
class LinuxX86Platform: public Platform
{
@@ -103,6 +105,50 @@ public:
};
+class LinuxX32Platform: public Platform
+{
+ public:
+ LinuxX32Platform(Architecture* arch): Platform(arch, "linux-x32")
+ {
+ Ref<CallingConvention> cc;
+ cc = arch->GetCallingConventionByName("sysv");
+ 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_X86_64)
+ return g_linuxX32;
+
+ return nullptr;
+ }
+};
+
+
class LinuxArmv7Platform: public Platform
{
public:
@@ -314,13 +360,20 @@ extern "C"
Ref<Architecture> x64 = Architecture::GetByName("x86_64");
if (x64)
{
- Ref<Platform> platform;
+ Ref<Platform> x64Platform = new LinuxX64Platform(x64);
+ g_linuxX32 = new LinuxX32Platform(x64);
+
+ Platform::Register("linux", x64Platform);
+ Platform::Register("linux", g_linuxX32);
- platform = new LinuxX64Platform(x64);
- 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, x64, x64Platform);
+ BinaryViewType::RegisterPlatform("ELF", 3, x64, x64Platform);
+
+
+ Ref<BinaryViewType> elf = BinaryViewType::GetByName("ELF");
+ if (elf)
+ elf->RegisterPlatformRecognizer(EM_X86_64, LittleEndian, LinuxX32Platform::Recognize);
}
Ref<Architecture> armv7 = Architecture::GetByName("armv7");