1//===- UniqueInternalLinkageNames.cpp - Unique Internal Linkage Sym Names -===//
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//
9// This file implements unique naming of internal linkage symbols with option
10// -funique-internal-linkage-symbols.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Transforms/Utils/UniqueInternalLinkageNames.h"
15#include "llvm/ADT/SmallString.h"
16#include "llvm/IR/Module.h"
17#include "llvm/InitializePasses.h"
18#include "llvm/Support/MD5.h"
19#include "llvm/Transforms/Utils/ModuleUtils.h"
20
21using namespace llvm;
22
23static bool uniqueifyInternalLinkageNames(Module &M) {
24  llvm::MD5 Md5;
25  Md5.update(M.getSourceFileName());
26  llvm::MD5::MD5Result R;
27  Md5.final(R);
28  SmallString<32> Str;
29  llvm::MD5::stringifyResult(R, Str);
30  std::string ModuleNameHash = (Twine(".") + Twine(Str)).str();
31  bool Changed = false;
32
33  // Append the module hash to all internal linkage functions.
34  for (auto &F : M) {
35    if (F.hasInternalLinkage()) {
36      F.setName(F.getName() + ModuleNameHash);
37      Changed = true;
38    }
39  }
40
41  // Append the module hash to all internal linkage globals.
42  for (auto &GV : M.globals()) {
43    if (GV.hasInternalLinkage()) {
44      GV.setName(GV.getName() + ModuleNameHash);
45      Changed = true;
46    }
47  }
48  return Changed;
49}
50
51namespace {
52
53// Legacy pass that provides a name to every anon globals.
54class UniqueInternalLinkageNamesLegacyPass : public ModulePass {
55
56public:
57  /// Pass identification, replacement for typeid
58  static char ID;
59
60  /// Specify pass name for debug output
61  StringRef getPassName() const override {
62    return "Unique Internal Linkage Names";
63  }
64
65  explicit UniqueInternalLinkageNamesLegacyPass() : ModulePass(ID) {
66    initializeUniqueInternalLinkageNamesLegacyPassPass(
67        *PassRegistry::getPassRegistry());
68  }
69
70  bool runOnModule(Module &M) override {
71    return uniqueifyInternalLinkageNames(M);
72  }
73};
74
75char UniqueInternalLinkageNamesLegacyPass::ID = 0;
76} // anonymous namespace
77
78PreservedAnalyses
79UniqueInternalLinkageNamesPass::run(Module &M, ModuleAnalysisManager &AM) {
80  if (!uniqueifyInternalLinkageNames(M))
81    return PreservedAnalyses::all();
82
83  return PreservedAnalyses::none();
84}
85
86INITIALIZE_PASS_BEGIN(UniqueInternalLinkageNamesLegacyPass,
87                      "unique-internal-linkage-names",
88                      "Uniqueify internal linkage names", false, false)
89INITIALIZE_PASS_END(UniqueInternalLinkageNamesLegacyPass,
90                    "unique-internal-linkage-names",
91                    "Uniqueify Internal linkage names", false, false)
92
93namespace llvm {
94ModulePass *createUniqueInternalLinkageNamesPass() {
95  return new UniqueInternalLinkageNamesLegacyPass();
96}
97} // namespace llvm
98