Skip to content

Conversation

mkrasnitski
Copy link
Contributor

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.

@mkrasnitski
Copy link
Contributor Author

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:

image image

Any help diagnosing these issues would be appreciated.

@zznop
Copy link
Member

zznop commented Aug 22, 2025

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 _ptr64 param for printf. Should be an easy fix.

@plafosse plafosse requested a review from zznop August 28, 2025 14:02
@mkrasnitski
Copy link
Contributor Author

mkrasnitski commented Aug 28, 2025

From your screenshots, it looks like clang is still parsing types as 64-bit, which is why you see the _ptr64 param for printf. Should be an easy fix.

I took a look at the clang debug output by setting BN_DEBUG_CLANG=1, and looks like the target triple for ilp32 binaries is being explicitly set to --target=arm64-unknown-linux-ilp32-unknown. I tried adding an implementation of AdjustTypeParserInput which sets it to --target=aarch64-unknown-linux-gnu_ilp32 but that didn't seem to solve the problem. Here's what I tried:

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 printf and __gmon_start__ seem to be using 64-bit pointers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants