Initial DWARF64 support for .debug_line
authorEd Maste <emaste@freebsd.org>
Wed, 23 Oct 2013 14:18:41 +0000 (14:18 +0000)
committerEd Maste <emaste@freebsd.org>
Wed, 23 Oct 2013 14:18:41 +0000 (14:18 +0000)
Some versions of the GNU MIPS toolchain generate 64-Bit DWARF (even though
it isn't really necessary).  This change adds support for the 64-Bit DWARF
format, but is not actually tested with >4GB of debug data.

Similar changes are in progress for llvm's version of DWARFDebugLine, in
review D1988.

llvm-svn: 193242

lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h

index 1da76ac..12612a0 100644 (file)
@@ -411,11 +411,22 @@ DWARFDebugLine::ParsePrologue(const DataExtractor& debug_line_data, lldb::offset
     uint32_t i;
     const char * s;
     prologue->total_length      = debug_line_data.GetU32(offset_ptr);
+    // 7.4 32-Bit and 64-Bit DWARF Formats
+    if (prologue->total_length == 0xffffffff)
+    {
+        prologue->is_64_bit     = true;
+        prologue->total_length  = debug_line_data.GetU64(offset_ptr);
+    }
+    else if (prologue->total_length >= 0xffffff00)
+    {
+        // Reserved.
+        return false;
+    }
     prologue->version           = debug_line_data.GetU16(offset_ptr);
     if (prologue->version != 2)
       return false;
 
-    prologue->prologue_length   = debug_line_data.GetU32(offset_ptr);
+    prologue->prologue_length   = debug_line_data.GetMaxU64(offset_ptr, prologue->SizeofPrologueLength());
     const lldb::offset_t end_prologue_offset = prologue->prologue_length + *offset_ptr;
     prologue->min_inst_length   = debug_line_data.GetU8(offset_ptr);
     prologue->default_is_stmt   = debug_line_data.GetU8(offset_ptr);
@@ -456,6 +467,7 @@ DWARFDebugLine::ParsePrologue(const DataExtractor& debug_line_data, lldb::offset
             break;
     }
 
+    // XXX GNU as is broken for 64-Bit DWARF
     if (*offset_ptr != end_prologue_offset)
     {
         Host::SystemLog (Host::eSystemLogWarning, 
@@ -474,13 +486,20 @@ DWARFDebugLine::ParseSupportFiles (const lldb::ModuleSP &module_sp,
                                    dw_offset_t stmt_list,
                                    FileSpecList &support_files)
 {
-    lldb::offset_t offset = stmt_list + 4;    // Skip the total length
+    lldb::offset_t offset = stmt_list;
+    // Skip the total length
+    size_t dwarf_offset_size = 4;
+    if (debug_line_data.GetU32(&offset) == 0xffffffff)
+    {
+        dwarf_offset_size = 8;
+        (void)debug_line_data.GetU64(&offset);
+    }
     const char * s;
     uint32_t version = debug_line_data.GetU16(&offset);
     if (version != 2)
       return false;
 
-    const dw_offset_t end_prologue_offset = debug_line_data.GetU32(&offset) + offset;
+    const dw_offset_t end_prologue_offset = debug_line_data.GetMaxU64(&offset, dwarf_offset_size) + offset;
     // Skip instruction length, default is stmt, line base, line range and
     // opcode base, and all opcode lengths
     offset += 4;
@@ -600,7 +619,7 @@ DWARFDebugLine::ParseStatementTable
     if (log)
         prologue->Dump (log);
 
-    const dw_offset_t end_offset = debug_line_offset + prologue->total_length + sizeof(prologue->total_length);
+    const dw_offset_t end_offset = debug_line_offset + prologue->total_length + (prologue->SizeofTotalLength());
 
     State state(prologue, log, callback, userData);
 
index cfa8654..7fa217c 100644 (file)
@@ -64,7 +64,8 @@ public:
             opcode_base(0),
             standard_opcode_lengths(),
             include_directories(),
-            file_names()
+            file_names(),
+            is_64_bit(false)
         {
         }
 
@@ -82,10 +83,13 @@ public:
         std::vector<std::string>        include_directories;
         std::vector<FileNameEntry>      file_names;
 
+        bool        is_64_bit;      // 64-bit dwarf
+        uint32_t SizeofTotalLength() const { return is_64_bit ? 12 : 4; }
+        uint32_t SizeofPrologueLength() const { return is_64_bit ? 8 : 4; }
         // Length of the prologue in bytes
-        uint32_t Length() const { return prologue_length + sizeof(total_length) + sizeof(version) + sizeof(prologue_length); }
+        uint32_t Length() const { return prologue_length + SizeofTotalLength() + sizeof(version) + SizeofPrologueLength(); }
         // Length of the line table data in bytes (not including the prologue)
-        uint32_t StatementTableLength() const { return total_length + sizeof(total_length) - Length(); }
+        uint32_t StatementTableLength() const { return total_length + SizeofPrologueLength() - Length(); }
         int32_t MaxLineIncrementForSpecialOpcode() const { return line_base + (int8_t)line_range - 1; }
         bool IsValid() const;
 //      void Append(BinaryStreamBuf& buff) const;
@@ -97,6 +101,7 @@ public:
             standard_opcode_lengths.clear();
             include_directories.clear();
             file_names.clear();
+            is_64_bit = false;
         }
         bool GetFile(uint32_t file_idx, std::string& file, std::string& dir) const;