For C++ program with try catch defined, when using g++ to compile it into assembly code (test is on x86 32bit Linux, g++ 4.6.3)

g++ -S cppexcept.cc

A specified section called .gcc_except_table is produced like below:

        .section        .gcc_except_table
        .align 4
        .byte   0xff
        .byte   0
        .uleb128 .LLSDATT980-.LLSDATTD980
        .byte   0x1
        .uleb128 .LLSDACSE980-.LLSDACSB980
        .uleb128 .LEHB3-.LFB980
        .uleb128 .LEHE3-.LEHB3
        .uleb128 0
        .uleb128 0
        .uleb128 .LEHB4-.LFB980
        .uleb128 .LEHE4-.LEHB4
        .uleb128 .L19-.LFB980
        .uleb128 0x3
        .uleb128 .LEHB5-.LFB980
        .uleb128 .LEHE5-.LEHB5
        .uleb128 0
        .uleb128 0
        .uleb128 .LEHB6-.LFB980
        .uleb128 .LEHE6-.LEHB6
        .uleb128 .L20-.LFB980
        .uleb128 0
        .uleb128 .LEHB7-.LFB980
        .uleb128 .LEHE7-.LEHB7
        .uleb128 .L21-.LFB980
        .uleb128 0

After the compilation into exe file with ELF format, it seems that there are two sections related to exception handling, which are .gcc_except_table and .eh_frame.

However, I dumped the contents of these two section with the following commands, comparing the labels' memory addresses with what are defined in .gcc_except_table, but it seems too blur to me...

objdump -s -j .gcc_except_table cppexcept
objdump -s -j .eh_frame cppexcept

So my question is:

Is there any way to recover the information defined in the .gcc_except_table (which is shown above) from ELF file's .gcc_except_table and eh_frame tables?


(I think you may get some extra comments if you use -fverbose-asm.)

Recovering information from these tables is definitely possible, although documentation is scarce and is often present only in the code which parses them.

The .eh_frame layout is described briefly in the LSB documentation. Ian Lance Taylor (author of the gold linker) also made some blog posts on .eh_frame and .gcc_except_table layout.

For a more reference-like description, check my Recon 2012 slides (start at 37 or so).

I've made an IDA script (gcc_extab.py) which parses .eh_frame and .gcc_except_table and formats them nicely.

Taking a sample program:

void f()
    throw 1;

int main()
    int j;
    try {
    } catch (int i) {
        j = i;
    return 0;

I'll show the commented structures produced by GCC.

First, the .eh_table (some parts omitted for clarity):

.Lframe1:                     # start of CFI 1
    .long   .LECIE1-.LSCIE1   # length of CIE 1 data
.LSCIE1:                      # start of CIE 1 data
    .long   0                 # CIE id
    .byte   0x1               # Version
    .string "zPL"             # augmentation string:
                              # z: has augmentation data
                              # P: has personality routine pointer
                              # L: has LSDA pointer
    .uleb128 0x1              # code alignment factor
    .sleb128 -4               # data alignment factor
    .byte   0x8               # return address register no.
    .uleb128 0x6              # augmentation data length (z)
    .byte   0                 # personality routine pointer encoding (P): DW_EH_PE_ptr|DW_EH_PE_absptr
    .long   __gxx_personality_v0 # personality routine pointer (P)
    .byte   0                 # LSDA pointer encoding: DW_EH_PE_ptr|DW_EH_PE_absptr
    .byte   0xc               # Initial CFI Instructions
    .align 4
.LECIE1:                      # end of CIE 1

.LSFDE3:                      # start of FDE 3
    .long   .LEFDE3-.LASFDE3  # length of FDE 3
.LASFDE3:                     # start of FDE 3 data
    .long   .LASFDE3-.Lframe1 # Distance to parent CIE from here
    .long   .LFB1             # initial location                
    .long   .LFE1-.LFB1       # range length                    
    .uleb128 0x4              # Augmentation data length (z)    
    .long   .LLSDA1           # LSDA pointer (L)                
    .byte   0x4               # CFI instructions                
    .long   .LCFI2-.LFB1
    .align 4
.LEFDE3:                      # end of FDE 3

Next, the LSDA (language-specific data area) in .gcc_except_table, referenced by FDE 3:

.LLSDA1:                           # LSDA 1
    .byte   0xff                   # LPStart encoding: DW_EH_PE_omit
    .byte   0                      # TType encoding: DW_EH_PE_ptr|DW_EH_PE_absptr
    .uleb128 .LLSDATT1-.LLSDATTD1  # TType offset
.LLSDATTD1:                        # LSDA 1 action table
    .byte   0x1                    # call site encoding: DW_EH_PE_uleb128|DW_EH_PE_absptr
    .uleb128 .LLSDACSE1-.LLSDACSB1 # call site table length
.LLSDACSB1:                        # LSDA 1 call site entries
    .uleb128 .LEHB0-.LFB1          # call site 0 start
    .uleb128 .LEHE0-.LEHB0         # call site 0 length
    .uleb128 .L8-.LFB1             # call site 0 landing pad
    .uleb128 0x1                   # call site 0 action (1=action 1)
    .uleb128 .LEHB1-.LFB1          # call site 1 start
    .uleb128 .LEHE1-.LEHB1         # call site 1 length
    .uleb128 0                     # call site 1 landing pad
    .uleb128 0                     # call site 1 action (0=no action)
.LLSDACSE1:                        # LSDA 1 action table entries
    .byte   0x1                    # action 1 filter (1=T1 typeinfo)
    .byte   0                      # displacement to next action (0=end of chain)
    .align 4
    .long   _ZTIi                  # T1 typeinfo ("typeinfo for int")
.LLSDATT1:                         # LSDA 1 TTBase
  • Hello Igor, thank you a lot for this helpful answer! Do you mind to attach how you compile the simple program.? I tried on my computer and process the script with IDA 6.4, but I can not get your output. Sep 25 '14 at 14:18
  • This output is not from the script, it's annotated assembler output from the compiler.
    – Igor Skochinsky
    Sep 25 '14 at 19:51

This site is temporarily in read only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .