From 4811e84d7c12540f651e90aaac521feef1edb169 Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 20 Jan 2018 18:18:09 +0100 Subject: [PATCH] Do not crash if CIE doesn't define CFA (#177) --- elftools/dwarf/callframe.py | 17 +++++++++-------- scripts/readelf.py | 13 +++++++++++-- test/testfiles_for_readelf/empty-cie.o.elf | Bin 0 -> 2344 bytes 3 files changed, 20 insertions(+), 10 deletions(-) create mode 100755 test/testfiles_for_readelf/empty-cie.o.elf diff --git a/elftools/dwarf/callframe.py b/elftools/dwarf/callframe.py index 127e2d8..e64c745 100644 --- a/elftools/dwarf/callframe.py +++ b/elftools/dwarf/callframe.py @@ -475,8 +475,11 @@ class CFIEntry(object): # line that serves as the base (first) line in the FDE's table. cie = self.cie cie_decoded_table = cie.get_decoded() - last_line_in_CIE = copy.copy(cie_decoded_table.table[-1]) - cur_line = copy.copy(last_line_in_CIE) + if len(cie_decoded_table.table) > 0: + last_line_in_CIE = copy.copy(cie_decoded_table.table[-1]) + cur_line = copy.copy(last_line_in_CIE) + else: + cur_line = dict(cfa=None) cur_line['pc'] = self['initial_location'] reg_order = copy.copy(cie_decoded_table.reg_order) @@ -569,8 +572,10 @@ class CFIEntry(object): cur_line = line_stack.pop() # The current line is appended to the table after all instructions - # have ended, in any case (even if there were no instructions). - table.append(cur_line) + # have ended, if there were instructions. + if cur_line['cfa'] is not None or len(cur_line) > 2: + table.append(cur_line) + return DecodedCallFrameTable(table=table, reg_order=reg_order) @@ -669,7 +674,3 @@ _OPCODE_NAME_MAP = {} for name in list(iterkeys(globals())): if name.startswith('DW_CFA'): _OPCODE_NAME_MAP[globals()[name]] = name - - - - diff --git a/scripts/readelf.py b/scripts/readelf.py index 397dfbd..4fec084 100755 --- a/scripts/readelf.py +++ b/scripts/readelf.py @@ -1171,13 +1171,17 @@ class ReadElf(object): self._emitline('\n%08x ZERO terminator' % entry.offset) continue + # Decode the table. + decoded_table = entry.get_decoded() + if len(decoded_table.table) == 0: + continue # Print the heading row for the decoded table self._emit(' LOC') self._emit(' ' if entry.structs.address_size == 4 else ' ') self._emit(' CFA ') - # Decode the table and look at the registers it describes. + # Look at the registers the decoded table describes. # We build reg_order here to match readelf's order. In particular, # registers are sorted by their number, and the register matching # ra_regnum is always listed last with a special heading. @@ -1201,7 +1205,12 @@ class ReadElf(object): for line in decoded_table.table: self._emit(self._format_hex( line['pc'], fullhex=True, lead0x=False)) - self._emit(' %-9s' % describe_CFI_CFA_rule(line['cfa'])) + + if line['cfa'] is not None: + s = describe_CFI_CFA_rule(line['cfa']) + else: + s = 'u' + self._emit(' %-9s' % s) for regnum in reg_order: if regnum in line: diff --git a/test/testfiles_for_readelf/empty-cie.o.elf b/test/testfiles_for_readelf/empty-cie.o.elf new file mode 100755 index 0000000000000000000000000000000000000000..978027331fb66938868201cf8b0a08ebe5b44e82 GIT binary patch literal 2344 zcmbVN-D^`x6hAk&ZR(oEtX2>f*08%umGxqx;1@2rt+$jYfrw#%6a#*Qm6=2VdOKJ2G*{CQhZtm7@YFtOpRhCb@Nrgou{X!69b0;l z!2;)Qa^a5CAojCGjx4d@R@G^+>^)Zb-(W#z9@U?MMf-0eas5C02G{>&H`q+jRux3AdvLY!^;hXqTlvS6~C%MtDpIJjt?IL~`n)mf-!>MVP|`g1*q z)hbTis5GBSf2rVGasY$<{reNWgNHNQ5__zal}w~|Cif(hslCXfM3NZ4 z9Rp(~ZfrpP2W*?LJ;9cuxHTgd?T&WYv1t5{NPnygdvk}tqFqP;Nbnx`Ip{2(5(?V^ zubN>zGxX*GnD`456C;I*$uqjzVnTE^h=>W@ZSd9^RUcaP-TqaZGCE{CUsv^D{nJInVdN8kw2`t31(~WG9NndS=9$4Ci6>ON)TA zPEQgwe% yVEP#@iU-@%#$T9W676C6s|mu4@TdIIw^%>_?}*W!^!2;N6aNNns>uDz_xb^|D*~PX literal 0 HcmV?d00001 -- 2.30.2