gpt4 book ai didi

c++ - 使用 llvm::Linker 以编程方式查找未解析的外部对象

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:36:38 24 4
gpt4 key购买 nike

我正在使用 clang/llvm 以编程方式编译和链接 C 源代码。我发现 llvm 链接器似乎没有将模块中存在未解析的外部对象这一事实报告为错误。

我有以下代码(请原谅长度,但这确实是最低要求):

int CompileAndLink()
{
llvm::InitializeNativeTarget();

std::string code = "int UnresolvedFunction();\n"
"int main() { return UnresolvedFunction(); }";

clang::DiagnosticOptions diagnosticOptions;
clang::TextDiagnosticPrinter tdp( llvm::outs(), diagnosticOptions );
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagIDs( new clang::DiagnosticIDs );
clang::Diagnostic diag( diagIDs, &tdp, false );

clang::FileSystemOptions fsOptions;
clang::FileManager fm( fsOptions );

clang::SourceManager sm( diag, fm );
clang::HeaderSearch hs( fm );

clang::TargetOptions targetOptions;
targetOptions.Triple = llvm::sys::getHostTriple();
clang::TargetInfo* ti = clang::TargetInfo::CreateTargetInfo( diag, targetOptions );

clang::HeaderSearchOptions headerSearchOptions;
clang::LangOptions langOptions;
clang::ApplyHeaderSearchOptions( hs, headerSearchOptions, langOptions, ti->getTriple() );

clang::PreprocessorOptions ppo;
clang::Preprocessor pp( diag, langOptions, *ti, sm, hs );

clang::FrontendOptions frontendOptions;
clang::InitializePreprocessor( pp, ppo, headerSearchOptions, frontendOptions );

pp.getBuiltinInfo().InitializeBuiltins( pp.getIdentifierTable(), langOptions );

llvm::MemoryBuffer* sourceBuffer = llvm::MemoryBuffer::getMemBufferCopy( code );
sm.createMainFileIDForMemBuffer( sourceBuffer );

clang::Builtin::Context bic( *ti );
clang::ASTContext astc( langOptions, sm, *ti,
pp.getIdentifierTable(),
pp.getSelectorTable(),
bic,
0 );

llvm::LLVMContext lc;
clang::CodeGenOptions codeGenOptions;
llvm::OwningPtr<clang::CodeGenerator> cg;
cg.reset( clang::CreateLLVMCodeGen( diag, "clang_test", codeGenOptions, lc ) );
if( cg == NULL ) {
printf( "could not create CodeGenerator\n" );
return -1;
}

clang::ParseAST( pp, cg.get(), astc );
if( tdp.getNumErrors() ) {
printf( "error parsing AST\n" );
return -2;
}

llvm::Module* new_module = cg->ReleaseModule();
if( !new_module ) {
printf( "error generating code\n" );
return -2;
}

llvm::Linker linker( "clang_test", "clang_test", lc, llvm::Linker::Verbose );

std::string error;
if( linker.LinkInModule( new_module, &error ) || !error.empty() ) {
printf( "link error\n" );
return -3;
}

llvm::Module* composite_module = linker.getModule();
if( composite_module == NULL ) {
printf( "link error\n" );
return -3;
}

llvm::ExecutionEngine *pEngine = llvm::ExecutionEngine::create( composite_module,
false,
&error );
if( !error.empty() || pEngine == NULL ) {
printf( "error creating ExecutionEngine\n" );
return -4;
}

llvm::Function* f = composite_module->getFunction( "main" );
if( f == NULL ) {
printf( "couldn't find main function\n" );
return -5;
}

// This will abort with the message:
// LLVM ERROR: Program used external function 'UnresolvedFunction' which could not be resolved!
std::vector<llvm::GenericValue> params;
llvm::GenericValue result = pEngine->runFunction( f, params );

printf( "function main returned %llu\n", result.IntVal.getZExtValue() );

return 0;
}

在我们接近尾声调用 runFunction 之前,任何地方都不会发生错误,这会给出错误“LLVM 错误:程序使用了无法解析的外部函数‘UnresolvedFunction’!”堕胎前。

我有点希望 LinkInModule 或 getModule 因某些错误而失败,但事实并非如此。我的问题是:是否有某种方法可以确定模块具有 Unresolved external 问题,以免在尝试执行代码时崩溃和烧毁?我已经在 llvm 源代码中探索了很长一段时间,但到目前为止找不到我要找的东西。

如果重要的话,我在 Mac OS X (x86_64) 上使用 llvm/clang 2.9。

编辑:我在 llvm 源代码 (llvm-2.9/lib/Linker/LinkArchives.cpp) 中发现了一个名为 GetAllUndefinedSymbols 的私有(private)函数,它似乎可以我想要的是。我想我希望有一个实际的 API,但我错过了什么?

最佳答案

IIRC,从来没有人要求过这样的 API,因此不存在。我不完全确定你会用这样的 API 做什么,无论如何......任何重要的程序都会引用任何 .bc 文件中 undefined symbol ,例如 malloc

如果你真的想检查,像下面这样的东西应该可以工作:

for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I)
if (I->isDeclaration())
UndefGlobals.insert(&*I);

for (Module::global_iterator I = M->global_begin(),
E = M->global_end();
I != E; ++I)
if (I->isDeclaration())
UndefGlobals.insert(&*I);

关于c++ - 使用 llvm::Linker 以编程方式查找未解析的外部对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6435400/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com