TransWikia.com

Meaning of Flags in ELF Section header?

Reverse Engineering Asked by Jiaming on December 18, 2020

Given this classic helloworld.c example,

#include <stdio.h>

int main() {
    printf("Hello world!n");
}

In below sections output, the value for Flags presents a couple of different values, e.g. A, AI, AX, WA, etc.

From man elf, I understand A probably corresponds to SHF_ALLOC, W for SHF_WRITE, X for SHF_EXECINSTR. But how about AI?

Is the correspondence between those long and short forms documented?

$ readelf -S helloworld

There are 34 section headers, starting at offset 0x2188:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .interp           PROGBITS         0000000000000238  00000238
       000000000000001c  0000000000000000   A       0     0     1
  [ 2] .note.ABI-tag     NOTE             0000000000000254  00000254
       0000000000000020  0000000000000000   A       0     0     4
  [ 3] .note.gnu.build-i NOTE             0000000000000274  00000274
       0000000000000024  0000000000000000   A       0     0     4
  [ 4] .gnu.hash         GNU_HASH         0000000000000298  00000298
       000000000000001c  0000000000000000   A       5     0     8
  [ 5] .dynsym           DYNSYM           00000000000002b8  000002b8
       00000000000000a8  0000000000000018   A       6     1     8
  [ 6] .dynstr           STRTAB           0000000000000360  00000360
       0000000000000082  0000000000000000   A       0     0     1
  [ 7] .gnu.version      VERSYM           00000000000003e2  000003e2
       000000000000000e  0000000000000002   A       5     0     2
  [ 8] .gnu.version_r    VERNEED          00000000000003f0  000003f0
       0000000000000020  0000000000000000   A       6     1     8
  [ 9] .rela.dyn         RELA             0000000000000410  00000410
       00000000000000c0  0000000000000018   A       5     0     8
  [10] .rela.plt         RELA             00000000000004d0  000004d0
       0000000000000018  0000000000000018  AI       5    22     8
  [11] .init             PROGBITS         00000000000004e8  000004e8
       0000000000000017  0000000000000000  AX       0     0     4
  [12] .plt              PROGBITS         0000000000000500  00000500
       0000000000000020  0000000000000010  AX       0     0     16
  [13] .plt.got          PROGBITS         0000000000000520  00000520
       0000000000000008  0000000000000008  AX       0     0     8
  [14] .text             PROGBITS         0000000000000530  00000530
       00000000000001a2  0000000000000000  AX       0     0     16
  [15] .fini             PROGBITS         00000000000006d4  000006d4
       0000000000000009  0000000000000000  AX       0     0     4
  [16] .rodata           PROGBITS         00000000000006e0  000006e0
       0000000000000011  0000000000000000   A       0     0     4
  [17] .eh_frame_hdr     PROGBITS         00000000000006f4  000006f4
       000000000000003c  0000000000000000   A       0     0     4
  [18] .eh_frame         PROGBITS         0000000000000730  00000730
       0000000000000108  0000000000000000   A       0     0     8
  [19] .init_array       INIT_ARRAY       0000000000200db8  00000db8
       0000000000000008  0000000000000008  WA       0     0     8
  [20] .fini_array       FINI_ARRAY       0000000000200dc0  00000dc0
       0000000000000008  0000000000000008  WA       0     0     8
  [21] .dynamic          DYNAMIC          0000000000200dc8  00000dc8
       00000000000001f0  0000000000000010  WA       6     0     8
  [22] .got              PROGBITS         0000000000200fb8  00000fb8
       0000000000000048  0000000000000008  WA       0     0     8
  [23] .data             PROGBITS         0000000000201000  00001000
       0000000000000010  0000000000000000  WA       0     0     8
  [24] .bss              NOBITS           0000000000201010  00001010
       0000000000000008  0000000000000000  WA       0     0     1

More following...

Let’s dump the section header table in binary to see what’s actually stored in place of the Flags,

hexdump -v -s 0x2188 -n 768 -e '4/1 "%02x" " " 4/1 "%02x" " " 8/1 "%02x" " " 48/1 "%02x" "n"' helloworld

As per Elf64_Shdr struct, the 3rd column in the following output is
the binary form of flags(sh_flags).

00000000 00000000 0000000000000000 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
1b000000 01000000 0200000000000000 380200000000000038020000000000001c00000000000000000000000000000001000000000000000000000000000000
23000000 07000000 0200000000000000 540200000000000054020000000000002000000000000000000000000000000004000000000000000000000000000000
31000000 07000000 0200000000000000 740200000000000074020000000000002400000000000000000000000000000004000000000000000000000000000000
44000000 f6ffff6f 0200000000000000 980200000000000098020000000000001c00000000000000050000000000000008000000000000000000000000000000
4e000000 0b000000 0200000000000000 b802000000000000b802000000000000a800000000000000060000000100000008000000000000001800000000000000
56000000 03000000 0200000000000000 600300000000000060030000000000008200000000000000000000000000000001000000000000000000000000000000
5e000000 ffffff6f 0200000000000000 e203000000000000e2030000000000000e00000000000000050000000000000002000000000000000200000000000000
6b000000 feffff6f 0200000000000000 f003000000000000f0030000000000002000000000000000060000000100000008000000000000000000000000000000
7a000000 04000000 0200000000000000 10040000000000001004000000000000c000000000000000050000000000000008000000000000001800000000000000
84000000 04000000 4200000000000000 d004000000000000d0040000000000001800000000000000050000001600000008000000000000001800000000000000
8e000000 01000000 0600000000000000 e804000000000000e8040000000000001700000000000000000000000000000004000000000000000000000000000000

As a combination of above two outputs, the following correspondence between the flag’s binary form and the literal form is observed.

02 = 0000 0010 = A
42 = 0100 0010 = AI
06 = 0000 0110 = AX

Are these correspondences documented?

2 Answers

The flag abbreviation of the letter "I" stands for SHF_INFO_LINK.

Since readelf is open-source you can access its code to verify this. This will also show you the full list of Flag possibilities:

...

switch (flag)
        {
        case SHF_WRITE:     *p = 'W'; break;
        case SHF_ALLOC:     *p = 'A'; break;
        case SHF_EXECINSTR:     *p = 'X'; break;
        case SHF_MERGE:     *p = 'M'; break;
        case SHF_STRINGS:       *p = 'S'; break;
        case SHF_INFO_LINK:     *p = 'I'; break;
        case SHF_LINK_ORDER:    *p = 'L'; break;
        case SHF_OS_NONCONFORMING:  *p = 'O'; break;
        case SHF_GROUP:     *p = 'G'; break;
        case SHF_TLS:       *p = 'T'; break;
        case SHF_EXCLUDE:       *p = 'E'; break;
        case SHF_COMPRESSED:    *p = 'C'; break;
        case SHF_GNU_MBIND:     *p = 'D'; break;

...

The relevant lines on Github can be found in the following link.

Correct answer by Megabeets on December 18, 2020

From the readelf output for section headers:

Key to Flags:

W (write), A (alloc), X (execute), M (merge), S (strings) I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) O (extra OS processing required) o (OS specific), p (processor specific)

Answered by rizwan on December 18, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP