aleksey-makarov / melf

A Haskell library to parse/serialize Executable and Linkable Format (ELF)
BSD 3-Clause "New" or "Revised" License
5 stars 1 forks source link

Spurious intersecting sections error on RISC-V ELF binary #6

Closed nmeum closed 1 year ago

nmeum commented 1 year ago

Consider the following ELF binary: https://user.informatik.uni-bremen.de/~tempel/tmp/test-binary.elf

This binary is parsed fine by the elf package:

ghci> import Data.Elf
ghci> import Data.ByteString
ghci> do { Data.ByteString.readFile "/tmp/test-binary.elf" >>= pure . elfClass . parseElf }
ELFCLASS32

melf, however, does not seem to like this binary:

ghci> import Data.Elf
ghci> import qualified Data.ByteString.Lazy as BL
ghci> do { BL.readFile "/tmp/test-binary.elf" >>= parseElf >> pure () }
*** Exception: section SHN_EXT 3 (empty @4096) and section SHN_EXT 6 (3908 ... 4787) intersect (src/Data/Internal/Elf.hs:277)

Other tools such as readelf(1) et cetera also do not complain about this binary:

$ riscv-none-elf-readelf -h -S /tmp/test-binary.elf
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           RISC-V
  Version:                           0x1
  Entry point address:               0x105c4
  Start of program headers:          52 (bytes into file)
  Start of section headers:          5272 (bytes into file)
  Flags:                             0x0
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         3
  Size of section headers:           40 (bytes)
  Number of section headers:         9
  Section header string table index: 8

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00010094 000094 000838 00  AX  0   0  4
  [ 2] .rodata           PROGBITS        000108cc 0008cc 000640 00   A  0   0  4
  [ 3] .bss              NOBITS          00011000 001000 001f44 00  WA  0   0  4
  [ 4] .comment          PROGBITS        00000000 000f0c 00001b 01  MS  0   0  1
  [ 5] .riscv.attributes RISCV_ATTRIBUTE 00000000 000f27 00001c 00      0   0  1
  [ 6] .symtab           SYMTAB          00000000 000f44 000370 10      7  28  4
  [ 7] .strtab           STRTAB          00000000 0012b4 00019b 00      0   0  1
  [ 8] .shstrtab         STRTAB          00000000 00144f 000049 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  D (mbind), p (processor specific)

So I guess this is a bug in melf?

nmeum commented 1 year ago

BTW: If you strip the binary (thereby getting rid of section 6 about which melf complains) then the error message changes to:

section SHN_EXT 3 (empty @4096) and section table (3964 ... 4243) intersect (src/Data/Internal/Elf.hs:277)
aleksey-makarov commented 1 year ago

Section 3 starts at 0x1000 and ends at 0x1000 + 0x1f44 = 0x2f44 in the ELF file. Section 6 starts at 0xf44 and ends at 0xf44 + 0x370 = 0x12B4. Obviously they intersect so I don't see any bug in melf here.

melf has to build the tree of the sections/segments so it is more demanding on the structure of ELF file. Some gcc/binutils versions have bugs that result in generating ELF files where sections or segments or tables intersect. You can find another example of such incorrect binary in melf/testdata/arm_64_lsb/chmod.bad. That file was created by some old version of gcc/binutils and that bug was fixed in the later versions of gcc/binutils.

aleksey-makarov commented 1 year ago

In this case section 3 is ".bss". It should not (and does not) have any data in ELF file. But sections table says it has size 0x1f44 which is wrong. You may want to report the bug to RISC-V binutils maintainers.