如何在 LLVM 传递期间破坏然后解散函数?
How to mangle and then demangle a function during LLVM pass?
我有一个用于重命名函数的LLVM通行证。给定一些源文件file.cc
,我生成LLVM位码如下:
clang -c -o foo.bc -emit-llvm foo.cc
.
我想运行一个LLVM传递foo.bc
并重命名所有全局变量,函数和别名,以便我可以将转换后的位码输出到一个新的文件file_renamed.bc
,然后将file.bc
和file_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级别工作,因此您根本不应该为语言细节(例如原始未修改的名称(而烦恼。
相关文章:
- 为什么我的递归函数按降序打印,然后按升序打印?
- 等待整个 omp 块完成,然后再调用第二个函数
- 如何为 std::vector 分配内存,然后稍后为某些元素调用构造函数?
- 为什么 ComPtr 的函数返回不同的值,然后 &?
- 在C++中编程,将 3 个数字发送到一个函数,然后计算这 3 个数字的平均函数
- 如何将子类作为函数的参数传递给期望基类,然后将该对象传递到指向这些抽象类对象的指针向量中?
- 如何在C++中获取lua函数作为参数,然后调用它
- 如何在类中制作 2D 数组元素,然后在其构造函数中指定其维度?
- 钩/绕道 d3d9 (现在/结束场景) - 似乎调用我的函数然后崩溃
- 使用函数打开文件,然后让其他函数利用该文件?
- C++:将向量传递给函数,然后在main中调用函数.错过了什么
- 努力将指向成员函数的指针绑定到类模板的T成员,然后在槽中调用
- 将函数应用于元组中的每个元素,将每个元素强制转换为类型包中的不同类型,然后作为参数包传递
- 是否可以将多个结构作为一个数据包存储在一个函数中,然后传递给其他函数并在那里提取?
- C++大括号初始值设定项作为参数调用不同的构造函数,然后预期
- C++ 如何创建 2D 数组,将其传递给另一个函数,然后打印
- 如何在 LLVM 传递期间破坏然后解散函数?
- 我的单例中的数组在离开函数后没有保留信息,然后在尝试再次访问信息时崩溃
- C++11 中的随机数:有没有一种简单的方法可以将生成器种子放在代码的一个位置,然后在不同的函数中使用它?
- 将int输入函数,将int输入开关,然后更改int的值