Friday, January 22, 2010

ELF, DWARF, and *COFF* more ELF(64)

This post likely isn't going to make a lot of sense unless you really get into this niche topic... sorry all, its time for me to totally geek out.

So digging deeper and deeper into the underbelly of the beast that is the PS3 (yeah, I love it...) I'm parsing the ELF executable format in an attempt to dynamically load executables on the SPU.

"Why?!" you ask, when there are libraries that do it for us. Yes, in fact, the homebrew PS3 with Linux installed on it has the spe_context_run functions and the real devkits have SPURS. We don't "need" yet another way to load executables... do we?

Yes. And, as it turns out, no, not really. Well, the no is if you *Have* a devkit, you can just go the simple way and use SPURS. If you don't have the devkit, you could launch a pthread that loads and runs the executable on the PS3 but that is expensive as you need to reload the entire SPU each time you want to run a process. Not to mention that then you have all of these threads hanging out on the PPU just waiting and occupying stack and heap space.

So, for my purposes, yes, it is entirely necessary (from a pseudo-masochistic standpoint, but it's fun and an incredible learning experience.)

I'm not yet to the point of actually loading and executing the image yet, I'm still in the stage of processing and learning the format but I have to say it's pretty interesting. The file format is set up as a simple block loader where it has a header, program segments, section segments, and a ton of other information in it. There are extensions for different architectures and all sorts of extraneous data included in the executable that we don't need.

Oh, did I say extraneous? Why yes, I did! (aah yes, nothing like writing a blog post on a highly technical topic while half asleep at 3am before a long weekend where much packing of belongings will be involved...)

As a lot of people know, executables typically contains a TON of extra information in them that aren't needed for execution. For example, Brian Raiter wrote a very interesting (although not overly useful in daily operations) article where he reduced a simple hello world style executable from 3998 bytes to 45 bytes. Check it out at http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html.

Now, I had no desire to go to these lengths to reduce my executable size, but there is still a ton of information in them that we can get rid of.

Almost all of the ELF header can be discarded. For 64 bit images, this saves 64 bytes and for 32 bit images it saves 52. Not a lot, I know, but there are more savings to be had. Inside the executable are 'NOTE' segments that we can almost always (always?) get rid of. There are segments containing the names of segments as null terminated strings, segments that define empty segments, segments which are never referenced, etc., etc., etc.

So here's the plan... I'm going to start off simple (well... somewhat, I am loading an executable after all...) and get it to load into memory and successfully execute. After that, I'll start knocking out sections that I don't need as I figure it out. Some of it will be easy; other parts... well, not so much.

Wish me luck! (oh, and if you've done this before, please speak up as I'm having a HECK of a time trying to find documentation for some of this stuff!)