Search code examples
linuxgccelfobjdump

Debug sections after binary is stripped


I built my application(c/c++) on linux and stripped it using "strip" command. I thought without giving any options it will strip all the debugging info from the original binary. I stripped using following:

strip my_app -o $odir/my_app_stripped  (where $odir is preconfigured location)

However, when I do the following:

objdump -h my_app_stripped

It gives me the following output:

my_app_stripped: file format elf32-i386
Sections:
Idx Name          Size      VMA       LMA       File off  Algn
 0 .interp       0000002c  00048154  00048154  00000154  2**0
                 CONTENTS, ALLOC, LOAD, READONLY, DATA
 1 .note.ABI-tag 00000020  00048180  00048180  00000180  2**2
              CONTENTS, ALLOC, LOAD, READONLY, DATA
 2 .hash         00067dcc  000481a0  000481a0  000001a0  2**2
              CONTENTS, ALLOC, LOAD, READONLY, DATA
 3 .dynsym       0011f6e0  000aff6c  000aff6c  00067f6c  2**2
              CONTENTS, ALLOC, LOAD, READONLY, DATA
 4 .dynstr       00488e4c  001cf64c  001cf64c  0018764c  2**0
              CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .gnu.version  00023edc  00658498  00658498  00610498  2**1
              CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .gnu.version_r 00000290  0067c374  0067c374  00634374  2**2
              CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .rel.dyn      00006860  0067c604  0067c604  00634604  2**2
              CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .rel.plt      00003768  00682e64  00682e64  0063ae64  2**2
              CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .init         00000017  006865cc  006865cc  0063e5cc  2**2
              CONTENTS, ALLOC, LOAD, READONLY, CODE
10 .plt          00006ee0  006865e4  006865e4  0063e5e4  2**2
              CONTENTS, ALLOC, LOAD, READONLY, CODE
11 .text         01120918  0068d4d0  0068d4d0  006454d0  2**4
              CONTENTS, ALLOC, LOAD, READONLY, CODE
12 BINK          00018d20  017addf0  017addf0  01765df0  2**4
              CONTENTS, ALLOC, LOAD, READONLY, CODE
13 BINK32        00001350  017c6b10  017c6b10  0177eb10  2**4
              CONTENTS, ALLOC, LOAD, READONLY, CODE
14 BINK16        00001008  017c7e60  017c7e60  0177fe60  2**4
              CONTENTS, ALLOC, LOAD, READONLY, CODE
15 BINKP8        000008fb  017c8e70  017c8e70  01780e70  2**4
              CONTENTS, ALLOC, LOAD, READONLY, CODE
16 BINKY16       000008e1  017c9770  017c9770  01781770  2**4
              CONTENTS, ALLOC, LOAD, READONLY, CODE
17 BINKY12       000001b0  017ca060  017ca060  01782060  2**4
              CONTENTS, ALLOC, LOAD, READONLY, CODE
18 .fini         0000001a  017ca210  017ca210  01782210  2**2
              CONTENTS, ALLOC, LOAD, READONLY, CODE
19 .rodata       00164204  017ca240  017ca240  01782240  2**6
              CONTENTS, ALLOC, LOAD, READONLY, DATA
20 .debug$S      000010f8  0192e444  0192e444  018e6444  2**0
              CONTENTS, ALLOC, LOAD, READONLY, DATA
21 BINKCONST     00004e40  0192f540  0192f540  018e7540  2**6
              CONTENTS, ALLOC, LOAD, READONLY, DATA
22 .debug$F      00000250  01934380  01934380  018ec380  2**0
              CONTENTS, ALLOC, LOAD, READONLY, DATA
23 .rdata        00000080  019345d0  019345d0  018ec5d0  2**4
              CONTENTS, ALLOC, LOAD, READONLY, DATA
24 .eh_frame_hdr 0004765c  01934650  01934650  018ec650  2**2
              CONTENTS, ALLOC, LOAD, READONLY, DATA
25 .eh_frame     00128fec  0197bcac  0197bcac  01933cac  2**2
              CONTENTS, ALLOC, LOAD, READONLY, DATA
26 .gcc_except_table 000aaaf1  01aa4c98  01aa4c98  01a5cc98  2**2
              CONTENTS, ALLOC, LOAD, READONLY, DATA
27 .tbss         00000004  01b5078c  01b5078c  01b0778c  2**2
              ALLOC, THREAD_LOCAL
28 .ctors        000004f4  01b5078c  01b5078c  01b0778c  2**2
              CONTENTS, ALLOC, LOAD, DATA
29 .dtors        000004d0  01b50c80  01b50c80  01b07c80  2**2
              CONTENTS, ALLOC, LOAD, DATA
30 .jcr          00000004  01b51150  01b51150  01b08150  2**2
              CONTENTS, ALLOC, LOAD, DATA
31 .data.rel.ro  00012160  01b51160  01b51160  01b08160  2**5
              CONTENTS, ALLOC, LOAD, DATA
32 .dynamic      00000240  01b632c0  01b632c0  01b1a2c0  2**2
              CONTENTS, ALLOC, LOAD, DATA
33 .got          00002e6c  01b63500  01b63500  01b1a500  2**2
              CONTENTS, ALLOC, LOAD, DATA
34 .data         000481a8  01b66380  01b66380  01b1d380  2**5
              CONTENTS, ALLOC, LOAD, DATA
35 .got.plt      00001bc0  01bae528  01bae528  01b65528  2**2
              CONTENTS, ALLOC, LOAD, DATA
36 BINKDATA      00002de0  01bb0100  01bb0100  01b67100  2**5
              CONTENTS, ALLOC, LOAD, DATA
37 .bss          0046f8e8  01bb2ee0  01bb2ee0  01b69ee0  2**5
              ALLOC
38 BINKBSS       000067a0  020227e0  020227e0  01b69ee0  2**5
              ALLOC
39 .comment      00002d95  00000000  00000000  01b69ee0  2**0
              CONTENTS, READONLY
40 .drectve      0000005d  00000000  00000000  01b6cc75  2**0
              CONTENTS, READONLY

So, if debugging was all removed what are the sections ".debug$S" and ".debug$F" ?


Solution

  • Despite their names those sections aren't debugging sections, at least not according to their flags. You'll notice that they have the same flags, CONTENTS, ALLOC, LOAD, READONLY, DATA, as a number of other sections in the executable like .rodata. These flags say that the section is meant to be loaded into memory and used as data. The strip command has no way knowing if these sections are unnecessary or not. Discarding the .rodata section would break your program, causing it to crash every time its run. The strip command doesn't know that discarding the .debug$F and .debug$S sections wouldn't do the same thing.

    Note that you don't normally find sections named .debug$F and debug$S in ELF executables. The DWARF debugging information normally used in ELF files is stored in sections whose names begin with .debug_ not .debug$. They also have the DEBUGGING flag set (but not the LOAD flag) so strip knows that they're debugging sections and that it should and can remove. Sections with these names are normally only seen in PECOFF files produced by Microsoft's compilers. They contain debugging information in Microsoft's proprietary format.

    If you can determine that these sections don't contain useful information and want to get rid of them you should remove them from the object files before linking. Since they're loaded into memory, it's probably too late to completely remove them after linking. You can use a command like objcopy -R ".debug$*" foo.o foo-stripped.o and then link with foo-stripped.o instead of foo.o.

    You might also want to strip the .comment and .directve sections from the executable, as the these sections probably aren't necessary. In particular .directve is another PECOFF section you don't normally see in ELF files.