7 ms·
I've kicked around the idea of translating machine code to LLVM assembly code specifically to do things like this. I actually got as far as creating a GitHub r
by wtracy 13y ago
I've kicked around the idea of translating machine code to LLVM assembly code specifically to do things like this.
I actually got as far as creating a GitHub repo to work on this <https://github.com/wtracy/recompile> https://github.com/wtracy/recompile> but my code never got farther than some logic for parsing ELF headers.
- tluyben2 13y agoExcuse my ignorance here; I wanted to get into LLVM more but never did. Don't you have: frontends which do Language => LLVM intermediate code and backends which do LLVM code => native ? So you were writing a frontend which could do x86 => LLVM code and then it can compile to ARM, x86, JS etc? Sounds like a HUGE undertaking (esp for one person) but worth it; once you have that frontend (if my assumptions are correct), you would be able to have a lot of fun.
- wtracy 13y agoThat's a pretty accurate description of what I was trying to do. You are correct that it's a huge undertaking. :-) That said, even once you've got x86 -> LLVM translation working, there's a lot of code out there that makes x86-specific assumptions. I once interviewed with a group that was trying to port a large codebase from PPC to x86, and even having the source code didn't help with the fact that their code assumed a big-endian architecture.
- moyix 13y agoOne approach to this is taken by RevGen [1], which uses QEMU to disassemble the target code and lift it to QEMU's intermediate representation (TCG). The TCG ops are then translated to LLVM. It's definitely not perfect, but I suspect it will work much better than trying to do x86->LLVM from scratch. QEMU's IR is very likely much closer to correct than anything you'd come up with, since it is used for emulation, and the mapping from QEMU IR to LLVM is very straightforward (you can even run QEMU with LLVM as the backend, albeit with some performance penalty). Two things to watch out for in this approach: helper functions (places where QEMU has decided to use a C function to implement some functionality rather than implementing it in TCG) and there may be some artifacts in the generated LLVM from things that are related to QEMU's system emulation rather than what the original code did. [1] http://infoscience.epfl.ch/record/166081/files/revgen.pdf http://infoscience.epfl.ch/record/166081/files/revgen.pdf
- wtracy 13y agoVery cool--I'll look at this if I ever get back to this project. (Unlikely, given the changes in my priorities since I started it.) At the time, my primary motivation was really to learn more about x86 machine code, which explains the brute-force approach. (Hey, Linux got started because Linus wanted to learn more about x86 memory management, so it's not a completely dumb approach.)
- jevinskie 13y agoI can't wait until I find such a project that is in a usable state! I've tried all of these (save dagger, no releases yet) and always hit some issue due to their immaturity. https://github.com/libcpu/libcpu https://github.com/libcpu/libcpu http://dagger.repzret.org/ http://dagger.repzret.org/ https://github.com/draperlaboratory/fracture https://github.com/draperlaboratory/fracture
- derefr 13y agoI think the most stable implementation in this space (if limited in scope) would be Apple's Rosetta. Sadly both closed-source and now abandoned; if it was opened up, it'd be great to base a more general A-to-B translator on.
- deleted 13y ago[deleted]
- dangero 13y agoYeah LLVM would be really cool like emscripten, but for x86. I would like to see a performance comparison of this approach vs. running a full virtual machine since the x86 to arm conversion approach still requires a wine lib to execute all the windows APIs.