Re: [PATCH] [cygwin|mingw] fix dlpreopen with --disable-static

2008-11-13 Thread Ralf Wildenhues
Hi Charles,

* Charles Wilson wrote on Thu, Nov 13, 2008 at 06:09:20AM CET:
 Ralf Wildenhues wrote:
  
  Well, --verbose is documented to be a reversal of --silent, and
  documented to be the default.  The fact that opt_verbose is never set is
  a limitation.  If fixed, that should better happen in a separate patch.
 
 Well, if --verbose is really the negation of --silent, then (unless the
 functionality is extended as you describe) the effect of --verbose
 should be to only unset opt_silent (which it does), and there should not
 exist any 'opt_verbose' variable.

Yes, I agree there is some inconsistency currently.

 In this case, to avoid backwards compatibility issues, the new I want
 really talkative output, but not --debug option should be something
 other than '--verbose' -- because that already has a specific meaning:
 negate--silent.
 
 --chatty?  (I know, it's idiomatic and that's bad. It's more a
 tongue-in-cheek suggestion anyway).
 
 Regardless, I think the current (2? 3?) usages of opt_verbose should be
 changed to !opt_silent.

20 uses of func_verbose, actually.  A bit much to undo, methinks.
OK, how about this.  It is a slight backward incompatibility, but
not a large one:
- --verbose undoes --silent *and* enables verbose output (that one with
  func_verbose),
- --no-silent *only* undoes --silent,

It should still be bearable for the user, in the sense that if you
use --verbose rather than --no-silent, it's not a big problem.
And we don't have to think about what
  --verbose --verbose --silent

causes, we can just make the last one win.

If you agree, then let's proceed this way.  I don't mind who writes the
patch.

  B) func_win32_libid() gives some confusing errors to users
 when (a) using recursive make, and (b) MAKEFLAGS does not
 contain $OBJDUMP. Add a diagnostic error message, rather
 than allowing $SED to die a horrible death.
[...]
 Actually, this may no longer be necessary given the _LT_DECL_OBJDUMP
 changes (I /said/ this was an old patch).  Here's the thread:
 http://cygwin.com/ml/cygwin/2008-09/msg00552.html

Ah, ok, thanks.

  When configuring with --disable-static, dlpreopen is very confused.
  First, libtool tries to extract the symbols -- using $NM and
  $global_symbols_pipe -- from the DLL. That works...poorly:
[...]
  OK, I see that this is problematic.  What I don't understand yet is:
  is there a way to extract only the interesting symbols from the DLL?
  I don't yet understand why we have to move to the import library.
 
 Because it's extremely tricky. You have to use objdump (not nm), and
 then search for the exported symbols which is non-trivial because you
 need a stateful parser -- maybe an awk program...

Hmm, yes, agreed.  Thanks for all your detailed explanations.  I'm glad
to not have had to analyze this myself.

 The ugliest part of my patch is the fallback code for deducing the
 dllname from an import library.  But that's *pretty* compared to mucking
 with objdump output.

OK.  :-)

 Alternatively, libtool used to embed an impgen program which could be
 ressurected to generate the symbol lists we need (rather than a .def
 file, as it used to do).  A better solution would be to push that
 functionality into dlltool (Hmm. I need to generate a symbol list or
 def file for a DLL. but 'dlltool --output-def=my.def my.dll' doesn't do
 what you expect).  Even so, the core functionality of impgen would need
 some improvements (especially so as to indicate DATA items, which it
 doesn't do at present).
 http://loreley.ath.cx/cygwin/impgen/impgen.c
 
 But then, you're back to requiring a very recent binutils, or providing
 a fallback -- see objdump ugliness above.

ACK.

  Once I understand that, I can better judge the rest of the patch.
 
 Well, one reason I sat on this for so long was the 'fallback' mechanism
 for deducing the dll name from the import library was just so...hideous.
 And it wasn't a fallback -- it was the only mechanism since I hadn't yet
 enhanced dlltool.

Do you steer dlltool development, BTW?

 The only reason to allow it is because (hopefully) that ugly fallback
 code can get flagged with a warning, and maybe in a year or so get
 removed.

Sounds like a good idea.

 Well, that, and it fixes a test that currently fails.

Which one, and can you post output for failure as well as success with
the patch, please?

  for example mentioning in the mail
  whether you considered cygwin or cegcc or so would be helpful for
  review).
 
 cygwin and mingw yes. I know nothing about cegcc.

