Re: [PATCH v7 2/2] docs/about/emulation: document the dlcall plugin

2026-07-09 Thread Pierrick Bouvier
On 7/8/2026 7:52 PM, Ziyang Zhang wrote:
> On Wed, 8 Jul 2026 18:29:59 -0700, Pierrick Bouvier wrote:
>> On 7/8/2026 5:27 PM, Ziyang Zhang wrote:
>>> Hi Pierrick,
>>>
>>> On Wed, 8 Jul 2026 16:55:19 -0700, Pierrick Bouvier wrote:
> +A minimal end-to-end example wraps a one-function library,
> ``libhello.so``,
> +declared by ``hello.h``:
> +
> +.. code-block:: c
> +
> +   void hello(const char *name, int lucky);
> +

 Please include full files for example:
 hello.h, hello.c and main.c calling hello function.

 Also, please include compiler commands for libhello.so and main.
 You can give a full example assuming it run on a x86_64 host.
>>> Good idea. I will get it done in v8.
>>>
 I could not get it to work.
 Following all the steps, the error message is:

 [GRT] failed to load host runtime
 qemu: uncaught target signal 6 (Aborted) - core dumped
 Aborted
>>> On the error. [GRT] failed to load host runtime is the host side (QEMU)
>>> failing to dlopen the Lorelei host runtime, which means $DEVKIT/lib was
>>> not on the host LD_LIBRARY_PATH, for example if $DEVKIT was not set in
>>> the shell that ran the command. -L only points QEMU at the guest's
>>> loader and libc, so it is unrelated.
>>>
>>> I reproduced it: dropping just $DEVKIT/lib from the host LD_LIBRARY_PATH
>>> gives exactly that message and the abort. The real fix is making the
>>> example self-contained so nothing stays implicit, which is what v8 does.
>>>
>>
>> I paid attention to follow steps correctly, but maybe I missed
>> something. Please see here a full dump of my env and commands:
>>
>> $ git status
>> Untracked files:
>>    (use "git add ..." to include in what will be committed)
>>  a.out
>>  hello.c
>>  hello.h
>>  libhello.so
>>  lorelei-devkit-x86_64-1.0.4.0.tar.xz
>>  lorelei-devkit-x86_64/
>>  main.c
>>  thunks/
>>
>> nothing added to commit but untracked files present (use "git add" to
>> track)
>> $ ldd a.out
>>  linux-vdso.so.1 (0x7f5855c3a000)
>>  libhello.so => not found
>>  libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
>> (0x7f5855a0a000)
>>  /lib64/ld-linux-x86-64.so.2 (0x7f5855c3c000)
>> $ LD_LIBRARY_PATH=./ ldd a.out
>>  linux-vdso.so.1 (0x7fef23831000)
>>  libhello.so => ./libhello.so (0x7fef2381f000)
>>  libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6
>> (0x7fef235fc000)
>>  /lib64/ld-linux-x86-64.so.2 (0x7fef23833000)
>> $ env | grep DEVKIT
>> DEVKIT=/home/user/.work/qemu/lorelei-devkit-x86_64
>> $ tree thunks/
>> thunks/
>> ├── lib
>> │   └── x86_64-LoreHTL
>> │   └── libhello_HTL.so
>> └── x86_64
>>  └── lib
>>  └── x86_64-LoreGTL
>>  └── libhello.so
>>
>> 6 directories, 2 files
>> $ LORELEI_THUNK_PATH=thunks LD_LIBRARY_PATH=$DEVKIT/lib:. \
>> build/qemu-x86_64 -plugin build/contrib/plugins/libdlcall.so \
>> -L $DEVKIT/x86_64/sysroot \
>>   -E LD_LIBRARY_PATH=$DEVKIT/x86_64/lib:thunks/x86_64/lib/x86_64-LoreGTL\
>> ./a.out
>> [GRT] failed to load host runtime
>> qemu: uncaught target signal 6 (Aborted) - core dumped
>> Aborted
>>
>> Any idea what could be missing?
> 
> The "[GRT] failed to load host runtime" message is the host side failing
> to dlopen libLoreHostRT.so, and until now it did not print why. The next
> Lorelei devkit (1.0.5.0) fixes that: the same failure now reads
> 
> [GRT] failed to load host runtime: 
> 
> so upgrading the devkit will usually tell you the cause directly, with
> nothing extra to run.
> 
> Set LD_DEBUG for the QEMU process, and unset it for the guest with -U so
> the guest loader does not also flood the output:
> 
> LD_DEBUG=libs LORELEI_THUNK_PATH=thunks \
> LD_LIBRARY_PATH=$DEVKIT/lib:. \
>     build/qemu-x86_64 -U LD_DEBUG -plugin build/contrib/plugins/
> libdlcall.so \
>     -L $DEVKIT/x86_64/sysroot \
>     -E LD_LIBRARY_PATH=$DEVKIT/x86_64/lib:thunks/x86_64/lib/x86_64-
> LoreGTL \
>     ./a.out 2>ld.txt
> Then look in ld.txt for the block that starts with find
> library=libLoreHostRT.so [0]; searching.
> 
> A healthy load tries $DEVKIT/lib first, finds it there, and ends in a
> matching "calling init" line. A failing load has no trying
> file=$DEVKIT/lib/libLoreHostRT.so line at all.
> 
> So the difference is a single line. If $DEVKIT/lib is never tried, then
> it did not reach the host LD_LIBRARY_PATH of the QEMU process for that
> command. If instead that line is present but the load still fails, the
> message after it (a missing dependency, an ABI mismatch) is the real
> reason, and that is what 1.0.5.0 would print.
>

