Question

I'm writing a linker that runs on Windows, and I've got it accepting most features of PE format object files, but I'm running into a problem with duplicate definitions of _aenvptr and _wenvptr in libcmt.

From what I've been able to figure out between the PE documentation, trial and error with the Microsoft compiler and dumpbin, and the occasional question here, the rules are:

int x;

as a global variable translates into IMAGE_SYM_CLASS_EXTERNAL with no section. If this occurs in more than one object file, this is fine, and the largest one is taken and used as a BSS definition.

int x = 0;

as a global variable translates into IMAGE_SYM_CLASS_EXTERNAL with a BSS section. If this occurs in more than one object file, this is a duplicate symbol error.

The problem is that libcmt provides multiple definitions of _aenvptr and _wenvptr in the latter form. The Microsoft linker is happy with this, but it's not happy with what as far as I can tell is an equivalent case in a small test library I created.

_aenvptr and _wenvptr are not COMDAT, nor do they have any auxiliary symbol records or anything else weird that I've been able to find.

What am I missing?

Was it helpful?

Solution

These symbols are defined in two objects, yes: there are definitions in both crt0.obj and dllcrt0.obj. These objects contain the startup code for EXEs and DLLs, respectively.

The trick here is that there should never be a case where both objects are linked into a single module. The linker does not pull all objects from a library into a link; instead, it only pulls in any objects that are required to satisfy dependencies. There is no case where both crt0.obj and dllcrt0.obj will be linked into a single module; their use is mutually exclusive.

Basically, there can be many definitions of the same external symbol in a library, so long as [1] each definition is in a different object and [2] only one of those objects is actually used in the link.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top