Bug in gcc and egcs with .linkonce

Mumit Khan khan@xraylith.wisc.edu
Fri Aug 28 18:04:00 GMT 1998

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:

  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
 	[ ... code for func() here ... ]
	[ ... and now the jump table. NOTE: We use .text instead of .rdata 
	  for now ... ]
	.align 4
	.section .text
	[ ... 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



More information about the Gcc-bugs mailing list