JIT doens't resolve address

classic Classic list List threaded Threaded
19 messages Options
Reply | Threaded
Open this post in threaded view
|

JIT doens't resolve address

Romanenkov Kirill via cfe-dev
Hello LLVM-World,

I was following the "Building a JIT in LLVM"-Tutorial and tried to load a normal main. My code is the following:
class Jitter
{
private:
  std::unique_ptr<TargetMachine> TM;
  const DataLayout DL;
  ObjectLinkingLayer<> ObjectLayer;
  IRCompileLayer<decltype(ObjectLayer)> CompileLayer;

public:
  typedef decltype(CompileLayer)::ModuleSetHandleT ModuleHandle;

  Jitter() : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
      CompileLayer(ObjectLayer, SimpleCompiler(*TM))
  {printf("!");
        llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
  }

  TargetMachine &getTargetMachine() { return *TM; }

  ModuleHandle addModule(std::unique_ptr<Module> &&M) {
  // Build our symbol resolver:
  // Lambda 1: Look back into the JIT itself to find symbols that are part of
  //           the same "logical dylib".
  // Lambda 2: Search for external symbols in the host process.
  auto Resolver = createLambdaResolver(
      [&](const std::string &Name)
      {
                printf("FLUSH :0\n");

        if (auto Sym = CompileLayer.findSymbol(Name, false))
          return Sym;
        return JITSymbol(nullptr);
      },
      [](const std::string &S)
          {
                  printf("PLUSH :0\n");

        if (auto SymAddr =
              RTDyldMemoryManager::getSymbolAddressInProcess(S))
          return JITSymbol(SymAddr, JITSymbolFlags::Exported);
        return JITSymbol(nullptr);
      });

  // Build a singleton module set to hold our module.
  std::vector<std::unique_ptr<Module>> Ms;
  Ms.push_back(std::move(M));

  // Add the set to the JIT with the resolver we created above and a newly
  // created SectionMemoryManager.
  return CompileLayer.addModuleSet(std::move(Ms),
                                   make_unique<SectionMemoryManager>(),
                                   std::move(Resolver));
}

JITSymbol findSymbol(const std::string Name) {
  std::string MangledName;
  raw_string_ostream MangledNameStream(MangledName);
  Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
  printf("Tzearch for: %s\n\n", MangledNameStream.str());
  return CompileLayer.findSymbol(MangledNameStream.str(), false);
}

void removeModule(ModuleHandle H) {
  CompileLayer.removeModuleSet(H);
}

};


And calling from main with:

int main()
{
        llvm::InitializeNativeTarget();
        llvm::InitializeNativeTargetAsmPrinter();
        llvm::InitializeNativeTargetAsmParser();

        llvm::LLVMContext context;
        llvm::SMDiagnostic dia;

        std::unique_ptr<llvm::Module> M = llvm::parseIRFile("./jit_main.ll", dia, context);
        Jitter jit;
        printf("Wuff?");
        Jitter::ModuleHandle h = jit.addModule(std::move(M));
        printf("KNUFF!\n");

        printf("Kuchen! 0x%p\n", jit.findSymbol("main").getAddress());

        system("PAUSE");
        return 0;
}

The Code runs without a fail, but when the programm tries to resolve "main" the address is 0. The strange thing: the printf "FLUSH :0\n" and "PLUSH :0\n" are never called, so did the code never compiled? What I'm doing wrong?

Kind regards
Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: JIT doens't resolve address

Romanenkov Kirill via cfe-dev
HI Bjoern,

There are two kinds of symbol lookup in the JIT:

(1) You want to find a symbol defined JIT'd code. This is what "findSymbol" on the JIT class does.

(2) The JIT wants to fix up a module that contains references to symbols defined elsewhere (either in your program, or in other JIT'd code). This is the SymbolResolver's job.

So assuming your main function in main.ll is trivial, e.g.

int main() {
  return 0;
}

then your findSymbol call will return the address of the JIT'd main without ever needing to look anything up in the resolver.

If, on the other hand, your main function contains an external reference, e.g.

int main() {
  printf("Hello, World!"); // Reference to externally defined function printf.
  return 0;
}

Then you'll receive a call back on your resolver looking for the address of printf.

Hope this helps!

Cheers,
Lang.

On Thu, Apr 20, 2017 at 6:43 AM, via cfe-dev <[hidden email]> wrote:
Hello LLVM-World,

I was following the "Building a JIT in LLVM"-Tutorial and tried to load a normal main. My code is the following:
class Jitter
{
private:
  std::unique_ptr<TargetMachine> TM;
  const DataLayout DL;
  ObjectLinkingLayer<> ObjectLayer;
  IRCompileLayer<decltype(ObjectLayer)> CompileLayer;

public:
  typedef decltype(CompileLayer)::ModuleSetHandleT ModuleHandle;

  Jitter() : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
      CompileLayer(ObjectLayer, SimpleCompiler(*TM))
  {printf("!");
        llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
  }

  TargetMachine &getTargetMachine() { return *TM; }

  ModuleHandle addModule(std::unique_ptr<Module> &&M) {
  // Build our symbol resolver:
  // Lambda 1: Look back into the JIT itself to find symbols that are part of
  //           the same "logical dylib".
  // Lambda 2: Search for external symbols in the host process.
  auto Resolver = createLambdaResolver(
      [&](const std::string &Name)
      {
                printf("FLUSH :0\n");

        if (auto Sym = CompileLayer.findSymbol(Name, false))
          return Sym;
        return JITSymbol(nullptr);
      },
      [](const std::string &S)
          {
                  printf("PLUSH :0\n");

        if (auto SymAddr =
              RTDyldMemoryManager::getSymbolAddressInProcess(S))
          return JITSymbol(SymAddr, JITSymbolFlags::Exported);
        return JITSymbol(nullptr);
      });

  // Build a singleton module set to hold our module.
  std::vector<std::unique_ptr<Module>> Ms;
  Ms.push_back(std::move(M));

  // Add the set to the JIT with the resolver we created above and a newly
  // created SectionMemoryManager.
  return CompileLayer.addModuleSet(std::move(Ms),
                                   make_unique<SectionMemoryManager>(),
                                   std::move(Resolver));
}

JITSymbol findSymbol(const std::string Name) {
  std::string MangledName;
  raw_string_ostream MangledNameStream(MangledName);
  Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
  printf("Tzearch for: %s\n\n", MangledNameStream.str());
  return CompileLayer.findSymbol(MangledNameStream.str(), false);
}

void removeModule(ModuleHandle H) {
  CompileLayer.removeModuleSet(H);
}

};


And calling from main with:

int main()
{
        llvm::InitializeNativeTarget();
        llvm::InitializeNativeTargetAsmPrinter();
        llvm::InitializeNativeTargetAsmParser();

        llvm::LLVMContext context;
        llvm::SMDiagnostic dia;

        std::unique_ptr<llvm::Module> M = llvm::parseIRFile("./jit_main.ll", dia, context);
        Jitter jit;
        printf("Wuff?");
        Jitter::ModuleHandle h = jit.addModule(std::move(M));
        printf("KNUFF!\n");

        printf("Kuchen! 0x%p\n", jit.findSymbol("main").getAddress());

        system("PAUSE");
        return 0;
}

The Code runs without a fail, but when the programm tries to resolve "main" the address is 0. The strange thing: the printf "FLUSH :0\n" and "PLUSH :0\n" are never called, so did the code never compiled? What I'm doing wrong?

Kind regards
Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: JIT doens't resolve address

Romanenkov Kirill via cfe-dev
Hi Bjoern,

Sorry - I just noticed that the address for your "main" function has come back as '0'. In this case the answer is even simpler: The JIT never found the function at all, and so definitely didn't have any external symbols to resolve, so it never called the resolver.

A failure to find main has three likely causes:

(1) jit_main.ll does not define main,
(2) jit_main.ll defines main with private/internal linkage (the JIT can't see private/internal symbols in general)
(3) jit_main.ll defines main with external linkage, but a system mangling is applied (e.g. on MacOSX 'main' is mangled to '_main'). The mangler code in your findSymbol function *should* correct for this, but this may fail if the default data layout for your TargetMachine varies from the Module's DataLayout.

Can you share the contents of your jit_main.ll Module?

Cheers,
Lang.
   

On Thu, Apr 20, 2017 at 1:35 PM, Lang Hames <[hidden email]> wrote:
HI Bjoern,

There are two kinds of symbol lookup in the JIT:

(1) You want to find a symbol defined JIT'd code. This is what "findSymbol" on the JIT class does.

(2) The JIT wants to fix up a module that contains references to symbols defined elsewhere (either in your program, or in other JIT'd code). This is the SymbolResolver's job.

So assuming your main function in main.ll is trivial, e.g.

int main() {
  return 0;
}

then your findSymbol call will return the address of the JIT'd main without ever needing to look anything up in the resolver.

If, on the other hand, your main function contains an external reference, e.g.

int main() {
  printf("Hello, World!"); // Reference to externally defined function printf.
  return 0;
}

Then you'll receive a call back on your resolver looking for the address of printf.

Hope this helps!

Cheers,
Lang.

On Thu, Apr 20, 2017 at 6:43 AM, via cfe-dev <[hidden email]> wrote:
Hello LLVM-World,

I was following the "Building a JIT in LLVM"-Tutorial and tried to load a normal main. My code is the following:
class Jitter
{
private:
  std::unique_ptr<TargetMachine> TM;
  const DataLayout DL;
  ObjectLinkingLayer<> ObjectLayer;
  IRCompileLayer<decltype(ObjectLayer)> CompileLayer;

public:
  typedef decltype(CompileLayer)::ModuleSetHandleT ModuleHandle;

  Jitter() : TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
      CompileLayer(ObjectLayer, SimpleCompiler(*TM))
  {printf("!");
        llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
  }

  TargetMachine &getTargetMachine() { return *TM; }

  ModuleHandle addModule(std::unique_ptr<Module> &&M) {
  // Build our symbol resolver:
  // Lambda 1: Look back into the JIT itself to find symbols that are part of
  //           the same "logical dylib".
  // Lambda 2: Search for external symbols in the host process.
  auto Resolver = createLambdaResolver(
      [&](const std::string &Name)
      {
                printf("FLUSH :0\n");

        if (auto Sym = CompileLayer.findSymbol(Name, false))
          return Sym;
        return JITSymbol(nullptr);
      },
      [](const std::string &S)
          {
                  printf("PLUSH :0\n");

        if (auto SymAddr =
              RTDyldMemoryManager::getSymbolAddressInProcess(S))
          return JITSymbol(SymAddr, JITSymbolFlags::Exported);
        return JITSymbol(nullptr);
      });

  // Build a singleton module set to hold our module.
  std::vector<std::unique_ptr<Module>> Ms;
  Ms.push_back(std::move(M));

  // Add the set to the JIT with the resolver we created above and a newly
  // created SectionMemoryManager.
  return CompileLayer.addModuleSet(std::move(Ms),
                                   make_unique<SectionMemoryManager>(),
                                   std::move(Resolver));
}

JITSymbol findSymbol(const std::string Name) {
  std::string MangledName;
  raw_string_ostream MangledNameStream(MangledName);
  Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
  printf("Tzearch for: %s\n\n", MangledNameStream.str());
  return CompileLayer.findSymbol(MangledNameStream.str(), false);
}

void removeModule(ModuleHandle H) {
  CompileLayer.removeModuleSet(H);
}

};


And calling from main with:

int main()
{
        llvm::InitializeNativeTarget();
        llvm::InitializeNativeTargetAsmPrinter();
        llvm::InitializeNativeTargetAsmParser();

        llvm::LLVMContext context;
        llvm::SMDiagnostic dia;

        std::unique_ptr<llvm::Module> M = llvm::parseIRFile("./jit_main.ll", dia, context);
        Jitter jit;
        printf("Wuff?");
        Jitter::ModuleHandle h = jit.addModule(std::move(M));
        printf("KNUFF!\n");

        printf("Kuchen! 0x%p\n", jit.findSymbol("main").getAddress());

        system("PAUSE");
        return 0;
}

The Code runs without a fail, but when the programm tries to resolve "main" the address is 0. The strange thing: the printf "FLUSH :0\n" and "PLUSH :0\n" are never called, so did the code never compiled? What I'm doing wrong?

Kind regards
Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev




_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: JIT doens't resolve address

Romanenkov Kirill via cfe-dev
Hello Lang,

the Code for my jit_main is a normal printf-HelloWorld program. I opended the file with notepad and found the following:

; Function Attrs: noinline norecurse uwtable
define i32 @main() #0 {
entry:
  %retval = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([35 x i8], [35 x i8]* @"\01??_C@_0CD@CMJEAMCD@Planschbeckilein?5sagt?5Halloilein@", i32 0, i32 0))
  %call1 = call i32 @system(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @"\01??_C@_05DIAHPDGL@PAUSE?$AA@", i32 0, i32 0))
  ret i32 0
}


So... there is a main... Anyway! The code for the main is this one:
#include <stdio.h>
#include <stdlib.h>

int main()
{
        printf("Planschbeckilein sagt Halloilein!\n");
        system("PAUSE");

        return 0;
}


Kind regards
Björn



From:        Lang Hames <[hidden email]>
To:        [hidden email]
Cc:        Clang Dev <[hidden email]>
Date:        20.04.2017 22:54
Subject:        Re: [cfe-dev] JIT doens't resolve address




Hi Bjoern,

Sorry - I just noticed that the address for your "main" function has come back as '0'. In this case the answer is even simpler: The JIT never found the function at all, and so definitely didn't have any external symbols to resolve, so it never called the resolver.

A failure to find main has three likely causes:

(1) jit_main.ll does not define main,
(2) jit_main.ll defines main with private/internal linkage (the JIT can't see private/internal symbols in general)
(3) jit_main.ll defines main with external linkage, but a system mangling is applied (e.g. on MacOSX 'main' is mangled to '_main'). The mangler code in your findSymbol function *should* correct for this, but this may fail if the default data layout for your TargetMachine varies from the Module's DataLayout.

Can you share the contents of your jit_main.ll Module?

Cheers,
Lang.
   

On Thu, Apr 20, 2017 at 1:35 PM, Lang Hames <lhames@...> wrote:
HI Bjoern,

There are two kinds of symbol lookup in the JIT:

(1) You want to find a symbol defined JIT'd code. This is what "findSymbol" on the JIT class does.

(2) The JIT wants to fix up a module that contains references to symbols defined elsewhere (either in your program, or in other JIT'd code). This is the SymbolResolver's job.

So assuming your main function in main.ll is trivial, e.g.

int main() {
  return 0;
}

then your findSymbol call will return the address of the JIT'd main without ever needing to look anything up in the resolver.

If, on the other hand, your main function contains an external reference, e.g.

int main() {
  printf("Hello, World!"); // Reference to externally defined function printf.
  return 0;
}

Then you'll receive a call back on your resolver looking for the address of printf.

Hope this helps!

Cheers,
Lang.

On Thu, Apr 20, 2017 at 6:43 AM, via cfe-dev <[hidden email]> wrote:
Hello LLVM-World,

I was following the "Building a JIT in LLVM"-Tutorial and tried to load a normal main. My code is the following:
class Jitter
{

private
:
  std::
unique_ptr<TargetMachine> TM;
 
const DataLayout DL;
 
ObjectLinkingLayer<> ObjectLayer;
 
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;

public
:
 
typedef decltype(CompileLayer)::ModuleSetHandleT ModuleHandle;

  Jitter() : TM(
EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
      CompileLayer(ObjectLayer,
SimpleCompiler(*TM))
  {printf(
"!");
        llvm::sys::
DynamicLibrary::LoadLibraryPermanently(nullptr);
  }


 
TargetMachine &getTargetMachine() { return *TM; }

 
ModuleHandle addModule(std::unique_ptr<Module> &&M) {
 
// Build our symbol resolver:
 
// Lambda 1: Look back into the JIT itself to find symbols that are part of
 
//           the same "logical dylib".
 
// Lambda 2: Search for external symbols in the host process.
 
auto Resolver = createLambdaResolver(
      [&](
const std::string &Name)
      {

                printf(
"FLUSH :0\n");

       
if (auto Sym = CompileLayer.findSymbol(Name, false))
         
return Sym;
       
return JITSymbol(nullptr);
      },

      [](
const std::string &S)
          {

                  printf(
"PLUSH :0\n");

       
if (auto SymAddr =
             
RTDyldMemoryManager::getSymbolAddressInProcess(S))
         
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
       
return JITSymbol(nullptr);
      });


 
// Build a singleton module set to hold our module.
  std::
vector<std::unique_ptr<Module>> Ms;
  Ms.push_back(std::move(
M));

 
// Add the set to the JIT with the resolver we created above and a newly
 
// created SectionMemoryManager.
 
return CompileLayer.addModuleSet(std::move(Ms),
                                   make_unique<
SectionMemoryManager>(),
                                   std::move(Resolver));

}


JITSymbol
findSymbol(const std::string Name) {
  std::
string MangledName;
 
raw_string_ostream MangledNameStream(MangledName);
 
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
  printf(
"Tzearch for: %s\n\n", MangledNameStream.str());
 
return CompileLayer.findSymbol(MangledNameStream.str(), false);
}


void
removeModule(ModuleHandle H) {
  CompileLayer.removeModuleSet(
H);
}


};



And calling from main with:
int main()
{

        llvm::InitializeNativeTarget();

        llvm::InitializeNativeTargetAsmPrinter();

        llvm::InitializeNativeTargetAsmParser();


        llvm::
LLVMContext context;
        llvm::
SMDiagnostic dia;

        std::
unique_ptr<llvm::Module> M = llvm::parseIRFile("./jit_main.ll", dia, context);
       
Jitter jit;
        printf(
"Wuff?");
       
Jitter::ModuleHandle h = jit.addModule(std::move(M));
        printf(
"KNUFF!\n");

        printf(
"Kuchen! 0x%p\n", jit.findSymbol("main").getAddress());

        system(
"PAUSE");
       
return 0;
}


The Code runs without a fail, but when the programm tries to resolve "main" the address is 0. The strange thing: the printf "
FLUSH :0\n" and "PLUSH :0\n" are never called, so did the code never compiled? What I'm doing wrong?

Kind regards

Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list

[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev





Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: JIT doens't resolve address

Romanenkov Kirill via cfe-dev
Hmm, I tried using your code (copy+pasted and then mass-dumped headers to fix includes), and it seems to work fine for me:


Do you get different results when using your LLVM? If not, can you identify the differences between your code and what I constructed from your snippets?

I noticed "PAUSE", are you on Windows? I'm not sure what the functionality/status of the JIT on Windows is, perhaps someone else can comment on that.

~Will

On Fri, Apr 21, 2017 at 1:03 AM, via cfe-dev <[hidden email]> wrote:
Hello Lang,

the Code for my jit_main is a normal printf-HelloWorld program. I opended the file with notepad and found the following:

; Function Attrs: noinline norecurse uwtable
define i32 @main() #0 {
entry:
  %retval = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([35 x i8], [35 x i8]* @"\01??_C@_0CD@CMJEAMCD@Planschbeckilein?5sagt?5Halloilein@", i32 0, i32 0))
  %call1 = call i32 @system(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @"\01??_C@_05DIAHPDGL@PAUSE?$AA@", i32 0, i32 0))
  ret i32 0
}


So... there is a main... Anyway! The code for the main is this one:
#include <stdio.h>
#include <stdlib.h>

int main()
{
        printf("Planschbeckilein sagt Halloilein!\n");
        system("PAUSE");

        return 0;
}


Kind regards
Björn



From:        Lang Hames <[hidden email]>
To:        [hidden email]
Cc:        Clang Dev <[hidden email]>
Date:        20.04.2017 22:54
Subject:        Re: [cfe-dev] JIT doens't resolve address




Hi Bjoern,

Sorry - I just noticed that the address for your "main" function has come back as '0'. In this case the answer is even simpler: The JIT never found the function at all, and so definitely didn't have any external symbols to resolve, so it never called the resolver.

A failure to find main has three likely causes:

(1) jit_main.ll does not define main,
(2) jit_main.ll defines main with private/internal linkage (the JIT can't see private/internal symbols in general)
(3) jit_main.ll defines main with external linkage, but a system mangling is applied (e.g. on MacOSX 'main' is mangled to '_main'). The mangler code in your findSymbol function *should* correct for this, but this may fail if the default data layout for your TargetMachine varies from the Module's DataLayout.

Can you share the contents of your jit_main.ll Module?

Cheers,
Lang.
   

On Thu, Apr 20, 2017 at 1:35 PM, Lang Hames <[hidden email]> wrote:
HI Bjoern,

There are two kinds of symbol lookup in the JIT:

(1) You want to find a symbol defined JIT'd code. This is what "findSymbol" on the JIT class does.

(2) The JIT wants to fix up a module that contains references to symbols defined elsewhere (either in your program, or in other JIT'd code). This is the SymbolResolver's job.

So assuming your main function in main.ll is trivial, e.g.

int main() {
  return 0;
}

then your findSymbol call will return the address of the JIT'd main without ever needing to look anything up in the resolver.

If, on the other hand, your main function contains an external reference, e.g.

int main() {
  printf("Hello, World!"); // Reference to externally defined function printf.
  return 0;
}

Then you'll receive a call back on your resolver looking for the address of printf.

Hope this helps!

Cheers,
Lang.

On Thu, Apr 20, 2017 at 6:43 AM, via cfe-dev <[hidden email]> wrote:
Hello LLVM-World,

I was following the "Building a JIT in LLVM"-Tutorial and tried to load a normal main. My code is the following:
class Jitter
{

private
:
  std::
unique_ptr<TargetMachine> TM;
 
const DataLayout DL;
 
ObjectLinkingLayer<> ObjectLayer;
 
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;

public
:
 
typedef decltype(CompileLayer)::ModuleSetHandleT ModuleHandle;

  Jitter() : TM(
EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
      CompileLayer(ObjectLayer,
SimpleCompiler(*TM))
  {printf(
"!");
        llvm::sys::
DynamicLibrary::LoadLibraryPermanently(nullptr);
  }


 
TargetMachine &getTargetMachine() { return *TM; }

 
ModuleHandle addModule(std::unique_ptr<Module> &&M) {
 
// Build our symbol resolver:
 
// Lambda 1: Look back into the JIT itself to find symbols that are part of
 
//           the same "logical dylib".
 
// Lambda 2: Search for external symbols in the host process.
 
auto Resolver = createLambdaResolver(
      [&](
const std::string &Name)
      {

                printf(
"FLUSH :0\n");

       
if (auto Sym = CompileLayer.findSymbol(Name, false))
         
return Sym;
       
return JITSymbol(nullptr);
      },

      [](
const std::string &S)
          {

                  printf(
"PLUSH :0\n");

       
if (auto SymAddr =
             
RTDyldMemoryManager::getSymbolAddressInProcess(S))
         
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
       
return JITSymbol(nullptr);
      });


 
// Build a singleton module set to hold our module.
  std::
vector<std::unique_ptr<Module>> Ms;
  Ms.push_back(std::move(
M));

 
// Add the set to the JIT with the resolver we created above and a newly
 
// created SectionMemoryManager.
 
return CompileLayer.addModuleSet(std::move(Ms),
                                   make_unique<
SectionMemoryManager>(),
                                   std::move(Resolver));

}


JITSymbol
findSymbol(const std::string Name) {
  std::
string MangledName;
 
raw_string_ostream MangledNameStream(MangledName);
 
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
  printf(
"Tzearch for: %s\n\n", MangledNameStream.str());
 
return CompileLayer.findSymbol(MangledNameStream.str(), false);
}


void
removeModule(ModuleHandle H) {
  CompileLayer.removeModuleSet(
H);
}


};



And calling from main with:
int main()
{

        llvm::InitializeNativeTarget();

        llvm::InitializeNativeTargetAsmPrinter();

        llvm::InitializeNativeTargetAsmParser();


        llvm::
LLVMContext context;
        llvm::
SMDiagnostic dia;

        std::
unique_ptr<llvm::Module> M = llvm::parseIRFile("./jit_main.ll", dia, context);
       
Jitter jit;
        printf(
"Wuff?");
       
Jitter::ModuleHandle h = jit.addModule(std::move(M));
        printf(
"KNUFF!\n");

        printf(
"Kuchen! 0x%p\n", jit.findSymbol("main").getAddress());

        system(
"PAUSE");
       
return 0;
}


The Code runs without a fail, but when the programm tries to resolve "main" the address is 0. The strange thing: the printf "
FLUSH :0\n" and "PLUSH :0\n" are never called, so did the code never compiled? What I'm doing wrong?

Kind regards

Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list

[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev





Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev



_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: JIT doens't resolve address - Resolve obj-Addresses?

Romanenkov Kirill via cfe-dev
Hello Mr. Dietz,

I tried using your code and now it works! I'm happy and surprised! I will now compare the codes and try to spot the main difference! Thanks for your help!
Do you know if there is a way to directly load .obj-Files and resolve the references with own addresses? Like when somebody used printf in the generated obj-File, but I replace the address with my own printf?

Kind regards
Björn



From:        Will Dietz <[hidden email]>
To:        [hidden email]
Cc:        Lang Hames <[hidden email]>, Clang Dev <[hidden email]>
Date:        21.04.2017 21:50
Subject:        Re: [cfe-dev] JIT doens't resolve address
Sent by:        [hidden email]




Hmm, I tried using your code (copy+pasted and then mass-dumped headers to fix includes), and it seems to work fine for me:

https://gist.github.com/dtzWill/df84b64a73001532e3fcfe73a2cffbb9#file-test-log

Do you get different results when using your LLVM? If not, can you identify the differences between your code and what I constructed from your snippets?

I noticed "PAUSE", are you on Windows? I'm not sure what the functionality/status of the JIT on Windows is, perhaps someone else can comment on that.

~Will

On Fri, Apr 21, 2017 at 1:03 AM, via cfe-dev <[hidden email]> wrote:
Hello Lang,

the Code for my jit_main is a normal printf-HelloWorld program. I opended the file with notepad and found the following:

; Function Attrs: noinline norecurse uwtable
define i32 @main() #0 {

entry:

  %retval = alloca i32, align 4

  store i32 0, i32* %retval, align 4

  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([35 x i8], [35 x i8]* @"\01??_C@_0CD@CMJEAMCD@Planschbeckilein?5sagt?5Halloilein@", i32 0, i32 0))

  %call1 = call i32 @system(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @"\01??_C@_05DIAHPDGL@PAUSE?$AA@", i32 0, i32 0))

  ret i32 0

}



So... there is a main... Anyway! The code for the main is this one:
#include <stdio.h>
#include
<stdlib.h>

int
main()
{

        printf(
"Planschbeckilein sagt Halloilein!\n");
        system(
"PAUSE");

       
return 0;
}



Kind regards

Björn




From:        
Lang Hames <lhames@...>
To:        
bjoern.gaier@...
Cc:        
Clang Dev <[hidden email]>
Date:        
20.04.2017 22:54
Subject:        
Re: [cfe-dev] JIT doens't resolve address





Hi Bjoern,

Sorry - I just noticed that the address for your "main" function has come back as '0'. In this case the answer is even simpler: The JIT never found the function at all, and so definitely didn't have any external symbols to resolve, so it never called the resolver.

A failure to find main has three likely causes:

(1) jit_main.ll does not define main,
(2) jit_main.ll defines main with private/internal linkage (the JIT can't see private/internal symbols in general)
(3) jit_main.ll defines main with external linkage, but a system mangling is applied (e.g. on MacOSX 'main' is mangled to '_main'). The mangler code in your findSymbol function *should* correct for this, but this may fail if the default data layout for your TargetMachine varies from the Module's DataLayout.

Can you share the contents of your jit_main.ll Module?

Cheers,
Lang.
   

On Thu, Apr 20, 2017 at 1:35 PM, Lang Hames <
lhames@...> wrote:
HI Bjoern,

There are two kinds of symbol lookup in the JIT:

(1) You want to find a symbol defined JIT'd code. This is what "findSymbol" on the JIT class does.

(2) The JIT wants to fix up a module that contains references to symbols defined elsewhere (either in your program, or in other JIT'd code). This is the SymbolResolver's job.

So assuming your main function in main.ll is trivial, e.g.

int main() {

  return 0;

}


then your findSymbol call will return the address of the JIT'd main without ever needing to look anything up in the resolver.

If, on the other hand, your main function contains an external reference, e.g.

int main() {

  printf("Hello, World!"); // Reference to externally defined function printf.

  return 0;

}


Then you'll receive a call back on your resolver looking for the address of printf.

Hope this helps!

Cheers,
Lang.

On Thu, Apr 20, 2017 at 6:43 AM, via cfe-dev <
[hidden email]> wrote:
Hello LLVM-World,


I was following the "Building a JIT in LLVM"-Tutorial and tried to load a normal main. My code is the following:
class Jitter
{

private
:
  std::
unique_ptr<TargetMachine> TM;
 
const DataLayout DL;
 
ObjectLinkingLayer<> ObjectLayer;
 
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;

public
:
 
typedef decltype(CompileLayer)::ModuleSetHandleT ModuleHandle;

  Jitter() : TM(
EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
      CompileLayer(ObjectLayer,
SimpleCompiler(*TM))
  {printf(
"!");
        llvm::sys::
DynamicLibrary::LoadLibraryPermanently(nullptr);
  }


 
TargetMachine &getTargetMachine() { return *TM; }

 
ModuleHandle addModule(std::unique_ptr<Module> &&M) {
 
// Build our symbol resolver:
 
// Lambda 1: Look back into the JIT itself to find symbols that are part of
 
//           the same "logical dylib".
 
// Lambda 2: Search for external symbols in the host process.
 
auto Resolver = createLambdaResolver(
      [&](
const std::string &Name)
      {

                printf(
"FLUSH :0\n");

       
if (auto Sym = CompileLayer.findSymbol(Name, false))
         
return Sym;
       
return JITSymbol(nullptr);
      },

      [](
const std::string &S)
          {

                  printf(
"PLUSH :0\n");

       
if (auto SymAddr =
             
RTDyldMemoryManager::getSymbolAddressInProcess(S))
         
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
       
return JITSymbol(nullptr);
      });


 
// Build a singleton module set to hold our module.
  std::
vector<std::unique_ptr<Module>> Ms;
  Ms.push_back(std::move(
M));

 
// Add the set to the JIT with the resolver we created above and a newly
 
// created SectionMemoryManager.
 
return CompileLayer.addModuleSet(std::move(Ms),
                                   make_unique<
SectionMemoryManager>(),
                                   std::move(Resolver));

}


JITSymbol
findSymbol(const std::string Name) {
  std::
string MangledName;
 
raw_string_ostream MangledNameStream(MangledName);
 
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
  printf(
"Tzearch for: %s\n\n", MangledNameStream.str());
 
return CompileLayer.findSymbol(MangledNameStream.str(), false);
}


void
removeModule(ModuleHandle H) {
  CompileLayer.removeModuleSet(
H);
}


};




And calling from main with:
int main()
{

        llvm::InitializeNativeTarget();

        llvm::InitializeNativeTargetAsmPrinter();

        llvm::InitializeNativeTargetAsmParser();


        llvm::
LLVMContext context;
        llvm::
SMDiagnostic dia;

        std::
unique_ptr<llvm::Module> M = llvm::parseIRFile("./jit_main.ll", dia, context);
       
Jitter jit;
        printf(
"Wuff?");
       
Jitter::ModuleHandle h = jit.addModule(std::move(M));
        printf(
"KNUFF!\n");

        printf(
"Kuchen! 0x%p\n", jit.findSymbol("main").getAddress());

        system(
"PAUSE");
       
return 0;
}



The Code runs without a fail, but when the programm tries to resolve "main" the address is 0. The strange thing: the printf "
FLUSH :0\n" and "PLUSH :0\n" are never called, so did the code never compiled? What I'm doing wrong?

Kind regards

Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list

[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev





Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.


_______________________________________________
cfe-dev mailing list

[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: JIT doens't resolve address

Romanenkov Kirill via cfe-dev
In reply to this post by Romanenkov Kirill via cfe-dev
Hi Björn,

Does the module containing your main function have a triple or data layout? There should be a couple of lines at the top of the module that look like:

target data layout = "..."
target triple = "..."

If these lines are missing (especially the data layout) then the problem might be name mangling: findSymbol is applying the default system specific mangling (which on Windows may include prefixes), but the module is being compiled without mangling.

Can you share the header for your module?
Could you also modify your JIT to print DL.getStringRepresentation() in the constructor and share this?

These should match.

Cheers,
Lang.


On Fri, Apr 21, 2017 at 12:50 PM, Will Dietz <[hidden email]> wrote:
Hmm, I tried using your code (copy+pasted and then mass-dumped headers to fix includes), and it seems to work fine for me:


Do you get different results when using your LLVM? If not, can you identify the differences between your code and what I constructed from your snippets?

I noticed "PAUSE", are you on Windows? I'm not sure what the functionality/status of the JIT on Windows is, perhaps someone else can comment on that.

~Will

On Fri, Apr 21, 2017 at 1:03 AM, via cfe-dev <[hidden email]> wrote:
Hello Lang,

the Code for my jit_main is a normal printf-HelloWorld program. I opended the file with notepad and found the following:

; Function Attrs: noinline norecurse uwtable
define i32 @main() #0 {
entry:
  %retval = alloca i32, align 4
  store i32 0, i32* %retval, align 4
  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([35 x i8], [35 x i8]* @"\01??_C@_0CD@CMJEAMCD@Planschbeckilein?5sagt?5Halloilein@", i32 0, i32 0))
  %call1 = call i32 @system(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @"\01??_C@_05DIAHPDGL@PAUSE?$AA@", i32 0, i32 0))
  ret i32 0
}


So... there is a main... Anyway! The code for the main is this one:
#include <stdio.h>
#include <stdlib.h>

int main()
{
        printf("Planschbeckilein sagt Halloilein!\n");
        system("PAUSE");

        return 0;
}


Kind regards
Björn



From:        Lang Hames <[hidden email]>
To:        [hidden email]
Cc:        Clang Dev <[hidden email]>
Date:        20.04.2017 22:54
Subject:        Re: [cfe-dev] JIT doens't resolve address




Hi Bjoern,

Sorry - I just noticed that the address for your "main" function has come back as '0'. In this case the answer is even simpler: The JIT never found the function at all, and so definitely didn't have any external symbols to resolve, so it never called the resolver.

A failure to find main has three likely causes:

(1) jit_main.ll does not define main,
(2) jit_main.ll defines main with private/internal linkage (the JIT can't see private/internal symbols in general)
(3) jit_main.ll defines main with external linkage, but a system mangling is applied (e.g. on MacOSX 'main' is mangled to '_main'). The mangler code in your findSymbol function *should* correct for this, but this may fail if the default data layout for your TargetMachine varies from the Module's DataLayout.

Can you share the contents of your jit_main.ll Module?

Cheers,
Lang.
   

On Thu, Apr 20, 2017 at 1:35 PM, Lang Hames <[hidden email]> wrote:
HI Bjoern,

There are two kinds of symbol lookup in the JIT:

(1) You want to find a symbol defined JIT'd code. This is what "findSymbol" on the JIT class does.

(2) The JIT wants to fix up a module that contains references to symbols defined elsewhere (either in your program, or in other JIT'd code). This is the SymbolResolver's job.

So assuming your main function in main.ll is trivial, e.g.

int main() {
  return 0;
}

then your findSymbol call will return the address of the JIT'd main without ever needing to look anything up in the resolver.

If, on the other hand, your main function contains an external reference, e.g.

int main() {
  printf("Hello, World!"); // Reference to externally defined function printf.
  return 0;
}

Then you'll receive a call back on your resolver looking for the address of printf.

Hope this helps!

Cheers,
Lang.

On Thu, Apr 20, 2017 at 6:43 AM, via cfe-dev <[hidden email]> wrote:
Hello LLVM-World,

I was following the "Building a JIT in LLVM"-Tutorial and tried to load a normal main. My code is the following:
class Jitter
{

private
:
  std::
unique_ptr<TargetMachine> TM;
 
const DataLayout DL;
 
ObjectLinkingLayer<> ObjectLayer;
 
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;

public
:
 
typedef decltype(CompileLayer)::ModuleSetHandleT ModuleHandle;

  Jitter() : TM(
EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
      CompileLayer(ObjectLayer,
SimpleCompiler(*TM))
  {printf(
"!");
        llvm::sys::
DynamicLibrary::LoadLibraryPermanently(nullptr);
  }


 
TargetMachine &getTargetMachine() { return *TM; }

 
ModuleHandle addModule(std::unique_ptr<Module> &&M) {
 
// Build our symbol resolver:
 
// Lambda 1: Look back into the JIT itself to find symbols that are part of
 
//           the same "logical dylib".
 
// Lambda 2: Search for external symbols in the host process.
 
auto Resolver = createLambdaResolver(
      [&](
const std::string &Name)
      {

                printf(
"FLUSH :0\n");

       
if (auto Sym = CompileLayer.findSymbol(Name, false))
         
return Sym;
       
return JITSymbol(nullptr);
      },

      [](
const std::string &S)
          {

                  printf(
"PLUSH :0\n");

       
if (auto SymAddr =
             
RTDyldMemoryManager::getSymbolAddressInProcess(S))
         
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
       
return JITSymbol(nullptr);
      });


 
// Build a singleton module set to hold our module.
  std::
vector<std::unique_ptr<Module>> Ms;
  Ms.push_back(std::move(
M));

 
// Add the set to the JIT with the resolver we created above and a newly
 
// created SectionMemoryManager.
 
return CompileLayer.addModuleSet(std::move(Ms),
                                   make_unique<
SectionMemoryManager>(),
                                   std::move(Resolver));

}


JITSymbol
findSymbol(const std::string Name) {
  std::
string MangledName;
 
raw_string_ostream MangledNameStream(MangledName);
 
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
  printf(
"Tzearch for: %s\n\n", MangledNameStream.str());
 
return CompileLayer.findSymbol(MangledNameStream.str(), false);
}


void
removeModule(ModuleHandle H) {
  CompileLayer.removeModuleSet(
H);
}


};



And calling from main with:
int main()
{

        llvm::InitializeNativeTarget();

        llvm::InitializeNativeTargetAsmPrinter();

        llvm::InitializeNativeTargetAsmParser();


        llvm::
LLVMContext context;
        llvm::
SMDiagnostic dia;

        std::
unique_ptr<llvm::Module> M = llvm::parseIRFile("./jit_main.ll", dia, context);
       
Jitter jit;
        printf(
"Wuff?");
       
Jitter::ModuleHandle h = jit.addModule(std::move(M));
        printf(
"KNUFF!\n");

        printf(
"Kuchen! 0x%p\n", jit.findSymbol("main").getAddress());

        system(
"PAUSE");
       
return 0;
}


The Code runs without a fail, but when the programm tries to resolve "main" the address is 0. The strange thing: the printf "
FLUSH :0\n" and "PLUSH :0\n" are never called, so did the code never compiled? What I'm doing wrong?

Kind regards

Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list

[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev





Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev




_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: JIT doens't resolve address - Resolve obj-Addresses?

Romanenkov Kirill via cfe-dev
In reply to this post by Romanenkov Kirill via cfe-dev
Hi Björn,

I tried using your code and now it works! I'm happy and surprised!

Oh - I missed that Will's code had fixed your issue. That's great. :)

Do you know if there is a way to directly load .obj-Files and resolve the references with own addresses? Like when somebody used printf in the generated obj-File, but I replace the address with my own printf? 

You can load precompiled object files by calling addObjectSet on the ObjectLayer.

All external symbol references are resolved by the JITSymbolResolver that is created by createLambdaResolver. In your example the resolution process is two-step: First the JIT searches its own function definitions to see if there is a function called "printf" defined there (this is what the call to CompileLayer.findSymbol does):

[&](const std::string &Name)  {
  printf("FLUSH :0\n");
  if (auto Sym = CompileLayer.findSymbol(Name, false))
    return Sym;
  return JITSymbol(nullptr);
}

Then, if it doesn't find a definition there, it falls back to searching in the current process (this is what RTDyldMemoryManager::getSymbolAddressInProcess does):

[](const std::string &S)  { 
  printf("PLUSH :0\n"); 
  if (auto SymAddr = 
        RTDyldMemoryManager::getSymbolAddressInProcess(S)) 
    return JITSymbol(SymAddr, JITSymbolFlags::Exported); 
  return JITSymbol(nullptr); 
}

If, for example, you wanted to redirect calls to printf to your own custom version (while resolving all other externals by the normal process) you could change the second lambda like so:

[](const std::string &S)  { 
  printf("PLUSH :0\n");
  if (S == mangleName("printf"))
    return JITSymbol((JITSymbolAddress)&myCustomPrintf,
                     JITSymbolFlags::Exported);
  if (auto SymAddr = 
        RTDyldMemoryManager::getSymbolAddressInProcess(S)) 
    return JITSymbol(SymAddr, JITSymbolFlags::Exported); 
  return JITSymbol(nullptr); 
}

(You'll just have to pull the mangling logic from findSymbol out into its own "mangleName" function for this).

Hope this helps.

Cheers,
Lang.


On Sun, Apr 23, 2017 at 11:08 PM, <[hidden email]> wrote:
Hello Mr. Dietz,

I tried using your code and now it works! I'm happy and surprised! I will now compare the codes and try to spot the main difference! Thanks for your help!
Do you know if there is a way to directly load .obj-Files and resolve the references with own addresses? Like when somebody used printf in the generated obj-File, but I replace the address with my own printf?

Kind regards
Björn



From:        Will Dietz <[hidden email]>
To:        [hidden email]
Cc:        Lang Hames <[hidden email]>, Clang Dev <[hidden email]>
Date:        21.04.2017 21:50
Subject:        Re: [cfe-dev] JIT doens't resolve address
Sent by:        [hidden email]




Hmm, I tried using your code (copy+pasted and then mass-dumped headers to fix includes), and it seems to work fine for me:

https://gist.github.com/dtzWill/df84b64a73001532e3fcfe73a2cffbb9#file-test-log

Do you get different results when using your LLVM? If not, can you identify the differences between your code and what I constructed from your snippets?

I noticed "PAUSE", are you on Windows? I'm not sure what the functionality/status of the JIT on Windows is, perhaps someone else can comment on that.

~Will

On Fri, Apr 21, 2017 at 1:03 AM, via cfe-dev <[hidden email]> wrote:
Hello Lang,

the Code for my jit_main is a normal printf-HelloWorld program. I opended the file with notepad and found the following:

; Function Attrs: noinline norecurse uwtable
define i32 @main() #0 {

entry:

  %retval = alloca i32, align 4

  store i32 0, i32* %retval, align 4

  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([35 x i8], [35 x i8]* @"\01??_C@_0CD@CMJEAMCD@Planschbeckilein?5sagt?5Halloilein@", i32 0, i32 0))

  %call1 = call i32 @system(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @"\01??_C@_05DIAHPDGL@PAUSE?$AA@", i32 0, i32 0))

  ret i32 0

}



So... there is a main... Anyway! The code for the main is this one:
#include <stdio.h>
#include
<stdlib.h>

int
main()
{

        printf(
"Planschbeckilein sagt Halloilein!\n");
        system(
"PAUSE");

       
return 0;
}



Kind regards

Björn




From:        
Lang Hames <[hidden email]>
To:        
[hidden email]
Cc:        
Clang Dev <[hidden email]>
Date:        
20.04.2017 22:54
Subject:        
Re: [cfe-dev] JIT doens't resolve address





Hi Bjoern,

Sorry - I just noticed that the address for your "main" function has come back as '0'. In this case the answer is even simpler: The JIT never found the function at all, and so definitely didn't have any external symbols to resolve, so it never called the resolver.

A failure to find main has three likely causes:

(1) jit_main.ll does not define main,
(2) jit_main.ll defines main with private/internal linkage (the JIT can't see private/internal symbols in general)
(3) jit_main.ll defines main with external linkage, but a system mangling is applied (e.g. on MacOSX 'main' is mangled to '_main'). The mangler code in your findSymbol function *should* correct for this, but this may fail if the default data layout for your TargetMachine varies from the Module's DataLayout.

Can you share the contents of your jit_main.ll Module?

Cheers,
Lang.
   

On Thu, Apr 20, 2017 at 1:35 PM, Lang Hames <
[hidden email]> wrote:
HI Bjoern,

There are two kinds of symbol lookup in the JIT:

(1) You want to find a symbol defined JIT'd code. This is what "findSymbol" on the JIT class does.

(2) The JIT wants to fix up a module that contains references to symbols defined elsewhere (either in your program, or in other JIT'd code). This is the SymbolResolver's job.

So assuming your main function in main.ll is trivial, e.g.

int main() {

  return 0;

}


then your findSymbol call will return the address of the JIT'd main without ever needing to look anything up in the resolver.

If, on the other hand, your main function contains an external reference, e.g.

int main() {

  printf("Hello, World!"); // Reference to externally defined function printf.

  return 0;

}


Then you'll receive a call back on your resolver looking for the address of printf.

Hope this helps!

Cheers,
Lang.

On Thu, Apr 20, 2017 at 6:43 AM, via cfe-dev <
[hidden email]> wrote:
Hello LLVM-World,


I was following the "Building a JIT in LLVM"-Tutorial and tried to load a normal main. My code is the following:
class Jitter
{

private
:
  std::
unique_ptr<TargetMachine> TM;
 
const DataLayout DL;
 
ObjectLinkingLayer<> ObjectLayer;
 
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;

public
:
 
typedef decltype(CompileLayer)::ModuleSetHandleT ModuleHandle;

  Jitter() : TM(
EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
      CompileLayer(ObjectLayer,
SimpleCompiler(*TM))
  {printf(
"!");
        llvm::sys::
DynamicLibrary::LoadLibraryPermanently(nullptr);
  }


 
TargetMachine &getTargetMachine() { return *TM; }

 
ModuleHandle addModule(std::unique_ptr<Module> &&M) {
 
// Build our symbol resolver:
 
// Lambda 1: Look back into the JIT itself to find symbols that are part of
 
//           the same "logical dylib".
 
// Lambda 2: Search for external symbols in the host process.
 
auto Resolver = createLambdaResolver(
      [&](
const std::string &Name)
      {

                printf(
"FLUSH :0\n");

       
if (auto Sym = CompileLayer.findSymbol(Name, false))
         
return Sym;
       
return JITSymbol(nullptr);
      },

      [](
const std::string &S)
          {

                  printf(
"PLUSH :0\n");

       
if (auto SymAddr =
             
RTDyldMemoryManager::getSymbolAddressInProcess(S))
         
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
       
return JITSymbol(nullptr);
      });


 
// Build a singleton module set to hold our module.
  std::
vector<std::unique_ptr<Module>> Ms;
  Ms.push_back(std::move(
M));

 
// Add the set to the JIT with the resolver we created above and a newly
 
// created SectionMemoryManager.
 
return CompileLayer.addModuleSet(std::move(Ms),
                                   make_unique<
SectionMemoryManager>(),
                                   std::move(Resolver));

}


JITSymbol
findSymbol(const std::string Name) {
  std::
string MangledName;
 
raw_string_ostream MangledNameStream(MangledName);
 
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
  printf(
"Tzearch for: %s\n\n", MangledNameStream.str());
 
return CompileLayer.findSymbol(MangledNameStream.str(), false);
}


void
removeModule(ModuleHandle H) {
  CompileLayer.removeModuleSet(
H);
}


};




And calling from main with:
int main()
{

        llvm::InitializeNativeTarget();

        llvm::InitializeNativeTargetAsmPrinter();

        llvm::InitializeNativeTargetAsmParser();


        llvm::
LLVMContext context;
        llvm::
SMDiagnostic dia;

        std::
unique_ptr<llvm::Module> M = llvm::parseIRFile("./jit_main.ll", dia, context);
       
Jitter jit;
        printf(
"Wuff?");
       
Jitter::ModuleHandle h = jit.addModule(std::move(M));
        printf(
"KNUFF!\n");

        printf(
"Kuchen! 0x%p\n", jit.findSymbol("main").getAddress());

        system(
"PAUSE");
       
return 0;
}



The Code runs without a fail, but when the programm tries to resolve "main" the address is 0. The strange thing: the printf "
FLUSH :0\n" and "PLUSH :0\n" are never called, so did the code never compiled? What I'm doing wrong?

Kind regards

Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list

[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev





Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.


_______________________________________________
cfe-dev mailing list

[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: JIT doens't resolve address - Resolve obj-Addresses?

Romanenkov Kirill via cfe-dev
Hi Bjoern,

CCing cfg-dev (since that's where the conversation started) and llvm-dev (since it's relevant there).

Do you know if there is a way to obtain the fully resolved obj-code? I wanted to load the functions into a shared memory, but how? The only thing I receive is a function pointer, but I don't know how large the function 'behind' is. Even a call to _msize (windows) does only resolve in a crash. 

You can access the fully-resolved object code on a per-section basis (there is no easy way to do it per-function) by using a custom memory manager, rather than SectionMemoryManager.

There are two ways to go about this:

(1) The easy way (only valid for shared-memory on the same machine) is to allocate the sections directly out of shared memory (by overriding allocateCodeSection/allocateDataSection).

(2) The hard way (which is general enough to allow you to copy the relocated bytes to remote machines) is three part:
(a) Allocate the sections locally (e.g. using malloc, or inheriting from SectionMemoryManager and capturing the allocation details)
(b) Override the notifyObjectLoaded method to allocate the final memory locations, then call RTDyldMemoryManager::mapSectionAddress to map each local allocation to its corresponding final address
(c) Override finalizeMemory to copy the relocated bytes to their final addresses

Hope this helps.

Cheers,
Lang.




On Tue, May 2, 2017 at 10:47 PM, <[hidden email]> wrote:
Hello Lang,

your answer explained a lot to me, thank you for that. Do you know if there is a way to obtain the fully resolved obj-code? I wanted to load the functions into a shared memory, but how? The only thing I receive is a function pointer, but I don't know how large the function 'behind' is. Even a call to _msize (windows) does only resolve in a crash.

Kind regards
Björn



From:        Lang Hames <[hidden email]>
To:        [hidden email]
Cc:        [hidden email], Clang Dev <[hidden email]>
Date:        01.05.2017 20:15
Subject:        Re: [cfe-dev] JIT doens't resolve address - Resolve obj-Addresses?




Hi Björn,

I tried using your code and now it works! I'm happy and surprised!

Oh - I missed that Will's code had fixed your issue. That's great. :)

Do you know if there is a way to directly load .obj-Files and resolve the references with own addresses? Like when somebody used printf in the generated obj-File, but I replace the address with my own printf? 

You can load precompiled object files by calling addObjectSet on the ObjectLayer.

All external symbol references are resolved by the JITSymbolResolver that is created by createLambdaResolver. In your example the resolution process is two-step: First the JIT searches its own function definitions to see if there is a function called "printf" defined there (this is what the call to CompileLayer.findSymbol does):

[&](const std::string &Name)  {
  printf("FLUSH :0\n");
  if (auto Sym = CompileLayer.findSymbol(Name, false))
    return Sym;
  return JITSymbol(nullptr);
}

Then, if it doesn't find a definition there, it falls back to searching in the current process (this is what RTDyldMemoryManager::getSymbolAddressInProcess does):

[](const std::string &S)  { 
  printf("PLUSH :0\n"); 
  if (auto SymAddr = 
        RTDyldMemoryManager::getSymbolAddressInProcess(S)) 
    return JITSymbol(SymAddr, JITSymbolFlags::Exported); 
  return JITSymbol(nullptr); 
}

If, for example, you wanted to redirect calls to printf to your own custom version (while resolving all other externals by the normal process) you could change the second lambda like so:

[](const std::string &S)  { 
  printf("PLUSH :0\n");
  if (S == mangleName("printf"))
    return JITSymbol((JITSymbolAddress)&myCustomPrintf,
                     JITSymbolFlags::Exported);
  if (auto SymAddr = 
        RTDyldMemoryManager::getSymbolAddressInProcess(S)) 
    return JITSymbol(SymAddr, JITSymbolFlags::Exported); 
  return JITSymbol(nullptr); 
}

(You'll just have to pull the mangling logic from findSymbol out into its own "mangleName" function for this).

Hope this helps.

Cheers,
Lang.


On Sun, Apr 23, 2017 at 11:08 PM, <[hidden email]> wrote:
Hello Mr. Dietz,

I tried using your code and now it works! I'm happy and surprised! I will now compare the codes and try to spot the main difference! Thanks for your help!

Do you know if there is a way to directly load .obj-Files and resolve the references with own addresses? Like when somebody used printf in the generated obj-File, but I replace the address with my own printf?


Kind regards

Björn




From:        
Will Dietz <[hidden email]>
To:        
[hidden email]
Cc:        
Lang Hames <[hidden email]>, Clang Dev <[hidden email]>
Date:        
21.04.2017 21:50
Subject:        
Re: [cfe-dev] JIT doens't resolve address
Sent by:        
[hidden email]




Hmm, I tried using your code (copy+pasted and then mass-dumped headers to fix includes), and it seems to work fine for me:

https://gist.github.com/dtzWill/df84b64a73001532e3fcfe73a2cffbb9#file-test-log

Do you get different results when using your LLVM? If not, can you identify the differences between your code and what I constructed from your snippets?

I noticed "PAUSE", are you on Windows? I'm not sure what the functionality/status of the JIT on Windows is, perhaps someone else can comment on that.

~Will

On Fri, Apr 21, 2017 at 1:03 AM, via cfe-dev <
[hidden email]> wrote:
Hello Lang,


the Code for my jit_main is a normal printf-HelloWorld program. I opended the file with notepad and found the following:
; Function Attrs: noinline norecurse uwtable
define i32 @main() #0 {

entry:

  %retval = alloca i32, align 4

  store i32 0, i32* %retval, align 4

  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([35 x i8], [35 x i8]* @"\01??_C@_0CD@CMJEAMCD@Planschbeckilein?5sagt?5Halloilein@", i32 0, i32 0))

  %call1 = call i32 @system(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @"\01??_C@_05DIAHPDGL@PAUSE?$AA@", i32 0, i32 0))

  ret i32 0

}




So... there is a main... Anyway! The code for the main is this one:
#include <stdio.h>
#include
<stdlib.h>

int
main()
{

        printf(
"Planschbeckilein sagt Halloilein!\n");
        system(
"PAUSE");

       
return 0;
}




Kind regards

Björn




From:        
Lang Hames <[hidden email]>
To:        
[hidden email]
Cc:        
Clang Dev <[hidden email]>
Date:        
20.04.2017 22:54
Subject:        
Re: [cfe-dev] JIT doens't resolve address





Hi Bjoern,

Sorry - I just noticed that the address for your "main" function has come back as '0'. In this case the answer is even simpler: The JIT never found the function at all, and so definitely didn't have any external symbols to resolve, so it never called the resolver.

A failure to find main has three likely causes:

(1) jit_main.ll does not define main,
(2) jit_main.ll defines main with private/internal linkage (the JIT can't see private/internal symbols in general)
(3) jit_main.ll defines main with external linkage, but a system mangling is applied (e.g. on MacOSX 'main' is mangled to '_main'). The mangler code in your findSymbol function *should* correct for this, but this may fail if the default data layout for your TargetMachine varies from the Module's DataLayout.

Can you share the contents of your jit_main.ll Module?

Cheers,
Lang.
   

On Thu, Apr 20, 2017 at 1:35 PM, Lang Hames <
[hidden email]> wrote:
HI Bjoern,

There are two kinds of symbol lookup in the JIT:

(1) You want to find a symbol defined JIT'd code. This is what "findSymbol" on the JIT class does.

(2) The JIT wants to fix up a module that contains references to symbols defined elsewhere (either in your program, or in other JIT'd code). This is the SymbolResolver's job.

So assuming your main function in main.ll is trivial, e.g.


int main() {

  return 0;

}


then your findSymbol call will return the address of the JIT'd main without ever needing to look anything up in the resolver.

If, on the other hand, your main function contains an external reference, e.g.


int main() {

  printf("Hello, World!"); // Reference to externally defined function printf.

  return 0;

}


Then you'll receive a call back on your resolver looking for the address of printf.

Hope this helps!

Cheers,
Lang.

On Thu, Apr 20, 2017 at 6:43 AM, via cfe-dev <
[hidden email]> wrote:
Hello LLVM-World,


I was following the "Building a JIT in LLVM"-Tutorial and tried to load a normal main. My code is the following:
class Jitter
{

private
:
  std::
unique_ptr<TargetMachine> TM;
 
const DataLayout DL;
 
ObjectLinkingLayer<> ObjectLayer;
 
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;

public
:
 
typedef decltype(CompileLayer)::ModuleSetHandleT ModuleHandle;

  Jitter() : TM(
EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
      CompileLayer(ObjectLayer,
SimpleCompiler(*TM))
  {printf(
"!");
        llvm::sys::
DynamicLibrary::LoadLibraryPermanently(nullptr);
  }


 
TargetMachine &getTargetMachine() { return *TM; }

 
ModuleHandle addModule(std::unique_ptr<Module> &&M) {
 
// Build our symbol resolver:
 
// Lambda 1: Look back into the JIT itself to find symbols that are part of
 
//           the same "logical dylib".
 
// Lambda 2: Search for external symbols in the host process.
 
auto Resolver = createLambdaResolver(
      [&](
const std::string &Name)
      {

                printf(
"FLUSH :0\n");

       
if (auto Sym = CompileLayer.findSymbol(Name, false))
         
return Sym;
       
return JITSymbol(nullptr);
      },

      [](
const std::string &S)
          {

                  printf(
"PLUSH :0\n");

       
if (auto SymAddr =
             
RTDyldMemoryManager::getSymbolAddressInProcess(S))
         
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
       
return JITSymbol(nullptr);
      });


 
// Build a singleton module set to hold our module.
  std::
vector<std::unique_ptr<Module>> Ms;
  Ms.push_back(std::move(
M));

 
// Add the set to the JIT with the resolver we created above and a newly
 
// created SectionMemoryManager.
 
return CompileLayer.addModuleSet(std::move(Ms),
                                   make_unique<
SectionMemoryManager>(),
                                   std::move(Resolver));

}


JITSymbol
findSymbol(const std::string Name) {
  std::
string MangledName;
 
raw_string_ostream MangledNameStream(MangledName);
 
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
  printf(
"Tzearch for: %s\n\n", MangledNameStream.str());
 
return CompileLayer.findSymbol(MangledNameStream.str(), false);
}


void
removeModule(ModuleHandle H) {
  CompileLayer.removeModuleSet(
H);
}


};





And calling from main with:
int main()
{

        llvm::InitializeNativeTarget();

        llvm::InitializeNativeTargetAsmPrinter();

        llvm::InitializeNativeTargetAsmParser();


        llvm::
LLVMContext context;
        llvm::
SMDiagnostic dia;

        std::
unique_ptr<llvm::Module> M = llvm::parseIRFile("./jit_main.ll", dia, context);
       
Jitter jit;
        printf(
"Wuff?");
       
Jitter::ModuleHandle h = jit.addModule(std::move(M));
        printf(
"KNUFF!\n");

        printf(
"Kuchen! 0x%p\n", jit.findSymbol("main").getAddress());

        system(
"PAUSE");
       
return 0;
}




The Code runs without a fail, but when the programm tries to resolve "main" the address is 0. The strange thing: the printf "
FLUSH :0\n" and "PLUSH :0\n" are never called, so did the code never compiled? What I'm doing wrong?

Kind regards

Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list

[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev





Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.


_______________________________________________
cfe-dev mailing list

[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: JIT doens't resolve address - Resolve obj-Addresses?

Romanenkov Kirill via cfe-dev
Hello Lang,

thanks for your answer! With small steps I'm coming to my goal.

But I don't know what to do with "NotifyObjectLoaded". So I overloaded the function and can now access the sections. Soo... I allocate memory in my sharedmemory for the sections and use mapSectionAddress to change the addresses. But how do I copy the memory in the finalizeMemory method? I don't have access to the section anymore!
Plus, is there a way to reallocate global variables too, which aren't declared as extern - give them another memory location? I see these values with "symbols" in "NotifyObjectLoaded", but I don't have an address for them.
And... can I load .obj files, which Visual Studio had generated?

Kind regards
Björn



From:        Lang Hames <[hidden email]>
To:        [hidden email], Clang Dev <[hidden email]>, LLVM Developers Mailing List <[hidden email]>
Date:        07.05.2017 04:37
Subject:        Re: [cfe-dev] JIT doens't resolve address - Resolve obj-Addresses?




Hi Bjoern,

CCing cfg-dev (since that's where the conversation started) and llvm-dev (since it's relevant there).

Do you know if there is a way to obtain the fully resolved obj-code? I wanted to load the functions into a shared memory, but how? The only thing I receive is a function pointer, but I don't know how large the function 'behind' is. Even a call to _msize (windows) does only resolve in a crash. 

You can access the fully-resolved object code on a per-section basis (there is no easy way to do it per-function) by using a custom memory manager, rather than SectionMemoryManager.

There are two ways to go about this:

(1) The easy way (only valid for shared-memory on the same machine) is to allocate the sections directly out of shared memory (by overriding allocateCodeSection/allocateDataSection).

(2) The hard way (which is general enough to allow you to copy the relocated bytes to remote machines) is three part:
(a) Allocate the sections locally (e.g. using malloc, or inheriting from SectionMemoryManager and capturing the allocation details)
(b) Override the notifyObjectLoaded method to allocate the final memory locations, then call RTDyldMemoryManager::mapSectionAddress to map each local allocation to its corresponding final address
(c) Override finalizeMemory to copy the relocated bytes to their final addresses

Hope this helps.

Cheers,
Lang.




On Tue, May 2, 2017 at 10:47 PM, <bjoern.gaier@...> wrote:
Hello Lang,

your answer explained a lot to me, thank you for that. Do you know if there is a way to obtain the fully resolved obj-code? I wanted to load the functions into a shared memory, but how? The only thing I receive is a function pointer, but I don't know how large the function 'behind' is. Even a call to _msize (windows) does only resolve in a crash.


Kind regards

Björn




From:        
Lang Hames <lhames@...>
To:        
bjoern.gaier@...
Cc:        
willdtz@..., Clang Dev <[hidden email]>
Date:        
01.05.2017 20:15
Subject:        
Re: [cfe-dev] JIT doens't resolve address - Resolve obj-Addresses?





Hi Björn,

I tried using your code and now it works! I'm happy and surprised!

Oh - I missed that Will's code had fixed your issue. That's great. :)

Do you know if there is a way to directly load .obj-Files and resolve the references with own addresses? Like when somebody used printf in the generated obj-File, but I replace the address with my own printf? 

You can load precompiled object files by calling addObjectSet on the ObjectLayer.

All external symbol references are resolved by the JITSymbolResolver that is created by createLambdaResolver. In your example the resolution process is two-step: First the JIT searches its own function definitions to see if there is a function called "printf" defined there (this is what the call to CompileLayer.findSymbol does):

[&](const std::string &Name)  {

  printf("FLUSH :0\n");

  if (auto Sym = CompileLayer.findSymbol(Name, false))

    return Sym;

  return JITSymbol(nullptr);

}


Then, if it doesn't find a definition there, it falls back to searching in the current process (this is what RTDyldMemoryManager::getSymbolAddressInProcess does):

[](const std::string &S)  { 

  printf("PLUSH :0\n"); 

  if (auto SymAddr = 

        RTDyldMemoryManager::getSymbolAddressInProcess(S)) 

    return JITSymbol(SymAddr, JITSymbolFlags::Exported); 

  return JITSymbol(nullptr); 

}


If, for example, you wanted to redirect calls to printf to your own custom version (while resolving all other externals by the normal process) you could change the second lambda like so:

[](const std::string &S)  { 

  printf("PLUSH :0\n");

  if (S == mangleName("printf"))

    return JITSymbol((JITSymbolAddress)&myCustomPrintf,

                     JITSymbolFlags::Exported);

  if (auto SymAddr = 

        RTDyldMemoryManager::getSymbolAddressInProcess(S)) 

    return JITSymbol(SymAddr, JITSymbolFlags::Exported); 

  return JITSymbol(nullptr); 

}


(You'll just have to pull the mangling logic from findSymbol out into its own "mangleName" function for this).

Hope this helps.

Cheers,
Lang.


On Sun, Apr 23, 2017 at 11:08 PM, <
bjoern.gaier@...> wrote:
Hello Mr. Dietz,


I tried using your code and now it works! I'm happy and surprised! I will now compare the codes and try to spot the main difference! Thanks for your help!

Do you know if there is a way to directly load .obj-Files and resolve the references with own addresses? Like when somebody used printf in the generated obj-File, but I replace the address with my own printf?


Kind regards

Björn




From:        
Will Dietz <willdtz@...>
To:        
bjoern.gaier@...
Cc:        
Lang Hames <lhames@...>, Clang Dev <[hidden email]>
Date:        
21.04.2017 21:50
Subject:        
Re: [cfe-dev] JIT doens't resolve address
Sent by:        
w@...




Hmm, I tried using your code (copy+pasted and then mass-dumped headers to fix includes), and it seems to work fine for me:


https://gist.github.com/dtzWill/df84b64a73001532e3fcfe73a2cffbb9#file-test-log

Do you get different results when using your LLVM? If not, can you identify the differences between your code and what I constructed from your snippets?

I noticed "PAUSE", are you on Windows? I'm not sure what the functionality/status of the JIT on Windows is, perhaps someone else can comment on that.

~Will

On Fri, Apr 21, 2017 at 1:03 AM, via cfe-dev <
[hidden email]> wrote:
Hello Lang,


the Code for my jit_main is a normal printf-HelloWorld program. I opended the file with notepad and found the following:
; Function Attrs: noinline norecurse uwtable
define i32 @main() #0 {

entry:

  %retval = alloca i32, align 4

  store i32 0, i32* %retval, align 4

  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([35 x i8], [35 x i8]* @"\01??_C@_0CD@CMJEAMCD@Planschbeckilein?5sagt?5Halloilein@", i32 0, i32 0))

  %call1 = call i32 @system(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @"\01??_C@_05DIAHPDGL@PAUSE?$AA@", i32 0, i32 0))

  ret i32 0

}





So... there is a main... Anyway! The code for the main is this one:
#include <stdio.h>
#include
<stdlib.h>

int
main()
{

        printf(
"Planschbeckilein sagt Halloilein!\n");
        system(
"PAUSE");

       
return 0;
}





Kind regards

Björn




From:        
Lang Hames <lhames@...>
To:        
bjoern.gaier@...
Cc:        
Clang Dev <[hidden email]>
Date:        
20.04.2017 22:54
Subject:        
Re: [cfe-dev] JIT doens't resolve address





Hi Bjoern,

Sorry - I just noticed that the address for your "main" function has come back as '0'. In this case the answer is even simpler: The JIT never found the function at all, and so definitely didn't have any external symbols to resolve, so it never called the resolver.

A failure to find main has three likely causes:

(1) jit_main.ll does not define main,
(2) jit_main.ll defines main with private/internal linkage (the JIT can't see private/internal symbols in general)
(3) jit_main.ll defines main with external linkage, but a system mangling is applied (e.g. on MacOSX 'main' is mangled to '_main'). The mangler code in your findSymbol function *should* correct for this, but this may fail if the default data layout for your TargetMachine varies from the Module's DataLayout.

Can you share the contents of your jit_main.ll Module?

Cheers,
Lang.
   

On Thu, Apr 20, 2017 at 1:35 PM, Lang Hames <
lhames@...> wrote:
HI Bjoern,

There are two kinds of symbol lookup in the JIT:

(1) You want to find a symbol defined JIT'd code. This is what "findSymbol" on the JIT class does.

(2) The JIT wants to fix up a module that contains references to symbols defined elsewhere (either in your program, or in other JIT'd code). This is the SymbolResolver's job.

So assuming your main function in main.ll is trivial, e.g.


int main() {

  return 0;

}


then your findSymbol call will return the address of the JIT'd main without ever needing to look anything up in the resolver.

If, on the other hand, your main function contains an external reference, e.g.


int main() {

  printf("Hello, World!"); // Reference to externally defined function printf.

  return 0;

}


Then you'll receive a call back on your resolver looking for the address of printf.

Hope this helps!

Cheers,
Lang.

On Thu, Apr 20, 2017 at 6:43 AM, via cfe-dev <
[hidden email]> wrote:
Hello LLVM-World,


I was following the "Building a JIT in LLVM"-Tutorial and tried to load a normal main. My code is the following:
class Jitter
{

private
:
  std::
unique_ptr<TargetMachine> TM;
 
const DataLayout DL;
 
ObjectLinkingLayer<> ObjectLayer;
 
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;

public
:
 
typedef decltype(CompileLayer)::ModuleSetHandleT ModuleHandle;

  Jitter() : TM(
EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
      CompileLayer(ObjectLayer,
SimpleCompiler(*TM))
  {printf(
"!");
        llvm::sys::
DynamicLibrary::LoadLibraryPermanently(nullptr);
  }


 
TargetMachine &getTargetMachine() { return *TM; }

 
ModuleHandle addModule(std::unique_ptr<Module> &&M) {
 
// Build our symbol resolver:
 
// Lambda 1: Look back into the JIT itself to find symbols that are part of
 
//           the same "logical dylib".
 
// Lambda 2: Search for external symbols in the host process.
 
auto Resolver = createLambdaResolver(
      [&](
const std::string &Name)
      {

                printf(
"FLUSH :0\n");

       
if (auto Sym = CompileLayer.findSymbol(Name, false))
         
return Sym;
       
return JITSymbol(nullptr);
      },

      [](
const std::string &S)
          {

                  printf(
"PLUSH :0\n");

       
if (auto SymAddr =
             
RTDyldMemoryManager::getSymbolAddressInProcess(S))
         
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
       
return JITSymbol(nullptr);
      });


 
// Build a singleton module set to hold our module.
  std::
vector<std::unique_ptr<Module>> Ms;
  Ms.push_back(std::move(
M));

 
// Add the set to the JIT with the resolver we created above and a newly
 
// created SectionMemoryManager.
 
return CompileLayer.addModuleSet(std::move(Ms),
                                   make_unique<
SectionMemoryManager>(),
                                   std::move(Resolver));

}


JITSymbol
findSymbol(const std::string Name) {
  std::
string MangledName;
 
raw_string_ostream MangledNameStream(MangledName);
 
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
  printf(
"Tzearch for: %s\n\n", MangledNameStream.str());
 
return CompileLayer.findSymbol(MangledNameStream.str(), false);
}


void
removeModule(ModuleHandle H) {
  CompileLayer.removeModuleSet(
H);
}


};






And calling from main with:
int main()
{

        llvm::InitializeNativeTarget();

        llvm::InitializeNativeTargetAsmPrinter();

        llvm::InitializeNativeTargetAsmParser();


        llvm::
LLVMContext context;
        llvm::
SMDiagnostic dia;

        std::
unique_ptr<llvm::Module> M = llvm::parseIRFile("./jit_main.ll", dia, context);
       
Jitter jit;
        printf(
"Wuff?");
       
Jitter::ModuleHandle h = jit.addModule(std::move(M));
        printf(
"KNUFF!\n");

        printf(
"Kuchen! 0x%p\n", jit.findSymbol("main").getAddress());

        system(
"PAUSE");
       
return 0;
}





The Code runs without a fail, but when the programm tries to resolve "main" the address is 0. The strange thing: the printf "
FLUSH :0\n" and "PLUSH :0\n" are never called, so did the code never compiled? What I'm doing wrong?

Kind regards

Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list

[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev





Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.


_______________________________________________
cfe-dev mailing list

[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: JIT doens't resolve address - Resolve obj-Addresses?

Romanenkov Kirill via cfe-dev
Hi Björn,

But I don't know what to do with "NotifyObjectLoaded". So I overloaded the function and can now access the sections. Soo... I allocate memory in my sharedmemory for the sections and use mapSectionAddress to change the addresses. But how do I copy the memory in the finalizeMemory method? I don't have access to the section anymore! 

You're following the recipe for "the hard way", so I'll stick to that: Notice that in this scheme the each section is allocated twice. The first allocation is done by allocateCodeSection/allocateDataSection, and you have to store a pointer to the memory you allocate (and the section size, alignment, memory protections, etc) in a collection somewhere inside the allocator. The second allocation should be done in NotifyObjectLoaded: You use the stored section information (sizes and alignments) to allocate the sections at their final addresses inside shared memory, then use the stored local addresses and newly allocated final addresses to set up the address mapping. Finally, in finalizeMemory, you copy the relocated bytes from the local memory allocated by the first allocation to the shared memory allocated by the second one, then set the appropriate memory protections on the shared memory. The pseudo-C++ for the whole process looks like this:

RTDyldLinkingLayer::loadObject(Obj) {
  for (auto &Section : Obj.sections()) {
    uint8_t *LocalAddr = MemMgr.allocateSection(Section.Size, Section.Align, ...);
    copyToLocalMemory(LocalAddr, Section);
  }
  MemMgr.notifyLoaded(Obj);

  // RTDyldLinkingLayer::finalize() will be called implicitly when you try to take the address
  // of a symbol.
}

RTDyldLinkingLayer::finalize() {
  // Apply relocations to our local copy of the sections based on the final addresses set up
  // in the address mapping.
  applyRelocationsToLocalMemory();

  // Call the memory manager to copy the now-relocated bytes from local memory to their final
  // addresses, then mprotect the memory so that the code at the final address can be
  // executed.
  MemMgr.finalizeMemory();
}

uint8_t* MyMemoryManager::allocate*Section(Size, Align, ...) {
  uint8_t *LocalAddr = allocate_aligned_memory(Size, Align);
  AllocsToRemap.push_back(RemapRecord(LocalAddr, Size, Align));
  return LocalAddr;
}

void MyMemoryManager::notifyLoaded(Obj, RTDyld) {
  for (auto &AR : AllocsToRemap) {
    JITTargetAddress FinalAddr = allocateSharedMemory(AR.Size, AR.Align);
    RTDyld.mapSectionAddress(AR.LocalAddr, FinalAddr);
    AllocsToFinalize.push_back(FinalizeRecord(LocalAddr, FinalAddr, Size));
  }
  AllocsToRemap.clear();
}

void MyMemoryManager::finalizeMemory() {
  for (auto &AR : AllocsToFinalize) {
    copyFromLocalToFinalMemory(AR.FinalAddr, AR.LocalAddr, AR.Size);
    setMemoryProtections(AR.FinalAddr, Size);
  }
  AllocsToFinalize.clear();
}

Hope this helps!
 
If you're JITing across processes with ORC it might be worth looking at OrcRemoteTargetClient.h and OrcRemoteTargetServer.h: They provide a built-in remote memory manager that can allocate memory in the JIT target process and convey those allocations back to the JIT compiler via RPC. There's an example of this in the 5th entry of the Building A JIT tutorial - http://releases.llvm.org/4.0.0/docs/tutorial/BuildingAJIT5.html (though unfortunately I haven't had time to write the tutorial text for it yet).

Cheers,
Lang.


On Tue, May 9, 2017 at 7:24 AM, <[hidden email]> wrote:
Hello Lang,

thanks for your answer! With small steps I'm coming to my goal.

But I don't know what to do with "NotifyObjectLoaded". So I overloaded the function and can now access the sections. Soo... I allocate memory in my sharedmemory for the sections and use mapSectionAddress to change the addresses. But how do I copy the memory in the finalizeMemory method? I don't have access to the section anymore!
Plus, is there a way to reallocate global variables too, which aren't declared as extern - give them another memory location? I see these values with "symbols" in "NotifyObjectLoaded", but I don't have an address for them.
And... can I load .obj files, which Visual Studio had generated?

Kind regards
Björn



From:        Lang Hames <[hidden email]>
To:        [hidden email], Clang Dev <[hidden email]>, LLVM Developers Mailing List <[hidden email]>
Date:        07.05.2017 04:37
Subject:        Re: [cfe-dev] JIT doens't resolve address - Resolve obj-Addresses?




Hi Bjoern,

CCing cfg-dev (since that's where the conversation started) and llvm-dev (since it's relevant there).

Do you know if there is a way to obtain the fully resolved obj-code? I wanted to load the functions into a shared memory, but how? The only thing I receive is a function pointer, but I don't know how large the function 'behind' is. Even a call to _msize (windows) does only resolve in a crash. 

You can access the fully-resolved object code on a per-section basis (there is no easy way to do it per-function) by using a custom memory manager, rather than SectionMemoryManager.

There are two ways to go about this:

(1) The easy way (only valid for shared-memory on the same machine) is to allocate the sections directly out of shared memory (by overriding allocateCodeSection/allocateDataSection).

(2) The hard way (which is general enough to allow you to copy the relocated bytes to remote machines) is three part:
(a) Allocate the sections locally (e.g. using malloc, or inheriting from SectionMemoryManager and capturing the allocation details)
(b) Override the notifyObjectLoaded method to allocate the final memory locations, then call RTDyldMemoryManager::mapSectionAddress to map each local allocation to its corresponding final address
(c) Override finalizeMemory to copy the relocated bytes to their final addresses

Hope this helps.

Cheers,
Lang.




On Tue, May 2, 2017 at 10:47 PM, <[hidden email]> wrote:
Hello Lang,

your answer explained a lot to me, thank you for that. Do you know if there is a way to obtain the fully resolved obj-code? I wanted to load the functions into a shared memory, but how? The only thing I receive is a function pointer, but I don't know how large the function 'behind' is. Even a call to _msize (windows) does only resolve in a crash.


Kind regards

Björn




From:        
Lang Hames <[hidden email]>
To:        
[hidden email]
Cc:        
[hidden email], Clang Dev <[hidden email]>
Date:        
01.05.2017 20:15
Subject:        
Re: [cfe-dev] JIT doens't resolve address - Resolve obj-Addresses?





Hi Björn,

I tried using your code and now it works! I'm happy and surprised!

Oh - I missed that Will's code had fixed your issue. That's great. :)

Do you know if there is a way to directly load .obj-Files and resolve the references with own addresses? Like when somebody used printf in the generated obj-File, but I replace the address with my own printf? 

You can load precompiled object files by calling addObjectSet on the ObjectLayer.

All external symbol references are resolved by the JITSymbolResolver that is created by createLambdaResolver. In your example the resolution process is two-step: First the JIT searches its own function definitions to see if there is a function called "printf" defined there (this is what the call to CompileLayer.findSymbol does):

[&](const std::string &Name)  {

  printf("FLUSH :0\n");

  if (auto Sym = CompileLayer.findSymbol(Name, false))

    return Sym;

  return JITSymbol(nullptr);

}


Then, if it doesn't find a definition there, it falls back to searching in the current process (this is what RTDyldMemoryManager::getSymbolAddressInProcess does):

[](const std::string &S)  { 

  printf("PLUSH :0\n"); 

  if (auto SymAddr = 

        RTDyldMemoryManager::getSymbolAddressInProcess(S)) 

    return JITSymbol(SymAddr, JITSymbolFlags::Exported); 

  return JITSymbol(nullptr); 

}


If, for example, you wanted to redirect calls to printf to your own custom version (while resolving all other externals by the normal process) you could change the second lambda like so:

[](const std::string &S)  { 

  printf("PLUSH :0\n");

  if (S == mangleName("printf"))

    return JITSymbol((JITSymbolAddress)&myCustomPrintf,

                     JITSymbolFlags::Exported);

  if (auto SymAddr = 

        RTDyldMemoryManager::getSymbolAddressInProcess(S)) 

    return JITSymbol(SymAddr, JITSymbolFlags::Exported); 

  return JITSymbol(nullptr); 

}


(You'll just have to pull the mangling logic from findSymbol out into its own "mangleName" function for this).

Hope this helps.

Cheers,
Lang.


On Sun, Apr 23, 2017 at 11:08 PM, <
[hidden email]> wrote:
Hello Mr. Dietz,


I tried using your code and now it works! I'm happy and surprised! I will now compare the codes and try to spot the main difference! Thanks for your help!

Do you know if there is a way to directly load .obj-Files and resolve the references with own addresses? Like when somebody used printf in the generated obj-File, but I replace the address with my own printf?


Kind regards

Björn




From:        
Will Dietz <[hidden email]>
To:        
[hidden email]
Cc:        
Lang Hames <[hidden email]>, Clang Dev <[hidden email]>
Date:        
21.04.2017 21:50
Subject:        
Re: [cfe-dev] JIT doens't resolve address
Sent by:        
[hidden email]




Hmm, I tried using your code (copy+pasted and then mass-dumped headers to fix includes), and it seems to work fine for me:


https://gist.github.com/dtzWill/df84b64a73001532e3fcfe73a2cffbb9#file-test-log

Do you get different results when using your LLVM? If not, can you identify the differences between your code and what I constructed from your snippets?

I noticed "PAUSE", are you on Windows? I'm not sure what the functionality/status of the JIT on Windows is, perhaps someone else can comment on that.

~Will

On Fri, Apr 21, 2017 at 1:03 AM, via cfe-dev <
[hidden email]> wrote:
Hello Lang,


the Code for my jit_main is a normal printf-HelloWorld program. I opended the file with notepad and found the following:
; Function Attrs: noinline norecurse uwtable
define i32 @main() #0 {

entry:

  %retval = alloca i32, align 4

  store i32 0, i32* %retval, align 4

  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([35 x i8], [35 x i8]* @"\01??_C@_0CD@CMJEAMCD@Planschbeckilein?5sagt?5Halloilein@", i32 0, i32 0))

  %call1 = call i32 @system(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @"\01??_C@_05DIAHPDGL@PAUSE?$AA@", i32 0, i32 0))

  ret i32 0

}





So... there is a main... Anyway! The code for the main is this one:
#include <stdio.h>
#include
<stdlib.h>

int
main()
{

        printf(
"Planschbeckilein sagt Halloilein!\n");
        system(
"PAUSE");

       
return 0;
}





Kind regards

Björn




From:        
Lang Hames <[hidden email]>
To:        
[hidden email]
Cc:        
Clang Dev <[hidden email]>
Date:        
20.04.2017 22:54
Subject:        
Re: [cfe-dev] JIT doens't resolve address





Hi Bjoern,

Sorry - I just noticed that the address for your "main" function has come back as '0'. In this case the answer is even simpler: The JIT never found the function at all, and so definitely didn't have any external symbols to resolve, so it never called the resolver.

A failure to find main has three likely causes:

(1) jit_main.ll does not define main,
(2) jit_main.ll defines main with private/internal linkage (the JIT can't see private/internal symbols in general)
(3) jit_main.ll defines main with external linkage, but a system mangling is applied (e.g. on MacOSX 'main' is mangled to '_main'). The mangler code in your findSymbol function *should* correct for this, but this may fail if the default data layout for your TargetMachine varies from the Module's DataLayout.

Can you share the contents of your jit_main.ll Module?

Cheers,
Lang.
   

On Thu, Apr 20, 2017 at 1:35 PM, Lang Hames <
[hidden email]> wrote:
HI Bjoern,

There are two kinds of symbol lookup in the JIT:

(1) You want to find a symbol defined JIT'd code. This is what "findSymbol" on the JIT class does.

(2) The JIT wants to fix up a module that contains references to symbols defined elsewhere (either in your program, or in other JIT'd code). This is the SymbolResolver's job.

So assuming your main function in main.ll is trivial, e.g.


int main() {

  return 0;

}


then your findSymbol call will return the address of the JIT'd main without ever needing to look anything up in the resolver.

If, on the other hand, your main function contains an external reference, e.g.


int main() {

  printf("Hello, World!"); // Reference to externally defined function printf.

  return 0;

}


Then you'll receive a call back on your resolver looking for the address of printf.

Hope this helps!

Cheers,
Lang.

On Thu, Apr 20, 2017 at 6:43 AM, via cfe-dev <
[hidden email]> wrote:
Hello LLVM-World,


I was following the "Building a JIT in LLVM"-Tutorial and tried to load a normal main. My code is the following:
class Jitter
{

private
:
  std::
unique_ptr<TargetMachine> TM;
 
const DataLayout DL;
 
ObjectLinkingLayer<> ObjectLayer;
 
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;

public
:
 
typedef decltype(CompileLayer)::ModuleSetHandleT ModuleHandle;

  Jitter() : TM(
EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
      CompileLayer(ObjectLayer,
SimpleCompiler(*TM))
  {printf(
"!");
        llvm::sys::
DynamicLibrary::LoadLibraryPermanently(nullptr);
  }


 
TargetMachine &getTargetMachine() { return *TM; }

 
ModuleHandle addModule(std::unique_ptr<Module> &&M) {
 
// Build our symbol resolver:
 
// Lambda 1: Look back into the JIT itself to find symbols that are part of
 
//           the same "logical dylib".
 
// Lambda 2: Search for external symbols in the host process.
 
auto Resolver = createLambdaResolver(
      [&](
const std::string &Name)
      {

                printf(
"FLUSH :0\n");

       
if (auto Sym = CompileLayer.findSymbol(Name, false))
         
return Sym;
       
return JITSymbol(nullptr);
      },

      [](
const std::string &S)
          {

                  printf(
"PLUSH :0\n");

       
if (auto SymAddr =
             
RTDyldMemoryManager::getSymbolAddressInProcess(S))
         
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
       
return JITSymbol(nullptr);
      });


 
// Build a singleton module set to hold our module.
  std::
vector<std::unique_ptr<Module>> Ms;
  Ms.push_back(std::move(
M));

 
// Add the set to the JIT with the resolver we created above and a newly
 
// created SectionMemoryManager.
 
return CompileLayer.addModuleSet(std::move(Ms),
                                   make_unique<
SectionMemoryManager>(),
                                   std::move(Resolver));

}


JITSymbol
findSymbol(const std::string Name) {
  std::
string MangledName;
 
raw_string_ostream MangledNameStream(MangledName);
 
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
  printf(
"Tzearch for: %s\n\n", MangledNameStream.str());
 
return CompileLayer.findSymbol(MangledNameStream.str(), false);
}


void
removeModule(ModuleHandle H) {
  CompileLayer.removeModuleSet(
H);
}


};






And calling from main with:
int main()
{

        llvm::InitializeNativeTarget();

        llvm::InitializeNativeTargetAsmPrinter();

        llvm::InitializeNativeTargetAsmParser();


        llvm::
LLVMContext context;
        llvm::
SMDiagnostic dia;

        std::
unique_ptr<llvm::Module> M = llvm::parseIRFile("./jit_main.ll", dia, context);
       
Jitter jit;
        printf(
"Wuff?");
       
Jitter::ModuleHandle h = jit.addModule(std::move(M));
        printf(
"KNUFF!\n");

        printf(
"Kuchen! 0x%p\n", jit.findSymbol("main").getAddress());

        system(
"PAUSE");
       
return 0;
}





The Code runs without a fail, but when the programm tries to resolve "main" the address is 0. The strange thing: the printf "
FLUSH :0\n" and "PLUSH :0\n" are never called, so did the code never compiled? What I'm doing wrong?

Kind regards

Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list

[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev





Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.


_______________________________________________
cfe-dev mailing list

[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: JIT doens't resolve address - Resolve obj-Addresses?

Romanenkov Kirill via cfe-dev
Hello Lang,

thank you very much! Now I'm understanding the whole JIT-ting a lot better. I guess, that every problem I had is solved now. Thank you!

Kind regards
Jörn



From:        Lang Hames <[hidden email]>
To:        [hidden email]
Cc:        Clang Dev <[hidden email]>, LLVM Developers Mailing List <[hidden email]>
Date:        10.05.2017 00:50
Subject:        Re: [cfe-dev] JIT doens't resolve address - Resolve obj-Addresses?




Hi Björn,

But I don't know what to do with "NotifyObjectLoaded". So I overloaded the function and can now access the sections. Soo... I allocate memory in my sharedmemory for the sections and use mapSectionAddress to change the addresses. But how do I copy the memory in the finalizeMemory method? I don't have access to the section anymore! 

You're following the recipe for "the hard way", so I'll stick to that: Notice that in this scheme the each section is allocated twice. The first allocation is done by allocateCodeSection/allocateDataSection, and you have to store a pointer to the memory you allocate (and the section size, alignment, memory protections, etc) in a collection somewhere inside the allocator. The second allocation should be done in NotifyObjectLoaded: You use the stored section information (sizes and alignments) to allocate the sections at their final addresses inside shared memory, then use the stored local addresses and newly allocated final addresses to set up the address mapping. Finally, in finalizeMemory, you copy the relocated bytes from the local memory allocated by the first allocation to the shared memory allocated by the second one, then set the appropriate memory protections on the shared memory. The pseudo-C++ for the whole process looks like this:

RTDyldLinkingLayer::loadObject(Obj) {
  for (auto &Section : Obj.sections()) {
    uint8_t *LocalAddr = MemMgr.allocateSection(Section.Size, Section.Align, ...);
    copyToLocalMemory(LocalAddr, Section);
  }
  MemMgr.notifyLoaded(Obj);

  // RTDyldLinkingLayer::finalize() will be called implicitly when you try to take the address
  // of a symbol.
}

RTDyldLinkingLayer::finalize() {
  // Apply relocations to our local copy of the sections based on the final addresses set up
  // in the address mapping.
  applyRelocationsToLocalMemory();

  // Call the memory manager to copy the now-relocated bytes from local memory to their final
  // addresses, then mprotect the memory so that the code at the final address can be
  // executed.
  MemMgr.finalizeMemory();
}

uint8_t* MyMemoryManager::allocate*Section(Size, Align, ...) {
  uint8_t *LocalAddr = allocate_aligned_memory(Size, Align);
  AllocsToRemap.push_back(RemapRecord(LocalAddr, Size, Align));
  return LocalAddr;
}

void MyMemoryManager::notifyLoaded(Obj, RTDyld) {
  for (auto &AR : AllocsToRemap) {
    JITTargetAddress FinalAddr = allocateSharedMemory(AR.Size, AR.Align);
    RTDyld.mapSectionAddress(AR.LocalAddr, FinalAddr);
    AllocsToFinalize.push_back(FinalizeRecord(LocalAddr, FinalAddr, Size));
  }
  AllocsToRemap.clear();
}

void MyMemoryManager::finalizeMemory() {
  for (auto &AR : AllocsToFinalize) {
    copyFromLocalToFinalMemory(AR.FinalAddr, AR.LocalAddr, AR.Size);
    setMemoryProtections(AR.FinalAddr, Size);
  }
  AllocsToFinalize.clear();
}

Hope this helps!
 
If you're JITing across processes with ORC it might be worth looking at OrcRemoteTargetClient.h and OrcRemoteTargetServer.h: They provide a built-in remote memory manager that can allocate memory in the JIT target process and convey those allocations back to the JIT compiler via RPC. There's an example of this in the 5th entry of the Building A JIT tutorial - http://releases.llvm.org/4.0.0/docs/tutorial/BuildingAJIT5.html (though unfortunately I haven't had time to write the tutorial text for it yet).

Cheers,
Lang.


On Tue, May 9, 2017 at 7:24 AM, <bjoern.gaier@...> wrote:
Hello Lang,

thanks for your answer! With small steps I'm coming to my goal.


But I don't know what to do with "NotifyObjectLoaded". So I overloaded the function and can now access the sections. Soo... I allocate memory in my sharedmemory for the sections and use mapSectionAddress to change the addresses. But how do I copy the memory in the finalizeMemory method? I don't have access to the section anymore!

Plus, is there a way to reallocate global variables too, which aren't declared as extern - give them another memory location? I see these values with "symbols" in "NotifyObjectLoaded", but I don't have an address for them.

And... can I load .obj files, which Visual Studio had generated?


Kind regards

Björn




From:        
Lang Hames <lhames@...>
To:        
bjoern.gaier@..., Clang Dev <[hidden email]>, LLVM Developers Mailing List <[hidden email]>
Date:        
07.05.2017 04:37
Subject:        Re: [cfe-dev] JIT doens't resolve address - Resolve obj-Addresses?




Hi Bjoern,

CCing cfg-dev (since that's where the conversation started) and llvm-dev (since it's relevant there).

Do you know if there is a way to obtain the fully resolved obj-code? I wanted to load the functions into a shared memory, but how? The only thing I receive is a function pointer, but I don't know how large the function 'behind' is. Even a call to _msize (windows) does only resolve in a crash. 

You can access the fully-resolved object code on a per-section basis (there is no easy way to do it per-function) by using a custom memory manager, rather than SectionMemoryManager.

There are two ways to go about this:

(1) The easy way (only valid for shared-memory on the same machine) is to allocate the sections directly out of shared memory (by overriding allocateCodeSection/allocateDataSection).

(2) The hard way (which is general enough to allow you to copy the relocated bytes to remote machines) is three part:
(a) Allocate the sections locally (e.g. using malloc, or inheriting from SectionMemoryManager and capturing the allocation details)
(b) Override the notifyObjectLoaded method to allocate the final memory locations, then call RTDyldMemoryManager::mapSectionAddress to map each local allocation to its corresponding final address
(c) Override finalizeMemory to copy the relocated bytes to their final addresses

Hope this helps.

Cheers,
Lang.




On Tue, May 2, 2017 at 10:47 PM, <
bjoern.gaier@...> wrote:
Hello Lang,


your answer explained a lot to me, thank you for that. Do you know if there is a way to obtain the fully resolved obj-code? I wanted to load the functions into a shared memory, but how? The only thing I receive is a function pointer, but I don't know how large the function 'behind' is. Even a call to _msize (windows) does only resolve in a crash.


Kind regards

Björn




From:        
Lang Hames <lhames@...>
To:        
bjoern.gaier@...
Cc:        
willdtz@..., Clang Dev <[hidden email]>
Date:        
01.05.2017 20:15
Subject:        
Re: [cfe-dev] JIT doens't resolve address - Resolve obj-Addresses?





Hi Björn,

I tried using your code and now it works! I'm happy and surprised!

Oh - I missed that Will's code had fixed your issue. That's great. :)

Do you know if there is a way to directly load .obj-Files and resolve the references with own addresses? Like when somebody used printf in the generated obj-File, but I replace the address with my own printf? 

You can load precompiled object files by calling addObjectSet on the ObjectLayer.

All external symbol references are resolved by the JITSymbolResolver that is created by createLambdaResolver. In your example the resolution process is two-step: First the JIT searches its own function definitions to see if there is a function called "printf" defined there (this is what the call to CompileLayer.findSymbol does):


[&](const std::string &Name)  {

  printf("FLUSH :0\n");

  if (auto Sym = CompileLayer.findSymbol(Name, false))

    return Sym;

  return JITSymbol(nullptr);

}


Then, if it doesn't find a definition there, it falls back to searching in the current process (this is what RTDyldMemoryManager::getSymbolAddressInProcess does):


[](const std::string &S)  { 

  printf("PLUSH :0\n"); 

  if (auto SymAddr = 

        RTDyldMemoryManager::getSymbolAddressInProcess(S)) 

    return JITSymbol(SymAddr, JITSymbolFlags::Exported); 

  return JITSymbol(nullptr); 

}


If, for example, you wanted to redirect calls to printf to your own custom version (while resolving all other externals by the normal process) you could change the second lambda like so:


[](const std::string &S)  { 

  printf("PLUSH :0\n");

  if (S == mangleName("printf"))

    return JITSymbol((JITSymbolAddress)&myCustomPrintf,

                     JITSymbolFlags::Exported);

  if (auto SymAddr = 

        RTDyldMemoryManager::getSymbolAddressInProcess(S)) 

    return JITSymbol(SymAddr, JITSymbolFlags::Exported); 

  return JITSymbol(nullptr); 

}


(You'll just have to pull the mangling logic from findSymbol out into its own "mangleName" function for this).

Hope this helps.

Cheers,
Lang.


On Sun, Apr 23, 2017 at 11:08 PM, <
bjoern.gaier@...> wrote:
Hello Mr. Dietz,


I tried using your code and now it works! I'm happy and surprised! I will now compare the codes and try to spot the main difference! Thanks for your help!

Do you know if there is a way to directly load .obj-Files and resolve the references with own addresses? Like when somebody used printf in the generated obj-File, but I replace the address with my own printf?


Kind regards

Björn




From:        
Will Dietz <willdtz@...>
To:        
bjoern.gaier@...
Cc:        
Lang Hames <lhames@...>, Clang Dev <[hidden email]>
Date:        
21.04.2017 21:50
Subject:        
Re: [cfe-dev] JIT doens't resolve address
Sent by:        
w@...




Hmm, I tried using your code (copy+pasted and then mass-dumped headers to fix includes), and it seems to work fine for me:


https://gist.github.com/dtzWill/df84b64a73001532e3fcfe73a2cffbb9#file-test-log

Do you get different results when using your LLVM? If not, can you identify the differences between your code and what I constructed from your snippets?

I noticed "PAUSE", are you on Windows? I'm not sure what the functionality/status of the JIT on Windows is, perhaps someone else can comment on that.

~Will

On Fri, Apr 21, 2017 at 1:03 AM, via cfe-dev <
[hidden email]> wrote:
Hello Lang,


the Code for my jit_main is a normal printf-HelloWorld program. I opended the file with notepad and found the following:
; Function Attrs: noinline norecurse uwtable
define i32 @main() #0 {

entry:

  %retval = alloca i32, align 4

  store i32 0, i32* %retval, align 4

  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([35 x i8], [35 x i8]* @"\01??_C@_0CD@CMJEAMCD@Planschbeckilein?5sagt?5Halloilein@", i32 0, i32 0))

  %call1 = call i32 @system(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @"\01??_C@_05DIAHPDGL@PAUSE?$AA@", i32 0, i32 0))

  ret i32 0

}






So... there is a main... Anyway! The code for the main is this one:
#include <stdio.h>
#include
<stdlib.h>

int
main()
{

        printf(
"Planschbeckilein sagt Halloilein!\n");
        system(
"PAUSE");

       
return 0;
}






Kind regards

Björn




From:        
Lang Hames <lhames@...>
To:        
bjoern.gaier@...
Cc:        
Clang Dev <[hidden email]>
Date:        
20.04.2017 22:54
Subject:        
Re: [cfe-dev] JIT doens't resolve address





Hi Bjoern,

Sorry - I just noticed that the address for your "main" function has come back as '0'. In this case the answer is even simpler: The JIT never found the function at all, and so definitely didn't have any external symbols to resolve, so it never called the resolver.

A failure to find main has three likely causes:

(1) jit_main.ll does not define main,
(2) jit_main.ll defines main with private/internal linkage (the JIT can't see private/internal symbols in general)
(3) jit_main.ll defines main with external linkage, but a system mangling is applied (e.g. on MacOSX 'main' is mangled to '_main'). The mangler code in your findSymbol function *should* correct for this, but this may fail if the default data layout for your TargetMachine varies from the Module's DataLayout.

Can you share the contents of your jit_main.ll Module?

Cheers,
Lang.
   

On Thu, Apr 20, 2017 at 1:35 PM, Lang Hames <
lhames@...> wrote:
HI Bjoern,

There are two kinds of symbol lookup in the JIT:

(1) You want to find a symbol defined JIT'd code. This is what "findSymbol" on the JIT class does.

(2) The JIT wants to fix up a module that contains references to symbols defined elsewhere (either in your program, or in other JIT'd code). This is the SymbolResolver's job.

So assuming your main function in main.ll is trivial, e.g.


int main() {

  return 0;

}


then your findSymbol call will return the address of the JIT'd main without ever needing to look anything up in the resolver.

If, on the other hand, your main function contains an external reference, e.g.


int main() {

  printf("Hello, World!"); // Reference to externally defined function printf.

  return 0;

}


Then you'll receive a call back on your resolver looking for the address of printf.

Hope this helps!

Cheers,
Lang.

On Thu, Apr 20, 2017 at 6:43 AM, via cfe-dev <
[hidden email]> wrote:
Hello LLVM-World,


I was following the "Building a JIT in LLVM"-Tutorial and tried to load a normal main. My code is the following:
class Jitter
{

private
:
  std::
unique_ptr<TargetMachine> TM;
 
const DataLayout DL;
 
ObjectLinkingLayer<> ObjectLayer;
 
IRCompileLayer<decltype(ObjectLayer)> CompileLayer;

public
:
 
typedef decltype(CompileLayer)::ModuleSetHandleT ModuleHandle;

  Jitter() : TM(
EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
      CompileLayer(ObjectLayer,
SimpleCompiler(*TM))
  {printf(
"!");
        llvm::sys::
DynamicLibrary::LoadLibraryPermanently(nullptr);
  }


 
TargetMachine &getTargetMachine() { return *TM; }

 
ModuleHandle addModule(std::unique_ptr<Module> &&M) {
 
// Build our symbol resolver:
 
// Lambda 1: Look back into the JIT itself to find symbols that are part of
 
//           the same "logical dylib".
 
// Lambda 2: Search for external symbols in the host process.
 
auto Resolver = createLambdaResolver(
      [&](
const std::string &Name)
      {

                printf(
"FLUSH :0\n");

       
if (auto Sym = CompileLayer.findSymbol(Name, false))
         
return Sym;
       
return JITSymbol(nullptr);
      },

      [](
const std::string &S)
          {

                  printf(
"PLUSH :0\n");

       
if (auto SymAddr =
             
RTDyldMemoryManager::getSymbolAddressInProcess(S))
         
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
       
return JITSymbol(nullptr);
      });


 
// Build a singleton module set to hold our module.
  std::
vector<std::unique_ptr<Module>> Ms;
  Ms.push_back(std::move(
M));

 
// Add the set to the JIT with the resolver we created above and a newly
 
// created SectionMemoryManager.
 
return CompileLayer.addModuleSet(std::move(Ms),
                                   make_unique<
SectionMemoryManager>(),
                                   std::move(Resolver));

}


JITSymbol
findSymbol(const std::string Name) {
  std::
string MangledName;
 
raw_string_ostream MangledNameStream(MangledName);
 
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
  printf(
"Tzearch for: %s\n\n", MangledNameStream.str());
 
return CompileLayer.findSymbol(MangledNameStream.str(), false);
}


void
removeModule(ModuleHandle H) {
  CompileLayer.removeModuleSet(
H);
}


};







And calling from main with:
int main()
{

        llvm::InitializeNativeTarget();

        llvm::InitializeNativeTargetAsmPrinter();

        llvm::InitializeNativeTargetAsmParser();


        llvm::
LLVMContext context;
        llvm::
SMDiagnostic dia;

        std::
unique_ptr<llvm::Module> M = llvm::parseIRFile("./jit_main.ll", dia, context);
       
Jitter jit;
        printf(
"Wuff?");
       
Jitter::ModuleHandle h = jit.addModule(std::move(M));
        printf(
"KNUFF!\n");

        printf(
"Kuchen! 0x%p\n", jit.findSymbol("main").getAddress());

        system(
"PAUSE");
       
return 0;
}






The Code runs without a fail, but when the programm tries to resolve "main" the address is 0. The strange thing: the printf "
FLUSH :0\n" and "PLUSH :0\n" are never called, so did the code never compiled? What I'm doing wrong?

Kind regards

Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list

[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev





Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.


_______________________________________________
cfe-dev mailing list

[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

JIT - Resolve obj file without a main

Romanenkov Kirill via cfe-dev
In reply to this post by Romanenkov Kirill via cfe-dev
Hello Lang,

I noticed, if I load a obj-File without a main-function, the Jitter won't resolve any address. But if I have a main, everything works fine. Why is this so? Is there a way to stop this?

Kind regards
Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: JIT - Resolve obj file without a main

Romanenkov Kirill via cfe-dev
Hi Björn,

I don't recall ever seeing this behavior before. Can you describe the situation in more detail?

Is this specifically for object files loaded via RTDyldLinkingLayer::addObjectSet, or does it apply to IR Modules without a main too?

When you say the JIT won't resolve an address, do you mean that you can't find anything when you call findSymbol on the JIT, or that the JIT isn't calling your SymbolResolver back to find addresses?

Was this for MacOS, Linux, or Windows?

Cheers,
Lang. 

On Fri, May 12, 2017 at 6:47 AM, <[hidden email]> wrote:
Hello Lang,

I noticed, if I load a obj-File without a main-function, the Jitter won't resolve any address. But if I have a main, everything works fine. Why is this so? Is there a way to stop this?

Kind regards
Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: JIT - Resolve obj file without a main

Romanenkov Kirill via cfe-dev
Hi Lang,

I'm using Windows. I was parsing an IR-File and added the Module to the ExectuionEngine. If I than searched for a function, I just got 0. But when the module had a main, I got an address. I solved the problem via a call to "generateCodeForModule". The JIT didn't even called my SymbolResolver in this special case.

Could you please tell me, if there is a way to allocate the memory for the codemodules more precise? I would like to allocate the memory for strings from a separated memory-pool. But how can I detect a string? The only moment I can do this is in "notifyObjectLoaded" via the names of the symbols. But than it is impossible for my to get the address of the symbols. I noticed that some strings are stored in .rdata, but this is no guarantee.

Kind regards
Björn



From:        Lang Hames <[hidden email]>
To:        [hidden email]
Cc:        Clang Dev <[hidden email]>, LLVM Developers Mailing List <[hidden email]>
Date:        16.05.2017 18:37
Subject:        Re: JIT - Resolve obj file without a main




Hi Björn,

I don't recall ever seeing this behavior before. Can you describe the situation in more detail?

Is this specifically for object files loaded via RTDyldLinkingLayer::addObjectSet, or does it apply to IR Modules without a main too?

When you say the JIT won't resolve an address, do you mean that you can't find anything when you call findSymbol on the JIT, or that the JIT isn't calling your SymbolResolver back to find addresses?

Was this for MacOS, Linux, or Windows?

Cheers,
Lang. 

On Fri, May 12, 2017 at 6:47 AM, <bjoern.gaier@...> wrote:
Hello Lang,

I noticed, if I load a obj-File without a main-function, the Jitter won't resolve any address. But if I have a main, everything works fine. Why is this so? Is there a way to stop this?


Kind regards

Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: JIT - Resolve obj file without a main

Romanenkov Kirill via cfe-dev
Hi Bjoern,

Could you please tell me, if there is a way to allocate the memory for the codemodules more precise? I would like to allocate the memory for strings from a separated memory-pool. But how can I detect a string? The only moment I can do this is in "notifyObjectLoaded" via the names of the symbols. But than it is impossible for my to get the address of the symbols. I noticed that some strings are stored in .rdata, but this is no guarantee. 

There is no easy way to do this at the moment, any it will always be limited by what the object format allows (as you said: you need the object format to tell you what's a string and what isn't, and they don't do that in all situations).

If you can identify strings at the IR level you could do this by allocating the strings in your own memory and marking the IR definitions as weak, but this would also require LLVM to be more careful about picking strong definitions, so it would require some non-trivial LLVM improvements. These improvements are on the drawing board, but there is no schedule for them to be implemented yet.

Cheers,
Lang.

On Wed, May 17, 2017 at 7:03 AM, <[hidden email]> wrote:
Hi Lang,

I'm using Windows. I was parsing an IR-File and added the Module to the ExectuionEngine. If I than searched for a function, I just got 0. But when the module had a main, I got an address. I solved the problem via a call to "generateCodeForModule". The JIT didn't even called my SymbolResolver in this special case.

Could you please tell me, if there is a way to allocate the memory for the codemodules more precise? I would like to allocate the memory for strings from a separated memory-pool. But how can I detect a string? The only moment I can do this is in "notifyObjectLoaded" via the names of the symbols. But than it is impossible for my to get the address of the symbols. I noticed that some strings are stored in .rdata, but this is no guarantee.

Kind regards
Björn



From:        Lang Hames <[hidden email]>
To:        [hidden email]
Cc:        Clang Dev <[hidden email]>, LLVM Developers Mailing List <[hidden email]>
Date:        16.05.2017 18:37
Subject:        Re: JIT - Resolve obj file without a main




Hi Björn,

I don't recall ever seeing this behavior before. Can you describe the situation in more detail?

Is this specifically for object files loaded via RTDyldLinkingLayer::addObjectSet, or does it apply to IR Modules without a main too?

When you say the JIT won't resolve an address, do you mean that you can't find anything when you call findSymbol on the JIT, or that the JIT isn't calling your SymbolResolver back to find addresses?

Was this for MacOS, Linux, or Windows?

Cheers,
Lang. 

On Fri, May 12, 2017 at 6:47 AM, <[hidden email]> wrote:
Hello Lang,

I noticed, if I load a obj-File without a main-function, the Jitter won't resolve any address. But if I have a main, everything works fine. Why is this so? Is there a way to stop this?


Kind regards

Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: JIT - Resolve obj file without a main

Romanenkov Kirill via cfe-dev
Hello Lang,

so you are part of the "Jitter-Team"?
I'm really interested in this whole jitting-process. I wanted to know, is there a way to load other obj-files, than the one created with clang? Could I load - for example - a obj-File from VisualStudio? Or will the namemangeling fail?

Kind regards
Björn



From:        Lang Hames <[hidden email]>
To:        [hidden email]
Cc:        Clang Dev <[hidden email]>, LLVM Developers Mailing List <[hidden email]>
Date:        24.05.2017 01:19
Subject:        Re: JIT - Resolve obj file without a main




Hi Bjoern,

Could you please tell me, if there is a way to allocate the memory for the codemodules more precise? I would like to allocate the memory for strings from a separated memory-pool. But how can I detect a string? The only moment I can do this is in "notifyObjectLoaded" via the names of the symbols. But than it is impossible for my to get the address of the symbols. I noticed that some strings are stored in .rdata, but this is no guarantee. 

There is no easy way to do this at the moment, any it will always be limited by what the object format allows (as you said: you need the object format to tell you what's a string and what isn't, and they don't do that in all situations).

If you can identify strings at the IR level you could do this by allocating the strings in your own memory and marking the IR definitions as weak, but this would also require LLVM to be more careful about picking strong definitions, so it would require some non-trivial LLVM improvements. These improvements are on the drawing board, but there is no schedule for them to be implemented yet.

Cheers,
Lang.

On Wed, May 17, 2017 at 7:03 AM, <bjoern.gaier@...> wrote:
Hi Lang,

I'm using Windows. I was parsing an IR-File and added the Module to the ExectuionEngine. If I than searched for a function, I just got 0. But when the module had a main, I got an address. I solved the problem via a call to "
generateCodeForModule". The JIT didn't even called my SymbolResolver in this special case.

Could you please tell me, if there is a way to allocate the memory for the codemodules more precise? I would like to allocate the memory for strings from a separated memory-pool. But how can I detect a string? The only moment I can do this is in "
notifyObjectLoaded" via the names of the symbols. But than it is impossible for my to get the address of the symbols. I noticed that some strings are stored in .rdata, but this is no guarantee.

Kind regards

Björn




From:        
Lang Hames <lhames@...>
To:        
bjoern.gaier@...
Cc:        
Clang Dev <[hidden email]>, LLVM Developers Mailing List <[hidden email]>
Date:        
16.05.2017 18:37
Subject:        
Re: JIT - Resolve obj file without a main





Hi Björn,

I don't recall ever seeing this behavior before. Can you describe the situation in more detail?

Is this specifically for object files loaded via RTDyldLinkingLayer::addObjectSet, or does it apply to IR Modules without a main too?

When you say the JIT won't resolve an address, do you mean that you can't find anything when you call findSymbol on the JIT, or that the JIT isn't calling your SymbolResolver back to find addresses?

Was this for MacOS, Linux, or Windows?

Cheers,
Lang. 

On Fri, May 12, 2017 at 6:47 AM, <
bjoern.gaier@...> wrote:
Hello Lang,


I noticed, if I load a obj-File without a main-function, the Jitter won't resolve any address. But if I have a main, everything works fine. Why is this so? Is there a way to stop this?


Kind regards

Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

JIT - Exception Handling under Windows

Romanenkov Kirill via cfe-dev
In reply to this post by Romanenkov Kirill via cfe-dev
Hello friendly Clang-World,

working with the JIT is real great and I'm learning great things. But one thing I couldn't get along with. I created an object-file, with a simple exception-handling. One functions throws an integer and another catches the exception. When I try to run the code, the application crashes. I noticed, that the reference "??_7type_info@@6B@" couldn't be resolved. Some research later, I discovered, that this value is the "type_info::vftable". But passing a fake-virtual-table to the reference didn't lead to a function being called. Later I found this article: https://groups.google.com/forum/#!topic/llvm-dev/Fd-ggDDWwRg

But using the msvcrt.lib didn't help me too, because there were other undefined references and the application continued crashing. So - what can I do? Loading every *.lib Windows is providing? Or is there a simpler solution? Couldn't I just change the exception type, when clang compiles my cpp-Files?

Kind regards
Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: [llvm-dev] JIT - Resolve obj file without a main

Romanenkov Kirill via cfe-dev
In reply to this post by Romanenkov Kirill via cfe-dev

Hi Björn

I am not aware of any symbol query issue that depends on the presence of a main function. However, if you call IRCompileLayer::findSymbol(const std::string &Name, bool ExportedSymbolsOnly) you should make sure to pass "false" as the second argument if you are running on Windows.

If you look for a working demo on Windows, that may be interesting for you (incl. a step-by-step guide in branches):
https://github.com/weliveindetail/JitFromScratch

Cheers
Stefan

Am 29.05.17 um 09:08 schrieb via llvm-dev:

Hello Lang,

so you are part of the "Jitter-Team"?
I'm really interested in this whole jitting-process. I wanted to know, is there a way to load other obj-files, than the one created with clang? Could I load - for example - a obj-File from VisualStudio? Or will the namemangeling fail?

Kind regards
Björn



From:        Lang Hames [hidden email]
To:        [hidden email]
Cc:        Clang Dev [hidden email], LLVM Developers Mailing List [hidden email]
Date:        24.05.2017 01:19
Subject:        Re: JIT - Resolve obj file without a main




Hi Bjoern,

Could you please tell me, if there is a way to allocate the memory for the codemodules more precise? I would like to allocate the memory for strings from a separated memory-pool. But how can I detect a string? The only moment I can do this is in "notifyObjectLoaded" via the names of the symbols. But than it is impossible for my to get the address of the symbols. I noticed that some strings are stored in .rdata, but this is no guarantee. 

There is no easy way to do this at the moment, any it will always be limited by what the object format allows (as you said: you need the object format to tell you what's a string and what isn't, and they don't do that in all situations).

If you can identify strings at the IR level you could do this by allocating the strings in your own memory and marking the IR definitions as weak, but this would also require LLVM to be more careful about picking strong definitions, so it would require some non-trivial LLVM improvements. These improvements are on the drawing board, but there is no schedule for them to be implemented yet.

Cheers,
Lang.

On Wed, May 17, 2017 at 7:03 AM, <[hidden email]> wrote:
Hi Lang,

I'm using Windows. I was parsing an IR-File and added the Module to the ExectuionEngine. If I than searched for a function, I just got 0. But when the module had a main, I got an address. I solved the problem via a call to "
generateCodeForModule". The JIT didn't even called my SymbolResolver in this special case.

Could you please tell me, if there is a way to allocate the memory for the codemodules more precise? I would like to allocate the memory for strings from a separated memory-pool. But how can I detect a string? The only moment I can do this is in "
notifyObjectLoaded" via the names of the symbols. But than it is impossible for my to get the address of the symbols. I noticed that some strings are stored in .rdata, but this is no guarantee.

Kind regards

Björn




From:        
Lang Hames <[hidden email]>
To:        
[hidden email]
Cc:        
Clang Dev <[hidden email]>, LLVM Developers Mailing List <[hidden email]>
Date:        
16.05.2017 18:37
Subject:        
Re: JIT - Resolve obj file without a main





Hi Björn,

I don't recall ever seeing this behavior before. Can you describe the situation in more detail?

Is this specifically for object files loaded via RTDyldLinkingLayer::addObjectSet, or does it apply to IR Modules without a main too?

When you say the JIT won't resolve an address, do you mean that you can't find anything when you call findSymbol on the JIT, or that the JIT isn't calling your SymbolResolver back to find addresses?

Was this for MacOS, Linux, or Windows?

Cheers,
Lang. 

On Fri, May 12, 2017 at 6:47 AM, <
[hidden email]> wrote:
Hello Lang,


I noticed, if I load a obj-File without a main-function, the Jitter won't resolve any address. But if I have a main, everything works fine. Why is this so? Is there a way to stop this?


Kind regards

Björn
Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.




Als GmbH eingetragen im Handelsregister Bad Homburg v.d.H. HRB 9816, USt.ID-Nr. DE 114 165 789
Geschäftsführer: Hiroshi Kawamura, Dr Hiroshi Nakamura, Markus Bode, Heiko Lampert, Takashi Nagano, Takeshi Fukushima.


_______________________________________________
LLVM Developers mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
-- 
https://about.me/stefan.graenitz
https://cryptup.org/pub/stefan.graenitz@...

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev