6

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 2

8

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.

2

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)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.