2003-02-26 Michal Ludvig * dwarf2cfi.c (parse_frame_info): It's not true that FDEs always refer to the last CIE. We must deal with such a situation. * dwarf2cfi.h ( diff -upr gdb-upto-08/dwarf2cfi.c gdb/dwarf2cfi.c --- gdb-upto-08/dwarf2cfi.c 2003-02-26 10:20:02.000000000 +0100 +++ gdb/dwarf2cfi.c 2003-02-26 17:17:30.000000000 +0100 @@ -50,6 +50,10 @@ struct cie_unit char *data; unsigned int data_length; + /* This field is 1 for CIE from .eh_frame + and 0 for one from .debug_frame. */ + int eh_frame; + struct objfile *objfile; /* Next in chain. */ @@ -1502,6 +1502,7 @@ parse_frame_info (struct objfile *objfil char *aug; cie->objfile = objfile; + cie->eh_frame = (eh_frame > 0); cie->next = cie_chunks; cie_chunks = cie; @@ -1586,26 +1587,31 @@ parse_frame_info (struct objfile *objfil /* We assume that debug_frame is in order CIE,FDE,CIE,FDE,FDE,... and thus the CIE for this FDE - should be stored in last_cie pointer. If not, we'll - try to find it by the older way. */ - if (last_cie) + should be stored in last_cie pointer. + However this assumption is not always true, because + the linker does some magic and adds ghost CIEs under + some circumstances. Thus we need to do some safety + checks. If last_cie isn't valid, we'll try to find + the correct one using the older way. */ + if (last_cie && last_cie->objfile == objfile && + last_cie->eh_frame == (eh_frame > 0) && + ((eh_frame && + last_cie->offset == (unit_offset + bytes_read - cie_id)) || + (!eh_frame && (cie->offset == cie_id)))) cie = last_cie; else { - warning ("CFI: last_cie == NULL. " - "Perhaps a malformed %s section in '%s'...?\n", - curr_section_name, objfile->name); - cie = cie_chunks; while (cie) { if (cie->objfile == objfile) { - if (eh_frame && - (cie->offset == - (unit_offset + bytes_read - cie_id))) + if (eh_frame && cie->eh_frame && + cie->offset == + (unit_offset + bytes_read - cie_id)) break; - if (!eh_frame && (cie->offset == cie_id)) + if (!eh_frame && !cie->eh_frame && + cie->offset == cie_id) break; } @@ -1614,6 +1620,7 @@ parse_frame_info (struct objfile *objfil if (!cie) error ("CFI: can't find CIE pointer [in module %s]", bfd_get_filename (abfd)); + last_cie = cie; } init_loc = read_encoded_pointer (abfd, &start,