Recent

Author Topic: How to create a linkable .obj file (COFF)?  (Read 44851 times)

CodeX

  • New Member
  • *
  • Posts: 24
How to create a linkable .obj file (COFF)?
« on: February 13, 2011, 07:09:33 pm »
Hi,

I've written a code that I compile into a dll. Everything's working fine so far.

Now I need this code to be used in another project where it needs to be included as a linkable file that can be used by MS link.exe, namely an *.obj file in Common Object File Format (COFF).

How do I create such a file? I tried whether the *.o file from "lib\x86_64-win64" in the project folder is such a file, but I get dozens of errors like "error LNK2001: unresolved external symbol INIT$_SYSTEM" so I think that *.o file is not the one I need.

So how do I create a correct one? And if the *.o file is a propper object file, then do I have to change something in the project so it can be used propperly?

Thanks in advance!
« Last Edit: February 13, 2011, 07:24:13 pm by CodeX »

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: How to create a linkable .obj file (COFF)?
« Reply #1 on: February 13, 2011, 07:36:56 pm »
FPC produces COFF compatible object files, so those *.o's are what you're looking for. You can't just use .o's from your project file, but also it's dependencies: system unit + all other units you use. If you don't use any other unit, AFAIR you need at least system and sysinitpas, and maybe si_prc.

CodeX

  • New Member
  • *
  • Posts: 24
Re: How to create a linkable .obj file (COFF)?
« Reply #2 on: February 13, 2011, 07:48:42 pm »
Thank you, I appreciate your quick reply!

But I'm not quite sure if I understood correctly:
You can't just use .o's from your project file, but also it's dependencies: system unit + all other units you use. If you don't use any other unit, AFAIR you need at least system and sysinitpas, and maybe si_prc.

In my dll project I have only "uses Windows;". So what do I have to do to get it working? Do I need to include more files (system, sysinitpas, si_prc) into the project or do I need to create COFF files for those files as well and link them, too? Sorry, I'm a bit clueless. Could you please give me some more information on this?

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: How to create a linkable .obj file (COFF)?
« Reply #3 on: February 14, 2011, 12:52:51 am »
Quote
n my dll project I have only "uses Windows;"
From the source file, it seems that Windows unit doesn't depend on any other unit. So, you can assume it only needs windows.o.
Quote
So what do I have to do to get it working? Do I need to include more files (system, sysinitpas, si_prc) into the project or do I need to create COFF files for those files as well and link them, too?
Take those files from <fpc dir>/units/i386-win32/rtl and link them all.
If the unresolved external symbol error still appears, that means, you're missing something. The hard way would be to look at the unresolved symbol. Read the documentation on how FPC mangles symbols. The easy way would be to compile the project with -Cn switch, then open the generated link.res, look all occurences of INPUT. The files inside it are the ones you need.

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12718
  • FPC developer.
Re: How to create a linkable .obj file (COFF)?
« Reply #4 on: February 14, 2011, 06:01:10 pm »
All pascal source implicitly depends on unit System.

If you use a Delphi or ObjFPC mode, you also implicitly depend on unit objpas.

This can also be seen in the symbols of the missing symbol, note the SYSTEM

CodeX

  • New Member
  • *
  • Posts: 24
Re: How to create a linkable .obj file (COFF)?
« Reply #5 on: February 14, 2011, 07:11:53 pm »
I played around a little bit with the settings and now an *.obj file is generated in the lib\... folder.
While the *.o file is only about 12KB the *.obj file is about 136KB in size. It seems to have everything included that I needed, because now I don't get any more unresolved messages.

Because I always changed several settings before trying out, but I think in the end it was not a project setting but a line of code that did the trick: {$R *.res}
Besides the *.res file it also creates the *.obj file. At the moment I'm not at that system, but I tried out at my x86 system to reprocude it. Surprisingly here I get an *.or file instead of the *.obj file. Not sure why this is and what an *.or file is for (can't try it out atm).

CodeX

  • New Member
  • *
  • Posts: 24
Re: How to create a linkable .obj file (COFF)?
« Reply #6 on: February 14, 2011, 07:32:33 pm »
Actually I forgot the most important part: Although the strange unresolved-messages disappeared, I still have one. And it's my own function that I need.

Code: [Select]
error LNK2001: unresolved external symbol myfunc
In the project I have declared that function as:
Code: [Select]
function myfunc(...) : Integer; stdcall;

[...]

exports
  myfunc;

