Trying to fix #61880, what characters are valid in assembler/symbol names
Hi everyone, I am trying to fix #61880 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61880 but will need some guidance as I am a complete newbie. The problem is concerns gccgo and the way the binaries it generates link with the rest of the objects. I have given a really tiny test case in the bug, but the relevant part is this: We try to use a function written in Go from C. Thus we have something written in Go that is compiled, something written in C that is compiled and them gluing them together with the layer provided with the cgo tool. Symbol names from the different parts need to be the same in order for the linker to match them. The names do not match. I am not sure which side of the naming the problem stands - i.e. if A!=B, should we change A, B or both to match. The symbol/assembler name (I do not know what is the right word) that is generated in the .h header file is: extern int Cgoexp_Dummy (int p0) __asm__("cgo_problem_example_com_demo.Cgoexp_Dummy"); -^ The symbol that exists in the object file is: cgo_problem_example.com_demo.Cgoexp_Dummy ---^ Thus we can either fix __asm__("cgo_problem_example_com_demo.Cgoexp_Dummy") to be __asm__("cgo_problem_example_com.demo.Cgoexp_Dummy") or fix the object name to be cgo_problem_example_com_demo.Cgoexp_Dummy This probably depends on which characters are valid in symbol names. If having two or more '.' is OK then I could patch the cgo tool that generates the __asm__ part If dots have special meaning or there is a custom mangling that has to be considered - I would need to find the part of gcc that issues the object names (which I still cannot identify, any guides welcome) Kind regards: al_shopov
Is escaping of a temp variable valid?
Running into an unexpected result with GCC with following case, but not sure if it is a valid C++ case. #define nullptr 0 enum nonetype { none }; template class class_zoo { public: const T *data; int length; class_zoo (nonetype) : data (nullptr), length (0) {} class_zoo (const T &e) : data (&e), length (1) {} }; int bar (class_zoo p1 = none, class_zoo p2 = none) { if (*p1.data==nullptr) return 1; return 0; } int foo (int *b) // If changing int to const int here, zoo will return 0 (pass) { class_zoo zoo(b); return bar(zoo); } int g = 678; int main () { return foo (&g); } $ g++ main.cpp -fstack-protector -o m $ ./m $ echo $? 1 Expand shows: D.2320 = b_2(D); class_zoo::class_zoo (&zoo, &D.2320); D.2320 ={v} {CLOBBER};<--- D.2320 is dead, but it is address escapes to zoo <--- with stack-protector, D.2322 reuses stack slot of D.2320, thus overwrite D.2320 class_zoo::class_zoo (&D.2322, 0); _8 = bar (zoo, D.2322);< D.2320 is accessed via its address, but value changed now _9 = _8; D.2322 ={v} {CLOBBER}; zoo ={v} {CLOBBER}; ;;succ: 3 ;; basic block 3, loop depth 0 ;;pred: 2 : return _9; ;;succ: EXIT } Partition 0: size 16 align 16 D.2322 D.2320 <--- GCC believes they are not conflict, which is what I not sure of here Partition 2: size 16 align 16 zoo Questions 1. Is this a correct test case? 2. If not, why escaping of D.2320's address to a local is not accounted as conflicting to other local variables? Thanks, Joey
Re: Is escaping of a temp variable valid?
On Fri, Aug 15, 2014 at 10:45 AM, Joey Ye wrote: > Running into an unexpected result with GCC with following case, but > not sure if it is a valid C++ case. > > #define nullptr 0 > enum nonetype { none }; > > template > class class_zoo { > public: > const T *data; > int length; > > class_zoo (nonetype) : data (nullptr), length (0) {} > class_zoo (const T &e) : data (&e), length (1) {} Capturing a const referece via a pointer is error-prone as for example literal constants class_zoo zoo(0) have associated objects that live only throughout the function call. So clearly your testcase is invalid. Richard. > }; > > int bar (class_zoo p1 = none, > class_zoo p2 = none) > { > if (*p1.data==nullptr) return 1; > return 0; > } > > int foo (int *b) // If changing int to const int here, zoo will > return 0 (pass) > { > class_zoo zoo(b); > return bar(zoo); > } > > int g = 678; > int main () > { > return foo (&g); > } > > $ g++ main.cpp -fstack-protector -o m > $ ./m > $ echo $? > 1 > > Expand shows: > D.2320 = b_2(D); > class_zoo::class_zoo (&zoo, &D.2320); > D.2320 ={v} {CLOBBER};<--- D.2320 is dead, but it is address > escapes to zoo ><--- with > stack-protector, D.2322 reuses stack slot of D.2320, thus overwrite > D.2320 > class_zoo::class_zoo (&D.2322, 0); > _8 = bar (zoo, D.2322);< D.2320 is accessed via its > address, but value changed now > _9 = _8; > D.2322 ={v} {CLOBBER}; > zoo ={v} {CLOBBER}; > ;;succ: 3 > > ;; basic block 3, loop depth 0 > ;;pred: 2 > : > return _9; > ;;succ: EXIT > > } > > > Partition 0: size 16 align 16 > D.2322 D.2320 <--- GCC believes they are not > conflict, which is what I not sure of here > Partition 2: size 16 align 16 > zoo > > Questions > 1. Is this a correct test case? > 2. If not, why escaping of D.2320's address to a local is not > accounted as conflicting to other local variables? > > Thanks, > Joey
Re: Trying to fix #61880, what characters are valid in assembler/symbol names
On Fri, Aug 15, 2014 at 12:48 AM, Alexander Shopov wrote: > > The symbol/assembler name (I do not know what is the right word) that > is generated in the .h header file is: > extern int Cgoexp_Dummy (int p0) > __asm__("cgo_problem_example_com_demo.Cgoexp_Dummy"); > > The symbol that exists in the object file is: > cgo_problem_example.com_demo.Cgoexp_Dummy > ---^ Normally the first name looks more right. The problem is some confusion over how to handle a package name that contains a '.'--in your case, example.com. The go tool will be passing a -fgo-pkgpath option to gccgo and a -gccgopkgpath option to cgo. You can use "go build -x" to see the exact commands being run. First make sure that those options are the same. If they are the same, either gccgo or cgo is handling the option differently--it looks like one is convert the '.' to '_' and the other is not. They need to do the same thing. Ian
What are open tasks about GIMPLE loop optimizations?
Dear GCC Developers, Nobody answers my question below, so perhaps something wrong with my email :) So let me clarify in more details what I’m asking about. I’ve made some very very very basic evaluation of GCC code ([1]) and started to think about concrete task to contribute to GCC (language and machine optimization would be interesting to me, in particular, loop optimization). I cannot invent this task myself because my knowledge of GCC and compilers in general is not enough for this. And even if I could think out something perhaps GCC developers have their own understanding of the world. Then I have looked at GCC site to answer my question. What I could find about loop optimizations is information from GNU Tools Cauldron 2012, “Status of High level Loop Optimizations”. So perhaps this is out-of-date in 2014. Unfortunately, I have not enough time, so I would not commit to manage a task which is on the critical task. (Are you interested only in full time developers?) So it would be great if you could advise some tasks, which could be useful to gcc in some future, however nobody will miss if I cannot do it (as you had not time/people for these tasks anyway :) ). What do you think? Thanks, Evgeniya [1] Used GDB to look inside GCC. Wrote some notes in my blog which could be useful to other newbies (http://perfstories.wordpress.com/2013/11/17/compiler-internals-introduction-to-a-new-post-series/). -- Forwarded message -- From: Evgeniya Maenkova Date: Fri, Aug 8, 2014 at 6:50 PM Subject: GIMPLE optimization passes: any Road Map? To: gcc@gcc.gnu.org Dear GCC Developers! Could you please clarify about GIMPLE loop passes? Where could I find the latest changes in these passes? Is it trunk or some of the branches? May I look at some RoadMap on GIMPLE loop optimizations? Actually, I ask these questions because I would like to contribute to GCC. GIMPLE optimizations would be interesting to me (in particular, loop optimizations). However, I’m newbie at GCC and have not enough time, so would not commit to manage a task which is on the critical path. So it would be great if you could advise some tasks, which could be useful to gcc in some future, however nobody will miss if I can’t do it (as you had not time/people for these tasks anyway :) ). Thank you! Evgeniya
LTO inhibiting dwarf lexical blocks output
So... I've been getting my feet wet with LTO and debugging and I noticed a seemingly unrelated yet annoying problem. On x86-64, gcc.dg/guality/pr48437.c fails when run in LTO mode. I've compared the dwarf output with and without LTO, and I noticed that the DW_TAG_lexical_block is missing from the LTO case. The relevant bit is that without LTO, we have a DW_TAG_lexical_block for lines 3-6, which is not present in the LTO case: 1 volatile int i; 2 for (i = 3; i < 7; ++i) 3{ 4 extern int i; 5 asm volatile (NOP : : : "memory"); 6} The reason this tag is not generated is because gen_block_die() unsets must_output_die because there are no BLOCK_VARS associated with the BLOCK. must_output_die = ((BLOCK_VARS (stmt) != NULL || BLOCK_NUM_NONLOCALIZED_VARS (stmt)) && (TREE_USED (stmt) || TREE_ASM_WRITTEN (stmt) || BLOCK_ABSTRACT (stmt))); And there is no block var because the streamer purposely avoided streaming an extern block var: /* We avoid outputting external vars or functions by reference to the global decls section as we do not want to have them enter decl merging. This is, of course, only for the call for streaming BLOCK_VARS, but other callers are safe. */ /* ??? FIXME wrt SCC streaming. Drop these for now. */ if (VAR_OR_FUNCTION_DECL_P (t) && DECL_EXTERNAL (t)) ; /* stream_write_tree_shallow_non_ref (ob, t, ref_p); */ else stream_write_tree (ob, t, ref_p); I naively tried to uncomment the offending line, but that brought about other problems in DFS assertions. I wasn't on the hunt for this, but I'm now curious. Can you (or anyone else) pontificate on this? Do we avoid streaming extern block variables by design? Thanks. Aldy
Re: LTO inhibiting dwarf lexical blocks output
On Fri, Aug 15, 2014 at 9:59 PM, Aldy Hernandez wrote: > So... I've been getting my feet wet with LTO and debugging and I noticed a > seemingly unrelated yet annoying problem. On x86-64, > gcc.dg/guality/pr48437.c fails when run in LTO mode. Eh, sorry I can't actually answer your question but, eh... Isn't the only real solution: to generate this kind of DIEs earlier (maybe already immediately after parsing) and stream them? Otherwise, how can this possibly be made to work with multi-language LTO? It seems to me that only the lowest-level DWARF (things we don't know about until RTL, like CFI) should be done at link time. Things like scoping and types are language dependent and have to be generated before streaming. Again, sorry for not actually being helpful - just a thought ;-) Ciao! Steven
Re: LTO inhibiting dwarf lexical blocks output
Isn't the only real solution: to generate this kind of DIEs earlier (maybe already immediately after parsing) and stream them? Ultimately yes, and that's what I hope to work on, but I was mostly curious because at stream out time, the information *is* there, and we silently dropped it. Aldy
Re: LTO inhibiting dwarf lexical blocks output
On Fri, Aug 15, 2014 at 10:08:38PM +0200, Steven Bosscher wrote: > On Fri, Aug 15, 2014 at 9:59 PM, Aldy Hernandez wrote: > > So... I've been getting my feet wet with LTO and debugging and I noticed a > > seemingly unrelated yet annoying problem. On x86-64, > > gcc.dg/guality/pr48437.c fails when run in LTO mode. > > > Eh, sorry I can't actually answer your question but, eh... > > Isn't the only real solution: to generate this kind of DIEs earlier > (maybe already immediately after parsing) and stream them? > > Otherwise, how can this possibly be made to work with multi-language LTO? > > It seems to me that only the lowest-level DWARF (things we don't know > about until RTL, like CFI) should be done at link time. Things like > scoping and types are language dependent and have to be generated > before streaming. > > Again, sorry for not actually being helpful - just a thought ;-) The plan is indeed to generate as much DWARF as possible early. But, BLOCKs are something which if you throw away during compilation like LTO does right now will never work properly, because while some minimal DWARF tree can be created for it early, for the lexical block to be useful you need to track on which exact instructions the lexical block is in scope and on which it is not. Jakub
Re: LTO inhibiting dwarf lexical blocks output
> So... I've been getting my feet wet with LTO and debugging and I > noticed a seemingly unrelated yet annoying problem. On x86-64, > gcc.dg/guality/pr48437.c fails when run in LTO mode. > > I've compared the dwarf output with and without LTO, and I noticed > that the DW_TAG_lexical_block is missing from the LTO case. > > The relevant bit is that without LTO, we have a DW_TAG_lexical_block > for lines 3-6, which is not present in the LTO case: > > 1 volatile int i; > 2 for (i = 3; i < 7; ++i) > 3{ > 4 extern int i; > 5 asm volatile (NOP : : : "memory"); > 6} > > The reason this tag is not generated is because gen_block_die() > unsets must_output_die because there are no BLOCK_VARS associated > with the BLOCK. > > must_output_die = ((BLOCK_VARS (stmt) != NULL > || BLOCK_NUM_NONLOCALIZED_VARS (stmt)) > && (TREE_USED (stmt) > || TREE_ASM_WRITTEN (stmt) > || BLOCK_ABSTRACT (stmt))); > > And there is no block var because the streamer purposely avoided > streaming an extern block var: > > /* We avoid outputting external vars or functions by reference >to the global decls section as we do not want to have them >enter decl merging. This is, of course, only for the call >for streaming BLOCK_VARS, but other callers are safe. */ > /* ??? FIXME wrt SCC streaming. Drop these for now. */ > if (VAR_OR_FUNCTION_DECL_P (t) > && DECL_EXTERNAL (t)) > ; /* stream_write_tree_shallow_non_ref (ob, t, ref_p); */ > else > stream_write_tree (ob, t, ref_p); > > I naively tried to uncomment the offending line, but that brought > about other problems in DFS assertions. The code deciding what to output is duplicated in between lto-streamer and tree-streamer. I suppose you want to update DFS::DFS_write_tree_body > > I wasn't on the hunt for this, but I'm now curious. Can you (or > anyone else) pontificate on this? Do we avoid streaming extern block > variables by design? I think the problem here is that blocks are hold together by DECL_CHAIN. Becuase the declarations get merged across compilation units based on their assembler names, they can sit in at most one block. Merging them will then probably accidentaly marge tails of BLOCK_VARs lists. Honza > > Thanks. > Aldy
ASAN test failures make compare_tests useless
On the compile farm, ASAN tests seem to fail a lot like: FAIL: c-c++-common/asan/global-overflow-1.c -O0 output pattern test, is ==31166==ERROR: AddressSanitizer failed to allocate 0xdfff0001000 (15392894357504) bytes at address 2008fff7000 (errno: 12) ==31166==ReserveShadowMemoryRange failed while trying to map 0xdfff0001000 bytes. Perhaps you're using ulimit -v , should match READ of size 1 at 0x[0-9a-f]+ thread T0.*( The problem is that those addresses and sizes are very random, so when I compare the test results of a pristine trunk with a patched one, I get: New tests that FAIL: unix//-m64: c-c++-common/asan/global-overflow-1.c -O0 output pattern test, is ==12875==ERROR: AddressSanitizer failed to allocate 0xdfff0001000 (15392894357504) bytes at address 2008fff7000 (errno: 12) unix//-m64: c-c++-common/asan/global-overflow-1.c -O0 output pattern test, is ==18428==ERROR: AddressSanitizer failed to allocate 0xdfff0001000 (15392894357504) bytes at address 2008fff7000 (errno: 12) [... hundreds of ASAN tests that failed...] Old tests that failed, that have disappeared: (Eeek!) unix//-m64: c-c++-common/asan/global-overflow-1.c -O0 output pattern test, is ==30142==ERROR: AddressSanitizer failed to allocate 0xdfff0001000 (15392894357504) bytes at address 2008fff7000 (errno: 12) unix//-m64: c-c++-common/asan/global-overflow-1.c -O0 output pattern test, is ==31166==ERROR: AddressSanitizer failed to allocate 0xdfff0001000 (15392894357504) bytes at address 2008fff7000 (errno: 12) [... the same hundreds of tests that already failed before...] The above makes very difficult to identify failures caused by my patch. Can we remove the "==" part of the error? This way compare_tests will ignore the failures. Alternatively, I could patch compare_tests to sed out that part before comparing. Would that be acceptable? Cheers, Manuel.