Thanks, I'll try from v9 and latest release.

 We talked about not overriding sysroot, so please remove -L part.
 Also, Why do current dir is passed in LD_LIBRARY_PATH?
>>> In this example it assumes that the host libhello.so is in the current
>>> directory, which must be able to be found in LD_LIBRA

Re: [PATCH v7 2/2] docs/about/emulation: document the dlcall plugin

2026-07-08 Thread Ziyang Zhang

On Wed, 8 Jul 2026 18:29:59 -0700, Pierrick Bouvier wrote:

On 7/8/2026 5:27 PM, Ziyang Zhang wrote:

Hi Pierrick,

On Wed, 8 Jul 2026 16:55:19 -0700, Pierrick Bouvier wrote:

+A minimal end-to-end example wraps a one-function library,
``libhello.so``,
+declared by ``hello.h``:
+
+.. code-block:: c
+
+   void hello(const char *name, int lucky);
+


Please include full files for example:
hello.h, hello.c and main.c calling hello function.

Also, please include compiler commands for libhello.so and main.
You can give a full example assuming it run on a x86_64 host.

Good idea. I will get it done in v8.


I could not get it to work.
Following all the steps, the error message is:

[GRT] failed to load host runtime
qemu: uncaught target signal 6 (Aborted) - core dumped
Aborted

On the error. [GRT] failed to load host runtime is the host side (QEMU)
failing to dlopen the Lorelei host runtime, which means $DEVKIT/lib was
not on the host LD_LIBRARY_PATH, for example if $DEVKIT was not set in
the shell that ran the command. -L only points QEMU at the guest's
loader and libc, so it is unrelated.

I reproduced it: dropping just $DEVKIT/lib from the host LD_LIBRARY_PATH
gives exactly that message and the abort. The real fix is making the
example self-contained so nothing stays implicit, which is what v8 does.



I paid attention to follow steps correctly, but maybe I missed
something. Please see here a full dump of my env and commands:

$ git status
Untracked files:
   (use "git add ..." to include in what will be committed)
 a.out
 hello.c
 hello.h
 libhello.so
 lorelei-devkit-x86_64-1.0.4.0.tar.xz
 lorelei-devkit-x86_64/
 main.c
 thunks/

nothing added to commit but untracked files present (use "git add" to track)
$ ldd a.out
 linux-vdso.so.1 (0x7f5855c3a000)
 libhello.so => not found
 libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x7f5855a0a000)
 /lib64/ld-linux-x86-64.so.2 (0x7f5855c3c000)
$ LD_LIBRARY_PATH=./ ldd a.out
 linux-vdso.so.1 (0x7fef23831000)
 libhello.so => ./libhello.so (0x7fef2381f000)
 libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x7fef235fc000)
 /lib64/ld-linux-x86-64.so.2 (0x7fef23833000)
$ env | grep DEVKIT
DEVKIT=/home/user/.work/qemu/lorelei-devkit-x86_64
$ tree thunks/
thunks/
├── lib
│   └── x86_64-LoreHTL
│   └── libhello_HTL.so
└── x86_64
 └── lib
 └── x86_64-LoreGTL
 └── libhello.so

6 directories, 2 files
$ LORELEI_THUNK_PATH=thunks LD_LIBRARY_PATH=$DEVKIT/lib:. \
build/qemu-x86_64 -plugin build/contrib/plugins/libdlcall.so \
-L $DEVKIT/x86_64/sysroot \
  -E LD_LIBRARY_PATH=$DEVKIT/x86_64/lib:thunks/x86_64/lib/x86_64-LoreGTL\