It works as a dll but isn't found by the linker. Do I need to do something else, so that it is available for external calls or COFF compatible symbol usage?

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: How to create a linkable .obj file (COFF)?
« Reply #7 on: February 15, 2011, 12:02:54 am »
Quote
Because I always changed several settings before trying out, but I think in the end it was not a project setting but a line of code that did the trick: {$R *.res}
Besides the *.res file it also creates the *.obj file. At the moment I'm not at that system, but I tried out at my x86 system to reprocude it. Surprisingly here I get an *.or file instead of the *.obj file. Not sure why this is and what an *.or file is for (can't try it out atm)
They're different beasts. {$R *.res} would link a .res file with the same name as the compiled file, fpcres would compile the resouce first to .or, before linking it with other .o files.
Quote
It works as a dll but isn't found by the linker. Do I need to do something else, so that it is available for external calls or COFF compatible symbol usage?
FPC seems to mangle stdcall declared routines with its own way (cdecl would mangle using C way). The exports section should actually make the symbol public with the name you specify, but since you use it from the object file, it doesn't happen. Try this:
Code: [Select]
function myfunc(...) : Integer; stdcall; [public,alias : 'myfunc']referenced from here

CodeX

  • New Member
  • *
  • Posts: 24
Re: How to create a linkable .obj file (COFF)?
« Reply #8 on: February 17, 2011, 04:41:22 pm »
Sorry for the delay and thank you very much for the promissing hint to add "[public,alias : 'myfunc']". I tried it out, but unfortunately it didn't change anything. I'm wondering if a dll structure is actually able to be used as a obj file at all. To use a function from a dll it must be added to the "exports" list, but I can't add stuff like the alias there, so I added it only to the function itself (as you suggested).

Is there something else that I could try?

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: How to create a linkable .obj file (COFF)?
« Reply #9 on: February 17, 2011, 04:53:41 pm »
Quote
I tried it out, but unfortunately it didn't change anything.
Does this show a line containing myfunc:
Code: [Select]
nm <your obj file> | grep myfuncIf not, then something must be wrong. My kernel uses that in some places and the symbols appear as expected.
Quote
Is there something else that I could try?
Nope from me

CodeX

  • New Member
  • *
  • Posts: 24
Re: How to create a linkable .obj file (COFF)?
« Reply #10 on: February 17, 2011, 07:52:40 pm »
What is nm(.exe) and where do I get that for doing the suggested test?
Maybe for clarification: I need that object file to be linked by MASM (ml64.exe) with some assembler code into an executable. I have a clear instruction how to use it which I followed, but the function within the object file is not recognized.
Is it important to have some certain compiler settings in the project preferences to be (in)active additionally?

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: How to create a linkable .obj file (COFF)?
« Reply #11 on: February 17, 2011, 11:19:09 pm »
Quote
What is nm(.exe) and where do I get that for doing the suggested test?
It's an object file's symbols lister. I'm not sure whether FPC default installation contains it or not. But it case not, you can download any Unix emulation layer for Windows such as msys (recommended) / cygwin / uwin / etc.
If you have visual studio (windows sdk to be precise) installed, there's also dumpbin utility that does the same. Use:
Code: [Select]
dumpbin /symbols <your object file>to achieve the same effect as above nm.
Quote
Is it important to have some certain compiler settings in the project preferences to be (in)active additionally?
Nope, except if you're doing this from different platform (e.g. i386-win32).

CodeX

  • New Member
  • *
  • Posts: 24
Re: How to create a linkable .obj file (COFF)?
« Reply #12 on: February 18, 2011, 12:13:34 am »
except if you're doing this from different platform (e.g. i386-win32).
Everything is done on a Win7 x64 system in a VM to get a proper x64 result.

I tried dumpbin with the following output:
Code: [Select]
Dump of file myfile.obj

File Type: COFF OBJECT

COFF SYMBOL TABLE
000 00000000 SECT1  notype       Static       | .rsrc

String Table Size = 0x0 bytes

  Summary

       21C4C .rsrc
Doesn't look like it's correct to me... :(
Any idea what might go wrong during the creation of the obj file? Or do you have a short step-by-step instruction how to get a proper obj file right from scratch?

Leledumbo

  • Hero Member
  • *****
  • Posts: 8835
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: How to create a linkable .obj file (COFF)?
« Reply #13 on: February 18, 2011, 02:28:32 am »
I never used dumpbin actually, since I prefer unix tools. But here's an insight, this code:
Code: [Select]
unit test;

interface

implementation

function myfunc: integer; stdcall; [public,alias: 'myfunc'];
begin
  myfunc := 0;
end;

end.
when compiled and nm-ed gives:
Quote
00000000 b .bss
00000000 d .data
00000000 d .data.n_THREADVARLIST_TEST
00000000 t .text
00000000 t .text.n_test_myfunc$$smallint
00000000 T TEST_MYFUNC$$SMALLINT
00000000 D THREADVARLIST_TEST
00000000 T myfunc
what if you try above code and dumpbin it?

CodeX

  • New Member
  • *
  • Posts: 24
Re: How to create a linkable .obj file (COFF)?
« Reply #14 on: February 18, 2011, 01:02:14 pm »
So you don't create a dll structure at all. Interesting. Well, maybe I should do the same. I'll be able to try this on Monday. I'll let you know about my results then. Thanks.

 

TinyPortal © 2005-2018