4

I'm going to write my first compiler (ok... most of the work was done by using ANTLR, but it still required effort)... I have already done the following things:

  • Implemented a working interpreter for very, very simple calculations (+, -, *, /, ^ - with proper precedence, of course, which was not that hard to implement)
  • Created a basic assembler code emitter (which was actually almost easier than writing the interpreter, because I used a rather simple "stack" based approach to handle the calculations - like: "push var1, push var2, add" - which could be then easily transformed into simple mov / add instructions
  • Was able to assemble to .exe (using ml64) and execute the resulting executable

Now my question is - if I want to create the COFF object files myself, how do I reference external symbols in libraries / other object files?

I mean, for example (if I want to call printf) it works like this, when I do it in ml64:

lea rcx, "address of string"
call printf

But what exactly do I write into the COFF file instead of "printf"?

Everything else is not THAT hard to implement, but I have absolutely no idea how to go about referencing libraries / other object files... hm...

Edit: fixed formatting (sorry) + clarifications

frankencode
  • 109
  • 1
  • 7

1 Answers1

5

Instead of the printf, you write four times 0x00, i. e. the call itself is assembled as 0xe8 0x00 0x00 0x00 0x00. Further, you need to write a relocation record with type DISP32, with the offset pointing to the first 0x00 and a value pointing to a symbol entry with the name printf. Wikipedia has some links to documents describing the COFF format in detail.

FPK
  • 2,008
  • 13
  • 19
  • Thank you... I seriously wonder why people who write specifications for file formats or API documentation don't always provide simple examples. Your two sentences answered question perfectly for me and should be part of COFF specification documents. :-) – frankencode Mar 13 '16 at 09:20