5

I am trying to use a Wifi-Dongle with a Raspberry Pi. The vendor of the dongle provides a Linux driver that I can compile successfully on the ARM-architecture, however, one object file, that comes with the driver, was precompiled for a x86-architecture, which causes the linker to fail.

I know it would be much easier to compile that (quite big) file again, but I don't have access to the source code.

Is it possible to convert that object file from a x86-architecture to an ARM-architecture?

Thank you!

Dawamaha
  • 287
  • 1
  • 5
  • 9

7 Answers7

8

Um, no, it looks to me like a waste of time. Wi-Fi driver is complex, and you say this one troublesome object file is 'large'. Lots of pain to translate, and chance of successful debug slim to none. Also, any parameter passing between this one object file and the rest of the system would not translate directly between x86 and ARM.

Joe Kul
  • 2,454
  • 16
  • 16
  • Correct, this is not just about converting from one instruction set to another but about converting from one ABI (application binary interface) to another. This includes parameter passing, structure layout, syscall interfaces etc. It may be possible to do individual cases as "heroic" efforts but any general plug-and-play solution would be both technically difficult and a legal nightmare. – Al Grant Dec 31 '12 at 18:41
7

In theory, yes. Doing it on a real kernel driver without access to source code will be difficult.

If you had high quality dis-assembly of the object file, and the code in the object file is "well behaved" (using standard calling conventions, no self modifying code) then you could automatically translate the X86 instructions into arm instructions. However, you probably don't have high quality dis-assembly. In particular, there can be portions of the object file that you will not be able to properly classify as code or data doing normal recursive descent dis-assembly. If you misinterpret data as code, it will be translated to ARM code, rather than copied as is, and so will have the wrong values. That will likely cause the code to not work correctly.

Even if you get lucky, and can properly classify all of the addresses in the object file, there are several issues that will trip you up:

  1. The calling conventions on X86 are different than the calling conventions on ARM. This means you will have to identify patterns related to X86 calling conventions and change them to use ARM calling conventions. This is a non trivial rewrite.

  2. The hardware interface on ARM is different than on X86. You will have to understand how the driver works in order to translate the code. That would require either a substantial X86 hardware comparability layer, or reverse engineering of how the driver works. If you can reverse engineer the driver, then you don't need to translate it. You could just write an arm version.

  3. The internal kernel APIS are different between ARM and X86. You will have to understand those difference and how to translate between them. That's likely non trivial.

  4. The Linux Kernel uses an "alternatives" mechanism, which will rewrite machine code dynamically when code is first loaded into the kernel. For example, on uni-processor machines, locks are often replaced with no-ops to improve perf. Instructions like "popcnt" are replaced with function calls on machines that don't support it, etc. It's use in the Kernel is extremely common. This means there's a good chance the code in the object is file is not "well behaved", according to the definition given above. You would have to either verify that the object file doesn't use that mechanism, or find a way to translate uses of it.

  5. X86 uses a different memory model than ARM does. To "safely" translate X86 code to ARM (without introducing race conditions) you would have to introduce memory fences after every memory access. That would result in REALLY BAD performance on an ARM chip. Figuring out when you need to introduce memory fences (without doing it everywhere) is an EXTREMELY hard problem. The most successful attempts at that sort of analysis require custom type systems, which you won't have in the object file.

Your best bet (quickest route to success) would be to try and reverse engineer what the object file in question does, and then just replace it.

Scott Wisniewski
  • 24,561
  • 8
  • 60
  • 89
1

There is no reasonable way of doing this. Contact the manufacturer and ask if they can provide the relevant code in ARM code, as x86 is useless to you. If they are not able to do that, you'll have to find a different supplier of either the hardware [that has an ARM version, or fully open source, of all the components], or supplier of the software [assuming there is another source of that].

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
0

You could translate the x86 assembly manually by installing x86 GNU binutils and disassemble the object file with objdump. Probably some addresses will differ but should be straight forward.

emil
  • 1,642
  • 13
  • 12
  • I'm not that experienced in Linux, how can I get the x86 binutils? And after disassembling, what do I need to do to assemble the file back to an object file? – Dawamaha Dec 30 '12 at 15:44
  • i think you could try directly with objdump in linux/arm, It should understand linux/x86: `objdump -d file.o`, write the arm instrictions to file.s and then assemble with `as(1)` or `gcc(1)`. http://arm-assembler-for-raspberrypi.posterous.com/lesson-1-hello-world – emil Dec 30 '12 at 16:38
  • 2
    Really, this is not a workable solution for anything more than a few hundred or maybe a couple of thousand instructions, unless you have a reasonable understanding of how it's meant to work - and even then it would be really hard work. Compiled code is not always easy to understand [because compiler re-orders the order things are done in various ways, inlines functions that are commonly called, etc, etc]. Trust me, I've spent MANY hours trying to figure out how some disassembled code works - even when you know roughly what it does, it's hard work. – Mats Petersson Dec 31 '12 at 14:17
0

Yes, you could most definitely do a static binary translation. x86 disassembly is painful though, if this was compiled from high level then it isnt as bad as it could be.

Is it really worth the effort? Might try an instruction set simulator instead. Have you done an analysis of the number of instructions used? System calls required, etc?

How far have you gotten so far on the disassembly?

old_timer
  • 69,149
  • 8
  • 89
  • 168
0

Maybe the file only contains a binary dump of the wifi firmware? If so you need no instruction translation and a conversion can be done using objcopy.

You can you use objdump -x file.o and look if any real executable code is inside the obj-file or if it's only data.

Nils Pipenbrinck
  • 83,631
  • 31
  • 151
  • 221
0

If you have access to IDA with Hex-Rays decompiler, you can (with some work) decompile the object file into C code and then try to recompile it for ARM.

Igor Skochinsky
  • 24,629
  • 2
  • 72
  • 109