diff mbox

[testsuite] Fix multiple definitions of _init

Message ID 1417418467.3387.89.camel@yam-132-YW-E178-FTW
State New
Headers show

Commit Message

Oleg Endo Dec. 1, 2014, 7:21 a.m. UTC
Hi,

When running the testsuite on a sh-elf configuration, some test cases
fail due to multiple definitions of the function '_init'.  This is
because on sh-elf every function is automatically prefixed with a '_'
char.  When defining a C function 'init' in some code, the actual name
becomes '_init' and this conflicts with the _init function in libgcc
(crti.S).  While the behavior of adding the '_' prefix is debatable, the
testsuite failures can be easily fixed by the attached patch.
Is this OK for trunk?

Cheers,
Oleg

gcc/testsuite/ChangeLog:

	* gcc.c-torture/execute/20120919-1.c (init): Rename to initt.
	* gcc.c-torture/execute/pr42248.c: Likewise.
	* gcc.c-torture/execute/pr53688.c: Likewise.
	* gcc.c-torture/execute/pr42614.c: Likewise.

Comments

Richard Biener Dec. 1, 2014, 11:09 a.m. UTC | #1
On Mon, Dec 1, 2014 at 8:21 AM, Oleg Endo <oleg.endo@t-online.de> wrote:
> Hi,
>
> When running the testsuite on a sh-elf configuration, some test cases
> fail due to multiple definitions of the function '_init'.  This is
> because on sh-elf every function is automatically prefixed with a '_'
> char.  When defining a C function 'init' in some code, the actual name
> becomes '_init' and this conflicts with the _init function in libgcc
> (crti.S).  While the behavior of adding the '_' prefix is debatable, the
> testsuite failures can be easily fixed by the attached patch.
> Is this OK for trunk?

The testcases are certainly valid C testcases and thus sh-elf is buggy
here.  As '_init' is a reserved identifier it shouldn't mangle 'init' as
'_init'.

Do you never run into "real" applications naming a function 'init'?

Richard.

> Cheers,
> Oleg
>
> gcc/testsuite/ChangeLog:
>
>         * gcc.c-torture/execute/20120919-1.c (init): Rename to initt.
>         * gcc.c-torture/execute/pr42248.c: Likewise.
>         * gcc.c-torture/execute/pr53688.c: Likewise.
>         * gcc.c-torture/execute/pr42614.c: Likewise.
Oleg Endo Dec. 1, 2014, 10:48 p.m. UTC | #2
On Mon, 2014-12-01 at 12:09 +0100, Richard Biener wrote:
> On Mon, Dec 1, 2014 at 8:21 AM, Oleg Endo <oleg.endo@t-online.de> wrote:
> > Hi,
> >
> > When running the testsuite on a sh-elf configuration, some test cases
> > fail due to multiple definitions of the function '_init'.  This is
> > because on sh-elf every function is automatically prefixed with a '_'
> > char.  When defining a C function 'init' in some code, the actual name
> > becomes '_init' and this conflicts with the _init function in libgcc
> > (crti.S).  While the behavior of adding the '_' prefix is debatable, the
> > testsuite failures can be easily fixed by the attached patch.
> > Is this OK for trunk?
> 
> The testcases are certainly valid C testcases and thus sh-elf is buggy
> here.  As '_init' is a reserved identifier it shouldn't mangle 'init' as
> '_init'.
> 
> Do you never run into "real" applications naming a function 'init'?

Looking for USER_LABEL_PREFIX shows that the '_' prefix mangling scheme
is being used by quite some targets/configs.  So it's not just sh-elf,
but other bare metal configs and their ABIs, where 'init' gets mangled
to '_init' and there's a '.global _init' in libgcc.  Yes, it does break
valid standard C code 'void init (void)', but it's been doing that for
quite a while.

I didn't mean to open a can of worms because of 4 test cases showing up
in sh-elf sim tests.  From what I can see, those 4 cases would also pop
up for other configs, not only sh-elf.  Anyway, the function names in
those test cases don't matter at all, do they?

Cheers,
Oleg
Richard Biener Dec. 2, 2014, 10:22 a.m. UTC | #3
On Mon, Dec 1, 2014 at 11:48 PM, Oleg Endo <oleg.endo@t-online.de> wrote:
> On Mon, 2014-12-01 at 12:09 +0100, Richard Biener wrote:
>> On Mon, Dec 1, 2014 at 8:21 AM, Oleg Endo <oleg.endo@t-online.de> wrote:
>> > Hi,
>> >
>> > When running the testsuite on a sh-elf configuration, some test cases
>> > fail due to multiple definitions of the function '_init'.  This is
>> > because on sh-elf every function is automatically prefixed with a '_'
>> > char.  When defining a C function 'init' in some code, the actual name
>> > becomes '_init' and this conflicts with the _init function in libgcc
>> > (crti.S).  While the behavior of adding the '_' prefix is debatable, the
>> > testsuite failures can be easily fixed by the attached patch.
>> > Is this OK for trunk?
>>
>> The testcases are certainly valid C testcases and thus sh-elf is buggy
>> here.  As '_init' is a reserved identifier it shouldn't mangle 'init' as
>> '_init'.
>>
>> Do you never run into "real" applications naming a function 'init'?
>
> Looking for USER_LABEL_PREFIX shows that the '_' prefix mangling scheme
> is being used by quite some targets/configs.  So it's not just sh-elf,
> but other bare metal configs and their ABIs, where 'init' gets mangled
> to '_init' and there's a '.global _init' in libgcc.  Yes, it does break
> valid standard C code 'void init (void)', but it's been doing that for
> quite a while.

