This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
Patch for strip
On Fri, May 12, 2000 at 04:00:09PM -0600, llewelly@dbritsch.dsl.xmission.com wrote:
> > > If you decide to strip(1) them, be careful. On my i686-pc-linux-gnu, with
> > > binutils 2.9.5.0.41, I need to use 'strip --strip-debug foo.a' and *not*
> > > 'strip --strip-unneeded foo.a'. The --strip-unneeded rips out the stack
> > > unwinding stuff needed for exceptions, which it seems to consider
> > > 'unneeded'
> >
> > This sounds like a bug in strip. Could you please provide a small
> > testcase? I'd like to fix it.
> >
> > Thanks.
> >
> >
> > H.J.
> >
>
> Actually, it appears that I misunderstood what was going on.
> I had had some problems with stripped executables that contained
> exception throwing code. I had noticed that strip removed the
> '__EXCEPTION_TABLE__' and '__FRAME_BEGIN__' symbols, so I
> (incorrectly) assumed that was the cause of the problems.
>
> It seems that the function containing the 'throw' is
> disappearing.
>
> I have a test case that (I think) shows a bug in strip, but it is not
> the bug I thought it was.
>
> Here it is:
>
> {~/cc_exer}cat foo_vanish.h
> void foo(int j);
>
> extern int l;
> {~/cc_exer}cat foo_vanish.cc
>
> #include"foo_vanish.h"
>
> int l=1;
>
> void bar(int j)
> {
> throw j;
> }
>
> void foo(int j)
> {
> bar(j);
> }
>
> {~/cc_exer}cat foo_vanish_main.cc
>
> #include"foo_vanish.h"
>
> int main()
> {
> int k=1;
> try
> {
> foo(k);
> }
> catch(int i)
> {
> return l;
> }
> return l;
> }
> {~/cc_exer}g++ -g -Wall -c foo_vanish.cc
> {~/cc_exer}nm --demangle foo_vanish.o
> 00000089 t Letext
> 00000000 ? __EXCEPTION_TABLE__
> 00000000 ? __FRAME_BEGIN__
> U __cp_push_exception
> U __eh_alloc
> U int type_info function
> U __throw
> 00000000 T bar(int)
> 0000006c T foo(int)
> 00000000 D l
> U terminate(void)
> {~/cc_exer}strip --strip-unneeded foo_vanish.o
> {~/cc_exer}nm --demangle foo_vanish.o
> U __cp_push_exception
> U __eh_alloc
> U int type_info function
> U __throw
> 00000000 T bar(int)
> U terminate(void)
> {~/cc_exer}g++ -g -Wall foo_vanish_main.cc foo_vanish.o
> /tmp/cciCkDOS.o: In function `main':
> /home/llewelly/cc_exer/foo_vanish_main.cc:9: undefined reference to `foo(int)'
> /home/llewelly/cc_exer/foo_vanish_main.cc:15: undefined reference to `l'
> /home/llewelly/cc_exer/foo_vanish_main.cc:13: undefined reference to `l'
> collect2: ld returned 1 exit status
How about this patch? I don't know how to tell an non-ELF object is
relocatable or not.
H.J.
----
2000-05-12 H.J. Lu (hjl@gnu.org)
* objcopy.c (filter_symbols): Don't strip global symbols in
ELF relocatable object files.
Index: objcopy.c
===================================================================
RCS file: /work/cvs/gnu/binutils/binutils/objcopy.c,v
retrieving revision 1.10
diff -u -p -r1.10 objcopy.c
--- objcopy.c 2000/05/12 15:11:30 1.10
+++ objcopy.c 2000/05/13 00:09:57
@@ -27,6 +27,9 @@
#include "budbg.h"
#include <sys/stat.h>
+#include "elf-bfd.h"
+#include "elf/common.h"
+
/* A list of symbols to explicitly strip out, or to keep. A linked
list is good enough for a small number from the command line, but
this will slow things down a lot if many symbols are being
@@ -556,6 +559,11 @@ filter_symbols (abfd, obfd, osyms, isyms
{
register asymbol **from = isyms, **to = osyms;
long src_count = 0, dst_count = 0;
+ int relocatable;
+
+ relocatable = bfd_get_flavour (abfd) == bfd_target_elf_flavour
+ && bfd_get_format (abfd) == bfd_object
+ && elf_elfheader (abfd)->e_type == ET_REL;
for (; src_count < symcount; src_count++)
{
@@ -609,6 +617,9 @@ filter_symbols (abfd, obfd, osyms, isyms
|| ((flags & BSF_SECTION_SYM) != 0
&& ((*bfd_get_section (sym)->symbol_ptr_ptr)->flags
& BSF_KEEP) != 0))
+ keep = 1;
+ else if (relocatable /* Relocatable file. */
+ && (flags & (BSF_GLOBAL | BSF_WEAK)) != 0)
keep = 1;
else if ((flags & BSF_GLOBAL) != 0 /* Global symbol. */
|| (flags & BSF_WEAK) != 0