Skip to Content.
Sympa Menu

freetds - Re: [freetds] freetds on solaris 11: symbol scope specifies local binding (same problem)

freetds AT lists.ibiblio.org

Subject: FreeTDS Development Group

List archive

Chronological Thread  
  • From: "James K. Lowden" <jklowden AT freetds.org>
  • To: freetds AT lists.ibiblio.org
  • Subject: Re: [freetds] freetds on solaris 11: symbol scope specifies local binding (same problem)
  • Date: Mon, 23 Sep 2013 17:47:01 -0400

On Mon, 23 Sep 2013 11:20:33 -0700
Justin T Pryzby <justinp AT norchemlab.com> wrote:

> On Mon, Sep 23, 2013 at 01:42:27PM -0400, James K. Lowden wrote:
> > On Mon, 23 Sep 2013 08:53:31 +0100 "Marco A. Ferra"
> > <MAFerra AT isq.pt> wrote:
> >
> > > Regarding Justin Pryzby's question on "freetds on solaris 11:
> > > symbol scope specifies local binding" [1] I'm also having a hard
> > > time compiling FreeTDS 0.91 from source on Solaris 11. The error
> > > is:
> [...]
>
> > My GNU ld manual doesn't mention options such as those on your
> > command line, e.g. allextract and defaultextract. Since those
> > options are accepted by the linker, I have to believe you're using
> > the Solaris linker. Perhaps Solaris's compiler, too?
> Not sure about Marco, but I wasn't; ./configure gives:
>
> checking for gcc... gcc
> checking whether we are using the GNU C compiler... yes
> checking if the linker (/usr/bin/ld) is GNU ld... no
> checking whether the gcc linker (/usr/bin/ld) supports shared
> libraries... yes checking whether -lc should be explicitly linked
> in... yes checking dynamic linker characteristics... solaris2.11 ld.so
> checking how to hardcode library paths into programs... immediate
> checking if libtool supports shared libraries... yes
> checking for ld used by GCC... /usr/bin/ld
> checking if the linker (/usr/bin/ld) is GNU ld... no
>
> There *is* a linker script being used:
> https://lists.ibiblio.org/sympa/arc/freetds/2013q3/028467.html
> > libtool: link: echo "{ global:" > .libs/libct.so.4.0.0.exp
> > libtool: link: cat .libs/libct.exp | /usr/bin/gsed -e "s/\(.*
> > \)/\1;/" >> .libs/libct.so.4.0.0.exp libtool: link: echo "local:
> > *; };" >> .libs/libct.so.4.0.0.exp libtool: link: gcc -shared
> > -Wl,-z -Wl,text -Wl,-M -Wl,.libs/libct.so.4.0.0.exp -Wl,-h
> > -Wl,libct.so.4
> > -o .libs/libct.so.4.0.0 .libs/ct.o .libs/cs.o .libs/blk.o .libs/ctutil.o
> > -Wl,-z
> > -Wl,allextract ../tds/.libs/libtds.a
> > ../replacements/.libs/libreplacements.a
> > -Wl,-z -Wl,defaultextract -lnsl -lsocket -lc -pthreads
> > -Wl,-Bsymbolic -pthreads

Hmm. So you are using solaris's linker:

> checking for ld used by GCC... /usr/bin/ld
> checking if the linker (/usr/bin/ld) is GNU ld... no

I have such a file on my machine, and it's just a list of public
ct-lib symbols:

$ awk -F_ '{print $1}' build/src/ctlib/.libs/libct.exp | uniq -c
19 blk
23 cs
32 ct

The effect of the commands

echo "{ global:" > .libs/libct.so.4.0.0.exp
cat .libs/libct.exp | /usr/bin/sed -e "s/\(.*\)/\1;/" \
>> .libs/libct.so.4.0.0.exp
echo "local: *; };" >> .libs/libct.so.4.0.0.exp

is, rather clumsily, to tack a line at the top and at the end, and to
stick a semicolon on the end of every line. So we would have

$ head .libs/libct.so.4.0.0.exp
{ global:
blk_alloc;
blk_bind;
blk_colval;
blk_default;
blk_describe;
blk_done;
blk_drop;
blk_getrow;
blk_gettext;

$ tail .libs/libct.so.4.0.0.exp
ct_init;
ct_options;
ct_param;
ct_poll;
ct_res_info;
ct_results;
ct_send;
ct_send_data;
ct_setparam;
local: *; };

What does yours say?

http://docs.oracle.com/cd/E19683-01/816-1386/6m7qcobkd/index.html
http://docs.oracle.com/cd/E19683-01/816-0210/6m6nb7mcs/index.html

(Here I am on the FreeTDS list helping someone use an Oracle product.
The future is a weird place.)

Remove the "-Wl," escapes, your linker command line is

-z text -M .libs/libct.so.4.0.0.exp -h libct.so.4 \
-o .libs/libct.so.4.0.0 \
.libs/ct.o .libs/cs.o .libs/blk.o .libs/ctutil.o \
-z allextract \
../tds/.libs/libtds.a ../replacements/.libs/libreplacements.a \
-z defaultextract -lnsl -lsocket -lc -Bsymbolic

Marco's is similar; I think the -Bsymbolic is impotent:

-z text -M .libs/libct.so.4.0.0.exp -h libct.so.4 \
-o .libs/libct.so.4.0.0 \
.libs/ct.o .libs/cs.o .libs/blk.o .libs/ctutil.o \
-z allextract \
../tds/.libs/libtds.a ../replacements/.libs/libreplacements.a \
-z defaultextract -lnsl -lsocket -lc

and the error is

> Undefined first referenced
> symbol in file
> strlen .libs/ct.o
> (symbol scope specifies local binding)

In the Solaris linker, the -M option introduces a map file, *not* a
linker script. And the last line of that file,
.libs/libct.so.4.0.0.exp, is

local: *; };

Perhaps there's a connection? The fine manual says,

"However, symbols defined as local or eliminate scope are
reduced to symbols with a local binding within any executable or shared
object file being generated."

and

"When in *local* scope, this symbol name can be defined as the
special auto-reduction directive "*". This directive results in all
global symbols, not explicitly defined to be global in the mapfile,
receiving a local binding within any executable or shared object file
being generated."

The intention of "local: *; };" seems to be that no symbols in
the .o files are global except for those explicitly mentioned in the
global section of the mapfile.

A testable hypothesis: it's not acting as intended. Perhaps references
to strlen are being "reduced" to local scope.

If you remove it and make the file to end with

ct_send_data;
ct_setparam; };

what effect does that have?

It's also not perfectly obvious you need any symbol-management
shenanigans. If I were writing my own Makefile, I'd begin with

-h libct.so.4 \
-o .libs/libct.so.4.0.0 \
.libs/ct.o .libs/cs.o .libs/blk.o .libs/ctutil.o \
../tds/.libs/libtds.a ../replacements/.libs/libreplacements.a \
-lnsl -lsocket -lc -pthreads

That might work, too. There might be too many symbols, but
that's usually better than not enough, as I'm sure you'd agree.

HTH.

--jkl




Archive powered by MHonArc 2.6.24.

Top of Page