OK, that's what I figured.

In summary, it'd be great if you could redo the patch(es) along the
comments in the previous message (but read below first).
Couple more nits inline:

 --- a/libltdl/config/ltmain.m4sh
 +++ b/libltdl/config/ltmain.m4sh

 @@ -1991,10 +1992,36 @@ extern \C\ {
 func_verbose extracting global C symbols from \`$dlprefile'
 func_basename $dlprefile
 name=$func_basename_result
 -   $opt_dry_run || {
 - eval 

Re: [PATCH] [cygwin|mingw] fix dlpreopen with --disable-static

2008-11-13 Thread Brian Dessent
Ralf Wildenhues wrote:

 I'm actually not sure whether _GLOBAL__F[ID]_.* can appear on w32.
 Do you know?  They should happen with C++ code using constructors
 and destructors IIRC.

Yes they do occur, although not matching that regexp.  For one, they
will have two leading underscores before the G, as with all symbols
compared to their linux counterparts (i.e. __USER_LABEL_PREFIX__ is _
on Cygwin/MinGW.)  For another I would have expected the regexp to match
[FID] not F[ID] as there seems to generally be only one character in
that position, whose purpose is illuminated by this comment in
gcc/tree.c:

/* Generate a name for a special-purpose function function.
   The generated name may need to be unique across the whole link.
   TYPE is some string to identify the purpose of this function to the
   linker or collect2; it must start with an uppercase letter,
   one of:
   I - for constructors
   D - for destructors
   N - for C++ anonymous namespaces
   F - for DWARF unwind frame information.  */

A testcase:

$ echo struct foo { int x; foo() : x(42) {}; }; static foo bar; \
  | g++ -x c++ -S - -o - -O2 
.file   
.section.ctors,w
.align 4
.long   __GLOBAL__I__77970994_840EDDA1
.lcomm _bar,16
.text
.align 2
.p2align 4,,15
.def__GLOBAL__I__77970994_840EDDA1; .scl3;  .type  
32; .endef
__GLOBAL__I__77970994_840EDDA1:
pushl   %ebp
movl$42, %eax
movl%esp, %ebp
popl%ebp
movl%eax, _bar
ret

Also:

$ c++filt __GLOBAL__I__foobar
global constructors keyed to _foobar

$ c++filt __GLOBAL__D__foobar
global destructors keyed to _foobar

$ c++filt __GLOBAL__FI__foobar
__GLOBAL__FI__foobar

This implies that 'FI' is not valid, or at least not recognised by the
demangler as significant.

Brian




Re: [PATCH] [cygwin|mingw] fix dlpreopen with --disable-static

2008-11-13 Thread libtool

On Thu, 13 Nov 2008 22:09:07 +0100, Ralf Wildenhues said:
 OK, how about this.  It is a slight backward incompatibility, but
 not a large one:
 - --verbose undoes --silent *and* enables verbose output (that one with
   func_verbose),
 - --no-silent *only* undoes --silent,
 
 It should still be bearable for the user, in the sense that if you
 use --verbose rather than --no-silent, it's not a big problem.
 And we don't have to think about what
   --verbose --verbose --silent
 
 causes, we can just make the last one win.
 
 If you agree, then let's proceed this way.  I don't mind who writes the
 patch.

That sounds good to me. The help output would need a little re-wording:

#   --quiet, --silentdon't print informational messages
#   -v, --verboseprint informational messages (default)
#   --no-silent  ???

I'll let you do that. g

   B) func_win32_libid() gives some confusing errors to users
  when (a) using recursive make, and (b) MAKEFLAGS does not
  contain $OBJDUMP. Add a diagnostic error message, rather
  than allowing $SED to die a horrible death.
 [...]
  Actually, this may no longer be necessary given the _LT_DECL_OBJDUMP
  changes (I /said/ this was an old patch).  Here's the thread:
  http://cygwin.com/ml/cygwin/2008-09/msg00552.html
 
 Ah, ok, thanks.

I'll remove any of these bits from the revised patch(es).

  Well, one reason I sat on this for so long was the 'fallback' mechanism
  for deducing the dll name from the import library was just so...hideous.
  And it wasn't a fallback -- it was the only mechanism since I hadn't yet
  enhanced dlltool.
 
 Do you steer dlltool development, BTW?

No. I've contributed a few patches over the years to dlltool and
binutils, but that's it.

  The only reason to allow it is because (hopefully) that ugly fallback
  code can get flagged with a warning, and maybe in a year or so get
  removed.
 
 Sounds like a good idea.

Of course, first I need to revise the dlltool patch and get it accepted;
there have been some comments on the binutils list.

  Well, that, and it fixes a test that currently fails.
 
 Which one, and can you post output for failure as well as success with
 the patch, please?

demo-exec after demo-shared, in the old test suite.

I'll post the output(s) tonight or tomorrow.

 Hmm.  I reviewed this whole function, and only when done I asked myself
 this, more radical question: we go great lengths here to find out a
 name.  Iff we have a *.la file to go with the implib, can't we just
 *know* the name?  I mean, we produced that thing, it has the expected
 name, no?  That's what the *.la file was designed for: to not have to
 look into the binary files for information.
 
 Or is this purely for import libraries not created with libtool (and
 people who throw away *.la files)?

The information (e.g. library to dlpreopen) is passed in $dlprefiles.
But, if that filename is .la:  
func_mode_link():
...
dlfiles|dlprefiles)
  if test $preload = no; then
# Add the symbol object into the linking commands.
func_append compile_command  @SYMFILE@
func_append finalize_command  @SYMFILE@
preload=yes
  fi
  case $arg in
  *.la | *.lo) ;;  # We handle these cases below.
  ...

...much later...
  *.la)
# A libtool-controlled library.

if test $prev = dlfiles; then
  # This library was specified with -dlopen.
  dlfiles=$dlfiles $arg
  prev=
elif test $prev = dlprefiles; then
  # The library was specified with -dlpreopen.
  dlprefiles=$dlprefiles $arg
  prev=
else
  deplibs=$deplibs $arg
fi
continue
;;

So far, so good.  But then we eventually source the .la file, and end up
here (this is, in fact, what's happening in the demo-shared case):

   # This library was specified with -dlpreopen.
if test $pass = dlpreopen; then
  if test -z $libdir  test $linkmode = prog; then
func_fatal_error only libraries may -dlpreopen a
convenience library: \`$lib'
  fi
  # Prefer using a static library (so that no silly _DYNAMIC
  symbols
  # are required to link).
  if test -n $old_library; then
newdlprefiles=$newdlprefiles $dir/$old_library
# Keep a list of preopened convenience libraries to check
# that they are being used correctly in the link pass.
test -z $libdir  \
dlpreconveniencelibs=$dlpreconveniencelibs
$dir/$old_library
  # Otherwise, use the dlname, so that lt_dlopen finds it.
  elif test -n $dlname; then
newdlprefiles=$newdlprefiles $dir/$dlname
  else
newdlprefiles=$newdlprefiles $dir/$linklib
  fi
fi # $pass = dlpreopen

We've stored the DLL name as just ONE of the entries in $newdlprefiles.

Re: [PATCH] [cygwin|mingw] fix dlpreopen with --disable-static

2008-11-13 Thread Ralf Wildenhues
* [EMAIL PROTECTED] wrote on Fri, Nov 14, 2008 at 12:28:36AM CET:
 
 The point is, we perhaps STARTED with the .la file, but the whole point
 of the dlpreopen $pass is to replace each .la file in $dlprefiles with
 the name of the object from which the symbols should be extracted, to
 build the symbol table. So, pick one: either the DLL, or the import
 library (there is no static lib, the failure mode in question occurs
 when --disable-static).
 
 If you pick DLL -- then it's real hard to get the symbols (objdump
 ugliness, plus figuring out which ones are DATA).
 
 If you pick implib -- then it's real hard to get the correct DLL name
 (but not nearly as hard as extracting the correct symbols from the dll).
 
 But the name of the .la file is no longer available.

But that's a problem that can be solved.

# turn $1 into a string suitable for a shell variable name
func_tr_sh ()
{
 ... # typically forks, except maybe with bash ${var/subst/repl}
}

# when treating $dlprefile, save the corresponding .la file name:
func_tr_sh $dlprefile
eval libfile_$tr_sh_result=\$corresponding_dotla_file

# later, when searching for the .la file, test libfile$tr_sh_result
# for contents

What do you think?

Cheers,
Ralf




Re: [PATCH] [cygwin|mingw] fix dlpreopen with --disable-static

2008-11-13 Thread Charles Wilson
Ralf Wildenhues wrote:
 The point is, we perhaps STARTED with the .la file, but the whole point
 of the dlpreopen $pass is to replace each .la file in $dlprefiles with
 the name of the object from which the symbols should be extracted, to
 build the symbol table. So, pick one: either the DLL, or the import
 library (there is no static lib, the failure mode in question occurs
 when --disable-static).

 If you pick DLL -- then it's real hard to get the symbols (objdump
 ugliness, plus figuring out which ones are DATA).

 If you pick implib -- then it's real hard to get the correct DLL name
 (but not nearly as hard as extracting the correct symbols from the dll).

 But the name of the .la file is no longer available.
 
 But that's a problem that can be solved.
 
 # turn $1 into a string suitable for a shell variable name
 func_tr_sh ()
 {
  ... # typically forks, except maybe with bash ${var/subst/repl}
 }
 
 # when treating $dlprefile, save the corresponding .la file name:
 func_tr_sh $dlprefile
 eval libfile_$tr_sh_result=\$corresponding_dotla_file
 
 # later, when searching for the .la file, test libfile$tr_sh_result
 # for contents
 
 What do you think?

That would work. But it only gets rid of the grotty find the name of
the DLL given the implib problem -- which is not a small thing, of course.

But that presupposes that my change to the dlpreopen $pass, where on
cygwin|mingw we replace the la file in the $dlprefiles list with the
implib, stands. Did I convince you we needed this bit:

- elif test -n $dlname; then
-   newdlprefiles=$newdlprefiles $dir/$dlname
+ # Except on mingw|cygwin, where we must use the import library,
+ # so lt_dlopen is handled in another way
  else
-   newdlprefiles=$newdlprefiles $dir/$linklib
+   case $host in
+ *cygwin* | *mingw* )
+   newdlprefiles=$newdlprefiles $dir/$linklib
+;;
+ * )
+   if test -n $dlname; then
+ newdlprefiles=$newdlprefiles $dir/$dlname
+   else
+ newdlprefiles=$newdlprefiles $dir/$linklib
+   fi
+;;
+   esac

If so, then I guess the other code section would look like

 func_verbose extracting global C symbols from \`$dlprefile'
 func_basename $dlprefile
 name=$func_basename_result
-$opt_dry_run || {
-  eval '$ECHO : $name   $nlist'
-  eval $NM $dlprefile 2/dev/null | $global_symbol_pipe  '$nlist'
-}
+case $host in
+  *cygwin | *mingw* )
+# if an import library, we need to obtain dlname
+if func_win32_import_lib_p $dlprefile; then
+  func_tr_sh $dlprefile
+  eval curr_lafile=\$libfile_$tr_sh_result
+  $opt_dry_run || {
+if test -n $curr_lafile  func_lalib_p $curr_lafile; then
+  # geez. does this need to happen in a subshell, to
+  # avoid clobbering our current variable values?
+  source $curr_lafile
+  if test -n $dlname ; then
+func_basename $dlname
+dlbasename=$func_basename_result
+eval '$ECHO : $dlbasename  $nlist'
+  else
+func_warning Could not compute DLL name from $name
+eval '$ECHO : $name   $nlist'
+  fi
+else
+  func_warning Could not determing .la name from $name
+  eval '$ECHO : $name   $nlist'
+fi
+eval $NM $dlprefile 2/dev/null | $global_symbol_pipe |
+  $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' 
'$nlist'
+  }
+else # not an import lib
+  $opt_dry_run || {
+  eval '$ECHO : $name   $nlist'
+  eval $NM $dlprefile 2/dev/null | $global_symbol_pipe 
'$nlist'
+  }
+fi
+;;
+  *)
etc.

Is that the idea?

--
Chuck