* global vars and symbol visibility for mips32/elf @ 1996-08-09 2:46 David S. Miller 1996-08-09 5:24 ` David S. Miller ` (2 more replies) 0 siblings, 3 replies; 28+ messages in thread From: David S. Miller @ 1996-08-09 2:46 UTC (permalink / raw) To: gcc2; +Cc: gas2 I have this problem and I don't know who exactly (binutils or gcc) is causing the problem. Hopefully with the homework I have done my debugging information will allow someone to see what and where the problem is. I have support for Linux/MIPS written for gcc/binutils. It uses the generic elf32-mips support in binutils. I am also using GNU libc to link against. Here is the delimma: When running c-torture I get a failure for execute/960218-1.c which looks like: int glob; g (x) { glob = x; return 0; } f (x) { int a = ~x; while (a) a = g (a); } main () { f (3); if (glob != -4) abort (); exit (0); } The problem is caused by the symbol 'glob'. GNU libc also has a symbol glob. The assembly output by gcc for the glob variable in the 960218-1.c test case looks like: .comm glob,4,4 And that is it. When assembled by gas into an object file it's symbol entry looks like. 00000004 C glob Now when it is linked, the problem occurs, the linker decides to override this symbol with the symbol for 'glob' in GNU libc, so in the final executable image glob is undefined and will be resolved at dynamic link time. This of course causes the test to erroneously write into the elf pltgot stub instructions when assigning values to the variable 'glob' in the test program. More data points. The symbol table entry for 'glob' in my shared GNU libc looks like: 600462f0 A glob I played around with the native assembler/linker under IRIX6.2 using gcc and here is what I found them to be doing when compiling this program. gcc for the IRIX6.2 target outputs the glob symbol information in the same way as my MIPS/Linux gcc does: .comm glob,4 The IRIX6.2 assembler also created the symbol in the same way within the object file: 00000004 C glob The IRIX6.2 linker however places this symbol in the MIPS_ACOMMON section of the resulting executable and does not override using the libc symbol of the same name (the shared IRIX libc does in fact have a symbol named 'glob' just like my MIPS/Linux GNU libc does). [37] | 268505200| 4|OBJT |GLOB |DEFAULT |MIPS_ACOMMON|glob The IRIX6.2 compiler outputs the 'glob' symbol differently in the resulting assembly. .globl glob .lcomm glob 4 Does anyone know who is at fault here (gcc, binutils, or my GNU libc for some reason) and how this problem can be resolved? This is all using the latest snapshots of gas and gcc btw. dm@engr.sgi.com 'Ooohh.. "FreeBSD is faster over loopback, when compared to Linux over the wire". Film at 11.' -Linus ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-09 2:46 global vars and symbol visibility for mips32/elf David S. Miller @ 1996-08-09 5:24 ` David S. Miller 1996-08-09 9:01 ` Ian Lance Taylor 1996-08-09 8:30 ` Ian Lance Taylor 1996-08-13 9:06 ` Ruediger Helsch 2 siblings, 1 reply; 28+ messages in thread From: David S. Miller @ 1996-08-09 5:24 UTC (permalink / raw) To: dm; +Cc: gcc2, gas2 Addendum, after further reasearch, the following patch to bfd/elflink.h "fixes" my problem. I say "fixes" because I am doubtful that my fix is correct. Would someone who is more knowledgable please comment on my change? --- elflink.h.~1~ Fri Aug 9 05:19:07 1996 +++ elflink.h Fri Aug 9 05:20:37 1996 @@ -685,7 +685,7 @@ if (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak || (h->root.type == bfd_link_hash_common - && bind == STB_WEAK)) + && (bind == STB_WEAK || bind == STB_GLOBAL))) { sec = bfd_und_section_ptr; definition = false; ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-09 5:24 ` David S. Miller @ 1996-08-09 9:01 ` Ian Lance Taylor 0 siblings, 0 replies; 28+ messages in thread From: Ian Lance Taylor @ 1996-08-09 9:01 UTC (permalink / raw) To: dm; +Cc: dm, gcc2, gas2 Date: Fri, 9 Aug 1996 05:24:28 -0700 From: "David S. Miller" <dm@neteng.engr.sgi.com> Addendum, after further reasearch, the following patch to bfd/elflink.h "fixes" my problem. I say "fixes" because I am doubtful that my fix is correct. Would someone who is more knowledgable please comment on my change? --- elflink.h.~1~ Fri Aug 9 05:19:07 1996 +++ elflink.h Fri Aug 9 05:20:37 1996 @@ -685,7 +685,7 @@ if (h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak || (h->root.type == bfd_link_hash_common - && bind == STB_WEAK)) + && (bind == STB_WEAK || bind == STB_GLOBAL))) { sec = bfd_und_section_ptr; definition = false; This patch is not correct. I have not tested this, but I believe that it will break a program that looks like this: int sys_nerr; foo () { printf ("%d\n", sys_nerr); } Your patch will cause the program to use the uninitialized common variable sys_nerr. However, what is desired here is that sys_nerr become a reference to the global variable sys_nerr in the shared library. Ian ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-09 2:46 global vars and symbol visibility for mips32/elf David S. Miller 1996-08-09 5:24 ` David S. Miller @ 1996-08-09 8:30 ` Ian Lance Taylor 1996-08-09 13:13 ` Ulrich Drepper 1996-08-13 9:06 ` Ruediger Helsch 2 siblings, 1 reply; 28+ messages in thread From: Ian Lance Taylor @ 1996-08-09 8:30 UTC (permalink / raw) To: dm; +Cc: gcc2, gas2 Date: Fri, 9 Aug 1996 02:46:18 -0700 From: "David S. Miller" <dm@neteng.engr.sgi.com> The problem is caused by the symbol 'glob'. GNU libc also has a symbol glob. This is the bug. An ANSI C compliant shared library may not have a global symbol which infringes on the ANSI C namespace. The symbol must, instead, be weak. It works to have a global symbol in a normal archive library, because then it will only be included if there is no other definition. However, all symbols in a shared library are included if any are, so there must be no extraneous global symbols. The IRIX6.2 linker however places this symbol in the MIPS_ACOMMON section of the resulting executable and does not override using the libc symbol of the same name (the shared IRIX libc does in fact have a symbol named 'glob' just like my MIPS/Linux GNU libc does). If you use elfdump -Dt on the Irix 6.2 libc, you will see that glob is a weak symbol. The use of the MIPS_ACOMMON section is an Irix linker optimization, not supported by gld, which has no particular bearing on this issue. Ian ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-09 8:30 ` Ian Lance Taylor @ 1996-08-09 13:13 ` Ulrich Drepper 1996-08-09 15:30 ` Ian Lance Taylor 0 siblings, 1 reply; 28+ messages in thread From: Ulrich Drepper @ 1996-08-09 13:13 UTC (permalink / raw) To: ian; +Cc: dm, gcc2, gas2 From: Ian Lance Taylor <ian@cygnus.com> Subject: Re: global vars and symbol visibility for mips32/elf Date: Fri, 9 Aug 1996 11:29:54 -0400 > The problem is caused by the symbol 'glob'. GNU libc also has a > symbol glob. > > This is the bug. An ANSI C compliant shared library may not have a > global symbol which infringes on the ANSI C namespace. The symbol > must, instead, be weak. Why should `glob' be made weak? In GNU libc we make a symbol only weak if necessary. It is correct that no symbol in a ISO C lib must have this name. But if the object file in the shared lib which contains the definition of glob is transitively not used by any ISO C function this is ok. At least this is what I currently know. Reading your words it seems that using a shared lib introduces *all* symbols of the shared lib in the namespace of the application. I.e., all symbols not mentioned in ISO C must be weak. Is this how it is implemented in GNU ld and how it is intend in ELF? If yes, this would mean that nearly every symbol in the shared lib must be weak. Thanks, -- Uli --------------. drepper@cygnus.com ,-. Rubensstrasse 5 Ulrich Drepper \ ,--------------------' \ 76149 Karlsruhe/Germany Cygnus Support `--' drepper@gnu.ai.mit.edu `------------------------ ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-09 13:13 ` Ulrich Drepper @ 1996-08-09 15:30 ` Ian Lance Taylor 1996-08-10 17:37 ` Richard Stallman 0 siblings, 1 reply; 28+ messages in thread From: Ian Lance Taylor @ 1996-08-09 15:30 UTC (permalink / raw) To: drepper; +Cc: dm, gcc2, gas2 Date: Fri, 09 Aug 1996 13:13:00 -0700 From: Ulrich Drepper <drepper@cygnus.com> From: Ian Lance Taylor <ian@cygnus.com> Subject: Re: global vars and symbol visibility for mips32/elf Date: Fri, 9 Aug 1996 11:29:54 -0400 > The problem is caused by the symbol 'glob'. GNU libc also has a > symbol glob. > > This is the bug. An ANSI C compliant shared library may not have a > global symbol which infringes on the ANSI C namespace. The symbol > must, instead, be weak. Why should `glob' be made weak? In GNU libc we make a symbol only weak if necessary. It is correct that no symbol in a ISO C lib must have this name. But if the object file in the shared lib which contains the definition of glob is transitively not used by any ISO C function this is ok. At least this is what I currently know. That turns out not to be the case. A shared library is not like an archive library. A shared library is a single object. Everything that composes a shared library is linked together. There is only one set of symbols. There is no way for the linker to form any sort of transitive closure operation, because there is no longer any distinction between the various object files which compose the shared library. Reading your words it seems that using a shared lib introduces *all* symbols of the shared lib in the namespace of the application. I.e., all symbols not mentioned in ISO C must be weak. Is this how it is implemented in GNU ld and how it is intend in ELF? Yes. That's how it's implemented in any ELF linker. If yes, this would mean that nearly every symbol in the shared lib must be weak. Right. Every symbol in the ANSI C namespace must be weak (in other words, you don't have to worry about symbols which start with underscore). If you look at libc.so on an SVR4 system, that is what you will see. Ian ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-09 15:30 ` Ian Lance Taylor @ 1996-08-10 17:37 ` Richard Stallman 1996-08-10 19:41 ` Ian Lance Taylor 0 siblings, 1 reply; 28+ messages in thread From: Richard Stallman @ 1996-08-10 17:37 UTC (permalink / raw) To: ian; +Cc: drepper, dm, gcc2, gas2 That turns out not to be the case. A shared library is not like an archive library. A shared library is a single object. Everything that composes a shared library is linked together. There is only one set of symbols. There is no way for the linker to form any sort of transitive closure operation, because there is no longer any distinction between the various object files which compose the shared library. Although this may be how things work now, it is not really a useful way for things to work. Dividing an ordinary library into separate members provides two benefits: * The members you don't refer to, do not take up space in your program. * The members you don't refer to, do not fill up your program's name space. The first benefit is not relevant or possible when using a shared library, but the second is completely applicable. Linking with a shared library should give you exactly the same external symbols that you would get by linking against the unshared library it was made from. Even if other people's shared library implementations don't do this right, ours should do it right. Doing this right does not require any changes in the shared library run-time mechanism. It only requires some way of representing, in the shared library's symbol table, a division of external symbols into various "library members". Then ld can treat as weak any external definitions which are not in the same "library members" as some symbol that is referenced. Each "library member" should have references as well as definitions; that way, ld can tell that if "library member" A is referenced, and it references member B, then the definitions in B are not weak. With an open-ended format such as ELF, it should not be hard to design a way of representing this information, which does not conflict with anything else and will not confuse other linkers. If ld finds this data, it should act accordingly; otherwise, it should do what it does now. That way, each of our tools is upward compatible. This will make it possible to turn any unshared library into a shared library, with no special precautions, and get no change in the behavior except for sharing of memory. Since ELF is the format that GNU systems use, it is not crucial to implement this in formats other than ELF. Would the people who work on ld please respond? ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-10 17:37 ` Richard Stallman @ 1996-08-10 19:41 ` Ian Lance Taylor 1996-08-10 23:26 ` Jim Wilson ` (2 more replies) 0 siblings, 3 replies; 28+ messages in thread From: Ian Lance Taylor @ 1996-08-10 19:41 UTC (permalink / raw) To: rms; +Cc: drepper, dm, gcc2, gas2 Date: Sat, 10 Aug 1996 20:37:03 -0400 From: Richard Stallman <rms@gnu.ai.mit.edu> That turns out not to be the case. A shared library is not like an archive library. A shared library is a single object. Everything that composes a shared library is linked together. There is only one set of symbols. There is no way for the linker to form any sort of transitive closure operation, because there is no longer any distinction between the various object files which compose the shared library. Although this may be how things work now, it is not really a useful way for things to work. Dividing an ordinary library into separate members provides two benefits: * The members you don't refer to, do not take up space in your program. * The members you don't refer to, do not fill up your program's name space. An ELF shared library only fills up a program's name space in a very specific sense. If a shared library defines a function foo, and your program defines a function foo, that does not cause any conflict. Your program's definition of foo is used. If functions in the shared library call foo, they will call your program's definition of foo rather than the shared library's definition. In this sense, shared libraries act just like archive libraries. The case which causes trouble is when a program uses a common variable (an uninitialized variable in C; most languages, including C++, have no notion of common variables). A common variable is treated as an undefined reference, unless no definition is seen. In the latter case, the common variable becomes a definition. When a common variable is used, the linker will resolve it against a definition found in a shared library. This is different from the handling of an archive library, at least in ELF. In an ELF archive library, a particular object will not be included in the link merely to satisfy a common reference; it will only be included to satisfy an undefined reference. In some cases, it will be desirable to resolve a common symbol with the definition in the shared library. This would be desirable when the actual intent was to use the initialized variable in the shared library. For example, if a program uses ``int optind;'' rather than ``extern int optind;'', and it also calls getopt, then, in both a shared library and an archive library, the common symbol optind will wind up referring to the initialized variable optind, rather than creating a new, uninitialized, optind variable. Thus, the only sense in which shared libraries occupy a program's name space is that common symbols will sometimes be bound to symbols defined in a shared library. Now that I've written this, I see that, since an ELF symbol table records whether a symbol represents a function or a variable, it would be possible to make the linker refuse to resolve a common symbol (which must represent a variable) against a function defined in a shared library. This will introduce a somewhat confusing situation in that a single symbol will be both a variable and a function. However, as far as I can see, if any actual confusion results from this, then the same program would not have worked correctly in the archive library case either. I will make this change. This will, as it happens, fix the particular test case which started this thread, so I was wrong in believing that this was a bug in the shared library. This will reduce the problematic cases in a shared library to global variables. It will continue to be the case that ELF common symbols and global variables will be resolved differently when using shared libraries as opposed to archive libraries. This should be much less of a problem, since libraries typically have relatively few global variables. Doing this right does not require any changes in the shared library run-time mechanism. It only requires some way of representing, in the shared library's symbol table, a division of external symbols into various "library members". Then ld can treat as weak any external definitions which are not in the same "library members" as some symbol that is referenced. Each "library member" should have references as well as definitions; that way, ld can tell that if "library member" A is referenced, and it references member B, then the definitions in B are not weak. With an open-ended format such as ELF, it should not be hard to design a way of representing this information, which does not conflict with anything else and will not confuse other linkers. If ld finds this data, it should act accordingly; otherwise, it should do what it does now. That way, each of our tools is upward compatible. This will make it possible to turn any unshared library into a shared library, with no special precautions, and get no change in the behavior except for sharing of memory. I can not see how to implement this without more than doubling the time it takes to link against a shared library. Linking against a shared library is a common operation, some shared libraries are large, and the amount of time it takes to link against them is important. I believe that this would be a poor tradeoff. Ian ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-10 19:41 ` Ian Lance Taylor @ 1996-08-10 23:26 ` Jim Wilson 1996-08-11 1:44 ` Richard Stallman 1996-08-13 10:58 ` Ruediger Helsch 2 siblings, 0 replies; 28+ messages in thread From: Jim Wilson @ 1996-08-10 23:26 UTC (permalink / raw) To: Ian Lance Taylor; +Cc: rms, drepper, dm, gcc2, gas2 The case which causes trouble is when a program uses a common variable (an uninitialized variable in C; most languages, including C++, have no notion of common variables). ANSI/ISO C also does not have common variables. A program with multiple external definitions of a variable has undefined behaviour. However, C compilers that make this work by treating uninitialized variables as common are so prevalent that most people aren't aware of this. This particular feature is mentioned in the `Common Extensions' appendix, in the section `Multiple External Definitions'. This also means that, technically, if you want to make sure that other ANSI/ISO C compilers can compile your code, you must use -fno-common in addition to -ansi and -pedantic. Jim ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-10 19:41 ` Ian Lance Taylor 1996-08-10 23:26 ` Jim Wilson @ 1996-08-11 1:44 ` Richard Stallman 1996-08-13 10:58 ` Ruediger Helsch 2 siblings, 0 replies; 28+ messages in thread From: Richard Stallman @ 1996-08-11 1:44 UTC (permalink / raw) To: ian; +Cc: drepper, dm, gcc2, gas2 If a shared library defines a function foo, and your program defines a function foo, that does not cause any conflict. Your program's definition of foo is used. If functions in the shared library call foo, they will call your program's definition of foo rather than the shared library's definition. In this sense, shared libraries act just like archive libraries. This is not, in general, what archive libraries do. Archive libraries do this in the common case where each defined global is in a separate member. But if one member defines two different globals, the archive library does not work this way. It is good practice, in most situations, to put each global definition into a separate member, but it is not universal practice. If one member defines two global symbols X and Y, you can have a program which links with no complaint against the shared library, but would get an error if linked against the archive library. All the program needs to do is reference X and define Y as weak. The archive library would define Y and thus override the weak definition from the program. The shared library would, I expect, let the program override Y's definition. I think we should make the shared library work just like the archive in all cases. What is needed is a table of implications: If symbol foo is referenced, treat symbol bar as strong. If symbol bar is referenced, treat symbol foo as strong. If symbol quux is referenced, treat symbols foo and bar as strong. ... (In that example, I've assumed that one member defines both foo and bar, while another member defines quux and references foo.) This table would selectively override the default behavior, which is the same as now (each defined global symbol in the shared library acts as weak). Given this table, there would be no need to do anything special for common symbols. A common symbol in the library could be treated just like any other definition in the library: use it to resolve an undefined reference, or if forced by the table due to a reference to some other symbol. I don't think this would make linking much slower. I think it could be made quite fast by means of a table that parallels the main symbol table in the library, so that you reference it using the same index used in the main symbol table, rather than by looking up names, ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-10 19:41 ` Ian Lance Taylor 1996-08-10 23:26 ` Jim Wilson 1996-08-11 1:44 ` Richard Stallman @ 1996-08-13 10:58 ` Ruediger Helsch 1996-08-13 13:36 ` Jim Wilson 2 siblings, 1 reply; 28+ messages in thread From: Ruediger Helsch @ 1996-08-13 10:58 UTC (permalink / raw) To: Ian Lance Taylor; +Cc: rms, drepper, dm, gcc2, gas2 On Sat, 10 Aug 1996, Ian Lance Taylor wrote: > The case which causes trouble is when a program uses a common variable > (an uninitialized variable in C; most languages, including C++, have > no notion of common variables). A common variable is treated as an > undefined reference, unless no definition is seen. In the latter > case, the common variable becomes a definition. > > When a common variable is used, the linker will resolve it against a > definition found in a shared library. This is different from the > handling of an archive library, at least in ELF. In an ELF archive > library, a particular object will not be included in the link merely > to satisfy a common reference; it will only be included to satisfy an > undefined reference. > > In some cases, it will be desirable to resolve a common symbol with > the definition in the shared library. This would be desirable when > the actual intent was to use the initialized variable in the shared > library. For example, if a program uses ``int optind;'' rather than > ``extern int optind;'', and it also calls getopt, then, in both a > shared library and an archive library, the common symbol optind will > wind up referring to the initialized variable optind, rather than > creating a new, uninitialized, optind variable. Wrong. A standard conforming compiler will conclaim about a multiply defined symbol. This problem has been avoided by the C standard by forbidding COMMON generation (ISO/IEC 9899:1990 6.7.2). Unfortunately GCC generates commons even when -ansi is specified. In either case it is not desirable to link commons against functions, which solves the problem without disabling commons. Ruediger Helsch <rh@unifix.de> ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-13 10:58 ` Ruediger Helsch @ 1996-08-13 13:36 ` Jim Wilson 1996-08-13 16:06 ` Ruediger Helsch 0 siblings, 1 reply; 28+ messages in thread From: Jim Wilson @ 1996-08-13 13:36 UTC (permalink / raw) To: Ruediger Helsch; +Cc: Ian Lance Taylor, rms, drepper, dm, gcc2, gas2 Wrong. A standard conforming compiler will conclaim about a multiply defined symbol. This is not correct. You have missed a subtle point here. A program that has multiple external definitions is not a strictly conforming program. If you want your programs to be strictly conforming, then you can not rely on common. A conforming compiler must accept any strictly conforming program. However, a conforming compiler can have extensions that allow it to accept non-strictly conforming programs providing that such extensions do not change the behaviour of any strictly conforming program. The standard says that a program with multiple external definitions results in undefined behaviour. A standard conforming compiler can do anything when an input program triggers undefined behaviour. Normally, we give a warning to encourage portable programming. In this particular case, gcc chooses to have an extensions that allows such programs to work. This extension is even sanctioned by the standard (in a sense), as it is documented in the section on common extensions. A very similar case is identifier names. Consider this program: int abcdef1; int abcdef2; This is not a strictly conforming program. The standard says that only the first 6 characters are guaranteed to be significant, and it is implementation defined whether any characters after the first 6 are used. Gcc however accepts this program without complaint, and it would be very unwise to change this. In this case, we do not want to enforce the strict limits of the standard, because that is far too inconvenient for programmers. It is debatable whether multiple external definitions deserves the same treatment. It is not a bug in gcc that it accepts them though. Jim ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-13 13:36 ` Jim Wilson @ 1996-08-13 16:06 ` Ruediger Helsch 1996-08-13 19:04 ` Jim Wilson 1996-08-14 0:18 ` Nick Ing-Simmons 0 siblings, 2 replies; 28+ messages in thread From: Ruediger Helsch @ 1996-08-13 16:06 UTC (permalink / raw) To: Jim Wilson; +Cc: Ian Lance Taylor, rms, drepper, dm, gcc2, gas2 On Tue, 13 Aug 1996, Jim Wilson wrote: > Wrong. A standard conforming compiler will conclaim about a multiply > defined symbol. > > This is not correct. You have missed a subtle point here. > > A program that has multiple external definitions is not a strictly conforming > program. If you want your programs to be strictly conforming, then you can not > rely on common. > > A conforming compiler must accept any strictly conforming program. However, a > conforming compiler can have extensions that allow it to accept non-strictly > conforming programs providing that such extensions do not change the behaviour > of any strictly conforming program. > > The standard says that a program with multiple external definitions results > in undefined behaviour. A standard conforming compiler can do anything when > an input program triggers undefined behaviour. Normally, we give a warning > to encourage portable programming. In this particular case, gcc chooses to > have an extensions that allows such programs to work. > > This extension is even sanctioned by the standard (in a sense), as it is > documented in the section on common extensions. But the standard allows such behaviour only if no strictly standard-conforming program is broken by the extension. The following program is strictly conforming and should continue to run: #include <assert.h> int optind[30000], optarg[30000]; main() { int i; for (i = 0; i < 30000; i++) { optind[i] = 1; optarg[i] = 2; } for (i = 0; i < 30000; i++) { assert(optind[i] == 1); assert(optarg[i] == 2); } return 0; } Try this to see whether your compiler conforms to the C standard! Ruediger Helsch <rh@unifix.de> ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-13 16:06 ` Ruediger Helsch @ 1996-08-13 19:04 ` Jim Wilson 1996-08-13 21:02 ` Richard Stallman 1996-08-14 0:18 ` Nick Ing-Simmons 1 sibling, 1 reply; 28+ messages in thread From: Jim Wilson @ 1996-08-13 19:04 UTC (permalink / raw) To: Ruediger Helsch Cc: Jim Wilson, Ian Lance Taylor, rms, drepper, dm, gcc2, gas2 #include <assert.h> int optind[30000], optarg[30000]; ... This is a good example. A number of systems get this wrong. One way to fix this is to make -fno-common the default. However, ANSI/ISO C does not require this solution. There are some other ways that this problem could be solved, by changing how the C library works, or by changing how the linker works. -fno-common is probably the easiest solution though. Jim ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-13 19:04 ` Jim Wilson @ 1996-08-13 21:02 ` Richard Stallman 1996-08-14 3:06 ` Ruediger Helsch 0 siblings, 1 reply; 28+ messages in thread From: Richard Stallman @ 1996-08-13 21:02 UTC (permalink / raw) To: wilson; +Cc: rh, wilson, ian, drepper, dm, gcc2, gas2 #include <assert.h> int optind[30000], optarg[30000]; ... If the problem here is that a definition from the library overrides these implicit definitions, it can be fixed in ld. In the old days, ld on a.out files got this right. It needs to use the maximum size specified by any definition. Making -fno-common the default is unacceptable because it causes trouble for too many programs. But fixing ld won't cause any other problems. So that is the right fix. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-13 21:02 ` Richard Stallman @ 1996-08-14 3:06 ` Ruediger Helsch 1996-08-14 23:44 ` Richard Stallman 0 siblings, 1 reply; 28+ messages in thread From: Ruediger Helsch @ 1996-08-14 3:06 UTC (permalink / raw) To: Richard Stallman; +Cc: wilson, ian, drepper, dm, gcc2, gas2 On Wed, 14 Aug 1996, Richard Stallman wrote: > #include <assert.h> > int optind[30000], optarg[30000]; > ... > > > If the problem here is that a definition from the library overrides > these implicit definitions, it can be fixed in ld. In the old days, > ld on a.out files got this right. It needs to use the maximum size > specified by any definition. To my best knowledge it never did, as optind is normally initialized (e.g. to 1) and not a common but a data definition, so that all commons with this name are resolved against the definition in the library. Ruediger Helsch <rh@unifix.de> ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-14 3:06 ` Ruediger Helsch @ 1996-08-14 23:44 ` Richard Stallman 0 siblings, 0 replies; 28+ messages in thread From: Richard Stallman @ 1996-08-14 23:44 UTC (permalink / raw) To: rh; +Cc: wilson, ian, drepper, dm, gcc2, gas2 To my best knowledge it never did, as optind is normally initialized (e.g. to 1) and not a common but a data definition, so that all commons with this name are resolved against the definition in the library. optind in that test program is a common symbol. A common symbol is not undefined, and there is no need for ld to resolve it. Perhaps some ld programs treat a common symbol as undefined in this situation. If so, that seems like a bug to me. If a symbol such as optind is common, and a library member contains a definition of optind, that in itself should not cause that library member to be linked in. Implementing this behavior will fix that test case. If shared libraries are made to mimic unshared libraries as regards which definitions are taken from them, that test cae will work with shared libraries too. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-13 16:06 ` Ruediger Helsch 1996-08-13 19:04 ` Jim Wilson @ 1996-08-14 0:18 ` Nick Ing-Simmons 1996-08-14 3:06 ` Ruediger Helsch 1996-08-15 11:24 ` H.J. Lu 1 sibling, 2 replies; 28+ messages in thread From: Nick Ing-Simmons @ 1996-08-14 0:18 UTC (permalink / raw) To: rh; +Cc: drepper, rms, dm, Jim Wilson, gas2, gcc2, Ian Lance Taylor Ruediger Helsch <rh@unifix.de> writes: >But the standard allows such behaviour only if no strictly >standard-conforming program is broken by the extension. The following >program is strictly conforming and should continue to run: > > #include <assert.h> > int optind[30000], optarg[30000]; > > main() > { > int i; > for (i = 0; i < 30000; i++) { > optind[i] = 1; > optarg[i] = 2; > } > > for (i = 0; i < 30000; i++) { > assert(optind[i] == 1); > assert(optarg[i] == 2); > } > return 0; > } > >Try this to see whether your compiler conforms to the C standard! > FWIW - gcc-2.7.2 (using /usr/ccs/bin/ld) , Solaris 2.5 gcc x.c -o x ld: warning: symbol `optind' has differing sizes: (file /var/tmp/cca006vl1.o value=0x1d4c0; file /usr/lib/libc.so value=0x4); /usr/lib/libc.so definition taken ld: warning: symbol `optarg' has differing sizes: (file /var/tmp/cca006vl1.o value=0x1d4c0; file /usr/lib/libc.so value=0x4); /usr/lib/libc.so definition taken pluto 5% x Segmentation Fault (core dumped) Identical results with SunPro cc ... ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-14 0:18 ` Nick Ing-Simmons @ 1996-08-14 3:06 ` Ruediger Helsch 1996-08-15 11:24 ` H.J. Lu 1 sibling, 0 replies; 28+ messages in thread From: Ruediger Helsch @ 1996-08-14 3:06 UTC (permalink / raw) To: Nick Ing-Simmons Cc: drepper, rms, dm, Jim Wilson, gas2, gcc2, Ian Lance Taylor On Wed, 14 Aug 1996, Nick Ing-Simmons wrote: > > #include <assert.h> > > int optind[30000], optarg[30000]; > ... > FWIW - gcc-2.7.2 (using /usr/ccs/bin/ld) , Solaris 2.5 > > gcc x.c -o x > ld: warning: symbol `optind' has differing sizes: > (file /var/tmp/cca006vl1.o value=0x1d4c0; file /usr/lib/libc.so value=0x4); > /usr/lib/libc.so definition taken > ld: warning: symbol `optarg' has differing sizes: > (file /var/tmp/cca006vl1.o value=0x1d4c0; file /usr/lib/libc.so value=0x4); > /usr/lib/libc.so definition taken > pluto 5% x > Segmentation Fault (core dumped) > > Identical results with SunPro cc ... Both broken! Ruediger Helsch <rh@unifix.de> ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-14 0:18 ` Nick Ing-Simmons 1996-08-14 3:06 ` Ruediger Helsch @ 1996-08-15 11:24 ` H.J. Lu 1 sibling, 0 replies; 28+ messages in thread From: H.J. Lu @ 1996-08-15 11:24 UTC (permalink / raw) To: Nick Ing-Simmons; +Cc: rh, drepper, rms, dm, wilson, gas2, gcc2, ian > > Ruediger Helsch <rh@unifix.de> writes: > >But the standard allows such behaviour only if no strictly > >standard-conforming program is broken by the extension. The following > >program is strictly conforming and should continue to run: > > > > #include <assert.h> > > int optind[30000], optarg[30000]; > > > > main() > > { > > int i; > > for (i = 0; i < 30000; i++) { > > optind[i] = 1; > > optarg[i] = 2; > > } > > > > for (i = 0; i < 30000; i++) { > > assert(optind[i] == 1); > > assert(optarg[i] == 2); > > } > > return 0; > > } > > > >Try this to see whether your compiler conforms to the C standard! > > > FWIW - gcc-2.7.2 (using /usr/ccs/bin/ld) , Solaris 2.5 > > gcc x.c -o x > ld: warning: symbol `optind' has differing sizes: > (file /var/tmp/cca006vl1.o value=0x1d4c0; file /usr/lib/libc.so value=0x4); > /usr/lib/libc.so definition taken > ld: warning: symbol `optarg' has differing sizes: > (file /var/tmp/cca006vl1.o value=0x1d4c0; file /usr/lib/libc.so value=0x4); > /usr/lib/libc.so definition taken > pluto 5% x > Segmentation Fault (core dumped) > > Identical results with SunPro cc ... > > On Linux, I got # gcc foo.c usr/i486-linux/bin/ld: Warning: size of symbol `optarg' changed from 120000 to 4 in /usr/lib/libc.so /usr/i486-linux/bin/ld: Warning: size of symbol `optind' changed from 120000 to 4 in /usr/lib/libc.so # a.out zsh: 19888 segmentation fault ./a.out -- H.J. Lu Innovix Technologies, Inc. hjl@innovix.com ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-09 2:46 global vars and symbol visibility for mips32/elf David S. Miller 1996-08-09 5:24 ` David S. Miller 1996-08-09 8:30 ` Ian Lance Taylor @ 1996-08-13 9:06 ` Ruediger Helsch 1996-08-13 10:58 ` Richard Stallman 2 siblings, 1 reply; 28+ messages in thread From: Ruediger Helsch @ 1996-08-13 9:06 UTC (permalink / raw) To: dm; +Cc: gcc2, gas2 On Fri, 9 Aug 1996, David S. Miller wrote: > The problem is caused by the symbol 'glob'. GNU libc also has a > symbol glob. The assembly output by gcc for the glob variable in the > 960218-1.c test case looks like: This is a combination of several bugs: 1) ANSI C compilers do not know COMMON, they should generate a data definition for glob (ISO/IEC 9899:1990 6.7.2). Gcc generates a COMMON even with -ansi (there is a comment in the code indicating this standard violation is on purpose). 2) The linker should not link a common against a function from the shared library. Both bugs are since nearly one year fixed in Unifix Linux and Linux-FT (POSIX certified). Ruediger Helsch <rh@unifix.de> ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-13 9:06 ` Ruediger Helsch @ 1996-08-13 10:58 ` Richard Stallman 1996-08-13 13:36 ` Ruediger Helsch 0 siblings, 1 reply; 28+ messages in thread From: Richard Stallman @ 1996-08-13 10:58 UTC (permalink / raw) To: rh; +Cc: dm, gcc2, gas2 Both bugs are since nearly one year fixed in Unifix Linux and Linux-FT (POSIX certified). So did you report the bugs, and your fixes, a year ago? You could have enabled the bug to have been fixed in the GNU sources a year ago, too. (I'm guessing that these systems are Linux-based GNU systems, like most of the systems that contain Linux, and that they use GNU ld. Please correct me if that is not so.) ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-13 10:58 ` Richard Stallman @ 1996-08-13 13:36 ` Ruediger Helsch 1996-08-13 13:36 ` Richard Stallman ` (2 more replies) 0 siblings, 3 replies; 28+ messages in thread From: Ruediger Helsch @ 1996-08-13 13:36 UTC (permalink / raw) To: Richard Stallman; +Cc: dm, gcc2, gas2 On Tue, 13 Aug 1996, Richard Stallman wrote: > Both bugs are since nearly one year fixed in Unifix Linux and Linux-FT > (POSIX certified). > > So did you report the bugs, and your fixes, a year ago? You could > have enabled the bug to have been fixed in the GNU sources a year ago, > too. The nonstandard behaviout in GCC is deliberate. See the comment in varasm.c line 1092: /* ANSI specifies that a tentative definition which is not merged with a non-tentative definition behaves exactly like a definition with an initializer equal to zero. (Section 3.7.2) -fno-common gives strict ANSI behavior. Usually you don't want it. This matters only for variables with external linkage. */ The comment says they know that this does not conform to the C standard, so why should we report something that seems well-known? While for the linker, we use a variant of the Linux linker distributed of H.J.Lu, which is a somehow modified GNU ld. There again somebody did the work and put in warning messages for the case that commons were linked against library functions. Again, this person obviously knew what the problem was and deliberately decided to issue a warning instead of preventing the symbol to match. In both cases the nonstandard behaviour was nonstandard on purpose. I am quite surprised to find that everybody thinks that GCC and LD should be changed. We modified them for our Linux distributions because we wanted strict C standard and POSIX conformance. But the standard conformant behaviour can also break many programs which rely on COMMONS. We had e.g. to adapt the X11 config files to use "cc -ansi -fcommon". Whether GCC should be changed is a question of policy more than of one of missing bug reports. I personally think that either "gcc -ansi" should conform to the C standard or the option should be renamed (-nearly-ansi), but until shortly this seemed to be a minority opinion. Ruediger Helsch <rh@unifix.de> ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-13 13:36 ` Ruediger Helsch @ 1996-08-13 13:36 ` Richard Stallman 1996-08-13 14:40 ` H.J. Lu 1996-08-13 16:06 ` Ulrich Drepper 2 siblings, 0 replies; 28+ messages in thread From: Richard Stallman @ 1996-08-13 13:36 UTC (permalink / raw) To: rh; +Cc: dm, gcc2, gas2 > So did you report the bugs, and your fixes, a year ago? You could > have enabled the bug to have been fixed in the GNU sources a year ago, > too. The nonstandard behaviout in GCC is deliberate. See the comment in varasm.c line 1092: Yes, THAT is deliberate. Indeed, there would have been no need to report that fact about GCC. But I thought you were talking of fixes in ld. Is that not so? While for the linker, we use a variant of the Linux linker distributed of H.J.Lu, which is a somehow modified GNU ld. There again somebody did the work and put in warning messages for the case that commons were linked against library functions. Again, this person obviously knew what the problem was and deliberately decided to issue a warning instead of preventing the symbol to match. These are the sort of changes I thought we were talking about. Who is it who made these changes and didn't send them or report the problem? I am quite surprised to find that everybody thinks that GCC and LD should be changed. We modified them for our Linux distributions because we wanted strict C standard and POSIX conformance. But the standard conformant behaviour can also break many programs which rely on COMMONS. I think you're talking about two different changes as if they were one. We need to keep the distinction clear. We DO NOT want to make -fno-common the default. We DO want to fix LD so it does the right thing when common symbols are used. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-13 13:36 ` Ruediger Helsch 1996-08-13 13:36 ` Richard Stallman @ 1996-08-13 14:40 ` H.J. Lu 1996-08-13 16:06 ` Ulrich Drepper 2 siblings, 0 replies; 28+ messages in thread From: H.J. Lu @ 1996-08-13 14:40 UTC (permalink / raw) To: Ruediger Helsch; +Cc: rms, dm, gcc2, gas2 > > While for the linker, we use a variant of the Linux linker distributed > of H.J.Lu, which is a somehow modified GNU ld. There again somebody did > the work and put in warning messages for the case that commons were > linked against library functions. Again, this person obviously knew > what the problem was and deliberately decided to issue a warning instead > of preventing the symbol to match. I modified BFD toa issue a warning when the symbol'ss type changes. It doesn't necessarily mean an error, especially when a read-only symbols are put into the .text section. But in some cases, the warning helps when you have foo () { } in a shared library and int foo = 0; in the application. H.J. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-13 13:36 ` Ruediger Helsch 1996-08-13 13:36 ` Richard Stallman 1996-08-13 14:40 ` H.J. Lu @ 1996-08-13 16:06 ` Ulrich Drepper 1996-08-13 16:06 ` Joe Buck 1996-08-13 17:02 ` Rohan LENARD 2 siblings, 2 replies; 28+ messages in thread From: Ulrich Drepper @ 1996-08-13 16:06 UTC (permalink / raw) To: rh; +Cc: rms, dm, gcc2, gas2 From: Ruediger Helsch <rh@unifix.de> Subject: Re: global vars and symbol visibility for mips32/elf Date: Tue, 13 Aug 1996 22:06:12 +0200 (MEST) > I am quite surprised to find that everybody thinks that GCC and LD > should be changed. We modified them for our Linux distributions because > we wanted strict C standard and POSIX conformance. But the standard > conformant behaviour can also break many programs which rely on COMMONS. > We had e.g. to adapt the X11 config files to use "cc -ansi -fcommon". I don't think at all that the standard behaviour should be to disallow commons. We use it in some places in glibc. It should be disallowed to match a common var with a function in the shared. This never makes sense. > I personally think that either "gcc -ansi" should conform to the C standard > or the option should be renamed (-nearly-ansi), but until shortly this > seemed to be a minority opinion. I think gcc -ansi should really be ANSI compliant (btw, what about changing the name to -iso since the official name is ISO C?) -- Uli --------------. drepper@cygnus.com ,-. Rubensstrasse 5 Ulrich Drepper \ ,--------------------' \ 76149 Karlsruhe/Germany Cygnus Support `--' drepper@gnu.ai.mit.edu `------------------------ ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-13 16:06 ` Ulrich Drepper @ 1996-08-13 16:06 ` Joe Buck 1996-08-13 17:02 ` Rohan LENARD 1 sibling, 0 replies; 28+ messages in thread From: Joe Buck @ 1996-08-13 16:06 UTC (permalink / raw) To: Ulrich Drepper; +Cc: rh, rms, dm, gcc2, gas2 > From: Ruediger Helsch <rh@unifix.de> > > I am quite surprised to find that everybody thinks that GCC and LD > > should be changed. We modified them for our Linux distributions because > > we wanted strict C standard and POSIX conformance. But the standard > > conformant behaviour can also break many programs which rely on COMMONS. > > We had e.g. to adapt the X11 config files to use "cc -ansi -fcommon". It would be correct to say that the X programs in question are not strict ANSI (or ISO), but does the standard mandate that a diagnostic be issued for such programs, or does it merely leave their behavior undefined or unspecified? Just because a test suite complains that it doesn't see a diagnostic does not mean that a diagnostic is mandated. Ulrich Drepper writes: > I don't think at all that the standard behaviour should be to disallow > commons. We use it in some places in glibc. Having -ansi imply -fno-common but not having it be the default is an option (I'm not sure it is the right option). > It should be disallowed to match a common var with a function in the > shared. This never makes sense. Yes. > I think gcc -ansi should really be ANSI compliant (btw, what about > changing the name to -iso since the official name is ISO C?) If you wish to add -iso as a synonym, fine. But ANSI is just as official as ISO (in a more limited geographical area, of course), and the switch is in wide use. ^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: global vars and symbol visibility for mips32/elf 1996-08-13 16:06 ` Ulrich Drepper 1996-08-13 16:06 ` Joe Buck @ 1996-08-13 17:02 ` Rohan LENARD 1 sibling, 0 replies; 28+ messages in thread From: Rohan LENARD @ 1996-08-13 17:02 UTC (permalink / raw) To: rh, Ulrich Drepper; +Cc: rms, dm, gcc2, gas2 Hi, Excerpts from gcc2: 13-Aug-96 Re: global vars and symbol .. Ulrich Drepper@cygnus.co (1263*) > I think gcc -ansi should really be ANSI compliant (btw, what about > changing the name to -iso since the official name is ISO C?) Probably supporting -iso and -ansi (as both doing the same thing) is a better solution. Rohan ^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~1996-08-15 11:24 UTC | newest] Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1996-08-09 2:46 global vars and symbol visibility for mips32/elf David S. Miller 1996-08-09 5:24 ` David S. Miller 1996-08-09 9:01 ` Ian Lance Taylor 1996-08-09 8:30 ` Ian Lance Taylor 1996-08-09 13:13 ` Ulrich Drepper 1996-08-09 15:30 ` Ian Lance Taylor 1996-08-10 17:37 ` Richard Stallman 1996-08-10 19:41 ` Ian Lance Taylor 1996-08-10 23:26 ` Jim Wilson 1996-08-11 1:44 ` Richard Stallman 1996-08-13 10:58 ` Ruediger Helsch 1996-08-13 13:36 ` Jim Wilson 1996-08-13 16:06 ` Ruediger Helsch 1996-08-13 19:04 ` Jim Wilson 1996-08-13 21:02 ` Richard Stallman 1996-08-14 3:06 ` Ruediger Helsch 1996-08-14 23:44 ` Richard Stallman 1996-08-14 0:18 ` Nick Ing-Simmons 1996-08-14 3:06 ` Ruediger Helsch 1996-08-15 11:24 ` H.J. Lu 1996-08-13 9:06 ` Ruediger Helsch 1996-08-13 10:58 ` Richard Stallman 1996-08-13 13:36 ` Ruediger Helsch 1996-08-13 13:36 ` Richard Stallman 1996-08-13 14:40 ` H.J. Lu 1996-08-13 16:06 ` Ulrich Drepper 1996-08-13 16:06 ` Joe Buck 1996-08-13 17:02 ` Rohan LENARD
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).