mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 17:32:19 +00:00
Changes necessary to enable linking of archives without LLVM symbol tables.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17811 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6238a85e4f
commit
766b793143
@ -77,11 +77,14 @@ bool GetBytecodeSymbols(const sys::Path& fileName,
|
|||||||
/// bytecode module defines. This is used for archiving and linking when only
|
/// bytecode module defines. This is used for archiving and linking when only
|
||||||
/// the list of symbols the module defines is needed and the bytecode is
|
/// the list of symbols the module defines is needed and the bytecode is
|
||||||
/// already in memory.
|
/// already in memory.
|
||||||
/// @returns true on success, false if the bytecode can't be parsed
|
/// @returns the ModuleProvider on success, 0 if the bytecode can't be parsed
|
||||||
/// @brief Get a bytecode file's externally visibile defined global symbols.
|
/// @brief Get a bytecode file's externally visibile defined global symbols.
|
||||||
bool llvm::GetBytecodeSymbols(const unsigned char*Buffer, unsigned Length,
|
ModuleProvider* llvm::GetBytecodeSymbols(
|
||||||
const std::string& ModuleID,
|
const unsigned char*Buffer, ///< The buffer to be parsed
|
||||||
std::vector<std::string>& symbols);
|
unsigned Length, ///< The length of \p Buffer
|
||||||
|
const std::string& ModuleID, ///< An identifier for the module
|
||||||
|
std::vector<std::string>& symbols ///< The symbols defined in the module
|
||||||
|
);
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
|
@ -391,13 +391,58 @@ Archive::findModuleDefiningSymbol(const std::string& symbol) {
|
|||||||
// ModuleProviders that define those symbols.
|
// ModuleProviders that define those symbols.
|
||||||
void
|
void
|
||||||
Archive::findModulesDefiningSymbols(const std::set<std::string>& symbols,
|
Archive::findModulesDefiningSymbols(const std::set<std::string>& symbols,
|
||||||
std::set<ModuleProvider*>& modules)
|
std::set<ModuleProvider*>& result)
|
||||||
{
|
{
|
||||||
|
assert(mapfile && base && "Can't findModulesDefiningSymbols on new archive");
|
||||||
|
if (symTab.empty()) {
|
||||||
|
// We don't have a symbol table, so we must build it now but lets also
|
||||||
|
// make sure that we populate the modules table as we do this to ensure
|
||||||
|
// that we don't load them twice when findModuleDefiningSymbol is called
|
||||||
|
// below.
|
||||||
|
|
||||||
|
// Get a pointer to the first file
|
||||||
|
const char* At = ((const char*)base) + firstFileOffset;
|
||||||
|
const char* End = ((const char*)base) + mapfile->size();
|
||||||
|
|
||||||
|
while ( At < End) {
|
||||||
|
// Compute the offset to be put in the symbol table
|
||||||
|
unsigned offset = At - base - firstFileOffset;
|
||||||
|
|
||||||
|
// Parse the file's header
|
||||||
|
ArchiveMember* mbr = parseMemberHeader(At, End);
|
||||||
|
|
||||||
|
// If it contains symbols
|
||||||
|
if (mbr->isBytecode() || mbr->isCompressedBytecode()) {
|
||||||
|
// Get the symbols
|
||||||
|
std::vector<std::string> symbols;
|
||||||
|
ModuleProvider* MP = GetBytecodeSymbols((const unsigned char*)At,
|
||||||
|
mbr->getSize(), mbr->getPath().get(),symbols);
|
||||||
|
|
||||||
|
if (MP) {
|
||||||
|
// Insert the module's symbols into the symbol table
|
||||||
|
for (std::vector<std::string>::iterator I = symbols.begin(),
|
||||||
|
E=symbols.end(); I != E; ++I ) {
|
||||||
|
symTab.insert(std::make_pair(*I,offset));
|
||||||
|
}
|
||||||
|
// Insert the ModuleProvider and the ArchiveMember into the table of
|
||||||
|
// modules.
|
||||||
|
modules.insert(std::make_pair(offset,std::make_pair(MP,mbr)));
|
||||||
|
} else {
|
||||||
|
throw std::string("Can't parse bytecode member: ") +
|
||||||
|
mbr->getPath().get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point we have a valid symbol table (one way or another) so we
|
||||||
|
// just use it to quickly find the symbols requested.
|
||||||
|
|
||||||
for (std::set<std::string>::const_iterator I=symbols.begin(),
|
for (std::set<std::string>::const_iterator I=symbols.begin(),
|
||||||
E=symbols.end(); I != E; ++I) {
|
E=symbols.end(); I != E; ++I) {
|
||||||
ModuleProvider* mp = findModuleDefiningSymbol(*I);
|
ModuleProvider* mp = findModuleDefiningSymbol(*I);
|
||||||
if (mp) {
|
if (mp) {
|
||||||
modules.insert(mp);
|
result.insert(mp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,19 +197,28 @@ Archive::writeMember(
|
|||||||
if (CreateSymbolTable &&
|
if (CreateSymbolTable &&
|
||||||
(member.isBytecode() || member.isCompressedBytecode())) {
|
(member.isBytecode() || member.isCompressedBytecode())) {
|
||||||
std::vector<std::string> symbols;
|
std::vector<std::string> symbols;
|
||||||
GetBytecodeSymbols((const unsigned char*)data,fSize,member.getPath().get(),
|
ModuleProvider* MP = GetBytecodeSymbols(
|
||||||
symbols);
|
(const unsigned char*)data,fSize,member.getPath().get(), symbols);
|
||||||
for (std::vector<std::string>::iterator SI = symbols.begin(),
|
|
||||||
SE = symbols.end(); SI != SE; ++SI) {
|
|
||||||
|
|
||||||
std::pair<SymTabType::iterator,bool> Res =
|
// If the bytecode parsed successfully
|
||||||
symTab.insert(std::make_pair(*SI,filepos));
|
if ( MP ) {
|
||||||
|
for (std::vector<std::string>::iterator SI = symbols.begin(),
|
||||||
|
SE = symbols.end(); SI != SE; ++SI) {
|
||||||
|
|
||||||
if (Res.second) {
|
std::pair<SymTabType::iterator,bool> Res =
|
||||||
symTabSize += SI->length() +
|
symTab.insert(std::make_pair(*SI,filepos));
|
||||||
numVbrBytes(SI->length()) +
|
|
||||||
numVbrBytes(filepos);
|
if (Res.second) {
|
||||||
|
symTabSize += SI->length() +
|
||||||
|
numVbrBytes(SI->length()) +
|
||||||
|
numVbrBytes(filepos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// We don't need this module any more.
|
||||||
|
delete MP;
|
||||||
|
} else {
|
||||||
|
throw std::string("Can't parse bytecode member: ") +
|
||||||
|
member.getPath().get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,13 +391,58 @@ Archive::findModuleDefiningSymbol(const std::string& symbol) {
|
|||||||
// ModuleProviders that define those symbols.
|
// ModuleProviders that define those symbols.
|
||||||
void
|
void
|
||||||
Archive::findModulesDefiningSymbols(const std::set<std::string>& symbols,
|
Archive::findModulesDefiningSymbols(const std::set<std::string>& symbols,
|
||||||
std::set<ModuleProvider*>& modules)
|
std::set<ModuleProvider*>& result)
|
||||||
{
|
{
|
||||||
|
assert(mapfile && base && "Can't findModulesDefiningSymbols on new archive");
|
||||||
|
if (symTab.empty()) {
|
||||||
|
// We don't have a symbol table, so we must build it now but lets also
|
||||||
|
// make sure that we populate the modules table as we do this to ensure
|
||||||
|
// that we don't load them twice when findModuleDefiningSymbol is called
|
||||||
|
// below.
|
||||||
|
|
||||||
|
// Get a pointer to the first file
|
||||||
|
const char* At = ((const char*)base) + firstFileOffset;
|
||||||
|
const char* End = ((const char*)base) + mapfile->size();
|
||||||
|
|
||||||
|
while ( At < End) {
|
||||||
|
// Compute the offset to be put in the symbol table
|
||||||
|
unsigned offset = At - base - firstFileOffset;
|
||||||
|
|
||||||
|
// Parse the file's header
|
||||||
|
ArchiveMember* mbr = parseMemberHeader(At, End);
|
||||||
|
|
||||||
|
// If it contains symbols
|
||||||
|
if (mbr->isBytecode() || mbr->isCompressedBytecode()) {
|
||||||
|
// Get the symbols
|
||||||
|
std::vector<std::string> symbols;
|
||||||
|
ModuleProvider* MP = GetBytecodeSymbols((const unsigned char*)At,
|
||||||
|
mbr->getSize(), mbr->getPath().get(),symbols);
|
||||||
|
|
||||||
|
if (MP) {
|
||||||
|
// Insert the module's symbols into the symbol table
|
||||||
|
for (std::vector<std::string>::iterator I = symbols.begin(),
|
||||||
|
E=symbols.end(); I != E; ++I ) {
|
||||||
|
symTab.insert(std::make_pair(*I,offset));
|
||||||
|
}
|
||||||
|
// Insert the ModuleProvider and the ArchiveMember into the table of
|
||||||
|
// modules.
|
||||||
|
modules.insert(std::make_pair(offset,std::make_pair(MP,mbr)));
|
||||||
|
} else {
|
||||||
|
throw std::string("Can't parse bytecode member: ") +
|
||||||
|
mbr->getPath().get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point we have a valid symbol table (one way or another) so we
|
||||||
|
// just use it to quickly find the symbols requested.
|
||||||
|
|
||||||
for (std::set<std::string>::const_iterator I=symbols.begin(),
|
for (std::set<std::string>::const_iterator I=symbols.begin(),
|
||||||
E=symbols.end(); I != E; ++I) {
|
E=symbols.end(); I != E; ++I) {
|
||||||
ModuleProvider* mp = findModuleDefiningSymbol(*I);
|
ModuleProvider* mp = findModuleDefiningSymbol(*I);
|
||||||
if (mp) {
|
if (mp) {
|
||||||
modules.insert(mp);
|
result.insert(mp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,19 +197,28 @@ Archive::writeMember(
|
|||||||
if (CreateSymbolTable &&
|
if (CreateSymbolTable &&
|
||||||
(member.isBytecode() || member.isCompressedBytecode())) {
|
(member.isBytecode() || member.isCompressedBytecode())) {
|
||||||
std::vector<std::string> symbols;
|
std::vector<std::string> symbols;
|
||||||
GetBytecodeSymbols((const unsigned char*)data,fSize,member.getPath().get(),
|
ModuleProvider* MP = GetBytecodeSymbols(
|
||||||
symbols);
|
(const unsigned char*)data,fSize,member.getPath().get(), symbols);
|
||||||
for (std::vector<std::string>::iterator SI = symbols.begin(),
|
|
||||||
SE = symbols.end(); SI != SE; ++SI) {
|
|
||||||
|
|
||||||
std::pair<SymTabType::iterator,bool> Res =
|
// If the bytecode parsed successfully
|
||||||
symTab.insert(std::make_pair(*SI,filepos));
|
if ( MP ) {
|
||||||
|
for (std::vector<std::string>::iterator SI = symbols.begin(),
|
||||||
|
SE = symbols.end(); SI != SE; ++SI) {
|
||||||
|
|
||||||
if (Res.second) {
|
std::pair<SymTabType::iterator,bool> Res =
|
||||||
symTabSize += SI->length() +
|
symTab.insert(std::make_pair(*SI,filepos));
|
||||||
numVbrBytes(SI->length()) +
|
|
||||||
numVbrBytes(filepos);
|
if (Res.second) {
|
||||||
|
symTabSize += SI->length() +
|
||||||
|
numVbrBytes(SI->length()) +
|
||||||
|
numVbrBytes(filepos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// We don't need this module any more.
|
||||||
|
delete MP;
|
||||||
|
} else {
|
||||||
|
throw std::string("Can't parse bytecode member: ") +
|
||||||
|
member.getPath().get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -391,26 +391,27 @@ bool llvm::GetBytecodeSymbols(const sys::Path& fName,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool llvm::GetBytecodeSymbols(const unsigned char*Buffer, unsigned Length,
|
ModuleProvider*
|
||||||
|
llvm::GetBytecodeSymbols(const unsigned char*Buffer, unsigned Length,
|
||||||
const std::string& ModuleID,
|
const std::string& ModuleID,
|
||||||
std::vector<std::string>& symbols) {
|
std::vector<std::string>& symbols) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
std::auto_ptr<ModuleProvider>
|
ModuleProvider* MP =
|
||||||
AMP(getBytecodeBufferModuleProvider(Buffer, Length, ModuleID));
|
getBytecodeBufferModuleProvider(Buffer, Length, ModuleID);
|
||||||
|
|
||||||
// Get the module from the provider
|
// Get the module from the provider
|
||||||
Module* M = AMP->releaseModule();
|
Module* M = MP->materializeModule();
|
||||||
|
|
||||||
// Get the symbols
|
// Get the symbols
|
||||||
getSymbols(M, symbols);
|
getSymbols(M, symbols);
|
||||||
|
|
||||||
// Done with the module
|
// Done with the module
|
||||||
delete M;
|
return MP;
|
||||||
return true;
|
|
||||||
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
return false;
|
// Fall through
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
// vim: sw=2 ai
|
// vim: sw=2 ai
|
||||||
|
Loading…
x
Reference in New Issue
Block a user