Don't lookup an object symbol name in the module.

Instead, walk the obj symbol list in parallel to find the GV. This shouldn't
change anything on ELF where global symbols are not mangled, but it is a step
toward supporting other object formats.

Gold itself is ELF only, but bfd ld supports COFF and the logic in the gold
plugin could be reused on lld.

llvm-svn: 223780
This commit is contained in:
Rafael Espindola 2014-12-09 16:13:59 +00:00
parent a94a68a8d2
commit 527e846ef7
3 changed files with 34 additions and 27 deletions

View File

@ -36,7 +36,10 @@ public:
std::error_code printSymbolName(raw_ostream &OS,
DataRefImpl Symb) const override;
uint32_t getSymbolFlags(DataRefImpl Symb) const override;
const GlobalValue *getSymbolGV(DataRefImpl Symb) const;
GlobalValue *getSymbolGV(DataRefImpl Symb);
const GlobalValue *getSymbolGV(DataRefImpl Symb) const {
return const_cast<IRObjectFile *>(this)->getSymbolGV(Symb);
}
basic_symbol_iterator symbol_begin_impl() const override;
basic_symbol_iterator symbol_end_impl() const override;
@ -46,6 +49,7 @@ public:
Module &getModule() {
return *M;
}
std::unique_ptr<Module> takeModule() { return std::move(M); }
static inline bool classof(const Binary *v) {
return v->isIR();

View File

@ -116,7 +116,7 @@ IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod)
IRObjectFile::~IRObjectFile() {
}
static const GlobalValue *getGV(DataRefImpl &Symb) {
static GlobalValue *getGV(DataRefImpl &Symb) {
if ((Symb.p & 3) == 3)
return nullptr;
@ -235,10 +235,7 @@ uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const {
return Res;
}
const GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) const {
const GlobalValue *GV = getGV(Symb);
return GV;
}
GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) { return getGV(Symb); }
basic_symbol_iterator IRObjectFile::symbol_begin_impl() const {
Module::const_iterator I = M->begin();

View File

@ -261,6 +261,14 @@ static const GlobalObject *getBaseObject(const GlobalValue &GV) {
return cast<GlobalObject>(&GV);
}
static bool shouldSkip(uint32_t Symflags) {
if (!(Symflags & object::BasicSymbolRef::SF_Global))
return true;
if (Symflags & object::BasicSymbolRef::SF_FormatSpecific)
return true;
return false;
}
/// Called by gold to see whether this file is one that our plugin can handle.
/// We'll try to open it and register all the symbols with add_symbol if
/// possible.
@ -318,10 +326,7 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
for (auto &Sym : Obj->symbols()) {
uint32_t Symflags = Sym.getFlags();
if (!(Symflags & object::BasicSymbolRef::SF_Global))
continue;
if (Symflags & object::BasicSymbolRef::SF_FormatSpecific)
if (shouldSkip(Symflags))
continue;
cf.syms.push_back(ld_plugin_symbol());
@ -556,40 +561,41 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, raw_fd_ostream *ApiFile,
if (get_view(F.handle, &View) != LDPS_OK)
message(LDPL_FATAL, "Failed to get a view of file");
llvm::ErrorOr<MemoryBufferRef> MBOrErr =
object::IRObjectFile::findBitcodeInMemBuffer(
MemoryBufferRef(StringRef((const char *)View, File.filesize), ""));
if (std::error_code EC = MBOrErr.getError())
MemoryBufferRef BufferRef(StringRef((const char *)View, File.filesize), "");
ErrorOr<std::unique_ptr<object::IRObjectFile>> ObjOrErr =
object::IRObjectFile::createIRObjectFile(BufferRef, Context);
if (std::error_code EC = ObjOrErr.getError())
message(LDPL_FATAL, "Could not read bitcode from file : %s",
EC.message().c_str());
std::unique_ptr<MemoryBuffer> Buffer =
MemoryBuffer::getMemBuffer(MBOrErr->getBuffer(), "", false);
if (release_input_file(F.handle) != LDPS_OK)
message(LDPL_FATAL, "Failed to release file information");
ErrorOr<Module *> MOrErr = getLazyBitcodeModule(std::move(Buffer), Context);
object::IRObjectFile &Obj = **ObjOrErr;
if (std::error_code EC = MOrErr.getError())
message(LDPL_FATAL, "Could not read bitcode from file : %s",
EC.message().c_str());
std::unique_ptr<Module> M(MOrErr.get());
Module &M = Obj.getModule();
SmallPtrSet<GlobalValue *, 8> Used;
collectUsedGlobalVariables(*M, Used, /*CompilerUsed*/ false);
collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);
DenseSet<GlobalValue *> Drop;
std::vector<GlobalAlias *> KeptAliases;
for (ld_plugin_symbol &Sym : F.syms) {
unsigned SymNum = 0;
for (auto &ObjSym : Obj.symbols()) {
if (shouldSkip(ObjSym.getFlags()))
continue;
ld_plugin_symbol &Sym = F.syms[SymNum];
++SymNum;
ld_plugin_symbol_resolution Resolution =
(ld_plugin_symbol_resolution)Sym.resolution;
if (options::generate_api_file)
*ApiFile << Sym.name << ' ' << getResolutionName(Resolution) << '\n';
GlobalValue *GV = M->getNamedValue(Sym.name);
GlobalValue *GV = Obj.getSymbolGV(ObjSym.getRawDataRefImpl());
if (!GV)
continue; // Asm symbol.
@ -671,7 +677,7 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, raw_fd_ostream *ApiFile,
for (auto *GV : Drop)
drop(*GV);
return M;
return Obj.takeModule();
}
static void runLTOPasses(Module &M, TargetMachine &TM) {