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:
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
More information about the Gcc-bugs
mailing list