[Lldb-commits] [lldb] r350511 - ObjectFileBreakpad: Implement sections

Pavel Labath via lldb-commits lldb-commits at lists.llvm.org
Mon Jan 7 03:14:08 PST 2019


Author: labath
Date: Mon Jan  7 03:14:08 2019
New Revision: 350511

URL: http://llvm.org/viewvc/llvm-project?rev=350511&view=rev
Log:
ObjectFileBreakpad: Implement sections

Summary:
This patch allows ObjectFileBreakpad to parse the contents of Breakpad
files into sections. This sounds slightly odd at first, but in essence
its not too different from how other object files handle things. For
example in elf files, the symtab section consists of a number of
"records", where each record represents a single symbol. The same is
true for breakpad's PUBLIC section, except in this case, the records will be
textual instead of binary.

To keep sections contiguous, I create a new section every time record
type changes. Normally, the breakpad processor will group all records of
the same type in one block, but the format allows them to be intermixed,
so in general, the "object file" may contain multiple sections with the
same record type.

Reviewers: clayborg, zturner, lemo, markmentovai, amccarth

Subscribers: lldb-commits

Differential Revision: https://reviews.llvm.org/D55434

Added:
    lldb/trunk/lit/Modules/Breakpad/Inputs/discontiguous-sections.syms
    lldb/trunk/lit/Modules/Breakpad/Inputs/sections-trailing-func.syms
    lldb/trunk/lit/Modules/Breakpad/Inputs/sections.syms
    lldb/trunk/lit/Modules/Breakpad/discontiguous-sections.test
    lldb/trunk/lit/Modules/Breakpad/sections-trailing-func.test
    lldb/trunk/lit/Modules/Breakpad/sections.test
Modified:
    lldb/trunk/include/lldb/Utility/DataExtractor.h
    lldb/trunk/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp

Modified: lldb/trunk/include/lldb/Utility/DataExtractor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Utility/DataExtractor.h?rev=350511&r1=350510&r2=350511&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Utility/DataExtractor.h (original)
+++ lldb/trunk/include/lldb/Utility/DataExtractor.h Mon Jan  7 03:14:08 2019
@@ -14,6 +14,7 @@
 #include "lldb/lldb-enumerations.h"
 #include "lldb/lldb-forward.h"
 #include "lldb/lldb-types.h"
+#include "llvm/ADT/ArrayRef.h"
 
 #include <cassert>
 #include <stdint.h>
@@ -1094,6 +1095,10 @@ public:
 
   void Checksum(llvm::SmallVectorImpl<uint8_t> &dest, uint64_t max_data = 0);
 
+  llvm::ArrayRef<uint8_t> GetData() const {
+    return {GetDataStart(), GetByteSize()};
+  }
+
 protected:
   //------------------------------------------------------------------
   // Member variables

Added: lldb/trunk/lit/Modules/Breakpad/Inputs/discontiguous-sections.syms
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Modules/Breakpad/Inputs/discontiguous-sections.syms?rev=350511&view=auto
==============================================================================
--- lldb/trunk/lit/Modules/Breakpad/Inputs/discontiguous-sections.syms (added)
+++ lldb/trunk/lit/Modules/Breakpad/Inputs/discontiguous-sections.syms Mon Jan  7 03:14:08 2019
@@ -0,0 +1,5 @@
+MODULE Linux x86_64 0000000024B5D199F0F766FFFFFF5DC30 linux.out
+INFO CODE_ID 00000000B52499D1F0F766FFFFFF5DC3
+FILE 0 /tmp/a.c
+PUBLIC 1010 0 _start
+FILE 1 /tmp/b.c

Added: lldb/trunk/lit/Modules/Breakpad/Inputs/sections-trailing-func.syms
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Modules/Breakpad/Inputs/sections-trailing-func.syms?rev=350511&view=auto
==============================================================================
--- lldb/trunk/lit/Modules/Breakpad/Inputs/sections-trailing-func.syms (added)
+++ lldb/trunk/lit/Modules/Breakpad/Inputs/sections-trailing-func.syms Mon Jan  7 03:14:08 2019
@@ -0,0 +1,8 @@
+MODULE Linux x86_64 0000000024B5D199F0F766FFFFFF5DC30 linux.out
+INFO CODE_ID 00000000B52499D1F0F766FFFFFF5DC3
+FILE 0 /tmp/a.c
+FUNC 1010 10 0 _start
+1010 4 4 0
+1014 5 5 0
+1019 5 6 0
+101e 2 7 0

