krytarowski updated this revision to Diff 96272.
krytarowski edited the summary of this revision.
krytarowski added a comment.
Herald added a subscriber: srhines.

Fix handling executable and shared library triple detection.

Apply changes from review.

Update revision summary.


Repository:
  rL LLVM

https://reviews.llvm.org/D32149

Files:
  source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
  source/Plugins/Process/elf-core/ProcessElfCore.cpp
  source/Plugins/Process/elf-core/ProcessElfCore.h

Index: source/Plugins/Process/elf-core/ProcessElfCore.h
===================================================================
--- source/Plugins/Process/elf-core/ProcessElfCore.h
+++ source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -125,6 +125,18 @@
     lldb_private::ConstString path;
   };
 
+  // Parse thread(s) data structuresNetBSD(prstatus, prpsinfo) from given NOTE
+  // segment
+  lldb_private::Error ParseThreadContextsFromNoteSegmentNetBSD(
+      const elf::ELFProgramHeader *segment_header,
+      lldb_private::DataExtractor segment_data);
+
+  // Parse thread(s) data structuresGeneric(prstatus, prpsinfo) from given NOTE
+  // segment
+  lldb_private::Error ParseThreadContextsFromNoteSegmentGeneric(
+      const elf::ELFProgramHeader *segment_header,
+      lldb_private::DataExtractor segment_data);
+
   //------------------------------------------------------------------
   // For ProcessElfCore only
   //------------------------------------------------------------------
Index: source/Plugins/Process/elf-core/ProcessElfCore.cpp
===================================================================
--- source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -27,6 +27,7 @@
 #include "lldb/Utility/DataBufferLLVM.h"
 #include "lldb/Utility/Log.h"
 
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/ELF.h"
 #include "llvm/Support/Threading.h"
 
@@ -219,7 +220,7 @@
   ArchSpec core_arch(m_core_module_sp->GetArchitecture());
   target_arch.MergeFrom(core_arch);
   GetTarget().SetArchitecture(target_arch);
- 
+
   SetUnixSignals(UnixSignals::Create(GetArchitecture()));
 
   // Ensure we found at least one thread that was stopped on a signal.
@@ -373,7 +374,8 @@
   lldb::addr_t bytes_left =
       0; // Number of bytes available in the core file from the given address
 
-  // Don't proceed if core file doesn't contain the actual data for this address range.
+  // Don't proceed if core file doesn't contain the actual data for this address
+  // range.
   if (file_start == file_end)
     return 0;
 
@@ -458,9 +460,14 @@
 
 namespace NETBSD {
 
-enum { NT_PROCINFO = 1, NT_AUXV, NT_AMD64_REGS = 33, NT_AMD64_FPREGS = 35 };
+enum { NT_PROCINFO = 1, NT_PROCINFO_SIZE = 160, NT_AUXV = 2 };
+
+namespace AMD64 {
+enum { NT_REGS = 33, NT_FPREGS = 35 };
 }
 
+} // namespace NETBSD
+
 // Parse a FreeBSD NT_PRSTATUS note - see FreeBSD sys/procfs.h for details.
 static void ParseFreeBSDPrStatus(ThreadData &thread_data, DataExtractor &data,
                                  ArchSpec &arch) {
@@ -497,15 +504,29 @@
   thread_data.name = data.GetCStr(&offset, 20);
 }
 