./a.out
[GRT] failed to load host runtime
qemu: uncaught target signal 6 (Aborted) - core dumped
Aborted

Any idea what could be missing?


The "[GRT] failed to load host runtime" message is the host side failing
to dlopen libLoreHostRT.so, and until now it did not print why. The next
Lorelei devkit (1.0.5.0) fixes that: the same failure now reads

[GRT] failed to load host runtime: 

so upgrading the devkit will usually tell you the cause directly, with
nothing extra to run.

Set LD_DEBUG for the QEMU process, and unset it for the guest with -U so
the guest loader does not also flood the output:

LD_DEBUG=libs LORELEI_THUNK_PATH=thunks \
LD_LIBRARY_PATH=$DEVKIT/lib:. \
build/qemu-x86_64 -U LD_DEBUG -plugin 
build/contrib/plugins/libdlcall.so \

-L $DEVKIT/x86_64/sysroot \
-E 
LD_LIBRARY_PATH=$DEVKIT/x86_64/lib:thunks/x86_64/lib/x86_64-LoreGTL \

./a.out 2>ld.txt
Then look in ld.txt for the block that starts with find
library=libLoreHostRT.so [0]; searching.

A healthy load tries $DEVKIT/lib first, finds it there, and ends in a
matching "calling init" line. A failing load has no trying
file=$DEVKIT/lib/libLoreHostRT.so line at all.

So the difference is a single line. If $DEVKIT/lib is never tried, then
it did not reach the host LD_LIBRARY_PATH of the QEMU process for that
command. If instead that line is present but the load still fails, the
message after it (a missing dependency, an ABI mismatch) is the real
reason, and that is what 1.0.5.0 would print.


We talked about not overriding sysroot, so please remove -L part.
Also, Why do current dir is passed in LD_LIBRARY_PATH?

In this example it assumes that the host libhello.so is in the current
directory, which must be able to be found in LD_LIBRARY_PATH.


+The guest ``LD_LIBRARY_PATH``, passed with ``-E``, controls what the
emulated
+program loads:
+
+* ``$DEVKIT/x86_64/lib`` contains the guest runtime support shipped
with the
+  devkit.
+* ``thunks/x86_64/lib/x86_64-LoreGTL`` contains the generated guest
+  ``libhello.so`` thunk, used in place of an ordinary guest library.
+
+The host ``LD_LIBRARY_PATH`` controls what the plugin and host thunk
load:
+
+* ``$DEVKIT/lib`` contains the host runtime support shipped wi

Re: [PATCH v7 2/2] docs/about/emulation: document the dlcall plugin

2026-07-08 Thread Ziyang Zhang

On Wed, 8 Jul 2026 18:29:59 -0700, Pierrick Bouvier wrote:

On 7/8/2026 5:27 PM, Ziyang Zhang wrote:

Hi Pierrick,

On Wed, 8 Jul 2026 16:55:19 -0700, Pierrick Bouvier wrote:

+A minimal end-to-end example wraps a one-function library,
``libhello.so``,
+declared by ``hello.h``:
+
+.. code-block:: c
+
+   void hello(const char *name, int lucky);
+


Please include full files for example:
hello.h, hello.c and main.c calling hello function.

Also, please include compiler commands for libhello.so and main.
You can give a full example assuming it run on a x86_64 host.

Good idea. I will get it done in v8.


I could not get it to work.
Following all the steps, the error message is:

[GRT] failed to load host runtime
qemu: uncaught target signal 6 (Aborted) - core dumped
Aborted

On the error. [GRT] failed to load host runtime is the host side (QEMU)
failing to dlopen the Lorelei host runtime, which means $DEVKIT/lib was
not on the host LD_LIBRARY_PATH, for example if $DEVKIT was not set in
the shell that ran the command. -L only points QEMU at the guest's
loader and libc, so it is unrelated.

I reproduced it: dropping just $DEVKIT/lib from the host LD_LIBRARY_PATH
gives exactly that message and the abort. The real fix is making the
example self-contained so nothing stays implicit, which is what v8 does.



I paid attention to follow steps correctly, but maybe I missed
something. Please see here a full dump of my env and commands:

$ git status
Untracked files:
   (use "git add ..." to include in what will be committed)
 a.out
 hello.c
 hello.h
 libhello.so
 lorelei-devkit-x86_64-1.0.4.0.tar.xz
 lorelei-devkit-x86_64/
 main.c
 thunks/

