parsingbinaryfiles32bit-64bitelfmemory-alignment

How to parse correctly the `.note.gnu.property` section of an ELF executable?


I am writing an ELF parser as a side project and I have encountered a problem while trying to parse .note* sections. The documentation for ELF32 and ELF64 (available here and here, pages 42 and 13 respectively) says

These sections contain any number of note entries, each of which is an array of N-byte words in the byte order defined in the ELF file header.

where N is 4 for ELF32 and 8 for ELF64.

Note Section entry format

But if I take a look into an example hello world program, written in C and compiled with gcc (11.4.0), with readelf -x .note.gnu.property hello.x I get

Hex dump of section '.note.gnu.property':
  0x00000338 04000000 20000000 05000000 474e5500 .... .......GNU.
  0x00000348 020000c0 04000000 03000000 00000000 ................
  0x00000358 028000c0 04000000 01000000 00000000 ................

This section does not seem made by 8-byte words even though the ELF is 64 bits: Output of readelf -h hello.x:

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Position-Independent Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x1060
  Start of program headers:          64 (bytes into file)
  Start of section headers:          13976 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         13
  Size of section headers:           64 (bytes)
  Number of section headers:         31
  Section header string table index: 30

Moreover, the entries in the section does not seem to be aligned on an 8-byte boundary as the section header says. Output of readelf --sections hello.x:

There are 31 section headers, starting at offset 0x3698:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
...
  [ 2] .note.gnu.pr[...] NOTE             0000000000000338  00000338
       0000000000000030  0000000000000000   A       0     0     8
...

I tried parsing the .note.gnu.property section as an array of 8-byte words aligned on 8-byte boundaries but that resulted in reading out of the file since, instead of reading namesz=0x4 and descsz=0x20, my program read namesz=0x2000000004 and tried reading that number of bytes from the file.

To conclude, it seems clear that the correct way to parse .note* sections is to read 4-byte words aligned on 4-byte boundaries as if they were in an ELF32 file regardless of the actual EI_CLASS. I just don't understand why, maybe I am just misinterpreting some information in the documentation.


Solution

  • I just don't understand why, maybe I am just misinterpreting some information in the documentation.

    You are mis-interpreting the documentation: