如何在 LLVM 传递期间破坏然后解散函数?

How to mangle and then demangle a function during LLVM pass?

本文关键字:然后 函数 LLVM      更新时间:2023-10-16

我有一个用于重命名函数的LLVM通行证。给定一些源文件file.cc,我生成LLVM位码如下:

clang -c -o foo.bc -emit-llvm foo.cc.

我想运行一个LLVM传递foo.bc并重命名所有全局变量,函数和别名,以便我可以将转换后的位码输出到一个新的文件file_renamed.bc,然后将file.bcfile_renamed.bc链接到单个文件中,file_linked.bc

我遇到的一个问题是,简单地做F.setName(F.getName() + "_renamed"),就会在F.getName()返回的损坏名称后面添加后缀。

另一个问题:我在下面有一个demangle(const std::string &Name)函数,可以成功破坏Name,但我在重新修改该名称时遇到了麻烦。

如果有更好的方法来重命名LLVM位码中的标识符,或者以其他方式链接同一位码的两个实例,但仍能够唯一标识每个版本中的函数和全局变量,请随时在您的答案中提出建议。

这是我的LLVM通行证。 请注意,我使用的是LLVM 3.4(它是我正在处理的项目的依赖项。

#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cxxabi.h>
#include <memory>
#include "llvm/Pass.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/TypeFinder.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/Target/Mangler.h"

法典

using namespace llvm;
namespace {
struct FunctionRename : public ModulePass {
static char ID; // Pass identification
FunctionRename() : ModulePass(ID) {}
bool runOnModule(Module &M) override {
// Rename all globals and references to them
for (auto it = M.global_begin(); it != M.global_end(); ++it)
{...}
// Rename all aliases and references to them
for (auto it = M.alias_begin(); it != M.alias_end(); ++it)
{...}
// Rename all functions and references to them
for (auto &F : M)
{
StringRef Name = F.getName();
if (F.isDeclaration())
continue;
std::string demangled_name = demangle(Name.str());
std::string new_name = rename(demangled_name);
F.setName(mangle(new_name, &F));
F.setLinkage(GlobalValue::WeakAnyLinkage);
}
return true;
}
std::string demangle(const std::string &Name)
{
int status;
char* demangled_name = NULL;
char* cstr_name = new char[Name.length() + 1];
strcpy(cstr_name, Name.c_str());
demangled_name = __cxxabiv1::__cxa_demangle(cstr_name, NULL, NULL, &status);
if (status != 0)
{
errs() << "Demangling operation failed:n";
switch (status)
{...}
exit(-1);
}
std::string s(demangled_name);
return s;
}
std::string rename(std::string &Name)
{
std::string search_str = std::string("(");
std::string suffix_str = std::string("_renamed");
size_t i = Name.find_first_of(search_str);
if (i == std::string::npos)
Name.append(suffix_str);
else
Name.insert(i, suffix_str);
return Name;
}
/* PROBLEMATIC FUNCTION */
std::string mangle(const std::string &Name, const GlobalValue *GV)
{
SmallString<256> MangledName(StringRef(Name));
Mangler m;
m.getNameWithPrefix((SmallVectorImpl<char>&) MangledName, GV, false, true);
Twine T;
StringRef S = T.toStringRef((SmallVectorImpl<char>&) MangledName);
return S.str();
}
};
}
// Register Pass
char FunctionRename::ID = 0;
static RegisterPass<FunctionRename> X("functionrename", "Function Rename Pass");

您不能仅从字符串中轻松破坏C++标识符。您需要有适当的C++ AST。事实上,我根本不明白为什么你需要那个破坏/破坏的东西。由于您是在LLVM IR级别工作,因此您根本不应该为语言细节(例如原始未修改的名称(而烦恼。

相关文章: