diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:51:52 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:51:52 +0000 | 
| commit | 5f29bb8a675e8f96452b632e7129113f7dec850e (patch) | |
| tree | 3d3f2a0d3ad10872a4dcaba8ec8d1d20c87ab147 /source/Plugins/ObjectFile | |
| parent | 88c643b6fec27eec436c8d138fee6346e92337d6 (diff) | |
Notes
Diffstat (limited to 'source/Plugins/ObjectFile')
| -rw-r--r-- | source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp | 411 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h | 163 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp | 197 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h | 16 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/ELF/ELFHeader.cpp | 47 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/ELF/ELFHeader.h | 99 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 410 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/ELF/ObjectFileELF.h | 36 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp | 61 | ||||
| -rw-r--r-- | source/Plugins/ObjectFile/JIT/ObjectFileJIT.h | 17 | 
10 files changed, 863 insertions, 594 deletions
diff --git a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp new file mode 100644 index 0000000000000..d489eaf11115a --- /dev/null +++ b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp @@ -0,0 +1,411 @@ +//===-- BreakpadRecords.cpp ----------------------------------- -*- 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 +// +//===----------------------------------------------------------------------===// + +#include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/FormatVariadic.h" + +using namespace lldb_private; +using namespace lldb_private::breakpad; + +namespace { +enum class Token { Unknown, Module, Info, CodeID, File, Func, Public, Stack, CFI, Init }; +} + +template<typename T> +static T stringTo(llvm::StringRef Str); + +template <> Token stringTo<Token>(llvm::StringRef Str) { +  return llvm::StringSwitch<Token>(Str) +      .Case("MODULE", Token::Module) +      .Case("INFO", Token::Info) +      .Case("CODE_ID", Token::CodeID) +      .Case("FILE", Token::File) +      .Case("FUNC", Token::Func) +      .Case("PUBLIC", Token::Public) +      .Case("STACK", Token::Stack) +      .Case("CFI", Token::CFI) +      .Case("INIT", Token::Init) +      .Default(Token::Unknown); +} + +template <> +llvm::Triple::OSType stringTo<llvm::Triple::OSType>(llvm::StringRef Str) { +  using llvm::Triple; +  return llvm::StringSwitch<Triple::OSType>(Str) +      .Case("Linux", Triple::Linux) +      .Case("mac", Triple::MacOSX) +      .Case("windows", Triple::Win32) +      .Default(Triple::UnknownOS); +} + +template <> +llvm::Triple::ArchType stringTo<llvm::Triple::ArchType>(llvm::StringRef Str) { +  using llvm::Triple; +  return llvm::StringSwitch<Triple::ArchType>(Str) +      .Case("arm", Triple::arm) +      .Cases("arm64", "arm64e", Triple::aarch64) +      .Case("mips", Triple::mips) +      .Case("ppc", Triple::ppc) +      .Case("ppc64", Triple::ppc64) +      .Case("s390", Triple::systemz) +      .Case("sparc", Triple::sparc) +      .Case("sparcv9", Triple::sparcv9) +      .Case("x86", Triple::x86) +      .Case("x86_64", Triple::x86_64) +      .Default(Triple::UnknownArch); +} + +template<typename T> +static T consume(llvm::StringRef &Str) { +  llvm::StringRef Token; +  std::tie(Token, Str) = getToken(Str); +  return stringTo<T>(Token); +} + +/// Return the number of hex digits needed to encode an (POD) object of a given +/// type. +template <typename T> static constexpr size_t hex_digits() { +  return 2 * sizeof(T); +} + +static UUID parseModuleId(llvm::Triple::OSType os, llvm::StringRef str) { +  struct data_t { +    using uuid_t = uint8_t[16]; +    uuid_t uuid; +    llvm::support::ubig32_t age; +  } data; +  static_assert(sizeof(data) == 20, ""); +  // The textual module id encoding should be between 33 and 40 bytes long, +  // depending on the size of the age field, which is of variable length. +  // The first three chunks of the id are encoded in big endian, so we need to +  // byte-swap those. +  if (str.size() <= hex_digits<data_t::uuid_t>() || +      str.size() > hex_digits<data_t>()) +    return UUID(); +  if (!all_of(str, llvm::isHexDigit)) +    return UUID(); + +  llvm::StringRef uuid_str = str.take_front(hex_digits<data_t::uuid_t>()); +  llvm::StringRef age_str = str.drop_front(hex_digits<data_t::uuid_t>()); + +  llvm::copy(fromHex(uuid_str), data.uuid); +  uint32_t age; +  bool success = to_integer(age_str, age, 16); +  assert(success); +  (void)success; +  data.age = age; + +  // On non-windows, the age field should always be zero, so we don't include to +  // match the native uuid format of these platforms. +  return UUID::fromData(&data, os == llvm::Triple::Win32 ? sizeof(data) +                                                         : sizeof(data.uuid)); +} + +llvm::Optional<Record::Kind> Record::classify(llvm::StringRef Line) { +  Token Tok = consume<Token>(Line); +  switch (Tok) { +  case Token::Module: +    return Record::Module; +  case Token::Info: +    return Record::Info; +  case Token::File: +    return Record::File; +  case Token::Func: +    return Record::Func; +  case Token::Public: +    return Record::Public; +  case Token::Stack: +    Tok = consume<Token>(Line); +    switch (Tok) { +    case Token::CFI: +      return Record::StackCFI; +    default: +      return llvm::None; +    } + +  case Token::Unknown: +    // Optimistically assume that any unrecognised token means this is a line +    // record, those don't have a special keyword and start directly with a +    // hex number. CODE_ID should never be at the start of a line, but if it +    // is, it can be treated the same way as a garbled line record. +    return Record::Line; + +  case Token::CodeID: +  case Token::CFI: +  case Token::Init: +    // These should never appear at the start of a valid record. +    return llvm::None; +  } +  llvm_unreachable("Fully covered switch above!"); +} + +llvm::Optional<ModuleRecord> ModuleRecord::parse(llvm::StringRef Line) { +  // MODULE Linux x86_64 E5894855C35DCCCCCCCCCCCCCCCCCCCC0 a.out +  if (consume<Token>(Line) != Token::Module) +    return llvm::None; + +  llvm::Triple::OSType OS = consume<llvm::Triple::OSType>(Line); +  if (OS == llvm::Triple::UnknownOS) +    return llvm::None; + +  llvm::Triple::ArchType Arch = consume<llvm::Triple::ArchType>(Line); +  if (Arch == llvm::Triple::UnknownArch) +    return llvm::None; + +  llvm::StringRef Str; +  std::tie(Str, Line) = getToken(Line); +  UUID ID = parseModuleId(OS, Str); +  if (!ID) +    return llvm::None; + +  return ModuleRecord(OS, Arch, std::move(ID)); +} + +llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, +                                        const ModuleRecord &R) { +  return OS << "MODULE " << llvm::Triple::getOSTypeName(R.OS) << " " +            << llvm::Triple::getArchTypeName(R.Arch) << " " +            << R.ID.GetAsString(); +} + +llvm::Optional<InfoRecord> InfoRecord::parse(llvm::StringRef Line) { +  // INFO CODE_ID 554889E55DC3CCCCCCCCCCCCCCCCCCCC [a.exe] +  if (consume<Token>(Line) != Token::Info) +    return llvm::None; + +  if (consume<Token>(Line) != Token::CodeID) +    return llvm::None; + +  llvm::StringRef Str; +  std::tie(Str, Line) = getToken(Line); +  // If we don't have any text following the code ID (e.g. on linux), we should +  // use this as the UUID. Otherwise, we should revert back to the module ID. +  UUID ID; +  if (Line.trim().empty()) { +    if (Str.empty() || ID.SetFromStringRef(Str, Str.size() / 2) != Str.size()) +      return llvm::None; +  } +  return InfoRecord(std::move(ID)); +} + +llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, +                                        const InfoRecord &R) { +  return OS << "INFO CODE_ID " << R.ID.GetAsString(); +} + +llvm::Optional<FileRecord> FileRecord::parse(llvm::StringRef Line) { +  // FILE number name +  if (consume<Token>(Line) != Token::File) +    return llvm::None; + +  llvm::StringRef Str; +  size_t Number; +  std::tie(Str, Line) = getToken(Line); +  if (!to_integer(Str, Number)) +    return llvm::None; + +  llvm::StringRef Name = Line.trim(); +  if (Name.empty()) +    return llvm::None; + +  return FileRecord(Number, Name); +} + +llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, +                                        const FileRecord &R) { +  return OS << "FILE " << R.Number << " " << R.Name; +} + +static bool parsePublicOrFunc(llvm::StringRef Line, bool &Multiple, +                              lldb::addr_t &Address, lldb::addr_t *Size, +                              lldb::addr_t &ParamSize, llvm::StringRef &Name) { +  // PUBLIC [m] address param_size name +  // or +  // FUNC [m] address size param_size name + +  Token Tok = Size ? Token::Func : Token::Public; + +  if (consume<Token>(Line) != Tok) +    return false; + +  llvm::StringRef Str; +  std::tie(Str, Line) = getToken(Line); +  Multiple = Str == "m"; + +  if (Multiple) +    std::tie(Str, Line) = getToken(Line); +  if (!to_integer(Str, Address, 16)) +    return false; + +  if (Tok == Token::Func) { +    std::tie(Str, Line) = getToken(Line); +    if (!to_integer(Str, *Size, 16)) +      return false; +  } + +  std::tie(Str, Line) = getToken(Line); +  if (!to_integer(Str, ParamSize, 16)) +    return false; + +  Name = Line.trim(); +  if (Name.empty()) +    return false; + +  return true; +} + +llvm::Optional<FuncRecord> FuncRecord::parse(llvm::StringRef Line) { +  bool Multiple; +  lldb::addr_t Address, Size, ParamSize; +  llvm::StringRef Name; + +  if (parsePublicOrFunc(Line, Multiple, Address, &Size, ParamSize, Name)) +    return FuncRecord(Multiple, Address, Size, ParamSize, Name); + +  return llvm::None; +} + +bool breakpad::operator==(const FuncRecord &L, const FuncRecord &R) { +  return L.Multiple == R.Multiple && L.Address == R.Address && +         L.Size == R.Size && L.ParamSize == R.ParamSize && L.Name == R.Name; +} +llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, +                                        const FuncRecord &R) { +  return OS << llvm::formatv("FUNC {0}{1:x-} {2:x-} {3:x-} {4}", +                             R.Multiple ? "m " : "", R.Address, R.Size, +                             R.ParamSize, R.Name); +} + +llvm::Optional<LineRecord> LineRecord::parse(llvm::StringRef Line) { +  lldb::addr_t Address; +  llvm::StringRef Str; +  std::tie(Str, Line) = getToken(Line); +  if (!to_integer(Str, Address, 16)) +    return llvm::None; + +  lldb::addr_t Size; +  std::tie(Str, Line) = getToken(Line); +  if (!to_integer(Str, Size, 16)) +    return llvm::None; + +  uint32_t LineNum; +  std::tie(Str, Line) = getToken(Line); +  if (!to_integer(Str, LineNum)) +    return llvm::None; + +  size_t FileNum; +  std::tie(Str, Line) = getToken(Line); +  if (!to_integer(Str, FileNum)) +    return llvm::None; + +  return LineRecord(Address, Size, LineNum, FileNum); +} + +bool breakpad::operator==(const LineRecord &L, const LineRecord &R) { +  return L.Address == R.Address && L.Size == R.Size && L.LineNum == R.LineNum && +         L.FileNum == R.FileNum; +} +llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, +                                        const LineRecord &R) { +  return OS << llvm::formatv("{0:x-} {1:x-} {2} {3}", R.Address, R.Size, +                             R.LineNum, R.FileNum); +} + +llvm::Optional<PublicRecord> PublicRecord::parse(llvm::StringRef Line) { +  bool Multiple; +  lldb::addr_t Address, ParamSize; +  llvm::StringRef Name; + +  if (parsePublicOrFunc(Line, Multiple, Address, nullptr, ParamSize, Name)) +    return PublicRecord(Multiple, Address, ParamSize, Name); + +  return llvm::None; +} + +bool breakpad::operator==(const PublicRecord &L, const PublicRecord &R) { +  return L.Multiple == R.Multiple && L.Address == R.Address && +         L.ParamSize == R.ParamSize && L.Name == R.Name; +} +llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, +                                        const PublicRecord &R) { +  return OS << llvm::formatv("PUBLIC {0}{1:x-} {2:x-} {3}", +                             R.Multiple ? "m " : "", R.Address, R.ParamSize, +                             R.Name); +} + +llvm::Optional<StackCFIRecord> StackCFIRecord::parse(llvm::StringRef Line) { +  // STACK CFI INIT address size reg1: expr1 reg2: expr2 ... +  // or +  // STACK CFI address reg1: expr1 reg2: expr2 ... +  // No token in exprN ends with a colon. + +  if (consume<Token>(Line) != Token::Stack) +    return llvm::None; +  if (consume<Token>(Line) != Token::CFI) +    return llvm::None; + +  llvm::StringRef Str; +  std::tie(Str, Line) = getToken(Line); + +  bool IsInitRecord = stringTo<Token>(Str) == Token::Init; +  if (IsInitRecord) +    std::tie(Str, Line) = getToken(Line); + +  lldb::addr_t Address; +  if (!to_integer(Str, Address, 16)) +    return llvm::None; + +  llvm::Optional<lldb::addr_t> Size; +  if (IsInitRecord) { +    Size.emplace(); +    std::tie(Str, Line) = getToken(Line); +    if (!to_integer(Str, *Size, 16)) +      return llvm::None; +  } + +  return StackCFIRecord(Address, Size, Line.trim()); +} + +bool breakpad::operator==(const StackCFIRecord &L, const StackCFIRecord &R) { +  return L.Address == R.Address && L.Size == R.Size && +         L.UnwindRules == R.UnwindRules; +} + +llvm::raw_ostream &breakpad::operator<<(llvm::raw_ostream &OS, +                                        const StackCFIRecord &R) { +  OS << "STACK CFI "; +  if (R.Size) +    OS << "INIT "; +  OS << llvm::formatv("{0:x-} ", R.Address); +  if (R.Size) +    OS << llvm::formatv("{0:x-} ", *R.Size); +  return OS << " " << R.UnwindRules; +} + +llvm::StringRef breakpad::toString(Record::Kind K) { +  switch (K) { +  case Record::Module: +    return "MODULE"; +  case Record::Info: +    return "INFO"; +  case Record::File: +    return "FILE"; +  case Record::Func: +    return "FUNC"; +  case Record::Line: +    return "LINE"; +  case Record::Public: +    return "PUBLIC"; +  case Record::StackCFI: +    return "STACK CFI"; +  } +  llvm_unreachable("Unknown record kind!"); +} diff --git a/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h new file mode 100644 index 0000000000000..5d5cdb319c10e --- /dev/null +++ b/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h @@ -0,0 +1,163 @@ +//===-- BreakpadRecords.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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H +#define LLDB_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H + +#include "lldb/Utility/UUID.h" +#include "lldb/lldb-types.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Support/FormatProviders.h" + +namespace lldb_private { +namespace breakpad { + +class Record { +public: +  enum Kind { Module, Info, File, Func, Line, Public, StackCFI }; + +  /// Attempt to guess the kind of the record present in the argument without +  /// doing a full parse. The returned kind will always be correct for valid +  /// records, but the full parse can still fail in case of corrupted input. +  static llvm::Optional<Kind> classify(llvm::StringRef Line); + +protected: +  Record(Kind K) : TheKind(K) {} + +  ~Record() = default; + +public: +  Kind getKind() { return TheKind; } + +private: +  Kind TheKind; +}; + +llvm::StringRef toString(Record::Kind K); +inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Record::Kind K) { +  OS << toString(K); +  return OS; +} + +class ModuleRecord : public Record { +public: +  static llvm::Optional<ModuleRecord> parse(llvm::StringRef Line); +  ModuleRecord(llvm::Triple::OSType OS, llvm::Triple::ArchType Arch, UUID ID) +      : Record(Module), OS(OS), Arch(Arch), ID(std::move(ID)) {} + +  llvm::Triple::OSType OS; +  llvm::Triple::ArchType Arch; +  UUID ID; +}; + +inline bool operator==(const ModuleRecord &L, const ModuleRecord &R) { +  return L.OS == R.OS && L.Arch == R.Arch && L.ID == R.ID; +} +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const ModuleRecord &R); + +class InfoRecord : public Record { +public: +  static llvm::Optional<InfoRecord> parse(llvm::StringRef Line); +  InfoRecord(UUID ID) : Record(Info), ID(std::move(ID)) {} + +  UUID ID; +}; + +inline bool operator==(const InfoRecord &L, const InfoRecord &R) { +  return L.ID == R.ID; +} +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const InfoRecord &R); + +class FileRecord : public Record { +public: +  static llvm::Optional<FileRecord> parse(llvm::StringRef Line); +  FileRecord(size_t Number, llvm::StringRef Name) +      : Record(File), Number(Number), Name(Name) {} + +  size_t Number; +  llvm::StringRef Name; +}; + +inline bool operator==(const FileRecord &L, const FileRecord &R) { +  return L.Number == R.Number && L.Name == R.Name; +} +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const FileRecord &R); + +class FuncRecord : public Record { +public: +  static llvm::Optional<FuncRecord> parse(llvm::StringRef Line); +  FuncRecord(bool Multiple, lldb::addr_t Address, lldb::addr_t Size, +             lldb::addr_t ParamSize, llvm::StringRef Name) +      : Record(Module), Multiple(Multiple), Address(Address), Size(Size), +        ParamSize(ParamSize), Name(Name) {} + +  bool Multiple; +  lldb::addr_t Address; +  lldb::addr_t Size; +  lldb::addr_t ParamSize; +  llvm::StringRef Name; +}; + +bool operator==(const FuncRecord &L, const FuncRecord &R); +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const FuncRecord &R); + +class LineRecord : public Record { +public: +  static llvm::Optional<LineRecord> parse(llvm::StringRef Line); +  LineRecord(lldb::addr_t Address, lldb::addr_t Size, uint32_t LineNum, +             size_t FileNum) +      : Record(Line), Address(Address), Size(Size), LineNum(LineNum), +        FileNum(FileNum) {} + +  lldb::addr_t Address; +  lldb::addr_t Size; +  uint32_t LineNum; +  size_t FileNum; +}; + +bool operator==(const LineRecord &L, const LineRecord &R); +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const LineRecord &R); + +class PublicRecord : public Record { +public: +  static llvm::Optional<PublicRecord> parse(llvm::StringRef Line); +  PublicRecord(bool Multiple, lldb::addr_t Address, lldb::addr_t ParamSize, +               llvm::StringRef Name) +      : Record(Module), Multiple(Multiple), Address(Address), +        ParamSize(ParamSize), Name(Name) {} + +  bool Multiple; +  lldb::addr_t Address; +  lldb::addr_t ParamSize; +  llvm::StringRef Name; +}; + +bool operator==(const PublicRecord &L, const PublicRecord &R); +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const PublicRecord &R); + +class StackCFIRecord : public Record { +public: +  static llvm::Optional<StackCFIRecord> parse(llvm::StringRef Line); +  StackCFIRecord(lldb::addr_t Address, llvm::Optional<lldb::addr_t> Size, +                 llvm::StringRef UnwindRules) +      : Record(StackCFI), Address(Address), Size(Size), +        UnwindRules(UnwindRules) {} + +  lldb::addr_t Address; +  llvm::Optional<lldb::addr_t> Size; +  llvm::StringRef UnwindRules; +}; + +bool operator==(const StackCFIRecord &L, const StackCFIRecord &R); +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const StackCFIRecord &R); + +} // namespace breakpad +} // namespace lldb_private + +#endif // LLDB_PLUGINS_OBJECTFILE_BREAKPAD_BREAKPADRECORDS_H diff --git a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp index 917025030ada4..60dd9f9cecf0f 100644 --- a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp +++ b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp @@ -1,18 +1,16 @@  //===-- ObjectFileBreakpad.cpp -------------------------------- -*- C++ -*-===//  // -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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  //  //===----------------------------------------------------------------------===//  #include "Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h" +#include "Plugins/ObjectFile/Breakpad/BreakpadRecords.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"  using namespace lldb;  using namespace lldb_private; @@ -24,164 +22,24 @@ 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) -      .Case("Linux", Triple::Linux) -      .Case("mac", Triple::MacOSX) -      .Case("windows", Triple::Win32) -      .Default(Triple::UnknownOS); -} - -static llvm::Triple::ArchType toArch(llvm::StringRef str) { -  using llvm::Triple; -  return llvm::StringSwitch<Triple::ArchType>(str) -      .Case("arm", Triple::arm) -      .Case("arm64", Triple::aarch64) -      .Case("mips", Triple::mips) -      .Case("ppc", Triple::ppc) -      .Case("ppc64", Triple::ppc64) -      .Case("s390", Triple::systemz) -      .Case("sparc", Triple::sparc) -      .Case("sparcv9", Triple::sparcv9) -      .Case("x86", Triple::x86) -      .Case("x86_64", Triple::x86_64) -      .Default(Triple::UnknownArch); -} - -static llvm::StringRef consume_front(llvm::StringRef &str, size_t n) { -  llvm::StringRef result = str.take_front(n); -  str = str.drop_front(n); -  return result; -} - -static UUID parseModuleId(llvm::Triple::OSType os, llvm::StringRef str) { -  struct uuid_data { -    llvm::support::ulittle32_t uuid1; -    llvm::support::ulittle16_t uuid2[2]; -    uint8_t uuid3[8]; -    llvm::support::ulittle32_t age; -  } data; -  static_assert(sizeof(data) == 20, ""); -  // The textual module id encoding should be between 33 and 40 bytes long, -  // depending on the size of the age field, which is of variable length. -  // The first three chunks of the id are encoded in big endian, so we need to -  // byte-swap those. -  if (str.size() < 33 || str.size() > 40) -    return UUID(); -  uint32_t t; -  if (to_integer(consume_front(str, 8), t, 16)) -    data.uuid1 = t; -  else -    return UUID(); -  for (int i = 0; i < 2; ++i) { -    if (to_integer(consume_front(str, 4), t, 16)) -      data.uuid2[i] = t; -    else -      return UUID(); -  } -  for (int i = 0; i < 8; ++i) { -    if (!to_integer(consume_front(str, 2), data.uuid3[i], 16)) -      return UUID(); -  } -  if (to_integer(str, t, 16)) -    data.age = t; -  else -    return UUID(); - -  // On non-windows, the age field should always be zero, so we don't include to -  // match the native uuid format of these platforms. -  return UUID::fromData(&data, os == llvm::Triple::Win32 ? 20 : 16); -} -  llvm::Optional<Header> Header::parse(llvm::StringRef text) { -  // A valid module should start with something like: -  // MODULE Linux x86_64 E5894855C35DCCCCCCCCCCCCCCCCCCCC0 a.out -  // optionally followed by -  // INFO CODE_ID 554889E55DC3CCCCCCCCCCCCCCCCCCCC [a.exe] -  llvm::StringRef token, line; +  llvm::StringRef line;    std::tie(line, text) = text.split('\n'); -  std::tie(token, line) = getToken(line); -  if (toToken(token) != Token::Module) +  auto Module = ModuleRecord::parse(line); +  if (!Module)      return llvm::None; -  std::tie(token, line) = getToken(line);    llvm::Triple triple; -  triple.setOS(toOS(token)); -  if (triple.getOS() == llvm::Triple::UnknownOS) -    return llvm::None; - -  std::tie(token, line) = getToken(line); -  triple.setArch(toArch(token)); -  if (triple.getArch() == llvm::Triple::UnknownArch) -    return llvm::None; - -  llvm::StringRef module_id; -  std::tie(module_id, line) = getToken(line); +  triple.setArch(Module->Arch); +  triple.setOS(Module->OS);    std::tie(line, text) = text.split('\n'); -  std::tie(token, line) = getToken(line); -  if (token == "INFO") { -    std::tie(token, line) = getToken(line); -    if (token != "CODE_ID") -      return llvm::None; -    std::tie(token, line) = getToken(line); -    // If we don't have any text following the code id (e.g. on linux), we -    // should use the module id as UUID. Otherwise, we revert back to the module -    // id. -    if (line.trim().empty()) { -      UUID uuid; -      if (uuid.SetFromStringRef(token, token.size() / 2) != token.size()) -        return llvm::None; - -      return Header{ArchSpec(triple), uuid}; -    } -  } - -  // We reach here if we don't have a INFO CODE_ID section, or we chose not to -  // use it. In either case, we need to properly decode the module id, whose -  // fields are encoded in big-endian. -  UUID uuid = parseModuleId(triple.getOS(), module_id); -  if (!uuid) -    return llvm::None; - -  return Header{ArchSpec(triple), uuid}; +  auto Info = InfoRecord::parse(line); +  UUID uuid = Info && Info->ID ? Info->ID : Module->ID; +  return Header{ArchSpec(triple), std::move(uuid)};  }  void ObjectFileBreakpad::Initialize() { @@ -264,50 +122,45 @@ Symtab *ObjectFileBreakpad::GetSymtab() {    return nullptr;  } -bool ObjectFileBreakpad::GetUUID(UUID *uuid) { -  *uuid = m_uuid; -  return true; -} -  void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) { -  if (m_sections_ap) +  if (m_sections_up)      return; -  m_sections_ap = llvm::make_unique<SectionList>(); +  m_sections_up = llvm::make_unique<SectionList>(); -  Token current_section = Token::Unknown; +  llvm::Optional<Record::Kind> current_section;    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) +    if (!current_section)        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, +        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); +    m_sections_up->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; +    llvm::Optional<Record::Kind> next_section = Record::classify(line); +    if (next_section == Record::Line) { +      // Line records logically belong to the preceding Func record, so we put +      // them in the same section. +      next_section = Record::Func;      } -    if (token == current_section) +    if (next_section == 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; +    current_section = next_section;      section_start = line.bytes_begin() - m_data.GetDataStart();    }    // Finally, add the last section. diff --git a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h index ba2a3ad30e5f9..e8885e0cc8982 100644 --- a/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h +++ b/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h @@ -1,9 +1,8 @@  //===-- ObjectFileBreakpad.h ---------------------------------- -*- C++ -*-===//  // -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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  //  //===----------------------------------------------------------------------===// @@ -12,16 +11,13 @@  #include "lldb/Symbol/ObjectFile.h"  #include "lldb/Utility/ArchSpec.h" -#include "llvm/ADT/Triple.h"  namespace lldb_private {  namespace breakpad {  class ObjectFileBreakpad : public ObjectFile {  public: -  //------------------------------------------------------------------    // Static Functions -  //------------------------------------------------------------------    static void Initialize();    static void Terminate(); @@ -47,16 +43,12 @@ public:                                          lldb::offset_t length,                                          ModuleSpecList &specs); -  //------------------------------------------------------------------    // PluginInterface protocol -  //------------------------------------------------------------------    ConstString GetPluginName() override { return GetPluginNameStatic(); }    uint32_t GetPluginVersion() override { return 1; } -  //------------------------------------------------------------------    // ObjectFile Protocol. -  //------------------------------------------------------------------    bool ParseHeader() override; @@ -84,7 +76,7 @@ public:    ArchSpec GetArchitecture() override { return m_arch; } -  bool GetUUID(UUID *uuid) override; +  UUID GetUUID() override { return m_uuid; }    FileSpecList GetDebugSymbolFilePaths() override { return FileSpecList(); } diff --git a/source/Plugins/ObjectFile/ELF/ELFHeader.cpp b/source/Plugins/ObjectFile/ELF/ELFHeader.cpp index 3d4735286bf2a..aa9871071b0e0 100644 --- a/source/Plugins/ObjectFile/ELF/ELFHeader.cpp +++ b/source/Plugins/ObjectFile/ELF/ELFHeader.cpp @@ -1,9 +1,8 @@  //===-- ELFHeader.cpp ----------------------------------------- -*- C++ -*-===//  // -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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  //  //===----------------------------------------------------------------------===// @@ -19,7 +18,6 @@ using namespace elf;  using namespace lldb;  using namespace llvm::ELF; -//------------------------------------------------------------------------------  // Static utility functions.  //  // GetMaxU64 and GetMaxS64 wrap the similarly named methods from DataExtractor @@ -68,7 +66,6 @@ static bool GetMaxS64(const lldb_private::DataExtractor &data,    return true;  } -//------------------------------------------------------------------------------  // ELFHeader  ELFHeader::ELFHeader() { memset(this, 0, sizeof(ELFHeader)); } @@ -117,7 +114,7 @@ void ELFHeader::ParseHeaderExtension(lldb_private::DataExtractor &data) {  bool ELFHeader::Parse(lldb_private::DataExtractor &data,                        lldb::offset_t *offset) {    // Read e_ident.  This provides byte order and address size info. -  if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL) +  if (data.GetU8(offset, &e_ident, EI_NIDENT) == nullptr)      return false;    const unsigned byte_size = Is32Bit() ? 4 : 8; @@ -125,11 +122,11 @@ bool ELFHeader::Parse(lldb_private::DataExtractor &data,    data.SetAddressByteSize(byte_size);    // Read e_type and e_machine. -  if (data.GetU16(offset, &e_type, 2) == NULL) +  if (data.GetU16(offset, &e_type, 2) == nullptr)      return false;    // Read e_version. -  if (data.GetU32(offset, &e_version, 1) == NULL) +  if (data.GetU32(offset, &e_version, 1) == nullptr)      return false;    // Read e_entry, e_phoff and e_shoff. @@ -137,11 +134,11 @@ bool ELFHeader::Parse(lldb_private::DataExtractor &data,      return false;    // Read e_flags. -  if (data.GetU32(offset, &e_flags, 1) == NULL) +  if (data.GetU32(offset, &e_flags, 1) == nullptr)      return false;    // Read e_ehsize, e_phentsize, e_phnum, e_shentsize, e_shnum and e_shstrndx. -  if (data.GetU16(offset, &e_ehsize, 6) == NULL) +  if (data.GetU16(offset, &e_ehsize, 6) == nullptr)      return false;    // Initialize e_phnum, e_shnum, and e_shstrndx with the values read from the @@ -216,7 +213,6 @@ unsigned ELFHeader::GetRelocationJumpSlotType() const {    return slot;  } -//------------------------------------------------------------------------------  // ELFSectionHeader  ELFSectionHeader::ELFSectionHeader() { @@ -228,7 +224,7 @@ bool ELFSectionHeader::Parse(const lldb_private::DataExtractor &data,    const unsigned byte_size = data.GetAddressByteSize();    // Read sh_name and sh_type. -  if (data.GetU32(offset, &sh_name, 2) == NULL) +  if (data.GetU32(offset, &sh_name, 2) == nullptr)      return false;    // Read sh_flags. @@ -240,7 +236,7 @@ bool ELFSectionHeader::Parse(const lldb_private::DataExtractor &data,      return false;    // Read sh_link and sh_info. -  if (data.GetU32(offset, &sh_link, 2) == NULL) +  if (data.GetU32(offset, &sh_link, 2) == nullptr)      return false;    // Read sh_addralign and sh_entsize. @@ -250,7 +246,6 @@ bool ELFSectionHeader::Parse(const lldb_private::DataExtractor &data,    return true;  } -//------------------------------------------------------------------------------  // ELFSymbol  ELFSymbol::ELFSymbol() { memset(this, 0, sizeof(ELFSymbol)); } @@ -327,7 +322,7 @@ bool ELFSymbol::Parse(const lldb_private::DataExtractor &data,    const bool parsing_32 = byte_size == 4;    // Read st_name. -  if (data.GetU32(offset, &st_name, 1) == NULL) +  if (data.GetU32(offset, &st_name, 1) == nullptr)      return false;    if (parsing_32) { @@ -336,29 +331,28 @@ bool ELFSymbol::Parse(const lldb_private::DataExtractor &data,        return false;      // Read st_info and st_other. -    if (data.GetU8(offset, &st_info, 2) == NULL) +    if (data.GetU8(offset, &st_info, 2) == nullptr)        return false;      // Read st_shndx. -    if (data.GetU16(offset, &st_shndx, 1) == NULL) +    if (data.GetU16(offset, &st_shndx, 1) == nullptr)        return false;    } else {      // Read st_info and st_other. -    if (data.GetU8(offset, &st_info, 2) == NULL) +    if (data.GetU8(offset, &st_info, 2) == nullptr)        return false;      // Read st_shndx. -    if (data.GetU16(offset, &st_shndx, 1) == NULL) +    if (data.GetU16(offset, &st_shndx, 1) == nullptr)        return false;      // Read st_value and st_size. -    if (data.GetU64(offset, &st_value, 2) == NULL) +    if (data.GetU64(offset, &st_value, 2) == nullptr)        return false;    }    return true;  } -//------------------------------------------------------------------------------  // ELFProgramHeader  ELFProgramHeader::ELFProgramHeader() { @@ -371,7 +365,7 @@ bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,    const bool parsing_32 = byte_size == 4;    // Read p_type; -  if (data.GetU32(offset, &p_type, 1) == NULL) +  if (data.GetU32(offset, &p_type, 1) == nullptr)      return false;    if (parsing_32) { @@ -380,7 +374,7 @@ bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,        return false;      // Read p_flags. -    if (data.GetU32(offset, &p_flags, 1) == NULL) +    if (data.GetU32(offset, &p_flags, 1) == nullptr)        return false;      // Read p_align. @@ -388,7 +382,7 @@ bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,        return false;    } else {      // Read p_flags. -    if (data.GetU32(offset, &p_flags, 1) == NULL) +    if (data.GetU32(offset, &p_flags, 1) == nullptr)        return false;      // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align. @@ -399,7 +393,6 @@ bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,    return true;  } -//------------------------------------------------------------------------------  // ELFDynamic  ELFDynamic::ELFDynamic() { memset(this, 0, sizeof(ELFDynamic)); } @@ -410,7 +403,6 @@ bool ELFDynamic::Parse(const lldb_private::DataExtractor &data,    return GetMaxS64(data, offset, &d_tag, byte_size, 2);  } -//------------------------------------------------------------------------------  // ELFRel  ELFRel::ELFRel() { memset(this, 0, sizeof(ELFRel)); } @@ -423,7 +415,6 @@ bool ELFRel::Parse(const lldb_private::DataExtractor &data,    return GetMaxU64(data, offset, &r_offset, byte_size, 2) != false;  } -//------------------------------------------------------------------------------  // ELFRela  ELFRela::ELFRela() { memset(this, 0, sizeof(ELFRela)); } diff --git a/source/Plugins/ObjectFile/ELF/ELFHeader.h b/source/Plugins/ObjectFile/ELF/ELFHeader.h index faaf8be99d687..bb228e269d406 100644 --- a/source/Plugins/ObjectFile/ELF/ELFHeader.h +++ b/source/Plugins/ObjectFile/ELF/ELFHeader.h @@ -1,13 +1,12 @@  //===-- ELFHeader.h ------------------------------------------- -*- C++ -*-===//  // -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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  //  //===----------------------------------------------------------------------===//  // -/// @file +/// \file  /// Generic structures and typedefs for ELF files.  ///  /// This file provides definitions for the various entities comprising an ELF @@ -32,8 +31,7 @@ class DataExtractor;  namespace elf { -//------------------------------------------------------------------------------ -/// @name ELF type definitions. +/// \name ELF type definitions.  ///  /// Types used to represent the various components of ELF structures.  All  /// types are signed or unsigned integral types wide enough to hold values @@ -50,8 +48,7 @@ typedef uint64_t elf_xword;  typedef int64_t elf_sxword;  //@} -//------------------------------------------------------------------------------ -/// @class ELFHeader +/// \class ELFHeader  /// Generic representation of an ELF file header.  ///  /// This object is used to identify the general attributes on an ELF file and @@ -81,93 +78,83 @@ struct ELFHeader {    ELFHeader(); -  //--------------------------------------------------------------------------    /// Returns true if this is a 32 bit ELF file header.    /// -  /// @return +  /// \return    ///    True if this is a 32 bit ELF file header.    bool Is32Bit() const {      return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS32;    } -  //--------------------------------------------------------------------------    /// Returns true if this is a 64 bit ELF file header.    /// -  /// @return +  /// \return    ///   True if this is a 64 bit ELF file header.    bool Is64Bit() const {      return e_ident[llvm::ELF::EI_CLASS] == llvm::ELF::ELFCLASS64;    } -  //--------------------------------------------------------------------------    /// The byte order of this ELF file header.    /// -  /// @return +  /// \return    ///    The byte order of this ELF file as described by the header.    lldb::ByteOrder GetByteOrder() const; -  //--------------------------------------------------------------------------    /// The jump slot relocation type of this ELF.    unsigned GetRelocationJumpSlotType() const; -  //--------------------------------------------------------------------------    /// Check if there should be header extension in section header #0    /// -  /// @return +  /// \return    ///    True if parsing the ELFHeader requires reading header extension    ///    and false otherwise.    bool HasHeaderExtension() const; -  //--------------------------------------------------------------------------    /// Parse an ELFHeader entry starting at position \p offset and update the    /// data extractor with the address size and byte order attributes as    /// defined by the header.    /// -  /// @param[in,out] data +  /// \param[in,out] data    ///    The DataExtractor to read from.  Updated with the address size and    ///    byte order attributes appropriate to this header.    /// -  /// @param[in,out] offset +  /// \param[in,out] offset    ///    Pointer to an offset in the data.  On return the offset will be    ///    advanced by the number of bytes read.    /// -  /// @return +  /// \return    ///    True if the ELFHeader was successfully read and false    ///    otherwise.    bool Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset); -  //--------------------------------------------------------------------------    /// Examines at most EI_NIDENT bytes starting from the given pointer and    /// determines if the magic ELF identification exists.    /// -  /// @return +  /// \return    ///    True if the given sequence of bytes identifies an ELF file.    static bool MagicBytesMatch(const uint8_t *magic); -  //--------------------------------------------------------------------------    /// Examines at most EI_NIDENT bytes starting from the given address and    /// determines the address size of the underlying ELF file.  This function    /// should only be called on an pointer for which MagicBytesMatch returns    /// true.    /// -  /// @return +  /// \return    ///    The number of bytes forming an address in the ELF file (either 4 or    ///    8), else zero if the address size could not be determined.    static unsigned AddressSizeInBytes(const uint8_t *magic);  private: -  //--------------------------------------------------------------------------    /// Parse an ELFHeader header extension entry.  This method is called by    /// Parse().    /// -  /// @param[in] data +  /// \param[in] data    ///    The DataExtractor to read from.    void ParseHeaderExtension(lldb_private::DataExtractor &data);  }; -//------------------------------------------------------------------------------ -/// @class ELFSectionHeader +/// \class ELFSectionHeader  /// Generic representation of an ELF section header.  struct ELFSectionHeader {    elf_word sh_name;       ///< Section name string index. @@ -183,26 +170,24 @@ struct ELFSectionHeader {    ELFSectionHeader(); -  //--------------------------------------------------------------------------    /// Parse an ELFSectionHeader entry from the given DataExtracter starting at    /// position \p offset.    /// -  /// @param[in] data +  /// \param[in] data    ///    The DataExtractor to read from.  The address size of the extractor    ///    determines if a 32 or 64 bit object should be read.    /// -  /// @param[in,out] offset +  /// \param[in,out] offset    ///    Pointer to an offset in the data.  On return the offset will be    ///    advanced by the number of bytes read.    /// -  /// @return +  /// \return    ///    True if the ELFSectionHeader was successfully read and false    ///    otherwise.    bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);  }; -//------------------------------------------------------------------------------ -/// @class ELFProgramHeader +/// \class ELFProgramHeader  /// Generic representation of an ELF program header.  struct ELFProgramHeader {    elf_word p_type;    ///< Type of program segment. @@ -220,22 +205,21 @@ struct ELFProgramHeader {    /// position \p offset.  The address size of the DataExtractor determines if    /// a 32 or 64 bit object is to be parsed.    /// -  /// @param[in] data +  /// \param[in] data    ///    The DataExtractor to read from.  The address size of the extractor    ///    determines if a 32 or 64 bit object should be read.    /// -  /// @param[in,out] offset +  /// \param[in,out] offset    ///    Pointer to an offset in the data.  On return the offset will be    ///    advanced by the number of bytes read.    /// -  /// @return +  /// \return    ///    True if the ELFProgramHeader was successfully read and false    ///    otherwise.    bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);  }; -//------------------------------------------------------------------------------ -/// @class ELFSymbol +/// \class ELFSymbol  /// Represents a symbol within an ELF symbol table.  struct ELFSymbol {    elf_addr st_value;      ///< Absolute or relocatable address. @@ -270,15 +254,15 @@ struct ELFSymbol {    /// position \p offset.  The address size of the DataExtractor determines if    /// a 32 or 64 bit object is to be parsed.    /// -  /// @param[in] data +  /// \param[in] data    ///    The DataExtractor to read from.  The address size of the extractor    ///    determines if a 32 or 64 bit object should be read.    /// -  /// @param[in,out] offset +  /// \param[in,out] offset    ///    Pointer to an offset in the data.  On return the offset will be    ///    advanced by the number of bytes read.    /// -  /// @return +  /// \return    ///    True if the ELFSymbol was successfully read and false otherwise.    bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); @@ -287,8 +271,7 @@ struct ELFSymbol {              const lldb_private::SectionList *section_list);  }; -//------------------------------------------------------------------------------ -/// @class ELFDynamic +/// \class ELFDynamic  /// Represents an entry in an ELF dynamic table.  struct ELFDynamic {    elf_sxword d_tag; ///< Type of dynamic table entry. @@ -303,22 +286,21 @@ struct ELFDynamic {    /// position \p offset.  The address size of the DataExtractor determines if    /// a 32 or 64 bit object is to be parsed.    /// -  /// @param[in] data +  /// \param[in] data    ///    The DataExtractor to read from.  The address size of the extractor    ///    determines if a 32 or 64 bit object should be read.    /// -  /// @param[in,out] offset +  /// \param[in,out] offset    ///    Pointer to an offset in the data.  On return the offset will be    ///    advanced by the number of bytes read.    /// -  /// @return +  /// \return    ///    True if the ELFDynamic entry was successfully read and false    ///    otherwise.    bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);  }; -//------------------------------------------------------------------------------ -/// @class ELFRel +/// \class ELFRel  /// Represents a relocation entry with an implicit addend.  struct ELFRel {    elf_addr r_offset; ///< Address of reference. @@ -330,15 +312,15 @@ struct ELFRel {    /// \p offset.  The address size of the DataExtractor determines if a 32 or    /// 64 bit object is to be parsed.    /// -  /// @param[in] data +  /// \param[in] data    ///    The DataExtractor to read from.  The address size of the extractor    ///    determines if a 32 or 64 bit object should be read.    /// -  /// @param[in,out] offset +  /// \param[in,out] offset    ///    Pointer to an offset in the data.  On return the offset will be    ///    advanced by the number of bytes read.    /// -  /// @return +  /// \return    ///    True if the ELFRel entry was successfully read and false otherwise.    bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); @@ -359,8 +341,7 @@ struct ELFRel {    static unsigned RelocSymbol64(const ELFRel &rel) { return rel.r_info >> 32; }  }; -//------------------------------------------------------------------------------ -/// @class ELFRela +/// \class ELFRela  /// Represents a relocation entry with an explicit addend.  struct ELFRela {    elf_addr r_offset;   ///< Address of reference. @@ -373,15 +354,15 @@ struct ELFRela {    /// \p offset.  The address size of the DataExtractor determines if a 32 or    /// 64 bit object is to be parsed.    /// -  /// @param[in] data +  /// \param[in] data    ///    The DataExtractor to read from.  The address size of the extractor    ///    determines if a 32 or 64 bit object should be read.    /// -  /// @param[in,out] offset +  /// \param[in,out] offset    ///    Pointer to an offset in the data.  On return the offset will be    ///    advanced by the number of bytes read.    /// -  /// @return +  /// \return    ///    True if the ELFRela entry was successfully read and false otherwise.    bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 9a6563afa0a01..d62afa34bbe81 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -1,9 +1,8 @@  //===-- ObjectFileELF.cpp ------------------------------------- -*- C++ -*-===//  // -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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  //  //===----------------------------------------------------------------------===// @@ -17,7 +16,6 @@  #include "lldb/Core/Module.h"  #include "lldb/Core/ModuleSpec.h"  #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RangeMap.h"  #include "lldb/Core/Section.h"  #include "lldb/Host/FileSystem.h"  #include "lldb/Symbol/DWARFCallFrameInfo.h" @@ -27,6 +25,7 @@  #include "lldb/Utility/ArchSpec.h"  #include "lldb/Utility/DataBufferHeap.h"  #include "lldb/Utility/Log.h" +#include "lldb/Utility/RangeMap.h"  #include "lldb/Utility/Status.h"  #include "lldb/Utility/Stream.h"  #include "lldb/Utility/Timer.h" @@ -56,8 +55,8 @@ namespace {  const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD";  const char *const LLDB_NT_OWNER_GNU = "GNU";  const char *const LLDB_NT_OWNER_NETBSD = "NetBSD"; +const char *const LLDB_NT_OWNER_NETBSDCORE = "NetBSD-CORE";  const char *const LLDB_NT_OWNER_OPENBSD = "OpenBSD"; -const char *const LLDB_NT_OWNER_CSR = "csr";  const char *const LLDB_NT_OWNER_ANDROID = "Android";  const char *const LLDB_NT_OWNER_CORE = "CORE";  const char *const LLDB_NT_OWNER_LINUX = "LINUX"; @@ -71,8 +70,10 @@ const elf_word LLDB_NT_GNU_ABI_SIZE = 16;  const elf_word LLDB_NT_GNU_BUILD_ID_TAG = 0x03; -const elf_word LLDB_NT_NETBSD_ABI_TAG = 0x01; -const elf_word LLDB_NT_NETBSD_ABI_SIZE = 4; +const elf_word LLDB_NT_NETBSD_IDENT_TAG = 1; +const elf_word LLDB_NT_NETBSD_IDENT_DESCSZ = 4; +const elf_word LLDB_NT_NETBSD_IDENT_NAMESZ = 7; +const elf_word LLDB_NT_NETBSD_PROCINFO = 1;  // GNU ABI note OS constants  const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00; @@ -115,7 +116,7 @@ const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02;  #define NT_METAG_TLS 0x502  //===----------------------------------------------------------------------===// -/// @class ELFRelocation +/// \class ELFRelocation  /// Generic wrapper for ELFRel and ELFRela.  ///  /// This helper class allows us to parse both ELFRel and ELFRela relocation @@ -125,7 +126,7 @@ public:    /// Constructs an ELFRelocation entry with a personality as given by @p    /// type.    /// -  /// @param type Either DT_REL or DT_RELA.  Any other value is invalid. +  /// \param type Either DT_REL or DT_RELA.  Any other value is invalid.    ELFRelocation(unsigned type);    ~ELFRelocation(); @@ -161,7 +162,7 @@ ELFRelocation::ELFRelocation(unsigned type) {      reloc = new ELFRela();    else {      assert(false && "unexpected relocation type"); -    reloc = static_cast<ELFRel *>(NULL); +    reloc = static_cast<ELFRel *>(nullptr);    }  } @@ -242,7 +243,7 @@ static user_id_t SegmentID(size_t PHdrIndex) { return ~PHdrIndex; }  bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {    // Read all fields. -  if (data.GetU32(offset, &n_namesz, 3) == NULL) +  if (data.GetU32(offset, &n_namesz, 3) == nullptr)      return false;    // The name field is required to be nul-terminated, and n_namesz includes the @@ -261,7 +262,7 @@ bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {    }    const char *cstr = data.GetCStr(offset, llvm::alignTo(n_namesz, 4)); -  if (cstr == NULL) { +  if (cstr == nullptr) {      Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));      if (log)        log->Printf("Failed to parse note name lacking nul terminator"); @@ -272,27 +273,6 @@ bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {    return true;  } -static uint32_t kalimbaVariantFromElfFlags(const elf::elf_word e_flags) { -  const uint32_t dsp_rev = e_flags & 0xFF; -  uint32_t kal_arch_variant = LLDB_INVALID_CPUTYPE; -  switch (dsp_rev) { -  // TODO(mg11) Support more variants -  case 10: -    kal_arch_variant = llvm::Triple::KalimbaSubArch_v3; -    break; -  case 14: -    kal_arch_variant = llvm::Triple::KalimbaSubArch_v4; -    break; -  case 17: -  case 20: -    kal_arch_variant = llvm::Triple::KalimbaSubArch_v5; -    break; -  default: -    break; -  } -  return kal_arch_variant; -} -  static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) {    const uint32_t mips_arch = header.e_flags & llvm::ELF::EF_MIPS_ARCH;    uint32_t endian = header.e_ident[EI_DATA]; @@ -350,40 +330,13 @@ static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) {    if (header.e_machine == llvm::ELF::EM_MIPS)      return mipsVariantFromElfFlags(header); -  return llvm::ELF::EM_CSR_KALIMBA == header.e_machine -             ? kalimbaVariantFromElfFlags(header.e_flags) -             : LLDB_INVALID_CPUTYPE; -} - -//! The kalimba toolchain identifies a code section as being -//! one with the SHT_PROGBITS set in the section sh_type and the top -//! bit in the 32-bit address field set. -static lldb::SectionType -kalimbaSectionType(const elf::ELFHeader &header, -                   const elf::ELFSectionHeader §_hdr) { -  if (llvm::ELF::EM_CSR_KALIMBA != header.e_machine) { -    return eSectionTypeOther; -  } - -  if (llvm::ELF::SHT_NOBITS == sect_hdr.sh_type) { -    return eSectionTypeZeroFill; -  } - -  if (llvm::ELF::SHT_PROGBITS == sect_hdr.sh_type) { -    const lldb::addr_t KAL_CODE_BIT = 1 << 31; -    return KAL_CODE_BIT & sect_hdr.sh_addr ? eSectionTypeCode -                                           : eSectionTypeData; -  } - -  return eSectionTypeOther; +  return LLDB_INVALID_CPUTYPE;  }  // Arbitrary constant used as UUID prefix for core files.  const uint32_t ObjectFileELF::g_core_uuid_magic(0xE210C); -//------------------------------------------------------------------  // Static methods. -//------------------------------------------------------------------  void ObjectFileELF::Initialize() {    PluginManager::RegisterPlugin(GetPluginNameStatic(),                                  GetPluginDescriptionStatic(), CreateInstance, @@ -436,14 +389,14 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,    unsigned address_size = ELFHeader::AddressSizeInBytes(magic);    if (address_size == 4 || address_size == 8) { -    std::unique_ptr<ObjectFileELF> objfile_ap(new ObjectFileELF( +    std::unique_ptr<ObjectFileELF> objfile_up(new ObjectFileELF(          module_sp, data_sp, data_offset, file, file_offset, length)); -    ArchSpec spec = objfile_ap->GetArchitecture(); -    if (spec && objfile_ap->SetModulesArchitecture(spec)) -      return objfile_ap.release(); +    ArchSpec spec = objfile_up->GetArchitecture(); +    if (spec && objfile_up->SetModulesArchitecture(spec)) +      return objfile_up.release();    } -  return NULL; +  return nullptr;  }  ObjectFile *ObjectFileELF::CreateMemoryInstance( @@ -454,15 +407,15 @@ ObjectFile *ObjectFileELF::CreateMemoryInstance(      if (ELFHeader::MagicBytesMatch(magic)) {        unsigned address_size = ELFHeader::AddressSizeInBytes(magic);        if (address_size == 4 || address_size == 8) { -        std::unique_ptr<ObjectFileELF> objfile_ap( +        std::unique_ptr<ObjectFileELF> objfile_up(              new ObjectFileELF(module_sp, data_sp, process_sp, header_addr)); -        ArchSpec spec = objfile_ap->GetArchitecture(); -        if (spec && objfile_ap->SetModulesArchitecture(spec)) -          return objfile_ap.release(); +        ArchSpec spec = objfile_up->GetArchitecture(); +        if (spec && objfile_up->SetModulesArchitecture(spec)) +          return objfile_up.release();        }      }    } -  return NULL; +  return nullptr;  }  bool ObjectFileELF::MagicBytesMatch(DataBufferSP &data_sp, @@ -756,17 +709,13 @@ size_t ObjectFileELF::GetModuleSpecifications(    return specs.GetSize() - initial_count;  } -//------------------------------------------------------------------  // PluginInterface protocol -//------------------------------------------------------------------  lldb_private::ConstString ObjectFileELF::GetPluginName() {    return GetPluginNameStatic();  }  uint32_t ObjectFileELF::GetPluginVersion() { return m_plugin_version; } -//------------------------------------------------------------------  // ObjectFile protocol -//------------------------------------------------------------------  ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,                               DataBufferSP &data_sp, lldb::offset_t data_offset, @@ -775,7 +724,7 @@ ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,      : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),        m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0),        m_program_headers(), m_section_headers(), m_dynamic_symbols(), -      m_filespec_ap(), m_entry_point_address(), m_arch_spec() { +      m_filespec_up(), m_entry_point_address(), m_arch_spec() {    if (file)      m_file = *file;    ::memset(&m_header, 0, sizeof(m_header)); @@ -788,7 +737,7 @@ ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,      : ObjectFile(module_sp, process_sp, header_addr, header_data_sp),        m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0),        m_program_headers(), m_section_headers(), m_dynamic_symbols(), -      m_filespec_ap(), m_entry_point_address(), m_arch_spec() { +      m_filespec_up(), m_entry_point_address(), m_arch_spec() {    ::memset(&m_header, 0, sizeof(m_header));  } @@ -897,49 +846,43 @@ bool ObjectFileELF::ParseHeader() {    return m_header.Parse(m_data, &offset);  } -bool ObjectFileELF::GetUUID(lldb_private::UUID *uuid) { +UUID ObjectFileELF::GetUUID() {    // Need to parse the section list to get the UUIDs, so make sure that's been    // done.    if (!ParseSectionHeaders() && GetType() != ObjectFile::eTypeCoreFile) -    return false; +    return UUID(); -  using u32le = llvm::support::ulittle32_t; -  if (m_uuid.IsValid()) { -    // We have the full build id uuid. -    *uuid = m_uuid; -    return true; -  } else if (GetType() == ObjectFile::eTypeCoreFile) { -    uint32_t core_notes_crc = 0; +  if (!m_uuid) { +    using u32le = llvm::support::ulittle32_t; +    if (GetType() == ObjectFile::eTypeCoreFile) { +      uint32_t core_notes_crc = 0; -    if (!ParseProgramHeaders()) -      return false; +      if (!ParseProgramHeaders()) +        return UUID(); -    core_notes_crc = CalculateELFNotesSegmentsCRC32(m_program_headers, m_data); +      core_notes_crc = +          CalculateELFNotesSegmentsCRC32(m_program_headers, m_data); -    if (core_notes_crc) { -      // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it look -      // different form .gnu_debuglink crc - followed by 4 bytes of note -      // segments crc. -      u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)}; -      m_uuid = UUID::fromData(data, sizeof(data)); -    } -  } else { -    if (!m_gnu_debuglink_crc) -      m_gnu_debuglink_crc = -          calc_gnu_debuglink_crc32(m_data.GetDataStart(), m_data.GetByteSize()); -    if (m_gnu_debuglink_crc) { -      // Use 4 bytes of crc from the .gnu_debuglink section. -      u32le data(m_gnu_debuglink_crc); -      m_uuid = UUID::fromData(&data, sizeof(data)); +      if (core_notes_crc) { +        // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it +        // look different form .gnu_debuglink crc - followed by 4 bytes of note +        // segments crc. +        u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)}; +        m_uuid = UUID::fromData(data, sizeof(data)); +      } +    } else { +      if (!m_gnu_debuglink_crc) +        m_gnu_debuglink_crc = calc_gnu_debuglink_crc32(m_data.GetDataStart(), +                                                       m_data.GetByteSize()); +      if (m_gnu_debuglink_crc) { +        // Use 4 bytes of crc from the .gnu_debuglink section. +        u32le data(m_gnu_debuglink_crc); +        m_uuid = UUID::fromData(&data, sizeof(data)); +      }      }    } -  if (m_uuid.IsValid()) { -    *uuid = m_uuid; -    return true; -  } - -  return false; +  return m_uuid;  }  lldb_private::FileSpecList ObjectFileELF::GetDebugSymbolFilePaths() { @@ -957,7 +900,7 @@ uint32_t ObjectFileELF::GetDependentModules(FileSpecList &files) {    uint32_t num_specs = 0;    for (unsigned i = 0; i < num_modules; ++i) { -    if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i))) +    if (files.AppendIfUnique(m_filespec_up->GetFileSpecAtIndex(i)))        num_specs++;    } @@ -1060,14 +1003,12 @@ Address ObjectFileELF::GetBaseAddress() {    return LLDB_INVALID_ADDRESS;  } -//----------------------------------------------------------------------  // ParseDependentModules -//----------------------------------------------------------------------  size_t ObjectFileELF::ParseDependentModules() { -  if (m_filespec_ap.get()) -    return m_filespec_ap->GetSize(); +  if (m_filespec_up) +    return m_filespec_up->GetSize(); -  m_filespec_ap.reset(new FileSpecList()); +  m_filespec_up.reset(new FileSpecList());    if (!ParseSectionHeaders())      return 0; @@ -1114,16 +1055,14 @@ size_t ObjectFileELF::ParseDependentModules() {        const char *lib_name = dynstr_data.PeekCStr(str_index);        FileSpec file_spec(lib_name);        FileSystem::Instance().Resolve(file_spec); -      m_filespec_ap->Append(file_spec); +      m_filespec_up->Append(file_spec);      }    } -  return m_filespec_ap->GetSize(); +  return m_filespec_up->GetSize();  } -//----------------------------------------------------------------------  // GetProgramHeaderInfo -//----------------------------------------------------------------------  size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,                                             DataExtractor &object_data,                                             const ELFHeader &header) { @@ -1158,9 +1097,7 @@ size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,    return program_headers.size();  } -//----------------------------------------------------------------------  // ParseProgramHeaders -//----------------------------------------------------------------------  bool ObjectFileELF::ParseProgramHeaders() {    return GetProgramHeaderInfo(m_program_headers, m_data, m_header) != 0;  } @@ -1301,46 +1238,45 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,          // The note.n_name == LLDB_NT_OWNER_GNU is valid for Linux platform          arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);      } -    // Process NetBSD ELF notes. +    // Process NetBSD ELF executables and shared libraries      else if ((note.n_name == LLDB_NT_OWNER_NETBSD) && -             (note.n_type == LLDB_NT_NETBSD_ABI_TAG) && -             (note.n_descsz == LLDB_NT_NETBSD_ABI_SIZE)) { -      // Pull out the min version info. +             (note.n_type == LLDB_NT_NETBSD_IDENT_TAG) && +             (note.n_descsz == LLDB_NT_NETBSD_IDENT_DESCSZ) && +             (note.n_namesz == LLDB_NT_NETBSD_IDENT_NAMESZ)) { +      // Pull out the version info.        uint32_t version_info;        if (data.GetU32(&offset, &version_info, 1) == nullptr) {          error.SetErrorString("failed to read NetBSD ABI note payload");          return error;        } - +      // Convert the version info into a major/minor/patch number. +      //     #define __NetBSD_Version__ MMmmrrpp00 +      // +      //     M = major version +      //     m = minor version; a minor number of 99 indicates current. +      //     r = 0 (since NetBSD 3.0 not used) +      //     p = patchlevel +      const uint32_t version_major = version_info / 100000000; +      const uint32_t version_minor = (version_info % 100000000) / 1000000; +      const uint32_t version_patch = (version_info % 10000) / 100; +      // Set the elf OS version to NetBSD.  Also clear the vendor. +      arch_spec.GetTriple().setOSName( +          llvm::formatv("netbsd{0}.{1}.{2}", version_major, version_minor, +                        version_patch).str()); +      arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); +    } +    // Process NetBSD ELF core(5) notes +    else if ((note.n_name == LLDB_NT_OWNER_NETBSDCORE) && +             (note.n_type == LLDB_NT_NETBSD_PROCINFO)) {        // Set the elf OS version to NetBSD.  Also clear the vendor.        arch_spec.GetTriple().setOS(llvm::Triple::OSType::NetBSD);        arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); - -      if (log) -        log->Printf( -            "ObjectFileELF::%s detected NetBSD, min version constant %" PRIu32, -            __FUNCTION__, version_info);      }      // Process OpenBSD ELF notes.      else if (note.n_name == LLDB_NT_OWNER_OPENBSD) {        // Set the elf OS version to OpenBSD.  Also clear the vendor.        arch_spec.GetTriple().setOS(llvm::Triple::OSType::OpenBSD);        arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); -    } -    // Process CSR kalimba notes -    else if ((note.n_type == LLDB_NT_GNU_ABI_TAG) && -             (note.n_name == LLDB_NT_OWNER_CSR)) { -      arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS); -      arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::CSR); - -      // TODO At some point the description string could be processed. -      // It could provide a steer towards the kalimba variant which this ELF -      // targets. -      if (note.n_descsz) { -        const char *cstr = -            data.GetCStr(&offset, llvm::alignTo(note.n_descsz, 4)); -        (void)cstr; -      }      } else if (note.n_name == LLDB_NT_OWNER_ANDROID) {        arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);        arch_spec.GetTriple().setEnvironment( @@ -1354,8 +1290,6 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,        // the contents look like this in a 64 bit ELF core file: count     =        // 0x000000000000000a (10) page_size = 0x0000000000001000 (4096) Index        // start              end                file_ofs           path ===== -      // ------------------ ------------------ ------------------ -      // ------------------------------------- [  0] 0x0000000000400000        // 0x0000000000401000 0x0000000000000000 /tmp/a.out [  1]        // 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out [        // 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out @@ -1479,9 +1413,7 @@ void ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length,    }  } -//----------------------------------------------------------------------  // GetSectionHeaderInfo -//----------------------------------------------------------------------  size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,                                             DataExtractor &object_data,                                             const elf::ELFHeader &header, @@ -1714,9 +1646,7 @@ ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const {    return symbol_name.substr(0, pos);  } -//----------------------------------------------------------------------  // ParseSectionHeaders -//----------------------------------------------------------------------  size_t ObjectFileELF::ParseSectionHeaders() {    return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid,                                m_gnu_debuglink_file, m_gnu_debuglink_crc, @@ -1726,12 +1656,12 @@ size_t ObjectFileELF::ParseSectionHeaders() {  const ObjectFileELF::ELFSectionHeaderInfo *  ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) {    if (!ParseSectionHeaders()) -    return NULL; +    return nullptr;    if (id < m_section_headers.size())      return &m_section_headers[id]; -  return NULL; +  return nullptr;  }  lldb::user_id_t ObjectFileELF::GetSectionIndexByName(const char *name) { @@ -1744,37 +1674,40 @@ lldb::user_id_t ObjectFileELF::GetSectionIndexByName(const char *name) {  }  static SectionType GetSectionTypeFromName(llvm::StringRef Name) { +  if (Name.consume_front(".debug_") || Name.consume_front(".zdebug_")) { +    return llvm::StringSwitch<SectionType>(Name) +        .Case("abbrev", eSectionTypeDWARFDebugAbbrev) +        .Case("abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo) +        .Case("addr", eSectionTypeDWARFDebugAddr) +        .Case("aranges", eSectionTypeDWARFDebugAranges) +        .Case("cu_index", eSectionTypeDWARFDebugCuIndex) +        .Case("frame", eSectionTypeDWARFDebugFrame) +        .Case("info", eSectionTypeDWARFDebugInfo) +        .Case("info.dwo", eSectionTypeDWARFDebugInfoDwo) +        .Cases("line", "line.dwo", eSectionTypeDWARFDebugLine) +        .Cases("line_str", "line_str.dwo", eSectionTypeDWARFDebugLineStr) +        .Cases("loc", "loc.dwo", eSectionTypeDWARFDebugLoc) +        .Cases("loclists", "loclists.dwo", eSectionTypeDWARFDebugLocLists) +        .Case("macinfo", eSectionTypeDWARFDebugMacInfo) +        .Cases("macro", "macro.dwo", eSectionTypeDWARFDebugMacro) +        .Case("names", eSectionTypeDWARFDebugNames) +        .Case("pubnames", eSectionTypeDWARFDebugPubNames) +        .Case("pubtypes", eSectionTypeDWARFDebugPubTypes) +        .Case("ranges", eSectionTypeDWARFDebugRanges) +        .Case("rnglists", eSectionTypeDWARFDebugRngLists) +        .Case("str", eSectionTypeDWARFDebugStr) +        .Case("str.dwo", eSectionTypeDWARFDebugStrDwo) +        .Case("str_offsets", eSectionTypeDWARFDebugStrOffsets) +        .Case("str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo) +        .Case("types", eSectionTypeDWARFDebugTypes) +        .Case("types.dwo", eSectionTypeDWARFDebugTypesDwo) +        .Default(eSectionTypeOther); +  }    return llvm::StringSwitch<SectionType>(Name)        .Case(".ARM.exidx", eSectionTypeARMexidx)        .Case(".ARM.extab", eSectionTypeARMextab)        .Cases(".bss", ".tbss", eSectionTypeZeroFill)        .Cases(".data", ".tdata", eSectionTypeData) -      .Case(".debug_abbrev", eSectionTypeDWARFDebugAbbrev) -      .Case(".debug_abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo) -      .Case(".debug_addr", eSectionTypeDWARFDebugAddr) -      .Case(".debug_aranges", eSectionTypeDWARFDebugAranges) -      .Case(".debug_cu_index", eSectionTypeDWARFDebugCuIndex) -      .Case(".debug_frame", eSectionTypeDWARFDebugFrame) -      .Case(".debug_info", eSectionTypeDWARFDebugInfo) -      .Case(".debug_info.dwo", eSectionTypeDWARFDebugInfoDwo) -      .Cases(".debug_line", ".debug_line.dwo", eSectionTypeDWARFDebugLine) -      .Cases(".debug_line_str", ".debug_line_str.dwo", -             eSectionTypeDWARFDebugLineStr) -      .Cases(".debug_loc", ".debug_loc.dwo", eSectionTypeDWARFDebugLoc) -      .Cases(".debug_loclists", ".debug_loclists.dwo", -             eSectionTypeDWARFDebugLocLists) -      .Case(".debug_macinfo", eSectionTypeDWARFDebugMacInfo) -      .Cases(".debug_macro", ".debug_macro.dwo", eSectionTypeDWARFDebugMacro) -      .Case(".debug_names", eSectionTypeDWARFDebugNames) -      .Case(".debug_pubnames", eSectionTypeDWARFDebugPubNames) -      .Case(".debug_pubtypes", eSectionTypeDWARFDebugPubTypes) -      .Case(".debug_ranges", eSectionTypeDWARFDebugRanges) -      .Case(".debug_rnglists", eSectionTypeDWARFDebugRngLists) -      .Case(".debug_str", eSectionTypeDWARFDebugStr) -      .Case(".debug_str.dwo", eSectionTypeDWARFDebugStrDwo) -      .Case(".debug_str_offsets", eSectionTypeDWARFDebugStrOffsets) -      .Case(".debug_str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo) -      .Case(".debug_types", eSectionTypeDWARFDebugTypes)        .Case(".eh_frame", eSectionTypeEHFrame)        .Case(".gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink)        .Case(".gosymtab", eSectionTypeGoSymtab) @@ -1798,14 +1731,7 @@ SectionType ObjectFileELF::GetSectionType(const ELFSectionHeaderInfo &H) const {    case SHT_DYNAMIC:      return eSectionTypeELFDynamicLinkInfo;    } -  SectionType Type = GetSectionTypeFromName(H.section_name.GetStringRef()); -  if (Type == eSectionTypeOther) { -    // the kalimba toolchain assumes that ELF section names are free-form. -    // It does support linkscripts which (can) give rise to various -    // arbitrarily named sections being "Code" or "Data". -    Type = kalimbaSectionType(m_header, H); -  } -  return Type; +  return GetSectionTypeFromName(H.section_name.GetStringRef());  }  static uint32_t GetTargetByteSize(SectionType Type, const ArchSpec &arch) { @@ -1938,11 +1864,11 @@ public:  }  void ObjectFileELF::CreateSections(SectionList &unified_section_list) { -  if (m_sections_ap) +  if (m_sections_up)      return; -  m_sections_ap = llvm::make_unique<SectionList>(); -  VMAddressProvider address_provider(CalculateType()); +  m_sections_up = llvm::make_unique<SectionList>(); +  VMAddressProvider address_provider(GetType());    size_t LoadID = 0;    for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) { @@ -1961,7 +1887,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {          eSectionTypeContainer, InfoOr->GetRangeBase(), InfoOr->GetByteSize(),          PHdr.p_offset, PHdr.p_filesz, Log2Align, /*flags*/ 0);      Segment->SetPermissions(GetPermissions(PHdr)); -    m_sections_ap->AddSection(Segment); +    m_sections_up->AddSection(Segment);      address_provider.AddSegment(*InfoOr, std::move(Segment));    } @@ -2007,7 +1933,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {      section_sp->SetPermissions(GetPermissions(header));      section_sp->SetIsThreadSpecific(header.sh_flags & SHF_TLS); -    (InfoOr->Segment ? InfoOr->Segment->GetChildren() : *m_sections_ap) +    (InfoOr->Segment ? InfoOr->Segment->GetChildren() : *m_sections_up)          .AddSection(section_sp);      address_provider.AddSection(std::move(*InfoOr), std::move(section_sp));    } @@ -2015,7 +1941,7 @@ void ObjectFileELF::CreateSections(SectionList &unified_section_list) {    // For eTypeDebugInfo files, the Symbol Vendor will take care of updating the    // unified section list.    if (GetType() != eTypeDebugInfo) -    unified_section_list = *m_sections_ap; +    unified_section_list = *m_sections_up;  }  // Find the arm/aarch64 mapping symbol character in the given symbol name. @@ -2073,8 +1999,8 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,    // custom extension and file name makes it highly unlikely that this will    // collide with anything else.    ConstString file_extension = m_file.GetFileNameExtension(); -  bool skip_oatdata_oatexec = file_extension == ConstString(".oat") || -                              file_extension == ConstString(".odex"); +  bool skip_oatdata_oatexec = +      file_extension == ".oat" || file_extension == ".odex";    ArchSpec arch = GetArchitecture();    ModuleSP module_sp(GetModule()); @@ -2166,7 +2092,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,      if (symbol_type == eSymbolTypeInvalid && symbol.getType() != STT_SECTION) {        if (symbol_section_sp) { -        const ConstString §_name = symbol_section_sp->GetName(); +        ConstString sect_name = symbol_section_sp->GetName();          if (sect_name == text_section_name || sect_name == init_section_name ||              sect_name == fini_section_name || sect_name == ctors_section_name ||              sect_name == dtors_section_name) { @@ -2262,11 +2188,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,         * class         * accordingly.        */ -      const llvm::Triple::ArchType llvm_arch = arch.GetMachine(); -      if (llvm_arch == llvm::Triple::mips || -          llvm_arch == llvm::Triple::mipsel || -          llvm_arch == llvm::Triple::mips64 || -          llvm_arch == llvm::Triple::mips64el) { +      if (arch.IsMIPS()) {          if (IS_MICROMIPS(symbol.st_other))            m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;          else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode)) { @@ -2310,7 +2232,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,      if (symbol_section_sp && module_section_list &&          module_section_list != section_list) { -      const ConstString §_name = symbol_section_sp->GetName(); +      ConstString sect_name = symbol_section_sp->GetName();        auto section_it = section_name_to_section.find(sect_name.GetCString());        if (section_it == section_name_to_section.end())          section_it = @@ -2391,7 +2313,7 @@ unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,    }    // Get section list for this object file. -  SectionList *section_list = m_sections_ap.get(); +  SectionList *section_list = m_sections_up.get();    if (!section_list)      return 0; @@ -2457,7 +2379,7 @@ size_t ObjectFileELF::ParseDynamicSymbols() {  const ELFDynamic *ObjectFileELF::FindDynamicSymbol(unsigned tag) {    if (!ParseDynamicSymbols()) -    return NULL; +    return nullptr;    DynamicSymbolCollIter I = m_dynamic_symbols.begin();    DynamicSymbolCollIter E = m_dynamic_symbols.end(); @@ -2468,7 +2390,7 @@ const ELFDynamic *ObjectFileELF::FindDynamicSymbol(unsigned tag) {        return symbol;    } -  return NULL; +  return nullptr;  }  unsigned ObjectFileELF::PLTRelocationType() { @@ -2619,7 +2541,7 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id,    if (!sym_hdr)      return 0; -  SectionList *section_list = m_sections_ap.get(); +  SectionList *section_list = m_sections_up.get();    if (!section_list)      return 0; @@ -2685,7 +2607,7 @@ unsigned ObjectFileELF::ApplyRelocations(      if (!rel.Parse(rel_data, &offset))        break; -    Symbol *symbol = NULL; +    Symbol *symbol = nullptr;      if (hdr->Is32Bit()) {        switch (reloc_type(rel)) { @@ -2804,7 +2726,7 @@ unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,  Symtab *ObjectFileELF::GetSymtab() {    ModuleSP module_sp(GetModule());    if (!module_sp) -    return NULL; +    return nullptr;    // We always want to use the main object file so we (hopefully) only have one    // cached copy of our symtab, dynamic sections, etc. @@ -2812,10 +2734,10 @@ Symtab *ObjectFileELF::GetSymtab() {    if (module_obj_file && module_obj_file != this)      return module_obj_file->GetSymtab(); -  if (m_symtab_ap.get() == NULL) { +  if (m_symtab_up == nullptr) {      SectionList *section_list = module_sp->GetSectionList();      if (!section_list) -      return NULL; +      return nullptr;      uint64_t symbol_id = 0;      std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); @@ -2836,8 +2758,8 @@ Symtab *ObjectFileELF::GetSymtab() {                .get();      }      if (symtab) { -      m_symtab_ap.reset(new Symtab(symtab->GetObjectFile())); -      symbol_id += ParseSymbolTable(m_symtab_ap.get(), symbol_id, symtab); +      m_symtab_up.reset(new Symtab(symtab->GetObjectFile())); +      symbol_id += ParseSymbolTable(m_symtab_up.get(), symbol_id, symtab);      }      // DT_JMPREL @@ -2861,30 +2783,30 @@ Symtab *ObjectFileELF::GetSymtab() {              GetSectionHeaderByIndex(reloc_id);          assert(reloc_header); -        if (m_symtab_ap == nullptr) -          m_symtab_ap.reset(new Symtab(reloc_section->GetObjectFile())); +        if (m_symtab_up == nullptr) +          m_symtab_up.reset(new Symtab(reloc_section->GetObjectFile())); -        ParseTrampolineSymbols(m_symtab_ap.get(), symbol_id, reloc_header, +        ParseTrampolineSymbols(m_symtab_up.get(), symbol_id, reloc_header,                                 reloc_id);        }      } -    DWARFCallFrameInfo *eh_frame = GetUnwindTable().GetEHFrameInfo(); -    if (eh_frame) { -      if (m_symtab_ap == nullptr) -        m_symtab_ap.reset(new Symtab(this)); -      ParseUnwindSymbols(m_symtab_ap.get(), eh_frame); +    if (DWARFCallFrameInfo *eh_frame = +            GetModule()->GetUnwindTable().GetEHFrameInfo()) { +      if (m_symtab_up == nullptr) +        m_symtab_up.reset(new Symtab(this)); +      ParseUnwindSymbols(m_symtab_up.get(), eh_frame);      }      // If we still don't have any symtab then create an empty instance to avoid      // do the section lookup next time. -    if (m_symtab_ap == nullptr) -      m_symtab_ap.reset(new Symtab(this)); +    if (m_symtab_up == nullptr) +      m_symtab_up.reset(new Symtab(this)); -    m_symtab_ap->CalculateSymbolSizes(); +    m_symtab_up->CalculateSymbolSizes();    } -  return m_symtab_ap.get(); +  return m_symtab_up.get();  }  void ObjectFileELF::RelocateSection(lldb_private::Section *section) @@ -2991,7 +2913,6 @@ bool ObjectFileELF::IsStripped() {  //  // Dump the specifics of the runtime file container (such as any headers  // segments, sections, etc). -//----------------------------------------------------------------------  void ObjectFileELF::Dump(Stream *s) {    ModuleSP module_sp(GetModule());    if (!module_sp) { @@ -3016,20 +2937,18 @@ void ObjectFileELF::Dump(Stream *s) {    s->EOL();    SectionList *section_list = GetSectionList();    if (section_list) -    section_list->Dump(s, NULL, true, UINT32_MAX); +    section_list->Dump(s, nullptr, true, UINT32_MAX);    Symtab *symtab = GetSymtab();    if (symtab) -    symtab->Dump(s, NULL, eSortOrderNone); +    symtab->Dump(s, nullptr, eSortOrderNone);    s->EOL();    DumpDependentModules(s);    s->EOL();  } -//----------------------------------------------------------------------  // DumpELFHeader  //  // Dump the ELF header to the specified output stream -//----------------------------------------------------------------------  void ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) {    s->PutCString("ELF Header\n");    s->Printf("e_ident[EI_MAG0   ] = 0x%2.2x\n", header.e_ident[EI_MAG0]); @@ -3062,11 +2981,9 @@ void ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) {    s->Printf("e_shstrndx  = 0x%8.8x\n", header.e_shstrndx);  } -//----------------------------------------------------------------------  // DumpELFHeader_e_type  //  // Dump an token value for the ELF header member e_type -//----------------------------------------------------------------------  void ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type) {    switch (e_type) {    case ET_NONE: @@ -3089,11 +3006,9 @@ void ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type) {    }  } -//----------------------------------------------------------------------  // DumpELFHeader_e_ident_EI_DATA  //  // Dump an token value for the ELF header member e_ident[EI_DATA] -//----------------------------------------------------------------------  void ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s,                                                    unsigned char ei_data) {    switch (ei_data) { @@ -3111,11 +3026,9 @@ void ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s,    }  } -//----------------------------------------------------------------------  // DumpELFProgramHeader  //  // Dump a single ELF program header to the specified output stream -//----------------------------------------------------------------------  void ObjectFileELF::DumpELFProgramHeader(Stream *s,                                           const ELFProgramHeader &ph) {    DumpELFProgramHeader_p_type(s, ph.p_type); @@ -3128,12 +3041,10 @@ void ObjectFileELF::DumpELFProgramHeader(Stream *s,    s->Printf(") %8.8" PRIx64, ph.p_align);  } -//----------------------------------------------------------------------  // DumpELFProgramHeader_p_type  //  // Dump an token value for the ELF program header member p_type which describes  // the type of the program header -// ----------------------------------------------------------------------  void ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) {    const int kStrWidth = 15;    switch (p_type) { @@ -3152,11 +3063,9 @@ void ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) {    }  } -//----------------------------------------------------------------------  // DumpELFProgramHeader_p_flags  //  // Dump an token value for the ELF program header member p_flags -//----------------------------------------------------------------------  void ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) {    *s << ((p_flags & PF_X) ? "PF_X" : "    ")       << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ') @@ -3165,11 +3074,9 @@ void ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) {       << ((p_flags & PF_R) ? "PF_R" : "    ");  } -//----------------------------------------------------------------------  // DumpELFProgramHeaders  //  // Dump all of the ELF program header to the specified output stream -//----------------------------------------------------------------------  void ObjectFileELF::DumpELFProgramHeaders(Stream *s) {    if (!ParseProgramHeaders())      return; @@ -3187,11 +3094,9 @@ void ObjectFileELF::DumpELFProgramHeaders(Stream *s) {    }  } -//----------------------------------------------------------------------  // DumpELFSectionHeader  //  // Dump a single ELF section header to the specified output stream -//----------------------------------------------------------------------  void ObjectFileELF::DumpELFSectionHeader(Stream *s,                                           const ELFSectionHeaderInfo &sh) {    s->Printf("%8.8x ", sh.sh_name); @@ -3204,12 +3109,10 @@ void ObjectFileELF::DumpELFSectionHeader(Stream *s,    s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);  } -//----------------------------------------------------------------------  // DumpELFSectionHeader_sh_type  //  // Dump an token value for the ELF section header member sh_type which  // describes the type of the section -//----------------------------------------------------------------------  void ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type) {    const int kStrWidth = 12;    switch (sh_type) { @@ -3235,11 +3138,9 @@ void ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type) {    }  } -//----------------------------------------------------------------------  // DumpELFSectionHeader_sh_flags  //  // Dump an token value for the ELF section header member sh_flags -//----------------------------------------------------------------------  void ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s,                                                    elf_xword sh_flags) {    *s << ((sh_flags & SHF_WRITE) ? "WRITE" : "     ") @@ -3249,11 +3150,9 @@ void ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s,       << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : "         ");  } -//----------------------------------------------------------------------  // DumpELFSectionHeaders  //  // Dump all of the ELF section header to the specified output stream -//----------------------------------------------------------------------  void ObjectFileELF::DumpELFSectionHeaders(Stream *s) {    if (!ParseSectionHeaders())      return; @@ -3283,7 +3182,7 @@ void ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) {    if (num_modules > 0) {      s->PutCString("Dependent Modules:\n");      for (unsigned i = 0; i < num_modules; ++i) { -      const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i); +      const FileSpec &spec = m_filespec_up->GetFileSpecAtIndex(i);        s->Printf("   %s\n", spec.GetFilename().GetCString());      }    } @@ -3299,7 +3198,7 @@ ArchSpec ObjectFileELF::GetArchitecture() {    }    if (CalculateType() == eTypeCoreFile && -      m_arch_spec.TripleOSIsUnspecifiedUnknown()) { +      !m_arch_spec.TripleOSWasSpecified()) {      // Core files don't have section headers yet they have PT_NOTE program      // headers that might shed more light on the architecture      for (const elf::ELFProgramHeader &H : ProgramHeaders()) { @@ -3405,7 +3304,8 @@ size_t ObjectFileELF::ReadSectionData(Section *section,      return section->GetObjectFile()->ReadSectionData(section, section_data);    size_t result = ObjectFile::ReadSectionData(section, section_data); -  if (result == 0 || !section->Test(SHF_COMPRESSED)) +  if (result == 0 || !llvm::object::Decompressor::isCompressedELFSection( +                         section->Get(), section->GetName().GetStringRef()))      return result;    auto Decompressor = llvm::object::Decompressor::create( diff --git a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index 08fd5bdc60a97..b63a5d14d4f5d 100644 --- a/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -1,9 +1,8 @@  //===-- ObjectFileELF.h --------------------------------------- -*- C++ -*-===//  // -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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  //  //===----------------------------------------------------------------------===// @@ -34,14 +33,14 @@ struct ELFNote {    /// Parse an ELFNote entry from the given DataExtractor starting at position    /// \p offset.    /// -  /// @param[in] data +  /// \param[in] data    ///    The DataExtractor to read from.    /// -  /// @param[in,out] offset +  /// \param[in,out] offset    ///    Pointer to an offset in the data.  On return the offset will be    ///    advanced by the number of bytes read.    /// -  /// @return +  /// \return    ///    True if the ELFRel entry was successfully read and false otherwise.    bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); @@ -50,8 +49,7 @@ struct ELFNote {    }  }; -//------------------------------------------------------------------------------ -/// @class ObjectFileELF +/// \class ObjectFileELF  /// Generic ELF object file reader.  ///  /// This class provides a generic ELF (32/64 bit) reader plugin implementing @@ -60,9 +58,7 @@ class ObjectFileELF : public lldb_private::ObjectFile {  public:    ~ObjectFileELF() override; -  //------------------------------------------------------------------    // Static Functions -  //------------------------------------------------------------------    static void Initialize();    static void Terminate(); @@ -90,16 +86,12 @@ public:    static bool MagicBytesMatch(lldb::DataBufferSP &data_sp, lldb::addr_t offset,                                lldb::addr_t length); -  //------------------------------------------------------------------    // PluginInterface protocol -  //------------------------------------------------------------------    lldb_private::ConstString GetPluginName() override;    uint32_t GetPluginVersion() override; -  //------------------------------------------------------------------    // ObjectFile Protocol. -  //------------------------------------------------------------------    bool ParseHeader() override;    bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, @@ -123,7 +115,7 @@ public:    lldb_private::ArchSpec GetArchitecture() override; -  bool GetUUID(lldb_private::UUID *uuid) override; +  lldb_private::UUID GetUUID() override;    lldb_private::FileSpecList GetDebugSymbolFilePaths() override; @@ -211,7 +203,7 @@ private:    /// List of file specifications corresponding to the modules (shared    /// libraries) on which this object file depends. -  mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_ap; +  mutable std::unique_ptr<lldb_private::FileSpecList> m_filespec_up;    /// Cached value of the entry point for this module.    lldb_private::Address m_entry_point_address; @@ -265,7 +257,7 @@ private:                                       lldb_private::ArchSpec &arch_spec);    /// Scans the dynamic section and locates all dependent modules (shared -  /// libraries) populating m_filespec_ap.  This method will compute the +  /// libraries) populating m_filespec_up.  This method will compute the    /// dependent module list only once.  Returns the number of dependent    /// modules parsed.    size_t ParseDependentModules(); @@ -275,7 +267,7 @@ private:    /// number of dynamic symbols parsed.    size_t ParseDynamicSymbols(); -  /// Populates m_symtab_ap will all non-dynamic linker symbols.  This method +  /// Populates m_symtab_up will all non-dynamic linker symbols.  This method    /// will parse the symbols only once.  Returns the number of symbols parsed.    unsigned ParseSymbolTable(lldb_private::Symtab *symbol_table,                              lldb::user_id_t start_id, @@ -331,7 +323,7 @@ private:    /// Returns the section header with the given id or NULL.    const ELFSectionHeaderInfo *GetSectionHeaderByIndex(lldb::user_id_t id); -  /// @name  ELF header dump routines +  /// \name  ELF header dump routines    //@{    static void DumpELFHeader(lldb_private::Stream *s,                              const elf::ELFHeader &header); @@ -343,7 +335,7 @@ private:                                     elf::elf_half e_type);    //@} -  /// @name ELF program header dump routines +  /// \name ELF program header dump routines    //@{    void DumpELFProgramHeaders(lldb_private::Stream *s); @@ -357,7 +349,7 @@ private:                                             elf::elf_word p_flags);    //@} -  /// @name ELF section header dump routines +  /// \name ELF section header dump routines    //@{    void DumpELFSectionHeaders(lldb_private::Stream *s); diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp index cfe61992be0d2..eaf973da38355 100644 --- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp +++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp @@ -1,9 +1,8 @@  //===-- ObjectFileJIT.cpp ---------------------------------------*- C++ -*-===//  // -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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  //  //===----------------------------------------------------------------------===// @@ -15,7 +14,6 @@  #include "lldb/Core/Module.h"  #include "lldb/Core/ModuleSpec.h"  #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RangeMap.h"  #include "lldb/Core/Section.h"  #include "lldb/Core/StreamFile.h"  #include "lldb/Host/Host.h" @@ -29,6 +27,7 @@  #include "lldb/Utility/DataBufferHeap.h"  #include "lldb/Utility/FileSpec.h"  #include "lldb/Utility/Log.h" +#include "lldb/Utility/RangeMap.h"  #include "lldb/Utility/StreamString.h"  #include "lldb/Utility/Timer.h"  #include "lldb/Utility/UUID.h" @@ -67,7 +66,7 @@ ObjectFile *ObjectFileJIT::CreateInstance(const lldb::ModuleSP &module_sp,                                            lldb::offset_t length) {    // JIT'ed object file is backed by the ObjectFileJITDelegate, never read from    // a file -  return NULL; +  return nullptr;  }  ObjectFile *ObjectFileJIT::CreateMemoryInstance(const lldb::ModuleSP &module_sp, @@ -76,7 +75,7 @@ ObjectFile *ObjectFileJIT::CreateMemoryInstance(const lldb::ModuleSP &module_sp,                                                  lldb::addr_t header_addr) {    // JIT'ed object file is backed by the ObjectFileJITDelegate, never read from    // memory -  return NULL; +  return nullptr;  }  size_t ObjectFileJIT::GetModuleSpecifications( @@ -89,7 +88,7 @@ size_t ObjectFileJIT::GetModuleSpecifications(  ObjectFileJIT::ObjectFileJIT(const lldb::ModuleSP &module_sp,                               const ObjectFileJITDelegateSP &delegate_sp) -    : ObjectFile(module_sp, NULL, 0, 0, DataBufferSP(), 0), m_delegate_wp() { +    : ObjectFile(module_sp, nullptr, 0, 0, DataBufferSP(), 0), m_delegate_wp() {    if (delegate_sp) {      m_delegate_wp = delegate_sp;      m_data.SetByteOrder(delegate_sp->GetByteOrder()); @@ -116,18 +115,18 @@ Symtab *ObjectFileJIT::GetSymtab() {    ModuleSP module_sp(GetModule());    if (module_sp) {      std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); -    if (m_symtab_ap.get() == NULL) { -      m_symtab_ap.reset(new Symtab(this)); +    if (m_symtab_up == nullptr) { +      m_symtab_up.reset(new Symtab(this));        std::lock_guard<std::recursive_mutex> symtab_guard( -          m_symtab_ap->GetMutex()); +          m_symtab_up->GetMutex());        ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());        if (delegate_sp) -        delegate_sp->PopulateSymtab(this, *m_symtab_ap); +        delegate_sp->PopulateSymtab(this, *m_symtab_up);        // TODO: get symbols from delegate -      m_symtab_ap->Finalize(); +      m_symtab_up->Finalize();      }    } -  return m_symtab_ap.get(); +  return m_symtab_up.get();  }  bool ObjectFileJIT::IsStripped() { @@ -135,12 +134,12 @@ bool ObjectFileJIT::IsStripped() {  }  void ObjectFileJIT::CreateSections(SectionList &unified_section_list) { -  if (!m_sections_ap.get()) { -    m_sections_ap.reset(new SectionList()); +  if (!m_sections_up) { +    m_sections_up.reset(new SectionList());      ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock());      if (delegate_sp) { -      delegate_sp->PopulateSectionList(this, *m_sections_ap); -      unified_section_list = *m_sections_ap; +      delegate_sp->PopulateSectionList(this, *m_sections_up); +      unified_section_list = *m_sections_up;      }    }  } @@ -160,16 +159,16 @@ void ObjectFileJIT::Dump(Stream *s) {      SectionList *sections = GetSectionList();      if (sections) -      sections->Dump(s, NULL, true, UINT32_MAX); +      sections->Dump(s, nullptr, true, UINT32_MAX); -    if (m_symtab_ap.get()) -      m_symtab_ap->Dump(s, NULL, eSortOrderNone); +    if (m_symtab_up) +      m_symtab_up->Dump(s, nullptr, eSortOrderNone);    }  } -bool ObjectFileJIT::GetUUID(lldb_private::UUID *uuid) { +UUID ObjectFileJIT::GetUUID() {    // TODO: maybe get from delegate, not needed for first pass -  return false; +  return UUID();  }  uint32_t ObjectFileJIT::GetDependentModules(FileSpecList &files) { @@ -195,9 +194,7 @@ ArchSpec ObjectFileJIT::GetArchitecture() {    return ArchSpec();  } -//------------------------------------------------------------------  // PluginInterface protocol -//------------------------------------------------------------------  lldb_private::ConstString ObjectFileJIT::GetPluginName() {    return GetPluginNameStatic();  } @@ -249,14 +246,12 @@ size_t ObjectFileJIT::ReadSectionData(    if (section->GetFileSize()) {      const void *src = (void *)(uintptr_t)section->GetFileOffset(); -    DataBufferSP data_sp( -        new lldb_private::DataBufferHeap(src, section->GetFileSize())); -    if (data_sp) { -      section_data.SetData(data_sp, 0, data_sp->GetByteSize()); -      section_data.SetByteOrder(GetByteOrder()); -      section_data.SetAddressByteSize(GetAddressByteSize()); -      return section_data.GetByteSize(); -    } +    DataBufferSP data_sp = +        std::make_shared<DataBufferHeap>(src, section->GetFileSize()); +    section_data.SetData(data_sp, 0, data_sp->GetByteSize()); +    section_data.SetByteOrder(GetByteOrder()); +    section_data.SetAddressByteSize(GetAddressByteSize()); +    return section_data.GetByteSize();    }    section_data.Clear();    return 0; diff --git a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h index 3d9e4748d3df3..99241126cd1a6 100644 --- a/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h +++ b/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h @@ -1,9 +1,8 @@  //===-- ObjectFileJIT.h -----------------------------------------*- C++ -*-===//  // -//                     The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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  //  //===----------------------------------------------------------------------===// @@ -13,10 +12,8 @@  #include "lldb/Core/Address.h"  #include "lldb/Symbol/ObjectFile.h" -//----------------------------------------------------------------------  // This class needs to be hidden as eventually belongs in a plugin that  // will export the ObjectFile protocol -//----------------------------------------------------------------------  class ObjectFileJIT : public lldb_private::ObjectFile {  public:    ObjectFileJIT(const lldb::ModuleSP &module_sp, @@ -24,9 +21,7 @@ public:    ~ObjectFileJIT() override; -  //------------------------------------------------------------------    // Static Functions -  //------------------------------------------------------------------    static void Initialize();    static void Terminate(); @@ -51,9 +46,7 @@ public:                                          lldb::offset_t length,                                          lldb_private::ModuleSpecList &specs); -  //------------------------------------------------------------------    // Member Functions -  //------------------------------------------------------------------    bool ParseHeader() override;    bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, @@ -75,7 +68,7 @@ public:    lldb_private::ArchSpec GetArchitecture() override; -  bool GetUUID(lldb_private::UUID *uuid) override; +  lldb_private::UUID GetUUID() override;    uint32_t GetDependentModules(lldb_private::FileSpecList &files) override; @@ -95,9 +88,7 @@ public:    ObjectFile::Strata CalculateStrata() override; -  //------------------------------------------------------------------    // PluginInterface protocol -  //------------------------------------------------------------------    lldb_private::ConstString GetPluginName() override;    uint32_t GetPluginVersion() override;  | 