nothing added to commit but untracked files present (use "git add" to track)
$ ldd a.out
 linux-vdso.so.1 (0x7f5855c3a000)
 libhello.so => not found
 libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x7f5855a0a000)
 /lib64/ld-linux-x86-64.so.2 (0x7f5855c3c000)
$ LD_LIBRARY_PATH=./ ldd a.out
 linux-vdso.so.1 (0x7fef23831000)
 libhello.so => ./libhello.so (0x7fef2381f000)
 libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x7fef235fc000)
 /lib64/ld-linux-x86-64.so.2 (0x7fef23833000)
$ env | grep DEVKIT
DEVKIT=/home/user/.work/qemu/lorelei-devkit-x86_64
$ tree thunks/
thunks/
├── lib
│   └── x86_64-LoreHTL
│   └── libhello_HTL.so
└── x86_64
 └── lib
 └── x86_64-LoreGTL
 └── libhello.so

6 directories, 2 files
$ LORELEI_THUNK_PATH=thunks LD_LIBRARY_PATH=$DEVKIT/lib:. \
build/qemu-x86_64 -plugin build/contrib/plugins/libdlcall.so \
-L $DEVKIT/x86_64/sysroot \
  -E LD_LIBRARY_PATH=$DEVKIT/x86_64/lib:thunks/x86_64/lib/x86_64-LoreGTL\
./a.out
[GRT] failed to load host runtime
qemu: uncaught target signal 6 (Aborted) - core dumped
Aborted

Any idea what could be missing?


We talked about not overriding sysroot, so please remove -L part.
Also, Why do current dir is passed in LD_LIBRARY_PATH?

In this example it assumes that the host libhello.so is in the current
directory, which must be able to be found in LD_LIBRARY_PATH.


+The guest ``LD_LIBRARY_PATH``, passed with ``-E``, controls what the
emulated
+program loads:
+
+* ``$DEVKIT/x86_64/lib`` contains the guest runtime support shipped
with the
+  devkit.
+* ``thunks/x86_64/lib/x86_64-LoreGTL`` contains the generated guest
+  ``libhello.so`` thunk, used in place of an ordinary guest library.
+
+The host ``LD_LIBRARY_PATH`` controls what the plugin and host thunk
load:
+
+* ``$DEVKIT/lib`` contains the host runtime support shipped with the
devkit.
+* ``.`` is the current directory, where the host's own
``libhello.so`` is
+  located.
+
+See the runnable
+`hello `_
+(minimal) and
+`demo `_
+(variadic functions and a callback that reenters the guest)
examples, and
+`Lorelei `_ for prebuilt thunk
trees and
+the runtime environment they expect.
+
+.. list-table:: Dynamic Linking Call arguments
+  :widths: 20 80
+  :header-rows: 1
+
+  * - Option
+    - Description
+  * - syscall_num=N
+    - The magic syscall number the guest issues (default 4096). Must
be high
+  enough not to clash with a real syscall.
+
   Other emulation features
   
   


Regards,
Pierrick


It looks unexplained today only because the walkthrough never shows
building it. v8 will.

v8 will also include the full hello.h, hello.c and main.c, plus the cc
and clang commands for libhello.so and main, as one runnable x86_64
sequence.


Although I have tested in the empty containers of each ISA, it is not
possible to cover all Linux distributions. Currently, the Lorelei Host
Runtime (in the devkit, libLoreHostRT.so) fails to load and does not
output dlerror(). At present, I am unable to analyze why there is an
error o

Re: [PATCH v7 2/2] docs/about/emulation: document the dlcall plugin

2026-07-08 Thread Pierrick Bouvier
On 7/8/2026 5:27 PM, Ziyang Zhang wrote:
> Hi Pierrick,
> 
> On Wed, 8 Jul 2026 16:55:19 -0700, Pierrick Bouvier wrote:
>>> +A minimal end-to-end example wraps a one-function library,
>>> ``libhello.so``,
>>> +declared by ``hello.h``:
>>> +
>>> +.. code-block:: c
>>> +
>>> +   void hello(const char *name, int lucky);
>>> +
>>
>> Please include full files for example:
>> hello.h, hello.c and main.c calling hello function.
>>
>> Also, please include compiler commands for libhello.so and main.
>> You can give a full example assuming it run on a x86_64 host.
> Good idea. I will get it done in v8.
> 
>> I could not get it to work.
>> Following all the steps, the error message is:
>>
>> [GRT] failed to load host runtime
>> qemu: uncaught target signal 6 (Aborted) - core dumped
>> Aborted
> On the error. [GRT] failed to load host runtime is the host side (QEMU)
> failing to dlopen the Lorelei host runtime, which means $DEVKIT/lib was
> not on the host LD_LIBRARY_PATH, for example if $DEVKIT was not set in
> the shell that ran the command. -L only points QEMU at the guest's
> loader and libc, so it is unrelated.
> 
> I reproduced it: dropping just $DEVKIT/lib from the host LD_LIBRARY_PATH
> gives exactly that message and the abort. The real fix is making the
> example self-contained so nothing stays implicit, which is what v8 does.
>

I paid attention to follow steps correctly, but maybe I missed
something. Please see here a full dump of my env and commands:

$ git status
Untracked files:
  (use "git add ..." to include in what will be committed)
a.out
hello.c
hello.h
libhello.so
lorelei-devkit-x86_64-1.0.4.0.tar.xz
lorelei-devkit-x86_64/
main.c
thunks/

nothing added to commit but untracked files present (use "git add" to track)
$ ldd a.out
linux-vdso.so.1 (0x7f5855c3a000)
libhello.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x7f5855a0a000)
/lib64/ld-linux-x86-64.so.2 (0x7f5855c3c000)
$ LD_LIBRARY_PATH=./ ldd a.out
linux-vdso.so.1 (0x7fef23831000)
libhello.so => ./libhello.so (0x7fef2381f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x7fef235fc000)
/lib64/ld-linux-x86-64.so.2 (0x7fef23833000)
$ env | grep DEVKIT
DEVKIT=/home/user/.work/qemu/lorelei-devkit-x86_64
$ tree thunks/
thunks/
├── lib
│   └── x86_64-LoreHTL
│   └── libhello_HTL.so
└── x86_64
└── lib
└── x86_64-LoreGTL
└── libhello.so

6 directories, 2 files
$ LORELEI_THUNK_PATH=thunks LD_LIBRARY_PATH=$DEVKIT/lib:. \
build/qemu-x86_64 -plugin build/contrib/plugins/libdlcall.so \
-L $DEVKIT/x86_64/sysroot \
 -E LD_LIBRARY_PATH=$DEVKIT/x86_64/lib:thunks/x86_64/lib/x86_64-LoreGTL\
./a.out
[GRT] failed to load host runtime
qemu: uncaught target signal 6 (Aborted) - core dumped
Aborted

Any idea what could be missing?

>> We talked about not overriding sysroot, so please remove -L part.
>> Also, Why do current dir is passed in LD_LIBRARY_PATH?
> In this example it assumes that the host libhello.so is in the current
> directory, which must be able to be found in LD_LIBRARY_PATH.
> 
>>> +The guest ``LD_LIBRARY_PATH``, passed with ``-E``, controls what the
>>> emulated
>>> +program loads:
>>> +
>>> +* ``$DEVKIT/x86_64/lib`` contains the guest runtime support shipped
>>> with the
>>> +  devkit.
>>> +* ``thunks/x86_64/lib/x86_64-LoreGTL`` contains the generated guest
>>> +  ``libhello.so`` thunk, used in place of an ordinary guest library.
>>> +
>>> +The host ``LD_LIBRARY_PATH`` controls what the plugin and host thunk
>>> load:
>>> +
>>> +* ``$DEVKIT/lib`` contains the host runtime support shipped with the
>>> devkit.
>>> +* ``.`` is the current directory, where the host's own
>>> ``libhello.so`` is
>>> +  located.
>>> +
>>> +See the runnable
>>> +`hello >> hello>`_
>>> +(minimal) and
>>> +`demo `_
>>> +(variadic functions and a callback that reenters the guest)
>>> examples, and
>>> +`Lorelei `_ for prebuilt thunk
>>> trees and
>>> +the runtime environment they expect.
>>> +
>>> +.. list-table:: Dynamic Linking Call arguments
>>> +  :widths: 20 80
>>> +  :header-rows: 1
>>> +
>>> +  * - Option
>>> +    - Description
>>> +  * - syscall_num=N
>>> +    - The magic syscall number the guest issues (default 4096). Must
>>> be high
>>> +  enough not to clash with a real syscall.
>>> +
>>>   Other emulation features
>>>   
>>>   
>>
>> Regards,
>> Pierrick
> 
> It looks unexplained today only because the walkthrough never shows
> building it. v8 will.
> 
> v8 will also include the full hello.h, hello.c and main.c, plus the cc
> and clang commands for libhello.so and main, as one runnable x86_64
> sequence.



Re: [PATCH v7 2/2] docs/about/emulation: document the dlcall plugin

2026-07-08 Thread Ziyang Zhang

Hi Pierrick,

On Wed, 8 Jul 2026 16:55:19 -0700, Pierrick Bouvier wrote:

+A minimal end-to-end example wraps a one-function library, ``libhello.so``,
+declared by ``hello.h``:
+
+.. code-block:: c
+
+   void hello(const char *name, int lucky);
+


Please include full files for example:
hello.h, hello.c and main.c calling hello function.

Also, please include compiler commands for libhello.so and main.
You can give a full example assuming it run on a x86_64 host.

Good idea. I will get it done in v8.


I could not get it to work.
Following all the steps, the error message is:

[GRT] failed to load host runtime
qemu: uncaught target signal 6 (Aborted) - core dumped
Aborted

On the error. [GRT] failed to load host runtime is the host side (QEMU)
failing to dlopen the Lorelei host runtime, which means $DEVKIT/lib was
not on the host LD_LIBRARY_PATH, for example if $DEVKIT was not set in
the shell that ran the command. -L only points QEMU at the guest's
loader and libc, so it is unrelated.

I reproduced it: dropping just $DEVKIT/lib from the host LD_LIBRARY_PATH
gives exactly that message and the abort. The real fix is making the
example self-contained so nothing stays implicit, which is what v8 does.


We talked about not overriding sysroot, so please remove -L part.
Also, Why do current dir is passed in LD_LIBRARY_PATH?

In this example it assumes that the host libhello.so is in the current
directory, which must be able to be found in LD_LIBRARY_PATH.


+The guest ``LD_LIBRARY_PATH``, passed with ``-E``, controls what the emulated
+program loads:
+
+* ``$DEVKIT/x86_64/lib`` contains the guest runtime support shipped with the
+  devkit.
+* ``thunks/x86_64/lib/x86_64-LoreGTL`` contains the generated guest
+  ``libhello.so`` thunk, used in place of an ordinary guest library.
+
+The host ``LD_LIBRARY_PATH`` controls what the plugin and host thunk load:
+
+* ``$DEVKIT/lib`` contains the host runtime support shipped with the devkit.
+* ``.`` is the current directory, where the host's own ``libhello.so`` is
+  located.
+
+See the runnable
+`hello `_
+(minimal) and
+`demo `_
+(variadic functions and a callback that reenters the guest) examples, and
+`Lorelei `_ for prebuilt thunk trees and
+the runtime environment they expect.
+
+.. list-table:: Dynamic Linking Call arguments
+  :widths: 20 80
+  :header-rows: 1
+
+  * - Option
+- Description
+  * - syscall_num=N
+- The magic syscall number the guest issues (default 4096). Must be high
+  enough not to clash with a real syscall.
+
  Other emulation features
  
  


Regards,
Pierrick


It looks unexplained today only because the walkthrough never shows
building it. v8 will.

v8 will also include the full hello.h, hello.c and main.c, plus the cc
and clang commands for libhello.so and main, as one runnable x86_64
sequence.



Re: [PATCH v7 2/2] docs/about/emulation: document the dlcall plugin

2026-07-08 Thread Pierrick Bouvier
On 7/8/2026 8:20 AM, Ziyang Zhang wrote:
> Document the dlcall plugin under Example Plugins: what it does, the trusted-
> guests and guest_base == 0 constraints, how to load it, and a pointer to
> Lorelei, one end-to-end userspace implementation, for prebuilt thunks and a
> runnable example.
> 
> Signed-off-by: Ziyang Zhang 
> ---
>  docs/about/emulation.rst | 122 +++
>  1 file changed, 122 insertions(+)
> 
> diff --git a/docs/about/emulation.rst b/docs/about/emulation.rst
> index 3b4c365933..07fbd24072 100644
> --- a/docs/about/emulation.rst
> +++ b/docs/about/emulation.rst
> @@ -1046,6 +1046,128 @@ Count traps
>  This plugin counts the number of interrupts (asynchronous events), exceptions
>  (synchronous events) and host calls (e.g. semihosting) per cpu.
>  
> +Dynamic Linking Call
> +
> +
> +``contrib/plugins/dlcall.c``
> +
> +This plugin provides a dynamic linking function call interception mechanism
> +for linux-user guests: the guest hands a call off to the host, where the 
> plugin
> +runs native code in its place instead of the guest emulating it. Interception
> +alone enables several uses, for instance tracing or auditing guest calls.
> +One use is acceleration by leveraging the host's native shared libraries. For
> +example, a thunk layer can run the stock zlib ``minizip`` utility under
> +emulation while forwarding its ``deflate`` calls to the host's native zlib
> +library (libz). This avoids emulating those selected library calls 
> instruction
> +by instruction.
> +
> +The guest issues a reserved "magic" system call (4096 by default, 
> configurable
> +with ``syscall_num=N``) whose first argument selects a pass-through 
> operation:
> +dlopen/dlclose a host library, dlsym a symbol, and invoke a resolved host
> +function. The plugin performs the operation on the host and consumes the
> +syscall, so the real kernel never sees it.
> +
> +.. warning::
> +
> +   Trusted guests only. The guest can load arbitrary host libraries and run
> +   arbitrary code in the QEMU host process. The plugin is not a sandbox and
> +   provides no isolation. It also requires ``guest_base == 0`` (qemu-user's
> +   default), as guest pointers are dereferenced as host addresses with no
> +   translation.
> +
> +The plugin intentionally keeps the QEMU side lightweight and knows nothing
> +about any particular library or its calling convention. Turning a real 
> library
> +into working thunks, including argument marshalling, callbacks and variadic
> +functions, is done entirely in userspace, and any toolchain can implement the
> +interface.
> +
> +Loading the plugin is all that is required from QEMU's side:
> +
> +.. code-block:: shell
> +
> +   qemu-x86_64 -plugin contrib/plugins/libdlcall.so  ...
> +
> +`Lorelei `_ is one end-to-end userspace
> +implementation of this: it provides the guest and host runtimes and an
> +automated toolchain that generates the thunks from a library's headers, so 
> guest
> +library calls run on the host's native libraries. Its prebuilt thunks are 
> for an
> +x86_64 guest, running on an x86_64, aarch64 or riscv64 host.
> +
> +A minimal end-to-end example wraps a one-function library, ``libhello.so``,
> +declared by ``hello.h``:
> +
> +.. code-block:: c
> +
> +   void hello(const char *name, int lucky);
> +

Please include full files for example:
hello.h, hello.c and main.c calling hello function.

Also, please include compiler commands for libhello.so and main.
You can give a full example assuming it run on a x86_64 host.

> +The guest program ``main`` is an ordinary x86_64 executable, linked against a
> +guest ``libhello.so`` and calling its ``hello()``. The host has its own
> +``libhello.so``, the same library built for the host. The goal is to run
> +``main``, but have each ``hello()`` call run on the host's ``libhello.so``.
> +
> +Lorelei ships a prebuilt toolchain (a "devkit") in its releases. Download one
> +for your host and unpack it:
> +
> +.. code-block:: shell
> +
> +   #  is your host architecture: x86_64, aarch64 or riscv64
> +   wget 
> https://github.com/rover2024/lorelei/releases/download/v/lorelei-devkit--.tar.xz
> +   tar -xf lorelei-devkit--.tar.xz
> +   DEVKIT=lorelei-devkit-
> +
> +A single command reads the host ``libhello.so`` and ``hello.h`` and generates
> +the thunk: a guest-side ``libhello.so`` that stands in for an ordinary guest
> +build, and a host-side thunk library that dispatches to the real one:
> +
> +.. code-block:: shell
> +
> +   $DEVKIT/bin/LoreMakeThunk.py --name hello --lib libhello.so --header 
> hello.h \
> +   -o thunks -- -I.
> +

Sounds good.

> +Running ``main`` under the plugin forwards each ``hello()`` call to the 
> host's
> +real ``libhello.so``:
> +
> +.. code-block:: shell
> +
> +   LORELEI_THUNK_PATH=thunks \
> +   LD_LIBRARY_PATH=$DEVKIT/lib:. \
> +   qemu-x86_64 -plugin contrib/plugins/libdlcall.so \
> +   -L $DEVKIT/x86_64/sysroo

[PATCH v7 2/2] docs/about/emulation: document the dlcall plugin

2026-07-08 Thread Ziyang Zhang
Document the dlcall plugin under Example Plugins: what it does, the trusted-
guests and guest_base == 0 constraints, how to load it, and a pointer to
Lorelei, one end-to-end userspace implementation, for prebuilt thunks and a
runnable example.

Signed-off-by: Ziyang Zhang 
---
 docs/about/emulation.rst | 122 +++
 1 file changed, 122 insertions(+)

diff --git a/docs/about/emulation.rst b/docs/about/emulation.rst
index 3b4c365933..07fbd24072 100644
--- a/docs/about/emulation.rst
+++ b/docs/about/emulation.rst
@@ -1046,6 +1046,128 @@ Count traps
 This plugin counts the number of interrupts (asynchronous events), exceptions
 (synchronous events) and host calls (e.g. semihosting) per cpu.
 