Added: lldb/trunk/lit/Modules/Breakpad/Inputs/sections.syms
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Modules/Breakpad/Inputs/sections.syms?rev=350511&view=auto
==============================================================================
--- lldb/trunk/lit/Modules/Breakpad/Inputs/sections.syms (added)
+++ lldb/trunk/lit/Modules/Breakpad/Inputs/sections.syms Mon Jan  7 03:14:08 2019
@@ -0,0 +1,12 @@
+MODULE Linux x86_64 0000000024B5D199F0F766FFFFFF5DC30 linux.out
+INFO CODE_ID 00000000B52499D1F0F766FFFFFF5DC3
+FILE 0 /tmp/a.c
+FUNC 1010 10 0 _start
+1010 4 4 0
+1014 5 5 0
+1019 5 6 0
+101e 2 7 0
+PUBLIC 1010 0 _start
+STACK CFI INIT 1010 10 .cfa: $rsp 8 + .ra: .cfa -8 + ^
+STACK CFI 1011 $rbp: .cfa -16 + ^ .cfa: $rsp 16 +
+STACK CFI 1014 .cfa: $rbp 16 +

Added: lldb/trunk/lit/Modules/Breakpad/discontiguous-sections.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Modules/Breakpad/discontiguous-sections.test?rev=350511&view=auto
==============================================================================
--- lldb/trunk/lit/Modules/Breakpad/discontiguous-sections.test (added)
+++ lldb/trunk/lit/Modules/Breakpad/discontiguous-sections.test Mon Jan  7 03:14:08 2019
@@ -0,0 +1,27 @@
+# Test handling discontiguous sections.
+RUN: lldb-test object-file %p/Inputs/discontiguous-sections.syms -contents | FileCheck %s
+
+CHECK: Showing 5 sections
+
+CHECK:        ID: 0x1
+CHECK-NEXT:   Name: MODULE
+
+CHECK:        ID: 0x2
+CHECK-NEXT:   Name: INFO
+
+CHECK:        ID: 0x3
+CHECK-NEXT:   Name: FILE
+CHECK:        File size: 16
+CHECK-NEXT:   Data:  (
+CHECK-NEXT:       0000: 46494C45 2030202F 746D702F 612E630A                                      |FILE 0 /tmp/a.c.|
+CHECK-NEXT:   )
+
+CHECK:        ID: 0x4
+CHECK-NEXT:   Name: PUBLIC
+
+CHECK:        ID: 0x5
+CHECK-NEXT:   Name: FILE
+CHECK:        File size: 16
+CHECK-NEXT:   Data:  (
+CHECK-NEXT:       0000: 46494C45 2031202F 746D702F 622E630A                                      |FILE 1 /tmp/b.c.|
+CHECK-NEXT:   )

Added: lldb/trunk/lit/Modules/Breakpad/sections-trailing-func.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Modules/Breakpad/sections-trailing-func.test?rev=350511&view=auto
==============================================================================
--- lldb/trunk/lit/Modules/Breakpad/sections-trailing-func.test (added)
+++ lldb/trunk/lit/Modules/Breakpad/sections-trailing-func.test Mon Jan  7 03:14:08 2019
@@ -0,0 +1,15 @@
+# Test handling of a (valid) breakpad file, which ends with a line without a
+# recognised keyword.
+
+RUN: lldb-test object-file %p/Inputs/sections-trailing-func.syms -contents | FileCheck %s
+
+CHECK: Showing 4 sections
+
+CHECK:       ID: 0x4
+CHECK-NEXT:  Name: FUNC
+CHECK:       File size: 66
+CHECK-NEXT:  Data:  (
+CHECK-NEXT:      0000: 46554E43 20313031 30203130 2030205F 73746172 740A3130 31302034 20342030  |FUNC 1010 10 0 _start.1010 4 4 0|
+CHECK-NEXT:      0020: 0A313031 34203520 3520300A 31303139 20352036 20300A31 30316520 32203720  |.1014 5 5 0.1019 5 6 0.101e 2 7 |
+CHECK-NEXT:      0040: 300A                                                                     |0.|
+CHECK-NEXT:  )

