[llvm-dev] Storing "blockaddress(@function, %block)" in a global variable?

Peter Collingbourne via llvm-dev llvm-dev at lists.llvm.org
Fri Jul 28 18:38:30 PDT 2017


I think I would expect this to work in general for ELF targets, as long as
both the global variable and the function are either not comdat members or
members of the same comdat.

If I compile your example to .ll I get:

@__sancov_gen_.5 = private constant [3 x i8*] [i8* bitcast
(%"class.std::basic_ostream"* (%"class.std::basic_ostream"*, i8*)*
@_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc to i8*), i8*
blockaddress(@_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc,
%if.then), i8*
blockaddress(@_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc,
%if.else)], section "__sancov_pcs", align 8

and later:

define available_externally dereferenceable(272)
%"class.std::basic_ostream"*
@_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(%"class.std::basic_ostream"*
dereferenceable(272) %__out, i8* %__s) local_unnamed_addr #3 {
  ...
}

The initializer is referencing a function with available_externally
linkage, which I wouldn't expect to work because the object file will not
contain a definition of the function. If I create a .s file from your
example and remove the definition of __sancov_gen_.5 I can produce an
object file using llvm-mc.

So I would probably try changing the instrumentation pass to skip
available_externally functions.

Peter

On Fri, Jul 28, 2017 at 6:03 PM, Kostya Serebryany <kcc at google.com> wrote:

> Hi,
>
> The LangRef warns that "blockaddress(@function, %block)" has a limited and
> target-dependent applicability:  https://llvm.org/docs/
> LangRef.html#addresses-of-basic-blocks
>
> But I wanted very much to save addresses of blocks in a global variable
> and so I did:
>
> % cat cond.c
> void foo(long *a) { if (a) *a = 0; }
>
> % clang -O1  -c  cond.c   -fsanitize-coverage=inline-8bit-counters,pc-table
> -S -o - -emit-llvm
>
> @__sancov_gen_.1 = private constant [3 x i8*] [i8* bitcast (void (i64*)*
> @foo to i8*), i8* blockaddress(@foo, %entry.if.end_crit_edge), i8*
> blockaddress(@foo, %if.then)], section "__sancov_pcs", align 8
>
> Is this expected to work?
> If not, is it reasonable to try to make it work?
>
> This works almost as I want it to, but not quite entirely:
> % cat cout.cpp
> #include <iostream>
> void Foo() { std::cout << ""; }
>
> % clang++   -fsanitize-coverage=inline-8bit-counters,pc-table cout.cpp -O1
> fatal error: error in backend: Undefined temporary symbol
>
> (the error message was added in http://llvm.org/viewvc/
> llvm-project?view=revision&revision=253328 by Oliver Sstannard, CC-ed)
>
> The error comes from lib/MC/ELFObjectWriter.cpp
> and it disappears with -O0 or -O2 or -no-integrated-as
>
> Thanks!
>
> --kcc
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170728/96bee70e/attachment.html>


More information about the llvm-dev mailing list