Oh, and I wonder why the global init isn't then __init (two underscores),
as obviously on those targets symbols with _ prefix are not in the
implementation namespace.

> I didn't mean to open a can of worms because of 4 test cases showing up
> in sh-elf sim tests.  From what I can see, those 4 cases would also pop
> up for other configs, not only sh-elf.  Anyway, the function names in
> those test cases don't matter at all, do they?

No, but it looks like papering over a problem.  After all we could have
a valid testcase checking for exactly this situation - that a C function
named 'init' works fine.

Joseph may have more experience with how targets should setup
USER_LABEL_PREFIX to avoid this situation.

Richard.

> Cheers,
> Oleg
>
Oleg Endo Dec. 2, 2014, 10:59 a.m. UTC | #4
On Tue, 2014-12-02 at 11:22 +0100, Richard Biener wrote:
> On Mon, Dec 1, 2014 at 11:48 PM, Oleg Endo <oleg.endo@t-online.de> wrote:
> > On Mon, 2014-12-01 at 12:09 +0100, Richard Biener wrote:
> >> On Mon, Dec 1, 2014 at 8:21 AM, Oleg Endo <oleg.endo@t-online.de> wrote:
> >> > Hi,
> >> >
> >> > When running the testsuite on a sh-elf configuration, some test cases
> >> > fail due to multiple definitions of the function '_init'.  This is
> >> > because on sh-elf every function is automatically prefixed with a '_'
> >> > char.  When defining a C function 'init' in some code, the actual name
> >> > becomes '_init' and this conflicts with the _init function in libgcc
> >> > (crti.S).  While the behavior of adding the '_' prefix is debatable, the
> >> > testsuite failures can be easily fixed by the attached patch.
> >> > Is this OK for trunk?
> >>
> >> The testcases are certainly valid C testcases and thus sh-elf is buggy
> >> here.  As '_init' is a reserved identifier it shouldn't mangle 'init' as
> >> '_init'.
> >>
> >> Do you never run into "real" applications naming a function 'init'?
> >
> > Looking for USER_LABEL_PREFIX shows that the '_' prefix mangling scheme
> > is being used by quite some targets/configs.  So it's not just sh-elf,
> > but other bare metal configs and their ABIs, where 'init' gets mangled
> > to '_init' and there's a '.global _init' in libgcc.  Yes, it does break
> > valid standard C code 'void init (void)', but it's been doing that for
> > quite a while.
> 
> Oh, and I wonder why the global init isn't then __init (two underscores),
> as obviously on those targets symbols with _ prefix are not in the
> implementation namespace.

My guess:  Because it's written in asm, and there it's not known whether
a _ prefix should be used or not.  It's an ABI/convention.  BTW it's not
only the init function, but potentially several others.  E.g.
newlib/libc/sys/sh/crt0.S refers to other symbols such as _stack,
_edata, _end, _main, _exit.  Thus, having something global named "stack"
in a C program will potentially clash.  So while we maybe could use
USER_LABEL_PREFIX in libgcc to add the prefix, there would still be
issues with things defined in e.g. newlib or the linker script.

For bare metal configs / programs having some additional
reserved/prohibited names is not a big deal, as there are often other
restrictions which are even worse.  I guess the issue isn't that bad.
Out of all the gcc test cases, I hit only 4.  In the context of gcc sim
testing, one option could be to use a special toolchain config, which
does not do the _ prefixing.  However, there's no such configure option
and the only way to change it is to change the USER_LABEL_PREFIX
definition, or add a subtarget which doesn't prefix _.  Another option
could be adding something to the global configure stuff so that the
option -fno-leading-underscore can be turned on by default for the
resulting compiler.

Cheers,
Oleg
Mike Stump Dec. 2, 2014, 6:23 p.m. UTC | #5
On Nov 30, 2014, at 11:21 PM, Oleg Endo <oleg.endo@t-online.de> wrote:
> When running the testsuite on a sh-elf configuration, some test cases
> fail due to multiple definitions of the function '_init'.  This is
> because on sh-elf every function is automatically prefixed with a '_'
> char.  When defining a C function 'init' in some code, the actual name
> becomes '_init' and this conflicts with the _init function in libgcc
> (crti.S).  While the behavior of adding the '_' prefix is debatable, the
> testsuite failures can be easily fixed by the attached patch.
> Is this OK for trunk?

