.text .proc get_fileinfo# get_fileinfo: .prologue 12, 35 [.LVL0:] .mmi .save ar.pfs, r36 alloc r36 = ar.pfs, 1, 5, 3, 0 addl r34 = @gprel(file_info_tree#), gp .save rp, r35 mov r35 = b0 .mmi mov r37 = r1 .body ;; .section .text.unlikely, "ax", @progbits .mmi nop 0 ;; .text .endp get_fileinfo# This is not unlike what gcc -freorder-blocks-and-partition would like to create. Whether or not you consider section switching legal, the assembler shouldn't crash.
Hi Richard, Agreed, the assembler should not crash. I am applying the patch in the attachmrnt to stop the seg fault hapeening. Cheers Nick gas/ChangeLog 2005-06-08 Nick Clifton <nickc@redhat.com> PR 994 * config/tc-ia64.c (slot_index): Check for a NULL first_frag.
Created attachment 510 [details] Fix seg fault by checking for a NULL pointer
Nick's patch avoids the assembler core dump, but results in corrupted unwind info. IMHO, this is worse, since it converted an obvious error into a silent one. I'm thinking the assembler should emit a warning (or perhaps an error) when this problem is seen. Also, the IA-64 compiler should emit a warning (or perhaps an error) when the -freorder-blocks-and-partition option is used, which will say that the option isn't supported for IA-64. It is exactly because of these kinds of problems why I keep saying that section switching should be a hard error. It will be so hard to modify the assembler to get this case right that it likely isn't worth the trouble. I think it is better is to fix the compiler to avoid constructs like this. It will probably take a lot of compiler work too though. The .text.unlikely code needs to be emitted after the function end. Also, you either need to guarantee that you will never put any code in .text.unlikely that can throw an exception, or else you need to emit proper unwind info for it. Emitting proper unwind info for it may require info about the context in which it is being called, in case we need something more than just a body region. Better might be to avoid such cases, which means we need to avoid putting any function returns in a .text.unlikely section, and we need to avoid putting any shrink wrapped prologue/epilogue code in there, etc. This is likely to be a big mess, even if implemented by someone who understands IA-64 code. On second thought, if this is a big enough mess in the compiler, then it might be worthwhile to try to make this work in the assembler. Getting this right in the assembler means that a lot of the assembler internal data in tc-ia64.c needs to be put in a structure and maintained separately for every text region, so that we can handle nested text regions, pushing/popping text regions, etc, and then still be able to sort everything out at the end. My worry here though would be that there are so few people who both understand the inner details of how IA-64 code works, and are willing to do binutils work, that we may not be able to find a competent volunteer to do this work.
Created attachment 511 [details] Warn for section switch that corrupts unwind info. This is my fix for the problem. It does two things: 1) It emits a warning when this problem is detected. tmp.s:21: Warning: Corrupted unwind info due to unsupported section switching 2) It tries to get the unwind info as correct as possible. With Nick's patch, the trailing body region has a length that is a large number computed from an address returned by malloc. With my patch, it is the correct number for this testcase. However, it is only the correct number if it is guaranteed that there is no code after the .text.unlikely section switch. This is not guaranteed to be true in general. So we still need the warning, or code to check for this special case. It isn't immediately obvious how to check for this, or whether we can even check for it without changes to the machine independent parts of the assembler, so I have made no attempt to write code for this check. I simply emit the warning unconditionally.
Richard, is my solution (a warning) acceptable? Or do you have another suggestion? It might be possible to do better, either add more code to get the unwind info correct in this case, or add code to determine when the warning is not necessary (as in this case), but I'm not motivated to try either, as I don't believe this assembler construct should be valid in the first place.
I should point out that while my patch does get the unwind info correct for the .text section (assuming no additional code in .text after the section switch), the .text.unlikely section unwind info is still missing, and hence the code is still broken. Thus the warning may still be useful even if we check for the case where there is no more code in .text after the section switch.
Yes, your warning solution is acceptable. I may look into disabling the section switching stuff for ia64. I'm unconvinced it's worth the effort it would take to get all the unwind info correct. This is "solved" for other platforms by disabling section switching if -fexceptions, but ia64 folk have a habit of using unwind info even without that switch.
Fixed by my patch, which has already been checked in.
See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24934 for a testcase as still ICEs.
So, reopen.
as -x c-lex.s -o /dev/null c-lex.min.s:30: Warning: Corrupted unwind info due to unsupported section switching Assertion failure in ia64_estimate_size_before_relax at ../../gas/config/tc-ia64.c line 3098. binutils-2.16.91.0.4-3 reduction with delta yields .proc get_fileinfo# get_fileinfo: .prologue 12, 35 .save ar.pfs, r36 .save rp, r35 mov r37 = r1 .body .mmi ld8 r14 = [r34] (p6) br.cond.spnt .L318 .mmi nop 0 br.call.sptk.many b0 = splay_tree_new# .mmi nop 0 nop 0 mov r39 = r32 nop 0 .mmb ld8 r38 = [r34] mov r1 = r37 addl r38 = 8, r0 .bbb nop 0 (p9) br.cond.spnt .L325 nop 0 br .L324 .section .text.unlikely .L324: .endp get_fileinfo#
I spent some time looking at this, and I'm giving up. I'm just making this a hard error. If someone else wants to try to make this work, good luck. There are a number of problems here. The .endp is ending up in the wrong frag, because we are in the wrong section. Switching back to the text section before the .endp doesn't help though, as there are other problems. We still have a break in the frag chain. The code in subsegs.c creates a list of frags, one for each text section. The code in tc-ia64.c assumes that all frags except the last one have been "fix"ed. However, with subsegs, we can have multiple un"fix"ed frags. Then there are larger problems such as how to manage code in multiple text sections given that the current assembler unwind support only knows how to handle one section at a time. Plus the fact that the compiler isn't emitting any sensible unwind info for the other text sections. The problems here are far beyond the scope of what I can do, other than just emit an error.
Fixed on mainline. http://sourceware.org/ml/binutils/2005-11/msg00335.html