mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-16 14:31:59 +00:00
Implement skeletal support for __.SYMDEF (ranlib) sections in archives.
Correctly parse the Long Filename section of the archive. When reading in archive members, set their ModuleIDs to "ARCHIVENAME(MEMBERNAME)", as is traditional. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10043 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cd4a398c25
commit
2c61d7b240
@ -21,6 +21,7 @@
|
|||||||
#include "Config/sys/stat.h"
|
#include "Config/sys/stat.h"
|
||||||
#include "Config/sys/mman.h"
|
#include "Config/sys/mman.h"
|
||||||
#include "Config/fcntl.h"
|
#include "Config/fcntl.h"
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
@ -39,6 +40,7 @@ namespace {
|
|||||||
UserObject, // A user .o/.bc file
|
UserObject, // A user .o/.bc file
|
||||||
Unknown, // Unknown file, just ignore it
|
Unknown, // Unknown file, just ignore it
|
||||||
SVR4LongFilename, // a "//" section used for long file names
|
SVR4LongFilename, // a "//" section used for long file names
|
||||||
|
ArchiveSymbolTable, // Symbol table produced by ranlib.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +49,8 @@ namespace {
|
|||||||
// purposes.
|
// purposes.
|
||||||
static enum ObjectType getObjectType(ar_hdr *H, unsigned Size) {
|
static enum ObjectType getObjectType(ar_hdr *H, unsigned Size) {
|
||||||
// Check for sections with special names...
|
// Check for sections with special names...
|
||||||
|
if (!memcmp(H->name, "__.SYMDEF ", 16))
|
||||||
|
return ArchiveSymbolTable;
|
||||||
if (!memcmp(H->name, "// ", 16))
|
if (!memcmp(H->name, "// ", 16))
|
||||||
return SVR4LongFilename;
|
return SVR4LongFilename;
|
||||||
|
|
||||||
@ -89,8 +93,13 @@ static bool ParseLongFilenameSection(unsigned char *Buffer, unsigned Size,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ParseSymbolTableSection(unsigned char *Buffer, unsigned Size,
|
||||||
|
std::string *S) {
|
||||||
|
// Currently not supported (succeeds without doing anything)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool ReadArchiveBuffer(const std::string &Filename,
|
static bool ReadArchiveBuffer(const std::string &ArchiveName,
|
||||||
unsigned char *Buffer, unsigned Length,
|
unsigned char *Buffer, unsigned Length,
|
||||||
std::vector<Module*> &Objects,
|
std::vector<Module*> &Objects,
|
||||||
std::string *ErrorStr) {
|
std::string *ErrorStr) {
|
||||||
@ -98,7 +107,7 @@ static bool ReadArchiveBuffer(const std::string &Filename,
|
|||||||
return Error(ErrorStr, "signature incorrect for an archive file!");
|
return Error(ErrorStr, "signature incorrect for an archive file!");
|
||||||
Buffer += 8; Length -= 8; // Skip the magic string.
|
Buffer += 8; Length -= 8; // Skip the magic string.
|
||||||
|
|
||||||
std::vector<std::string> LongFilenames;
|
std::vector<char> LongFilenames;
|
||||||
|
|
||||||
while (Length >= sizeof(ar_hdr)) {
|
while (Length >= sizeof(ar_hdr)) {
|
||||||
ar_hdr *Hdr = (ar_hdr*)Buffer;
|
ar_hdr *Hdr = (ar_hdr*)Buffer;
|
||||||
@ -106,25 +115,41 @@ static bool ReadArchiveBuffer(const std::string &Filename,
|
|||||||
if (Size+sizeof(ar_hdr) > Length)
|
if (Size+sizeof(ar_hdr) > Length)
|
||||||
return Error(ErrorStr, "invalid record length in archive file!");
|
return Error(ErrorStr, "invalid record length in archive file!");
|
||||||
|
|
||||||
|
// Get name of archive member.
|
||||||
|
char *startp = Hdr->name;
|
||||||
|
char *endp = strchr (startp, '/');
|
||||||
|
if (startp == endp && isdigit (Hdr->name[1])) {
|
||||||
|
// Long filenames are abbreviated as "/I", where I is a decimal
|
||||||
|
// index into the LongFilenames vector.
|
||||||
|
unsigned Index = atoi (&Hdr->name[1]);
|
||||||
|
assert (LongFilenames.size () > Index
|
||||||
|
&& "Long filename for archive member not found");
|
||||||
|
startp = &LongFilenames[Index];
|
||||||
|
endp = strchr (startp, '/');
|
||||||
|
}
|
||||||
|
std::string MemberName (startp, endp);
|
||||||
|
std::string FullMemberName = ArchiveName + "(" + MemberName + ")";
|
||||||
|
|
||||||
switch (getObjectType(Hdr, Size)) {
|
switch (getObjectType(Hdr, Size)) {
|
||||||
case SVR4LongFilename:
|
case SVR4LongFilename:
|
||||||
// If this is a long filename section, read all of the file names into the
|
// If this is a long filename section, read all of the file names into the
|
||||||
// LongFilenames vector.
|
// LongFilenames vector.
|
||||||
//
|
LongFilenames.assign (Buffer+sizeof(ar_hdr), Buffer+sizeof(ar_hdr)+Size);
|
||||||
if (ParseLongFilenameSection(Buffer+sizeof(ar_hdr), Size,
|
|
||||||
LongFilenames, ErrorStr))
|
|
||||||
return true;
|
|
||||||
break;
|
break;
|
||||||
case UserObject: {
|
case UserObject: {
|
||||||
Module *M = ParseBytecodeBuffer(Buffer+sizeof(ar_hdr), Size,
|
Module *M = ParseBytecodeBuffer(Buffer+sizeof(ar_hdr), Size,
|
||||||
Filename+":somefile", ErrorStr);
|
FullMemberName, ErrorStr);
|
||||||
if (!M) return true;
|
if (!M) return true;
|
||||||
Objects.push_back(M);
|
Objects.push_back(M);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Unknown:
|
case ArchiveSymbolTable:
|
||||||
std::cerr << "ReadArchiveBuffer: WARNING: Skipping unknown file: ";
|
if (ParseSymbolTableSection(Buffer+sizeof(ar_hdr), Size, ErrorStr))
|
||||||
std::cerr << std::string(Hdr->name, Hdr->name+sizeof(Hdr->name+1)) <<"\n";
|
return true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
std::cerr << "ReadArchiveBuffer: WARNING: Skipping unknown file: "
|
||||||
|
<< FullMemberName << "\n";
|
||||||
break; // Just ignore unknown files.
|
break; // Just ignore unknown files.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "Config/sys/stat.h"
|
#include "Config/sys/stat.h"
|
||||||
#include "Config/sys/mman.h"
|
#include "Config/sys/mman.h"
|
||||||
#include "Config/fcntl.h"
|
#include "Config/fcntl.h"
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
@ -39,6 +40,7 @@ namespace {
|
|||||||
UserObject, // A user .o/.bc file
|
UserObject, // A user .o/.bc file
|
||||||
Unknown, // Unknown file, just ignore it
|
Unknown, // Unknown file, just ignore it
|
||||||
SVR4LongFilename, // a "//" section used for long file names
|
SVR4LongFilename, // a "//" section used for long file names
|
||||||
|
ArchiveSymbolTable, // Symbol table produced by ranlib.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +49,8 @@ namespace {
|
|||||||
// purposes.
|
// purposes.
|
||||||
static enum ObjectType getObjectType(ar_hdr *H, unsigned Size) {
|
static enum ObjectType getObjectType(ar_hdr *H, unsigned Size) {
|
||||||
// Check for sections with special names...
|
// Check for sections with special names...
|
||||||
|
if (!memcmp(H->name, "__.SYMDEF ", 16))
|
||||||
|
return ArchiveSymbolTable;
|
||||||
if (!memcmp(H->name, "// ", 16))
|
if (!memcmp(H->name, "// ", 16))
|
||||||
return SVR4LongFilename;
|
return SVR4LongFilename;
|
||||||
|
|
||||||
@ -89,8 +93,13 @@ static bool ParseLongFilenameSection(unsigned char *Buffer, unsigned Size,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ParseSymbolTableSection(unsigned char *Buffer, unsigned Size,
|
||||||
|
std::string *S) {
|
||||||
|
// Currently not supported (succeeds without doing anything)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool ReadArchiveBuffer(const std::string &Filename,
|
static bool ReadArchiveBuffer(const std::string &ArchiveName,
|
||||||
unsigned char *Buffer, unsigned Length,
|
unsigned char *Buffer, unsigned Length,
|
||||||
std::vector<Module*> &Objects,
|
std::vector<Module*> &Objects,
|
||||||
std::string *ErrorStr) {
|
std::string *ErrorStr) {
|
||||||
@ -98,7 +107,7 @@ static bool ReadArchiveBuffer(const std::string &Filename,
|
|||||||
return Error(ErrorStr, "signature incorrect for an archive file!");
|
return Error(ErrorStr, "signature incorrect for an archive file!");
|
||||||
Buffer += 8; Length -= 8; // Skip the magic string.
|
Buffer += 8; Length -= 8; // Skip the magic string.
|
||||||
|
|
||||||
std::vector<std::string> LongFilenames;
|
std::vector<char> LongFilenames;
|
||||||
|
|
||||||
while (Length >= sizeof(ar_hdr)) {
|
while (Length >= sizeof(ar_hdr)) {
|
||||||
ar_hdr *Hdr = (ar_hdr*)Buffer;
|
ar_hdr *Hdr = (ar_hdr*)Buffer;
|
||||||
@ -106,25 +115,41 @@ static bool ReadArchiveBuffer(const std::string &Filename,
|
|||||||
if (Size+sizeof(ar_hdr) > Length)
|
if (Size+sizeof(ar_hdr) > Length)
|
||||||
return Error(ErrorStr, "invalid record length in archive file!");
|
return Error(ErrorStr, "invalid record length in archive file!");
|
||||||
|
|
||||||
|
// Get name of archive member.
|
||||||
|
char *startp = Hdr->name;
|
||||||
|
char *endp = strchr (startp, '/');
|
||||||
|
if (startp == endp && isdigit (Hdr->name[1])) {
|
||||||
|
// Long filenames are abbreviated as "/I", where I is a decimal
|
||||||
|
// index into the LongFilenames vector.
|
||||||
|
unsigned Index = atoi (&Hdr->name[1]);
|
||||||
|
assert (LongFilenames.size () > Index
|
||||||
|
&& "Long filename for archive member not found");
|
||||||
|
startp = &LongFilenames[Index];
|
||||||
|
endp = strchr (startp, '/');
|
||||||
|
}
|
||||||
|
std::string MemberName (startp, endp);
|
||||||
|
std::string FullMemberName = ArchiveName + "(" + MemberName + ")";
|
||||||
|
|
||||||
switch (getObjectType(Hdr, Size)) {
|
switch (getObjectType(Hdr, Size)) {
|
||||||
case SVR4LongFilename:
|
case SVR4LongFilename:
|
||||||
// If this is a long filename section, read all of the file names into the
|
// If this is a long filename section, read all of the file names into the
|
||||||
// LongFilenames vector.
|
// LongFilenames vector.
|
||||||
//
|
LongFilenames.assign (Buffer+sizeof(ar_hdr), Buffer+sizeof(ar_hdr)+Size);
|
||||||
if (ParseLongFilenameSection(Buffer+sizeof(ar_hdr), Size,
|
|
||||||
LongFilenames, ErrorStr))
|
|
||||||
return true;
|
|
||||||
break;
|
break;
|
||||||
case UserObject: {
|
case UserObject: {
|
||||||
Module *M = ParseBytecodeBuffer(Buffer+sizeof(ar_hdr), Size,
|
Module *M = ParseBytecodeBuffer(Buffer+sizeof(ar_hdr), Size,
|
||||||
Filename+":somefile", ErrorStr);
|
FullMemberName, ErrorStr);
|
||||||
if (!M) return true;
|
if (!M) return true;
|
||||||
Objects.push_back(M);
|
Objects.push_back(M);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Unknown:
|
case ArchiveSymbolTable:
|
||||||
std::cerr << "ReadArchiveBuffer: WARNING: Skipping unknown file: ";
|
if (ParseSymbolTableSection(Buffer+sizeof(ar_hdr), Size, ErrorStr))
|
||||||
std::cerr << std::string(Hdr->name, Hdr->name+sizeof(Hdr->name+1)) <<"\n";
|
return true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
std::cerr << "ReadArchiveBuffer: WARNING: Skipping unknown file: "
|
||||||
|
<< FullMemberName << "\n";
|
||||||
break; // Just ignore unknown files.
|
break; // Just ignore unknown files.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "Config/sys/stat.h"
|
#include "Config/sys/stat.h"
|
||||||
#include "Config/sys/mman.h"
|
#include "Config/sys/mman.h"
|
||||||
#include "Config/fcntl.h"
|
#include "Config/fcntl.h"
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
@ -39,6 +40,7 @@ namespace {
|
|||||||
UserObject, // A user .o/.bc file
|
UserObject, // A user .o/.bc file
|
||||||
Unknown, // Unknown file, just ignore it
|
Unknown, // Unknown file, just ignore it
|
||||||
SVR4LongFilename, // a "//" section used for long file names
|
SVR4LongFilename, // a "//" section used for long file names
|
||||||
|
ArchiveSymbolTable, // Symbol table produced by ranlib.
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +49,8 @@ namespace {
|
|||||||
// purposes.
|
// purposes.
|
||||||
static enum ObjectType getObjectType(ar_hdr *H, unsigned Size) {
|
static enum ObjectType getObjectType(ar_hdr *H, unsigned Size) {
|
||||||
// Check for sections with special names...
|
// Check for sections with special names...
|
||||||
|
if (!memcmp(H->name, "__.SYMDEF ", 16))
|
||||||
|
return ArchiveSymbolTable;
|
||||||
if (!memcmp(H->name, "// ", 16))
|
if (!memcmp(H->name, "// ", 16))
|
||||||
return SVR4LongFilename;
|
return SVR4LongFilename;
|
||||||
|
|
||||||
@ -89,8 +93,13 @@ static bool ParseLongFilenameSection(unsigned char *Buffer, unsigned Size,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ParseSymbolTableSection(unsigned char *Buffer, unsigned Size,
|
||||||
|
std::string *S) {
|
||||||
|
// Currently not supported (succeeds without doing anything)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static bool ReadArchiveBuffer(const std::string &Filename,
|
static bool ReadArchiveBuffer(const std::string &ArchiveName,
|
||||||
unsigned char *Buffer, unsigned Length,
|
unsigned char *Buffer, unsigned Length,
|
||||||
std::vector<Module*> &Objects,
|
std::vector<Module*> &Objects,
|
||||||
std::string *ErrorStr) {
|
std::string *ErrorStr) {
|
||||||
@ -98,7 +107,7 @@ static bool ReadArchiveBuffer(const std::string &Filename,
|
|||||||
return Error(ErrorStr, "signature incorrect for an archive file!");
|
return Error(ErrorStr, "signature incorrect for an archive file!");
|
||||||
Buffer += 8; Length -= 8; // Skip the magic string.
|
Buffer += 8; Length -= 8; // Skip the magic string.
|
||||||
|
|
||||||
std::vector<std::string> LongFilenames;
|
std::vector<char> LongFilenames;
|
||||||
|
|
||||||
while (Length >= sizeof(ar_hdr)) {
|
while (Length >= sizeof(ar_hdr)) {
|
||||||
ar_hdr *Hdr = (ar_hdr*)Buffer;
|
ar_hdr *Hdr = (ar_hdr*)Buffer;
|
||||||
@ -106,25 +115,41 @@ static bool ReadArchiveBuffer(const std::string &Filename,
|
|||||||
if (Size+sizeof(ar_hdr) > Length)
|
if (Size+sizeof(ar_hdr) > Length)
|
||||||
return Error(ErrorStr, "invalid record length in archive file!");
|
return Error(ErrorStr, "invalid record length in archive file!");
|
||||||
|
|
||||||
|
// Get name of archive member.
|
||||||
|
char *startp = Hdr->name;
|
||||||
|
char *endp = strchr (startp, '/');
|
||||||
|
if (startp == endp && isdigit (Hdr->name[1])) {
|
||||||
|
// Long filenames are abbreviated as "/I", where I is a decimal
|
||||||
|
// index into the LongFilenames vector.
|
||||||
|
unsigned Index = atoi (&Hdr->name[1]);
|
||||||
|
assert (LongFilenames.size () > Index
|
||||||
|
&& "Long filename for archive member not found");
|
||||||
|
startp = &LongFilenames[Index];
|
||||||
|
endp = strchr (startp, '/');
|
||||||
|
}
|
||||||
|
std::string MemberName (startp, endp);
|
||||||
|
std::string FullMemberName = ArchiveName + "(" + MemberName + ")";
|
||||||
|
|
||||||
switch (getObjectType(Hdr, Size)) {
|
switch (getObjectType(Hdr, Size)) {
|
||||||
case SVR4LongFilename:
|
case SVR4LongFilename:
|
||||||
// If this is a long filename section, read all of the file names into the
|
// If this is a long filename section, read all of the file names into the
|
||||||
// LongFilenames vector.
|
// LongFilenames vector.
|
||||||
//
|
LongFilenames.assign (Buffer+sizeof(ar_hdr), Buffer+sizeof(ar_hdr)+Size);
|
||||||
if (ParseLongFilenameSection(Buffer+sizeof(ar_hdr), Size,
|
|
||||||
LongFilenames, ErrorStr))
|
|
||||||
return true;
|
|
||||||
break;
|
break;
|
||||||
case UserObject: {
|
case UserObject: {
|
||||||
Module *M = ParseBytecodeBuffer(Buffer+sizeof(ar_hdr), Size,
|
Module *M = ParseBytecodeBuffer(Buffer+sizeof(ar_hdr), Size,
|
||||||
Filename+":somefile", ErrorStr);
|
FullMemberName, ErrorStr);
|
||||||
if (!M) return true;
|
if (!M) return true;
|
||||||
Objects.push_back(M);
|
Objects.push_back(M);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Unknown:
|
case ArchiveSymbolTable:
|
||||||
std::cerr << "ReadArchiveBuffer: WARNING: Skipping unknown file: ";
|
if (ParseSymbolTableSection(Buffer+sizeof(ar_hdr), Size, ErrorStr))
|
||||||
std::cerr << std::string(Hdr->name, Hdr->name+sizeof(Hdr->name+1)) <<"\n";
|
return true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
std::cerr << "ReadArchiveBuffer: WARNING: Skipping unknown file: "
|
||||||
|
<< FullMemberName << "\n";
|
||||||
break; // Just ignore unknown files.
|
break; // Just ignore unknown files.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user