+Dynamic Linking Call
+
+
+``contrib/plugins/dlcall.c``
+
+This plugin provides a dynamic linking function call interception mechanism
+for linux-user guests: the guest hands a call off to the host, where the plugin
+runs native code in its place instead of the guest emulating it. Interception
+alone enables several uses, for instance tracing or auditing guest calls.
+One use is acceleration by leveraging the host's native shared libraries. For
+example, a thunk layer can run the stock zlib ``minizip`` utility under
+emulation while forwarding its ``deflate`` calls to the host's native zlib
+library (libz). This avoids emulating those selected library calls instruction
+by instruction.
+
+The guest issues a reserved "magic" system call (4096 by default, configurable
+with ``syscall_num=N``) whose first argument selects a pass-through operation:
+dlopen/dlclose a host library, dlsym a symbol, and invoke a resolved host
+function. The plugin performs the operation on the host and consumes the
+syscall, so the real kernel never sees it.
+
+.. warning::
+
+   Trusted guests only. The guest can load arbitrary host libraries and run
+   arbitrary code in the QEMU host process. The plugin is not a sandbox and
+   provides no isolation. It also requires ``guest_base == 0`` (qemu-user's
+   default), as guest pointers are dereferenced as host addresses with no
+   translation.
+
+The plugin intentionally keeps the QEMU side lightweight and knows nothing
+about any particular library or its calling convention. Turning a real library
+into working thunks, including argument marshalling, callbacks and variadic
+functions, is done entirely in userspace, and any toolchain can implement the
+interface.
+
+Loading the plugin is all that is required from QEMU's side:
+
+.. code-block:: shell
+
+   qemu-x86_64 -plugin contrib/plugins/libdlcall.so  ...
+
+`Lorelei `_ is one end-to-end userspace
+implementation of this: it provides the guest and host runtimes and an
+automated toolchain that generates the thunks from a library's headers, so 
guest
+library calls run on the host's native libraries. Its prebuilt thunks are for 
an
+x86_64 guest, running on an x86_64, aarch64 or riscv64 host.
+
+A minimal end-to-end example wraps a one-function library, ``libhello.so``,
+declared by ``hello.h``:
+
+.. code-block:: c
+
+   void hello(const char *name, int lucky);
+
+The guest program ``main`` is an ordinary x86_64 executable, linked against a
+guest ``libhello.so`` and calling its ``hello()``. The host has its own
+``libhello.so``, the same library built for the host. The goal is to run
+``main``, but have each ``hello()`` call run on the host's ``libhello.so``.
+
+Lorelei ships a prebuilt toolchain (a "devkit") in its releases. Download one
+for your host and unpack it:
+
+.. code-block:: shell
+
+   #  is your host architecture: x86_64, aarch64 or riscv64
+   wget 
https://github.com/rover2024/lorelei/releases/download/v/lorelei-devkit--.tar.xz
+   tar -xf lorelei-devkit--.tar.xz
+   DEVKIT=lorelei-devkit-
+
+A single command reads the host ``libhello.so`` and ``hello.h`` and generates
+the thunk: a guest-side ``libhello.so`` that stands in for an ordinary guest
+build, and a host-side thunk library that dispatches to the real one:
+
+.. code-block:: shell
+
+   $DEVKIT/bin/LoreMakeThunk.py --name hello --lib libhello.so --header 
hello.h \
+   -o thunks -- -I.
+
+Running ``main`` under the plugin forwards each ``hello()`` call to the host's
+real ``libhello.so``:
+
+.. code-block:: shell
+
+   LORELEI_THUNK_PATH=thunks \
+   LD_LIBRARY_PATH=$DEVKIT/lib:. \
+   qemu-x86_64 -plugin contrib/plugins/libdlcall.so \
+   -L $DEVKIT/x86_64/sysroot \
+   -E LD_LIBRARY_PATH=$DEVKIT/x86_64/lib:thunks/x86_64/lib/x86_64-LoreGTL \
+   ./main
+
+The guest ``LD_LIBRARY_PATH``, passed with ``-E``, controls what the emulated
+program loads:
+
+* ``$DEVKIT/x86_64/lib`` contains the guest runtime support shipped with the
+  devkit.
+* ``thunks/x86_64/lib/x86_64-LoreGTL`` contains the generated guest
+  ``libhello.so`` thunk, used in place of an ordinary guest library.
+
+The host ``LD_LIBRARY_PATH`` controls what the plugin and host thunk load:
+
+* ``$