Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
Shared Object for ARMv7L Target Has Incorrect Offsets on x86_64 Host #314
Describe the bug
I installed the 9.0.1 on my x86_64 Ubuntu desktop, created a new project from scratch, and imported a shared object (library) compiled for an ARMv7L target that contains multiple object files. I am still seeing Ghidra get confused about what symbols are where due to the incorrect 0x10000 offset.
When I compare the output of objdump for the same file and run the ARMv7L target itself, I can see that Ghidra has the disassembly for the function diminuto_cue_debounce correct, but because of the incorrect offset, it places it in the middle of an entirely different object module diminuto_controller.o and proceeds to interpret the variables as if they were in that module (e.g. "numerator" etc.) instead of diminuto_cue.o. Remarkably, the decompile for diminuto_due_debounce seems reasonable.
I similarly analyzed the same shared object but compiled for two different x86_64 targets (one of which was the host on which I ran Ghidra) and both disassemblies seem correct; I don't see the incorrect offset and the disassembly interprets the variables correctly.
Placement of symbols (e.g. functions) in disassembly should match output of tools run on the target like objdump; they don't for an ARMv7L target, they do for an x86_64 target.
Environment (please complete the following information):
The import of this file looks fine. If your only concern is the 0x10000 offset when compared to objdump this is not an import error unless the file has been prelinked in which case we should use the prelinked image base. This file is a relocatable shared library which can generally be imported to any base address of your choosing (see importer options). We default to offset 0x10000 which is somewhat arbitrary. We try to avoid loading at offset 0 when possible to help avoid mistaking small constants for address offsets. The importer has an image base offset option which can be set.
It's unclear what you are using as a basis for your module memory map since this is a relocatable module. Do you get the expected result if you set the import image base to 0?
BTW, my concern wasn't that it didn't match the output of objdump; my concern was that the disassembly was incorrect, placing symbols in the wrong locations. I can deal with issues in the decompile (I'm kind of amazed that it works at all) because I can read the disassembly to resolve any ambiguities. Example: when I insert some memory barrier machine instructions into the C code, in either the x86_64 or ARMv7L build, the decompiler gets confused and drops some of the idiomatic C instruction sequences (like straightforward variable assignments); but the disassembly is correct. I can live with that. But putting symbols in the wrong locations in the disassembly is very misleading.
When I originally looked at your sample I had only done an import to see where the ELF loader was placing symbols. Having just run analysis I now see the issue you pointed out. You may have also noticed a bunch of DWARF related errors in your log during analysis when an image base of 0x10000 was used. Using an image base of 0 likely avoids these errors. We currently are not handling relocation of DWARF debug data which is based at 0 for your sample. This results in DWARF analysis laying down symbols at the incorrect offset since the image base adjustment had not been applied. When DWARF data exists the 0 image base should probably be used until we are able to handle DWARF debug data relocations.