started implementing dumping --debug-dump=frames
diff --git a/elftools/dwarf/callframe.py b/elftools/dwarf/callframe.py
index cfb2d07..2d51317 100644
--- a/elftools/dwarf/callframe.py
+++ b/elftools/dwarf/callframe.py
@@ -29,10 +29,12 @@
 class CIE(object):
     """ CIE - Common Information Entry.
         Contains a header and a list of instructions (CallFrameInstruction).
+        offset: the offset of this entry from the beginning of the section
     """
-    def __init__(self, header, instructions):
+    def __init__(self, header, instructions, offset):
         self.header = header
         self.instructions = instructions
+        self.offset = offset
 
     def __getitem__(self, name):
         """ Implement dict-like access to header entries
@@ -44,10 +46,12 @@
     """ FDE - Frame Description Entry.
         Contains a header, a list of instructions (CallFrameInstruction) and a
         reference to the CIE object associated with this FDE.
+        offset: the offset of this entry from the beginning of the section
     """
-    def __init__(self, header, instructions, cie):
+    def __init__(self, header, instructions, offset, cie):
         self.header = header
         self.instructions = instructions
+        self.offset = offset
         self.cie = cie
 
     def __getitem__(self, name):
@@ -148,12 +152,13 @@
 
         if is_CIE:
             self._entry_cache[offset] = CIE(
-                header=header, instructions=instructions)
+                header=header, instructions=instructions, offset=offset)
         else: # FDE
             with preserve_stream_pos(self.stream):
                 cie = self._parse_entry_at(header['CIE_pointer'])
             self._entry_cache[offset] = FDE(
-                header=header, instructions=instructions, cie=cie)
+                header=header, instructions=instructions, offset=offset,
+                cie=cie)
         return self._entry_cache[offset]
 
     def _parse_instructions(self, structs, offset, end_offset):
diff --git a/elftools/dwarf/constants.py b/elftools/dwarf/constants.py
index 745bd6d..8bf38e8 100644
--- a/elftools/dwarf/constants.py
+++ b/elftools/dwarf/constants.py
@@ -139,6 +139,14 @@
 

 # Call frame instructions

 #

+# Note that the first 3 instructions have the so-called "primary opcode"

+# (as described in DWARFv3 7.23), so only their highest 2 bits take part

+# in the opcode decoding. They are kept as constants with the low bits masked

+# out, and the callframe module knows how to handle this.

+# The other instructions use an "extended opcode" encoded just in the low 6

+# bits, with the high 2 bits, so these constants are exactly as they would

+# appear in an actual file.

+#

 DW_CFA_advance_loc = 0b01000000

 DW_CFA_offset = 0b10000000

 DW_CFA_restore = 0b11000000

diff --git a/elftools/dwarf/descriptions.py b/elftools/dwarf/descriptions.py
index f7afcd8..b400310 100644
--- a/elftools/dwarf/descriptions.py
+++ b/elftools/dwarf/descriptions.py
@@ -37,6 +37,15 @@
     return str(val_description) + '\t' + extra_info    
 
 
+def describe_CFI_instruction(instruction, entry, context):
+    # ZZZ: just get a list of instructions and keep the context internally!!
+    """ Given a CFI instruction, return its textual description. Also needs the
+        entry that contains this instruction.
+        context is a
+    """
+    return ''
+
+
 def describe_reg_name(regnum, machine_arch):
     """ Provide a textual description for a register name, given its serial
         number. The number is expected to be valid.
diff --git a/scripts/readelf.py b/scripts/readelf.py
index 335d5ee..01c4d1f 100755
--- a/scripts/readelf.py
+++ b/scripts/readelf.py
@@ -36,9 +36,10 @@
     )
 from elftools.dwarf.dwarfinfo import DWARFInfo
 from elftools.dwarf.descriptions import (
-    describe_attr_value, set_global_machine_arch)
+    describe_attr_value, set_global_machine_arch, describe_CFI_instruction)
 from elftools.dwarf.constants import (
     DW_LNS_copy, DW_LNS_set_file, DW_LNE_define_file)
+from elftools.dwarf.callframe import CIE, FDE
 
 
 class ReadElf(object):
@@ -432,6 +433,8 @@
             self._dump_debug_info()
         elif dump_what == 'decodedline':
             self._dump_debug_line_programs()
+        elif dump_what == 'frames':
+            self._dump_debug_frames()
         else:
             self._emitline('debug dump not yet supported for "%s"' % dump_what)
 
@@ -598,6 +601,34 @@
                     # Another readelf oddity...
                     self._emitline()
 
+    def _dump_debug_frames(self):
+        """ Dump the raw frame information from .debug_frame
+        """
+        self._emitline('Contents of the .debug_frame section:')
+
+        for entry in self._dwarfinfo.CFI_entries():
+            if isinstance(entry, CIE):
+                self._emitline('\n%08x %08x %08x CIE' % (
+                    entry.offset, entry['length'], entry['CIE_id']))
+                self._emitline('  Version:               %d' % entry['version'])
+                self._emitline('  Augmentation:          "%s"' % entry['augmentation'])
+                self._emitline('  Code alignment factor: %u' % entry['code_alignment_factor'])
+                self._emitline('  Data alignment factor: %d' % entry['data_alignment_factor'])
+                self._emitline('  Return address column: %d' % entry['return_address_register'])
+            else: # FDE
+                self._emitline('\n%08x %08x %08x FDE cie=%08x pc=%08x..%08x' % (
+                    entry.offset,
+                    entry['length'],
+                    entry['CIE_pointer'],
+                    entry.cie.offset,
+                    entry['initial_location'],
+                    entry['initial_location'] + entry['address_range']))
+
+            if len(entry.instructions) > 0:
+                self._emitline('')
+                for instr in entry.instructions:
+                    self._emitline(describe_CFI_instruction(instr, entry))
+
     def _emit(self, s=''):
         """ Emit an object to output
         """