RecordStreamer.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. //===-- RecordStreamer.cpp - Record asm defined and used symbols ----------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "RecordStreamer.h"
  9. #include "llvm/IR/Mangler.h"
  10. #include "llvm/IR/Module.h"
  11. #include "llvm/MC/MCContext.h"
  12. #include "llvm/MC/MCSymbol.h"
  13. using namespace llvm;
  14. void RecordStreamer::markDefined(const MCSymbol &Symbol) {
  15. State &S = Symbols[Symbol.getName()];
  16. switch (S) {
  17. case DefinedGlobal:
  18. case Global:
  19. S = DefinedGlobal;
  20. break;
  21. case NeverSeen:
  22. case Defined:
  23. case Used:
  24. S = Defined;
  25. break;
  26. case DefinedWeak:
  27. break;
  28. case UndefinedWeak:
  29. S = DefinedWeak;
  30. }
  31. }
  32. void RecordStreamer::markGlobal(const MCSymbol &Symbol,
  33. MCSymbolAttr Attribute) {
  34. State &S = Symbols[Symbol.getName()];
  35. switch (S) {
  36. case DefinedGlobal:
  37. case Defined:
  38. S = (Attribute == MCSA_Weak) ? DefinedWeak : DefinedGlobal;
  39. break;
  40. case NeverSeen:
  41. case Global:
  42. case Used:
  43. S = (Attribute == MCSA_Weak) ? UndefinedWeak : Global;
  44. break;
  45. case UndefinedWeak:
  46. case DefinedWeak:
  47. break;
  48. }
  49. }
  50. void RecordStreamer::markUsed(const MCSymbol &Symbol) {
  51. State &S = Symbols[Symbol.getName()];
  52. switch (S) {
  53. case DefinedGlobal:
  54. case Defined:
  55. case Global:
  56. case DefinedWeak:
  57. case UndefinedWeak:
  58. break;
  59. case NeverSeen:
  60. case Used:
  61. S = Used;
  62. break;
  63. }
  64. }
  65. void RecordStreamer::visitUsedSymbol(const MCSymbol &Sym) { markUsed(Sym); }
  66. RecordStreamer::RecordStreamer(MCContext &Context, const Module &M)
  67. : MCStreamer(Context), M(M) {}
  68. RecordStreamer::const_iterator RecordStreamer::begin() {
  69. return Symbols.begin();
  70. }
  71. RecordStreamer::const_iterator RecordStreamer::end() { return Symbols.end(); }
  72. void RecordStreamer::emitInstruction(const MCInst &Inst,
  73. const MCSubtargetInfo &STI) {
  74. MCStreamer::emitInstruction(Inst, STI);
  75. }
  76. void RecordStreamer::emitLabel(MCSymbol *Symbol, SMLoc Loc) {
  77. MCStreamer::emitLabel(Symbol);
  78. markDefined(*Symbol);
  79. }
  80. void RecordStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
  81. markDefined(*Symbol);
  82. MCStreamer::emitAssignment(Symbol, Value);
  83. }
  84. bool RecordStreamer::emitSymbolAttribute(MCSymbol *Symbol,
  85. MCSymbolAttr Attribute) {
  86. if (Attribute == MCSA_Global || Attribute == MCSA_Weak)
  87. markGlobal(*Symbol, Attribute);
  88. if (Attribute == MCSA_LazyReference)
  89. markUsed(*Symbol);
  90. return true;
  91. }
  92. void RecordStreamer::emitZerofill(MCSection *Section, MCSymbol *Symbol,
  93. uint64_t Size, Align ByteAlignment,
  94. SMLoc Loc) {
  95. markDefined(*Symbol);
  96. }
  97. void RecordStreamer::emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
  98. Align ByteAlignment) {
  99. markDefined(*Symbol);
  100. }
  101. RecordStreamer::State RecordStreamer::getSymbolState(const MCSymbol *Sym) {
  102. auto SI = Symbols.find(Sym->getName());
  103. if (SI == Symbols.end())
  104. return NeverSeen;
  105. return SI->second;
  106. }
  107. void RecordStreamer::emitELFSymverDirective(const MCSymbol *OriginalSym,
  108. StringRef Name,
  109. bool KeepOriginalSym) {
  110. SymverAliasMap[OriginalSym].push_back(Name);
  111. }
  112. iterator_range<RecordStreamer::const_symver_iterator>
  113. RecordStreamer::symverAliases() {
  114. return {SymverAliasMap.begin(), SymverAliasMap.end()};
  115. }
  116. void RecordStreamer::flushSymverDirectives() {
  117. // Mapping from mangled name to GV.
  118. StringMap<const GlobalValue *> MangledNameMap;
  119. // The name in the assembler will be mangled, but the name in the IR
  120. // might not, so we first compute a mapping from mangled name to GV.
  121. Mangler Mang;
  122. SmallString<64> MangledName;
  123. for (const GlobalValue &GV : M.global_values()) {
  124. if (!GV.hasName())
  125. continue;
  126. MangledName.clear();
  127. MangledName.reserve(GV.getName().size() + 1);
  128. Mang.getNameWithPrefix(MangledName, &GV, /*CannotUsePrivateLabel=*/false);
  129. MangledNameMap[MangledName] = &GV;
  130. }
  131. // Walk all the recorded .symver aliases, and set up the binding
  132. // for each alias.
  133. for (auto &Symver : SymverAliasMap) {
  134. const MCSymbol *Aliasee = Symver.first;
  135. MCSymbolAttr Attr = MCSA_Invalid;
  136. bool IsDefined = false;
  137. // First check if the aliasee binding was recorded in the asm.
  138. RecordStreamer::State state = getSymbolState(Aliasee);
  139. switch (state) {
  140. case RecordStreamer::Global:
  141. case RecordStreamer::DefinedGlobal:
  142. Attr = MCSA_Global;
  143. break;
  144. case RecordStreamer::UndefinedWeak:
  145. case RecordStreamer::DefinedWeak:
  146. Attr = MCSA_Weak;
  147. break;
  148. default:
  149. break;
  150. }
  151. switch (state) {
  152. case RecordStreamer::Defined:
  153. case RecordStreamer::DefinedGlobal:
  154. case RecordStreamer::DefinedWeak:
  155. IsDefined = true;
  156. break;
  157. case RecordStreamer::NeverSeen:
  158. case RecordStreamer::Global:
  159. case RecordStreamer::Used:
  160. case RecordStreamer::UndefinedWeak:
  161. break;
  162. }
  163. if (Attr == MCSA_Invalid || !IsDefined) {
  164. const GlobalValue *GV = M.getNamedValue(Aliasee->getName());
  165. if (!GV) {
  166. auto MI = MangledNameMap.find(Aliasee->getName());
  167. if (MI != MangledNameMap.end())
  168. GV = MI->second;
  169. }
  170. if (GV) {
  171. // If we don't have a symbol attribute from assembly, then check if
  172. // the aliasee was defined in the IR.
  173. if (Attr == MCSA_Invalid) {
  174. if (GV->hasExternalLinkage())
  175. Attr = MCSA_Global;
  176. else if (GV->hasLocalLinkage())
  177. Attr = MCSA_Local;
  178. else if (GV->isWeakForLinker())
  179. Attr = MCSA_Weak;
  180. }
  181. IsDefined = IsDefined || !GV->isDeclarationForLinker();
  182. }
  183. }
  184. // Set the detected binding on each alias with this aliasee.
  185. for (auto AliasName : Symver.second) {
  186. std::pair<StringRef, StringRef> Split = AliasName.split("@@@");
  187. SmallString<128> NewName;
  188. if (!Split.second.empty() && !Split.second.startswith("@")) {
  189. // Special processing for "@@@" according
  190. // https://sourceware.org/binutils/docs/as/Symver.html
  191. const char *Separator = IsDefined ? "@@" : "@";
  192. AliasName =
  193. (Split.first + Separator + Split.second).toStringRef(NewName);
  194. }
  195. MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
  196. // TODO: Handle "@@@". Depending on SymbolAttribute value it needs to be
  197. // converted into @ or @@.
  198. const MCExpr *Value = MCSymbolRefExpr::create(Aliasee, getContext());
  199. if (IsDefined)
  200. markDefined(*Alias);
  201. // Don't use EmitAssignment override as it always marks alias as defined.
  202. MCStreamer::emitAssignment(Alias, Value);
  203. if (Attr != MCSA_Invalid)
  204. emitSymbolAttribute(Alias, Attr);
  205. }
  206. }
  207. }