diff --git a/dwarf-el.cabal b/dwarf-el.cabal
--- a/dwarf-el.cabal
+++ b/dwarf-el.cabal
@@ -1,9 +1,9 @@
 Name:          dwarf-el
-Version:       0.1
+Version:       0.2
 License:       BSD3
 License-file:  LICENSE
 Category:      Data
-Author:        Eyal Lotem
+Author:        Eyal Lotem, Erik Charlebois
 Copyright:     Eyal Lotem, Erik Charlebois
 Maintainer:    Eyal Lotem <eyal.lotem@gmail.com>
 Stability:     unstable
diff --git a/src/Data/Dwarf.hs b/src/Data/Dwarf.hs
--- a/src/Data/Dwarf.hs
+++ b/src/Data/Dwarf.hs
@@ -368,27 +368,31 @@
   cuContext@CUContext { cuReader = dr, cuOffset = cu, cuSections = dc }
   form
   = case form of
-    DW_FORM_addr      -> DW_ATVAL_UINT . fromIntegral <$> drGetTargetAddress dr
-    DW_FORM_block1    -> DW_ATVAL_BLOB <$> getByteStringLen getWord8
-    DW_FORM_block2    -> DW_ATVAL_BLOB <$> getByteStringLen (drGetW16 dr)
-    DW_FORM_block4    -> DW_ATVAL_BLOB <$> getByteStringLen (drGetW32 dr)
-    DW_FORM_block     -> DW_ATVAL_BLOB <$> getByteStringLen getULEB128
-    DW_FORM_data1     -> DW_ATVAL_UINT . fromIntegral <$> getWord8
-    DW_FORM_data2     -> DW_ATVAL_UINT . fromIntegral <$> drGetW16 dr
-    DW_FORM_data4     -> DW_ATVAL_UINT . fromIntegral <$> drGetW32 dr
-    DW_FORM_data8     -> DW_ATVAL_UINT . fromIntegral <$> drGetW64 dr
-    DW_FORM_udata     -> DW_ATVAL_UINT <$> getULEB128
-    DW_FORM_sdata     -> DW_ATVAL_INT <$> getSLEB128
-    DW_FORM_flag      -> DW_ATVAL_BOOL . (/= 0) <$> getWord8
-    DW_FORM_string    -> DW_ATVAL_STRING <$> getUTF8Str0
-    DW_FORM_ref1      -> DW_ATVAL_REF . inCU cu <$> getWord8
-    DW_FORM_ref2      -> DW_ATVAL_REF . inCU cu <$> drGetW16 dr
-    DW_FORM_ref4      -> DW_ATVAL_REF . inCU cu <$> drGetW32 dr
-    DW_FORM_ref8      -> DW_ATVAL_REF . inCU cu <$> drGetW64 dr
-    DW_FORM_ref_udata -> DW_ATVAL_REF . inCU cu <$> getULEB128
-    DW_FORM_ref_addr  -> DW_ATVAL_UINT <$> drGetOffset dr
-    DW_FORM_indirect  -> getForm cuContext . dw_form =<< getULEB128
-    DW_FORM_strp      -> do
+    DW_FORM_addr         -> DW_ATVAL_UINT . fromIntegral <$> drGetTargetAddress dr
+    DW_FORM_block1       -> DW_ATVAL_BLOB <$> getByteStringLen getWord8
+    DW_FORM_block2       -> DW_ATVAL_BLOB <$> getByteStringLen (drGetW16 dr)
+    DW_FORM_block4       -> DW_ATVAL_BLOB <$> getByteStringLen (drGetW32 dr)
+    DW_FORM_block        -> DW_ATVAL_BLOB <$> getByteStringLen getULEB128
+    DW_FORM_data1        -> DW_ATVAL_UINT . fromIntegral <$> getWord8
+    DW_FORM_data2        -> DW_ATVAL_UINT . fromIntegral <$> drGetW16 dr
+    DW_FORM_data4        -> DW_ATVAL_UINT . fromIntegral <$> drGetW32 dr
+    DW_FORM_data8        -> DW_ATVAL_UINT . fromIntegral <$> drGetW64 dr
+    DW_FORM_udata        -> DW_ATVAL_UINT <$> getULEB128
+    DW_FORM_sdata        -> DW_ATVAL_INT <$> getSLEB128
+    DW_FORM_flag         -> DW_ATVAL_BOOL . (/= 0) <$> getWord8
+    DW_FORM_string       -> DW_ATVAL_STRING <$> getUTF8Str0
+    DW_FORM_ref1         -> DW_ATVAL_REF . inCU cu <$> getWord8
+    DW_FORM_ref2         -> DW_ATVAL_REF . inCU cu <$> drGetW16 dr
+    DW_FORM_ref4         -> DW_ATVAL_REF . inCU cu <$> drGetW32 dr
+    DW_FORM_ref8         -> DW_ATVAL_REF . inCU cu <$> drGetW64 dr
+    DW_FORM_ref_udata    -> DW_ATVAL_REF . inCU cu <$> getULEB128
+    DW_FORM_ref_addr     -> DW_ATVAL_UINT <$> drGetOffset dr
+    DW_FORM_sec_offset   -> DW_ATVAL_UINT <$> drGetOffset dr
+    DW_FORM_exprloc      -> DW_ATVAL_BLOB <$> getByteStringLen getULEB128
+    DW_FORM_flag_present -> pure $ DW_ATVAL_BOOL True
+    DW_FORM_ref_sig8     -> DW_ATVAL_UINT . fromIntegral <$> drGetW64 dr
+    DW_FORM_indirect     -> getForm cuContext . dw_form =<< getULEB128
+    DW_FORM_strp         -> do
       offset <- fromIntegral <$> drGetOffset dr
       pure . DW_ATVAL_STRING .
         getAt getUTF8Str0 offset $ dsStrSection dc
diff --git a/src/Data/Dwarf/Form.hs b/src/Data/Dwarf/Form.hs
--- a/src/Data/Dwarf/Form.hs
+++ b/src/Data/Dwarf/Form.hs
@@ -24,6 +24,10 @@
     | DW_FORM_ref8                -- ^ reference
     | DW_FORM_ref_udata           -- ^ reference
     | DW_FORM_indirect            -- ^ (see Section 7.5.3 of DWARF3 specification)
+    | DW_FORM_sec_offset          -- ^ (Dwarf 4)
+    | DW_FORM_exprloc             -- ^ (Dwarf 4)
+    | DW_FORM_flag_present        -- ^ (Dwarf 4)
+    | DW_FORM_ref_sig8            -- ^ (Dwarf 4)
     deriving (Eq, Ord, Read, Show)
 dw_form :: Word64 -> DW_FORM
 dw_form 0x01 = DW_FORM_addr
@@ -47,4 +51,8 @@
 dw_form 0x14 = DW_FORM_ref8
 dw_form 0x15 = DW_FORM_ref_udata
 dw_form 0x16 = DW_FORM_indirect
+dw_form 0x17 = DW_FORM_sec_offset
+dw_form 0x18 = DW_FORM_exprloc
+dw_form 0x19 = DW_FORM_flag_present
+dw_form 0x20 = DW_FORM_ref_sig8
 dw_form n    = error $ "Unrecognized DW_FORM " ++ show n
diff --git a/src/Data/Dwarf/Types.hs b/src/Data/Dwarf/Types.hs
--- a/src/Data/Dwarf/Types.hs
+++ b/src/Data/Dwarf/Types.hs
@@ -87,6 +87,7 @@
     | DW_LANG_ObjC_plus_plus
     | DW_LANG_UPC
     | DW_LANG_D
+    | DW_LANG_User Int -- 0x8000..0xFFFF
     deriving (Eq, Ord, Read, Show)
 dw_lang :: Word64 -> DW_LANG
 dw_lang 0x0001 = DW_LANG_C89
@@ -108,7 +109,11 @@
 dw_lang 0x0011 = DW_LANG_ObjC_plus_plus
 dw_lang 0x0012 = DW_LANG_UPC
 dw_lang 0x0013 = DW_LANG_D
-dw_lang n = error $ "Unrecognized DW_LANG " ++ show n
+dw_lang n
+  | 0x8000 <= n && n <= 0xffff =
+    DW_LANG_User $ fromIntegral n
+  | otherwise =
+    error $ "Unrecognized DW_LANG " ++ show n
 
 data DW_ID
     = DW_ID_case_sensitive
