Subject: Re: Bug in gcc and egcs with .linkonce
From: [email-masked] (Mumit Khan)

29 Aug 1998 07:01:08 -0700
Message-ID: <[email-masked]>
References: <[email-masked]>
Mime-Version: 1.0
Content-Type: TEXT/PLAIN; charset=US-ASCII
To: Ralf Scheidhauer <[email-masked]>
Cc: [email-masked], [email-masked]

On Thu, 27 Aug 1998, Ralf Scheidhauer supplies the test case that causes
program to crash if a function containing a jump table is not inlined. 
This happens on all ix86-*win32 targets. There have similar reports in
egcs-bugs very recently as well.

I was a bit hasty in responding earlier, so here's a bit more info on the
codegen bug. I have a tentative patch, but I'm worried about breakage
elsewhere, especially right when 1.1 is about to be released!

Here's another similar testcase:

  inline
  int func(char c)
  {
    switch (c)
    {
      case 'a':return 1;
      case 't':return 2;
      case 'g':return 3;
      case 'c':return 4;
      case 'n':return 5;
    }
  }

  int main () {
    return func ('g');
  }

now let's look at what the compiler generates for the function when it's
*not* inlined.

	.file	"case-bug.cc"
	[ .... code for main here ... ]
	.section .text$func__Fc,"x"
	.linkonce discard
	.align 4
..globl _func__Fc
	.def	_func__Fc;	.scl	2;	.type	32;	.endef
_func__Fc:
 	[ ... code for func() here ... ]
	[ ... and now the jump table. NOTE: We use .text instead of .rdata 
	  for now ... ]
	.align 4
	.section .text
L8:
	[ ... jump table Here ... ]
	[ ... now back to the function section ... ]
	.section .text$func__Fc,"x"
	.linkonce discard	<<<<< BUG. This confuses the linker
	.align 4
	[ ... rest of code ...]

This is because the win32 definition of ASM_OUTPUT_SECTION_NAME adds 
the ``.linkonce [discard|same_size]'' directive every time!  If you
remove the second .linkonce, everything should work as expected;
otherwise, the linker simply discards one of the "parts" of func()
thanks to the .linkonce directive.

IMO, the correct solution is to use a static list to remember what 
sections we've already produced directives for, and not repeat the 
linkonce for those. See the ASM_OUTPUT_SECTION_NAME macro in 
gcc/config/svr4.h for an example.

One other possible solution is to use ASM_WEAKEN_LABEL to mark it 
..linkonce, but then we don't know if it's a function or variable 
declaration and can't decide on the right qualifier such as ``discard'' 
or ``same_size'' etc. I don't believe this would work for win32 in
general.

Suggestions?

Regards,
Mumit

-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".