/* -----------------------------------------------------------------------------
- * $Id: Linker.c,v 1.63 2001/09/04 16:33:04 sewardj Exp $
+ * $Id: Linker.c,v 1.67 2001/09/12 14:53:39 sewardj Exp $
*
* (c) The GHC Team, 2000, 2001
*
Sym(StgReturn) \
Sym(init_stack) \
SymX(cmp_thread) \
- Sym(__init_PrelGHC) \
+ Sym(__stginit_PrelGHC) \
SymX(freeHaskellFunctionPtr) \
SymX(OnExitHook) \
SymX(ErrorHdrHook) \
}
k = 0;
- oc->n_sections = ehdr->e_shnum;
- oc->sections = stgMallocBytes( oc->n_sections * sizeof(Section),
- "ocGetNames_ELF(oc->sections)" );
-
- for (i = 0; i < oc->n_sections; i++) {
+ for (i = 0; i < ehdr->e_shnum; i++) {
/* make a section entry for relevant sections */
SectionKind kind = SECTIONKIND_OTHER;
it, and set its .sh_offset field such that
ehdrC + .sh_offset == addr_of_zeroed_space. */
char* zspace = stgCallocBytes(1, shdr[i].sh_size,
- "ocGetNames_ELF(anonymous bss)");
+ "ocGetNames_ELF(BSS)");
shdr[i].sh_offset = ((char*)zspace) - ((char*)ehdrC);
- /* We don't prod BSS sections, hence the following isn't
- necessary:
- addProddableBlock(oc, zspace, shdr[i].sh_size);
- */
- /*
+ /*
fprintf(stderr, "BSS section at 0x%x, size %d\n",
zspace, shdr[i].sh_size);
- */
+ */
}
/* fill in the section info */
- oc->sections[i].start = ehdrC + shdr[i].sh_offset;
- oc->sections[i].end = ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1;
- oc->sections[i].kind = kind;
+ addSection(oc, kind, ehdrC + shdr[i].sh_offset,
+ ehdrC + shdr[i].sh_offset + shdr[i].sh_size - 1);
if (kind != SECTIONKIND_OTHER && shdr[i].sh_size > 0)
addProddableBlock(oc, ehdrC + shdr[i].sh_offset, shdr[i].sh_size);
"ocGetNames_ELF(oc->symbols)");
for (j = 0; j < nent; j++) {
+
+ char isLocal = FALSE; /* avoids uninit-var warning */
+ char* ad = NULL;
+ char* nm = strtab + stab[j].st_name;
+ int secno = stab[j].st_shndx;
+
+ /* Figure out if we want to add it; if so, set ad to its
+ address. Otherwise leave ad == NULL. */
+
+ if (secno == SHN_COMMON) {
+ isLocal = FALSE;
+ ad = stgCallocBytes(1, stab[j].st_size, "ocGetNames_ELF(COMMON)");
+ /*
+ fprintf(stderr, "COMMON symbol, size %d name %s\n",
+ stab[j].st_size, nm);
+ */
+ /* Pointless to do addProddableBlock() for this area,
+ since the linker should never poke around in it. */
+ }
+ else
if ( ( ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL
|| ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL
)
ELF32_ST_TYPE(stab[j].st_info)==STT_NOTYPE
)
) {
- char* nm;
- char* ad;
- int secno = stab[j].st_shndx;
/* Section 0 is the undefined section, hence > and not >=. */
ASSERT(secno > 0 && secno < ehdr->e_shnum);
- nm = strtab + stab[j].st_name;
- /*
+ /*
if (shdr[secno].sh_type == SHT_NOBITS) {
- fprintf(stderr, "bss symbol, size %d off %d name %s\n",
- stab[j].st_size, stab[j].st_value, nm);
+ fprintf(stderr, " BSS symbol, size %d off %d name %s\n",
+ stab[j].st_size, stab[j].st_value, nm);
}
*/
ad = ehdrC + shdr[ secno ].sh_offset + stab[j].st_value;
- ASSERT(nm != NULL);
- ASSERT(ad != NULL);
- oc->symbols[j] = nm;
if (ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL) {
IF_DEBUG(linker,belch( "addOTabName(LOCL): %10p %s %s",
ad, oc->fileName, nm ));
- insertStrHashTable(oc->lochash, nm, ad);
+ isLocal = TRUE;
} else {
IF_DEBUG(linker,belch( "addOTabName(GLOB): %10p %s %s",
ad, oc->fileName, nm ));
- insertStrHashTable(symhash, nm, ad);
+ isLocal = FALSE;
}
}
- else {
+
+ /* And the decision is ... */
+
+ if (ad != NULL) {
+ ASSERT(nm != NULL);
+ oc->symbols[j] = nm;
+ /* Acquire! */
+ if (isLocal) {
+ insertStrHashTable(oc->lochash, nm, ad);
+ } else {
+ insertStrHashTable(symhash, nm, ad);
+ }
+ } else {
+ /* Skip. */
IF_DEBUG(linker,belch( "skipping `%s'",
strtab + stab[j].st_name ));
/*
*/
oc->symbols[j] = NULL;
}
+
}
}
Elf32_Addr offset = rtab[j].r_offset;
Elf32_Word info = rtab[j].r_info;
Elf32_Sword addend = rtab[j].r_addend;
-
Elf32_Addr P = ((Elf32_Addr)targ) + offset;
Elf32_Addr A = addend;
Elf32_Addr S;
}
IF_DEBUG(linker,fprintf ( stderr, "Reloc: P = %p S = %p A = %p\n",
(void*)P, (void*)S, (void*)A ));
- checkProddableBlock ( oc, P );
+ checkProddableBlock ( oc, (void*)P );
switch (ELF32_R_TYPE(info)) {
# if defined(sparc_TARGET_ARCH)
case R_SPARC_WDISP30: