Bug 4479 - objcopy --only-keep-debug broken
Summary: objcopy --only-keep-debug broken
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.18
: P2 normal
Target Milestone: ---
Assignee: Alan Modra
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-05-09 17:45 UTC by Andreas Schwab
Modified: 2007-05-15 11:16 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2007-05-10 07:00:24


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Schwab 2007-05-09 17:45:38 UTC
The patch for PR4144 broke objcopy --only-keep-debug.

$ objcopy --only-keep-debug vmlinux-2.6.21-4-default 
vmlinux-2.6.21-4-default.debug
BFD: vmlinux-2.6.21-4-default.debug: section `.text' can't be allocated in 
segment 0
objcopy: vmlinux-2.6.21-4-default.debug: Bad value
BFD: vmlinux-2.6.21-4-default.debug: section `.text' can't be allocated in 
segment 0
objcopy: vmlinux-2.6.21-4-default.debug: Bad value

The problem is that a !SEC_LOAD section does not contribute to p_filesz, so 
that in assign_file_positions_for_load_sections the value for adjust includes 
the size of all previous sections.  This causes p_memsz to overshoot, 
eventually growing so much that p_vaddr + p_memsz overflows in 
ELF_IS_SECTION_IN_SEGMENT.  Even if it does not overflow the values for p_memsz 
in the segments will be wrong.
Comment 1 Andreas Schwab 2007-05-09 17:55:12 UTC
To reproduce the bug (where objcopy.old has the patch for PR4144 reverted):

$ cat hello.c
#include <stdio.h>

int
main (void)
{
  printf ("Hello, world!\n");
}
$ gcc -g hello.c -o hello
$ objcopy.old --only-keep-debug hello hello.debug.1
$ objcopy --only-keep-debug hello hello.debug.2
$ diff -u <(readelf -l hello.debug.{1,2})
--- /dev/fd/63  2007-05-09 18:54:19.226345354 +0200
+++ /dev/fd/62  2007-05-09 18:54:19.218345356 +0200
@@ -12,9 +12,9 @@
                  0x0000000000000000 0x0000000000000018  R      1
       [Requesting program interpreter: ]
   LOAD           0x0000000000000000 0x4000000000000000 0x4000000000000000
-                 0x0000000000000238 0x0000000000000b40  R E    10000
+                 0x0000000000000238 0x000000000000380c  R E    10000
   LOAD           0x0000000000000b40 0x6000000000000b40 0x6000000000000b40
-                 0x0000000000000000 0x00000000000002d0  RW     10000
+                 0x0000000000000000 0x000000000000169c  RW     10000
   DYNAMIC        0x0000000000000b40 0x6000000000000b68 0x6000000000000b68
                  0x0000000000000000 0x00000000000001f0  RW     8
   NOTE           0x0000000000000238 0x4000000000000250 0x4000000000000250
Comment 2 Alan Modra 2007-05-10 03:16:08 UTC
I'd say that the p_memsz values were "wrong" before my patch.  It's also
interesting to look at what older objcopy does.  eg.
2.15 objcopy --only-keep-debug does this
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x10000000 0x10000000 0x00134 0x008fc R E 0x10000
  LOAD           0x0008fc 0x100108fc 0x100108fc 0x00000 0x00194 RWE 0x10000
vs. 2.16
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x10000034 0x10000034 0x00100 0x00100 R E 0x4
  INTERP         0x000134 0x10000134 0x10000134 0x00000 0x0000d R   0x1
      [Requesting program interpreter: ]
  LOAD           0x000000 0x10000000 0x10000000 0x00134 0x008fc R E 0x10000
  LOAD           0x0008fc 0x100108fc 0x100108fc 0x00000 0x00194 RWE 0x10000
  DYNAMIC        0x0008fc 0x10010920 0x10010920 0x00000 0x000c8 RW  0x4
  NOTE           0x000134 0x10000144 0x10000144 0x00000 0x00020 R   0x4
  NOTE           0x000134 0x10000164 0x10000164 0x00000 0x00018 R   0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x4
vs. mainline
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x10000034 0x10000034 0x00100 0x00100 R E 0x4
  INTERP         0x000134 0x10000134 0x10000134 0x00000 0x0000d R   0x1
      [Requesting program interpreter: ]
  LOAD           0x000000 0x10000000 0x10000000 0x00134 0x02c4b R E 0x10000
  LOAD           0x0008fc 0x100108fc 0x100108fc 0x00000 0x00658 RWE 0x10000
  DYNAMIC        0x0008fc 0x10010920 0x10010920 0x00000 0x000c8 RW  0x4
  NOTE           0x000134 0x10000144 0x10000144 0x00000 0x00020 R   0x4
  NOTE           0x000134 0x10000164 0x10000164 0x00000 0x00018 R   0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x4

I haven't looked to see yet whether the 2.15 -> 2.16 change was deliberate or not.
Comment 3 Alan Modra 2007-05-10 06:52:51 UTC
Probably not deliberate.  It came with 2004-05-17 David Heine.  I can't see that
there is any need for program headers in the debug info file anyway.
Comment 5 Andreas Schwab 2007-05-11 10:57:50 UTC
Fixed by <http://sourceware.org/ml/binutils-cvs/2007-05/msg00051.html>.
Comment 6 Alan Modra 2007-05-11 15:11:27 UTC
Further fix to completely remove headers
http://sourceware.org/ml/binutils-cvs/2007-05/msg00060.html
Comment 7 Andreas Schwab 2007-05-14 13:43:09 UTC
The removed program headers now breaks ia64:

BFD: a.debug: warning: allocated section `.IA_64.unwind' not in segment

The .IA_64.unwind section has SHT_IA64_UNWIND instead of SHT_NOBITS in the 
output.
Comment 8 Alan Modra 2007-05-15 11:58:08 UTC
This ought to cure the ia64 fallout. 
http://sourceware.org/ml/binutils-cvs/2007-05/msg00079.html
Comment 9 Andreas Schwab 2007-05-15 12:16:29 UTC
Works fine now.