From: emersion Date: Sat, 20 Jan 2018 17:18:09 +0000 (+0100) Subject: Do not crash if CIE doesn't define CFA (#177) X-Git-Tag: v0.25~15 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4811e84d7c12540f651e90aaac521feef1edb169;p=pyelftools.git Do not crash if CIE doesn't define CFA (#177) --- 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 0000000..9780273 Binary files /dev/null and b/test/testfiles_for_readelf/empty-cie.o.elf differ