This is the mail archive of the
java@gcc.gnu.org
mailing list for the Java project.
Linker name conflicts due to optimization in gjavah
- From: Terry Laurenzo <tlaurenzo at gmail dot com>
- To: java at gcc dot gnu dot org
- Date: Wed, 17 Aug 2005 12:50:24 -0600
- Subject: Linker name conflicts due to optimization in gjavah
- Reply-to: tj at laurenzo dot org
When linking an executable that users java/util/logging/Logger, I get
a a linkage error:
------------ Linkage error ------------
l:/gcc_native/i686-pc-mingw32/bin/../lib/gcc/i686-pc-mingw32/4.1.0/../../../libgcj.a(natLogger.o)(.text$_ZN4java4util7logging6Logger7getNameEPNS_4lang6StringEv[java::util::logging::Logger::getName(java::lang::String*,
void)]+0x0):natLogger.cc: multiple definition of
`java::util::logging::Logger::getName(java::lang::String*, void)'
l:/gcc_native/i686-pc-mingw32/bin/../lib/gcc/i686-pc-mingw32/4.1.0/../../../libgcj.a(Logger.o)(.text+0x950):Logger.java:
first defined here
collect2: ld returned 1 exit status
------------ End linkage error --------
I traced this down to a problem in gjavah.c. For simple getter
methods it generates code like this (extracted from generated
Logger.h):
virtual ::java::lang::String *getName () { return name; }
Note that this is a virtual inline method declaration, which means
that if you declare a CNI class that includes the generated header, it
will errantly create a virtual method in the object file that can
conflict with the method declared in the corresponding Java class.
It looks like gjavah is trying to be too smart, as is seen in the
following snippet from the decompile_method function in gjavah.c:
---------------- Code Snippet ---------------
/* If the method is synchronized, don't touch it. */
if ((method_access & ACC_SYNCHRONIZED))
return;
if (code_len == 5
&& codes[0] == OPCODE_aload_0
&& codes[1] == OPCODE_getfield
&& (codes[4] == OPCODE_areturn
|| codes[4] == OPCODE_dreturn
|| codes[4] == OPCODE_freturn
|| codes[4] == OPCODE_ireturn
|| codes[4] == OPCODE_lreturn))
{
/* Found code like `return FIELD'. */
index = (codes[2] << 8) | codes[3];
/* FIXME: ensure that tag is CONSTANT_Fieldref. */
name_and_type = JPOOL_USHORT2 (jcf, index);
/* FIXME: ensure that tag is CONSTANT_NameAndType. */
name = JPOOL_USHORT1 (jcf, name_and_type);
if (codes[4] == OPCODE_areturn)
decompile_return_statement (out, jcf, method_signature,
name, JPOOL_USHORT2 (jcf, name_and_type));
else
{
fputs (" { return ", out);
/* FIXME: flags. */
print_field_name (out, jcf, name, 0);
fputs ("; }", out);
}
decompiled = 1;
}
---------------------------------------------------------
Note that it is decompiling the method and if it finds a simple
getter-style method, just emitting the corresponding C++ inline
definition. Is it really worth the trouble to be doing this? Maybe
some platforms are merging the duplicated methods or something (or
maybe no one has seen this problem before) but mine isn't.
At the risk of offending the person who wrote the optimization code, I
suggest that it be taken out. I found this in CVS head and the
5/15/2005 snapshort. Any objections? Should a bug be opened?
TJ