summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Object
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Object')
-rw-r--r--llvm/lib/Object/ModuleSymbolTable.cpp81
-rw-r--r--llvm/lib/Object/RecordStreamer.cpp5
-rw-r--r--llvm/lib/Object/RecordStreamer.h14
3 files changed, 64 insertions, 36 deletions
diff --git a/llvm/lib/Object/ModuleSymbolTable.cpp b/llvm/lib/Object/ModuleSymbolTable.cpp
index f0d70aefd42..b353ef3c835 100644
--- a/llvm/lib/Object/ModuleSymbolTable.cpp
+++ b/llvm/lib/Object/ModuleSymbolTable.cpp
@@ -68,9 +68,9 @@ void ModuleSymbolTable::addModule(Module *M) {
});
}
-void ModuleSymbolTable::CollectAsmSymbols(
- const Module &M,
- function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
+static void
+initializeRecordStreamer(const Module &M,
+ function_ref<void(RecordStreamer &)> Init) {
StringRef InlineAsm = M.getModuleInlineAsm();
if (InlineAsm.empty())
return;
@@ -119,36 +119,53 @@ void ModuleSymbolTable::CollectAsmSymbols(
if (Parser->Run(false))
return;
- Streamer.flushSymverDirectives();
-
- for (auto &KV : Streamer) {
- StringRef Key = KV.first();
- RecordStreamer::State Value = KV.second;
- // FIXME: For now we just assume that all asm symbols are executable.
- uint32_t Res = BasicSymbolRef::SF_Executable;
- switch (Value) {
- case RecordStreamer::NeverSeen:
- llvm_unreachable("NeverSeen should have been replaced earlier");
- case RecordStreamer::DefinedGlobal:
- Res |= BasicSymbolRef::SF_Global;
- break;
- case RecordStreamer::Defined:
- break;
- case RecordStreamer::Global:
- case RecordStreamer::Used:
- Res |= BasicSymbolRef::SF_Undefined;
- Res |= BasicSymbolRef::SF_Global;
- break;
- case RecordStreamer::DefinedWeak:
- Res |= BasicSymbolRef::SF_Weak;
- Res |= BasicSymbolRef::SF_Global;
- break;
- case RecordStreamer::UndefinedWeak:
- Res |= BasicSymbolRef::SF_Weak;
- Res |= BasicSymbolRef::SF_Undefined;
+ Init(Streamer);
+}
+
+void ModuleSymbolTable::CollectAsmSymbols(
+ const Module &M,
+ function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
+ initializeRecordStreamer(M, [&](RecordStreamer &Streamer) {
+ Streamer.flushSymverDirectives();
+
+ for (auto &KV : Streamer) {
+ StringRef Key = KV.first();
+ RecordStreamer::State Value = KV.second;
+ // FIXME: For now we just assume that all asm symbols are executable.
+ uint32_t Res = BasicSymbolRef::SF_Executable;
+ switch (Value) {
+ case RecordStreamer::NeverSeen:
+ llvm_unreachable("NeverSeen should have been replaced earlier");
+ case RecordStreamer::DefinedGlobal:
+ Res |= BasicSymbolRef::SF_Global;
+ break;
+ case RecordStreamer::Defined:
+ break;
+ case RecordStreamer::Global:
+ case RecordStreamer::Used:
+ Res |= BasicSymbolRef::SF_Undefined;
+ Res |= BasicSymbolRef::SF_Global;
+ break;
+ case RecordStreamer::DefinedWeak:
+ Res |= BasicSymbolRef::SF_Weak;
+ Res |= BasicSymbolRef::SF_Global;
+ break;
+ case RecordStreamer::UndefinedWeak:
+ Res |= BasicSymbolRef::SF_Weak;
+ Res |= BasicSymbolRef::SF_Undefined;
+ }
+ AsmSymbol(Key, BasicSymbolRef::Flags(Res));
}
- AsmSymbol(Key, BasicSymbolRef::Flags(Res));
- }
+ });
+}
+
+void ModuleSymbolTable::CollectAsmSymvers(
+ const Module &M, function_ref<void(StringRef, StringRef)> AsmSymver) {
+ initializeRecordStreamer(M, [&](RecordStreamer &Streamer) {
+ for (auto &KV : Streamer.symverAliases())
+ for (auto &Alias : KV.second)
+ AsmSymver(KV.first->getName(), Alias);
+ });
}
void ModuleSymbolTable::printSymbolName(raw_ostream &OS, Symbol S) const {
diff --git a/llvm/lib/Object/RecordStreamer.cpp b/llvm/lib/Object/RecordStreamer.cpp
index 21577bb5696..f49c823c068 100644
--- a/llvm/lib/Object/RecordStreamer.cpp
+++ b/llvm/lib/Object/RecordStreamer.cpp
@@ -128,6 +128,11 @@ void RecordStreamer::emitELFSymverDirective(StringRef AliasName,
SymverAliasMap[Aliasee].push_back(AliasName);
}
+iterator_range<RecordStreamer::const_symver_iterator>
+RecordStreamer::symverAliases() {
+ return {SymverAliasMap.begin(), SymverAliasMap.end()};
+}
+
void RecordStreamer::flushSymverDirectives() {
// Mapping from mangled name to GV.
StringMap<const GlobalValue *> MangledNameMap;
diff --git a/llvm/lib/Object/RecordStreamer.h b/llvm/lib/Object/RecordStreamer.h
index 60b2d3ec3e8..13eac028a28 100644
--- a/llvm/lib/Object/RecordStreamer.h
+++ b/llvm/lib/Object/RecordStreamer.h
@@ -47,10 +47,6 @@ private:
public:
RecordStreamer(MCContext &Context, const Module &M);
- using const_iterator = StringMap<State>::const_iterator;
-
- const_iterator begin();
- const_iterator end();
void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
bool) override;
void EmitLabel(MCSymbol *Symbol, SMLoc Loc = SMLoc()) override;
@@ -63,9 +59,19 @@ public:
/// Record .symver aliases for later processing.
void emitELFSymverDirective(StringRef AliasName,
const MCSymbol *Aliasee) override;
+
// Emit ELF .symver aliases and ensure they have the same binding as the
// defined symbol they alias with.
void flushSymverDirectives();
+
+ // Symbols iterators
+ using const_iterator = StringMap<State>::const_iterator;
+ const_iterator begin();
+ const_iterator end();
+
+ // SymverAliasMap iterators
+ using const_symver_iterator = decltype(SymverAliasMap)::const_iterator;
+ iterator_range<const_symver_iterator> symverAliases();
};
} // end namespace llvm
OpenPOWER on IntegriCloud