This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Bug or feature: symbol names of global/extern variables
- From: "Jan Beulich" <JBeulich at novell dot com>
- To: "Wolfgang Roemer" <w dot r dot a dot roemer at t-online dot de>
- Cc: "Robert Dewar" <dewar at adacore dot com>,<gcc at gnu dot org>,"Michael Veksler" <VEKSLER at il dot ibm dot com>,<binutils at sourceware dot org>
- Date: Thu, 06 Oct 2005 15:38:57 +0200
- Subject: Bug or feature: symbol names of global/extern variables
- References: <200510061444.59094.w.r.a.roemer@t-online.de>
I don't think this has anything to do with binutils; whether linking
succeeds exclusively depends on the mangling method used (VC does mangle
data object names, while g++ doesn't). AFAIK the standard only talks
about function signatures, meaning mangling data object names is neither
prohibited nor required (i.e. implementation defined) [7.5 clause 9
deals with that].
Jan
>>> Wolfgang Roemer <w.r.a.roemer@t-online.de> 06.10.05 14:44:58 >>>
Hello,
I encountered a subtle SEGV in a program and was able to track the
problem
down to symbol names concerning global/extern variables. I discussed
that
with some guys from the GCC project (see recipient list) and we came to
the
conclusion it would make more sense to share our thoughts with you.
Here the
problem:
If you have a global variable inside a cpp file and create a library
out of
that, the symbol name for that global variable does in no way take the
type of
the variable into account. A user of that variable can "make" it any
type
with an "extern" declaration and thus produce subtle errors. An
example:
-------- lib.cpp ------------
int maximum;
int minimum;
static bool init ( )
{
maximum = 2;
minimum = -7;
}
static bool initialized = init ( );
-------------------------------
Create a library out of that lib.cpp file. Then compile the following
main.cpp
and link it against the library:
--------- main.cpp ------------------
extern double maximum;
extern int minimum;
void main (int, char**)
{
// Assume you are on a machine where the sizeof (int) is 4 bytes
// and the sizeof (double) is 8 bytes.
assert (minimum == -7);
{
maximum = 2342343242343.3;
}
assert (minimum == -7);
return 0;
}
---------------------------------
The main.o will perfectly link with the library although main.o needs a
double
variable named maximum and the lib only offers an int variable named
maximum.
Because the symbol name does in no way reflect the variable type,
everything
links fine but in fact the variable named "minimum" gets scrambled in
this
example because "maximum" is accessed as if it is a double variable
thus
overwriting 4 additional bytes (in this case the 4 bytes of the
variable
minimum). The assertion will show that.
I tested that on Windows with Visual C++ as well and there main.obj
doesn't
link because the variable type is part of the symbol name and everthing
is
fine.
I think it would be very very important for the binary interface to
have that
feature as well.
Regards,
Wolfgang Roemer