location lists kinda working. need more docs & readelf support
diff --git a/elftools/dwarf/dwarfinfo.py b/elftools/dwarf/dwarfinfo.py
index cc2a7b9..665f4d4 100644
--- a/elftools/dwarf/dwarfinfo.py
+++ b/elftools/dwarf/dwarfinfo.py
@@ -16,6 +16,7 @@
 from .abbrevtable import AbbrevTable
 from .lineprogram import LineProgram
 from .callframe import CallFrameInfo
+from .locationlists import LocationLists
 
 
 # Describes a debug section
@@ -148,6 +149,12 @@
             base_structs=self.structs)
         return cfi.get_entries()
 
+    def location_lists(self):
+        """ Get a LocationLists object representing the .debug_loc section of
+            the DWARF data, or None if this section doesn't exist.
+        """
+        return LocationLists(self.debug_loc_sec.stream, self.structs)
+
     #------ PRIVATE ------#
 
     def _parse_CUs_iter(self):
diff --git a/elftools/dwarf/locationlists.py b/elftools/dwarf/locationlists.py
index afe12e3..2e08b0d 100644
--- a/elftools/dwarf/locationlists.py
+++ b/elftools/dwarf/locationlists.py
@@ -6,6 +6,7 @@
 # Eli Bendersky (eliben@gmail.com)
 # This code is in the public domain
 #-------------------------------------------------------------------------------
+import os
 from collections import namedtuple
 
 from ..common.utils import struct_parse
@@ -16,14 +17,32 @@
 
 
 class LocationLists(object):
+    """ A single location list is a Python list consisting of LocationEntry or
+        BaseAddressEntry objects.
+    """
     def __init__(self, stream, structs):
+        self.stream = stream
+        self.structs = structs
         self._max_addr = 2 ** (self.structs.address_size * 8) - 1
         
     def get_location_list_at_offset(self, offset):
-        pass
+        """ Get a location list at the given offset in the section.
+        """
+        self.stream.seek(offset, os.SEEK_SET)
+        return self._parse_location_list_from_stream()
 
     def iter_location_lists(self):
-        pass
+        """ Yield all location lists found in the section.
+        """
+        # Just call _parse_location_list_from_stream until the stream ends
+        self.stream.seek(0, os.SEEK_END)
+        endpos = self.stream.tell()
+
+        self.stream.seek(0, os.SEEK_SET)
+        while self.stream.tell() < endpos:
+            yield self._parse_location_list_from_stream()
+
+    #------ PRIVATE ------#
 
     def _parse_location_list_from_stream(self):
         lst = []
@@ -36,9 +55,18 @@
                 # End of list - we're done.
                 break
             elif begin_offset == self._max_addr:
-                # base
+                # Base address selection entry
+                lst.append(BaseAddressEntry(base_address=end_offset))
             else: 
-                # entry...
-        
-
+                # Location list entry
+                expr_len = struct_parse(
+                    self.structs.Dwarf_uint16(''), self.stream)
+                loc_expr = [struct_parse(self.structs.Dwarf_uint8(''),
+                                         self.stream)
+                                for i in range(expr_len)]
+                lst.append(LocationEntry(
+                    begin_offset=begin_offset,
+                    end_offset=end_offset,
+                    loc_expr=loc_expr))
+        return lst
 
diff --git a/examples/dwarf_location_lists.py b/examples/dwarf_location_lists.py
new file mode 100644
index 0000000..266bceb
--- /dev/null
+++ b/examples/dwarf_location_lists.py
@@ -0,0 +1,76 @@
+#-------------------------------------------------------------------------------
+# elftools example: dwarf_location_lists.py
+#
+# Examine DIE entries which have location list values, and decode these
+# location lists.
+#
+# Eli Bendersky (eliben@gmail.com)
+# This code is in the public domain
+#-------------------------------------------------------------------------------
+from __future__ import print_function
+import sys
+
+# If elftools is not installed, maybe we're running from the root or examples
+# dir of the source distribution
+try:
+    import elftools
+except ImportError:
+    sys.path.extend(['.', '..'])
+
+from elftools.elf.elffile import ELFFile
+
+
+def process_file(filename):
+    print('Processing file:', filename)
+    with open(filename) as f:
+        elffile = ELFFile(f)
+
+        if not elffile.has_dwarf_info():
+            print('  file has no DWARF info')
+            return
+
+        # get_dwarf_info returns a DWARFInfo context object, which is the
+        # starting point for all DWARF-based processing in pyelftools.
+        dwarfinfo = elffile.get_dwarf_info()
+
+        # The location lists are extracted by DWARFInfo from the .debug_loc
+        # section, and returned here as a LocationLists object.
+        location_lists = dwarfinfo.location_lists()
+
+        for CU in dwarfinfo.iter_CUs():
+            # DWARFInfo allows to iterate over the compile units contained in
+            # the .debug_info section. CU is a CompileUnit object, with some
+            # computed attributes (such as its offset in the section) and
+            # a header which conforms to the DWARF standard. The access to
+            # header elements is, as usual, via item-lookup.
+            print('  Found a compile unit at offset %s, length %s' % (
+                CU.cu_offset, CU['unit_length']))
+
+            # A CU provides a simple API to iterate over all the DIEs in it.
+            for DIE in CU.iter_DIEs():
+                # Go over all attributes of the DIE. Each attribute is an
+                # AttributeValue object (from elftools.dwarf.die), which we
+                # can examine.
+                for attr in DIE.attributes.itervalues():
+                    if (    attr.name == 'DW_AT_location' and
+                            attr.form in ('DW_FORM_data4', 'DW_FORM_data8')):
+                        # This is a location list. Its value is an offset into
+                        # the .debug_loc section, so we can use the location
+                        # lists object to decode it.
+                        loclist = location_lists.get_location_list_at_offset(
+                            attr.value)
+                        print('   DIE %s. attr %s.\n      %s' % (
+                            DIE.tag,
+                            attr.name,
+                            loclist))
+
+
+if __name__ == '__main__':
+    for filename in sys.argv[1:]:
+        process_file(filename)
+
+
+
+
+
+
diff --git a/z.py b/z.py
index e5f26b7..f04c4cd 100644
--- a/z.py
+++ b/z.py
@@ -16,3 +16,13 @@
 print 'elfclass', efile.elfclass
 print '===> %s sections!' % efile.num_sections() 
 print efile.header
+
+dinfo = efile.get_dwarf_info()
+from elftools.dwarf.locationlists import LocationLists
+from elftools.dwarf.descriptions import describe_DWARF_expr
+llists = LocationLists(dinfo.debug_loc_sec.stream, dinfo.structs)
+for li in  llists.get_location_list_at_offset(0):
+    print li
+    print describe_DWARF_expr(li.loc_expr, dinfo.structs)
+
+