-static void ParseNetBSDProcInfo(ThreadData &thread_data, DataExtractor &data) {
+static Error ParseNetBSDProcInfo(DataExtractor &data, uint32_t &cpi_nlwps,
+                                 uint32_t &cpi_signo, uint32_t &cpi_siglwp) {
   lldb::offset_t offset = 0;
 
-  int version = data.GetU32(&offset);
+  uint32_t version = data.GetU32(&offset);
   if (version != 1)
-    return;
+    return Error(
+        "Error parsing NetBSD core(5) notes: Unsupported procinfo version");
 
-  offset += 4;
-  thread_data.signo = data.GetU32(&offset);
+  uint32_t cpisize = data.GetU32(&offset);
+  if (cpisize != NETBSD::NT_PROCINFO_SIZE)
+    return Error(
+        "Error parsing NetBSD core(5) notes: Unsupported procinfo size");
+
+  cpi_signo = data.GetU32(&offset); /* killing signal */
+
+  offset += 108;
+  cpi_nlwps = data.GetU32(&offset); /* number of LWPs */
+
+  offset += 32;
+  cpi_siglwp = data.GetU32(&offset); /* LWP target of killing signal */
+
+  return Error();
 }
 
 static void ParseOpenBSDProcInfo(ThreadData &thread_data, DataExtractor &data) {
@@ -524,12 +545,28 @@
 /// 1) A PT_NOTE segment is composed of one or more NOTE entries.
 /// 2) NOTE Entry contains a standard header followed by variable size data.
 ///   (see ELFNote structure)
-/// 3) A Thread Context in a core file usually described by 3 NOTE entries.
+Error ProcessElfCore::ParseThreadContextsFromNoteSegment(
+    const elf::ELFProgramHeader *segment_header, DataExtractor segment_data) {
+
+  assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE);
+
+  switch (GetArchitecture().GetTriple().getOS()) {
+  case llvm::Triple::NetBSD:
+    return ParseThreadContextsFromNoteSegmentNetBSD(segment_header,
+                                                    segment_data);
+  default:
+    return ParseThreadContextsFromNoteSegmentGeneric(segment_header,
+                                                     segment_data);
+  }
+}
+
+/// Generic (Linux, Android, FreeBSD, ...) Thread context from PT_NOTE segment
+/// 1) A Thread Context in a core file usually described by 3 NOTE entries.
 ///    a) NT_PRSTATUS - Register context
 ///    b) NT_PRPSINFO - Process info(pid..)
 ///    c) NT_FPREGSET - Floating point registers
-/// 4) The NOTE entries can be in any order
-/// 5) If a core file contains multiple thread contexts then there is two data
+/// 2) The NOTE entries can be in any order
+/// 3) If a core file contains multiple thread contexts then there is two data
 /// forms
 ///    a) Each thread context(2 or more NOTE entries) contained in its own
 ///    segment (PT_NOTE)
@@ -540,8 +577,9 @@
 ///        new thread when it finds NT_PRSTATUS or NT_PRPSINFO NOTE entry.
 ///    For case (b) there may be either one NT_PRPSINFO per thread, or a single
 ///    one that applies to all threads (depending on the platform type).
-Error ProcessElfCore::ParseThreadContextsFromNoteSegment(
+Error ProcessElfCore::ParseThreadContextsFromNoteSegmentGeneric(
     const elf::ELFProgramHeader *segment_header, DataExtractor segment_data) {
+
   assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE);
 
   lldb::offset_t offset = 0;
@@ -607,21 +645,6 @@
       default:
         break;
       }
-    } else if (note.n_name.substr(0, 11) == "NetBSD-CORE") {
-      // NetBSD per-thread information is stored in notes named
-      // "NetBSD-CORE@nnn" so match on the initial part of the string.
-      m_os = llvm::Triple::NetBSD;
-      if (note.n_type == NETBSD::NT_PROCINFO) {
-        ParseNetBSDProcInfo(*thread_data, note_data);
-      } else if (note.n_type == NETBSD::NT_AUXV) {
-        m_auxv = DataExtractor(note_data);
-      } else if (arch.GetMachine() == llvm::Triple::x86_64 &&
-                 note.n_type == NETBSD::NT_AMD64_REGS) {
-        thread_data->gpregset = note_data;
-      } else if (arch.GetMachine() == llvm::Triple::x86_64 &&
-                 note.n_type == NETBSD::NT_AMD64_FPREGS) {
-        thread_data->fpregset = note_data;
-      }
     } else if (note.n_name.substr(0, 7) == "OpenBSD") {
       // OpenBSD per-thread information is stored in notes named
       // "OpenBSD@nnn" so match on the initial part of the string.
@@ -659,7 +682,7 @@
         // The result from FXSAVE is in NT_PRXFPREG for i386 core files
         if (arch.GetCore() == ArchSpec::eCore_x86_64_x86_64)
           thread_data->fpregset = note_data;
-        else if(arch.IsMIPS())
+        else if (arch.IsMIPS())
           thread_data->fpregset = note_data;
         break;
       case NT_PRPSINFO:
@@ -717,6 +740,136 @@
   return error;
 }
 
+/// NetBSD specific Thread context from PT_NOTE segment
+///
+/// NetBSD ELF core files use notes to provide information about
+/// the process's state.  The note name is "NetBSD-CORE" for
+/// information that is global to the process, and "NetBSD-CORE@nn",
+/// where "nn" is the lwpid of the LWP that the information belongs
+/// to (such as register state).
+///
+/// NetBSD uses the following note identifiers:
+///
+///      ELF_NOTE_NETBSD_CORE_PROCINFO (value 1)
+///             Note is a "netbsd_elfcore_procinfo" structure.
+///      ELF_NOTE_NETBSD_CORE_AUXV     (value 2; since NetBSD 8.0)
+///             Note is an array of AuxInfo structures.
+///
+/// NetBSD also uses ptrace(2) request numbers (the ones that exist in
+/// machine-dependent space) to identify register info notes.  The
+/// info in such notes is in the same format that ptrace(2) would
+/// export that information.
+///
+/// For more information see /usr/include/sys/exec_elf.h
+///
+Error ProcessElfCore::ParseThreadContextsFromNoteSegmentNetBSD(
+    const elf::ELFProgramHeader *segment_header, DataExtractor segment_data) {
+
+  assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE);
+
+  lldb::offset_t offset = 0;
+  ArchSpec arch = GetArchitecture();
+  m_os = llvm::Triple::NetBSD;
+
+  /*
+   * To be extracted from struct netbsd_elfcore_procinfo
+   * Used to sanity check of the LWPs of the process
+   */
+  uint32_t nlwps = 0;
+  uint32_t signo;  /* killing signal */
+  uint32_t siglwp; /* LWP target of killing signal */
+
+  while (offset < segment_header->p_filesz) {
+    ELFNote note = ELFNote();
+    note.Parse(segment_data, &offset);
+
+    size_t note_start, note_size;
+    note_start = offset;
+    note_size = llvm::alignTo(note.n_descsz, 4);
+
+    // Store the NOTE information in the current thread
+    DataExtractor note_data(segment_data, note_start, note_size);
+    note_data.SetAddressByteSize(
+        m_core_module_sp->GetArchitecture().GetAddressByteSize());
+
+    llvm::StringRef name = note.n_name;
+
+    if (name == "NetBSD-CORE") {
+      if (note.n_type == NETBSD::NT_PROCINFO) {
+        Error error = ParseNetBSDProcInfo(note_data, nlwps, signo, siglwp);
+        if (error.Fail())
+          return error;
+      } else if (note.n_type == NETBSD::NT_AUXV) {
+        m_auxv = DataExtractor(note_data);
+      }
+    } else if (name.consume_front("NetBSD-CORE@")) {
+      lldb::tid_t tid;
+      if (name.getAsInteger(10, tid))
+        return Error("Error parsing NetBSD core(5) notes: Cannot convert "
+                     "LWP ID to integer");
+
+      switch (arch.GetMachine()) {
+      case llvm::Triple::x86_64: {
+        /* Assume order PT_GETREGS, PT_GETFPREGS */
+        if (note.n_type == NETBSD::AMD64::NT_REGS) {
+          m_thread_data.push_back(ThreadData());
+          m_thread_data.back().gpregset = note_data;
+          m_thread_data.back().tid = tid;
+        } else if (note.n_type == NETBSD::AMD64::NT_FPREGS) {
+          if (m_thread_data.empty() || tid != m_thread_data.back().tid)
+            return Error("Error parsing NetBSD core(5) notes: Unexpected order "
+                         "of NOTEs PT_GETFPREG before PT_GETREG");
+          m_thread_data.back().fpregset = note_data;
+        } else {
+          return Error(
+              "Error parsing NetBSD core(5) notes: Unsupported AMD64 NOTE");
+        }
+      } break;
+      default:
+        return Error(
+            "Error parsing NetBSD core(5) notes: Unsupported architecture");
+      }
+    } else {
+      return Error("Error parsing NetBSD core(5) notes: Unrecognized note");
+    }
+
+    offset += note_size;
+  }
+
+  if (m_thread_data.empty())
+    return Error("Error parsing NetBSD core(5) notes: No threads information "
+                 "specified in notes");
+
+  if (m_thread_data.size() != nlwps)
+    return Error("rror parsing NetBSD core(5) notes: Mismatch between the "
+                 "number of LWPs in netbsd_elfcore_procinfo and the number of "
+                 "LWPs specified by MD notes");
+
+  /* The whole process signal */
+  if (siglwp == 0) {
+    for (auto &data : m_thread_data)
+      data.signo = signo;
+  }
+  /* Signal destinated for a particular LWP */
+  else {
+    bool passed = false;
+
+    for (auto &data : m_thread_data) {
+      if (data.tid == siglwp) {
+        data.signo = signo;
+        passed = true;
+        break;
+      }
+    }
+
+    if (!passed)
+      return Error(
+          "Error parsing NetBSD core(5) notes: Signal passed to unknown LWP");
+  }
+
+  return Error();
+}
+
 uint32_t ProcessElfCore::GetNumThreadContexts() {
   if (!m_thread_data_valid)
     DoLoadCore();
@@ -730,7 +883,7 @@
   core_file->GetArchitecture(arch);
 
   ArchSpec target_arch = GetTarget().GetArchitecture();
-  
+
   if (target_arch.IsMIPS())
     return target_arch;
 
Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
===================================================================
--- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -52,6 +52,7 @@
 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";
@@ -67,8 +68,10 @@
 
 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_NT_NETBSD_IDENT_TAG = 1;
+const elf_word LLDB_NT_NETBSD_NT_NETBSD_IDENT_DESCSZ = 4;
+const elf_word LLDB_NT_NETBSD_NT_NETBSD_IDENT_NAMESZ = 7;
+const elf_word LLDB_NT_NETBSD_NT_PROCINFO = 1;
 
 // GNU ABI note OS constants
 const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00;
@@ -288,14 +291,15 @@
   return kal_arch_variant;
 }
 
-static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) {
+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];
   uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown;
   uint32_t fileclass = header.e_ident[EI_CLASS];
 
-  // If there aren't any elf flags available (e.g core elf file) then return default 
-  // 32 or 64 bit arch (without any architecture revision) based on object file's class.
+  // If there aren't any elf flags available (e.g core elf file) then return
+  // default 32 or 64 bit arch (without any architecture revision) based on
+  // object file's class.
   if (header.e_type == ET_CORE) {
     switch (fileclass) {
     case llvm::ELF::ELFCLASS32:
@@ -404,8 +408,8 @@
                                           lldb::offset_t file_offset,
                                           lldb::offset_t length) {
   if (!data_sp) {
-    data_sp =
-        DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset);
+    data_sp = DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length,
+                                                  file_offset);
     if (!data_sp)
       return nullptr;
     data_offset = 0;
@@ -422,8 +426,8 @@
 
   // Update the data to contain the entire file if it doesn't already
   if (data_sp->GetByteSize() < length) {
-    data_sp =
-        DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset);
+    data_sp = DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length,
+                                                  file_offset);
     if (!data_sp)
       return nullptr;
     data_offset = 0;
@@ -681,7 +685,7 @@
           // with a bigger data source to get the actual values.
           size_t section_header_end = header.e_shoff + header.e_shentsize;
           if (header.HasHeaderExtension() &&
-            section_header_end > data_sp->GetByteSize()) {
+              section_header_end > data_sp->GetByteSize()) {
             data_sp = DataBufferLLVM::CreateSliceFromPath(
                 file.GetPath(), section_header_end, file_offset);
             if (data_sp) {
@@ -767,8 +771,8 @@
                     CalculateELFNotesSegmentsCRC32(program_headers, data);
               } else {
                 // Need to map entire file into memory to calculate the crc.
-                data_sp = DataBufferLLVM::CreateSliceFromPath(file.GetPath(), -1,
-                                                         file_offset);
+                data_sp = DataBufferLLVM::CreateSliceFromPath(file.GetPath(),
+                                                              -1, file_offset);
                 if (data_sp) {
                   data.SetData(data_sp);
                   gnu_debuglink_crc = calc_gnu_debuglink_crc32(
@@ -1370,25 +1374,41 @@
         // 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_NT_NETBSD_IDENT_TAG) &&
+             (note.n_descsz == LLDB_NT_NETBSD_NT_NETBSD_IDENT_DESCSZ) &&
+             (note.n_namesz == LLDB_NT_NETBSD_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;
+      char os_name[32];
+      snprintf(os_name, sizeof(os_name),
+               "netbsd%" PRIu32 ".%" PRIu32 ".%" PRIu32, version_major,
+               version_minor, version_patch);
+      // Set the elf OS version to NetBSD.  Also clear the vendor.
+      arch_spec.GetTriple().setOSName(os_name);
+      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_NT_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) {
@@ -1465,7 +1485,8 @@
             return error;
           }
           llvm::StringRef path(cstr);
-          if (path.contains("/lib/x86_64-linux-gnu") || path.contains("/lib/i386-linux-gnu")) {
+          if (path.contains("/lib/x86_64-linux-gnu") ||
+              path.contains("/lib/i386-linux-gnu")) {
             arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
             break;
           }
@@ -1475,7 +1496,7 @@
           // In case of MIPSR6, the LLDB_NT_OWNER_GNU note is missing
           // for some cases (e.g. compile with -nostdlib)
           // Hence set OS to Linux
-          arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); 
+          arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
       }
     }
 
@@ -1579,7 +1600,7 @@
     const uint32_t sub_type = subTypeFromElfHeader(header);
     arch_spec.SetArchitecture(eArchTypeELF, header.e_machine, sub_type,
                               header.e_ident[EI_OSABI]);
-    
+
     // Validate if it is ok to remove GetOsFromOSABI.
     // Note, that now the OS is determined based on EI_OSABI flag and
     // the info extracted from ELF notes (see RefineModuleDetailsFromNote).
@@ -2357,7 +2378,7 @@
        * flag to check whether the symbol is microMIPS and then set the address
        * class
        * accordingly.
-      */
+       */
       const llvm::Triple::ArchType llvm_arch = arch.GetMachine();
       if (llvm_arch == llvm::Triple::mips ||
           llvm_arch == llvm::Triple::mipsel ||
@@ -3016,41 +3037,42 @@
   // it have to recalculate the index first.
   std::vector<Symbol> new_symbols;
 
-  eh_frame->ForEachFDEEntries([this, symbol_table, section_list, &new_symbols](
-      lldb::addr_t file_addr, uint32_t size, dw_offset_t) {
-    Symbol *symbol = symbol_table->FindSymbolAtFileAddress(file_addr);
-    if (symbol) {
-      if (!symbol->GetByteSizeIsValid()) {
-        symbol->SetByteSize(size);
-        symbol->SetSizeIsSynthesized(true);
-      }
-    } else {
-      SectionSP section_sp =
-          section_list->FindSectionContainingFileAddress(file_addr);
-      if (section_sp) {
-        addr_t offset = file_addr - section_sp->GetFileAddress();
-        const char *symbol_name = GetNextSyntheticSymbolName().GetCString();
-        uint64_t symbol_id = symbol_table->GetNumSymbols();
-        Symbol eh_symbol(
-            symbol_id,       // Symbol table index.
-            symbol_name,     // Symbol name.
-            false,           // Is the symbol name mangled?
-            eSymbolTypeCode, // Type of this symbol.
-            true,            // Is this globally visible?
-            false,           // Is this symbol debug info?
-            false,           // Is this symbol a trampoline?
-            true,            // Is this symbol artificial?
-            section_sp,      // Section in which this symbol is defined or null.
-            offset,          // Offset in section or symbol value.
-            0,     // Size:          Don't specify the size as an FDE can
-            false, // Size is valid: cover multiple symbols.
-            false, // Contains linker annotations?
-            0);    // Symbol flags.
-        new_symbols.push_back(eh_symbol);
-      }
-    }
-    return true;
-  });
+  eh_frame->ForEachFDEEntries(
+      [this, symbol_table, section_list,
+       &new_symbols](lldb::addr_t file_addr, uint32_t size, dw_offset_t) {
+        Symbol *symbol = symbol_table->FindSymbolAtFileAddress(file_addr);
+        if (symbol) {
+          if (!symbol->GetByteSizeIsValid()) {
+            symbol->SetByteSize(size);
+            symbol->SetSizeIsSynthesized(true);
+          }
+        } else {
+          SectionSP section_sp =
+              section_list->FindSectionContainingFileAddress(file_addr);
+          if (section_sp) {
+            addr_t offset = file_addr - section_sp->GetFileAddress();
+            const char *symbol_name = GetNextSyntheticSymbolName().GetCString();
+            uint64_t symbol_id = symbol_table->GetNumSymbols();
+            Symbol eh_symbol(
+                symbol_id,       // Symbol table index.
+                symbol_name,     // Symbol name.
+                false,           // Is the symbol name mangled?
+                eSymbolTypeCode, // Type of this symbol.
+                true,            // Is this globally visible?
+                false,           // Is this symbol debug info?
+                false,           // Is this symbol a trampoline?
+                true,            // Is this symbol artificial?
+                section_sp, // Section in which this symbol is defined or null.
+                offset,     // Offset in section or symbol value.
+                0,     // Size:          Don't specify the size as an FDE can
+                false, // Size is valid: cover multiple symbols.
+                false, // Contains linker annotations?
+                0);    // Symbol flags.
+            new_symbols.push_back(eh_symbol);
+          }
+        }
+        return true;
+      });
 
   for (const Symbol &s : new_symbols)
     symbol_table->AddSymbol(s);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to