Added: lldb/trunk/lit/Modules/Breakpad/sections.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/Modules/Breakpad/sections.test?rev=350511&view=auto
==============================================================================
--- lldb/trunk/lit/Modules/Breakpad/sections.test (added)
+++ lldb/trunk/lit/Modules/Breakpad/sections.test Mon Jan  7 03:14:08 2019
@@ -0,0 +1,89 @@
+RUN: lldb-test object-file %p/Inputs/sections.syms -contents | FileCheck %s
+
+CHECK: Showing 6 sections
+
+CHECK:        Index: 0
+CHECK-NEXT:   ID: 0x1
+CHECK-NEXT:   Name: MODULE
+CHECK-NEXT:   Type: regular
+CHECK-NEXT:   Permissions: ---
+CHECK-NEXT:   Thread specific: no
+CHECK-NEXT:   VM address: 0
+CHECK-NEXT:   VM size: 0
+CHECK-NEXT:   File size: 64
+CHECK-NEXT:   Data:  (
+CHECK-NEXT:       0000: 4D4F4455 4C45204C 696E7578 20783836 5F363420 30303030 30303030 32344235  |MODULE Linux x86_64 0000000024B5|
+CHECK-NEXT:       0020: 44313939 46304637 36364646 46464646 35444333 30206C69 6E75782E 6F75740A  |D199F0F766FFFFFF5DC30 linux.out.|
+CHECK-NEXT:   )
+
+CHECK:        Index: 1
+CHECK-NEXT:   ID: 0x2
+CHECK-NEXT:   Name: INFO
+CHECK-NEXT:   Type: regular
+CHECK-NEXT:   Permissions: ---
+CHECK-NEXT:   Thread specific: no
+CHECK-NEXT:   VM address: 0
+CHECK-NEXT:   VM size: 0
+CHECK-NEXT:   File size: 46
+CHECK-NEXT:   Data:  (
+CHECK-NEXT:       0000: 494E464F 20434F44 455F4944 20303030 30303030 30423532 34393944 31463046  |INFO CODE_ID 00000000B52499D1F0F|
+CHECK-NEXT:       0020: 37363646 46464646 46354443 330A                                          |766FFFFFF5DC3.|
+CHECK-NEXT:   )
+
+CHECK:        Index: 2
+CHECK-NEXT:   ID: 0x3
+CHECK-NEXT:   Name: FILE
+CHECK-NEXT:   Type: regular
+CHECK-NEXT:   Permissions: ---
+CHECK-NEXT:   Thread specific: no
+CHECK-NEXT:   VM address: 0
+CHECK-NEXT:   VM size: 0
+CHECK-NEXT:   File size: 16
+CHECK-NEXT:   Data:  (
+CHECK-NEXT:       0000: 46494C45 2030202F 746D702F 612E630A                                      |FILE 0 /tmp/a.c.|
+CHECK-NEXT:   )
+
+CHECK:        Index: 3
+CHECK-NEXT:   ID: 0x4
+CHECK-NEXT:   Name: FUNC
+CHECK-NEXT:   Type: regular
+CHECK-NEXT:   Permissions: ---
+CHECK-NEXT:   Thread specific: no
+CHECK-NEXT:   VM address: 0
+CHECK-NEXT:   VM size: 0
+CHECK-NEXT:   File size: 66
+CHECK-NEXT:   Data:  (
+CHECK-NEXT:       0000: 46554E43 20313031 30203130 2030205F 73746172 740A3130 31302034 20342030  |FUNC 1010 10 0 _start.1010 4 4 0|
+CHECK-NEXT:       0020: 0A313031 34203520 3520300A 31303139 20352036 20300A31 30316520 32203720  |.1014 5 5 0.1019 5 6 0.101e 2 7 |
+CHECK-NEXT:       0040: 300A                                                                     |0.|
+CHECK-NEXT:   )
+
+CHECK:        Index: 4
+CHECK-NEXT:   ID: 0x5
+CHECK-NEXT:   Name: PUBLIC
+CHECK-NEXT:   Type: regular
+CHECK-NEXT:   Permissions: ---
+CHECK-NEXT:   Thread specific: no
+CHECK-NEXT:   VM address: 0
+CHECK-NEXT:   VM size: 0
+CHECK-NEXT:   File size: 21
+CHECK-NEXT:   Data:  (
+CHECK-NEXT:       0000: 5055424C 49432031 30313020 30205F73 74617274 0A                          |PUBLIC 1010 0 _start.|
+CHECK-NEXT:   )
+
+CHECK:        Index: 5
+CHECK-NEXT:   ID: 0x6
+CHECK-NEXT:   Name: STACK
+CHECK-NEXT:   Type: regular
+CHECK-NEXT:   Permissions: ---
+CHECK-NEXT:   Thread specific: no
+CHECK-NEXT:   VM address: 0
+CHECK-NEXT:   VM size: 0
+CHECK-NEXT:   File size: 136
+CHECK-NEXT:   Data:  (
+CHECK-NEXT:       0000: 53544143 4B204346 4920494E 49542031 30313020 3130202E 6366613A 20247273  |STACK CFI INIT 1010 10 .cfa: $rs|
+CHECK-NEXT:       0020: 70203820 2B202E72 613A202E 63666120 2D38202B 205E0A53 5441434B 20434649  |p 8 + .ra: .cfa -8 + ^.STACK CFI|
+CHECK-NEXT:       0040: 20313031 31202472 62703A20 2E636661 202D3136 202B205E 202E6366 613A2024  | 1011 $rbp: .cfa -16 + ^ .cfa: $|
+CHECK-NEXT:       0060: 72737020 3136202B 0A535441 434B2043 46492031 30313420 2E636661 3A202472  |rsp 16 +.STACK CFI 1014 .cfa: $r|
+CHECK-NEXT:       0080: 62702031 36202B0A                                                        |bp 16 +.|
+CHECK-NEXT:   )

Modified: lldb/trunk/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp?rev=350511&r1=350510&r2=350511&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp Mon Jan  7 03:14:08 2019
@@ -10,6 +10,7 @@
 #include "Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h"
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Section.h"
 #include "lldb/Utility/DataBuffer.h"
 #include "llvm/ADT/StringExtras.h"
 
@@ -23,8 +24,41 @@ struct Header {
   UUID uuid;
   static llvm::Optional<Header> parse(llvm::StringRef text);
 };
+
+enum class Token { Unknown, Module, Info, File, Func, Public, Stack };
 } // namespace
 
+static Token toToken(llvm::StringRef str) {
+  return llvm::StringSwitch<Token>(str)
+      .Case("MODULE", Token::Module)
+      .Case("INFO", Token::Info)
+      .Case("FILE", Token::File)
+      .Case("FUNC", Token::Func)
+      .Case("PUBLIC", Token::Public)
+      .Case("STACK", Token::Stack)
+      .Default(Token::Unknown);
+}
+
+static llvm::StringRef toString(Token t) {
+  switch (t) {
+  case Token::Unknown:
+    return "";
+  case Token::Module:
+    return "MODULE";
+  case Token::Info:
+    return "INFO";
+  case Token::File:
+    return "FILE";
+  case Token::Func:
+    return "FUNC";
+  case Token::Public:
+    return "PUBLIC";
+  case Token::Stack:
+    return "STACK";
+  }
+  llvm_unreachable("Unknown token!");
+}
+
 static llvm::Triple::OSType toOS(llvm::StringRef str) {
   using llvm::Triple;
   return llvm::StringSwitch<Triple::OSType>(str)
@@ -103,7 +137,7 @@ llvm::Optional<Header> Header::parse(llv
   llvm::StringRef token, line;
   std::tie(line, text) = text.split('\n');
   std::tie(token, line) = getToken(line);
-  if (token != "MODULE")
+  if (toToken(token) != Token::Module)
     return llvm::None;
 
   std::tie(token, line) = getToken(line);
@@ -236,5 +270,46 @@ bool ObjectFileBreakpad::GetUUID(UUID *u
 }
 
 void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) {
-  // TODO
+  if (m_sections_ap)
+    return;
+  m_sections_ap = llvm::make_unique<SectionList>();
+
+  Token current_section = Token::Unknown;
+  offset_t section_start;
+  llvm::StringRef text = toStringRef(m_data.GetData());
+  uint32_t next_section_id = 1;
+  auto maybe_add_section = [&](const uint8_t *end_ptr) {
+    if (current_section == Token::Unknown)
+      return; // We have been called before parsing the first line.
+
+    offset_t end_offset = end_ptr - m_data.GetDataStart();
+    auto section_sp = std::make_shared<Section>(
+        GetModule(), this, next_section_id++,
+        ConstString(toString(current_section)), eSectionTypeOther,
+        /*file_vm_addr*/ 0, /*vm_size*/ 0, section_start,
+        end_offset - section_start, /*log2align*/ 0, /*flags*/ 0);
+    m_sections_ap->AddSection(section_sp);
+    unified_section_list.AddSection(section_sp);
+  };
+  while (!text.empty()) {
+    llvm::StringRef line;
+    std::tie(line, text) = text.split('\n');
+
+    Token token = toToken(getToken(line).first);
+    if (token == Token::Unknown) {
+      // We assume this is a line record, which logically belongs to the Func
+      // section. Errors will be handled when parsing the Func section.
+      token = Token::Func;
+    }
+    if (token == current_section)
+      continue;
+
+    // Changing sections, finish off the previous one, if there was any.
+    maybe_add_section(line.bytes_begin());
+    // And start a new one.
+    current_section = token;
+    section_start = line.bytes_begin() - m_data.GetDataStart();
+  }
+  // Finally, add the last section.
+  maybe_add_section(m_data.GetDataEnd());
 }




More information about the lldb-commits mailing list