GoLink: now can mix obj files, lib code, from different compilers

Started by jorgon, February 01, 2009, 01:32:25 PM

Previous topic - Next topic

jorgon

I have now added the /mix switch to GoLink (version 26.10 beta attached).  This will allow you to use GoLink to link object files made with a "C" compiler or MASM, and mix these with GoAsm object files.

As highlighted by some recent topics on this board, GoLink was not recognising symbols in object files made with those tools.  This is because the symbols had been "decorated" automatically by the tools.

Examples are:-
_MessageBoxW@16 (indirect call to an API where there are four parameters)
__imp__GetKeyState@4 (direct call to an API where there is one parameter)
_MyDataLabel (simple decoration applied to a data label)
_MyCodeLabel (simple decoration applied to a code label)
_MyCodeLabel@4 (decoration applied to a code label declared as having one parameter)

The idea behind the _Name@xx decoration is that it provides a check that the number of parameters declared for a function is the same between the various modules (object files).  In practice however, the added complexity of the required source code (eg. in MASM the need for EXTRN, EXTERN or PROTO to define the type of symbol) is very much out of proportion to the benefits achieved. 
Some compilers also use decoration to enhance error reporting, but this has another problem: there is no consistent format for this.
Because GoAsm does not decorate symbols (unless the GoAsm /ms switch is used), GoLink does not expect symbol decoration.  This means that if you want to use GoLink to link files made with a third party compiler which decorates symbols you must specify the /mix switch.  This will cause GoLink to strip out decoration when comparing symbol names. 

If you use the /mix switch, you will be unable to use a single leading underscore intentionally to differentiate between symbols.  For example GoLink will regard _DOG and DOG as the same name.

The /mix switch may also resolve problems if you have merged in a GoAsm module static library code made with such third party tools.  If such code calls or references other such merged code, it is possible that this will be done with decorated symbols.  These would not be recognised by GoLink unless the /mix switch is used.



[attachment deleted by admin]
Author of the "Go" tools (GoAsm, GoLink, GoRC, GoBug)

jorgon

I have now added something else to the /mix switch in GoLink 26.10 beta2 (in the original message).  It's a smaller file because it does not include the help file.

When the /mix switch is used, this latest version beta2 can also find a symbol which is undecorated in a DLL, but which has simple decoration of the type "_CodeLabel" (no @xx at the end or __imp_ at the beginning) in the symbol table of the caller's object file.  This seems to happen if the source code for the caller's module does not provide a complete description of the call.

Without the /mix switch, if a symbol has a leading underscore and no more decoration then GoLink expects both the symbols in the DLL and in the calling module to have a leading underscore.  This is to cover the possibility that the programmer intended the symbol name to have a leading underscore.  Therefore if you use the /mix switch, you should not use intentional leading underscores.

Author of the "Go" tools (GoAsm, GoLink, GoRC, GoBug)

Vortex

Hi Jeremy,

Thanks for this new version of GoLink supporting mixed object modules.

Attached is a Pelles C project using GoLink's new switch /mix. Both decorated and non-decorated forms of external functions are processed by GoLink.

[attachment deleted by admin]

jorgon

Thanks very much for trying this out and reporting it as ok, Vortex.
So no nasty surprises in Pelles C object files!

Author of the "Go" tools (GoAsm, GoLink, GoRC, GoBug)

jorgon

Mitchi and Beatrix have identified in recent postings, that GoLink is not finding certain symbols emitted by a "C" compiler.
From the files they have posted, these are "common symbols" which are symbols which which are not actually defined in the source, but which need to be given an allocation in unitialised data at link time by the linker.  As I understand it, all the data in such common symbols is merged [a symbol with the same name in different modules will occupy the same place in the resulting exe, although they may be different sizes and may not be defined (declared) at all].  In this respect they act like global symbols but the difference is that they are not actually declared anywhere.  It also means that data can be written over because of the merger.

As I understand it, you can intentionally make common symbols with the GNU assembler and with MASM using COMM (although I can't think of any reason to do so), and I now understand from recent postings that a "C" compiler will use these "behind your back" if you try to create a data reference using something like

int MyVar;

I have now adjusted GoLink to support common symbols using the /mix switch.

See Version 0.26.10 beta3 in the original posting.


Author of the "Go" tools (GoAsm, GoLink, GoRC, GoBug)