[LLVMdev] Weird behavior of llvm-ld

Bram Adams bram.adams at ugent.be
Fri Aug 18 08:49:08 PDT 2006


Hi,

Reid Spencer wrote:
>> That's interesting! So, one only needs to add a 2-arg function called  
>> RunOptimizations to the module (can't check it right now)?
>>     
>
> That is correct. That function and only that function will be called.
> What happens in that function is up to you :)
>   
So, I tried this the last two days, but to no avail. I first wrote the 
following three files to introduce the RunOptimizations-symbol (adapted 
from http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.8):

a) Loader.h

#ifndef LOADER_H
#define LOADER_H

#ifdef __cplusplus
#include "llvm/PassManager.h"
using namespace llvm;
#else
typedef struct PassManager PassManager;
#endif
 
#ifdef __cplusplus
extern "C" {
  extern void RunOptimizations(PassManager*,...);   /* ANSI C prototypes */
  extern PassManager* load_weaver_passes(PassManager*);
}
#endif

#endif


b) c-Loader.c

#include "loader/Loader.h"

void RunOptimizations(PassManager* mgr,...){
  load_weaver_passes(mgr);
}


c) Loader.cpp

#include "loader/Loader.h"
#include "matcher/Matcher.h"
#include "reifier/Reifier.h"

PassManager* load_weaver_passes(PassManager* mgr){
  mgr->add(createFirstPass());
  mgr->add(createSecondPass());

  return mgr;
}

In short, the C part (RunOptimizations) hands its first argument over to 
a global C++ method to add my passes.

When using this machinery with llvm-ld (Slackware 10.2, GCC 3.3.6 and 
LLVM 1.8a), my passes are indeed loaded in and the PassManager attempts 
to run on the processed module. Then, I get the following:

Program received signal SIGSEGV, Segmentation fault.
0xb7f16abf in __dynamic_cast () from /usr/lib/libstdc++.so.5

#0  0xb7ea9abf in __dynamic_cast () from /usr/lib/libstdc++.so.5
#1  0x0843f19d in llvm::PMDebug::PrintArgumentInformation (P=0x85e3b00) 
at /.../llvm/lib/VMCore/Pass.cpp:132
#2  0x0843f1fc in llvm::PMDebug::PrintArgumentInformation (P=0x85ca030) 
at /.../llvm/lib/VMCore/Pass.cpp:134
#3  0x0844e3b8 in llvm::PMDebug::PerformPassStartupStuff (P=0x85ca030) 
at PassManagerT.h:66
#4  0x08444146 in llvm::PassManagerT<llvm::MTraits>::runOnUnit 
(this=0x85ca048, M=0x85bf330) at PassManagerT.h:280
#5  0x0843eb26 in llvm::ModulePassManager::runOnModule (this=0x85ca030, 
M=@0x85bf330) at PassManagerT.h:905
#6  0x0843eebf in llvm::PassManager::run (this=0xbfe36400, M=@0x85bf330) 
at /.../llvm/lib/VMCore/Pass.cpp:85
#7  0x082a0361 in llvm::Optimize (M=0x85bf330) at 
/.../llvm/tools/llvm-ld/Optimize.cpp:189
#8  0x082a7161 in main (argc=14, argv=0xbfe365e4, envp=0xbfe36620) at 
/.../llvm/tools/llvm-ld/llvm-ld.cpp:467

The backtrace led me to this code snippet (lib/VMCore/Pass.cpp near line 
132):

void PMDebug::PrintArgumentInformation(const Pass *P) {
  // Print out passes in pass manager...
  if (const AnalysisResolver *PM = dynamic_cast<const 
AnalysisResolver*>(P)) { //<-- !!!!!!! ERROR !!!!!!!
    for (unsigned i = 0, e = PM->getNumContainedPasses(); i != e; ++i)
      PrintArgumentInformation(PM->getContainedPass(i));

  } else {  // Normal pass.  Print argument information...
    // Print out arguments for registered passes that are _optimizations_
    if (const PassInfo *PI = P->getPassInfo())
      if (PI->getPassType() & PassInfo::Optimization)
        std::cerr << " -" << PI->getPassArgument();
  }
}

While I could verify (using GDB/DDD) that my passes were loaded 
perfectly in load_weaver_pass, once they got on the line marked with 
ERROR the pointer to their vtable suddenly was inaccessible. This made 
dynamic_cast crash. The hardcoded passes, loaded in before mine by 
llvm-ld, had no problems whatsoever. For some reason, some memory 
allocated in my C/C++ bridge is just not accessible anymore by llvm-ld, 
but I don't know why ...

At long last, I decided to port opt's pass loading mechanism to llvm-ld 
to see if this would solve things in my case (despite its limitations). 
And it did! I attached my hack (with uncommented existing loading 
mechanism) in case someone else encounters the same problems. Maybe some 
extra argument switch for llvm-ld could allow user-switchable 
coexistence of both loading mechanisms?

Has anyone else experimented with llvm-ld yet? Did the same problem arise?

Kind regards,

Bram Adams
GH-SEL, INTEC, Ghent University
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20060818/767fea73/attachment.html>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: patch.llvm-ld-1.8
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20060818/767fea73/attachment.ksh>


More information about the llvm-dev mailing list