I wrote:
Eric Pouech wrote:
Could you send me the libwinspool.drv.so file that objcopy is choking on? I'd like to look whether there's something strange with that.
here it is... (I've used libpsapi.so instead, because it's smaller, but effects are the same)
Well, one difference I see is that yours has a .rel.stabs section, while mine doesn't. Now I don't quite understand why stabs need to be relocated, but I guess this could be a source of confusion. In any case, after I strip the stabs data using objcopy --strip-debug, I can subsequently use objcopy -N without problems.
The problem might be caused by the objcopy -L step not correctly updating the debug info. Could you try adding a --debugging argument to objcopy in both localize_imports and strip_imports?
No, it's definitely a problem with the .rel.stabs section. In fact, *every* invocation of objcopy that leaves the .rel.stabs section in its output fails -- even a simple identical copy. (Note that if you *remove* the .rel.stabs section, it works -- this is why a normal 'strip' works ...)
The reason for this is that objcopy relies on the bfd library to assign the file offsets of the sections in the output file. Unfortunately, the automatic assignment is done only for sections that are part of a segment (i.e. loaded into memory), and also for *those* sections outside of segments that are *not* reloc sections ... For reloc sections outside of segments, like the .rel.stabs section, no automatic file offset assignment is performed. Instead, the upper layers must do this themselves, which e.g. the linker does in its final_link step.
The objcopy tool, however, never does. This leads to an invalid file offset being used when writing out the .rel.stabs section, which causes the abort.
As a side note: I've tried using the --debugging argument, which basically recreates the debug sections from scratch instead of copying them, and this fails completely with my toolchain -- it runs into an endless loop. The reason for this is apparently a compiler bug in gcc 2.95.2 that miscompiles a routine from objcopy by converting a recursive function call into tail recursion in an invalid way ...
I still don't understand why your toolchain creates a .rel.stabs section in the first place. Could you check at which point this is created first (as, ld, ld -shared)?
Bye, Ulrich
I still don't understand why your toolchain creates a .rel.stabs section in the first place. Could you check at which point this is created first (as, ld, ld -shared)?
it's done in latest ld -shared step. even a simple test example generates a .rel.stab section... (simple function compiled and linked to generate a .so file)
I got a quick look at its content... it's always a relative relocation (like for a symbol global address), which in most examples I've seen is set to 0...
another nice "feature" is that lots of libraries also have the .rel.stab, so it seems to come also from the distro itself (even if I goofed somehow with my setup)
I'll dig further
anyway, I don't think removing the .rel.stab is a big deal. the current debugger code doesn't use the address of a global symbol in .stab section, but rather rely on the ELF information... (but if we also start by removing the .rel.stab section, the compilation scheme becomes more and more ugly)
A+
Eric Pouech wrote:
anyway, I don't think removing the .rel.stab is a big deal. the current debugger code doesn't use the address of a global symbol in .stab section, but rather rely on the ELF information... (but if we also start by removing the .rel.stab section, the compilation scheme becomes more and more ugly)
So, if you use this version of strip_imports, does the Wine build run through then?
#!/bin/sh # # Strip import stub symbols from Wine DLLs #
while [ $# -gt 0 ] do if [ ! -e $1 ] then echo "strip_imports: $1: file not found" exit 1 fi
/* Hack alert: some broken toolchains create a .rel.stab section. objcopy (all versions) has a bug that makes it unable to process reloc sections outside of segments (which .rel.stab is) ... Thus, we kill the .rel.stab section before running objcopy to remove the import stub symbols */ objcopy -R .rel.stab $1
IMPLIST=`nm $1 | grep __wine_dllimport | sed -e 's/^.*__wine_dllimport_[^_]*_/-N /'` if [ "$IMPLIST" != "" ] then echo $IMPLIST | xargs objcopy $1 fi
shift done
exit 0
Bye, Ulrich
Ulrich Weigand wrote:
Eric Pouech wrote:
anyway, I don't think removing the .rel.stab is a big deal. the current debugger code doesn't use the address of a global symbol in .stab section, but rather rely on the ELF information... (but if we also start by removing the .rel.stab section, the compilation scheme becomes more and more ugly)
So, if you use this version of strip_imports, does the Wine build run through then?
well, except from the fact that C comments are not welcomed in SHELL scripts :-O , the rest went fine (at least from the compilation point of view) debugger seemed to run fine... I could set the bp were I wanted there's still a few points I need to look at (especially if ELF addresses are right, and source file location for <x>.spec.c file)
I also asked a few .rel.stab questions to the binutils mailing list...
last point, couldn't we use a -s option to xargs ? (but I don't know if it's a nice feature of GNU gcc and if it's portable)
A+
Eric Pouech:
well, except from the fact that C comments are not welcomed in SHELL scripts :-O , the rest went fine (at least from the compilation point of view) debugger seemed to run fine... I could set the bp were I wanted there's still a few points I need to look at (especially if ELF addresses are right, and source file location for <x>.spec.c file)
Great. ;-)
last point, couldn't we use a -s option to xargs ? (but I don't know if it's a nice feature of GNU gcc and if it's portable)
I guess -s is quite portable; it's part of the Single Unix Specification. But why would we need it? Without -s, xargs is supposed to make the command lines as long as possible, i.e. up to the maximum length of the command line supported by the operating system. Isn't this exactly what we want here?
But I just noticed that I don't need the "$IMPLIST" != "" check, as a 'objcopy libxxx.so' does nothing, successfully ... So the command simplifies to
nm $1 | grep __wine_dllimport | sed -e 's/^.*__wine_dllimport_[^_]*_/-N /' | xargs objcopy $1
or maybe even
nm $1 | awk -F '__wine_dllimport_[^_]*_' '$2 {print "-N " $2}' | xargs objcopy $1
which is nearly simple enough to be inlined in the Make.rules again :-/
Bye, Ulrich