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?

1 Answer 1


(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, 2014 at 14:18
  • This output is not from the script, it's annotated assembler output from the compiler.
    – Igor Skochinsky
    Sep 25, 2014 at 19:51

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.