2013-09-13

2013-09-13 ELF Relocatable Executables

Last night I added an article about ELF Relocatable Executables, and as I was talking through it with Pink today, we came to the conclusion that getting the arbitrarily linked executable with relocation information (the one generated by --emit-relocs) was the best way to go.  If I take this approach, as I load each section, I need only store a single value for each which indicates the difference in memory address between where it was supposed to be loaded and where it ended up.  With this table, I could then parse the relocation table and just add the offset for the corresponding section to each relocation value.  Things are slightly more complicated for relocations which are Program Counter Relative in the code, but not hugely so.

Working on the ELF loader some more.   Originally it was a COFF loader which worked on the premise of there being one text section, one data section, and one BSS section, which is what DJGPP was generating for me at the time.  I'm now rewotking it to be less of a COFF-loader-adapted-to-ELF and more ELF friendly.

I've had to change a number of elements to change what was an ELF library loader to load executable files with relocation information in them.  After many hours of stepping through each section as I was modifying it, it has completed a first attempt.  All the signs look good that it loaded the executable, and performed the relocation to correct the file for where it was loaded, and called into the entry point.  The System Call interrupt handler fired, now just to see why it didn't seem to print the message.

libs_libraryDefinition at 0x40003C
LibraryNode: 0x0
LibraryName: 0x0
LibraryVersion: 0x0
LibraryLength: 0x0
SymbolTable: 0x4000CC
SymbolCount: 0x13
StringTable: 0x4001B0
EntryPoint: 0x4002B0
SectionCount: 0x16
  Section[0]: 0x0   Section[1]: 0x400294   Section[2]: 0x0
  Section[3]: 0x4004A1   Section[4]: 0x4004C0   Section[5]: 0x0
  Section[6]: 0x400670   Section[7]: 0x400670
--------------------------------------------------------------------------------
Interrupt 48 at 0x40044F
--------------------------------------------------------------------------------
0x10B8C0                                       B5 BE 02 00                µ¾..
0x10B8D0   B4 BE 02 00 38 B9 10 00 EC B8 10 00 20 BD 02 00    ´¾..8¹..ì¸.. ½..
0x10B8E0   D5 03 00 00 03 00 00 00 00 00 00 00 30 00 00 00    Õ...........0...
0x10B8F0   00 00 00 00 4F 04 40 00 08 00 00 00 06 02 00 00    ....O.@.........
0x10B900   D1 1D 10 00 88 42 10 00                            Ñ...ˆB..
SysCall
--------------------------------------------------------------------------------
-- Fin --

Ok, I've confirmed that it's gotten the resolve() function, and called it get the read, write and lseek API functions.  write() is then being called, but it's being called twice, once with a gibberish file descriptor, and once with 0.

I've put in the code to initialise the stdout FILE structure (oops), but it's still not calling write() with the correct parameters, and seems to sometimes spin off into the weeds.

There's probably something wrong with the relocation, maybe if I dump the RAM from the emulator and disassemble it to see if everything ended up as it should.  But probably tomorrow.

So as I've now fixed up the FILE structure for stdout, this has created relocations for the .data section.  What are the chances I'm not processing them?

No comments:

Post a Comment