No.  It is reasonable for the test suite to fail when the implementation of gcc is wrong (unclean) or newlib startup code is wrong (unclean).  Since that is what happened, the fix is to fix the cleanliness problem.

I’ve read through the thread…  I think the sh newlib port has a trivial bug and should be fixed.  Either, add an underscore or remove one, just like _all_ the other ports.  There is no complexity here, just a typo (or someone copied the wrong port).

When newlib/libc/sys/sh/crt0.S is fixed, and libgcc/config/sh/crt1.S is fixed, then these test cases will pass.

USER_LABEL_PREFIX  is not the issue.  Let me quote from the code:

        .long   _atexit
        .long   _init

This is wrong.

Also, _fini needs to be fixed as well.  It is unfortunate that the fix involves two packages, but, such is life.
Joseph Myers Dec. 2, 2014, 9:55 p.m. UTC | #6
On Tue, 2 Dec 2014, Richard Biener wrote:

> Joseph may have more experience with how targets should setup
> USER_LABEL_PREFIX to avoid this situation.

See e.g. config/arm/lib1funcs.S:

#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x)

(and the associated macro definition of CONCAT1 that uses, etc.).  If you 
have .S sources that may be used on targets both with and without a 
prefix, you should do something similar.  (The ELF gABI says "External C 
symbols have the same names in C and object files' symbol tables.", so ELF 
targets using leading underscores on C symbol names are going against the 
gABI.)
diff mbox

Patch

Index: gcc/testsuite/gcc.c-torture/execute/20120919-1.c
===================================================================
--- gcc/testsuite/gcc.c-torture/execute/20120919-1.c	(revision 218199)
+++ gcc/testsuite/gcc.c-torture/execute/20120919-1.c	(working copy)
@@ -9,9 +9,9 @@ 
 
 extern void abort(void);
 
-void init (int *n, int *dummy) __attribute__ ((noinline,noclone));
+void initt (int *n, int *dummy) __attribute__ ((noinline,noclone));
 
-void init (int *n, int *dummy)
+void initt (int *n, int *dummy)
 {
   if(0 == n) dummy[0] = 0;
 }
@@ -20,7 +20,7 @@ 
 {
   int dummy[1532];
   int i = -1, n = 1, s = 0;
-  init (&n, dummy);
+  initt (&n, dummy);
   while (i < n) {
     if (i == 0) {
       if (pd[i] > 0) {
Index: gcc/testsuite/gcc.c-torture/execute/pr42248.c
===================================================================
--- gcc/testsuite/gcc.c-torture/execute/pr42248.c	(revision 218199)
+++ gcc/testsuite/gcc.c-torture/execute/pr42248.c	(working copy)
@@ -12,7 +12,7 @@ 
 }
 
 void
-init (Scf10 *p, _Complex double y)
+initt (Scf10 *p, _Complex double y)
 {
   p->a = y;
 }
@@ -20,7 +20,7 @@ 
 int
 main ()
 {
-  init (&g1s, (_Complex double)1);
+  initt (&g1s, (_Complex double)1);
   check (g1s, (_Complex double)1);
 
   return 0;
Index: gcc/testsuite/gcc.c-torture/execute/pr53688.c
===================================================================
--- gcc/testsuite/gcc.c-torture/execute/pr53688.c	(revision 218199)
+++ gcc/testsuite/gcc.c-torture/execute/pr53688.c	(working copy)
@@ -5,7 +5,7 @@ 
 } p;
 
 void __attribute__((noinline,noclone))
-init()
+initt()
 {
   __builtin_memcpy (p.part1, "FOOBARFOO", sizeof (p.part1));
   __builtin_memcpy (p.part2, "SPEC CPU", sizeof (p.part2));
@@ -15,7 +15,7 @@ 
 {
   char *x;
   int c;
-  init();
+  initt();
   __builtin_memcpy (&headline[0], p.part1, 9);
   c = 9;
   x = &headline[0];
Index: gcc/testsuite/gcc.c-torture/execute/pr42614.c
===================================================================
--- gcc/testsuite/gcc.c-torture/execute/pr42614.c	(revision 218199)
+++ gcc/testsuite/gcc.c-torture/execute/pr42614.c	(working copy)
@@ -12,7 +12,7 @@ 
   TEntry data[2];
 } TTable;
 
-TTable *init ()
+TTable *initt ()
 {
   return malloc(sizeof(TTable));
 }
@@ -54,7 +54,7 @@ 
 main ()
 {
   unsigned char index = 0;
-  TTable *table_p = init();
+  TTable *table_p = initt();
   TEntry work;
 
   inlined_wrong (&(table_p->data[1]), 1);