Skip to content

Commit 4448f8c

Browse files
committed
Linux platform for x86-64 with x32 ABI
1 parent 239b5db commit 4448f8c

File tree

1 file changed

+58
-5
lines changed

1 file changed

+58
-5
lines changed

platform/linux/platform_linux.cpp

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
using namespace BinaryNinja;
44
using namespace std;
55

6+
Ref<Platform> g_linuxX32;
7+
#define EM_X86_64 62 // AMD x86-64 architecture
68

79
class LinuxX86Platform: public Platform
810
{
@@ -103,6 +105,50 @@ class LinuxX64Platform: public Platform
103105
};
104106

105107

108+
class LinuxX32Platform: public Platform
109+
{
110+
public:
111+
LinuxX32Platform(Architecture* arch): Platform(arch, "linux-x32")
112+
{
113+
Ref<CallingConvention> cc;
114+
cc = arch->GetCallingConventionByName("sysv");
115+
if (cc)
116+
{
117+
RegisterDefaultCallingConvention(cc);
118+
RegisterCdeclCallingConvention(cc);
119+
RegisterFastcallCallingConvention(cc);
120+
RegisterStdcallCallingConvention(cc);
121+
}
122+
123+
cc = arch->GetCallingConventionByName("linux-syscall");
124+
if (cc)
125+
SetSystemCallConvention(cc);
126+
}
127+
128+
virtual size_t GetAddressSize() const override
129+
{
130+
return 4;
131+
}
132+
133+
static Ref<Platform> Recognize(BinaryView* view, Metadata* metadata)
134+
{
135+
Ref<Metadata> fileClass = metadata->Get("EI_CLASS");
136+
137+
if (!fileClass || !fileClass->IsUnsignedInteger())
138+
return nullptr;
139+
140+
Ref<Metadata> machine = metadata->Get("e_machine");
141+
if (!machine || !machine->IsUnsignedInteger())
142+
return nullptr;
143+
144+
if (fileClass->GetUnsignedInteger() == 1 && machine->GetUnsignedInteger() == EM_X86_64)
145+
return g_linuxX32;
146+
147+
return nullptr;
148+
}
149+
};
150+
151+
106152
class LinuxArmv7Platform: public Platform
107153
{
108154
public:
@@ -314,13 +360,20 @@ extern "C"
314360
Ref<Architecture> x64 = Architecture::GetByName("x86_64");
315361
if (x64)
316362
{
317-
Ref<Platform> platform;
363+
Ref<Platform> x64Platform = new LinuxX64Platform(x64);
364+
g_linuxX32 = new LinuxX32Platform(x64);
365+
366+
Platform::Register("linux", x64Platform);
367+
Platform::Register("linux", g_linuxX32);
318368

319-
platform = new LinuxX64Platform(x64);
320-
Platform::Register("linux", platform);
321369
// Linux binaries sometimes have an OS identifier of zero, even though 3 is the correct one
322-
BinaryViewType::RegisterPlatform("ELF", 0, platform);
323-
BinaryViewType::RegisterPlatform("ELF", 3, platform);
370+
BinaryViewType::RegisterPlatform("ELF", 0, x64, x64Platform);
371+
BinaryViewType::RegisterPlatform("ELF", 3, x64, x64Platform);
372+
373+
374+
Ref<BinaryViewType> elf = BinaryViewType::GetByName("ELF");
375+
if (elf)
376+
elf->RegisterPlatformRecognizer(EM_X86_64, LittleEndian, LinuxX32Platform::Recognize);
324377
}
325378

326379
Ref<Architecture> armv7 = Architecture::GetByName("armv7");

0 commit comments

Comments
 (0)