in rts/Linker.c [1480:1562]
HsInt loadOc (ObjectCode* oc)
{
int r;
IF_DEBUG(linker, debugBelch("loadOc: start\n"));
/* verify the in-memory image */
# if defined(OBJFORMAT_ELF)
r = ocVerifyImage_ELF ( oc );
# elif defined(OBJFORMAT_PEi386)
r = ocVerifyImage_PEi386 ( oc );
# elif defined(OBJFORMAT_MACHO)
r = ocVerifyImage_MachO ( oc );
# else
barf("loadObj: no verify method");
# endif
if (!r) {
IF_DEBUG(linker, debugBelch("loadOc: ocVerifyImage_* failed\n"));
return r;
}
/* Note [loadOc orderings]
The order of `ocAllocateExtras` and `ocGetNames` matters. For MachO
and ELF, `ocInit` and `ocGetNames` initialize a bunch of pointers based
on the offset to `oc->image`, but `ocAllocateExtras` may relocate
the address of `oc->image` and invalidate those pointers. So we must
compute or recompute those pointers after `ocAllocateExtras`.
On Windows, when we have an import library we (for now, as we don't honor
the lazy loading semantics of the library and instead GHCi is already
lazy) don't use the library after ocGetNames as it just populates the
symbol table. Allocating space for jump tables in ocAllocateExtras
would just be a waste then as we'll be stopping further processing of the
library in the next few steps. If necessary, the actual allocation
happens in `ocGetNames_PEi386` and `ocAllocateExtras_PEi386` simply
set the correct pointers.
*/
#if defined(NEED_SYMBOL_EXTRAS)
# if defined(OBJFORMAT_MACHO)
r = ocAllocateExtras_MachO ( oc );
if (!r) {
IF_DEBUG(linker,
debugBelch("loadOc: ocAllocateExtras_MachO failed\n"));
return r;
}
# elif defined(OBJFORMAT_ELF)
r = ocAllocateExtras_ELF ( oc );
if (!r) {
IF_DEBUG(linker,
debugBelch("loadOc: ocAllocateExtras_ELF failed\n"));
return r;
}
# endif
#endif
/* build the symbol list for this image */
# if defined(OBJFORMAT_ELF)
r = ocGetNames_ELF ( oc );
# elif defined(OBJFORMAT_PEi386)
r = ocGetNames_PEi386 ( oc );
# elif defined(OBJFORMAT_MACHO)
r = ocGetNames_MachO ( oc );
# else
barf("loadObj: no getNames method");
# endif
if (!r) {
IF_DEBUG(linker, debugBelch("loadOc: ocGetNames_* failed\n"));
return r;
}
#if defined(NEED_SYMBOL_EXTRAS)
# if defined(OBJFORMAT_PEi386)
ocAllocateExtras_PEi386 ( oc );
# endif
#endif
/* loaded, but not resolved yet, ensure the OC is in a consistent state */
setOcInitialStatus( oc );
IF_DEBUG(linker, debugBelch("loadOc: done.\n"));
return 1;
}