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

Kostya Serebryany via llvm-dev llvm-dev at lists.llvm.org
Mon Jul 31 13:01:54 PDT 2017


Yes, indeed, thanks Peter!
In fact, asan already rejects available_externally functions, for a similar
reason.

On Fri, Jul 28, 2017 at 6:38 PM, Peter Collingbourne <pcc at google.com> wrote:

> 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/20170731/35003831/attachment.html>


More information about the llvm-dev mailing list