Menu

#541 elfcopy produces corrupted output when combining --only-section and --output-format

RELEASE_1_0
closed
Kai Wang
None
2016-12-27
2016-12-09
Ed Maste
No

Keeping only certain sections and converting to a non-ELF format in one step produces corrupted output. Reproduction case below. The converted PE file is not expected to be useful, but demonstrates the issue.

  • Start with the same test object as ticket 540:
% cat hello.c
#include <stdio.h>
int main(int argc, char *argv[]) { puts("hello world"); }
% cc hello.c
  • Create a new ELF file keeping only three sections, then convert that to EFI output, and examine the result:
% elfcopy/elfcopy -j .ctors -j .text -j .data a.out a.elf       
% elfcopy/elfcopy --output-target efi-app-x86_64 a.elf a.efi
% objdump -h a.efi                                          

a.efi:     file format efi-app-x86_64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .text         000002b8  00000000004004e0  00000000004004e0  00000200  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .ctors        00000010  0000000000600860  0000000000600860  00000600  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .data         0000001c  0000000000600a30  0000000000600a30  00000800  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  • Keep three sections and convert to PE in one step, observe corrupt section names:
% elfcopy/elfcopy -j .ctors -j .text -j .data --output-target efi-app-x86_64 a.out a.efi
% objdump -h a.efi

a.efi:     file format efi-app-x86_64

Sections:
Idx Name          Size      VMA               LMA               File off  Algn
  0 .interp       000002b8  00000000004004e0  00000000004004e0  00000200  2**2
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 p             00000010  0000000000600860  0000000000600860  00000600  2**2
                  CONTENTS, ALLOC, LOAD, DATA
  2 .tag          0000001c  0000000000600a30  0000000000600a30  00000800  2**2
                  CONTENTS, ALLOC, LOAD, DATA

In this case the section contents appear to be valid, only the names are corrupt. In other cases at least addresses are also incorrect.

See LLVM PR 23214, comment 37 for the original case that found this issue.

Discussion

  • Ed Maste

    Ed Maste - 2016-12-09
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -1,13 +1,13 @@
     Keeping only certain sections and converting to a non-ELF format in one step produces corrupted output. Reproduction case below. The converted PE file is not expected to be useful, but demonstrates the issue.
    
    -1. Start with the same test object as ticket 540:
    +* Start with the same test object as ticket 540:
     ```
     % cat hello.c
     #include <stdio.h>
     int main(int argc, char *argv[]) { puts("hello world"); }
     % cc hello.c
     ```
    -2. Create a new ELF file keeping only three sections, then convert that to EFI output, and examine the result:
    +* Create a new ELF file keeping only three sections, then convert that to EFI output, and examine the result:
     ```
     % elfcopy/elfcopy -j .ctors -j .text -j .data a.out a.elf       
     % elfcopy/elfcopy --output-target efi-app-x86_64 a.elf a.efi
    @@ -24,7 +24,7 @@
       2 .data         0000001c  0000000000600a30  0000000000600a30  00000800  2**2
                       CONTENTS, ALLOC, LOAD, DATA
     ```
    -3. Keep three sections and convert to PE in one step, observe corrupt section names:
    +* Keep three sections and convert to PE in one step, observe corrupt section names:
     ```
     % elfcopy/elfcopy -j .ctors -j .text -j .data --output-target efi-app-x86_64 a.out a.efi
     % objdump -h a.efi
    
     
  • Kai Wang

    Kai Wang - 2016-12-19
    • status: new --> assigned
    • assigned_to: Kai Wang
     
  • Kai Wang

    Kai Wang - 2016-12-27
    • status: assigned --> closed
     
  • Kai Wang

    Kai Wang - 2016-12-27

    Thanks! This seems to be a long standing bug. Should be fixed by [r3507].

     

    Related

    Commit: [r3507]

  • Ed Maste

    Ed Maste - 2016-12-27

    Confirmed, thank you for the fix!

    One other difference I noticed during the investigation that prompted this ticket is that GNU objcopy maintains a relationship (modulo 2K alignment) between the VMA and file offset, while elfcopy does not. GNU objcopy also drops the READONLY flag on .data. I'm not sure what PE specs say about either of these, and whether it's important or not.

    For example from GNU objcopy:

    Sections:
    Idx Name          Size      VMA               LMA               File off  Algn
      0 .eh_frame     000083d8  0000000000002000  0000000000002000  00000400  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
      1 .text         00046f03  000000000000b000  000000000000b000  00008800  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, CODE
      2 .data         0000671b  0000000000052000  0000000000052000  0004f800  2**2
                      CONTENTS, ALLOC, LOAD, DATA
      3 .data         0000aa22  0000000000058720  0000000000058720  00056120  2**2
                      CONTENTS, ALLOC, LOAD, DATA
      4 .data         00000040  0000000000063150  0000000000063150  00060d50  2**2
                      CONTENTS, ALLOC, LOAD, DATA
      5 .data         00000051  0000000000063190  0000000000063190  00060f90  2**2
                      CONTENTS, ALLOC, LOAD, DATA
      6 .data         00000016  00000000000631e2  00000000000631e2  000611e2  2**2
                      CONTENTS, ALLOC, LOAD, DATA
      7 .data         00000008  00000000000631f8  00000000000631f8  000613f8  2**2
                      CONTENTS, ALLOC, LOAD, DATA
      8 .sdata        00000568  0000000000065000  0000000000065000  00061600  2**2
                      CONTENTS, ALLOC, LOAD, DATA
      9 .dynamic      000000b0  0000000000066000  0000000000066000  00061c00  2**2
                      CONTENTS, ALLOC, LOAD, DATA
     10 .rela.dyn     00004158  0000000000067000  0000000000067000  00061e00  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
     11 .reloc        0000000a  000000000006c000  000000000006c000  00066000  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
     12 .dynsym       00003c18  000000000006d000  000000000006d000  00066200  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
    

    From elfcopy:

    Sections:
    Idx Name          Size      VMA               LMA               File off  Algn
      0 .eh_fram      000083d8  0000000000002000  0000000000002000  00000400  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
      1 .text         00046f03  000000000000b000  000000000000b000  00008800  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, CODE
      2 .data         0000671b  0000000000052000  0000000000052000  0004f800  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
      3 .data         0000aa22  0000000000058720  0000000000058720  00056000  2**2
                      CONTENTS, ALLOC, LOAD, DATA
      4 .data         00000040  0000000000063150  0000000000063150  00060c00  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
      5 .data         00000051  0000000000063190  0000000000063190  00060e00  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
      6 .data         00000016  00000000000631e2  00000000000631e2  00061000  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
      7 .data         00000008  00000000000631f8  00000000000631f8  00061200  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
      8 .sdata        00000568  0000000000065000  0000000000065000  00061400  2**2
                      CONTENTS, ALLOC, LOAD, DATA
      9 .dynamic      000000b0  0000000000066000  0000000000066000  00061a00  2**2
                      CONTENTS, ALLOC, LOAD, DATA
     10 .rela.dy      00004158  0000000000067000  0000000000067000  00061c00  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
     11 .reloc        0000000a  000000000006c000  000000000006c000  00065e00  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
     12 .dynsym       00003c18  000000000006d000  000000000006d000  00066000  2**2
                      CONTENTS, ALLOC, LOAD, READONLY, DATA
    
     

Log in to post a comment.