reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
//===-- ProcessElfCore.h ----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// Notes about Linux Process core dumps:
//  1) Linux core dump is stored as ELF file.
//  2) The ELF file's PT_NOTE and PT_LOAD segments describes the program's
//     address space and thread contexts.
//  3) PT_NOTE segment contains note entries which describes a thread context.
//  4) PT_LOAD segment describes a valid contiguous range of process address
//     space.
//===----------------------------------------------------------------------===//

#ifndef liblldb_ProcessElfCore_h_
#define liblldb_ProcessElfCore_h_

#include <list>
#include <vector>

#include "lldb/Target/Process.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/Utility/Status.h"

#include "Plugins/ObjectFile/ELF/ELFHeader.h"
#include "Plugins/Process/elf-core/RegisterUtilities.h"

struct ThreadData;

class ProcessElfCore : public lldb_private::Process {
public:
  // Constructors and Destructors
  static lldb::ProcessSP
  CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
                 const lldb_private::FileSpec *crash_file_path);

  static void Initialize();

  static void Terminate();

  static lldb_private::ConstString GetPluginNameStatic();

  static const char *GetPluginDescriptionStatic();

  // Constructors and Destructors
  ProcessElfCore(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
                 const lldb_private::FileSpec &core_file);

  ~ProcessElfCore() override;

  // Check if a given Process
  bool CanDebug(lldb::TargetSP target_sp,
                bool plugin_specified_by_name) override;

  // Creating a new process, or attaching to an existing one
  lldb_private::Status DoLoadCore() override;

  lldb_private::DynamicLoader *GetDynamicLoader() override;

  // PluginInterface protocol
  lldb_private::ConstString GetPluginName() override;

  uint32_t GetPluginVersion() override;

  // Process Control
  lldb_private::Status DoDestroy() override;

  void RefreshStateAfterStop() override;

  lldb_private::Status WillResume() override {
    lldb_private::Status error;
    error.SetErrorStringWithFormat(
        "error: %s does not support resuming processes",
        GetPluginName().GetCString());
    return error;
  }

  // Process Queries
  bool IsAlive() override;

  bool WarnBeforeDetach() const override { return false; }

  // Process Memory
  size_t ReadMemory(lldb::addr_t addr, void *buf, size_t size,
                    lldb_private::Status &error) override;

  size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size,
                      lldb_private::Status &error) override;

  lldb_private::Status
  GetMemoryRegionInfo(lldb::addr_t load_addr,
                      lldb_private::MemoryRegionInfo &region_info) override;

  lldb::addr_t GetImageInfoAddress() override;

  lldb_private::ArchSpec GetArchitecture();

  // Returns AUXV structure found in the core file
  lldb_private::DataExtractor GetAuxvData() override;

  bool GetProcessInfo(lldb_private::ProcessInstanceInfo &info) override;

protected:
  void Clear();

  bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
                        lldb_private::ThreadList &new_thread_list) override;

private:
  struct NT_FILE_Entry {
    lldb::addr_t start;
    lldb::addr_t end;
    lldb::addr_t file_ofs;
    lldb_private::ConstString path;
  };

  // For ProcessElfCore only
  typedef lldb_private::Range<lldb::addr_t, lldb::addr_t> FileRange;
  typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, FileRange>
      VMRangeToFileOffset;
  typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, uint32_t>
      VMRangeToPermissions;

  lldb::ModuleSP m_core_module_sp;
  lldb_private::FileSpec m_core_file;
  std::string m_dyld_plugin_name;
  DISALLOW_COPY_AND_ASSIGN(ProcessElfCore);

  // True if m_thread_contexts contains valid entries
  bool m_thread_data_valid = false;

  // Contain thread data read from NOTE segments
  std::vector<ThreadData> m_thread_data;

  // AUXV structure found from the NOTE segment
  lldb_private::DataExtractor m_auxv;

  // Address ranges found in the core
  VMRangeToFileOffset m_core_aranges;

  // Permissions for all ranges
  VMRangeToPermissions m_core_range_infos;

  // NT_FILE entries found from the NOTE segment
  std::vector<NT_FILE_Entry> m_nt_file_entries;

  // Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment
  llvm::Error ParseThreadContextsFromNoteSegment(
      const elf::ELFProgramHeader &segment_header,
      lldb_private::DataExtractor segment_data);

  // Returns number of thread contexts stored in the core file
  uint32_t GetNumThreadContexts();

  // Parse a contiguous address range of the process from LOAD segment
  lldb::addr_t
  AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader &header);

  llvm::Expected<std::vector<lldb_private::CoreNote>>
  parseSegment(const lldb_private::DataExtractor &segment);
  llvm::Error parseFreeBSDNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
  llvm::Error parseNetBSDNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
  llvm::Error parseOpenBSDNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
  llvm::Error parseLinuxNotes(llvm::ArrayRef<lldb_private::CoreNote> notes);
};

#endif // liblldb_ProcessElfCore_h_