int compileResult;
#endif
+ IF_DEBUG(linker, debugBelch("initLinker: start\n"));
+
/* Make initLinker idempotent, so we can call it
before evey relevant operation; that means we
don't need to initialise the linker separately */
- if (linker_init_done == 1) { return; } else {
- linker_init_done = 1;
+ if (linker_init_done == 1) {
+ IF_DEBUG(linker, debugBelch("initLinker: idempotent return\n"));
+ return;
+ } else {
+ linker_init_done = 1;
}
#if defined(THREADED_RTS) && (defined(OBJFORMAT_ELF) || defined(OBJFORMAT_MACHO))
for (sym = rtsSyms; sym->lbl != NULL; sym++) {
ghciInsertStrHashTable("(GHCi built-in symbols)",
symhash, sym->lbl, sym->addr);
+ IF_DEBUG(linker, debugBelch("initLinker: inserting rts symbol %s, %p\n", sym->lbl, sym->addr));
}
# if defined(OBJFORMAT_MACHO) && defined(powerpc_HOST_ARCH)
machoInitSymbolsWithoutUnderscore();
addDLL("msvcrt");
addDLL("kernel32");
#endif
+
+ IF_DEBUG(linker, debugBelch("initLinker: done\n"));
+ return;
}
void
lookupSymbol( char *lbl )
{
void *val;
+ IF_DEBUG(linker, debugBelch("lookupSymbol: looking up %s\n", lbl));
initLinker() ;
ASSERT(symhash != NULL);
val = lookupStrHashTable(symhash, lbl);
if (val == NULL) {
+ IF_DEBUG(linker, debugBelch("lookupSymbol: symbol not found\n"));
# if defined(OBJFORMAT_ELF)
return dlsym(dl_prog_handle, lbl);
# elif defined(OBJFORMAT_MACHO)
symbol name. For now, we simply strip it off here (and ONLY
here).
*/
+ IF_DEBUG(linker, debugBelch("lookupSymbol: looking up %s with dlsym\n", lbl));
ASSERT(lbl[0] == '_');
return dlsym(dl_prog_handle, lbl+1);
# else
return NULL;
# endif
} else {
+ IF_DEBUG(linker, debugBelch("lookupSymbol: value of %s is %p\n", lbl, val));
return val;
}
}
/* loaded, but not resolved yet */
oc->status = OBJECT_LOADED;
+ IF_DEBUG(linker, debugBelch("loadObj done.\n"));
return 1;
}
ObjectCode *oc;
int r;
+ IF_DEBUG(linker, debugBelch("resolveObjs: start\n"));
initLinker();
for (oc = objects; oc; oc = oc->next) {
oc->status = OBJECT_RESOLVED;
}
}
+ IF_DEBUG(linker, debugBelch("resolveObjs: done\n"));
return 1;
}
{
ProddableBlock* pb
= stgMallocBytes(sizeof(ProddableBlock), "addProddableBlock");
- /* debugBelch("aPB %p %p %d\n", oc, start, size); */
+ IF_DEBUG(linker, debugBelch("addProddableBlock %p %p %d\n", oc, start, size));
ASSERT(size > 0);
pb->start = start;
pb->size = size;
unsigned i;
size_t itemSize = 4;
+ IF_DEBUG(linker, debugBelch("resolveImports: start\n"));
+
#if i386_HOST_ARCH
int isJumpTable = 0;
if(!strcmp(sect->sectname,"__jump_table"))
char *nm = image + symLC->stroff + symbol->n_un.n_strx;
void *addr = NULL;
- if((symbol->n_type & N_TYPE) == N_UNDF
- && (symbol->n_type & N_EXT) && (symbol->n_value != 0))
+ IF_DEBUG(linker, debugBelch("resolveImports: resolving %s\n", nm));
+ if ((symbol->n_type & N_TYPE) == N_UNDF
+ && (symbol->n_type & N_EXT) && (symbol->n_value != 0)) {
addr = (void*) (symbol->n_value);
- else
+ IF_DEBUG(linker, debugBelch("resolveImports: undefined external %s has value %p\n", nm, addr));
+ } else {
addr = lookupSymbol(nm);
- if(!addr)
+ IF_DEBUG(linker, debugBelch("resolveImports: looking up %s, %p\n", nm, addr));
+ }
+ if (!addr)
{
errorBelch("\n%s: unknown symbol `%s'", oc->fileName, nm);
return 0;
}
}
+ IF_DEBUG(linker, debugBelch("resolveImports: done\n"));
return 1;
}
unsigned long address)
{
int i;
- for(i = 0; i < nSections; i++)
+ IF_DEBUG(linker, debugBelch("relocateAddress: start\n"));
+ for (i = 0; i < nSections; i++)
{
- if(sections[i].addr <= address
+ IF_DEBUG(linker, debugBelch(" relocating address in section %d\n", i));
+ if (sections[i].addr <= address
&& address < sections[i].addr + sections[i].size)
{
return (unsigned long)oc->image
int nSections, struct section* sections, struct section *sect)
{
struct relocation_info *relocs;
- int i,n;
+ int i, n;
+
+ IF_DEBUG(linker, debugBelch("relocateSection: start\n"));
if(!strcmp(sect->sectname,"__la_symbol_ptr"))
return 1;
return 1;
n = sect->nreloc;
+ IF_DEBUG(linker, debugBelch("relocateSection: number of relocations: %d\n", n));
+
relocs = (struct relocation_info*) (image + sect->reloff);
for(i=0;i<n;i++)
default:
barf("Unknown size.");
}
-
- if(type == X86_64_RELOC_GOT
+
+ IF_DEBUG(linker,
+ debugBelch("relocateSection: length = %d, thing = %d, baseValue = %p\n",
+ reloc->r_length, thing, baseValue));
+
+ if (type == X86_64_RELOC_GOT
|| type == X86_64_RELOC_GOT_LOAD)
{
+ struct nlist *symbol = &nlist[reloc->r_symbolnum];
+ char *nm = image + symLC->stroff + symbol->n_un.n_strx;
+
+ IF_DEBUG(linker, debugBelch("relocateSection: making jump island for %s, extern = %d, X86_64_RELOC_GOT\n", nm, reloc->r_extern));
ASSERT(reloc->r_extern);
- value = (uint64_t) &makeSymbolExtra(oc, reloc->r_symbolnum, value)->addr;
+ value = (uint64_t) &makeSymbolExtra(oc, reloc->r_symbolnum, (unsigned long)lookupSymbol(nm))->addr;
type = X86_64_RELOC_SIGNED;
}
{
struct nlist *symbol = &nlist[reloc->r_symbolnum];
char *nm = image + symLC->stroff + symbol->n_un.n_strx;
- if(symbol->n_value == 0)
- value = (uint64_t) lookupSymbol(nm);
- else
+
+ IF_DEBUG(linker, debugBelch("relocateSection: looking up external symbol %s\n", nm));
+ IF_DEBUG(linker, debugBelch(" : type = %d\n", symbol->n_type));
+ IF_DEBUG(linker, debugBelch(" : sect = %d\n", symbol->n_sect));
+ IF_DEBUG(linker, debugBelch(" : desc = %d\n", symbol->n_desc));
+ IF_DEBUG(linker, debugBelch(" : value = %d\n", symbol->n_value));
+ if ((symbol->n_type & N_TYPE) == N_SECT) {
value = relocateAddress(oc, nSections, sections,
symbol->n_value);
+ IF_DEBUG(linker, debugBelch("relocateSection, defined external symbol %s, relocated address %p\n", nm, value));
+ }
+ else {
+ value = (uint64_t) lookupSymbol(nm);
+ IF_DEBUG(linker, debugBelch("relocateSection: external symbol %s, address %p\n", nm, value));
+ }
}
else
{
- sections[reloc->r_symbolnum-1].addr
+ (uint64_t) image;
}
-
- if(type == X86_64_RELOC_BRANCH)
+
+ IF_DEBUG(linker, debugBelch("relocateSection: value = %p\n", value));
+
+ if (type == X86_64_RELOC_BRANCH)
{
if((int32_t)(value - baseValue) != (int64_t)(value - baseValue))
{
}
#endif
}
+ IF_DEBUG(linker, debugBelch("relocateSection: done\n"));
return 1;
}
char *commonStorage = NULL;
unsigned long commonCounter;
- IF_DEBUG(linker,debugBelch("ocGetNames_MachO\n"));
+ IF_DEBUG(linker,debugBelch("ocGetNames_MachO: start\n"));
for(i=0;i<header->ncmds;i++)
{
for(i=0;i<segLC->nsects;i++)
{
- if(sections[i].size == 0)
+ IF_DEBUG(linker, debugBelch("ocGetNames_MachO: segment %d\n"));
+ if (sections[i].size == 0)
continue;
if((sections[i].flags & SECTION_TYPE) == S_ZEROFILL)
}
}
}
+ IF_DEBUG(linker, debugBelch("ocGetNames_MachO: %d external symbols\n", oc->n_symbols));
oc->symbols = stgMallocBytes(oc->n_symbols * sizeof(char*),
"ocGetNames_MachO(oc->symbols)");
if(nlist[i].n_type & N_EXT)
{
char *nm = image + symLC->stroff + nlist[i].n_un.n_strx;
- if((nlist[i].n_desc & N_WEAK_DEF) && lookupSymbol(nm))
- ; // weak definition, and we already have a definition
+ if ((nlist[i].n_desc & N_WEAK_DEF) && lookupSymbol(nm)) {
+ // weak definition, and we already have a definition
+ IF_DEBUG(linker, debugBelch(" weak: %s\n", nm));
+ }
else
{
- IF_DEBUG(linker,debugBelch("Adding symbol 1 %s\n", nm));
+ IF_DEBUG(linker, debugBelch("ocGetNames_MachO: inserting %s\n", nm));
ghciInsertStrHashTable(oc->fileName, symhash, nm,
image
+ sections[nlist[i].n_sect-1].offset
nlist[i].n_value = commonCounter;
- IF_DEBUG(linker,debugBelch("Adding symbol 2 %s\n", nm));
+ IF_DEBUG(linker, debugBelch("ocGetNames_MachO: inserting common symbol: %s\n", nm));
ghciInsertStrHashTable(oc->fileName, symhash, nm,
(void*)commonCounter);
oc->symbols[curSymbol++] = nm;
struct dysymtab_command *dsymLC = NULL;
struct nlist *nlist;
- for(i=0;i<header->ncmds;i++)
+ IF_DEBUG(linker, debugBelch("ocResolve_MachO: start\n"));
+ for (i = 0; i < header->ncmds; i++)
{
if(lc->cmd == LC_SEGMENT || lc->cmd == LC_SEGMENT_64)
segLC = (struct segment_command*) lc;
unsigned long *indirectSyms
= (unsigned long*) (image + dsymLC->indirectsymoff);
- for(i=0;i<segLC->nsects;i++)
+ IF_DEBUG(linker, debugBelch("ocResolve_MachO: resolving dsymLC\n"));
+ for (i = 0; i < segLC->nsects; i++)
{
if( !strcmp(sections[i].sectname,"__la_symbol_ptr")
|| !strcmp(sections[i].sectname,"__la_sym_ptr2")
if(!resolveImports(oc,image,symLC,§ions[i],indirectSyms,nlist))
return 0;
}
+ else
+ {
+ IF_DEBUG(linker, debugBelch("ocResolve_MachO: unknown section\n"));
+ }
}
}
for(i=0;i<segLC->nsects;i++)
{
- if(!relocateSection(oc,image,symLC,nlist,segLC->nsects,sections,§ions[i]))
+ IF_DEBUG(linker, debugBelch("ocResolve_MachO: relocating section %d\n", i));
+
+ if (!relocateSection(oc,image,symLC,nlist,segLC->nsects,sections,§ions[i]))
return 0;
}