This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Symbol versioning in C++ (two ld bugs)


[cc'd to the other people who have been involved so far]



None of what follows is mentioned in the current ld manual.  Consider that
as bug #0, if you will.  (I volunteer to update ld/ld.texinfo if y'all
will help me work these out.)


Background
==========
For libstdc++-v3 we need to start versioning the symbols of the shared
library.  I am exploring the option of requiring GNU ld and making use
of the "extern 'lang'" extension in the version scripts.  Right now I'm
playing with a --version-script consisting of

    FOO {

      global:
        extern "C++"
        {
          std::* 
        };

      local:
        * ;
    };

which binds everything in namespace std to version FOO.  The problem is
that there are all kinds of things in std which we must make local; the
script above exposes (and versions!) std::__random_implementation_detail,
which is bad.

So I tried to list something like

    global:
      extern "C++"
      {
        std::[A-Za-z][A-Za-z0-9_]*
      };

and that's where the fun begins.


Bug #1
======
The parser routine which stores the symbol patterns for later comparison
is named "lang_new_vers_regex", implying that the symbol pattern is a
regular expression.

The routines which compare the pattern with a given symbol,
"lang_vers_match_lang_X" where X is c, cplsuplus, or java, all call
fnmatch().

fnmatch() matches shell filename patterns, i.e., globbing, not regexps.

Oops.

So:  which kind of patterns are supposed to be accepted?


Bug #2
======
The ldlex.l lexer only specifies

        [*?.$_a-zA-Z]([*?.$_a-zA-Z0-9]|::)*

for a version symbol pattern (see V_IDENTIFIER).  No brackets, no ranges,
no braces -- that is, we can't even use the globbing patterns that fnmatch()
would allow!

The only "wildcard" used in the examples in the manual is a trailing
'*', and there's no documentation of what exactly it's supposed to mean,
although I think I can guess in the presence of fnmatch().

Should I be trying things like

    global:
      extern "C++"
      {
        std::A*
        std::B*
        ...
        std::Z*
        std::a*
        std::b*
        ...
        std::z*
      };

instead?  That would seem exceptionally and needlessly pathetic.  We ought
to be able to do better than that.  :-)


For the record, std::* is not the only problem; there are other namespaces
and other patterns which also need to be exposed (the __cxa_* stuff for
example).


Phil

-- 
If ye love wealth greater than liberty, the tranquility of servitude greater
than the animating contest for freedom, go home and leave us in peace.  We seek
not your counsel, nor your arms.  Crouch down and lick the hand that feeds you;
and may posterity forget that ye were our countrymen.            - Samuel Adams


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]