SushiHangover

PowerShell, Learn it or Perish ;-)

master nix
Gitter

LLVM and the ARM ELF .ARM.exidx* section

In my last post I did a very basic comparsion of ARM code generation between LLVM and GCC compilers and testing the AXF in Qemu. The stand out difference was LLVM produced a *.ARM.exidx** section in the AXF/ELF while arm-gcc did not. The code is very simple, one .s and one .c file, no .cpp/.h involved.

So what is a .ARM.exidx section?

ARM ELF manual show this under the special sections chapter:

| Name |Type |Attributes | | - | - | - | | ARM.exidx | SHT_ARM_EXIDX | SHF_ALLOC + SHF_LINK_ORDER | _

Names beginning .ARM.exidx name sections containing index entries for section unwinding. Names beginning .ARM.extab name sections containing exception unwinding information. See [EHABI] for details.

Table 4_4 from that manual shows the Processor specific section types and our attribute is:

| Name | Value | Comment | | - | - | - | | “SHT_ARM_EXIDX” | 0x70000001 | | _

So the question remains, what is in the section and what is being created? Lets dump HelloWorldSimple.o and only look at that section:

1
2
3
4
5
6
7
Relocation section '.rel.ARM.exidx' at offset 0x580 contains 2 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00000000  00000b2a R_ARM_PREL31      00000000   .text
00000008  00000b2a R_ARM_PREL31      00000000   .text
Unwind table index '.ARM.exidx' at offset 0xcc contains 2 entries:
0x0 <print_uart0>: 0x1 [cantunwind]
0x54 <c_entry>: 0x1 [cantunwind]

So it added both function calls to the table, but are marked cantunwind, which makes sense, but since nothing in the section can be unwound, why include the section? Using gc-sections during linking does not remove it as it has references to functions that are being used…

Let do a quick test and add -funwind-tables, recompile and yes we get a fully populated unwind table and using -fno-unwind-tables produces the results from above, so that is the default one that is being use. Research is on-going on this one…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Relocation section '.rel.ARM.exidx' at offset 0x5a4 contains 4 entries:
 Offset     Info    Type            Sym.Value  Sym. Name
00000000  00000b2a R_ARM_PREL31      00000000   .text
00000000  00001600 R_ARM_NONE        00000000   __aeabi_unwind_cpp_pr0
00000008  00000b2a R_ARM_PREL31      00000000   .text
00000008  00001600 R_ARM_NONE        00000000   __aeabi_unwind_cpp_pr0
Unwind table index '.ARM.exidx' at offset 0xcc contains 2 entries:
0x0 <print_uart0>: 0x8001b0b0
  Compact model index: 0
  0x01      vsp = vsp + 8
  0xb0      finish
  0xb0      finish
0x54 <c_entry>: 0x809b8480
  Compact model index: 0
  0x9b      vsp = r11
  0x84 0x80 pop {r11, r14}

Additional Reading: ARM unwind table linker processing; this concerns a patch to bintutils/ld:

The patch below implements linker processing of ARM unwinding tables (SHT_ARM_EXIDX).

ARM exception index tables only define the start address of each region. This means that code with no unwinding information is effectively covered by the preceding unwinding table entry.

For normal exceptions that doesn’t matter so much - the user should ensure that any code they throw exceptions through has proper unwinding information.

Just as a quick check, I grep’d some source and the *.ARM.exidx** section is generated by the ARMELFStreamer:

1
2
3
4
5
6
7
8
http://llvm.org/docs/doxygen/html/ARMELFStreamer_8cpp_source.html
00274 inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
00275   SwitchToEHSection(".ARM.exidx",
00276                     ELF::SHT_ARM_EXIDX,
00277                     ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER,
00278                     SectionKind::getDataRel(),
00279                     FnStart);
00280 }
1
2
3
http://llvm.org/docs/doxygen/html/Support_2ELF_8h_source.html01145   // Fixme: All this is duplicated in MCSectionELF. Why??
01146   // Exception Index table
01147   SHT_ARM_EXIDX           = 0x70000001U,

Comments