Bug 994 - section switch in function causes segfault
Summary: section switch in function causes segfault
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: gas (show other bugs)
Version: 2.17
: P2 normal
Target Milestone: ---
Assignee: wilson@specifixinc.com
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-06-07 22:07 UTC by Richard Henderson
Modified: 2005-11-23 04:41 UTC (History)
2 users (show)

See Also:
Host:
Target: ia64-linux
Build:
Last reconfirmed:


Attachments
Fix seg fault by checking for a NULL pointer (371 bytes, patch)
2005-06-08 15:46 UTC, Nick Clifton
Details | Diff
Warn for section switch that corrupts unwind info. (897 bytes, patch)
2005-06-08 19:55 UTC, wilson@specifixinc.com
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Henderson 2005-06-07 22:07:09 UTC
.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.
Comment 1 Nick Clifton 2005-06-08 15:45:45 UTC
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.
Comment 2 Nick Clifton 2005-06-08 15:46:39 UTC
Created attachment 510 [details]
Fix seg fault by checking for a NULL pointer
Comment 3 wilson@specifixinc.com 2005-06-08 18:48:57 UTC
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.
Comment 4 wilson@specifixinc.com 2005-06-08 19:55:06 UTC
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.
Comment 5 wilson@specifixinc.com 2005-06-08 20:00:05 UTC
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.
Comment 6 wilson@specifixinc.com 2005-06-08 20:09:10 UTC
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.
Comment 7 Richard Henderson 2005-06-08 20:19:55 UTC
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.
Comment 8 wilson@specifixinc.com 2005-06-08 21:12:22 UTC
Fixed by my patch, which has already been checked in.
Comment 9 Richard Biener 2005-11-18 21:05:29 UTC
See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24934 for a testcase as still ICEs.
Comment 10 Richard Biener 2005-11-18 21:06:12 UTC
So, reopen.
Comment 11 Richard Biener 2005-11-18 21:18:10 UTC
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#
Comment 12 wilson@specifix.com 2005-11-23 03:25:46 UTC
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.
Comment 13 wilson@specifix.com 2005-11-23 04:41:28 UTC
Fixed on mainline.
    http://sourceware.org/ml/binutils/2005-11/msg00335.html