Opened 13 years ago
Last modified 12 years ago
#8520 new enhancement
runtime loader should check elf headers for things like architecture.
Reported by: | kallisti5 | Owned by: | bonefish |
---|---|---|---|
Priority: | normal | Milestone: | Unscheduled |
Component: | System/runtime_loader | Version: | R1/Development |
Keywords: | Cc: | landonf@… | |
Blocked By: | Blocking: | ||
Platform: | All |
Description
Running a PowerPC BeOS binary under Haiku results in a generic failure message such as:
- Could not find an application to open "XXX" (Invalid Argument)
Enhanced checks on binaries would be a nice feature. Example:
- Detecting running a binary for a non-compatible architecture.
- Detecting running pre-BeOS R5 binaries?
mmu mentioned adding B_BAD_IMAGE_ARCHITECTURE for arch failure checks and maybe B_BAD_IMAGE_PLATFORM.
Attachments (2)
Change History (18)
comment:1 by , 13 years ago
follow-up: 3 comment:2 by , 13 years ago
PowerPC BeOS binaries have non-elf format(binary start by "Joy!"), haven't they?
Also it will be good if Haiku's runtime_loader could use dynamic translator if target and host architecture differs. Dynamic translator can be found in Qemu sources. For PowerPC it mostly don't have practical reasons, but when Haiku will be ported to ARM users could run x86 binaries(from BeOS and new) on ARM tablets and smartphones.
comment:3 by , 13 years ago
Replying to X512:
PowerPC BeOS binaries have non-elf format(binary start by "Joy!"), haven't they?
It's been a while, but I believe you're correct, if memory serves the mwcc toolchain used on BeOS/PPC outputted PeCOFF binaries.
comment:4 by , 13 years ago
X512: you are correct.. we verified this in irc.
It was discussed adding a check for Joy! in test_executable, however that wouldn't be *super* reliable as it could result in false positives.
We still should check elf binaries though as it would be nice feedback... especially after arch-ports are better formed :)
follow-up: 10 comment:6 by , 13 years ago
Replying to kallisti5:
A side note, parse_elf_header returns a failure if the elf is != 32-bits... that may cause issues in our x86_64 (or any non-32-bit) port.
The runtime loader only supports ELF32 ATM, so it's not this check that will cause problems, but the complete absence of ELF64 support. :-)
Investing any time in pre BeOS R5 x86 or BeOS PPC executables is a waste of time IMO.
Regarding the architecture check, that certainly makes sense. Since we only have a single architecture that even supports a userland ATM, the need for this check isn't particularly dire, though. But sure, feel free to add it. parse_elf_header()
is the place to do it. The same check can be added to test_executable()
as well (could be extracted to a commonly called function).
@X512: It's one thing to translate machine code from a different architecture, it's another thing to do that in an API/ABI compatible way. This is probably a big project and not particularly worthwhile IMO. Most of Haiku's software is open source anyway, so it can just be recompiled for the other architecture. For the remaining closed source projects it's easier to provide a cross-compilation environment, so that the vendors can build the executables themselves.
comment:7 by , 13 years ago
patch: | 0 → 1 |
---|
comment:8 by , 13 years ago
first go at it attached.. I definitely want some oversight before I commit such a change.
comment:9 by , 13 years ago
oops... if it is a shared library, status gets overwritten by the arch check. Will fix and upload version 2
comment:10 by , 13 years ago
Replying to bonefish:
@X512: It's one thing to translate machine code from a different architecture, it's another thing to do that in an API/ABI compatible way. This is probably a big project and not particularly worthwhile IMO.
It's much simpler that you think. To run an application you of cource need compiled Haiku libs for target architecture. For example if you run x86 Wonderbrush(it's closed source, isn't it?) on ARM, haiku will use x86 libraries without modification. There are no need in dynamic ABI translation, only syscalls translation needed.
As I understand Qemu already provide everything needed to launch apps with other target architecture on linux. Only runtime_loader integration(runtime_loader add-ons mayble?) and diffrent syscalls translation needed.
Sorry for offtop.
comment:11 by , 13 years ago
@kallisti5: The check should not only be done in test_executable()
. That function is called for an executable that is asked to be executed. It is not called for libraries or add-ons being loaded. So a check in parse_elf_header()
is required as well.
Regarding the patch:
- The new error macro definitions should be appended to the block for the runtime loader errors, continuing the sequence.
- I don't see what error condition
B_BAD_IMAGE_PLATFORM
would indicate. - For
B_BAD_IMAGE_ARCHITECTURE
I would find "MISMATCHING" instead of "BAD" more fitting. I'd also drop the "IMAGE". - I doubt
test_architecture()
even compiles. It declareschar name[128]
, but assigns string literals to the variable. - I would organize the architecture check differently: In some header define a macro
ELF_MACHINE
for the expected ELF machine via #ifdef chain. The check intest_architecture()
becomeselfMachine == ELF_MACHINE
. The debug output is not needed IMO, sotest_architecture()
becomes superfluous; the check can be inlined in bothtest_executable()
andparse_elf_header()
.
Regarding your TODO question: No, the i386/x86_64 check cannot be done in the runtime loader. The kernel already needs to load the respective runtime loader matching the architecture.
@X512: No, it isn't that simple. At some points (whether it is shared object boundaries or the kernel interface and client-server protocols) the emulated program needs to interface with the native system. At these points a translation has to happen that qemu cannot possibly know about. E.g. a C structure that is passed to the kernel doesn't necessarily have the same layout for all architectures (certain datatypes may or may not change width depending on the architecture). The information for such a conversion is not present in the object code.
comment:12 by , 13 years ago
@bonefish thanks for the feedback... all great ideas + info.
I'll rework the patch.
the B_BAD_IMAGE_PLATFORM was incase the binary code was PE vs ELF... however that's kind of moot now.. can remove.
comment:13 by , 13 years ago
"I doubt test_architecture() even compiles. It declares char name[128], but assigns string literals to the variable."
Also, yeah.. it was a quick brain dump of a patch. Next version will be more final. I figured quite a bit would need to change :)
comment:14 by , 12 years ago
Milestone: | R1/alpha4 → Unscheduled |
---|
This isn't required for alpha4, or even R1 for that matter, so moving to unscheduled. But don't let that stop you from working on it in the meantime.
comment:15 by , 12 years ago
Cc: | added |
---|
I needed to solve this issue as part of the FatELF work; I've cherry picked my specific patches to create a standalone issue branch here:
https://github.com/landonf/haiku-fatelf/compare/haiku_issue_8520
With this in place:
~> cp /bin/ls ./ls-bad ~> elfedit --output-mach=x86_64 ls-bad ~> ./ls-bad bash: ./ls-bad: Executable not supported by this architecture
Feel free to cherry pick as desired, if desired.
A little research:
I *think* parse_elf_header would be an ideal place it looks like for the arch check.
eheader->e_machine I *think* is the correct field to look at.
A side note, parse_elf_header returns a failure if the elf is != 32-bits... that may cause issues in our x86_64 (or any non-32-bit) port.