Commit 57fcae70 authored by pho@cielonegro.org's avatar pho@cielonegro.org
Browse files

New member "archiveMemberName" for struct _ObjectCode

struct _ObjectCode should be able to retain the name of archive members.
Though currently the only use of those names are for debugging outputs.
parent bf60bbfb
...@@ -119,7 +119,8 @@ static /*Str*/HashTable *stablehash; ...@@ -119,7 +119,8 @@ static /*Str*/HashTable *stablehash;
ObjectCode *objects = NULL; /* initially empty */ ObjectCode *objects = NULL; /* initially empty */
static HsInt loadOc( ObjectCode* oc ); static HsInt loadOc( ObjectCode* oc );
static ObjectCode* mkOc( char *path, char *image, int imageSize static ObjectCode* mkOc( char *path, char *image, int imageSize,
char *archiveMemberName
#ifndef USE_MMAP #ifndef USE_MMAP
#ifdef darwin_HOST_OS #ifdef darwin_HOST_OS
, int misalignment , int misalignment
...@@ -1602,7 +1603,8 @@ mmap_again: ...@@ -1602,7 +1603,8 @@ mmap_again:
#endif // USE_MMAP #endif // USE_MMAP
static ObjectCode* static ObjectCode*
mkOc( char *path, char *image, int imageSize mkOc( char *path, char *image, int imageSize,
char *archiveMemberName
#ifndef USE_MMAP #ifndef USE_MMAP
#ifdef darwin_HOST_OS #ifdef darwin_HOST_OS
, int misalignment , int misalignment
...@@ -1626,10 +1628,17 @@ mkOc( char *path, char *image, int imageSize ...@@ -1626,10 +1628,17 @@ mkOc( char *path, char *image, int imageSize
oc->image = image; oc->image = image;
/* sigh, strdup() isn't a POSIX function, so do it the long way */ /* sigh, strdup() isn't a POSIX function, so do it the long way */
/* XXX What should this be for an archive? */
oc->fileName = stgMallocBytes( strlen(path)+1, "loadObj" ); oc->fileName = stgMallocBytes( strlen(path)+1, "loadObj" );
strcpy(oc->fileName, path); strcpy(oc->fileName, path);
if (archiveMemberName) {
oc->archiveMemberName = stgMallocBytes( strlen(archiveMemberName)+1, "loadObj" );
strcpy(oc->archiveMemberName, archiveMemberName);
}
else {
oc->archiveMemberName = NULL;
}
oc->fileSize = imageSize; oc->fileSize = imageSize;
oc->symbols = NULL; oc->symbols = NULL;
oc->sections = NULL; oc->sections = NULL;
...@@ -1739,6 +1748,8 @@ loadArchive( char *path ) ...@@ -1739,6 +1748,8 @@ loadArchive( char *path )
} }
if (isObject) { if (isObject) {
char *archiveMemberName;
/* We can't mmap from the archive directly, as object /* We can't mmap from the archive directly, as object
files need to be 8-byte aligned but files in .ar files need to be 8-byte aligned but files in .ar
archives are 2-byte aligned, and if we malloc the archives are 2-byte aligned, and if we malloc the
...@@ -1749,13 +1760,20 @@ loadArchive( char *path ) ...@@ -1749,13 +1760,20 @@ loadArchive( char *path )
n = fread ( image, 1, imageSize, f ); n = fread ( image, 1, imageSize, f );
if (n != imageSize) if (n != imageSize)
barf("loadObj: error whilst reading `%s'", path); barf("loadObj: error whilst reading `%s'", path);
oc = mkOc(path, image, imageSize
archiveMemberName = stgMallocBytes(strlen(path) + fileNameSize + 3, "loadArchive(file)");
sprintf(archiveMemberName, "%s(%.*s)", path, (int)fileNameSize, file);
oc = mkOc(path, image, imageSize, archiveMemberName
#ifndef USE_MMAP #ifndef USE_MMAP
#ifdef darwin_HOST_OS #ifdef darwin_HOST_OS
, 0 , 0
#endif #endif
#endif #endif
); );
stgFree(archiveMemberName);
if (0 == loadOc(oc)) { if (0 == loadOc(oc)) {
stgFree(file); stgFree(file);
return 0; return 0;
...@@ -1899,7 +1917,7 @@ loadObj( char *path ) ...@@ -1899,7 +1917,7 @@ loadObj( char *path )
fclose(f); fclose(f);
#endif /* USE_MMAP */ #endif /* USE_MMAP */
oc = mkOc(path, image, fileSize oc = mkOc(path, image, fileSize, NULL
#ifndef USE_MMAP #ifndef USE_MMAP
#ifdef darwin_HOST_OS #ifdef darwin_HOST_OS
, misalignment , misalignment
...@@ -2004,6 +2022,7 @@ HsInt ...@@ -2004,6 +2022,7 @@ HsInt
unloadObj( char *path ) unloadObj( char *path )
{ {
ObjectCode *oc, *prev; ObjectCode *oc, *prev;
HsBool unloadedAnyObj = HS_BOOL_FALSE;
ASSERT(symhash != NULL); ASSERT(symhash != NULL);
ASSERT(objects != NULL); ASSERT(objects != NULL);
...@@ -2043,12 +2062,20 @@ unloadObj( char *path ) ...@@ -2043,12 +2062,20 @@ unloadObj( char *path )
stgFree(oc->symbols); stgFree(oc->symbols);
stgFree(oc->sections); stgFree(oc->sections);
stgFree(oc); stgFree(oc);
return 1;
/* This could be a member of an archive so continue
* unloading other members. */
unloadedAnyObj = HS_BOOL_TRUE;
} }
} }
if (unloadedAnyObj) {
return 1;
}
else {
errorBelch("unloadObj: can't find `%s' to unload", path); errorBelch("unloadObj: can't find `%s' to unload", path);
return 0; return 0;
}
} }
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
...@@ -4631,7 +4658,9 @@ static int relocateSection( ...@@ -4631,7 +4658,9 @@ static int relocateSection(
"scattered relocation entry: " "scattered relocation entry: "
"object file %s; entry type %ld; " "object file %s; entry type %ld; "
"address %#lx\n", "address %#lx\n",
oc->fileName, scat->r_type, scat->r_address); OC_INFORMATIVE_FILENAME(oc),
scat->r_type,
scat->r_address);
return 0; return 0;
} }
...@@ -4668,7 +4697,9 @@ static int relocateSection( ...@@ -4668,7 +4697,9 @@ static int relocateSection(
"with this r_length tag: " "with this r_length tag: "
"object file %s; entry type %ld; " "object file %s; entry type %ld; "
"r_length tag %ld; address %#lx\n", "r_length tag %ld; address %#lx\n",
oc->fileName, scat->r_type, scat->r_length, OC_INFORMATIVE_FILENAME(oc),
scat->r_type,
scat->r_length,
scat->r_address); scat->r_address);
return 0; return 0;
} }
...@@ -4678,7 +4709,9 @@ static int relocateSection( ...@@ -4678,7 +4709,9 @@ static int relocateSection(
barf("Don't know how to handle *PC-relative* Mach-O " barf("Don't know how to handle *PC-relative* Mach-O "
"scattered relocation entry: " "scattered relocation entry: "
"object file %s; entry type %ld; address %#lx\n", "object file %s; entry type %ld; address %#lx\n",
oc->fileName, scat->r_type, scat->r_address); OC_INFORMATIVE_FILENAME(oc),
scat->r_type,
scat->r_address);
return 0; return 0;
} }
...@@ -4733,7 +4766,9 @@ static int relocateSection( ...@@ -4733,7 +4766,9 @@ static int relocateSection(
barf("Can't handle this Mach-O relocation entry " barf("Can't handle this Mach-O relocation entry "
"(not scattered): " "(not scattered): "
"object file %s; entry type %ld; address %#lx\n", "object file %s; entry type %ld; address %#lx\n",
oc->fileName, reloc->r_type, reloc->r_address); OC_INFORMATIVE_FILENAME(oc),
reloc->r_type,
reloc->r_address);
return 0; return 0;
} }
...@@ -4807,20 +4842,32 @@ static int relocateSection( ...@@ -4807,20 +4842,32 @@ static int relocateSection(
} }
else if(reloc->r_type == PPC_RELOC_BR24) else if(reloc->r_type == PPC_RELOC_BR24)
{ {
if((long)word > (long)0x01FFFFFF || (long)word < (long)0xFFE00000) if((word & 0x03) != 0)
barf("%s: unconditional relative branch with a displacement "
"which isn't a multiple of 4 bytes: %#lx",
OC_INFORMATIVE_FILENAME(oc),
word);
if((word & 0xFE000000) != 0xFE000000 &&
(word & 0xFE000000) != 0x00000000)
{ {
// The branch offset is too large. // The branch offset is too large.
// Therefore, we try to use a jump island. // Therefore, we try to use a jump island.
if(jumpIsland == 0) if(jumpIsland == 0)
{ {
barf("unconditional relative branch out of range: " barf("%s: unconditional relative branch out of range: "
"no jump island available"); "no jump island available: %#lx",
OC_INFORMATIVE_FILENAME(oc),
word);
} }
word = offsetToJumpIsland; word = offsetToJumpIsland;
if((long)word > (long)0x01FFFFFF || (long)word < (long)0xFFE00000) if((word & 0xFE000000) != 0xFE000000 &&
barf("unconditional relative branch out of range: " (word & 0xFE000000) != 0x00000000)
"jump island out of range"); barf("%s: unconditional relative branch out of range: "
"jump island out of range: %#lx",
OC_INFORMATIVE_FILENAME(oc),
word);
} }
*wordPtr = (*wordPtr & 0xFC000003) | (word & 0x03FFFFFC); *wordPtr = (*wordPtr & 0xFC000003) | (word & 0x03FFFFFC);
continue; continue;
...@@ -4833,7 +4880,9 @@ static int relocateSection( ...@@ -4833,7 +4880,9 @@ static int relocateSection(
"with this r_length tag: " "with this r_length tag: "
"object file %s; entry type %ld; " "object file %s; entry type %ld; "
"r_length tag %ld; address %#lx\n", "r_length tag %ld; address %#lx\n",
oc->fileName, reloc->r_type, reloc->r_length, OC_INFORMATIVE_FILENAME(oc),
reloc->r_type,
reloc->r_length,
reloc->r_address); reloc->r_address);
return 0; return 0;
} }
......
...@@ -65,6 +65,11 @@ typedef struct _ObjectCode { ...@@ -65,6 +65,11 @@ typedef struct _ObjectCode {
int fileSize; int fileSize;
char* formatName; /* eg "ELF32", "DLL", "COFF", etc. */ char* formatName; /* eg "ELF32", "DLL", "COFF", etc. */
/* If this object is a member of an archive, archiveMemberName is
* like "libarchive.a(object.o)". Otherwise it's NULL.
*/
char* archiveMemberName;
/* An array containing ptrs to all the symbol names copied from /* An array containing ptrs to all the symbol names copied from
this object into the global symbol hash table. This is so that this object into the global symbol hash table. This is so that
we know which parts of the latter mapping to nuke when this we know which parts of the latter mapping to nuke when this
...@@ -107,6 +112,12 @@ typedef struct _ObjectCode { ...@@ -107,6 +112,12 @@ typedef struct _ObjectCode {
} ObjectCode; } ObjectCode;
#define OC_INFORMATIVE_FILENAME(OC) \
( (OC)->archiveMemberName ? \
(OC)->archiveMemberName : \
(OC)->fileName \
)
extern ObjectCode *objects; extern ObjectCode *objects;
void exitLinker( void ); void exitLinker( void );
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment