projects
/
ghc-hetmet.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
01073a9
)
[project @ 2001-02-12 12:46:23 by sewardj]
author
sewardj
<unknown>
Mon, 12 Feb 2001 12:46:23 +0000
(12:46 +0000)
committer
sewardj
<unknown>
Mon, 12 Feb 2001 12:46:23 +0000
(12:46 +0000)
Teach the runtime linker about local symbols, so that we don't have to
rely on batch linkers to resolve local symbols in libraries at
library-build-time.
ghc/rts/Linker.c
patch
|
blob
|
history
ghc/rts/LinkerInternals.h
patch
|
blob
|
history
diff --git
a/ghc/rts/Linker.c
b/ghc/rts/Linker.c
index
4f2a456
..
b4d682e
100644
(file)
--- a/
ghc/rts/Linker.c
+++ b/
ghc/rts/Linker.c
@@
-1,5
+1,5
@@
/* -----------------------------------------------------------------------------
/* -----------------------------------------------------------------------------
- * $Id: Linker.c,v 1.23 2001/02/12 12:22:01 simonmar Exp $
+ * $Id: Linker.c,v 1.24 2001/02/12 12:46:23 sewardj Exp $
*
* (c) The GHC Team, 2000
*
*
* (c) The GHC Team, 2000
*
@@
-295,6
+295,21
@@
lookupSymbol( char *lbl )
}
}
}
}
+static
+void *
+lookupLocalSymbol( ObjectCode* oc, char *lbl )
+{
+ SymbolVal *val;
+ val = lookupStrHashTable(oc->lochash, lbl);
+
+ if (val == NULL) {
+ return NULL;
+ } else {
+ return val->addr;
+ }
+}
+
+
/* -----------------------------------------------------------------------------
* Load an obj (populate the global symbol table, but don't resolve yet)
*
/* -----------------------------------------------------------------------------
* Load an obj (populate the global symbol table, but don't resolve yet)
*
@@
-308,14
+323,14
@@
loadObj( char *path )
int r, n;
FILE *f;
int r, n;
FILE *f;
-#ifdef DEBUG
+# ifdef DEBUG
/* assert that we haven't already loaded this object */
{
ObjectCode *o;
for (o = objects; o; o = o->next)
ASSERT(strcmp(o->fileName, path));
}
/* assert that we haven't already loaded this object */
{
ObjectCode *o;
for (o = objects; o; o = o->next)
ASSERT(strcmp(o->fileName, path));
}
-#endif /* DEBUG */
+# endif /* DEBUG */
oc = stgMallocBytes(sizeof(ObjectCode), "loadObj(oc)");
oc = stgMallocBytes(sizeof(ObjectCode), "loadObj(oc)");
@@
-331,7
+346,7
@@
loadObj( char *path )
r = stat(path, &st);
if (r == -1) { return 0; }
r = stat(path, &st);
if (r == -1) { return 0; }
- /* sigh, stdup() isn't a POSIX function, so do it the long way */
+ /* sigh, strdup() isn't a POSIX function, so do it the long way */
oc->fileName = stgMallocBytes( strlen(path)+1, "loadObj" );
strcpy(oc->fileName, path);
oc->fileName = stgMallocBytes( strlen(path)+1, "loadObj" );
strcpy(oc->fileName, path);
@@
-339,6
+354,7
@@
loadObj( char *path )
oc->image = stgMallocBytes( st.st_size, "loadObj(image)" );
oc->symbols = NULL;
oc->sections = NULL;
oc->image = stgMallocBytes( st.st_size, "loadObj(image)" );
oc->symbols = NULL;
oc->sections = NULL;
+ oc->lochash = allocStrHashTable();
/* chain it onto the list of objects */
oc->next = objects;
/* chain it onto the list of objects */
oc->next = objects;
@@
-394,13
+410,13
@@
resolveObjs( void )
for (oc = objects; oc; oc = oc->next) {
if (oc->status != OBJECT_RESOLVED) {
for (oc = objects; oc; oc = oc->next) {
if (oc->status != OBJECT_RESOLVED) {
-# if defined(OBJFORMAT_ELF)
+# if defined(OBJFORMAT_ELF)
r = ocResolve_ELF ( oc );
r = ocResolve_ELF ( oc );
-# elif defined(OBJFORMAT_PEi386)
+# elif defined(OBJFORMAT_PEi386)
r = ocResolve_PEi386 ( oc );
r = ocResolve_PEi386 ( oc );
-# else
+# else
barf("link: not implemented on this platform");
barf("link: not implemented on this platform");
-# endif
+# endif
if (!r) { return r; }
oc->status = OBJECT_RESOLVED;
}
if (!r) { return r; }
oc->status = OBJECT_RESOLVED;
}
@@
-447,6
+463,7
@@
unloadObj( char *path )
free(oc->fileName);
free(oc->symbols);
free(oc->sections);
free(oc->fileName);
free(oc->symbols);
free(oc->sections);
+ freeHashTable(oc->lochash, NULL);
free(oc);
return 1;
}
free(oc);
return 1;
}
@@
-1332,27
+1349,34
@@
ocGetNames_ELF ( ObjectCode* oc )
oc->n_symbols = nent;
for (j = 0; j < nent; j++) {
if ( ( ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL
oc->n_symbols = nent;
for (j = 0; j < nent; j++) {
if ( ( ELF32_ST_BIND(stab[j].st_info)==STB_GLOBAL
- /* || ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL */
+ || ELF32_ST_BIND(stab[j].st_info)==STB_LOCAL
)
)
- /* and not an undefined symbol */
- && stab[j].st_shndx != SHN_UNDEF
- &&
+ /* and not an undefined symbol */
+ && stab[j].st_shndx != SHN_UNDEF
+ &&
/* and it's a not a section or string table or anything silly */
( ELF32_ST_TYPE(stab[j].st_info)==STT_FUNC ||
ELF32_ST_TYPE(stab[j].st_info)==STT_OBJECT ||
/* and it's a not a section or string table or anything silly */
( ELF32_ST_TYPE(stab[j].st_info)==STT_FUNC ||
ELF32_ST_TYPE(stab[j].st_info)==STT_OBJECT ||
- ELF32_ST_TYPE(stab[j].st_info)==STT_NOTYPE )
- ) {
+ ELF32_ST_TYPE(stab[j].st_info)==STT_NOTYPE
+ )
+ ) {
char* nm = strtab + stab[j].st_name;
char* ad = ehdrC
+ shdr[ stab[j].st_shndx ].sh_offset
+ stab[j].st_value;
ASSERT(nm != NULL);
ASSERT(ad != NULL);
char* nm = strtab + stab[j].st_name;
char* ad = ehdrC
+ shdr[ stab[j].st_shndx ].sh_offset
+ stab[j].st_value;
ASSERT(nm != NULL);
ASSERT(ad != NULL);
- IF_DEBUG(linker,belch( "addOTabName: %10p %s %s",
- ad, oc->fileName, nm ));
oc->symbols[j].lbl = nm;
oc->symbols[j].addr = ad;
oc->symbols[j].lbl = nm;
oc->symbols[j].addr = ad;
- insertStrHashTable(symhash, nm, &(oc->symbols[j]));
+ 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, &(oc->symbols[j]));
+ } else {
+ IF_DEBUG(linker,belch( "addOTabName(GLOB): %10p %s %s",
+ ad, oc->fileName, nm ));
+ insertStrHashTable(symhash, nm, &(oc->symbols[j]));
+ }
}
else {
IF_DEBUG(linker,belch( "skipping `%s'",
}
else {
IF_DEBUG(linker,belch( "skipping `%s'",
@@
-1415,9
+1439,12
@@
static int do_Elf32_Rel_relocations ( ObjectCode* oc, char* ehdrC,
(ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
+ stab[ELF32_R_SYM(info)].st_value);
} else {
(ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
+ stab[ELF32_R_SYM(info)].st_value);
} else {
- /* No? Should be in the symbol table then. */
+ /* No? Should be in a symbol table then; first try the
+ local one. */
symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
- (void *)S = lookupSymbol( symbol );
+ (void*)S = lookupLocalSymbol( oc, symbol );
+ if ((void*)S == NULL)
+ (void*)S = lookupSymbol( symbol );
}
if (!S) {
barf("do_Elf32_Rel_relocations: %s: unknown symbol `%s'",
}
if (!S) {
barf("do_Elf32_Rel_relocations: %s: unknown symbol `%s'",
@@
-1487,9
+1514,12
@@
static int do_Elf32_Rela_relocations ( ObjectCode* oc, char* ehdrC,
(ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
+ stab[ELF32_R_SYM(info)].st_value);
} else {
(ehdrC + shdr[stab[ELF32_R_SYM(info)].st_shndx ].sh_offset
+ stab[ELF32_R_SYM(info)].st_value);
} else {
- /* No? Should be in the symbol table then. */
+ /* No? Should be in a symbol table then; first try the
+ local one. */
symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
symbol = strtab+stab[ ELF32_R_SYM(info)].st_name;
- (void *)S = lookupSymbol( symbol );
+ (void*)S = lookupLocalSymbol( oc, symbol );
+ if ((void*)S == NULL)
+ (void*)S = lookupSymbol( symbol );
}
if (!S) {
barf("ocResolve_ELF: %s: unknown symbol `%s'",
}
if (!S) {
barf("ocResolve_ELF: %s: unknown symbol `%s'",
@@
-1530,9
+1560,6
@@
static int do_Elf32_Rela_relocations ( ObjectCode* oc, char* ehdrC,
w2 = (Elf32_Word)(S + A);
*pP = w2;
break;
w2 = (Elf32_Word)(S + A);
*pP = w2;
break;
- case R_SPARC_NONE: belch("R_SPARC_NONE");
- break;
-
# endif
default:
fprintf(stderr, "unhandled ELF relocation(RelA) type %d\n",
# endif
default:
fprintf(stderr, "unhandled ELF relocation(RelA) type %d\n",
diff --git
a/ghc/rts/LinkerInternals.h
b/ghc/rts/LinkerInternals.h
index
d124979
..
9cf3317
100644
(file)
--- a/
ghc/rts/LinkerInternals.h
+++ b/
ghc/rts/LinkerInternals.h
@@
-1,5
+1,5
@@
/* -----------------------------------------------------------------------------
/* -----------------------------------------------------------------------------
- * $Id: LinkerInternals.h,v 1.1 2001/02/11 17:51:07 simonmar Exp $
+ * $Id: LinkerInternals.h,v 1.2 2001/02/12 12:46:23 sewardj Exp $
*
* (c) The GHC Team, 2000
*
*
* (c) The GHC Team, 2000
*
@@
-36,20
+36,23
@@
typedef struct { void* start; void* end; SectionKind kind; }
* for each object file in use.
*/
typedef struct _ObjectCode {
* for each object file in use.
*/
typedef struct _ObjectCode {
- OStatus status;
- char* fileName;
- int fileSize;
- char* formatName; /* eg "ELF32", "DLL", "COFF", etc. */
+ OStatus status;
+ char* fileName;
+ int fileSize;
+ char* formatName; /* eg "ELF32", "DLL", "COFF", etc. */
- SymbolVal *symbols;
- int n_symbols;
+ SymbolVal *symbols;
+ int n_symbols;
/* ptr to malloc'd lump of memory holding the obj file */
/* ptr to malloc'd lump of memory holding the obj file */
- void* image;
+ void* image;
/* The section-kind entries for this object module. Dynamically expands. */
/* The section-kind entries for this object module. Dynamically expands. */
- Section* sections;
- int n_sections;
+ Section* sections;
+ int n_sections;
+
+ /* A private hash table for local symbols. */
+ HashTable* lochash;
/* Allow a chain of these things */
struct _ObjectCode * next;
/* Allow a chain of these things */
struct _ObjectCode * next;