<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
Interesting that we don't see the same failure then (Debug is the
default build type). <br>
<br>
So I did some debugging:<br>
<br>
Actually, the ZTIN prefix of the missing symbol indicates a typeinfo
symbol. This is weird because we don't usually build anything with
RTTI in LLVM right? Anyway I rebuilt orc_rt_macho_dlfcn_remote.cpp.o
with an explicit "-fno-rtti" and voila! That fixes the issue.<br>
<br>
It seems that COMPILER_RT_COMMON_CFLAGS doesn't disable RTTI by
default. Or maybe just on my system? Should we add it for
clang_rt.orc as long as we do have the libSupport dependency? I put
up a PR here: <a class="moz-txt-link-freetext" href="https://github.com/lhames/llvm-project/pull/3">https://github.com/lhames/llvm-project/pull/3</a><br>
<br>
Cheers<br>
Stefan<br>
<br>
<div class="moz-cite-prefix">On 18/01/2021 22:45, Lang Hames wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CALLttgqzBr5zFW5xdF33txUErPSJ-6CVMVc=Fy9dXQJ4ytFsyA@mail.gmail.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">Hi Stefan,
<div><br>
</div>
<div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">%
./bin/llvm-jitlink -oop-executor inits.o<br>
JIT session error: Symbols not found: [
__ZTIN4llvm6detail14format_adapterE ]</blockquote>
</div>
<div><br>
</div>
<div>I've been testing with a debug build:</div>
<div><br>
</div>
<div>% xcrun cmake -GNinja -DCMAKE_BUILD_TYPE=Debug
-DLLVM_ENABLE_PROJECTS="llvm;clang;compiler-rt" ../llvm</div>
<div><br>
</div>
<div>
<div>Matching this build might fix the issue, though
building with my config (if it works) is only a
short-term fix. The error that you're seeing implies
that the runtime is dependending on a symbol from
libSupport that is not being linked in to the target
(llvm-jitlink-executor). I'll aim to break these
dependencies on libSupport in the future. Mostly that
means either removing the dependence on llvm::Error /
llvm::Expected (e.g. by creating stripped down versions
for the orc runtime), or making those types header-only.</div>
</div>
<div><br>
</div>
<div>-- Lang.</div>
<div><br>
</div>
<div><br>
</div>
<div><br>
</div>
<div><br>
</div>
</div>
</div>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Tue, Jan 19, 2021 at 12:50
AM Stefan Gränitz <<a
href="mailto:stefan.graenitz@gmail.com"
moz-do-not-send="true">stefan.graenitz@gmail.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px
0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<div> Wow, thanks for the update. One more ORC milestone in a
short period of time!<br>
<br>
On macOS I built the C++ example like this:<br>
<br>
% cmake -GNinja -DLLVM_TARGETS_TO_BUILD=host
-DLLVM_ENABLE_PROJECTS="clang;compiler-rt" ../llvm<br>
% ninja llvm-jitlink llvm-jitlink-executor
lib/clang/12.0.0/lib/darwin/libclang_rt.orc_osx.a<br>
% clang++ -c -o inits.o inits.cpp<br>
<br>
The in-process version works perfectly, but with the
out-of-process flag the examples fails:<br>
<br>
% ./bin/llvm-jitlink inits.o<br>
Foo::Foo()<br>
Foo::foo()<br>
Foo::~Foo()<br>
% ./bin/llvm-jitlink -oop-executor inits.o<br>
JIT session error: Symbols not found: [
__ZTIN4llvm6detail14format_adapterE ]<br>
<br>
Any idea what could go wrong here? Otherwise I can try to
debug it later this week. (Full error below.)<br>
<br>
Best<br>
Stefan<br>
<br>
--<br>
<br>
JIT session error: Symbols not found: [
__ZTIN4llvm6detail14format_adapterE ]<br>
/Users/staefsn/Develop/LLVM/monorepo/llvm-orc-runtime/build/bin/llvm-jitlink:
Failed to materialize symbols: { (Main, {
___orc_rt_macho_symbol_lookup_remote,
__ZN4llvm3orc6shared21WrapperFunctionResult22destroyWithArrayDeleteE39LLVMOrcSharedCWrapperFunctionResultDatay,
__ZNSt3__113__vector_baseIN4llvm3orc6shared25MachOJITDylibInitializersENS_9allocatorIS4_EEED2Ev,
__ZNK4llvm8ExpectedINS_3orc6shared21WrapperFunctionResultEE22fatalUncheckedExpectedEv,
__ZN4llvm3orc6shared21toWrapperFunctionBlobIJNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEEEENS1_21WrapperFunctionResultEDpRKT_,
__ZN4llvm3orc6shared20VectorRawByteChannelD1Ev,
__ZN4llvm3orc6shared21SequenceSerializationINS1_20VectorRawByteChannelEJNSt3__16vectorINS1_25MachOJITDylibInitializers13SectionExtentENS4_9allocatorIS7_EEEESA_SA_EE11deserializeISA_JSA_SA_EEENS_5ErrorERS3_RT_DpRT0_,
__ZNSt3__16vectorIN4llvm3orc6shared25MachOJITDylibInitializers13SectionExtentENS_9allocatorIS5_EEE8__appendEm,
__ZN4llvm3orc6shared21toWrapperFunctionBlobIJyNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEEEENS1_21WrapperFunctionResultEDpRKT_,
__ZN4llvm29VerifyEnableABIBreakingChecksE,
__ZN4llvm15format_providerImvE6formatERKmRNS_11raw_ostreamENS_9StringRefE,
__ZNSt3__114__split_bufferIN4llvm3orc6shared25MachOJITDylibInitializersERNS_9allocatorIS4_EEED2Ev,
__ZTVN4llvm6detail23provider_format_adapterIRmEE,
__ZN4llvm3orc6shared21SequenceSerializationINS1_20VectorRawByteChannelEJyNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEEE9serializeIRKyJRKSA_EEENS_5ErrorERS3_OT_DpOT0_,
__ZTVN4llvm6detail23provider_format_adapterImEE,
__ZN4llvm6detail23provider_format_adapterImE6formatERNS_11raw_ostreamENS_9StringRefE,
__ZN4llvm6detail23provider_format_adapterIRmED1Ev,
___orc_rt_macho_get_deinitializers_tag,
__ZN4llvm6detail23provider_format_adapterIRmED0Ev,
__ZTVN4llvm3orc6shared14RawByteChannelE,
__ZN6orc_rt12jit_dispatchEPKvN4llvm8ArrayRefIhEE,
__ZN4llvm3orc6shared20VectorRawByteChannelD0Ev,
__ZTVN4llvm3orc6shared20VectorRawByteChannelE,
__ZN4llvm8cantFailENS_5ErrorEPKc,
__ZN4llvm6detail23provider_format_adapterImED1Ev,
__ZTVN4llvm6detail23provider_format_adapterIRjEE,
__ZN4llvm6detail23provider_format_adapterImED0Ev,
__ZN4llvm15format_providerIjvE6formatERKjRNS_11raw_ostreamENS_9StringRefE,
__ZTSN4llvm3orc6shared14RawByteChannelE,
__ZN4llvm6detail23provider_format_adapterIRjE6formatERNS_11raw_ostreamENS_9StringRefE,
__ZN4llvm6detail23provider_format_adapterIRjED0Ev,
__ZN4llvm3orc6shared19SerializationTraitsINS1_20VectorRawByteChannelENSt3__16vectorINS1_25MachOJITDylibInitializersENS4_9allocatorIS6_EEEES9_vE11deserializeERS3_RS9_,
__ZTIN4llvm6detail23provider_format_adapterImEE,
__ZN4llvm6detail15HelperFunctions15consumeHexStyleERNS_9StringRefERNS_13HexPrintStyleE,
__ZTIN4llvm6detail23provider_format_adapterIRmEE,
___orc_rt_macho_get_initializers_tag,
__ZTSN4llvm6detail23provider_format_adapterImEE,
__ZN4llvm3orc6shared20VectorRawByteChannel4sendEv,
__ZN4llvm6detail23provider_format_adapterIRmE6formatERNS_11raw_ostreamENS_9StringRefE,
___orc_rt_macho_symbol_lookup_tag,
__ZTSN4llvm6detail23provider_format_adapterIRmEE,
__ZN4llvm3orc6shared20VectorRawByteChannel11appendBytesEPKcj,
__ZTSN4llvm6detail23provider_format_adapterIRjEE,
__ZN4llvm3orc6shared20VectorRawByteChannel9readBytesEPcj,
__ZTSN4llvm3orc6shared20VectorRawByteChannelE,
__ZN4llvm6detail23provider_format_adapterIRjED1Ev,
__ZN4llvm3orc6shared14RawByteChannelD1Ev,
__ZN4llvm3orc6shared23fromWrapperFunctionBlobIJNSt3__16vectorINS1_25MachOJITDylibInitializersENS3_9allocatorIS5_EEEEEEENS_5ErrorENS_8ArrayRefIhEEDpRT_,
__ZN4llvm3orc6shared14RawByteChannelD0Ev,
__ZN4llvm3orc6shared21SequenceSerializationINS1_20VectorRawByteChannelEJyyNSt3__16vectorINS1_25MachOJITDylibInitializers13SectionExtentENS4_9allocatorIS7_EEEESA_SA_EE11deserializeIyJySA_SA_SA_EEENS_5ErrorERS3_RT_DpRT0_,
__ZNSt3__16vectorIN4llvm3orc6shared25MachOJITDylibInitializersENS_9allocatorIS4_EEE8__appendEm,
__ZN4llvm3orc6shared21SequenceSerializationINS1_20VectorRawByteChannelEJyyEE11deserializeIyJyEEENS_5ErrorERS3_RT_DpRT0_,
__ZNSt3__16vectorIN4llvm3orc6shared25MachOJITDylibInitializersENS_9allocatorIS4_EEE6resizeEm,
__ZN4llvm3orc6shared19SerializationTraitsINS1_20VectorRawByteChannelENSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEESA_vE11deserializeERNS1_14RawByteChannelERSA_,
__ZN4llvm3orc6shared23fromWrapperFunctionBlobIJyEEENS_5ErrorENS_8ArrayRefIhEEDpRT_,
__ZTIN4llvm6detail23provider_format_adapterIRjEE,
__ZN4llvm3orc6shared21WrapperFunctionResult20getAnyOutOfBandErrorEv,
__ZTIN4llvm3orc6shared20VectorRawByteChannelE,
___orc_rt_macho_get_initializers_remote,
__ZTIN4llvm3orc6shared14RawByteChannelE,
__ZNSt3__16vectorIhNS_9allocatorIhEEE26__swap_out_circular_bufferERNS_14__split_bufferIhRS2_EE,
__ZN4llvm3orc6shared19SerializationTraitsINS1_20VectorRawByteChannelENSt3__16vectorINS1_25MachOJITDylibInitializers13SectionExtentENS4_9allocatorIS7_EEEESA_vE11deserializeERS3_RSA_
}) }<br>
/Users/staefsn/Develop/LLVM/monorepo/llvm-orc-runtime/build/bin/llvm-jitlink-executor:Response
has unknown sequence number 527162<br>
<br>
<div>On 18/01/2021 08:55, Lang Hames wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">Hi
All,</div>
<div dir="ltr"><br>
</div>
<div dir="ltr">Happy
2021!<br>
<div><br>
</div>
<div>I've just
posted a new
Orc Runtime
Preview patch:
<a
href="https://github.com/lhames/llvm-project/commit/8833a7f24693f1c7a3616438718e7927c6624894"
target="_blank" moz-do-not-send="true">https://github.com/lhames/llvm-project/commit/8833a7f24693f1c7a3616438718e7927c6624894</a></div>
<div><br>
</div>
<div>Quick
background:</div>
<div><br>
</div>
<div>To date,
neither ORC
nor MCJIT have
had their own
runtime
libraries.
This has
limited and
complicated
the
implementation
of many
features (e.g.
jit re-entry
functions,
exception
handling,
JID'd
initializers
and
de-initializers),
and
more-or-less
prevented the
implementation
of others
(e.g. native
thread local
storage).</div>
<div><br>
</div>
<div>Late last
year I started
work on a
prototype ORC
runtime
library to
address this,
and with the
above commit
I've finally
got something
worth sharing.</div>
<div><br>
</div>
<div>The
prototype
above is
simultaneously
limited and
complex.
Limited, in
that it only
tackles a
small subset
of the desired
functionality.
Complex in
that it's one
of the most
involved
pieces of
functionality
that I
anticipate
supporting, as
it requires
two-way
communication
between the
executor and
JIT processes.
My aim in
choosing to
tackle the
hard part
first was to
get a sense of
our ultimate
requirements
for the
project,
particularly
in regards to
<i>where it
should live
within the
LLVM Project</i>.
It's not a
perfect fit
for LLVM
proper: there
will be lots
of target
specific code,
including
assembly, and
it should be
easily
buildable for
multiple
targets (that
sounds more
like
compiler-rt).
On the other
hand it's not
a perfect fit
for
compiler-rt:
it shares data
structures
with LLVM, and
it would be
very useful to
be able to
re-use
llvm::Error /
llvm::Expected
(that sounds
like LLVM). At
the moment I
think the best
way to square
things would
be to keep it
in
compiler-rt,
allow
inclusion of
header-only
code from LLVM
in
compiler-rt,
and then make
Error /
Expected
header-only
(or copy /
adapt them for
this library).
This will be a
discussion for
llvm-dev at
some point in
the near
future.</div>
<div><br>
</div>
<div>On to the
actual
functionality
though: The
prototype
makes
significant
changes to the
MachOPlatform
class and
introduces an
ORC runtime
library in
compiler-rt/lib/orc.
Together,
these changes
allow us to
emulate the
dlopen / dlsym
/ dlclose in
the JIT
executor
process. We
can use this
to define what
it means to
run a <i>JIT
program</i>,
rather than
just running a
JIT function
(the way
TargetProcessControl::runAsMain
does):</div>
<div><br>
</div>
<div>
<div
style="color:rgb(0,0,0)"><font
face="monospace">ORC_RT_INTERFACE <font color="#38761d">int64_t</font> <font
color="#0b5394">__orc_rt_macho_run_program</font>(<font color="#38761d">int</font> <font
color="#bf9000">argc</font>, <font color="#38761d">char</font> *<font
color="#bf9000">argv</font>[])
{</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#45818e">using</font> <font
color="#38761d">MainTy</font> = <font
color="#38761d">int</font> (*)(<font color="#38761d">int</font>, <font
color="#38761d">char</font> *[]);</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"><br>
</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#38761d">void</font> *<font
color="#bf9000">H</font> =
__orc_rt_macho_jit_dlopen(<font color="#6aa84f">"Main"</font>,
ORC_RT_RTLD_LAZY);</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#45818e">if</font> (!H) {</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> __orc_rt_log_error(__orc_rt_macho_jit_dlerror());</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#45818e">return</font> -1;</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> }</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"><br>
</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#45818e">auto</font> *<font
color="#bf9000">Main</font> = <font
color="#45818e">reinterpret_cast</font><<font color="#38761d">MainTy</font>>(__orc_rt_macho_jit_dlsym(H, <font
color="#6aa84f">"main"</font>));</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#45818e">if</font> (!Main) {<br>
</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> __orc_rt_log_error(__orc_rt_macho_jit_dlerror());</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#45818e">return</font> -1;</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> }</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"><br>
</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#38761d">int</font> <font
color="#bf9000">Result</font> =
Main(argc,
argv);</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"><br>
</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#45818e">if</font> (__orc_rt_macho_jit_dlclose(H)
== -1)</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> __orc_rt_log_error(__orc_rt_macho_jit_dlerror());</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"><br>
</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace"> <font color="#45818e">return</font> Result;</font></div>
<div
style="color:rgb(0,0,0)"><font
face="monospace">}</font></div>
</div>
<div><br>
</div>
<div>The
functions __orc_rt_macho_jit_dlopen, __orc_rt_macho_jit_dlsym,
and __orc_rt_macho_jit_dlclose behave the same as their dlfcn.h
counterparts
(dlopen,
dlsym,
dlclose), but
operate on
JITDylibs
rather than
regular
dylibs. This
includes
running static
initializers
and
registering
with language
runtimes (e.g.
ObjC). </div>
<div><br>
</div>
<div>While we
could run
static
initializers
before (e.g.
via
LLJIT::runConstructors),
we had to
initiate this
from the JIT
process side,
which has two
significant
drawbacks: (1)
Extra RPC
round trips,
and (2) in the
out-of-process
case:
initializers
not running on
the executor
thread that
requested
them, since
that thread
will be
blocked
waiting for
its call to
return. Issue
(1) only
affects
performance,
but (2) can
affect
correctness if
the
initializers
modify thread
local values,
or interact
with locks or
threads.
Interacting
with threads
from
initializers
is generally
best avoided,
but
nonetheless is
done by
real-world
code, so we
want to
support it. By
using the
runtime we can
improve both
performance
and
correctness
(or at least
consistency
with current
behavior). </div>
<div><br>
</div>
<div>The
effect of this
is that we can
now load C++,
Objective-C
and Swift
programs in
the JIT and
expect them to
run correctly,
at least for
simple cases.
This works
regardless of
whether the
JIT'd code
runs
in-process or
out-of-process. To test all this I have integrated support for the
prototype
runtime into
llvm-jitlink.
You can demo
output from
this tool
below for two
simple input
programs: One
swift, one
C++. All of
this is MachO
specific at
the moment,
but provides a
template that
could be
easily re-used
to support
this on ELF
platforms, and
likely on COFF
platforms too.<br>
</div>
<div><br>
</div>
<div>While the
discussion on
where the
runtime should
live plays out
I will
continue
adding /
moving
functionality
to the
prototype
runtime. Next
up will be
eh-frame
registration
and resolver
functions
(both
currently in
OrcTargetProcess).
After that
I'll try to
tackle support
for native
MachO thread
local storage.</div>
<div><br>
</div>
<div>As
always:
Questions and
comments are
very welcome.</div>
<div><br>
</div>
<div>-- Lang.</div>
<div><br>
</div>
<div>
<div
style="color:rgb(0,0,0)">
<div><font
face="monospace">lhames@Langs-MacBook-Pro
scratch % cat
foo.swift</font></div>
<div><font
face="monospace">class
MyClass {</font></div>
<div><font
face="monospace">
func foo() {</font></div>
<div><font
face="monospace">
print("foo")</font></div>
<div><font
face="monospace">
}</font></div>
<div><font
face="monospace">}</font></div>
<div><font
face="monospace"><br>
</font></div>
<div><font
face="monospace">let
m = MyClass()</font></div>
<div><font
face="monospace">m.foo();</font></div>
<div><font
face="monospace"><br>
</font></div>
<div><font
face="monospace">lhames@Langs-MacBook-Pro
scratch %
xcrun swiftc
-emit-object
-o foo.o
foo.swift
</font></div>
<div><font
face="monospace">lhames@Langs-MacBook-Pro
scratch %
llvm-jitlink
-dlopen
/usr/lib/swift/libswiftCore.dylib
foo.o
</font></div>
<div><font
face="monospace">foo</font></div>
<div><font
face="monospace">lhames@Langs-MacBook-Pro
scratch %
llvm-jitlink
-oop-executor
-dlopen
/usr/lib/swift/libswiftCore.dylib
foo.o</font></div>
<div><font
face="monospace">foo</font></div>
<div><font
face="monospace">lhames@Langs-MacBook-Pro
scratch % cat
inits.cpp </font></div>
<div><font
face="monospace">#include
<iostream></font></div>
<div><font
face="monospace"><br>
</font></div>
<div><font
face="monospace">class
Foo {</font></div>
<div><font
face="monospace">public:</font></div>
<div><font
face="monospace">
Foo() {
std::cout
<<
"Foo::Foo()\n";
}</font></div>
<div><font
face="monospace">
~Foo() {
std::cout
<<
"Foo::~Foo()\n";
}</font></div>
<div><font
face="monospace">
void foo() {
std::cout
<<
"Foo::foo()\n";
}</font></div>
<div><font
face="monospace">};</font></div>
<div><font
face="monospace"><br>
</font></div>
<div><font
face="monospace">Foo
F;</font></div>
<div><font
face="monospace"><br>
</font></div>
<div><font
face="monospace">int
main(int argc,
char *argv[])
{</font></div>
<div><font
face="monospace">
F.foo();</font></div>
<div><font
face="monospace">
return 0;</font></div>
<div><font
face="monospace">}</font></div>
<div><font
face="monospace">lhames@Langs-MacBook-Pro
scratch %
xcrun clang++
-c -o inits.o
inits.cpp</font></div>
<div><font
face="monospace">lhames@Langs-MacBook-Pro
scratch %
llvm-jitlink
inits.o
</font></div>
<div><font
face="monospace">Foo::Foo()</font></div>
<div><font
face="monospace">Foo::foo()</font></div>
<div><font
face="monospace">Foo::~Foo()</font></div>
<div><font
face="monospace">lhames@Langs-MacBook-Pro
scratch %
llvm-jitlink
-oop-executor
inits.o</font></div>
<div><font
face="monospace">Foo::Foo()</font></div>
<div><font
face="monospace">Foo::foo()</font></div>
<div><font
face="monospace">Foo::~Foo()</font></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<pre cols="72">--
<a href="https://flowcrypt.com/pub/stefan.graenitz@gmail.com" target="_blank" moz-do-not-send="true">https://flowcrypt.com/pub/stefan.graenitz@gmail.com</a></pre>
</div>
</blockquote>
</div>
</blockquote>
<pre class="moz-signature" cols="72">--
<a class="moz-txt-link-freetext" href="https://flowcrypt.com/pub/stefan.graenitz@gmail.com">https://flowcrypt.com/pub/stefan.graenitz@gmail.com</a></pre>
</body>
</html>