-
Notifications
You must be signed in to change notification settings - Fork 275
Add basic linux-ilp32 platform support #7292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Doing some testing with this PR reveals some additional issues with ILP32 compatibility, that I think might be at the aarch64 level. I have the following code: #include <stdio.h>
int main(void);
void * MAIN_ADDRESS = &main;
int main(void) {
printf("Sizes int=%lu long=%lu ptr=%lu\n", sizeof(int), sizeof(long), sizeof(int *));
printf("main addr: %p\n", MAIN_ADDRESS);
return 0;
}I generated a 32-bit and 64-bit aarch64 elf using gcc (the only 32-bit toolchain I could find online was https://snapshots.linaro.org/components/toolchain/binaries/7.5-2019.12-rc1/aarch64-linux-gnu_ilp32). In the Ilp32 binary there were still a couple places where pointer sizes were wrong:
Any help diagnosing these issues would be appreciated. |
|
Hey @mkrasnitski thanks for the PR! I'll take a closer look soon, but it looks like this gets us most of the way there. From your screenshots, it looks like clang is still parsing types as 64-bit, which is why you see the |
I took a look at the clang debug output by setting virtual void AdjustTypeParserInput(
Ref<TypeParser> parser,
std::vector<std::string>& arguments,
std::vector<std::pair<std::string, std::string>>& sourceFiles
) override
{
if (parser->GetName() != "ClangTypeParser")
{
return;
}
for (auto& arg: arguments)
{
if (arg.find("--target=") == 0 && arg.find("-unknown-") != std::string::npos)
{
arg = "--target=aarch64-unknown-linux-gnu_ilp32";
}
}
}The debug output confirms that the platform ends up modifying the clang args, however the same problems still persist, where the GOT entries for |
Is this code part of the core or will it be pushed to |
|
Here's the commit for the function recognizer changes |
|
This has been merged. ILP32 support is included in |
|
Sorry, just now getting around to testing this. Still running into a couple bugs around the PLT and function parameters. Specifically, |
|
Yes, I noticed this as well. I'm fairly confident the issue with the unresolved jumps from the PLT to the GOT are lifting bugs as a result of the 32-bit address being loaded into This shouldn't impact analysis much though since I updated function recognizer to identify the As for no params being passed to
|
|
I added platform types in diff --git a/arch/arm64/il.cpp b/arch/arm64/il.cpp
index f02cdd2d..ab6ff084 100644
--- a/arch/arm64/il.cpp
+++ b/arch/arm64/il.cpp
@@ -905,8 +905,11 @@ static void LoadStoreOperand(LowLevelILFunction& il, bool load,
ILSETREG_O(operand1, il.Operand(1, il.Load(load_store_sz, ILREG_O(operand2)))));
break;
case MEM_OFFSET:
- if (!load_store_sz)
- load_store_sz = REGSZ_O(operand1);
+ if ((operand1.reg[0] >= REG_W0 && operand1.reg[0] <= REG_WSP) || (operand1.reg[0] >= REG_S0 && operand1.reg[0] <= REG_S31))
+ {
+ BNRegisterInfo regInfo = il.GetArchitecture()->GetRegisterInfo(operand1.reg[0]);
+ operand1.reg[0] = (Register)regInfo.fullWidthRegister;
+ }
// operand1.reg = [operand2.reg + operand2.imm]
if (IMM_O(operand2) == 0)However, this isn't a good solution and we should be correctly handling the zero-extension from w17 to x17 in core. I'll create a separate issue for this. |




Now that platforms can specify their own address size, it would be nice for Binja to support ILP32 binaries. This PR adds initial support for recognizing when AARCH64 binaries are stored in a 32-bit ELF, based on the implementation for X32 binaries. Currently I am unsure if any underlying changes to the arm64 architecture itself are needed.