Kostya Serebryany via llvm-dev
2017-Jul-29 01:03 UTC
[llvm-dev] Storing "blockaddress(@function, %block)" in a global variable?
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/c8cb27a2/attachment.html>
Peter Collingbourne via llvm-dev
2017-Jul-29 01:38 UTC
[llvm-dev] Storing "blockaddress(@function, %block)" in a global variable?
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>
Kostya Serebryany via llvm-dev
2017-Jul-31 20:01 UTC
[llvm-dev] Storing "blockaddress(@function, %block)" in a global variable?
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>