HsInt loadOc()

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;
}