xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (revision 101d251d5caf88a9341f3045ab62e122abae1b90)
1dda28197Spatrick //===-- ObjectFileELF.cpp -------------------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick 
9061da546Spatrick #include "ObjectFileELF.h"
10061da546Spatrick 
11061da546Spatrick #include <algorithm>
12061da546Spatrick #include <cassert>
13*101d251dSrobert #include <optional>
14061da546Spatrick #include <unordered_map>
15061da546Spatrick 
16061da546Spatrick #include "lldb/Core/FileSpecList.h"
17061da546Spatrick #include "lldb/Core/Module.h"
18061da546Spatrick #include "lldb/Core/ModuleSpec.h"
19061da546Spatrick #include "lldb/Core/PluginManager.h"
20a0747c9fSpatrick #include "lldb/Core/Progress.h"
21061da546Spatrick #include "lldb/Core/Section.h"
22061da546Spatrick #include "lldb/Host/FileSystem.h"
23061da546Spatrick #include "lldb/Host/LZMA.h"
24061da546Spatrick #include "lldb/Symbol/DWARFCallFrameInfo.h"
25061da546Spatrick #include "lldb/Symbol/SymbolContext.h"
26061da546Spatrick #include "lldb/Target/SectionLoadList.h"
27061da546Spatrick #include "lldb/Target/Target.h"
28061da546Spatrick #include "lldb/Utility/ArchSpec.h"
29061da546Spatrick #include "lldb/Utility/DataBufferHeap.h"
30*101d251dSrobert #include "lldb/Utility/LLDBLog.h"
31061da546Spatrick #include "lldb/Utility/Log.h"
32061da546Spatrick #include "lldb/Utility/RangeMap.h"
33061da546Spatrick #include "lldb/Utility/Status.h"
34061da546Spatrick #include "lldb/Utility/Stream.h"
35061da546Spatrick #include "lldb/Utility/Timer.h"
36061da546Spatrick #include "llvm/ADT/IntervalMap.h"
37061da546Spatrick #include "llvm/ADT/PointerUnion.h"
38061da546Spatrick #include "llvm/ADT/StringRef.h"
39061da546Spatrick #include "llvm/BinaryFormat/ELF.h"
40061da546Spatrick #include "llvm/Object/Decompressor.h"
41061da546Spatrick #include "llvm/Support/ARMBuildAttributes.h"
42061da546Spatrick #include "llvm/Support/CRC.h"
43a0747c9fSpatrick #include "llvm/Support/FormatVariadic.h"
44061da546Spatrick #include "llvm/Support/MathExtras.h"
45061da546Spatrick #include "llvm/Support/MemoryBuffer.h"
46061da546Spatrick #include "llvm/Support/MipsABIFlags.h"
47061da546Spatrick 
48061da546Spatrick #define CASE_AND_STREAM(s, def, width)                                         \
49061da546Spatrick   case def:                                                                    \
50061da546Spatrick     s->Printf("%-*s", width, #def);                                            \
51061da546Spatrick     break;
52061da546Spatrick 
53061da546Spatrick using namespace lldb;
54061da546Spatrick using namespace lldb_private;
55061da546Spatrick using namespace elf;
56061da546Spatrick using namespace llvm::ELF;
57061da546Spatrick 
58dda28197Spatrick LLDB_PLUGIN_DEFINE(ObjectFileELF)
59dda28197Spatrick 
60061da546Spatrick // ELF note owner definitions
61*101d251dSrobert static const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD";
62*101d251dSrobert static const char *const LLDB_NT_OWNER_GNU = "GNU";
63*101d251dSrobert static const char *const LLDB_NT_OWNER_NETBSD = "NetBSD";
64*101d251dSrobert static const char *const LLDB_NT_OWNER_NETBSDCORE = "NetBSD-CORE";
65*101d251dSrobert static const char *const LLDB_NT_OWNER_OPENBSD = "OpenBSD";
66*101d251dSrobert static const char *const LLDB_NT_OWNER_ANDROID = "Android";
67*101d251dSrobert static const char *const LLDB_NT_OWNER_CORE = "CORE";
68*101d251dSrobert static const char *const LLDB_NT_OWNER_LINUX = "LINUX";
69061da546Spatrick 
70061da546Spatrick // ELF note type definitions
71*101d251dSrobert static const elf_word LLDB_NT_FREEBSD_ABI_TAG = 0x01;
72*101d251dSrobert static const elf_word LLDB_NT_FREEBSD_ABI_SIZE = 4;
73061da546Spatrick 
74*101d251dSrobert static const elf_word LLDB_NT_GNU_ABI_TAG = 0x01;
75*101d251dSrobert static const elf_word LLDB_NT_GNU_ABI_SIZE = 16;
76061da546Spatrick 
77*101d251dSrobert static const elf_word LLDB_NT_GNU_BUILD_ID_TAG = 0x03;
78061da546Spatrick 
79*101d251dSrobert static const elf_word LLDB_NT_NETBSD_IDENT_TAG = 1;
80*101d251dSrobert static const elf_word LLDB_NT_NETBSD_IDENT_DESCSZ = 4;
81*101d251dSrobert static const elf_word LLDB_NT_NETBSD_IDENT_NAMESZ = 7;
82*101d251dSrobert static const elf_word LLDB_NT_NETBSD_PROCINFO = 1;
83061da546Spatrick 
84061da546Spatrick // GNU ABI note OS constants
85*101d251dSrobert static const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00;
86*101d251dSrobert static const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01;
87*101d251dSrobert static const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02;
88*101d251dSrobert 
89*101d251dSrobert namespace {
90061da546Spatrick 
91061da546Spatrick //===----------------------------------------------------------------------===//
92061da546Spatrick /// \class ELFRelocation
93061da546Spatrick /// Generic wrapper for ELFRel and ELFRela.
94061da546Spatrick ///
95061da546Spatrick /// This helper class allows us to parse both ELFRel and ELFRela relocation
96061da546Spatrick /// entries in a generic manner.
97061da546Spatrick class ELFRelocation {
98061da546Spatrick public:
99061da546Spatrick   /// Constructs an ELFRelocation entry with a personality as given by @p
100061da546Spatrick   /// type.
101061da546Spatrick   ///
102061da546Spatrick   /// \param type Either DT_REL or DT_RELA.  Any other value is invalid.
103061da546Spatrick   ELFRelocation(unsigned type);
104061da546Spatrick 
105061da546Spatrick   ~ELFRelocation();
106061da546Spatrick 
107061da546Spatrick   bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
108061da546Spatrick 
109061da546Spatrick   static unsigned RelocType32(const ELFRelocation &rel);
110061da546Spatrick 
111061da546Spatrick   static unsigned RelocType64(const ELFRelocation &rel);
112061da546Spatrick 
113061da546Spatrick   static unsigned RelocSymbol32(const ELFRelocation &rel);
114061da546Spatrick 
115061da546Spatrick   static unsigned RelocSymbol64(const ELFRelocation &rel);
116061da546Spatrick 
117*101d251dSrobert   static elf_addr RelocOffset32(const ELFRelocation &rel);
118061da546Spatrick 
119*101d251dSrobert   static elf_addr RelocOffset64(const ELFRelocation &rel);
120061da546Spatrick 
121*101d251dSrobert   static elf_sxword RelocAddend32(const ELFRelocation &rel);
122061da546Spatrick 
123*101d251dSrobert   static elf_sxword RelocAddend64(const ELFRelocation &rel);
124*101d251dSrobert 
IsRela()125*101d251dSrobert   bool IsRela() { return (reloc.is<ELFRela *>()); }
126061da546Spatrick 
127061da546Spatrick private:
128061da546Spatrick   typedef llvm::PointerUnion<ELFRel *, ELFRela *> RelocUnion;
129061da546Spatrick 
130061da546Spatrick   RelocUnion reloc;
131061da546Spatrick };
132*101d251dSrobert } // end anonymous namespace
133061da546Spatrick 
ELFRelocation(unsigned type)134061da546Spatrick ELFRelocation::ELFRelocation(unsigned type) {
135061da546Spatrick   if (type == DT_REL || type == SHT_REL)
136061da546Spatrick     reloc = new ELFRel();
137061da546Spatrick   else if (type == DT_RELA || type == SHT_RELA)
138061da546Spatrick     reloc = new ELFRela();
139061da546Spatrick   else {
140061da546Spatrick     assert(false && "unexpected relocation type");
141061da546Spatrick     reloc = static_cast<ELFRel *>(nullptr);
142061da546Spatrick   }
143061da546Spatrick }
144061da546Spatrick 
~ELFRelocation()145061da546Spatrick ELFRelocation::~ELFRelocation() {
146061da546Spatrick   if (reloc.is<ELFRel *>())
147061da546Spatrick     delete reloc.get<ELFRel *>();
148061da546Spatrick   else
149061da546Spatrick     delete reloc.get<ELFRela *>();
150061da546Spatrick }
151061da546Spatrick 
Parse(const lldb_private::DataExtractor & data,lldb::offset_t * offset)152061da546Spatrick bool ELFRelocation::Parse(const lldb_private::DataExtractor &data,
153061da546Spatrick                           lldb::offset_t *offset) {
154061da546Spatrick   if (reloc.is<ELFRel *>())
155061da546Spatrick     return reloc.get<ELFRel *>()->Parse(data, offset);
156061da546Spatrick   else
157061da546Spatrick     return reloc.get<ELFRela *>()->Parse(data, offset);
158061da546Spatrick }
159061da546Spatrick 
RelocType32(const ELFRelocation & rel)160061da546Spatrick unsigned ELFRelocation::RelocType32(const ELFRelocation &rel) {
161061da546Spatrick   if (rel.reloc.is<ELFRel *>())
162061da546Spatrick     return ELFRel::RelocType32(*rel.reloc.get<ELFRel *>());
163061da546Spatrick   else
164061da546Spatrick     return ELFRela::RelocType32(*rel.reloc.get<ELFRela *>());
165061da546Spatrick }
166061da546Spatrick 
RelocType64(const ELFRelocation & rel)167061da546Spatrick unsigned ELFRelocation::RelocType64(const ELFRelocation &rel) {
168061da546Spatrick   if (rel.reloc.is<ELFRel *>())
169061da546Spatrick     return ELFRel::RelocType64(*rel.reloc.get<ELFRel *>());
170061da546Spatrick   else
171061da546Spatrick     return ELFRela::RelocType64(*rel.reloc.get<ELFRela *>());
172061da546Spatrick }
173061da546Spatrick 
RelocSymbol32(const ELFRelocation & rel)174061da546Spatrick unsigned ELFRelocation::RelocSymbol32(const ELFRelocation &rel) {
175061da546Spatrick   if (rel.reloc.is<ELFRel *>())
176061da546Spatrick     return ELFRel::RelocSymbol32(*rel.reloc.get<ELFRel *>());
177061da546Spatrick   else
178061da546Spatrick     return ELFRela::RelocSymbol32(*rel.reloc.get<ELFRela *>());
179061da546Spatrick }
180061da546Spatrick 
RelocSymbol64(const ELFRelocation & rel)181061da546Spatrick unsigned ELFRelocation::RelocSymbol64(const ELFRelocation &rel) {
182061da546Spatrick   if (rel.reloc.is<ELFRel *>())
183061da546Spatrick     return ELFRel::RelocSymbol64(*rel.reloc.get<ELFRel *>());
184061da546Spatrick   else
185061da546Spatrick     return ELFRela::RelocSymbol64(*rel.reloc.get<ELFRela *>());
186061da546Spatrick }
187061da546Spatrick 
RelocOffset32(const ELFRelocation & rel)188*101d251dSrobert elf_addr ELFRelocation::RelocOffset32(const ELFRelocation &rel) {
189061da546Spatrick   if (rel.reloc.is<ELFRel *>())
190061da546Spatrick     return rel.reloc.get<ELFRel *>()->r_offset;
191061da546Spatrick   else
192061da546Spatrick     return rel.reloc.get<ELFRela *>()->r_offset;
193061da546Spatrick }
194061da546Spatrick 
RelocOffset64(const ELFRelocation & rel)195*101d251dSrobert elf_addr ELFRelocation::RelocOffset64(const ELFRelocation &rel) {
196061da546Spatrick   if (rel.reloc.is<ELFRel *>())
197061da546Spatrick     return rel.reloc.get<ELFRel *>()->r_offset;
198061da546Spatrick   else
199061da546Spatrick     return rel.reloc.get<ELFRela *>()->r_offset;
200061da546Spatrick }
201061da546Spatrick 
RelocAddend32(const ELFRelocation & rel)202*101d251dSrobert elf_sxword ELFRelocation::RelocAddend32(const ELFRelocation &rel) {
203061da546Spatrick   if (rel.reloc.is<ELFRel *>())
204061da546Spatrick     return 0;
205061da546Spatrick   else
206061da546Spatrick     return rel.reloc.get<ELFRela *>()->r_addend;
207061da546Spatrick }
208061da546Spatrick 
RelocAddend64(const ELFRelocation & rel)209*101d251dSrobert elf_sxword  ELFRelocation::RelocAddend64(const ELFRelocation &rel) {
210061da546Spatrick   if (rel.reloc.is<ELFRel *>())
211061da546Spatrick     return 0;
212061da546Spatrick   else
213061da546Spatrick     return rel.reloc.get<ELFRela *>()->r_addend;
214061da546Spatrick }
215061da546Spatrick 
SegmentID(size_t PHdrIndex)216dda28197Spatrick static user_id_t SegmentID(size_t PHdrIndex) {
217dda28197Spatrick   return ~user_id_t(PHdrIndex);
218dda28197Spatrick }
219061da546Spatrick 
Parse(const DataExtractor & data,lldb::offset_t * offset)220061da546Spatrick bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {
221061da546Spatrick   // Read all fields.
222061da546Spatrick   if (data.GetU32(offset, &n_namesz, 3) == nullptr)
223061da546Spatrick     return false;
224061da546Spatrick 
225061da546Spatrick   // The name field is required to be nul-terminated, and n_namesz includes the
226061da546Spatrick   // terminating nul in observed implementations (contrary to the ELF-64 spec).
227061da546Spatrick   // A special case is needed for cores generated by some older Linux versions,
228061da546Spatrick   // which write a note named "CORE" without a nul terminator and n_namesz = 4.
229061da546Spatrick   if (n_namesz == 4) {
230061da546Spatrick     char buf[4];
231061da546Spatrick     if (data.ExtractBytes(*offset, 4, data.GetByteOrder(), buf) != 4)
232061da546Spatrick       return false;
233061da546Spatrick     if (strncmp(buf, "CORE", 4) == 0) {
234061da546Spatrick       n_name = "CORE";
235061da546Spatrick       *offset += 4;
236061da546Spatrick       return true;
237061da546Spatrick     }
238061da546Spatrick   }
239061da546Spatrick 
240061da546Spatrick   const char *cstr = data.GetCStr(offset, llvm::alignTo(n_namesz, 4));
241061da546Spatrick   if (cstr == nullptr) {
242*101d251dSrobert     Log *log = GetLog(LLDBLog::Symbols);
243061da546Spatrick     LLDB_LOGF(log, "Failed to parse note name lacking nul terminator");
244061da546Spatrick 
245061da546Spatrick     return false;
246061da546Spatrick   }
247061da546Spatrick   n_name = cstr;
248061da546Spatrick   return true;
249061da546Spatrick }
250061da546Spatrick 
mipsVariantFromElfFlags(const elf::ELFHeader & header)251061da546Spatrick static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) {
252061da546Spatrick   const uint32_t mips_arch = header.e_flags & llvm::ELF::EF_MIPS_ARCH;
253061da546Spatrick   uint32_t endian = header.e_ident[EI_DATA];
254061da546Spatrick   uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown;
255061da546Spatrick   uint32_t fileclass = header.e_ident[EI_CLASS];
256061da546Spatrick 
257061da546Spatrick   // If there aren't any elf flags available (e.g core elf file) then return
258061da546Spatrick   // default
259061da546Spatrick   // 32 or 64 bit arch (without any architecture revision) based on object file's class.
260061da546Spatrick   if (header.e_type == ET_CORE) {
261061da546Spatrick     switch (fileclass) {
262061da546Spatrick     case llvm::ELF::ELFCLASS32:
263061da546Spatrick       return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el
264061da546Spatrick                                      : ArchSpec::eMIPSSubType_mips32;
265061da546Spatrick     case llvm::ELF::ELFCLASS64:
266061da546Spatrick       return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el
267061da546Spatrick                                      : ArchSpec::eMIPSSubType_mips64;
268061da546Spatrick     default:
269061da546Spatrick       return arch_variant;
270061da546Spatrick     }
271061da546Spatrick   }
272061da546Spatrick 
273061da546Spatrick   switch (mips_arch) {
274061da546Spatrick   case llvm::ELF::EF_MIPS_ARCH_1:
275061da546Spatrick   case llvm::ELF::EF_MIPS_ARCH_2:
276061da546Spatrick   case llvm::ELF::EF_MIPS_ARCH_32:
277061da546Spatrick     return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el
278061da546Spatrick                                    : ArchSpec::eMIPSSubType_mips32;
279061da546Spatrick   case llvm::ELF::EF_MIPS_ARCH_32R2:
280061da546Spatrick     return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r2el
281061da546Spatrick                                    : ArchSpec::eMIPSSubType_mips32r2;
282061da546Spatrick   case llvm::ELF::EF_MIPS_ARCH_32R6:
283061da546Spatrick     return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r6el
284061da546Spatrick                                    : ArchSpec::eMIPSSubType_mips32r6;
285061da546Spatrick   case llvm::ELF::EF_MIPS_ARCH_3:
286061da546Spatrick   case llvm::ELF::EF_MIPS_ARCH_4:
287061da546Spatrick   case llvm::ELF::EF_MIPS_ARCH_5:
288061da546Spatrick   case llvm::ELF::EF_MIPS_ARCH_64:
289061da546Spatrick     return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el
290061da546Spatrick                                    : ArchSpec::eMIPSSubType_mips64;
291061da546Spatrick   case llvm::ELF::EF_MIPS_ARCH_64R2:
292061da546Spatrick     return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r2el
293061da546Spatrick                                    : ArchSpec::eMIPSSubType_mips64r2;
294061da546Spatrick   case llvm::ELF::EF_MIPS_ARCH_64R6:
295061da546Spatrick     return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r6el
296061da546Spatrick                                    : ArchSpec::eMIPSSubType_mips64r6;
297061da546Spatrick   default:
298061da546Spatrick     break;
299061da546Spatrick   }
300061da546Spatrick 
301061da546Spatrick   return arch_variant;
302061da546Spatrick }
303061da546Spatrick 
riscvVariantFromElfFlags(const elf::ELFHeader & header)304a0747c9fSpatrick static uint32_t riscvVariantFromElfFlags(const elf::ELFHeader &header) {
305a0747c9fSpatrick   uint32_t fileclass = header.e_ident[EI_CLASS];
306a0747c9fSpatrick   switch (fileclass) {
307a0747c9fSpatrick   case llvm::ELF::ELFCLASS32:
308a0747c9fSpatrick     return ArchSpec::eRISCVSubType_riscv32;
309a0747c9fSpatrick   case llvm::ELF::ELFCLASS64:
310a0747c9fSpatrick     return ArchSpec::eRISCVSubType_riscv64;
311a0747c9fSpatrick   default:
312a0747c9fSpatrick     return ArchSpec::eRISCVSubType_unknown;
313a0747c9fSpatrick   }
314a0747c9fSpatrick }
315a0747c9fSpatrick 
ppc64VariantFromElfFlags(const elf::ELFHeader & header)316*101d251dSrobert static uint32_t ppc64VariantFromElfFlags(const elf::ELFHeader &header) {
317*101d251dSrobert   uint32_t endian = header.e_ident[EI_DATA];
318*101d251dSrobert   if (endian == ELFDATA2LSB)
319*101d251dSrobert     return ArchSpec::eCore_ppc64le_generic;
320*101d251dSrobert   else
321*101d251dSrobert     return ArchSpec::eCore_ppc64_generic;
322*101d251dSrobert }
323*101d251dSrobert 
loongarchVariantFromElfFlags(const elf::ELFHeader & header)324*101d251dSrobert static uint32_t loongarchVariantFromElfFlags(const elf::ELFHeader &header) {
325*101d251dSrobert   uint32_t fileclass = header.e_ident[EI_CLASS];
326*101d251dSrobert   switch (fileclass) {
327*101d251dSrobert   case llvm::ELF::ELFCLASS32:
328*101d251dSrobert     return ArchSpec::eLoongArchSubType_loongarch32;
329*101d251dSrobert   case llvm::ELF::ELFCLASS64:
330*101d251dSrobert     return ArchSpec::eLoongArchSubType_loongarch64;
331*101d251dSrobert   default:
332*101d251dSrobert     return ArchSpec::eLoongArchSubType_unknown;
333*101d251dSrobert   }
334*101d251dSrobert }
335*101d251dSrobert 
subTypeFromElfHeader(const elf::ELFHeader & header)336061da546Spatrick static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) {
337061da546Spatrick   if (header.e_machine == llvm::ELF::EM_MIPS)
338061da546Spatrick     return mipsVariantFromElfFlags(header);
339*101d251dSrobert   else if (header.e_machine == llvm::ELF::EM_PPC64)
340*101d251dSrobert     return ppc64VariantFromElfFlags(header);
341a0747c9fSpatrick   else if (header.e_machine == llvm::ELF::EM_RISCV)
342a0747c9fSpatrick     return riscvVariantFromElfFlags(header);
343*101d251dSrobert   else if (header.e_machine == llvm::ELF::EM_LOONGARCH)
344*101d251dSrobert     return loongarchVariantFromElfFlags(header);
345061da546Spatrick 
346061da546Spatrick   return LLDB_INVALID_CPUTYPE;
347061da546Spatrick }
348061da546Spatrick 
349061da546Spatrick char ObjectFileELF::ID;
350061da546Spatrick 
351061da546Spatrick // Arbitrary constant used as UUID prefix for core files.
352061da546Spatrick const uint32_t ObjectFileELF::g_core_uuid_magic(0xE210C);
353061da546Spatrick 
354061da546Spatrick // Static methods.
Initialize()355061da546Spatrick void ObjectFileELF::Initialize() {
356061da546Spatrick   PluginManager::RegisterPlugin(GetPluginNameStatic(),
357061da546Spatrick                                 GetPluginDescriptionStatic(), CreateInstance,
358061da546Spatrick                                 CreateMemoryInstance, GetModuleSpecifications);
359061da546Spatrick }
360061da546Spatrick 
Terminate()361061da546Spatrick void ObjectFileELF::Terminate() {
362061da546Spatrick   PluginManager::UnregisterPlugin(CreateInstance);
363061da546Spatrick }
364061da546Spatrick 
CreateInstance(const lldb::ModuleSP & module_sp,DataBufferSP data_sp,lldb::offset_t data_offset,const lldb_private::FileSpec * file,lldb::offset_t file_offset,lldb::offset_t length)365061da546Spatrick ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
366*101d251dSrobert                                           DataBufferSP data_sp,
367061da546Spatrick                                           lldb::offset_t data_offset,
368061da546Spatrick                                           const lldb_private::FileSpec *file,
369061da546Spatrick                                           lldb::offset_t file_offset,
370061da546Spatrick                                           lldb::offset_t length) {
371*101d251dSrobert   bool mapped_writable = false;
372061da546Spatrick   if (!data_sp) {
373*101d251dSrobert     data_sp = MapFileDataWritable(*file, length, file_offset);
374061da546Spatrick     if (!data_sp)
375061da546Spatrick       return nullptr;
376061da546Spatrick     data_offset = 0;
377*101d251dSrobert     mapped_writable = true;
378061da546Spatrick   }
379061da546Spatrick 
380061da546Spatrick   assert(data_sp);
381061da546Spatrick 
382061da546Spatrick   if (data_sp->GetByteSize() <= (llvm::ELF::EI_NIDENT + data_offset))
383061da546Spatrick     return nullptr;
384061da546Spatrick 
385061da546Spatrick   const uint8_t *magic = data_sp->GetBytes() + data_offset;
386061da546Spatrick   if (!ELFHeader::MagicBytesMatch(magic))
387061da546Spatrick     return nullptr;
388061da546Spatrick 
389061da546Spatrick   // Update the data to contain the entire file if it doesn't already
390061da546Spatrick   if (data_sp->GetByteSize() < length) {
391*101d251dSrobert     data_sp = MapFileDataWritable(*file, length, file_offset);
392061da546Spatrick     if (!data_sp)
393061da546Spatrick       return nullptr;
394061da546Spatrick     data_offset = 0;
395*101d251dSrobert     mapped_writable = true;
396*101d251dSrobert     magic = data_sp->GetBytes();
397*101d251dSrobert   }
398*101d251dSrobert 
399*101d251dSrobert   // If we didn't map the data as writable take ownership of the buffer.
400*101d251dSrobert   if (!mapped_writable) {
401*101d251dSrobert     data_sp = std::make_shared<DataBufferHeap>(data_sp->GetBytes(),
402*101d251dSrobert                                                data_sp->GetByteSize());
403*101d251dSrobert     data_offset = 0;
404061da546Spatrick     magic = data_sp->GetBytes();
405061da546Spatrick   }
406061da546Spatrick 
407061da546Spatrick   unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
408061da546Spatrick   if (address_size == 4 || address_size == 8) {
409061da546Spatrick     std::unique_ptr<ObjectFileELF> objfile_up(new ObjectFileELF(
410061da546Spatrick         module_sp, data_sp, data_offset, file, file_offset, length));
411061da546Spatrick     ArchSpec spec = objfile_up->GetArchitecture();
412061da546Spatrick     if (spec && objfile_up->SetModulesArchitecture(spec))
413061da546Spatrick       return objfile_up.release();
414061da546Spatrick   }
415061da546Spatrick 
416061da546Spatrick   return nullptr;
417061da546Spatrick }
418061da546Spatrick 
CreateMemoryInstance(const lldb::ModuleSP & module_sp,WritableDataBufferSP data_sp,const lldb::ProcessSP & process_sp,lldb::addr_t header_addr)419061da546Spatrick ObjectFile *ObjectFileELF::CreateMemoryInstance(
420*101d251dSrobert     const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp,
421061da546Spatrick     const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) {
422061da546Spatrick   if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT)) {
423061da546Spatrick     const uint8_t *magic = data_sp->GetBytes();
424061da546Spatrick     if (ELFHeader::MagicBytesMatch(magic)) {
425061da546Spatrick       unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
426061da546Spatrick       if (address_size == 4 || address_size == 8) {
427061da546Spatrick         std::unique_ptr<ObjectFileELF> objfile_up(
428061da546Spatrick             new ObjectFileELF(module_sp, data_sp, process_sp, header_addr));
429061da546Spatrick         ArchSpec spec = objfile_up->GetArchitecture();
430061da546Spatrick         if (spec && objfile_up->SetModulesArchitecture(spec))
431061da546Spatrick           return objfile_up.release();
432061da546Spatrick       }
433061da546Spatrick     }
434061da546Spatrick   }
435061da546Spatrick   return nullptr;
436061da546Spatrick }
437061da546Spatrick 
MagicBytesMatch(DataBufferSP & data_sp,lldb::addr_t data_offset,lldb::addr_t data_length)438061da546Spatrick bool ObjectFileELF::MagicBytesMatch(DataBufferSP &data_sp,
439061da546Spatrick                                     lldb::addr_t data_offset,
440061da546Spatrick                                     lldb::addr_t data_length) {
441061da546Spatrick   if (data_sp &&
442061da546Spatrick       data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset)) {
443061da546Spatrick     const uint8_t *magic = data_sp->GetBytes() + data_offset;
444061da546Spatrick     return ELFHeader::MagicBytesMatch(magic);
445061da546Spatrick   }
446061da546Spatrick   return false;
447061da546Spatrick }
448061da546Spatrick 
calc_crc32(uint32_t init,const DataExtractor & data)449061da546Spatrick static uint32_t calc_crc32(uint32_t init, const DataExtractor &data) {
450*101d251dSrobert   return llvm::crc32(init,
451*101d251dSrobert                      llvm::ArrayRef(data.GetDataStart(), data.GetByteSize()));
452061da546Spatrick }
453061da546Spatrick 
CalculateELFNotesSegmentsCRC32(const ProgramHeaderColl & program_headers,DataExtractor & object_data)454061da546Spatrick uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32(
455061da546Spatrick     const ProgramHeaderColl &program_headers, DataExtractor &object_data) {
456061da546Spatrick 
457061da546Spatrick   uint32_t core_notes_crc = 0;
458061da546Spatrick 
459061da546Spatrick   for (const ELFProgramHeader &H : program_headers) {
460061da546Spatrick     if (H.p_type == llvm::ELF::PT_NOTE) {
461061da546Spatrick       const elf_off ph_offset = H.p_offset;
462061da546Spatrick       const size_t ph_size = H.p_filesz;
463061da546Spatrick 
464061da546Spatrick       DataExtractor segment_data;
465061da546Spatrick       if (segment_data.SetData(object_data, ph_offset, ph_size) != ph_size) {
466061da546Spatrick         // The ELF program header contained incorrect data, probably corefile
467061da546Spatrick         // is incomplete or corrupted.
468061da546Spatrick         break;
469061da546Spatrick       }
470061da546Spatrick 
471061da546Spatrick       core_notes_crc = calc_crc32(core_notes_crc, segment_data);
472061da546Spatrick     }
473061da546Spatrick   }
474061da546Spatrick 
475061da546Spatrick   return core_notes_crc;
476061da546Spatrick }
477061da546Spatrick 
OSABIAsCString(unsigned char osabi_byte)478061da546Spatrick static const char *OSABIAsCString(unsigned char osabi_byte) {
479061da546Spatrick #define _MAKE_OSABI_CASE(x)                                                    \
480061da546Spatrick   case x:                                                                      \
481061da546Spatrick     return #x
482061da546Spatrick   switch (osabi_byte) {
483061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_NONE);
484061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_HPUX);
485061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_NETBSD);
486061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_GNU);
487061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_HURD);
488061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_SOLARIS);
489061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_AIX);
490061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_IRIX);
491061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_FREEBSD);
492061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_TRU64);
493061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_MODESTO);
494061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_OPENBSD);
495061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_OPENVMS);
496061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_NSK);
497061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_AROS);
498061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_FENIXOS);
499061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_C6000_ELFABI);
500061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_C6000_LINUX);
501061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_ARM);
502061da546Spatrick     _MAKE_OSABI_CASE(ELFOSABI_STANDALONE);
503061da546Spatrick   default:
504061da546Spatrick     return "<unknown-osabi>";
505061da546Spatrick   }
506061da546Spatrick #undef _MAKE_OSABI_CASE
507061da546Spatrick }
508061da546Spatrick 
509061da546Spatrick //
510061da546Spatrick // WARNING : This function is being deprecated
511061da546Spatrick // It's functionality has moved to ArchSpec::SetArchitecture This function is
512061da546Spatrick // only being kept to validate the move.
513061da546Spatrick //
514061da546Spatrick // TODO : Remove this function
GetOsFromOSABI(unsigned char osabi_byte,llvm::Triple::OSType & ostype)515061da546Spatrick static bool GetOsFromOSABI(unsigned char osabi_byte,
516061da546Spatrick                            llvm::Triple::OSType &ostype) {
517061da546Spatrick   switch (osabi_byte) {
518061da546Spatrick   case ELFOSABI_AIX:
519061da546Spatrick     ostype = llvm::Triple::OSType::AIX;
520061da546Spatrick     break;
521061da546Spatrick   case ELFOSABI_FREEBSD:
522061da546Spatrick     ostype = llvm::Triple::OSType::FreeBSD;
523061da546Spatrick     break;
524061da546Spatrick   case ELFOSABI_GNU:
525061da546Spatrick     ostype = llvm::Triple::OSType::Linux;
526061da546Spatrick     break;
527061da546Spatrick   case ELFOSABI_NETBSD:
528061da546Spatrick     ostype = llvm::Triple::OSType::NetBSD;
529061da546Spatrick     break;
530061da546Spatrick   case ELFOSABI_OPENBSD:
531061da546Spatrick     ostype = llvm::Triple::OSType::OpenBSD;
532061da546Spatrick     break;
533061da546Spatrick   case ELFOSABI_SOLARIS:
534061da546Spatrick     ostype = llvm::Triple::OSType::Solaris;
535061da546Spatrick     break;
536061da546Spatrick   default:
537061da546Spatrick     ostype = llvm::Triple::OSType::UnknownOS;
538061da546Spatrick   }
539061da546Spatrick   return ostype != llvm::Triple::OSType::UnknownOS;
540061da546Spatrick }
541061da546Spatrick 
GetModuleSpecifications(const lldb_private::FileSpec & file,lldb::DataBufferSP & data_sp,lldb::offset_t data_offset,lldb::offset_t file_offset,lldb::offset_t length,lldb_private::ModuleSpecList & specs)542061da546Spatrick size_t ObjectFileELF::GetModuleSpecifications(
543061da546Spatrick     const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
544061da546Spatrick     lldb::offset_t data_offset, lldb::offset_t file_offset,
545061da546Spatrick     lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
546*101d251dSrobert   Log *log = GetLog(LLDBLog::Modules);
547061da546Spatrick 
548061da546Spatrick   const size_t initial_count = specs.GetSize();
549061da546Spatrick 
550061da546Spatrick   if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
551061da546Spatrick     DataExtractor data;
552061da546Spatrick     data.SetData(data_sp);
553061da546Spatrick     elf::ELFHeader header;
554061da546Spatrick     lldb::offset_t header_offset = data_offset;
555061da546Spatrick     if (header.Parse(data, &header_offset)) {
556061da546Spatrick       if (data_sp) {
557061da546Spatrick         ModuleSpec spec(file);
558061da546Spatrick 
559061da546Spatrick         const uint32_t sub_type = subTypeFromElfHeader(header);
560061da546Spatrick         spec.GetArchitecture().SetArchitecture(
561061da546Spatrick             eArchTypeELF, header.e_machine, sub_type, header.e_ident[EI_OSABI]);
562061da546Spatrick 
563061da546Spatrick         if (spec.GetArchitecture().IsValid()) {
564061da546Spatrick           llvm::Triple::OSType ostype;
565061da546Spatrick           llvm::Triple::VendorType vendor;
566061da546Spatrick           llvm::Triple::OSType spec_ostype =
567061da546Spatrick               spec.GetArchitecture().GetTriple().getOS();
568061da546Spatrick 
569061da546Spatrick           LLDB_LOGF(log, "ObjectFileELF::%s file '%s' module OSABI: %s",
570061da546Spatrick                     __FUNCTION__, file.GetPath().c_str(),
571061da546Spatrick                     OSABIAsCString(header.e_ident[EI_OSABI]));
572061da546Spatrick 
573061da546Spatrick           // SetArchitecture should have set the vendor to unknown
574061da546Spatrick           vendor = spec.GetArchitecture().GetTriple().getVendor();
575061da546Spatrick           assert(vendor == llvm::Triple::UnknownVendor);
576061da546Spatrick           UNUSED_IF_ASSERT_DISABLED(vendor);
577061da546Spatrick 
578061da546Spatrick           //
579061da546Spatrick           // Validate it is ok to remove GetOsFromOSABI
580061da546Spatrick           GetOsFromOSABI(header.e_ident[EI_OSABI], ostype);
581061da546Spatrick           assert(spec_ostype == ostype);
582061da546Spatrick           if (spec_ostype != llvm::Triple::OSType::UnknownOS) {
583061da546Spatrick             LLDB_LOGF(log,
584061da546Spatrick                       "ObjectFileELF::%s file '%s' set ELF module OS type "
585061da546Spatrick                       "from ELF header OSABI.",
586061da546Spatrick                       __FUNCTION__, file.GetPath().c_str());
587061da546Spatrick           }
588061da546Spatrick 
589dda28197Spatrick           if (data_sp->GetByteSize() < length)
590061da546Spatrick             data_sp = MapFileData(file, -1, file_offset);
591061da546Spatrick           if (data_sp)
592061da546Spatrick             data.SetData(data_sp);
593061da546Spatrick           // In case there is header extension in the section #0, the header we
594061da546Spatrick           // parsed above could have sentinel values for e_phnum, e_shnum, and
595061da546Spatrick           // e_shstrndx.  In this case we need to reparse the header with a
596061da546Spatrick           // bigger data source to get the actual values.
597061da546Spatrick           if (header.HasHeaderExtension()) {
598061da546Spatrick             lldb::offset_t header_offset = data_offset;
599061da546Spatrick             header.Parse(data, &header_offset);
600061da546Spatrick           }
601061da546Spatrick 
602061da546Spatrick           uint32_t gnu_debuglink_crc = 0;
603061da546Spatrick           std::string gnu_debuglink_file;
604061da546Spatrick           SectionHeaderColl section_headers;
605061da546Spatrick           lldb_private::UUID &uuid = spec.GetUUID();
606061da546Spatrick 
607061da546Spatrick           GetSectionHeaderInfo(section_headers, data, header, uuid,
608061da546Spatrick                                gnu_debuglink_file, gnu_debuglink_crc,
609061da546Spatrick                                spec.GetArchitecture());
610061da546Spatrick 
611061da546Spatrick           llvm::Triple &spec_triple = spec.GetArchitecture().GetTriple();
612061da546Spatrick 
613061da546Spatrick           LLDB_LOGF(log,
614061da546Spatrick                     "ObjectFileELF::%s file '%s' module set to triple: %s "
615061da546Spatrick                     "(architecture %s)",
616061da546Spatrick                     __FUNCTION__, file.GetPath().c_str(),
617061da546Spatrick                     spec_triple.getTriple().c_str(),
618061da546Spatrick                     spec.GetArchitecture().GetArchitectureName());
619061da546Spatrick 
620061da546Spatrick           if (!uuid.IsValid()) {
621061da546Spatrick             uint32_t core_notes_crc = 0;
622061da546Spatrick 
623061da546Spatrick             if (!gnu_debuglink_crc) {
624a0747c9fSpatrick               LLDB_SCOPED_TIMERF(
625061da546Spatrick                   "Calculating module crc32 %s with size %" PRIu64 " KiB",
626061da546Spatrick                   file.GetLastPathComponent().AsCString(),
627dda28197Spatrick                   (length - file_offset) / 1024);
628061da546Spatrick 
629061da546Spatrick               // For core files - which usually don't happen to have a
630061da546Spatrick               // gnu_debuglink, and are pretty bulky - calculating whole
631061da546Spatrick               // contents crc32 would be too much of luxury.  Thus we will need
632061da546Spatrick               // to fallback to something simpler.
633061da546Spatrick               if (header.e_type == llvm::ELF::ET_CORE) {
634061da546Spatrick                 ProgramHeaderColl program_headers;
635061da546Spatrick                 GetProgramHeaderInfo(program_headers, data, header);
636061da546Spatrick 
637061da546Spatrick                 core_notes_crc =
638061da546Spatrick                     CalculateELFNotesSegmentsCRC32(program_headers, data);
639061da546Spatrick               } else {
640061da546Spatrick                 gnu_debuglink_crc = calc_crc32(0, data);
641061da546Spatrick               }
642061da546Spatrick             }
643061da546Spatrick             using u32le = llvm::support::ulittle32_t;
644061da546Spatrick             if (gnu_debuglink_crc) {
645061da546Spatrick               // Use 4 bytes of crc from the .gnu_debuglink section.
646061da546Spatrick               u32le data(gnu_debuglink_crc);
647*101d251dSrobert               uuid = UUID(&data, sizeof(data));
648061da546Spatrick             } else if (core_notes_crc) {
649061da546Spatrick               // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make
650061da546Spatrick               // it look different form .gnu_debuglink crc followed by 4 bytes
651061da546Spatrick               // of note segments crc.
652061da546Spatrick               u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)};
653*101d251dSrobert               uuid = UUID(data, sizeof(data));
654061da546Spatrick             }
655061da546Spatrick           }
656061da546Spatrick 
657061da546Spatrick           specs.Append(spec);
658061da546Spatrick         }
659061da546Spatrick       }
660061da546Spatrick     }
661061da546Spatrick   }
662061da546Spatrick 
663061da546Spatrick   return specs.GetSize() - initial_count;
664061da546Spatrick }
665061da546Spatrick 
666061da546Spatrick // ObjectFile protocol
667061da546Spatrick 
ObjectFileELF(const lldb::ModuleSP & module_sp,DataBufferSP data_sp,lldb::offset_t data_offset,const FileSpec * file,lldb::offset_t file_offset,lldb::offset_t length)668061da546Spatrick ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
669*101d251dSrobert                              DataBufferSP data_sp, lldb::offset_t data_offset,
670061da546Spatrick                              const FileSpec *file, lldb::offset_t file_offset,
671061da546Spatrick                              lldb::offset_t length)
672061da546Spatrick     : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset) {
673061da546Spatrick   if (file)
674061da546Spatrick     m_file = *file;
675061da546Spatrick }
676061da546Spatrick 
ObjectFileELF(const lldb::ModuleSP & module_sp,DataBufferSP header_data_sp,const lldb::ProcessSP & process_sp,addr_t header_addr)677061da546Spatrick ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
678*101d251dSrobert                              DataBufferSP header_data_sp,
679061da546Spatrick                              const lldb::ProcessSP &process_sp,
680061da546Spatrick                              addr_t header_addr)
681061da546Spatrick     : ObjectFile(module_sp, process_sp, header_addr, header_data_sp) {}
682061da546Spatrick 
IsExecutable() const683061da546Spatrick bool ObjectFileELF::IsExecutable() const {
684061da546Spatrick   return ((m_header.e_type & ET_EXEC) != 0) || (m_header.e_entry != 0);
685061da546Spatrick }
686061da546Spatrick 
SetLoadAddress(Target & target,lldb::addr_t value,bool value_is_offset)687061da546Spatrick bool ObjectFileELF::SetLoadAddress(Target &target, lldb::addr_t value,
688061da546Spatrick                                    bool value_is_offset) {
689061da546Spatrick   ModuleSP module_sp = GetModule();
690061da546Spatrick   if (module_sp) {
691061da546Spatrick     size_t num_loaded_sections = 0;
692061da546Spatrick     SectionList *section_list = GetSectionList();
693061da546Spatrick     if (section_list) {
694061da546Spatrick       if (!value_is_offset) {
695061da546Spatrick         addr_t base = GetBaseAddress().GetFileAddress();
696061da546Spatrick         if (base == LLDB_INVALID_ADDRESS)
697061da546Spatrick           return false;
698061da546Spatrick         value -= base;
699061da546Spatrick       }
700061da546Spatrick 
701061da546Spatrick       const size_t num_sections = section_list->GetSize();
702061da546Spatrick       size_t sect_idx = 0;
703061da546Spatrick 
704061da546Spatrick       for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
705061da546Spatrick         // Iterate through the object file sections to find all of the sections
706061da546Spatrick         // that have SHF_ALLOC in their flag bits.
707061da546Spatrick         SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
708061da546Spatrick         if (section_sp->Test(SHF_ALLOC) ||
709061da546Spatrick             section_sp->GetType() == eSectionTypeContainer) {
710061da546Spatrick           lldb::addr_t load_addr = section_sp->GetFileAddress();
711061da546Spatrick           // We don't want to update the load address of a section with type
712061da546Spatrick           // eSectionTypeAbsoluteAddress as they already have the absolute load
713061da546Spatrick           // address already specified
714061da546Spatrick           if (section_sp->GetType() != eSectionTypeAbsoluteAddress)
715061da546Spatrick             load_addr += value;
716061da546Spatrick 
717061da546Spatrick           // On 32-bit systems the load address have to fit into 4 bytes. The
718061da546Spatrick           // rest of the bytes are the overflow from the addition.
719061da546Spatrick           if (GetAddressByteSize() == 4)
720061da546Spatrick             load_addr &= 0xFFFFFFFF;
721061da546Spatrick 
722061da546Spatrick           if (target.GetSectionLoadList().SetSectionLoadAddress(section_sp,
723061da546Spatrick                                                                 load_addr))
724061da546Spatrick             ++num_loaded_sections;
725061da546Spatrick         }
726061da546Spatrick       }
727061da546Spatrick       return num_loaded_sections > 0;
728061da546Spatrick     }
729061da546Spatrick   }
730061da546Spatrick   return false;
731061da546Spatrick }
732061da546Spatrick 
GetByteOrder() const733061da546Spatrick ByteOrder ObjectFileELF::GetByteOrder() const {
734061da546Spatrick   if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
735061da546Spatrick     return eByteOrderBig;
736061da546Spatrick   if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
737061da546Spatrick     return eByteOrderLittle;
738061da546Spatrick   return eByteOrderInvalid;
739061da546Spatrick }
740061da546Spatrick 
GetAddressByteSize() const741061da546Spatrick uint32_t ObjectFileELF::GetAddressByteSize() const {
742061da546Spatrick   return m_data.GetAddressByteSize();
743061da546Spatrick }
744061da546Spatrick 
GetAddressClass(addr_t file_addr)745061da546Spatrick AddressClass ObjectFileELF::GetAddressClass(addr_t file_addr) {
746061da546Spatrick   Symtab *symtab = GetSymtab();
747061da546Spatrick   if (!symtab)
748061da546Spatrick     return AddressClass::eUnknown;
749061da546Spatrick 
750061da546Spatrick   // The address class is determined based on the symtab. Ask it from the
751061da546Spatrick   // object file what contains the symtab information.
752061da546Spatrick   ObjectFile *symtab_objfile = symtab->GetObjectFile();
753061da546Spatrick   if (symtab_objfile != nullptr && symtab_objfile != this)
754061da546Spatrick     return symtab_objfile->GetAddressClass(file_addr);
755061da546Spatrick 
756061da546Spatrick   auto res = ObjectFile::GetAddressClass(file_addr);
757061da546Spatrick   if (res != AddressClass::eCode)
758061da546Spatrick     return res;
759061da546Spatrick 
760061da546Spatrick   auto ub = m_address_class_map.upper_bound(file_addr);
761061da546Spatrick   if (ub == m_address_class_map.begin()) {
762061da546Spatrick     // No entry in the address class map before the address. Return default
763061da546Spatrick     // address class for an address in a code section.
764061da546Spatrick     return AddressClass::eCode;
765061da546Spatrick   }
766061da546Spatrick 
767061da546Spatrick   // Move iterator to the address class entry preceding address
768061da546Spatrick   --ub;
769061da546Spatrick 
770061da546Spatrick   return ub->second;
771061da546Spatrick }
772061da546Spatrick 
SectionIndex(const SectionHeaderCollIter & I)773061da546Spatrick size_t ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I) {
774061da546Spatrick   return std::distance(m_section_headers.begin(), I);
775061da546Spatrick }
776061da546Spatrick 
SectionIndex(const SectionHeaderCollConstIter & I) const777061da546Spatrick size_t ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const {
778061da546Spatrick   return std::distance(m_section_headers.begin(), I);
779061da546Spatrick }
780061da546Spatrick 
ParseHeader()781061da546Spatrick bool ObjectFileELF::ParseHeader() {
782061da546Spatrick   lldb::offset_t offset = 0;
783061da546Spatrick   return m_header.Parse(m_data, &offset);
784061da546Spatrick }
785061da546Spatrick 
GetUUID()786061da546Spatrick UUID ObjectFileELF::GetUUID() {
787061da546Spatrick   // Need to parse the section list to get the UUIDs, so make sure that's been
788061da546Spatrick   // done.
789061da546Spatrick   if (!ParseSectionHeaders() && GetType() != ObjectFile::eTypeCoreFile)
790061da546Spatrick     return UUID();
791061da546Spatrick 
792061da546Spatrick   if (!m_uuid) {
793061da546Spatrick     using u32le = llvm::support::ulittle32_t;
794061da546Spatrick     if (GetType() == ObjectFile::eTypeCoreFile) {
795061da546Spatrick       uint32_t core_notes_crc = 0;
796061da546Spatrick 
797061da546Spatrick       if (!ParseProgramHeaders())
798061da546Spatrick         return UUID();
799061da546Spatrick 
800061da546Spatrick       core_notes_crc =
801061da546Spatrick           CalculateELFNotesSegmentsCRC32(m_program_headers, m_data);
802061da546Spatrick 
803061da546Spatrick       if (core_notes_crc) {
804061da546Spatrick         // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it
805061da546Spatrick         // look different form .gnu_debuglink crc - followed by 4 bytes of note
806061da546Spatrick         // segments crc.
807061da546Spatrick         u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)};
808*101d251dSrobert         m_uuid = UUID(data, sizeof(data));
809061da546Spatrick       }
810061da546Spatrick     } else {
811061da546Spatrick       if (!m_gnu_debuglink_crc)
812061da546Spatrick         m_gnu_debuglink_crc = calc_crc32(0, m_data);
813061da546Spatrick       if (m_gnu_debuglink_crc) {
814061da546Spatrick         // Use 4 bytes of crc from the .gnu_debuglink section.
815061da546Spatrick         u32le data(m_gnu_debuglink_crc);
816*101d251dSrobert         m_uuid = UUID(&data, sizeof(data));
817061da546Spatrick       }
818061da546Spatrick     }
819061da546Spatrick   }
820061da546Spatrick 
821061da546Spatrick   return m_uuid;
822061da546Spatrick }
823061da546Spatrick 
GetDebugLink()824*101d251dSrobert std::optional<FileSpec> ObjectFileELF::GetDebugLink() {
825061da546Spatrick   if (m_gnu_debuglink_file.empty())
826*101d251dSrobert     return std::nullopt;
827061da546Spatrick   return FileSpec(m_gnu_debuglink_file);
828061da546Spatrick }
829061da546Spatrick 
GetDependentModules(FileSpecList & files)830061da546Spatrick uint32_t ObjectFileELF::GetDependentModules(FileSpecList &files) {
831061da546Spatrick   size_t num_modules = ParseDependentModules();
832061da546Spatrick   uint32_t num_specs = 0;
833061da546Spatrick 
834061da546Spatrick   for (unsigned i = 0; i < num_modules; ++i) {
835061da546Spatrick     if (files.AppendIfUnique(m_filespec_up->GetFileSpecAtIndex(i)))
836061da546Spatrick       num_specs++;
837061da546Spatrick   }
838061da546Spatrick 
839061da546Spatrick   return num_specs;
840061da546Spatrick }
841061da546Spatrick 
GetImageInfoAddress(Target * target)842061da546Spatrick Address ObjectFileELF::GetImageInfoAddress(Target *target) {
843061da546Spatrick   if (!ParseDynamicSymbols())
844061da546Spatrick     return Address();
845061da546Spatrick 
846061da546Spatrick   SectionList *section_list = GetSectionList();
847061da546Spatrick   if (!section_list)
848061da546Spatrick     return Address();
849061da546Spatrick 
850061da546Spatrick   // Find the SHT_DYNAMIC (.dynamic) section.
851061da546Spatrick   SectionSP dynsym_section_sp(
852061da546Spatrick       section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true));
853061da546Spatrick   if (!dynsym_section_sp)
854061da546Spatrick     return Address();
855061da546Spatrick   assert(dynsym_section_sp->GetObjectFile() == this);
856061da546Spatrick 
857061da546Spatrick   user_id_t dynsym_id = dynsym_section_sp->GetID();
858061da546Spatrick   const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
859061da546Spatrick   if (!dynsym_hdr)
860061da546Spatrick     return Address();
861061da546Spatrick 
862061da546Spatrick   for (size_t i = 0; i < m_dynamic_symbols.size(); ++i) {
863061da546Spatrick     ELFDynamic &symbol = m_dynamic_symbols[i];
864061da546Spatrick 
865061da546Spatrick     if (symbol.d_tag == DT_DEBUG) {
866061da546Spatrick       // Compute the offset as the number of previous entries plus the size of
867061da546Spatrick       // d_tag.
868061da546Spatrick       addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
869061da546Spatrick       return Address(dynsym_section_sp, offset);
870061da546Spatrick     }
871061da546Spatrick     // MIPS executables uses DT_MIPS_RLD_MAP_REL to support PIE. DT_MIPS_RLD_MAP
872061da546Spatrick     // exists in non-PIE.
873061da546Spatrick     else if ((symbol.d_tag == DT_MIPS_RLD_MAP ||
874061da546Spatrick               symbol.d_tag == DT_MIPS_RLD_MAP_REL) &&
875061da546Spatrick              target) {
876061da546Spatrick       addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
877061da546Spatrick       addr_t dyn_base = dynsym_section_sp->GetLoadBaseAddress(target);
878061da546Spatrick       if (dyn_base == LLDB_INVALID_ADDRESS)
879061da546Spatrick         return Address();
880061da546Spatrick 
881061da546Spatrick       Status error;
882061da546Spatrick       if (symbol.d_tag == DT_MIPS_RLD_MAP) {
883061da546Spatrick         // DT_MIPS_RLD_MAP tag stores an absolute address of the debug pointer.
884061da546Spatrick         Address addr;
885a0747c9fSpatrick         if (target->ReadPointerFromMemory(dyn_base + offset, error, addr, true))
886061da546Spatrick           return addr;
887061da546Spatrick       }
888061da546Spatrick       if (symbol.d_tag == DT_MIPS_RLD_MAP_REL) {
889061da546Spatrick         // DT_MIPS_RLD_MAP_REL tag stores the offset to the debug pointer,
890061da546Spatrick         // relative to the address of the tag.
891061da546Spatrick         uint64_t rel_offset;
892061da546Spatrick         rel_offset = target->ReadUnsignedIntegerFromMemory(
893a0747c9fSpatrick             dyn_base + offset, GetAddressByteSize(), UINT64_MAX, error, true);
894061da546Spatrick         if (error.Success() && rel_offset != UINT64_MAX) {
895061da546Spatrick           Address addr;
896061da546Spatrick           addr_t debug_ptr_address =
897061da546Spatrick               dyn_base + (offset - GetAddressByteSize()) + rel_offset;
898061da546Spatrick           addr.SetOffset(debug_ptr_address);
899061da546Spatrick           return addr;
900061da546Spatrick         }
901061da546Spatrick       }
902061da546Spatrick     }
903061da546Spatrick   }
904061da546Spatrick 
905061da546Spatrick   return Address();
906061da546Spatrick }
907061da546Spatrick 
GetEntryPointAddress()908061da546Spatrick lldb_private::Address ObjectFileELF::GetEntryPointAddress() {
909061da546Spatrick   if (m_entry_point_address.IsValid())
910061da546Spatrick     return m_entry_point_address;
911061da546Spatrick 
912061da546Spatrick   if (!ParseHeader() || !IsExecutable())
913061da546Spatrick     return m_entry_point_address;
914061da546Spatrick 
915061da546Spatrick   SectionList *section_list = GetSectionList();
916061da546Spatrick   addr_t offset = m_header.e_entry;
917061da546Spatrick 
918061da546Spatrick   if (!section_list)
919061da546Spatrick     m_entry_point_address.SetOffset(offset);
920061da546Spatrick   else
921061da546Spatrick     m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
922061da546Spatrick   return m_entry_point_address;
923061da546Spatrick }
924061da546Spatrick 
GetBaseAddress()925061da546Spatrick Address ObjectFileELF::GetBaseAddress() {
926061da546Spatrick   for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) {
927061da546Spatrick     const ELFProgramHeader &H = EnumPHdr.value();
928061da546Spatrick     if (H.p_type != PT_LOAD)
929061da546Spatrick       continue;
930061da546Spatrick 
931061da546Spatrick     return Address(
932061da546Spatrick         GetSectionList()->FindSectionByID(SegmentID(EnumPHdr.index())), 0);
933061da546Spatrick   }
934061da546Spatrick   return LLDB_INVALID_ADDRESS;
935061da546Spatrick }
936061da546Spatrick 
937061da546Spatrick // ParseDependentModules
ParseDependentModules()938061da546Spatrick size_t ObjectFileELF::ParseDependentModules() {
939061da546Spatrick   if (m_filespec_up)
940061da546Spatrick     return m_filespec_up->GetSize();
941061da546Spatrick 
942dda28197Spatrick   m_filespec_up = std::make_unique<FileSpecList>();
943061da546Spatrick 
944061da546Spatrick   if (!ParseSectionHeaders())
945061da546Spatrick     return 0;
946061da546Spatrick 
947061da546Spatrick   SectionList *section_list = GetSectionList();
948061da546Spatrick   if (!section_list)
949061da546Spatrick     return 0;
950061da546Spatrick 
951061da546Spatrick   // Find the SHT_DYNAMIC section.
952061da546Spatrick   Section *dynsym =
953061da546Spatrick       section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true)
954061da546Spatrick           .get();
955061da546Spatrick   if (!dynsym)
956061da546Spatrick     return 0;
957061da546Spatrick   assert(dynsym->GetObjectFile() == this);
958061da546Spatrick 
959061da546Spatrick   const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex(dynsym->GetID());
960061da546Spatrick   if (!header)
961061da546Spatrick     return 0;
962061da546Spatrick   // sh_link: section header index of string table used by entries in the
963061da546Spatrick   // section.
964061da546Spatrick   Section *dynstr = section_list->FindSectionByID(header->sh_link).get();
965061da546Spatrick   if (!dynstr)
966061da546Spatrick     return 0;
967061da546Spatrick 
968061da546Spatrick   DataExtractor dynsym_data;
969061da546Spatrick   DataExtractor dynstr_data;
970061da546Spatrick   if (ReadSectionData(dynsym, dynsym_data) &&
971061da546Spatrick       ReadSectionData(dynstr, dynstr_data)) {
972061da546Spatrick     ELFDynamic symbol;
973061da546Spatrick     const lldb::offset_t section_size = dynsym_data.GetByteSize();
974061da546Spatrick     lldb::offset_t offset = 0;
975061da546Spatrick 
976061da546Spatrick     // The only type of entries we are concerned with are tagged DT_NEEDED,
977061da546Spatrick     // yielding the name of a required library.
978061da546Spatrick     while (offset < section_size) {
979061da546Spatrick       if (!symbol.Parse(dynsym_data, &offset))
980061da546Spatrick         break;
981061da546Spatrick 
982061da546Spatrick       if (symbol.d_tag != DT_NEEDED)
983061da546Spatrick         continue;
984061da546Spatrick 
985061da546Spatrick       uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
986061da546Spatrick       const char *lib_name = dynstr_data.PeekCStr(str_index);
987061da546Spatrick       FileSpec file_spec(lib_name);
988061da546Spatrick       FileSystem::Instance().Resolve(file_spec);
989061da546Spatrick       m_filespec_up->Append(file_spec);
990061da546Spatrick     }
991061da546Spatrick   }
992061da546Spatrick 
993061da546Spatrick   return m_filespec_up->GetSize();
994061da546Spatrick }
995061da546Spatrick 
996061da546Spatrick // GetProgramHeaderInfo
GetProgramHeaderInfo(ProgramHeaderColl & program_headers,DataExtractor & object_data,const ELFHeader & header)997061da546Spatrick size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
998061da546Spatrick                                            DataExtractor &object_data,
999061da546Spatrick                                            const ELFHeader &header) {
1000061da546Spatrick   // We have already parsed the program headers
1001061da546Spatrick   if (!program_headers.empty())
1002061da546Spatrick     return program_headers.size();
1003061da546Spatrick 
1004061da546Spatrick   // If there are no program headers to read we are done.
1005061da546Spatrick   if (header.e_phnum == 0)
1006061da546Spatrick     return 0;
1007061da546Spatrick 
1008061da546Spatrick   program_headers.resize(header.e_phnum);
1009061da546Spatrick   if (program_headers.size() != header.e_phnum)
1010061da546Spatrick     return 0;
1011061da546Spatrick 
1012061da546Spatrick   const size_t ph_size = header.e_phnum * header.e_phentsize;
1013061da546Spatrick   const elf_off ph_offset = header.e_phoff;
1014061da546Spatrick   DataExtractor data;
1015061da546Spatrick   if (data.SetData(object_data, ph_offset, ph_size) != ph_size)
1016061da546Spatrick     return 0;
1017061da546Spatrick 
1018061da546Spatrick   uint32_t idx;
1019061da546Spatrick   lldb::offset_t offset;
1020061da546Spatrick   for (idx = 0, offset = 0; idx < header.e_phnum; ++idx) {
1021061da546Spatrick     if (!program_headers[idx].Parse(data, &offset))
1022061da546Spatrick       break;
1023061da546Spatrick   }
1024061da546Spatrick 
1025061da546Spatrick   if (idx < program_headers.size())
1026061da546Spatrick     program_headers.resize(idx);
1027061da546Spatrick 
1028061da546Spatrick   return program_headers.size();
1029061da546Spatrick }
1030061da546Spatrick 
1031061da546Spatrick // ParseProgramHeaders
ParseProgramHeaders()1032061da546Spatrick bool ObjectFileELF::ParseProgramHeaders() {
1033061da546Spatrick   return GetProgramHeaderInfo(m_program_headers, m_data, m_header) != 0;
1034061da546Spatrick }
1035061da546Spatrick 
1036061da546Spatrick lldb_private::Status
RefineModuleDetailsFromNote(lldb_private::DataExtractor & data,lldb_private::ArchSpec & arch_spec,lldb_private::UUID & uuid)1037061da546Spatrick ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
1038061da546Spatrick                                            lldb_private::ArchSpec &arch_spec,
1039061da546Spatrick                                            lldb_private::UUID &uuid) {
1040*101d251dSrobert   Log *log = GetLog(LLDBLog::Modules);
1041061da546Spatrick   Status error;
1042061da546Spatrick 
1043061da546Spatrick   lldb::offset_t offset = 0;
1044061da546Spatrick 
1045061da546Spatrick   while (true) {
1046061da546Spatrick     // Parse the note header.  If this fails, bail out.
1047061da546Spatrick     const lldb::offset_t note_offset = offset;
1048061da546Spatrick     ELFNote note = ELFNote();
1049061da546Spatrick     if (!note.Parse(data, &offset)) {
1050061da546Spatrick       // We're done.
1051061da546Spatrick       return error;
1052061da546Spatrick     }
1053061da546Spatrick 
1054061da546Spatrick     LLDB_LOGF(log, "ObjectFileELF::%s parsing note name='%s', type=%" PRIu32,
1055061da546Spatrick               __FUNCTION__, note.n_name.c_str(), note.n_type);
1056061da546Spatrick 
1057061da546Spatrick     // Process FreeBSD ELF notes.
1058061da546Spatrick     if ((note.n_name == LLDB_NT_OWNER_FREEBSD) &&
1059061da546Spatrick         (note.n_type == LLDB_NT_FREEBSD_ABI_TAG) &&
1060061da546Spatrick         (note.n_descsz == LLDB_NT_FREEBSD_ABI_SIZE)) {
1061061da546Spatrick       // Pull out the min version info.
1062061da546Spatrick       uint32_t version_info;
1063061da546Spatrick       if (data.GetU32(&offset, &version_info, 1) == nullptr) {
1064061da546Spatrick         error.SetErrorString("failed to read FreeBSD ABI note payload");
1065061da546Spatrick         return error;
1066061da546Spatrick       }
1067061da546Spatrick 
1068061da546Spatrick       // Convert the version info into a major/minor number.
1069061da546Spatrick       const uint32_t version_major = version_info / 100000;
1070061da546Spatrick       const uint32_t version_minor = (version_info / 1000) % 100;
1071061da546Spatrick 
1072061da546Spatrick       char os_name[32];
1073061da546Spatrick       snprintf(os_name, sizeof(os_name), "freebsd%" PRIu32 ".%" PRIu32,
1074061da546Spatrick                version_major, version_minor);
1075061da546Spatrick 
1076061da546Spatrick       // Set the elf OS version to FreeBSD.  Also clear the vendor.
1077061da546Spatrick       arch_spec.GetTriple().setOSName(os_name);
1078061da546Spatrick       arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
1079061da546Spatrick 
1080061da546Spatrick       LLDB_LOGF(log,
1081061da546Spatrick                 "ObjectFileELF::%s detected FreeBSD %" PRIu32 ".%" PRIu32
1082061da546Spatrick                 ".%" PRIu32,
1083061da546Spatrick                 __FUNCTION__, version_major, version_minor,
1084061da546Spatrick                 static_cast<uint32_t>(version_info % 1000));
1085061da546Spatrick     }
1086061da546Spatrick     // Process GNU ELF notes.
1087061da546Spatrick     else if (note.n_name == LLDB_NT_OWNER_GNU) {
1088061da546Spatrick       switch (note.n_type) {
1089061da546Spatrick       case LLDB_NT_GNU_ABI_TAG:
1090061da546Spatrick         if (note.n_descsz == LLDB_NT_GNU_ABI_SIZE) {
1091061da546Spatrick           // Pull out the min OS version supporting the ABI.
1092061da546Spatrick           uint32_t version_info[4];
1093061da546Spatrick           if (data.GetU32(&offset, &version_info[0], note.n_descsz / 4) ==
1094061da546Spatrick               nullptr) {
1095061da546Spatrick             error.SetErrorString("failed to read GNU ABI note payload");
1096061da546Spatrick             return error;
1097061da546Spatrick           }
1098061da546Spatrick 
1099061da546Spatrick           // Set the OS per the OS field.
1100061da546Spatrick           switch (version_info[0]) {
1101061da546Spatrick           case LLDB_NT_GNU_ABI_OS_LINUX:
1102061da546Spatrick             arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
1103061da546Spatrick             arch_spec.GetTriple().setVendor(
1104061da546Spatrick                 llvm::Triple::VendorType::UnknownVendor);
1105061da546Spatrick             LLDB_LOGF(log,
1106061da546Spatrick                       "ObjectFileELF::%s detected Linux, min version %" PRIu32
1107061da546Spatrick                       ".%" PRIu32 ".%" PRIu32,
1108061da546Spatrick                       __FUNCTION__, version_info[1], version_info[2],
1109061da546Spatrick                       version_info[3]);
1110061da546Spatrick             // FIXME we have the minimal version number, we could be propagating
1111061da546Spatrick             // that.  version_info[1] = OS Major, version_info[2] = OS Minor,
1112061da546Spatrick             // version_info[3] = Revision.
1113061da546Spatrick             break;
1114061da546Spatrick           case LLDB_NT_GNU_ABI_OS_HURD:
1115061da546Spatrick             arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS);
1116061da546Spatrick             arch_spec.GetTriple().setVendor(
1117061da546Spatrick                 llvm::Triple::VendorType::UnknownVendor);
1118061da546Spatrick             LLDB_LOGF(log,
1119061da546Spatrick                       "ObjectFileELF::%s detected Hurd (unsupported), min "
1120061da546Spatrick                       "version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
1121061da546Spatrick                       __FUNCTION__, version_info[1], version_info[2],
1122061da546Spatrick                       version_info[3]);
1123061da546Spatrick             break;
1124061da546Spatrick           case LLDB_NT_GNU_ABI_OS_SOLARIS:
1125061da546Spatrick             arch_spec.GetTriple().setOS(llvm::Triple::OSType::Solaris);
1126061da546Spatrick             arch_spec.GetTriple().setVendor(
1127061da546Spatrick                 llvm::Triple::VendorType::UnknownVendor);
1128061da546Spatrick             LLDB_LOGF(log,
1129061da546Spatrick                       "ObjectFileELF::%s detected Solaris, min version %" PRIu32
1130061da546Spatrick                       ".%" PRIu32 ".%" PRIu32,
1131061da546Spatrick                       __FUNCTION__, version_info[1], version_info[2],
1132061da546Spatrick                       version_info[3]);
1133061da546Spatrick             break;
1134061da546Spatrick           default:
1135061da546Spatrick             LLDB_LOGF(log,
1136061da546Spatrick                       "ObjectFileELF::%s unrecognized OS in note, id %" PRIu32
1137061da546Spatrick                       ", min version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
1138061da546Spatrick                       __FUNCTION__, version_info[0], version_info[1],
1139061da546Spatrick                       version_info[2], version_info[3]);
1140061da546Spatrick             break;
1141061da546Spatrick           }
1142061da546Spatrick         }
1143061da546Spatrick         break;
1144061da546Spatrick 
1145061da546Spatrick       case LLDB_NT_GNU_BUILD_ID_TAG:
1146061da546Spatrick         // Only bother processing this if we don't already have the uuid set.
1147061da546Spatrick         if (!uuid.IsValid()) {
1148061da546Spatrick           // 16 bytes is UUID|MD5, 20 bytes is SHA1. Other linkers may produce a
1149061da546Spatrick           // build-id of a different length. Accept it as long as it's at least
1150061da546Spatrick           // 4 bytes as it will be better than our own crc32.
1151061da546Spatrick           if (note.n_descsz >= 4) {
1152061da546Spatrick             if (const uint8_t *buf = data.PeekData(offset, note.n_descsz)) {
1153061da546Spatrick               // Save the build id as the UUID for the module.
1154*101d251dSrobert               uuid = UUID(buf, note.n_descsz);
1155061da546Spatrick             } else {
1156061da546Spatrick               error.SetErrorString("failed to read GNU_BUILD_ID note payload");
1157061da546Spatrick               return error;
1158061da546Spatrick             }
1159061da546Spatrick           }
1160061da546Spatrick         }
1161061da546Spatrick         break;
1162061da546Spatrick       }
1163061da546Spatrick       if (arch_spec.IsMIPS() &&
1164061da546Spatrick           arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS)
1165061da546Spatrick         // The note.n_name == LLDB_NT_OWNER_GNU is valid for Linux platform
1166061da546Spatrick         arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
1167061da546Spatrick     }
1168061da546Spatrick     // Process NetBSD ELF executables and shared libraries
1169061da546Spatrick     else if ((note.n_name == LLDB_NT_OWNER_NETBSD) &&
1170061da546Spatrick              (note.n_type == LLDB_NT_NETBSD_IDENT_TAG) &&
1171061da546Spatrick              (note.n_descsz == LLDB_NT_NETBSD_IDENT_DESCSZ) &&
1172061da546Spatrick              (note.n_namesz == LLDB_NT_NETBSD_IDENT_NAMESZ)) {
1173061da546Spatrick       // Pull out the version info.
1174061da546Spatrick       uint32_t version_info;
1175061da546Spatrick       if (data.GetU32(&offset, &version_info, 1) == nullptr) {
1176061da546Spatrick         error.SetErrorString("failed to read NetBSD ABI note payload");
1177061da546Spatrick         return error;
1178061da546Spatrick       }
1179061da546Spatrick       // Convert the version info into a major/minor/patch number.
1180061da546Spatrick       //     #define __NetBSD_Version__ MMmmrrpp00
1181061da546Spatrick       //
1182061da546Spatrick       //     M = major version
1183061da546Spatrick       //     m = minor version; a minor number of 99 indicates current.
1184061da546Spatrick       //     r = 0 (since NetBSD 3.0 not used)
1185061da546Spatrick       //     p = patchlevel
1186061da546Spatrick       const uint32_t version_major = version_info / 100000000;
1187061da546Spatrick       const uint32_t version_minor = (version_info % 100000000) / 1000000;
1188061da546Spatrick       const uint32_t version_patch = (version_info % 10000) / 100;
1189061da546Spatrick       // Set the elf OS version to NetBSD.  Also clear the vendor.
1190061da546Spatrick       arch_spec.GetTriple().setOSName(
1191061da546Spatrick           llvm::formatv("netbsd{0}.{1}.{2}", version_major, version_minor,
1192061da546Spatrick                         version_patch).str());
1193061da546Spatrick       arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
1194061da546Spatrick     }
1195061da546Spatrick     // Process NetBSD ELF core(5) notes
1196061da546Spatrick     else if ((note.n_name == LLDB_NT_OWNER_NETBSDCORE) &&
1197061da546Spatrick              (note.n_type == LLDB_NT_NETBSD_PROCINFO)) {
1198061da546Spatrick       // Set the elf OS version to NetBSD.  Also clear the vendor.
1199061da546Spatrick       arch_spec.GetTriple().setOS(llvm::Triple::OSType::NetBSD);
1200061da546Spatrick       arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
1201061da546Spatrick     }
1202061da546Spatrick     // Process OpenBSD ELF notes.
1203061da546Spatrick     else if (note.n_name == LLDB_NT_OWNER_OPENBSD) {
1204061da546Spatrick       // Set the elf OS version to OpenBSD.  Also clear the vendor.
1205061da546Spatrick       arch_spec.GetTriple().setOS(llvm::Triple::OSType::OpenBSD);
1206061da546Spatrick       arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
1207061da546Spatrick     } else if (note.n_name == LLDB_NT_OWNER_ANDROID) {
1208061da546Spatrick       arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
1209061da546Spatrick       arch_spec.GetTriple().setEnvironment(
1210061da546Spatrick           llvm::Triple::EnvironmentType::Android);
1211061da546Spatrick     } else if (note.n_name == LLDB_NT_OWNER_LINUX) {
1212061da546Spatrick       // This is sometimes found in core files and usually contains extended
1213061da546Spatrick       // register info
1214061da546Spatrick       arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
1215061da546Spatrick     } else if (note.n_name == LLDB_NT_OWNER_CORE) {
1216*101d251dSrobert       // Parse the NT_FILE to look for stuff in paths to shared libraries
1217*101d251dSrobert       // The contents look like this in a 64 bit ELF core file:
1218*101d251dSrobert       //
1219*101d251dSrobert       // count     = 0x000000000000000a (10)
1220*101d251dSrobert       // page_size = 0x0000000000001000 (4096)
1221*101d251dSrobert       // Index start              end                file_ofs           path
1222*101d251dSrobert       // ===== ------------------ ------------------ ------------------ -------------------------------------
1223*101d251dSrobert       // [  0] 0x0000000000401000 0x0000000000000000                    /tmp/a.out
1224*101d251dSrobert       // [  1] 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out
1225*101d251dSrobert       // [  2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out
1226*101d251dSrobert       // [  3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000 /lib/x86_64-linux-gnu/libc-2.19.so
1227*101d251dSrobert       // [  4] 0x00007fa79cba8000 0x00007fa79cda7000 0x00000000000001bb /lib/x86_64-linux-gnu/libc-2.19.so
1228*101d251dSrobert       // [  5] 0x00007fa79cda7000 0x00007fa79cdab000 0x00000000000001ba /lib/x86_64-linux-gnu/libc-2.19.so
1229*101d251dSrobert       // [  6] 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be /lib/x86_64-linux-gnu/libc-2.19.so
1230*101d251dSrobert       // [  7] 0x00007fa79cdb2000 0x00007fa79cdd5000 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so
1231*101d251dSrobert       // [  8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 /lib/x86_64-linux-gnu/ld-2.19.so
1232*101d251dSrobert       // [  9] 0x00007fa79cfd5000 0x00007fa79cfd6000 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so
1233*101d251dSrobert       //
1234*101d251dSrobert       // In the 32 bit ELFs the count, page_size, start, end, file_ofs are
1235*101d251dSrobert       // uint32_t.
1236*101d251dSrobert       //
1237*101d251dSrobert       // For reference: see readelf source code (in binutils).
1238061da546Spatrick       if (note.n_type == NT_FILE) {
1239061da546Spatrick         uint64_t count = data.GetAddress(&offset);
1240061da546Spatrick         const char *cstr;
1241061da546Spatrick         data.GetAddress(&offset); // Skip page size
1242061da546Spatrick         offset += count * 3 *
1243061da546Spatrick                   data.GetAddressByteSize(); // Skip all start/end/file_ofs
1244061da546Spatrick         for (size_t i = 0; i < count; ++i) {
1245061da546Spatrick           cstr = data.GetCStr(&offset);
1246061da546Spatrick           if (cstr == nullptr) {
1247061da546Spatrick             error.SetErrorStringWithFormat("ObjectFileELF::%s trying to read "
1248061da546Spatrick                                            "at an offset after the end "
1249061da546Spatrick                                            "(GetCStr returned nullptr)",
1250061da546Spatrick                                            __FUNCTION__);
1251061da546Spatrick             return error;
1252061da546Spatrick           }
1253061da546Spatrick           llvm::StringRef path(cstr);
1254061da546Spatrick           if (path.contains("/lib/x86_64-linux-gnu") || path.contains("/lib/i386-linux-gnu")) {
1255061da546Spatrick             arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
1256061da546Spatrick             break;
1257061da546Spatrick           }
1258061da546Spatrick         }
1259061da546Spatrick         if (arch_spec.IsMIPS() &&
1260061da546Spatrick             arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS)
1261061da546Spatrick           // In case of MIPSR6, the LLDB_NT_OWNER_GNU note is missing for some
1262061da546Spatrick           // cases (e.g. compile with -nostdlib) Hence set OS to Linux
1263061da546Spatrick           arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
1264061da546Spatrick       }
1265061da546Spatrick     }
1266061da546Spatrick 
1267061da546Spatrick     // Calculate the offset of the next note just in case "offset" has been
1268061da546Spatrick     // used to poke at the contents of the note data
1269061da546Spatrick     offset = note_offset + note.GetByteSize();
1270061da546Spatrick   }
1271061da546Spatrick 
1272061da546Spatrick   return error;
1273061da546Spatrick }
1274061da546Spatrick 
ParseARMAttributes(DataExtractor & data,uint64_t length,ArchSpec & arch_spec)1275061da546Spatrick void ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length,
1276061da546Spatrick                                        ArchSpec &arch_spec) {
1277061da546Spatrick   lldb::offset_t Offset = 0;
1278061da546Spatrick 
1279061da546Spatrick   uint8_t FormatVersion = data.GetU8(&Offset);
1280dda28197Spatrick   if (FormatVersion != llvm::ELFAttrs::Format_Version)
1281061da546Spatrick     return;
1282061da546Spatrick 
1283061da546Spatrick   Offset = Offset + sizeof(uint32_t); // Section Length
1284061da546Spatrick   llvm::StringRef VendorName = data.GetCStr(&Offset);
1285061da546Spatrick 
1286061da546Spatrick   if (VendorName != "aeabi")
1287061da546Spatrick     return;
1288061da546Spatrick 
1289061da546Spatrick   if (arch_spec.GetTriple().getEnvironment() ==
1290061da546Spatrick       llvm::Triple::UnknownEnvironment)
1291061da546Spatrick     arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI);
1292061da546Spatrick 
1293061da546Spatrick   while (Offset < length) {
1294061da546Spatrick     uint8_t Tag = data.GetU8(&Offset);
1295061da546Spatrick     uint32_t Size = data.GetU32(&Offset);
1296061da546Spatrick 
1297061da546Spatrick     if (Tag != llvm::ARMBuildAttrs::File || Size == 0)
1298061da546Spatrick       continue;
1299061da546Spatrick 
1300061da546Spatrick     while (Offset < length) {
1301061da546Spatrick       uint64_t Tag = data.GetULEB128(&Offset);
1302061da546Spatrick       switch (Tag) {
1303061da546Spatrick       default:
1304061da546Spatrick         if (Tag < 32)
1305061da546Spatrick           data.GetULEB128(&Offset);
1306061da546Spatrick         else if (Tag % 2 == 0)
1307061da546Spatrick           data.GetULEB128(&Offset);
1308061da546Spatrick         else
1309061da546Spatrick           data.GetCStr(&Offset);
1310061da546Spatrick 
1311061da546Spatrick         break;
1312061da546Spatrick 
1313061da546Spatrick       case llvm::ARMBuildAttrs::CPU_raw_name:
1314061da546Spatrick       case llvm::ARMBuildAttrs::CPU_name:
1315061da546Spatrick         data.GetCStr(&Offset);
1316061da546Spatrick 
1317061da546Spatrick         break;
1318061da546Spatrick 
1319061da546Spatrick       case llvm::ARMBuildAttrs::ABI_VFP_args: {
1320061da546Spatrick         uint64_t VFPArgs = data.GetULEB128(&Offset);
1321061da546Spatrick 
1322061da546Spatrick         if (VFPArgs == llvm::ARMBuildAttrs::BaseAAPCS) {
1323061da546Spatrick           if (arch_spec.GetTriple().getEnvironment() ==
1324061da546Spatrick                   llvm::Triple::UnknownEnvironment ||
1325061da546Spatrick               arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABIHF)
1326061da546Spatrick             arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI);
1327061da546Spatrick 
1328061da546Spatrick           arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float);
1329061da546Spatrick         } else if (VFPArgs == llvm::ARMBuildAttrs::HardFPAAPCS) {
1330061da546Spatrick           if (arch_spec.GetTriple().getEnvironment() ==
1331061da546Spatrick                   llvm::Triple::UnknownEnvironment ||
1332061da546Spatrick               arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABI)
1333061da546Spatrick             arch_spec.GetTriple().setEnvironment(llvm::Triple::EABIHF);
1334061da546Spatrick 
1335061da546Spatrick           arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float);
1336061da546Spatrick         }
1337061da546Spatrick 
1338061da546Spatrick         break;
1339061da546Spatrick       }
1340061da546Spatrick       }
1341061da546Spatrick     }
1342061da546Spatrick   }
1343061da546Spatrick }
1344061da546Spatrick 
1345061da546Spatrick // GetSectionHeaderInfo
GetSectionHeaderInfo(SectionHeaderColl & section_headers,DataExtractor & object_data,const elf::ELFHeader & header,lldb_private::UUID & uuid,std::string & gnu_debuglink_file,uint32_t & gnu_debuglink_crc,ArchSpec & arch_spec)1346061da546Spatrick size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl &section_headers,
1347061da546Spatrick                                            DataExtractor &object_data,
1348061da546Spatrick                                            const elf::ELFHeader &header,
1349061da546Spatrick                                            lldb_private::UUID &uuid,
1350061da546Spatrick                                            std::string &gnu_debuglink_file,
1351061da546Spatrick                                            uint32_t &gnu_debuglink_crc,
1352061da546Spatrick                                            ArchSpec &arch_spec) {
1353061da546Spatrick   // Don't reparse the section headers if we already did that.
1354061da546Spatrick   if (!section_headers.empty())
1355061da546Spatrick     return section_headers.size();
1356061da546Spatrick 
1357061da546Spatrick   // Only initialize the arch_spec to okay defaults if they're not already set.
1358061da546Spatrick   // We'll refine this with note data as we parse the notes.
1359061da546Spatrick   if (arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) {
1360061da546Spatrick     llvm::Triple::OSType ostype;
1361061da546Spatrick     llvm::Triple::OSType spec_ostype;
1362061da546Spatrick     const uint32_t sub_type = subTypeFromElfHeader(header);
1363061da546Spatrick     arch_spec.SetArchitecture(eArchTypeELF, header.e_machine, sub_type,
1364061da546Spatrick                               header.e_ident[EI_OSABI]);
1365061da546Spatrick 
1366061da546Spatrick     // Validate if it is ok to remove GetOsFromOSABI. Note, that now the OS is
1367061da546Spatrick     // determined based on EI_OSABI flag and the info extracted from ELF notes
1368061da546Spatrick     // (see RefineModuleDetailsFromNote). However in some cases that still
1369061da546Spatrick     // might be not enough: for example a shared library might not have any
1370061da546Spatrick     // notes at all and have EI_OSABI flag set to System V, as result the OS
1371061da546Spatrick     // will be set to UnknownOS.
1372061da546Spatrick     GetOsFromOSABI(header.e_ident[EI_OSABI], ostype);
1373061da546Spatrick     spec_ostype = arch_spec.GetTriple().getOS();
1374061da546Spatrick     assert(spec_ostype == ostype);
1375061da546Spatrick     UNUSED_IF_ASSERT_DISABLED(spec_ostype);
1376061da546Spatrick   }
1377061da546Spatrick 
1378061da546Spatrick   if (arch_spec.GetMachine() == llvm::Triple::mips ||
1379061da546Spatrick       arch_spec.GetMachine() == llvm::Triple::mipsel ||
1380061da546Spatrick       arch_spec.GetMachine() == llvm::Triple::mips64 ||
1381061da546Spatrick       arch_spec.GetMachine() == llvm::Triple::mips64el) {
1382061da546Spatrick     switch (header.e_flags & llvm::ELF::EF_MIPS_ARCH_ASE) {
1383061da546Spatrick     case llvm::ELF::EF_MIPS_MICROMIPS:
1384061da546Spatrick       arch_spec.SetFlags(ArchSpec::eMIPSAse_micromips);
1385061da546Spatrick       break;
1386061da546Spatrick     case llvm::ELF::EF_MIPS_ARCH_ASE_M16:
1387061da546Spatrick       arch_spec.SetFlags(ArchSpec::eMIPSAse_mips16);
1388061da546Spatrick       break;
1389061da546Spatrick     case llvm::ELF::EF_MIPS_ARCH_ASE_MDMX:
1390061da546Spatrick       arch_spec.SetFlags(ArchSpec::eMIPSAse_mdmx);
1391061da546Spatrick       break;
1392061da546Spatrick     default:
1393061da546Spatrick       break;
1394061da546Spatrick     }
1395061da546Spatrick   }
1396061da546Spatrick 
1397061da546Spatrick   if (arch_spec.GetMachine() == llvm::Triple::arm ||
1398061da546Spatrick       arch_spec.GetMachine() == llvm::Triple::thumb) {
1399061da546Spatrick     if (header.e_flags & llvm::ELF::EF_ARM_SOFT_FLOAT)
1400061da546Spatrick       arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float);
1401061da546Spatrick     else if (header.e_flags & llvm::ELF::EF_ARM_VFP_FLOAT)
1402061da546Spatrick       arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float);
1403061da546Spatrick   }
1404061da546Spatrick 
1405*101d251dSrobert   if (arch_spec.GetMachine() == llvm::Triple::riscv32 ||
1406*101d251dSrobert       arch_spec.GetMachine() == llvm::Triple::riscv64) {
1407*101d251dSrobert     uint32_t flags = arch_spec.GetFlags();
1408*101d251dSrobert 
1409*101d251dSrobert     if (header.e_flags & llvm::ELF::EF_RISCV_RVC)
1410*101d251dSrobert       flags |= ArchSpec::eRISCV_rvc;
1411*101d251dSrobert     if (header.e_flags & llvm::ELF::EF_RISCV_RVE)
1412*101d251dSrobert       flags |= ArchSpec::eRISCV_rve;
1413*101d251dSrobert 
1414*101d251dSrobert     if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE) ==
1415*101d251dSrobert         llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE)
1416*101d251dSrobert       flags |= ArchSpec::eRISCV_float_abi_single;
1417*101d251dSrobert     else if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE) ==
1418*101d251dSrobert              llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE)
1419*101d251dSrobert       flags |= ArchSpec::eRISCV_float_abi_double;
1420*101d251dSrobert     else if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD) ==
1421*101d251dSrobert              llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD)
1422*101d251dSrobert       flags |= ArchSpec::eRISCV_float_abi_quad;
1423*101d251dSrobert 
1424*101d251dSrobert     arch_spec.SetFlags(flags);
1425*101d251dSrobert   }
1426*101d251dSrobert 
1427061da546Spatrick   // If there are no section headers we are done.
1428061da546Spatrick   if (header.e_shnum == 0)
1429061da546Spatrick     return 0;
1430061da546Spatrick 
1431*101d251dSrobert   Log *log = GetLog(LLDBLog::Modules);
1432061da546Spatrick 
1433061da546Spatrick   section_headers.resize(header.e_shnum);
1434061da546Spatrick   if (section_headers.size() != header.e_shnum)
1435061da546Spatrick     return 0;
1436061da546Spatrick 
1437061da546Spatrick   const size_t sh_size = header.e_shnum * header.e_shentsize;
1438061da546Spatrick   const elf_off sh_offset = header.e_shoff;
1439061da546Spatrick   DataExtractor sh_data;
1440061da546Spatrick   if (sh_data.SetData(object_data, sh_offset, sh_size) != sh_size)
1441061da546Spatrick     return 0;
1442061da546Spatrick 
1443061da546Spatrick   uint32_t idx;
1444061da546Spatrick   lldb::offset_t offset;
1445061da546Spatrick   for (idx = 0, offset = 0; idx < header.e_shnum; ++idx) {
1446061da546Spatrick     if (!section_headers[idx].Parse(sh_data, &offset))
1447061da546Spatrick       break;
1448061da546Spatrick   }
1449061da546Spatrick   if (idx < section_headers.size())
1450061da546Spatrick     section_headers.resize(idx);
1451061da546Spatrick 
1452061da546Spatrick   const unsigned strtab_idx = header.e_shstrndx;
1453061da546Spatrick   if (strtab_idx && strtab_idx < section_headers.size()) {
1454061da546Spatrick     const ELFSectionHeaderInfo &sheader = section_headers[strtab_idx];
1455061da546Spatrick     const size_t byte_size = sheader.sh_size;
1456061da546Spatrick     const Elf64_Off offset = sheader.sh_offset;
1457061da546Spatrick     lldb_private::DataExtractor shstr_data;
1458061da546Spatrick 
1459061da546Spatrick     if (shstr_data.SetData(object_data, offset, byte_size) == byte_size) {
1460061da546Spatrick       for (SectionHeaderCollIter I = section_headers.begin();
1461061da546Spatrick            I != section_headers.end(); ++I) {
1462061da546Spatrick         static ConstString g_sect_name_gnu_debuglink(".gnu_debuglink");
1463061da546Spatrick         const ELFSectionHeaderInfo &sheader = *I;
1464061da546Spatrick         const uint64_t section_size =
1465061da546Spatrick             sheader.sh_type == SHT_NOBITS ? 0 : sheader.sh_size;
1466061da546Spatrick         ConstString name(shstr_data.PeekCStr(I->sh_name));
1467061da546Spatrick 
1468061da546Spatrick         I->section_name = name;
1469061da546Spatrick 
1470061da546Spatrick         if (arch_spec.IsMIPS()) {
1471061da546Spatrick           uint32_t arch_flags = arch_spec.GetFlags();
1472061da546Spatrick           DataExtractor data;
1473061da546Spatrick           if (sheader.sh_type == SHT_MIPS_ABIFLAGS) {
1474061da546Spatrick 
1475061da546Spatrick             if (section_size && (data.SetData(object_data, sheader.sh_offset,
1476061da546Spatrick                                               section_size) == section_size)) {
1477061da546Spatrick               // MIPS ASE Mask is at offset 12 in MIPS.abiflags section
1478061da546Spatrick               lldb::offset_t offset = 12; // MIPS ABI Flags Version: 0
1479061da546Spatrick               arch_flags |= data.GetU32(&offset);
1480061da546Spatrick 
1481061da546Spatrick               // The floating point ABI is at offset 7
1482061da546Spatrick               offset = 7;
1483061da546Spatrick               switch (data.GetU8(&offset)) {
1484061da546Spatrick               case llvm::Mips::Val_GNU_MIPS_ABI_FP_ANY:
1485061da546Spatrick                 arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_ANY;
1486061da546Spatrick                 break;
1487061da546Spatrick               case llvm::Mips::Val_GNU_MIPS_ABI_FP_DOUBLE:
1488061da546Spatrick                 arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_DOUBLE;
1489061da546Spatrick                 break;
1490061da546Spatrick               case llvm::Mips::Val_GNU_MIPS_ABI_FP_SINGLE:
1491061da546Spatrick                 arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SINGLE;
1492061da546Spatrick                 break;
1493061da546Spatrick               case llvm::Mips::Val_GNU_MIPS_ABI_FP_SOFT:
1494061da546Spatrick                 arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT;
1495061da546Spatrick                 break;
1496061da546Spatrick               case llvm::Mips::Val_GNU_MIPS_ABI_FP_OLD_64:
1497061da546Spatrick                 arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_OLD_64;
1498061da546Spatrick                 break;
1499061da546Spatrick               case llvm::Mips::Val_GNU_MIPS_ABI_FP_XX:
1500061da546Spatrick                 arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_XX;
1501061da546Spatrick                 break;
1502061da546Spatrick               case llvm::Mips::Val_GNU_MIPS_ABI_FP_64:
1503061da546Spatrick                 arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64;
1504061da546Spatrick                 break;
1505061da546Spatrick               case llvm::Mips::Val_GNU_MIPS_ABI_FP_64A:
1506061da546Spatrick                 arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64A;
1507061da546Spatrick                 break;
1508061da546Spatrick               }
1509061da546Spatrick             }
1510061da546Spatrick           }
1511061da546Spatrick           // Settings appropriate ArchSpec ABI Flags
1512061da546Spatrick           switch (header.e_flags & llvm::ELF::EF_MIPS_ABI) {
1513061da546Spatrick           case llvm::ELF::EF_MIPS_ABI_O32:
1514061da546Spatrick             arch_flags |= lldb_private::ArchSpec::eMIPSABI_O32;
1515061da546Spatrick             break;
1516061da546Spatrick           case EF_MIPS_ABI_O64:
1517061da546Spatrick             arch_flags |= lldb_private::ArchSpec::eMIPSABI_O64;
1518061da546Spatrick             break;
1519061da546Spatrick           case EF_MIPS_ABI_EABI32:
1520061da546Spatrick             arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI32;
1521061da546Spatrick             break;
1522061da546Spatrick           case EF_MIPS_ABI_EABI64:
1523061da546Spatrick             arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI64;
1524061da546Spatrick             break;
1525061da546Spatrick           default:
1526061da546Spatrick             // ABI Mask doesn't cover N32 and N64 ABI.
1527061da546Spatrick             if (header.e_ident[EI_CLASS] == llvm::ELF::ELFCLASS64)
1528061da546Spatrick               arch_flags |= lldb_private::ArchSpec::eMIPSABI_N64;
1529061da546Spatrick             else if (header.e_flags & llvm::ELF::EF_MIPS_ABI2)
1530061da546Spatrick               arch_flags |= lldb_private::ArchSpec::eMIPSABI_N32;
1531061da546Spatrick             break;
1532061da546Spatrick           }
1533061da546Spatrick           arch_spec.SetFlags(arch_flags);
1534061da546Spatrick         }
1535061da546Spatrick 
1536061da546Spatrick         if (arch_spec.GetMachine() == llvm::Triple::arm ||
1537061da546Spatrick             arch_spec.GetMachine() == llvm::Triple::thumb) {
1538061da546Spatrick           DataExtractor data;
1539061da546Spatrick 
1540061da546Spatrick           if (sheader.sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 &&
1541061da546Spatrick               data.SetData(object_data, sheader.sh_offset, section_size) == section_size)
1542061da546Spatrick             ParseARMAttributes(data, section_size, arch_spec);
1543061da546Spatrick         }
1544061da546Spatrick 
1545061da546Spatrick         if (name == g_sect_name_gnu_debuglink) {
1546061da546Spatrick           DataExtractor data;
1547061da546Spatrick           if (section_size && (data.SetData(object_data, sheader.sh_offset,
1548061da546Spatrick                                             section_size) == section_size)) {
1549061da546Spatrick             lldb::offset_t gnu_debuglink_offset = 0;
1550061da546Spatrick             gnu_debuglink_file = data.GetCStr(&gnu_debuglink_offset);
1551061da546Spatrick             gnu_debuglink_offset = llvm::alignTo(gnu_debuglink_offset, 4);
1552061da546Spatrick             data.GetU32(&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
1553061da546Spatrick           }
1554061da546Spatrick         }
1555061da546Spatrick 
1556061da546Spatrick         // Process ELF note section entries.
1557061da546Spatrick         bool is_note_header = (sheader.sh_type == SHT_NOTE);
1558061da546Spatrick 
1559061da546Spatrick         // The section header ".note.android.ident" is stored as a
1560061da546Spatrick         // PROGBITS type header but it is actually a note header.
1561061da546Spatrick         static ConstString g_sect_name_android_ident(".note.android.ident");
1562061da546Spatrick         if (!is_note_header && name == g_sect_name_android_ident)
1563061da546Spatrick           is_note_header = true;
1564061da546Spatrick 
1565061da546Spatrick         if (is_note_header) {
1566061da546Spatrick           // Allow notes to refine module info.
1567061da546Spatrick           DataExtractor data;
1568061da546Spatrick           if (section_size && (data.SetData(object_data, sheader.sh_offset,
1569061da546Spatrick                                             section_size) == section_size)) {
1570061da546Spatrick             Status error = RefineModuleDetailsFromNote(data, arch_spec, uuid);
1571061da546Spatrick             if (error.Fail()) {
1572061da546Spatrick               LLDB_LOGF(log, "ObjectFileELF::%s ELF note processing failed: %s",
1573061da546Spatrick                         __FUNCTION__, error.AsCString());
1574061da546Spatrick             }
1575061da546Spatrick           }
1576061da546Spatrick         }
1577061da546Spatrick       }
1578061da546Spatrick 
1579061da546Spatrick       // Make any unknown triple components to be unspecified unknowns.
1580061da546Spatrick       if (arch_spec.GetTriple().getVendor() == llvm::Triple::UnknownVendor)
1581061da546Spatrick         arch_spec.GetTriple().setVendorName(llvm::StringRef());
1582061da546Spatrick       if (arch_spec.GetTriple().getOS() == llvm::Triple::UnknownOS)
1583061da546Spatrick         arch_spec.GetTriple().setOSName(llvm::StringRef());
1584061da546Spatrick 
1585061da546Spatrick       return section_headers.size();
1586061da546Spatrick     }
1587061da546Spatrick   }
1588061da546Spatrick 
1589061da546Spatrick   section_headers.clear();
1590061da546Spatrick   return 0;
1591061da546Spatrick }
1592061da546Spatrick 
1593061da546Spatrick llvm::StringRef
StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const1594061da546Spatrick ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const {
1595061da546Spatrick   size_t pos = symbol_name.find('@');
1596061da546Spatrick   return symbol_name.substr(0, pos);
1597061da546Spatrick }
1598061da546Spatrick 
1599061da546Spatrick // ParseSectionHeaders
ParseSectionHeaders()1600061da546Spatrick size_t ObjectFileELF::ParseSectionHeaders() {
1601061da546Spatrick   return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid,
1602061da546Spatrick                               m_gnu_debuglink_file, m_gnu_debuglink_crc,
1603061da546Spatrick                               m_arch_spec);
1604061da546Spatrick }
1605061da546Spatrick 
1606061da546Spatrick const ObjectFileELF::ELFSectionHeaderInfo *
GetSectionHeaderByIndex(lldb::user_id_t id)1607061da546Spatrick ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) {
1608061da546Spatrick   if (!ParseSectionHeaders())
1609061da546Spatrick     return nullptr;
1610061da546Spatrick 
1611061da546Spatrick   if (id < m_section_headers.size())
1612061da546Spatrick     return &m_section_headers[id];
1613061da546Spatrick 
1614061da546Spatrick   return nullptr;
1615061da546Spatrick }
1616061da546Spatrick 
GetSectionIndexByName(const char * name)1617061da546Spatrick lldb::user_id_t ObjectFileELF::GetSectionIndexByName(const char *name) {
1618061da546Spatrick   if (!name || !name[0] || !ParseSectionHeaders())
1619061da546Spatrick     return 0;
1620061da546Spatrick   for (size_t i = 1; i < m_section_headers.size(); ++i)
1621061da546Spatrick     if (m_section_headers[i].section_name == ConstString(name))
1622061da546Spatrick       return i;
1623061da546Spatrick   return 0;
1624061da546Spatrick }
1625061da546Spatrick 
GetSectionTypeFromName(llvm::StringRef Name)1626061da546Spatrick static SectionType GetSectionTypeFromName(llvm::StringRef Name) {
1627*101d251dSrobert   if (Name.consume_front(".debug_")) {
1628061da546Spatrick     return llvm::StringSwitch<SectionType>(Name)
1629061da546Spatrick         .Case("abbrev", eSectionTypeDWARFDebugAbbrev)
1630061da546Spatrick         .Case("abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo)
1631061da546Spatrick         .Case("addr", eSectionTypeDWARFDebugAddr)
1632061da546Spatrick         .Case("aranges", eSectionTypeDWARFDebugAranges)
1633061da546Spatrick         .Case("cu_index", eSectionTypeDWARFDebugCuIndex)
1634061da546Spatrick         .Case("frame", eSectionTypeDWARFDebugFrame)
1635061da546Spatrick         .Case("info", eSectionTypeDWARFDebugInfo)
1636061da546Spatrick         .Case("info.dwo", eSectionTypeDWARFDebugInfoDwo)
1637061da546Spatrick         .Cases("line", "line.dwo", eSectionTypeDWARFDebugLine)
1638061da546Spatrick         .Cases("line_str", "line_str.dwo", eSectionTypeDWARFDebugLineStr)
1639061da546Spatrick         .Case("loc", eSectionTypeDWARFDebugLoc)
1640061da546Spatrick         .Case("loc.dwo", eSectionTypeDWARFDebugLocDwo)
1641061da546Spatrick         .Case("loclists", eSectionTypeDWARFDebugLocLists)
1642061da546Spatrick         .Case("loclists.dwo", eSectionTypeDWARFDebugLocListsDwo)
1643061da546Spatrick         .Case("macinfo", eSectionTypeDWARFDebugMacInfo)
1644061da546Spatrick         .Cases("macro", "macro.dwo", eSectionTypeDWARFDebugMacro)
1645061da546Spatrick         .Case("names", eSectionTypeDWARFDebugNames)
1646061da546Spatrick         .Case("pubnames", eSectionTypeDWARFDebugPubNames)
1647061da546Spatrick         .Case("pubtypes", eSectionTypeDWARFDebugPubTypes)
1648061da546Spatrick         .Case("ranges", eSectionTypeDWARFDebugRanges)
1649061da546Spatrick         .Case("rnglists", eSectionTypeDWARFDebugRngLists)
1650061da546Spatrick         .Case("rnglists.dwo", eSectionTypeDWARFDebugRngListsDwo)
1651061da546Spatrick         .Case("str", eSectionTypeDWARFDebugStr)
1652061da546Spatrick         .Case("str.dwo", eSectionTypeDWARFDebugStrDwo)
1653061da546Spatrick         .Case("str_offsets", eSectionTypeDWARFDebugStrOffsets)
1654061da546Spatrick         .Case("str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo)
1655dda28197Spatrick         .Case("tu_index", eSectionTypeDWARFDebugTuIndex)
1656061da546Spatrick         .Case("types", eSectionTypeDWARFDebugTypes)
1657061da546Spatrick         .Case("types.dwo", eSectionTypeDWARFDebugTypesDwo)
1658061da546Spatrick         .Default(eSectionTypeOther);
1659061da546Spatrick   }
1660061da546Spatrick   return llvm::StringSwitch<SectionType>(Name)
1661061da546Spatrick       .Case(".ARM.exidx", eSectionTypeARMexidx)
1662061da546Spatrick       .Case(".ARM.extab", eSectionTypeARMextab)
1663061da546Spatrick       .Cases(".bss", ".tbss", eSectionTypeZeroFill)
1664061da546Spatrick       .Cases(".data", ".tdata", eSectionTypeData)
1665061da546Spatrick       .Case(".eh_frame", eSectionTypeEHFrame)
1666061da546Spatrick       .Case(".gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink)
1667061da546Spatrick       .Case(".gosymtab", eSectionTypeGoSymtab)
1668061da546Spatrick       .Case(".text", eSectionTypeCode)
1669061da546Spatrick       .Default(eSectionTypeOther);
1670061da546Spatrick }
1671061da546Spatrick 
GetSectionType(const ELFSectionHeaderInfo & H) const1672061da546Spatrick SectionType ObjectFileELF::GetSectionType(const ELFSectionHeaderInfo &H) const {
1673061da546Spatrick   switch (H.sh_type) {
1674061da546Spatrick   case SHT_PROGBITS:
1675061da546Spatrick     if (H.sh_flags & SHF_EXECINSTR)
1676061da546Spatrick       return eSectionTypeCode;
1677061da546Spatrick     break;
1678061da546Spatrick   case SHT_SYMTAB:
1679061da546Spatrick     return eSectionTypeELFSymbolTable;
1680061da546Spatrick   case SHT_DYNSYM:
1681061da546Spatrick     return eSectionTypeELFDynamicSymbols;
1682061da546Spatrick   case SHT_RELA:
1683061da546Spatrick   case SHT_REL:
1684061da546Spatrick     return eSectionTypeELFRelocationEntries;
1685061da546Spatrick   case SHT_DYNAMIC:
1686061da546Spatrick     return eSectionTypeELFDynamicLinkInfo;
1687061da546Spatrick   }
1688061da546Spatrick   return GetSectionTypeFromName(H.section_name.GetStringRef());
1689061da546Spatrick }
1690061da546Spatrick 
GetTargetByteSize(SectionType Type,const ArchSpec & arch)1691061da546Spatrick static uint32_t GetTargetByteSize(SectionType Type, const ArchSpec &arch) {
1692061da546Spatrick   switch (Type) {
1693061da546Spatrick   case eSectionTypeData:
1694061da546Spatrick   case eSectionTypeZeroFill:
1695061da546Spatrick     return arch.GetDataByteSize();
1696061da546Spatrick   case eSectionTypeCode:
1697061da546Spatrick     return arch.GetCodeByteSize();
1698061da546Spatrick   default:
1699061da546Spatrick     return 1;
1700061da546Spatrick   }
1701061da546Spatrick }
1702061da546Spatrick 
GetPermissions(const ELFSectionHeader & H)1703061da546Spatrick static Permissions GetPermissions(const ELFSectionHeader &H) {
1704061da546Spatrick   Permissions Perm = Permissions(0);
1705061da546Spatrick   if (H.sh_flags & SHF_ALLOC)
1706061da546Spatrick     Perm |= ePermissionsReadable;
1707061da546Spatrick   if (H.sh_flags & SHF_WRITE)
1708061da546Spatrick     Perm |= ePermissionsWritable;
1709061da546Spatrick   if (H.sh_flags & SHF_EXECINSTR)
1710061da546Spatrick     Perm |= ePermissionsExecutable;
1711061da546Spatrick   return Perm;
1712061da546Spatrick }
1713061da546Spatrick 
GetPermissions(const ELFProgramHeader & H)1714061da546Spatrick static Permissions GetPermissions(const ELFProgramHeader &H) {
1715061da546Spatrick   Permissions Perm = Permissions(0);
1716061da546Spatrick   if (H.p_flags & PF_R)
1717061da546Spatrick     Perm |= ePermissionsReadable;
1718061da546Spatrick   if (H.p_flags & PF_W)
1719061da546Spatrick     Perm |= ePermissionsWritable;
1720061da546Spatrick   if (H.p_flags & PF_X)
1721061da546Spatrick     Perm |= ePermissionsExecutable;
1722061da546Spatrick   return Perm;
1723061da546Spatrick }
1724061da546Spatrick 
1725061da546Spatrick namespace {
1726061da546Spatrick 
1727061da546Spatrick using VMRange = lldb_private::Range<addr_t, addr_t>;
1728061da546Spatrick 
1729061da546Spatrick struct SectionAddressInfo {
1730061da546Spatrick   SectionSP Segment;
1731061da546Spatrick   VMRange Range;
1732061da546Spatrick };
1733061da546Spatrick 
1734061da546Spatrick // (Unlinked) ELF object files usually have 0 for every section address, meaning
1735061da546Spatrick // we need to compute synthetic addresses in order for "file addresses" from
1736061da546Spatrick // different sections to not overlap. This class handles that logic.
1737061da546Spatrick class VMAddressProvider {
1738061da546Spatrick   using VMMap = llvm::IntervalMap<addr_t, SectionSP, 4,
1739061da546Spatrick                                        llvm::IntervalMapHalfOpenInfo<addr_t>>;
1740061da546Spatrick 
1741061da546Spatrick   ObjectFile::Type ObjectType;
1742061da546Spatrick   addr_t NextVMAddress = 0;
1743061da546Spatrick   VMMap::Allocator Alloc;
1744*101d251dSrobert   VMMap Segments{Alloc};
1745*101d251dSrobert   VMMap Sections{Alloc};
1746*101d251dSrobert   lldb_private::Log *Log = GetLog(LLDBLog::Modules);
1747061da546Spatrick   size_t SegmentCount = 0;
1748061da546Spatrick   std::string SegmentName;
1749061da546Spatrick 
GetVMRange(const ELFSectionHeader & H)1750061da546Spatrick   VMRange GetVMRange(const ELFSectionHeader &H) {
1751061da546Spatrick     addr_t Address = H.sh_addr;
1752061da546Spatrick     addr_t Size = H.sh_flags & SHF_ALLOC ? H.sh_size : 0;
1753061da546Spatrick     if (ObjectType == ObjectFile::Type::eTypeObjectFile && Segments.empty() && (H.sh_flags & SHF_ALLOC)) {
1754061da546Spatrick       NextVMAddress =
1755061da546Spatrick           llvm::alignTo(NextVMAddress, std::max<addr_t>(H.sh_addralign, 1));
1756061da546Spatrick       Address = NextVMAddress;
1757061da546Spatrick       NextVMAddress += Size;
1758061da546Spatrick     }
1759061da546Spatrick     return VMRange(Address, Size);
1760061da546Spatrick   }
1761061da546Spatrick 
1762061da546Spatrick public:
VMAddressProvider(ObjectFile::Type Type,llvm::StringRef SegmentName)1763061da546Spatrick   VMAddressProvider(ObjectFile::Type Type, llvm::StringRef SegmentName)
1764dda28197Spatrick       : ObjectType(Type), SegmentName(std::string(SegmentName)) {}
1765061da546Spatrick 
GetNextSegmentName() const1766061da546Spatrick   std::string GetNextSegmentName() const {
1767061da546Spatrick     return llvm::formatv("{0}[{1}]", SegmentName, SegmentCount).str();
1768061da546Spatrick   }
1769061da546Spatrick 
GetAddressInfo(const ELFProgramHeader & H)1770*101d251dSrobert   std::optional<VMRange> GetAddressInfo(const ELFProgramHeader &H) {
1771061da546Spatrick     if (H.p_memsz == 0) {
1772061da546Spatrick       LLDB_LOG(Log, "Ignoring zero-sized {0} segment. Corrupt object file?",
1773061da546Spatrick                SegmentName);
1774*101d251dSrobert       return std::nullopt;
1775061da546Spatrick     }
1776061da546Spatrick 
1777061da546Spatrick     if (Segments.overlaps(H.p_vaddr, H.p_vaddr + H.p_memsz)) {
1778061da546Spatrick       LLDB_LOG(Log, "Ignoring overlapping {0} segment. Corrupt object file?",
1779061da546Spatrick                SegmentName);
1780*101d251dSrobert       return std::nullopt;
1781061da546Spatrick     }
1782061da546Spatrick     return VMRange(H.p_vaddr, H.p_memsz);
1783061da546Spatrick   }
1784061da546Spatrick 
GetAddressInfo(const ELFSectionHeader & H)1785*101d251dSrobert   std::optional<SectionAddressInfo> GetAddressInfo(const ELFSectionHeader &H) {
1786061da546Spatrick     VMRange Range = GetVMRange(H);
1787061da546Spatrick     SectionSP Segment;
1788061da546Spatrick     auto It = Segments.find(Range.GetRangeBase());
1789061da546Spatrick     if ((H.sh_flags & SHF_ALLOC) && It.valid()) {
1790061da546Spatrick       addr_t MaxSize;
1791061da546Spatrick       if (It.start() <= Range.GetRangeBase()) {
1792061da546Spatrick         MaxSize = It.stop() - Range.GetRangeBase();
1793061da546Spatrick         Segment = *It;
1794061da546Spatrick       } else
1795061da546Spatrick         MaxSize = It.start() - Range.GetRangeBase();
1796061da546Spatrick       if (Range.GetByteSize() > MaxSize) {
1797061da546Spatrick         LLDB_LOG(Log, "Shortening section crossing segment boundaries. "
1798061da546Spatrick                       "Corrupt object file?");
1799061da546Spatrick         Range.SetByteSize(MaxSize);
1800061da546Spatrick       }
1801061da546Spatrick     }
1802061da546Spatrick     if (Range.GetByteSize() > 0 &&
1803061da546Spatrick         Sections.overlaps(Range.GetRangeBase(), Range.GetRangeEnd())) {
1804061da546Spatrick       LLDB_LOG(Log, "Ignoring overlapping section. Corrupt object file?");
1805*101d251dSrobert       return std::nullopt;
1806061da546Spatrick     }
1807061da546Spatrick     if (Segment)
1808061da546Spatrick       Range.Slide(-Segment->GetFileAddress());
1809061da546Spatrick     return SectionAddressInfo{Segment, Range};
1810061da546Spatrick   }
1811061da546Spatrick 
AddSegment(const VMRange & Range,SectionSP Seg)1812061da546Spatrick   void AddSegment(const VMRange &Range, SectionSP Seg) {
1813061da546Spatrick     Segments.insert(Range.GetRangeBase(), Range.GetRangeEnd(), std::move(Seg));
1814061da546Spatrick     ++SegmentCount;
1815061da546Spatrick   }
1816061da546Spatrick 
AddSection(SectionAddressInfo Info,SectionSP Sect)1817061da546Spatrick   void AddSection(SectionAddressInfo Info, SectionSP Sect) {
1818061da546Spatrick     if (Info.Range.GetByteSize() == 0)
1819061da546Spatrick       return;
1820061da546Spatrick     if (Info.Segment)
1821061da546Spatrick       Info.Range.Slide(Info.Segment->GetFileAddress());
1822061da546Spatrick     Sections.insert(Info.Range.GetRangeBase(), Info.Range.GetRangeEnd(),
1823061da546Spatrick                     std::move(Sect));
1824061da546Spatrick   }
1825061da546Spatrick };
1826061da546Spatrick }
1827061da546Spatrick 
CreateSections(SectionList & unified_section_list)1828061da546Spatrick void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
1829061da546Spatrick   if (m_sections_up)
1830061da546Spatrick     return;
1831061da546Spatrick 
1832061da546Spatrick   m_sections_up = std::make_unique<SectionList>();
1833061da546Spatrick   VMAddressProvider regular_provider(GetType(), "PT_LOAD");
1834061da546Spatrick   VMAddressProvider tls_provider(GetType(), "PT_TLS");
1835061da546Spatrick 
1836061da546Spatrick   for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) {
1837061da546Spatrick     const ELFProgramHeader &PHdr = EnumPHdr.value();
1838061da546Spatrick     if (PHdr.p_type != PT_LOAD && PHdr.p_type != PT_TLS)
1839061da546Spatrick       continue;
1840061da546Spatrick 
1841061da546Spatrick     VMAddressProvider &provider =
1842061da546Spatrick         PHdr.p_type == PT_TLS ? tls_provider : regular_provider;
1843061da546Spatrick     auto InfoOr = provider.GetAddressInfo(PHdr);
1844061da546Spatrick     if (!InfoOr)
1845061da546Spatrick       continue;
1846061da546Spatrick 
1847061da546Spatrick     uint32_t Log2Align = llvm::Log2_64(std::max<elf_xword>(PHdr.p_align, 1));
1848061da546Spatrick     SectionSP Segment = std::make_shared<Section>(
1849061da546Spatrick         GetModule(), this, SegmentID(EnumPHdr.index()),
1850061da546Spatrick         ConstString(provider.GetNextSegmentName()), eSectionTypeContainer,
1851061da546Spatrick         InfoOr->GetRangeBase(), InfoOr->GetByteSize(), PHdr.p_offset,
1852061da546Spatrick         PHdr.p_filesz, Log2Align, /*flags*/ 0);
1853061da546Spatrick     Segment->SetPermissions(GetPermissions(PHdr));
1854061da546Spatrick     Segment->SetIsThreadSpecific(PHdr.p_type == PT_TLS);
1855061da546Spatrick     m_sections_up->AddSection(Segment);
1856061da546Spatrick 
1857061da546Spatrick     provider.AddSegment(*InfoOr, std::move(Segment));
1858061da546Spatrick   }
1859061da546Spatrick 
1860061da546Spatrick   ParseSectionHeaders();
1861061da546Spatrick   if (m_section_headers.empty())
1862061da546Spatrick     return;
1863061da546Spatrick 
1864061da546Spatrick   for (SectionHeaderCollIter I = std::next(m_section_headers.begin());
1865061da546Spatrick        I != m_section_headers.end(); ++I) {
1866061da546Spatrick     const ELFSectionHeaderInfo &header = *I;
1867061da546Spatrick 
1868061da546Spatrick     ConstString &name = I->section_name;
1869061da546Spatrick     const uint64_t file_size =
1870061da546Spatrick         header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
1871061da546Spatrick 
1872061da546Spatrick     VMAddressProvider &provider =
1873061da546Spatrick         header.sh_flags & SHF_TLS ? tls_provider : regular_provider;
1874061da546Spatrick     auto InfoOr = provider.GetAddressInfo(header);
1875061da546Spatrick     if (!InfoOr)
1876061da546Spatrick       continue;
1877061da546Spatrick 
1878061da546Spatrick     SectionType sect_type = GetSectionType(header);
1879061da546Spatrick 
1880061da546Spatrick     const uint32_t target_bytes_size =
1881061da546Spatrick         GetTargetByteSize(sect_type, m_arch_spec);
1882061da546Spatrick 
1883061da546Spatrick     elf::elf_xword log2align =
1884061da546Spatrick         (header.sh_addralign == 0) ? 0 : llvm::Log2_64(header.sh_addralign);
1885061da546Spatrick 
1886061da546Spatrick     SectionSP section_sp(new Section(
1887061da546Spatrick         InfoOr->Segment, GetModule(), // Module to which this section belongs.
1888061da546Spatrick         this,            // ObjectFile to which this section belongs and should
1889061da546Spatrick                          // read section data from.
1890061da546Spatrick         SectionIndex(I), // Section ID.
1891061da546Spatrick         name,            // Section name.
1892061da546Spatrick         sect_type,       // Section type.
1893061da546Spatrick         InfoOr->Range.GetRangeBase(), // VM address.
1894061da546Spatrick         InfoOr->Range.GetByteSize(),  // VM size in bytes of this section.
1895061da546Spatrick         header.sh_offset,             // Offset of this section in the file.
1896061da546Spatrick         file_size,           // Size of the section as found in the file.
1897061da546Spatrick         log2align,           // Alignment of the section
1898061da546Spatrick         header.sh_flags,     // Flags for this section.
1899061da546Spatrick         target_bytes_size)); // Number of host bytes per target byte
1900061da546Spatrick 
1901061da546Spatrick     section_sp->SetPermissions(GetPermissions(header));
1902061da546Spatrick     section_sp->SetIsThreadSpecific(header.sh_flags & SHF_TLS);
1903061da546Spatrick     (InfoOr->Segment ? InfoOr->Segment->GetChildren() : *m_sections_up)
1904061da546Spatrick         .AddSection(section_sp);
1905061da546Spatrick     provider.AddSection(std::move(*InfoOr), std::move(section_sp));
1906061da546Spatrick   }
1907061da546Spatrick 
1908061da546Spatrick   // For eTypeDebugInfo files, the Symbol Vendor will take care of updating the
1909061da546Spatrick   // unified section list.
1910061da546Spatrick   if (GetType() != eTypeDebugInfo)
1911061da546Spatrick     unified_section_list = *m_sections_up;
1912061da546Spatrick 
1913061da546Spatrick   // If there's a .gnu_debugdata section, we'll try to read the .symtab that's
1914061da546Spatrick   // embedded in there and replace the one in the original object file (if any).
1915061da546Spatrick   // If there's none in the orignal object file, we add it to it.
1916061da546Spatrick   if (auto gdd_obj_file = GetGnuDebugDataObjectFile()) {
1917061da546Spatrick     if (auto gdd_objfile_section_list = gdd_obj_file->GetSectionList()) {
1918061da546Spatrick       if (SectionSP symtab_section_sp =
1919061da546Spatrick               gdd_objfile_section_list->FindSectionByType(
1920061da546Spatrick                   eSectionTypeELFSymbolTable, true)) {
1921061da546Spatrick         SectionSP module_section_sp = unified_section_list.FindSectionByType(
1922061da546Spatrick             eSectionTypeELFSymbolTable, true);
1923061da546Spatrick         if (module_section_sp)
1924061da546Spatrick           unified_section_list.ReplaceSection(module_section_sp->GetID(),
1925061da546Spatrick                                               symtab_section_sp);
1926061da546Spatrick         else
1927061da546Spatrick           unified_section_list.AddSection(symtab_section_sp);
1928061da546Spatrick       }
1929061da546Spatrick     }
1930061da546Spatrick   }
1931061da546Spatrick }
1932061da546Spatrick 
GetGnuDebugDataObjectFile()1933061da546Spatrick std::shared_ptr<ObjectFileELF> ObjectFileELF::GetGnuDebugDataObjectFile() {
1934061da546Spatrick   if (m_gnu_debug_data_object_file != nullptr)
1935061da546Spatrick     return m_gnu_debug_data_object_file;
1936061da546Spatrick 
1937061da546Spatrick   SectionSP section =
1938061da546Spatrick       GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"));
1939061da546Spatrick   if (!section)
1940061da546Spatrick     return nullptr;
1941061da546Spatrick 
1942061da546Spatrick   if (!lldb_private::lzma::isAvailable()) {
1943061da546Spatrick     GetModule()->ReportWarning(
1944061da546Spatrick         "No LZMA support found for reading .gnu_debugdata section");
1945061da546Spatrick     return nullptr;
1946061da546Spatrick   }
1947061da546Spatrick 
1948061da546Spatrick   // Uncompress the data
1949061da546Spatrick   DataExtractor data;
1950061da546Spatrick   section->GetSectionData(data);
1951061da546Spatrick   llvm::SmallVector<uint8_t, 0> uncompressedData;
1952061da546Spatrick   auto err = lldb_private::lzma::uncompress(data.GetData(), uncompressedData);
1953061da546Spatrick   if (err) {
1954061da546Spatrick     GetModule()->ReportWarning(
1955*101d251dSrobert         "An error occurred while decompression the section {0}: {1}",
1956061da546Spatrick         section->GetName().AsCString(), llvm::toString(std::move(err)).c_str());
1957061da546Spatrick     return nullptr;
1958061da546Spatrick   }
1959061da546Spatrick 
1960061da546Spatrick   // Construct ObjectFileELF object from decompressed buffer
1961061da546Spatrick   DataBufferSP gdd_data_buf(
1962061da546Spatrick       new DataBufferHeap(uncompressedData.data(), uncompressedData.size()));
1963061da546Spatrick   auto fspec = GetFileSpec().CopyByAppendingPathComponent(
1964061da546Spatrick       llvm::StringRef("gnu_debugdata"));
1965061da546Spatrick   m_gnu_debug_data_object_file.reset(new ObjectFileELF(
1966061da546Spatrick       GetModule(), gdd_data_buf, 0, &fspec, 0, gdd_data_buf->GetByteSize()));
1967061da546Spatrick 
1968061da546Spatrick   // This line is essential; otherwise a breakpoint can be set but not hit.
1969061da546Spatrick   m_gnu_debug_data_object_file->SetType(ObjectFile::eTypeDebugInfo);
1970061da546Spatrick 
1971061da546Spatrick   ArchSpec spec = m_gnu_debug_data_object_file->GetArchitecture();
1972061da546Spatrick   if (spec && m_gnu_debug_data_object_file->SetModulesArchitecture(spec))
1973061da546Spatrick     return m_gnu_debug_data_object_file;
1974061da546Spatrick 
1975061da546Spatrick   return nullptr;
1976061da546Spatrick }
1977061da546Spatrick 
1978061da546Spatrick // Find the arm/aarch64 mapping symbol character in the given symbol name.
1979061da546Spatrick // Mapping symbols have the form of "$<char>[.<any>]*". Additionally we
1980061da546Spatrick // recognize cases when the mapping symbol prefixed by an arbitrary string
1981061da546Spatrick // because if a symbol prefix added to each symbol in the object file with
1982061da546Spatrick // objcopy then the mapping symbols are also prefixed.
FindArmAarch64MappingSymbol(const char * symbol_name)1983061da546Spatrick static char FindArmAarch64MappingSymbol(const char *symbol_name) {
1984061da546Spatrick   if (!symbol_name)
1985061da546Spatrick     return '\0';
1986061da546Spatrick 
1987061da546Spatrick   const char *dollar_pos = ::strchr(symbol_name, '$');
1988061da546Spatrick   if (!dollar_pos || dollar_pos[1] == '\0')
1989061da546Spatrick     return '\0';
1990061da546Spatrick 
1991061da546Spatrick   if (dollar_pos[2] == '\0' || dollar_pos[2] == '.')
1992061da546Spatrick     return dollar_pos[1];
1993061da546Spatrick   return '\0';
1994061da546Spatrick }
1995061da546Spatrick 
1996061da546Spatrick #define STO_MIPS_ISA (3 << 6)
1997061da546Spatrick #define STO_MICROMIPS (2 << 6)
1998061da546Spatrick #define IS_MICROMIPS(ST_OTHER) (((ST_OTHER)&STO_MIPS_ISA) == STO_MICROMIPS)
1999061da546Spatrick 
2000061da546Spatrick // private
ParseSymbols(Symtab * symtab,user_id_t start_id,SectionList * section_list,const size_t num_symbols,const DataExtractor & symtab_data,const DataExtractor & strtab_data)2001061da546Spatrick unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
2002061da546Spatrick                                      SectionList *section_list,
2003061da546Spatrick                                      const size_t num_symbols,
2004061da546Spatrick                                      const DataExtractor &symtab_data,
2005061da546Spatrick                                      const DataExtractor &strtab_data) {
2006061da546Spatrick   ELFSymbol symbol;
2007061da546Spatrick   lldb::offset_t offset = 0;
2008061da546Spatrick 
2009061da546Spatrick   static ConstString text_section_name(".text");
2010061da546Spatrick   static ConstString init_section_name(".init");
2011061da546Spatrick   static ConstString fini_section_name(".fini");
2012061da546Spatrick   static ConstString ctors_section_name(".ctors");
2013061da546Spatrick   static ConstString dtors_section_name(".dtors");
2014061da546Spatrick 
2015061da546Spatrick   static ConstString data_section_name(".data");
2016061da546Spatrick   static ConstString rodata_section_name(".rodata");
2017061da546Spatrick   static ConstString rodata1_section_name(".rodata1");
2018061da546Spatrick   static ConstString data2_section_name(".data1");
2019061da546Spatrick   static ConstString bss_section_name(".bss");
2020061da546Spatrick   static ConstString opd_section_name(".opd"); // For ppc64
2021061da546Spatrick 
2022061da546Spatrick   // On Android the oatdata and the oatexec symbols in the oat and odex files
2023061da546Spatrick   // covers the full .text section what causes issues with displaying unusable
2024061da546Spatrick   // symbol name to the user and very slow unwinding speed because the
2025061da546Spatrick   // instruction emulation based unwind plans try to emulate all instructions
2026061da546Spatrick   // in these symbols. Don't add these symbols to the symbol list as they have
2027061da546Spatrick   // no use for the debugger and they are causing a lot of trouble. Filtering
2028061da546Spatrick   // can't be restricted to Android because this special object file don't
2029061da546Spatrick   // contain the note section specifying the environment to Android but the
2030061da546Spatrick   // custom extension and file name makes it highly unlikely that this will
2031061da546Spatrick   // collide with anything else.
2032061da546Spatrick   ConstString file_extension = m_file.GetFileNameExtension();
2033061da546Spatrick   bool skip_oatdata_oatexec =
2034061da546Spatrick       file_extension == ".oat" || file_extension == ".odex";
2035061da546Spatrick 
2036061da546Spatrick   ArchSpec arch = GetArchitecture();
2037061da546Spatrick   ModuleSP module_sp(GetModule());
2038061da546Spatrick   SectionList *module_section_list =
2039061da546Spatrick       module_sp ? module_sp->GetSectionList() : nullptr;
2040061da546Spatrick 
2041061da546Spatrick   // Local cache to avoid doing a FindSectionByName for each symbol. The "const
2042061da546Spatrick   // char*" key must came from a ConstString object so they can be compared by
2043061da546Spatrick   // pointer
2044061da546Spatrick   std::unordered_map<const char *, lldb::SectionSP> section_name_to_section;
2045061da546Spatrick 
2046061da546Spatrick   unsigned i;
2047061da546Spatrick   for (i = 0; i < num_symbols; ++i) {
2048061da546Spatrick     if (!symbol.Parse(symtab_data, &offset))
2049061da546Spatrick       break;
2050061da546Spatrick 
2051061da546Spatrick     const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
2052061da546Spatrick     if (!symbol_name)
2053061da546Spatrick       symbol_name = "";
2054061da546Spatrick 
2055061da546Spatrick     // No need to add non-section symbols that have no names
2056061da546Spatrick     if (symbol.getType() != STT_SECTION &&
2057061da546Spatrick         (symbol_name == nullptr || symbol_name[0] == '\0'))
2058061da546Spatrick       continue;
2059061da546Spatrick 
2060061da546Spatrick     // Skipping oatdata and oatexec sections if it is requested. See details
2061061da546Spatrick     // above the definition of skip_oatdata_oatexec for the reasons.
2062061da546Spatrick     if (skip_oatdata_oatexec && (::strcmp(symbol_name, "oatdata") == 0 ||
2063061da546Spatrick                                  ::strcmp(symbol_name, "oatexec") == 0))
2064061da546Spatrick       continue;
2065061da546Spatrick 
2066061da546Spatrick     SectionSP symbol_section_sp;
2067061da546Spatrick     SymbolType symbol_type = eSymbolTypeInvalid;
2068061da546Spatrick     Elf64_Half shndx = symbol.st_shndx;
2069061da546Spatrick 
2070061da546Spatrick     switch (shndx) {
2071061da546Spatrick     case SHN_ABS:
2072061da546Spatrick       symbol_type = eSymbolTypeAbsolute;
2073061da546Spatrick       break;
2074061da546Spatrick     case SHN_UNDEF:
2075061da546Spatrick       symbol_type = eSymbolTypeUndefined;
2076061da546Spatrick       break;
2077061da546Spatrick     default:
2078061da546Spatrick       symbol_section_sp = section_list->FindSectionByID(shndx);
2079061da546Spatrick       break;
2080061da546Spatrick     }
2081061da546Spatrick 
2082061da546Spatrick     // If a symbol is undefined do not process it further even if it has a STT
2083061da546Spatrick     // type
2084061da546Spatrick     if (symbol_type != eSymbolTypeUndefined) {
2085061da546Spatrick       switch (symbol.getType()) {
2086061da546Spatrick       default:
2087061da546Spatrick       case STT_NOTYPE:
2088061da546Spatrick         // The symbol's type is not specified.
2089061da546Spatrick         break;
2090061da546Spatrick 
2091061da546Spatrick       case STT_OBJECT:
2092061da546Spatrick         // The symbol is associated with a data object, such as a variable, an
2093061da546Spatrick         // array, etc.
2094061da546Spatrick         symbol_type = eSymbolTypeData;
2095061da546Spatrick         break;
2096061da546Spatrick 
2097061da546Spatrick       case STT_FUNC:
2098061da546Spatrick         // The symbol is associated with a function or other executable code.
2099061da546Spatrick         symbol_type = eSymbolTypeCode;
2100061da546Spatrick         break;
2101061da546Spatrick 
2102061da546Spatrick       case STT_SECTION:
2103061da546Spatrick         // The symbol is associated with a section. Symbol table entries of
2104061da546Spatrick         // this type exist primarily for relocation and normally have STB_LOCAL
2105061da546Spatrick         // binding.
2106061da546Spatrick         break;
2107061da546Spatrick 
2108061da546Spatrick       case STT_FILE:
2109061da546Spatrick         // Conventionally, the symbol's name gives the name of the source file
2110061da546Spatrick         // associated with the object file. A file symbol has STB_LOCAL
2111061da546Spatrick         // binding, its section index is SHN_ABS, and it precedes the other
2112061da546Spatrick         // STB_LOCAL symbols for the file, if it is present.
2113061da546Spatrick         symbol_type = eSymbolTypeSourceFile;
2114061da546Spatrick         break;
2115061da546Spatrick 
2116061da546Spatrick       case STT_GNU_IFUNC:
2117061da546Spatrick         // The symbol is associated with an indirect function. The actual
2118061da546Spatrick         // function will be resolved if it is referenced.
2119061da546Spatrick         symbol_type = eSymbolTypeResolver;
2120061da546Spatrick         break;
2121061da546Spatrick       }
2122061da546Spatrick     }
2123061da546Spatrick 
2124061da546Spatrick     if (symbol_type == eSymbolTypeInvalid && symbol.getType() != STT_SECTION) {
2125061da546Spatrick       if (symbol_section_sp) {
2126061da546Spatrick         ConstString sect_name = symbol_section_sp->GetName();
2127061da546Spatrick         if (sect_name == text_section_name || sect_name == init_section_name ||
2128061da546Spatrick             sect_name == fini_section_name || sect_name == ctors_section_name ||
2129061da546Spatrick             sect_name == dtors_section_name) {
2130061da546Spatrick           symbol_type = eSymbolTypeCode;
2131061da546Spatrick         } else if (sect_name == data_section_name ||
2132061da546Spatrick                    sect_name == data2_section_name ||
2133061da546Spatrick                    sect_name == rodata_section_name ||
2134061da546Spatrick                    sect_name == rodata1_section_name ||
2135061da546Spatrick                    sect_name == bss_section_name) {
2136061da546Spatrick           symbol_type = eSymbolTypeData;
2137061da546Spatrick         }
2138061da546Spatrick       }
2139061da546Spatrick     }
2140061da546Spatrick 
2141061da546Spatrick     int64_t symbol_value_offset = 0;
2142061da546Spatrick     uint32_t additional_flags = 0;
2143061da546Spatrick 
2144061da546Spatrick     if (arch.IsValid()) {
2145061da546Spatrick       if (arch.GetMachine() == llvm::Triple::arm) {
2146061da546Spatrick         if (symbol.getBinding() == STB_LOCAL) {
2147061da546Spatrick           char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);
2148061da546Spatrick           if (symbol_type == eSymbolTypeCode) {
2149061da546Spatrick             switch (mapping_symbol) {
2150061da546Spatrick             case 'a':
2151061da546Spatrick               // $a[.<any>]* - marks an ARM instruction sequence
2152061da546Spatrick               m_address_class_map[symbol.st_value] = AddressClass::eCode;
2153061da546Spatrick               break;
2154061da546Spatrick             case 'b':
2155061da546Spatrick             case 't':
2156061da546Spatrick               // $b[.<any>]* - marks a THUMB BL instruction sequence
2157061da546Spatrick               // $t[.<any>]* - marks a THUMB instruction sequence
2158061da546Spatrick               m_address_class_map[symbol.st_value] =
2159061da546Spatrick                   AddressClass::eCodeAlternateISA;
2160061da546Spatrick               break;
2161061da546Spatrick             case 'd':
2162061da546Spatrick               // $d[.<any>]* - marks a data item sequence (e.g. lit pool)
2163061da546Spatrick               m_address_class_map[symbol.st_value] = AddressClass::eData;
2164061da546Spatrick               break;
2165061da546Spatrick             }
2166061da546Spatrick           }
2167061da546Spatrick           if (mapping_symbol)
2168061da546Spatrick             continue;
2169061da546Spatrick         }
2170061da546Spatrick       } else if (arch.GetMachine() == llvm::Triple::aarch64) {
2171061da546Spatrick         if (symbol.getBinding() == STB_LOCAL) {
2172061da546Spatrick           char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);
2173061da546Spatrick           if (symbol_type == eSymbolTypeCode) {
2174061da546Spatrick             switch (mapping_symbol) {
2175061da546Spatrick             case 'x':
2176061da546Spatrick               // $x[.<any>]* - marks an A64 instruction sequence
2177061da546Spatrick               m_address_class_map[symbol.st_value] = AddressClass::eCode;
2178061da546Spatrick               break;
2179061da546Spatrick             case 'd':
2180061da546Spatrick               // $d[.<any>]* - marks a data item sequence (e.g. lit pool)
2181061da546Spatrick               m_address_class_map[symbol.st_value] = AddressClass::eData;
2182061da546Spatrick               break;
2183061da546Spatrick             }
2184061da546Spatrick           }
2185061da546Spatrick           if (mapping_symbol)
2186061da546Spatrick             continue;
2187061da546Spatrick         }
2188061da546Spatrick       }
2189061da546Spatrick 
2190061da546Spatrick       if (arch.GetMachine() == llvm::Triple::arm) {
2191061da546Spatrick         if (symbol_type == eSymbolTypeCode) {
2192061da546Spatrick           if (symbol.st_value & 1) {
2193061da546Spatrick             // Subtracting 1 from the address effectively unsets the low order
2194061da546Spatrick             // bit, which results in the address actually pointing to the
2195061da546Spatrick             // beginning of the symbol. This delta will be used below in
2196061da546Spatrick             // conjunction with symbol.st_value to produce the final
2197061da546Spatrick             // symbol_value that we store in the symtab.
2198061da546Spatrick             symbol_value_offset = -1;
2199061da546Spatrick             m_address_class_map[symbol.st_value ^ 1] =
2200061da546Spatrick                 AddressClass::eCodeAlternateISA;
2201061da546Spatrick           } else {
2202061da546Spatrick             // This address is ARM
2203061da546Spatrick             m_address_class_map[symbol.st_value] = AddressClass::eCode;
2204061da546Spatrick           }
2205061da546Spatrick         }
2206061da546Spatrick       }
2207061da546Spatrick 
2208061da546Spatrick       /*
2209061da546Spatrick        * MIPS:
2210061da546Spatrick        * The bit #0 of an address is used for ISA mode (1 for microMIPS, 0 for
2211061da546Spatrick        * MIPS).
2212061da546Spatrick        * This allows processor to switch between microMIPS and MIPS without any
2213061da546Spatrick        * need
2214061da546Spatrick        * for special mode-control register. However, apart from .debug_line,
2215061da546Spatrick        * none of
2216061da546Spatrick        * the ELF/DWARF sections set the ISA bit (for symbol or section). Use
2217061da546Spatrick        * st_other
2218061da546Spatrick        * flag to check whether the symbol is microMIPS and then set the address
2219061da546Spatrick        * class
2220061da546Spatrick        * accordingly.
2221061da546Spatrick       */
2222061da546Spatrick       if (arch.IsMIPS()) {
2223061da546Spatrick         if (IS_MICROMIPS(symbol.st_other))
2224061da546Spatrick           m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
2225061da546Spatrick         else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode)) {
2226061da546Spatrick           symbol.st_value = symbol.st_value & (~1ull);
2227061da546Spatrick           m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
2228061da546Spatrick         } else {
2229061da546Spatrick           if (symbol_type == eSymbolTypeCode)
2230061da546Spatrick             m_address_class_map[symbol.st_value] = AddressClass::eCode;
2231061da546Spatrick           else if (symbol_type == eSymbolTypeData)
2232061da546Spatrick             m_address_class_map[symbol.st_value] = AddressClass::eData;
2233061da546Spatrick           else
2234061da546Spatrick             m_address_class_map[symbol.st_value] = AddressClass::eUnknown;
2235061da546Spatrick         }
2236061da546Spatrick       }
2237061da546Spatrick     }
2238061da546Spatrick 
2239061da546Spatrick     // symbol_value_offset may contain 0 for ARM symbols or -1 for THUMB
2240061da546Spatrick     // symbols. See above for more details.
2241061da546Spatrick     uint64_t symbol_value = symbol.st_value + symbol_value_offset;
2242061da546Spatrick 
2243061da546Spatrick     if (symbol_section_sp &&
2244061da546Spatrick         CalculateType() != ObjectFile::Type::eTypeObjectFile)
2245061da546Spatrick       symbol_value -= symbol_section_sp->GetFileAddress();
2246061da546Spatrick 
2247061da546Spatrick     if (symbol_section_sp && module_section_list &&
2248061da546Spatrick         module_section_list != section_list) {
2249061da546Spatrick       ConstString sect_name = symbol_section_sp->GetName();
2250061da546Spatrick       auto section_it = section_name_to_section.find(sect_name.GetCString());
2251061da546Spatrick       if (section_it == section_name_to_section.end())
2252061da546Spatrick         section_it =
2253061da546Spatrick             section_name_to_section
2254061da546Spatrick                 .emplace(sect_name.GetCString(),
2255061da546Spatrick                          module_section_list->FindSectionByName(sect_name))
2256061da546Spatrick                 .first;
2257061da546Spatrick       if (section_it->second)
2258061da546Spatrick         symbol_section_sp = section_it->second;
2259061da546Spatrick     }
2260061da546Spatrick 
2261061da546Spatrick     bool is_global = symbol.getBinding() == STB_GLOBAL;
2262061da546Spatrick     uint32_t flags = symbol.st_other << 8 | symbol.st_info | additional_flags;
2263061da546Spatrick     llvm::StringRef symbol_ref(symbol_name);
2264061da546Spatrick 
2265061da546Spatrick     // Symbol names may contain @VERSION suffixes. Find those and strip them
2266061da546Spatrick     // temporarily.
2267061da546Spatrick     size_t version_pos = symbol_ref.find('@');
2268061da546Spatrick     bool has_suffix = version_pos != llvm::StringRef::npos;
2269061da546Spatrick     llvm::StringRef symbol_bare = symbol_ref.substr(0, version_pos);
2270061da546Spatrick     Mangled mangled(symbol_bare);
2271061da546Spatrick 
2272061da546Spatrick     // Now append the suffix back to mangled and unmangled names. Only do it if
2273061da546Spatrick     // the demangling was successful (string is not empty).
2274061da546Spatrick     if (has_suffix) {
2275061da546Spatrick       llvm::StringRef suffix = symbol_ref.substr(version_pos);
2276061da546Spatrick 
2277061da546Spatrick       llvm::StringRef mangled_name = mangled.GetMangledName().GetStringRef();
2278061da546Spatrick       if (!mangled_name.empty())
2279061da546Spatrick         mangled.SetMangledName(ConstString((mangled_name + suffix).str()));
2280061da546Spatrick 
2281dda28197Spatrick       ConstString demangled = mangled.GetDemangledName();
2282061da546Spatrick       llvm::StringRef demangled_name = demangled.GetStringRef();
2283061da546Spatrick       if (!demangled_name.empty())
2284061da546Spatrick         mangled.SetDemangledName(ConstString((demangled_name + suffix).str()));
2285061da546Spatrick     }
2286061da546Spatrick 
2287061da546Spatrick     // In ELF all symbol should have a valid size but it is not true for some
2288061da546Spatrick     // function symbols coming from hand written assembly. As none of the
2289061da546Spatrick     // function symbol should have 0 size we try to calculate the size for
2290061da546Spatrick     // these symbols in the symtab with saying that their original size is not
2291061da546Spatrick     // valid.
2292061da546Spatrick     bool symbol_size_valid =
2293061da546Spatrick         symbol.st_size != 0 || symbol.getType() != STT_FUNC;
2294061da546Spatrick 
2295061da546Spatrick     Symbol dc_symbol(
2296061da546Spatrick         i + start_id, // ID is the original symbol table index.
2297061da546Spatrick         mangled,
2298061da546Spatrick         symbol_type,                    // Type of this symbol
2299061da546Spatrick         is_global,                      // Is this globally visible?
2300061da546Spatrick         false,                          // Is this symbol debug info?
2301061da546Spatrick         false,                          // Is this symbol a trampoline?
2302061da546Spatrick         false,                          // Is this symbol artificial?
2303061da546Spatrick         AddressRange(symbol_section_sp, // Section in which this symbol is
2304061da546Spatrick                                         // defined or null.
2305061da546Spatrick                      symbol_value,      // Offset in section or symbol value.
2306061da546Spatrick                      symbol.st_size),   // Size in bytes of this symbol.
2307061da546Spatrick         symbol_size_valid,              // Symbol size is valid
2308061da546Spatrick         has_suffix,                     // Contains linker annotations?
2309061da546Spatrick         flags);                         // Symbol flags.
2310061da546Spatrick     if (symbol.getBinding() == STB_WEAK)
2311061da546Spatrick       dc_symbol.SetIsWeak(true);
2312061da546Spatrick     symtab->AddSymbol(dc_symbol);
2313061da546Spatrick   }
2314061da546Spatrick   return i;
2315061da546Spatrick }
2316061da546Spatrick 
ParseSymbolTable(Symtab * symbol_table,user_id_t start_id,lldb_private::Section * symtab)2317061da546Spatrick unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,
2318061da546Spatrick                                          user_id_t start_id,
2319061da546Spatrick                                          lldb_private::Section *symtab) {
2320061da546Spatrick   if (symtab->GetObjectFile() != this) {
2321061da546Spatrick     // If the symbol table section is owned by a different object file, have it
2322061da546Spatrick     // do the parsing.
2323061da546Spatrick     ObjectFileELF *obj_file_elf =
2324061da546Spatrick         static_cast<ObjectFileELF *>(symtab->GetObjectFile());
2325061da546Spatrick     return obj_file_elf->ParseSymbolTable(symbol_table, start_id, symtab);
2326061da546Spatrick   }
2327061da546Spatrick 
2328061da546Spatrick   // Get section list for this object file.
2329061da546Spatrick   SectionList *section_list = m_sections_up.get();
2330061da546Spatrick   if (!section_list)
2331061da546Spatrick     return 0;
2332061da546Spatrick 
2333061da546Spatrick   user_id_t symtab_id = symtab->GetID();
2334061da546Spatrick   const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
2335061da546Spatrick   assert(symtab_hdr->sh_type == SHT_SYMTAB ||
2336061da546Spatrick          symtab_hdr->sh_type == SHT_DYNSYM);
2337061da546Spatrick 
2338061da546Spatrick   // sh_link: section header index of associated string table.
2339061da546Spatrick   user_id_t strtab_id = symtab_hdr->sh_link;
2340061da546Spatrick   Section *strtab = section_list->FindSectionByID(strtab_id).get();
2341061da546Spatrick 
2342061da546Spatrick   if (symtab && strtab) {
2343061da546Spatrick     assert(symtab->GetObjectFile() == this);
2344061da546Spatrick     assert(strtab->GetObjectFile() == this);
2345061da546Spatrick 
2346061da546Spatrick     DataExtractor symtab_data;
2347061da546Spatrick     DataExtractor strtab_data;
2348061da546Spatrick     if (ReadSectionData(symtab, symtab_data) &&
2349061da546Spatrick         ReadSectionData(strtab, strtab_data)) {
2350061da546Spatrick       size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize;
2351061da546Spatrick 
2352061da546Spatrick       return ParseSymbols(symbol_table, start_id, section_list, num_symbols,
2353061da546Spatrick                           symtab_data, strtab_data);
2354061da546Spatrick     }
2355061da546Spatrick   }
2356061da546Spatrick 
2357061da546Spatrick   return 0;
2358061da546Spatrick }
2359061da546Spatrick 
ParseDynamicSymbols()2360061da546Spatrick size_t ObjectFileELF::ParseDynamicSymbols() {
2361061da546Spatrick   if (m_dynamic_symbols.size())
2362061da546Spatrick     return m_dynamic_symbols.size();
2363061da546Spatrick 
2364061da546Spatrick   SectionList *section_list = GetSectionList();
2365061da546Spatrick   if (!section_list)
2366061da546Spatrick     return 0;
2367061da546Spatrick 
2368061da546Spatrick   // Find the SHT_DYNAMIC section.
2369061da546Spatrick   Section *dynsym =
2370061da546Spatrick       section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true)
2371061da546Spatrick           .get();
2372061da546Spatrick   if (!dynsym)
2373061da546Spatrick     return 0;
2374061da546Spatrick   assert(dynsym->GetObjectFile() == this);
2375061da546Spatrick 
2376061da546Spatrick   ELFDynamic symbol;
2377061da546Spatrick   DataExtractor dynsym_data;
2378061da546Spatrick   if (ReadSectionData(dynsym, dynsym_data)) {
2379061da546Spatrick     const lldb::offset_t section_size = dynsym_data.GetByteSize();
2380061da546Spatrick     lldb::offset_t cursor = 0;
2381061da546Spatrick 
2382061da546Spatrick     while (cursor < section_size) {
2383061da546Spatrick       if (!symbol.Parse(dynsym_data, &cursor))
2384061da546Spatrick         break;
2385061da546Spatrick 
2386061da546Spatrick       m_dynamic_symbols.push_back(symbol);
2387061da546Spatrick     }
2388061da546Spatrick   }
2389061da546Spatrick 
2390061da546Spatrick   return m_dynamic_symbols.size();
2391061da546Spatrick }
2392061da546Spatrick 
FindDynamicSymbol(unsigned tag)2393061da546Spatrick const ELFDynamic *ObjectFileELF::FindDynamicSymbol(unsigned tag) {
2394061da546Spatrick   if (!ParseDynamicSymbols())
2395061da546Spatrick     return nullptr;
2396061da546Spatrick 
2397061da546Spatrick   DynamicSymbolCollIter I = m_dynamic_symbols.begin();
2398061da546Spatrick   DynamicSymbolCollIter E = m_dynamic_symbols.end();
2399061da546Spatrick   for (; I != E; ++I) {
2400061da546Spatrick     ELFDynamic *symbol = &*I;
2401061da546Spatrick 
2402061da546Spatrick     if (symbol->d_tag == tag)
2403061da546Spatrick       return symbol;
2404061da546Spatrick   }
2405061da546Spatrick 
2406061da546Spatrick   return nullptr;
2407061da546Spatrick }
2408061da546Spatrick 
PLTRelocationType()2409061da546Spatrick unsigned ObjectFileELF::PLTRelocationType() {
2410061da546Spatrick   // DT_PLTREL
2411061da546Spatrick   //  This member specifies the type of relocation entry to which the
2412061da546Spatrick   //  procedure linkage table refers. The d_val member holds DT_REL or
2413061da546Spatrick   //  DT_RELA, as appropriate. All relocations in a procedure linkage table
2414061da546Spatrick   //  must use the same relocation.
2415061da546Spatrick   const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
2416061da546Spatrick 
2417061da546Spatrick   if (symbol)
2418061da546Spatrick     return symbol->d_val;
2419061da546Spatrick 
2420061da546Spatrick   return 0;
2421061da546Spatrick }
2422061da546Spatrick 
2423061da546Spatrick // Returns the size of the normal plt entries and the offset of the first
2424061da546Spatrick // normal plt entry. The 0th entry in the plt table is usually a resolution
2425061da546Spatrick // entry which have different size in some architectures then the rest of the
2426061da546Spatrick // plt entries.
2427061da546Spatrick static std::pair<uint64_t, uint64_t>
GetPltEntrySizeAndOffset(const ELFSectionHeader * rel_hdr,const ELFSectionHeader * plt_hdr)2428061da546Spatrick GetPltEntrySizeAndOffset(const ELFSectionHeader *rel_hdr,
2429061da546Spatrick                          const ELFSectionHeader *plt_hdr) {
2430061da546Spatrick   const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
2431061da546Spatrick 
2432061da546Spatrick   // Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are
2433061da546Spatrick   // 16 bytes. So round the entsize up by the alignment if addralign is set.
2434061da546Spatrick   elf_xword plt_entsize =
2435061da546Spatrick       plt_hdr->sh_addralign
2436061da546Spatrick           ? llvm::alignTo(plt_hdr->sh_entsize, plt_hdr->sh_addralign)
2437061da546Spatrick           : plt_hdr->sh_entsize;
2438061da546Spatrick 
2439061da546Spatrick   // Some linkers e.g ld for arm, fill plt_hdr->sh_entsize field incorrectly.
2440061da546Spatrick   // PLT entries relocation code in general requires multiple instruction and
2441061da546Spatrick   // should be greater than 4 bytes in most cases. Try to guess correct size
2442061da546Spatrick   // just in case.
2443061da546Spatrick   if (plt_entsize <= 4) {
2444061da546Spatrick     // The linker haven't set the plt_hdr->sh_entsize field. Try to guess the
2445061da546Spatrick     // size of the plt entries based on the number of entries and the size of
2446061da546Spatrick     // the plt section with the assumption that the size of the 0th entry is at
2447061da546Spatrick     // least as big as the size of the normal entries and it isn't much bigger
2448061da546Spatrick     // then that.
2449061da546Spatrick     if (plt_hdr->sh_addralign)
2450061da546Spatrick       plt_entsize = plt_hdr->sh_size / plt_hdr->sh_addralign /
2451061da546Spatrick                     (num_relocations + 1) * plt_hdr->sh_addralign;
2452061da546Spatrick     else
2453061da546Spatrick       plt_entsize = plt_hdr->sh_size / (num_relocations + 1);
2454061da546Spatrick   }
2455061da546Spatrick 
2456061da546Spatrick   elf_xword plt_offset = plt_hdr->sh_size - num_relocations * plt_entsize;
2457061da546Spatrick 
2458061da546Spatrick   return std::make_pair(plt_entsize, plt_offset);
2459061da546Spatrick }
2460061da546Spatrick 
ParsePLTRelocations(Symtab * symbol_table,user_id_t start_id,unsigned rel_type,const ELFHeader * hdr,const ELFSectionHeader * rel_hdr,const ELFSectionHeader * plt_hdr,const ELFSectionHeader * sym_hdr,const lldb::SectionSP & plt_section_sp,DataExtractor & rel_data,DataExtractor & symtab_data,DataExtractor & strtab_data)2461061da546Spatrick static unsigned ParsePLTRelocations(
2462061da546Spatrick     Symtab *symbol_table, user_id_t start_id, unsigned rel_type,
2463061da546Spatrick     const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
2464061da546Spatrick     const ELFSectionHeader *plt_hdr, const ELFSectionHeader *sym_hdr,
2465061da546Spatrick     const lldb::SectionSP &plt_section_sp, DataExtractor &rel_data,
2466061da546Spatrick     DataExtractor &symtab_data, DataExtractor &strtab_data) {
2467061da546Spatrick   ELFRelocation rel(rel_type);
2468061da546Spatrick   ELFSymbol symbol;
2469061da546Spatrick   lldb::offset_t offset = 0;
2470061da546Spatrick 
2471061da546Spatrick   uint64_t plt_offset, plt_entsize;
2472061da546Spatrick   std::tie(plt_entsize, plt_offset) =
2473061da546Spatrick       GetPltEntrySizeAndOffset(rel_hdr, plt_hdr);
2474061da546Spatrick   const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
2475061da546Spatrick 
2476061da546Spatrick   typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
2477061da546Spatrick   reloc_info_fn reloc_type;
2478061da546Spatrick   reloc_info_fn reloc_symbol;
2479061da546Spatrick 
2480061da546Spatrick   if (hdr->Is32Bit()) {
2481061da546Spatrick     reloc_type = ELFRelocation::RelocType32;
2482061da546Spatrick     reloc_symbol = ELFRelocation::RelocSymbol32;
2483061da546Spatrick   } else {
2484061da546Spatrick     reloc_type = ELFRelocation::RelocType64;
2485061da546Spatrick     reloc_symbol = ELFRelocation::RelocSymbol64;
2486061da546Spatrick   }
2487061da546Spatrick 
2488061da546Spatrick   unsigned slot_type = hdr->GetRelocationJumpSlotType();
2489061da546Spatrick   unsigned i;
2490061da546Spatrick   for (i = 0; i < num_relocations; ++i) {
2491061da546Spatrick     if (!rel.Parse(rel_data, &offset))
2492061da546Spatrick       break;
2493061da546Spatrick 
2494061da546Spatrick     if (reloc_type(rel) != slot_type)
2495061da546Spatrick       continue;
2496061da546Spatrick 
2497061da546Spatrick     lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
2498061da546Spatrick     if (!symbol.Parse(symtab_data, &symbol_offset))
2499061da546Spatrick       break;
2500061da546Spatrick 
2501061da546Spatrick     const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
2502061da546Spatrick     uint64_t plt_index = plt_offset + i * plt_entsize;
2503061da546Spatrick 
2504061da546Spatrick     Symbol jump_symbol(
2505061da546Spatrick         i + start_id,          // Symbol table index
2506061da546Spatrick         symbol_name,           // symbol name.
2507061da546Spatrick         eSymbolTypeTrampoline, // Type of this symbol
2508061da546Spatrick         false,                 // Is this globally visible?
2509061da546Spatrick         false,                 // Is this symbol debug info?
2510061da546Spatrick         true,                  // Is this symbol a trampoline?
2511061da546Spatrick         true,                  // Is this symbol artificial?
2512061da546Spatrick         plt_section_sp, // Section in which this symbol is defined or null.
2513061da546Spatrick         plt_index,      // Offset in section or symbol value.
2514061da546Spatrick         plt_entsize,    // Size in bytes of this symbol.
2515061da546Spatrick         true,           // Size is valid
2516061da546Spatrick         false,          // Contains linker annotations?
2517061da546Spatrick         0);             // Symbol flags.
2518061da546Spatrick 
2519061da546Spatrick     symbol_table->AddSymbol(jump_symbol);
2520061da546Spatrick   }
2521061da546Spatrick 
2522061da546Spatrick   return i;
2523061da546Spatrick }
2524061da546Spatrick 
2525061da546Spatrick unsigned
ParseTrampolineSymbols(Symtab * symbol_table,user_id_t start_id,const ELFSectionHeaderInfo * rel_hdr,user_id_t rel_id)2526061da546Spatrick ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id,
2527061da546Spatrick                                       const ELFSectionHeaderInfo *rel_hdr,
2528061da546Spatrick                                       user_id_t rel_id) {
2529061da546Spatrick   assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
2530061da546Spatrick 
2531061da546Spatrick   // The link field points to the associated symbol table.
2532061da546Spatrick   user_id_t symtab_id = rel_hdr->sh_link;
2533061da546Spatrick 
2534061da546Spatrick   // If the link field doesn't point to the appropriate symbol name table then
2535061da546Spatrick   // try to find it by name as some compiler don't fill in the link fields.
2536061da546Spatrick   if (!symtab_id)
2537061da546Spatrick     symtab_id = GetSectionIndexByName(".dynsym");
2538061da546Spatrick 
2539061da546Spatrick   // Get PLT section.  We cannot use rel_hdr->sh_info, since current linkers
2540061da546Spatrick   // point that to the .got.plt or .got section instead of .plt.
2541061da546Spatrick   user_id_t plt_id = GetSectionIndexByName(".plt");
2542061da546Spatrick 
2543061da546Spatrick   if (!symtab_id || !plt_id)
2544061da546Spatrick     return 0;
2545061da546Spatrick 
2546061da546Spatrick   const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id);
2547061da546Spatrick   if (!plt_hdr)
2548061da546Spatrick     return 0;
2549061da546Spatrick 
2550061da546Spatrick   const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id);
2551061da546Spatrick   if (!sym_hdr)
2552061da546Spatrick     return 0;
2553061da546Spatrick 
2554061da546Spatrick   SectionList *section_list = m_sections_up.get();
2555061da546Spatrick   if (!section_list)
2556061da546Spatrick     return 0;
2557061da546Spatrick 
2558061da546Spatrick   Section *rel_section = section_list->FindSectionByID(rel_id).get();
2559061da546Spatrick   if (!rel_section)
2560061da546Spatrick     return 0;
2561061da546Spatrick 
2562061da546Spatrick   SectionSP plt_section_sp(section_list->FindSectionByID(plt_id));
2563061da546Spatrick   if (!plt_section_sp)
2564061da546Spatrick     return 0;
2565061da546Spatrick 
2566061da546Spatrick   Section *symtab = section_list->FindSectionByID(symtab_id).get();
2567061da546Spatrick   if (!symtab)
2568061da546Spatrick     return 0;
2569061da546Spatrick 
2570061da546Spatrick   // sh_link points to associated string table.
2571061da546Spatrick   Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link).get();
2572061da546Spatrick   if (!strtab)
2573061da546Spatrick     return 0;
2574061da546Spatrick 
2575061da546Spatrick   DataExtractor rel_data;
2576061da546Spatrick   if (!ReadSectionData(rel_section, rel_data))
2577061da546Spatrick     return 0;
2578061da546Spatrick 
2579061da546Spatrick   DataExtractor symtab_data;
2580061da546Spatrick   if (!ReadSectionData(symtab, symtab_data))
2581061da546Spatrick     return 0;
2582061da546Spatrick 
2583061da546Spatrick   DataExtractor strtab_data;
2584061da546Spatrick   if (!ReadSectionData(strtab, strtab_data))
2585061da546Spatrick     return 0;
2586061da546Spatrick 
2587061da546Spatrick   unsigned rel_type = PLTRelocationType();
2588061da546Spatrick   if (!rel_type)
2589061da546Spatrick     return 0;
2590061da546Spatrick 
2591061da546Spatrick   return ParsePLTRelocations(symbol_table, start_id, rel_type, &m_header,
2592061da546Spatrick                              rel_hdr, plt_hdr, sym_hdr, plt_section_sp,
2593061da546Spatrick                              rel_data, symtab_data, strtab_data);
2594061da546Spatrick }
2595061da546Spatrick 
ApplyELF64ABS64Relocation(Symtab * symtab,ELFRelocation & rel,DataExtractor & debug_data,Section * rel_section)2596*101d251dSrobert static void ApplyELF64ABS64Relocation(Symtab *symtab, ELFRelocation &rel,
2597*101d251dSrobert                                       DataExtractor &debug_data,
2598*101d251dSrobert                                       Section *rel_section) {
2599*101d251dSrobert   Symbol *symbol = symtab->FindSymbolByID(ELFRelocation::RelocSymbol64(rel));
2600*101d251dSrobert   if (symbol) {
2601*101d251dSrobert     addr_t value = symbol->GetAddressRef().GetFileAddress();
2602*101d251dSrobert     DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
2603*101d251dSrobert     // ObjectFileELF creates a WritableDataBuffer in CreateInstance.
2604*101d251dSrobert     WritableDataBuffer *data_buffer =
2605*101d251dSrobert         llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
2606*101d251dSrobert     uint64_t *dst = reinterpret_cast<uint64_t *>(
2607*101d251dSrobert         data_buffer->GetBytes() + rel_section->GetFileOffset() +
2608*101d251dSrobert         ELFRelocation::RelocOffset64(rel));
2609*101d251dSrobert     uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel);
2610*101d251dSrobert     memcpy(dst, &val_offset, sizeof(uint64_t));
2611*101d251dSrobert   }
2612*101d251dSrobert }
2613*101d251dSrobert 
ApplyELF64ABS32Relocation(Symtab * symtab,ELFRelocation & rel,DataExtractor & debug_data,Section * rel_section,bool is_signed)2614*101d251dSrobert static void ApplyELF64ABS32Relocation(Symtab *symtab, ELFRelocation &rel,
2615*101d251dSrobert                                       DataExtractor &debug_data,
2616*101d251dSrobert                                       Section *rel_section, bool is_signed) {
2617*101d251dSrobert   Symbol *symbol = symtab->FindSymbolByID(ELFRelocation::RelocSymbol64(rel));
2618*101d251dSrobert   if (symbol) {
2619*101d251dSrobert     addr_t value = symbol->GetAddressRef().GetFileAddress();
2620*101d251dSrobert     value += ELFRelocation::RelocAddend32(rel);
2621*101d251dSrobert     if ((!is_signed && (value > UINT32_MAX)) ||
2622*101d251dSrobert         (is_signed &&
2623*101d251dSrobert          ((int64_t)value > INT32_MAX || (int64_t)value < INT32_MIN))) {
2624*101d251dSrobert       Log *log = GetLog(LLDBLog::Modules);
2625*101d251dSrobert       LLDB_LOGF(log, "Failed to apply debug info relocations");
2626*101d251dSrobert       return;
2627*101d251dSrobert     }
2628*101d251dSrobert     uint32_t truncated_addr = (value & 0xFFFFFFFF);
2629*101d251dSrobert     DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
2630*101d251dSrobert     // ObjectFileELF creates a WritableDataBuffer in CreateInstance.
2631*101d251dSrobert     WritableDataBuffer *data_buffer =
2632*101d251dSrobert         llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
2633*101d251dSrobert     uint32_t *dst = reinterpret_cast<uint32_t *>(
2634*101d251dSrobert         data_buffer->GetBytes() + rel_section->GetFileOffset() +
2635*101d251dSrobert         ELFRelocation::RelocOffset32(rel));
2636*101d251dSrobert     memcpy(dst, &truncated_addr, sizeof(uint32_t));
2637*101d251dSrobert   }
2638*101d251dSrobert }
2639*101d251dSrobert 
ApplyRelocations(Symtab * symtab,const ELFHeader * hdr,const ELFSectionHeader * rel_hdr,const ELFSectionHeader * symtab_hdr,const ELFSectionHeader * debug_hdr,DataExtractor & rel_data,DataExtractor & symtab_data,DataExtractor & debug_data,Section * rel_section)2640061da546Spatrick unsigned ObjectFileELF::ApplyRelocations(
2641061da546Spatrick     Symtab *symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
2642061da546Spatrick     const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr,
2643061da546Spatrick     DataExtractor &rel_data, DataExtractor &symtab_data,
2644061da546Spatrick     DataExtractor &debug_data, Section *rel_section) {
2645061da546Spatrick   ELFRelocation rel(rel_hdr->sh_type);
2646061da546Spatrick   lldb::addr_t offset = 0;
2647061da546Spatrick   const unsigned num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
2648061da546Spatrick   typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
2649061da546Spatrick   reloc_info_fn reloc_type;
2650061da546Spatrick   reloc_info_fn reloc_symbol;
2651061da546Spatrick 
2652061da546Spatrick   if (hdr->Is32Bit()) {
2653061da546Spatrick     reloc_type = ELFRelocation::RelocType32;
2654061da546Spatrick     reloc_symbol = ELFRelocation::RelocSymbol32;
2655061da546Spatrick   } else {
2656061da546Spatrick     reloc_type = ELFRelocation::RelocType64;
2657061da546Spatrick     reloc_symbol = ELFRelocation::RelocSymbol64;
2658061da546Spatrick   }
2659061da546Spatrick 
2660061da546Spatrick   for (unsigned i = 0; i < num_relocations; ++i) {
2661*101d251dSrobert     if (!rel.Parse(rel_data, &offset)) {
2662*101d251dSrobert       GetModule()->ReportError(".rel{0}[{1:d}] failed to parse relocation",
2663*101d251dSrobert                                rel_section->GetName().AsCString(), i);
2664061da546Spatrick       break;
2665*101d251dSrobert     }
2666061da546Spatrick     Symbol *symbol = nullptr;
2667061da546Spatrick 
2668061da546Spatrick     if (hdr->Is32Bit()) {
2669061da546Spatrick       switch (reloc_type(rel)) {
2670061da546Spatrick       case R_386_32:
2671*101d251dSrobert         symbol = symtab->FindSymbolByID(reloc_symbol(rel));
2672*101d251dSrobert         if (symbol) {
2673*101d251dSrobert           addr_t f_offset =
2674*101d251dSrobert               rel_section->GetFileOffset() + ELFRelocation::RelocOffset32(rel);
2675*101d251dSrobert           DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
2676*101d251dSrobert           // ObjectFileELF creates a WritableDataBuffer in CreateInstance.
2677*101d251dSrobert           WritableDataBuffer *data_buffer =
2678*101d251dSrobert               llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
2679*101d251dSrobert           uint32_t *dst = reinterpret_cast<uint32_t *>(
2680*101d251dSrobert               data_buffer->GetBytes() + f_offset);
2681*101d251dSrobert 
2682*101d251dSrobert           addr_t value = symbol->GetAddressRef().GetFileAddress();
2683*101d251dSrobert           if (rel.IsRela()) {
2684*101d251dSrobert             value += ELFRelocation::RelocAddend32(rel);
2685*101d251dSrobert           } else {
2686*101d251dSrobert             value += *dst;
2687*101d251dSrobert           }
2688*101d251dSrobert           *dst = value;
2689*101d251dSrobert         } else {
2690*101d251dSrobert           GetModule()->ReportError(".rel{0}[{1}] unknown symbol id: {2:d}",
2691*101d251dSrobert                                    rel_section->GetName().AsCString(), i,
2692*101d251dSrobert                                    reloc_symbol(rel));
2693*101d251dSrobert         }
2694*101d251dSrobert         break;
2695061da546Spatrick       case R_386_PC32:
2696061da546Spatrick       default:
2697*101d251dSrobert         GetModule()->ReportError("unsupported 32-bit relocation:"
2698*101d251dSrobert                                  " .rel{0}[{1}], type {2}",
2699*101d251dSrobert                                  rel_section->GetName().AsCString(), i,
2700*101d251dSrobert                                  reloc_type(rel));
2701061da546Spatrick       }
2702061da546Spatrick     } else {
2703*101d251dSrobert       switch (hdr->e_machine) {
2704*101d251dSrobert       case llvm::ELF::EM_AARCH64:
2705061da546Spatrick         switch (reloc_type(rel)) {
2706061da546Spatrick         case R_AARCH64_ABS64:
2707*101d251dSrobert           ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section);
2708*101d251dSrobert           break;
2709*101d251dSrobert         case R_AARCH64_ABS32:
2710*101d251dSrobert           ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, true);
2711*101d251dSrobert           break;
2712*101d251dSrobert         default:
2713*101d251dSrobert           assert(false && "unexpected relocation type");
2714061da546Spatrick         }
2715061da546Spatrick         break;
2716*101d251dSrobert       case llvm::ELF::EM_LOONGARCH:
2717*101d251dSrobert         switch (reloc_type(rel)) {
2718*101d251dSrobert         case R_LARCH_64:
2719*101d251dSrobert           ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section);
2720*101d251dSrobert           break;
2721*101d251dSrobert         case R_LARCH_32:
2722*101d251dSrobert           ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, true);
2723*101d251dSrobert           break;
2724*101d251dSrobert         default:
2725*101d251dSrobert           assert(false && "unexpected relocation type");
2726061da546Spatrick         }
2727*101d251dSrobert         break;
2728*101d251dSrobert       case llvm::ELF::EM_X86_64:
2729*101d251dSrobert         switch (reloc_type(rel)) {
2730*101d251dSrobert         case R_X86_64_64:
2731*101d251dSrobert           ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section);
2732*101d251dSrobert           break;
2733061da546Spatrick         case R_X86_64_32:
2734*101d251dSrobert           ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section,
2735*101d251dSrobert                                     false);
2736*101d251dSrobert           break;
2737061da546Spatrick         case R_X86_64_32S:
2738*101d251dSrobert           ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, true);
2739061da546Spatrick           break;
2740061da546Spatrick         case R_X86_64_PC32:
2741061da546Spatrick         default:
2742061da546Spatrick           assert(false && "unexpected relocation type");
2743061da546Spatrick         }
2744*101d251dSrobert         break;
2745*101d251dSrobert       default:
2746*101d251dSrobert         assert(false && "unsupported machine");
2747*101d251dSrobert       }
2748061da546Spatrick     }
2749061da546Spatrick   }
2750061da546Spatrick 
2751061da546Spatrick   return 0;
2752061da546Spatrick }
2753061da546Spatrick 
RelocateDebugSections(const ELFSectionHeader * rel_hdr,user_id_t rel_id,lldb_private::Symtab * thetab)2754061da546Spatrick unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,
2755061da546Spatrick                                               user_id_t rel_id,
2756061da546Spatrick                                               lldb_private::Symtab *thetab) {
2757061da546Spatrick   assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
2758061da546Spatrick 
2759061da546Spatrick   // Parse in the section list if needed.
2760061da546Spatrick   SectionList *section_list = GetSectionList();
2761061da546Spatrick   if (!section_list)
2762061da546Spatrick     return 0;
2763061da546Spatrick 
2764061da546Spatrick   user_id_t symtab_id = rel_hdr->sh_link;
2765061da546Spatrick   user_id_t debug_id = rel_hdr->sh_info;
2766061da546Spatrick 
2767061da546Spatrick   const ELFSectionHeader *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
2768061da546Spatrick   if (!symtab_hdr)
2769061da546Spatrick     return 0;
2770061da546Spatrick 
2771061da546Spatrick   const ELFSectionHeader *debug_hdr = GetSectionHeaderByIndex(debug_id);
2772061da546Spatrick   if (!debug_hdr)
2773061da546Spatrick     return 0;
2774061da546Spatrick 
2775061da546Spatrick   Section *rel = section_list->FindSectionByID(rel_id).get();
2776061da546Spatrick   if (!rel)
2777061da546Spatrick     return 0;
2778061da546Spatrick 
2779061da546Spatrick   Section *symtab = section_list->FindSectionByID(symtab_id).get();
2780061da546Spatrick   if (!symtab)
2781061da546Spatrick     return 0;
2782061da546Spatrick 
2783061da546Spatrick   Section *debug = section_list->FindSectionByID(debug_id).get();
2784061da546Spatrick   if (!debug)
2785061da546Spatrick     return 0;
2786061da546Spatrick 
2787061da546Spatrick   DataExtractor rel_data;
2788061da546Spatrick   DataExtractor symtab_data;
2789061da546Spatrick   DataExtractor debug_data;
2790061da546Spatrick 
2791061da546Spatrick   if (GetData(rel->GetFileOffset(), rel->GetFileSize(), rel_data) &&
2792061da546Spatrick       GetData(symtab->GetFileOffset(), symtab->GetFileSize(), symtab_data) &&
2793061da546Spatrick       GetData(debug->GetFileOffset(), debug->GetFileSize(), debug_data)) {
2794061da546Spatrick     ApplyRelocations(thetab, &m_header, rel_hdr, symtab_hdr, debug_hdr,
2795061da546Spatrick                      rel_data, symtab_data, debug_data, debug);
2796061da546Spatrick   }
2797061da546Spatrick 
2798061da546Spatrick   return 0;
2799061da546Spatrick }
2800061da546Spatrick 
ParseSymtab(Symtab & lldb_symtab)2801*101d251dSrobert void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
2802061da546Spatrick   ModuleSP module_sp(GetModule());
2803061da546Spatrick   if (!module_sp)
2804*101d251dSrobert     return;
2805061da546Spatrick 
2806*101d251dSrobert   Progress progress(
2807*101d251dSrobert       llvm::formatv("Parsing symbol table for {0}",
2808a0747c9fSpatrick                     m_file.GetFilename().AsCString("<Unknown>")));
2809*101d251dSrobert   ElapsedTime elapsed(module_sp->GetSymtabParseTime());
2810a0747c9fSpatrick 
2811061da546Spatrick   // We always want to use the main object file so we (hopefully) only have one
2812061da546Spatrick   // cached copy of our symtab, dynamic sections, etc.
2813061da546Spatrick   ObjectFile *module_obj_file = module_sp->GetObjectFile();
2814061da546Spatrick   if (module_obj_file && module_obj_file != this)
2815*101d251dSrobert     return module_obj_file->ParseSymtab(lldb_symtab);
2816061da546Spatrick 
2817061da546Spatrick   SectionList *section_list = module_sp->GetSectionList();
2818061da546Spatrick   if (!section_list)
2819*101d251dSrobert     return;
2820061da546Spatrick 
2821061da546Spatrick   uint64_t symbol_id = 0;
2822061da546Spatrick 
2823061da546Spatrick   // Sharable objects and dynamic executables usually have 2 distinct symbol
2824061da546Spatrick   // tables, one named ".symtab", and the other ".dynsym". The dynsym is a
2825061da546Spatrick   // smaller version of the symtab that only contains global symbols. The
2826061da546Spatrick   // information found in the dynsym is therefore also found in the symtab,
2827061da546Spatrick   // while the reverse is not necessarily true.
2828061da546Spatrick   Section *symtab =
2829061da546Spatrick       section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
2830*101d251dSrobert   if (symtab)
2831*101d251dSrobert     symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, symtab);
2832061da546Spatrick 
2833061da546Spatrick   // The symtab section is non-allocable and can be stripped, while the
2834061da546Spatrick   // .dynsym section which should always be always be there. To support the
2835061da546Spatrick   // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo
2836061da546Spatrick   // section, nomatter if .symtab was already parsed or not. This is because
2837061da546Spatrick   // minidebuginfo normally removes the .symtab symbols which have their
2838061da546Spatrick   // matching .dynsym counterparts.
2839061da546Spatrick   if (!symtab ||
2840061da546Spatrick       GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) {
2841061da546Spatrick     Section *dynsym =
2842061da546Spatrick         section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
2843061da546Spatrick             .get();
2844*101d251dSrobert     if (dynsym)
2845*101d251dSrobert       symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, dynsym);
2846061da546Spatrick   }
2847061da546Spatrick 
2848061da546Spatrick   // DT_JMPREL
2849061da546Spatrick   //      If present, this entry's d_ptr member holds the address of
2850061da546Spatrick   //      relocation
2851061da546Spatrick   //      entries associated solely with the procedure linkage table.
2852061da546Spatrick   //      Separating
2853061da546Spatrick   //      these relocation entries lets the dynamic linker ignore them during
2854061da546Spatrick   //      process initialization, if lazy binding is enabled. If this entry is
2855061da546Spatrick   //      present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
2856061da546Spatrick   //      also be present.
2857061da546Spatrick   const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
2858061da546Spatrick   if (symbol) {
2859adae0cfdSpatrick     const ELFDynamic *pltrelsz = FindDynamicSymbol(DT_PLTRELSZ);
2860adae0cfdSpatrick     assert(pltrelsz != NULL);
2861061da546Spatrick     // Synthesize trampoline symbols to help navigate the PLT.
2862061da546Spatrick     addr_t addr = symbol->d_ptr;
2863061da546Spatrick     Section *reloc_section =
2864061da546Spatrick         section_list->FindSectionContainingFileAddress(addr).get();
2865adae0cfdSpatrick     if (reloc_section && pltrelsz->d_val > 0) {
2866061da546Spatrick       user_id_t reloc_id = reloc_section->GetID();
2867061da546Spatrick       const ELFSectionHeaderInfo *reloc_header =
2868061da546Spatrick           GetSectionHeaderByIndex(reloc_id);
2869*101d251dSrobert       if (reloc_header)
2870*101d251dSrobert         ParseTrampolineSymbols(&lldb_symtab, symbol_id, reloc_header, reloc_id);
2871061da546Spatrick     }
2872a0747c9fSpatrick   }
2873061da546Spatrick 
2874061da546Spatrick   if (DWARFCallFrameInfo *eh_frame =
2875061da546Spatrick           GetModule()->GetUnwindTable().GetEHFrameInfo()) {
2876*101d251dSrobert     ParseUnwindSymbols(&lldb_symtab, eh_frame);
2877061da546Spatrick   }
2878061da546Spatrick 
2879061da546Spatrick   // In the event that there's no symbol entry for the entry point we'll
2880dda28197Spatrick   // artificially create one. We delegate to the symtab object the figuring
2881061da546Spatrick   // out of the proper size, this will usually make it span til the next
2882061da546Spatrick   // symbol it finds in the section. This means that if there are missing
2883061da546Spatrick   // symbols the entry point might span beyond its function definition.
2884061da546Spatrick   // We're fine with this as it doesn't make it worse than not having a
2885061da546Spatrick   // symbol entry at all.
2886061da546Spatrick   if (CalculateType() == eTypeExecutable) {
2887061da546Spatrick     ArchSpec arch = GetArchitecture();
2888061da546Spatrick     auto entry_point_addr = GetEntryPointAddress();
2889061da546Spatrick     bool is_valid_entry_point =
2890061da546Spatrick         entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
2891061da546Spatrick     addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
2892*101d251dSrobert     if (is_valid_entry_point && !lldb_symtab.FindSymbolContainingFileAddress(
2893061da546Spatrick                                     entry_point_file_addr)) {
2894*101d251dSrobert       uint64_t symbol_id = lldb_symtab.GetNumSymbols();
2895a0747c9fSpatrick       // Don't set the name for any synthetic symbols, the Symbol
2896a0747c9fSpatrick       // object will generate one if needed when the name is accessed
2897a0747c9fSpatrick       // via accessors.
2898a0747c9fSpatrick       SectionSP section_sp = entry_point_addr.GetSection();
2899a0747c9fSpatrick       Symbol symbol(
2900a0747c9fSpatrick           /*symID=*/symbol_id,
2901a0747c9fSpatrick           /*name=*/llvm::StringRef(), // Name will be auto generated.
2902a0747c9fSpatrick           /*type=*/eSymbolTypeCode,
2903a0747c9fSpatrick           /*external=*/true,
2904a0747c9fSpatrick           /*is_debug=*/false,
2905a0747c9fSpatrick           /*is_trampoline=*/false,
2906a0747c9fSpatrick           /*is_artificial=*/true,
2907a0747c9fSpatrick           /*section_sp=*/section_sp,
2908a0747c9fSpatrick           /*offset=*/0,
2909a0747c9fSpatrick           /*size=*/0, // FDE can span multiple symbols so don't use its size.
2910a0747c9fSpatrick           /*size_is_valid=*/false,
2911a0747c9fSpatrick           /*contains_linker_annotations=*/false,
2912a0747c9fSpatrick           /*flags=*/0);
2913061da546Spatrick       // When the entry point is arm thumb we need to explicitly set its
2914061da546Spatrick       // class address to reflect that. This is important because expression
2915061da546Spatrick       // evaluation relies on correctly setting a breakpoint at this
2916061da546Spatrick       // address.
2917061da546Spatrick       if (arch.GetMachine() == llvm::Triple::arm &&
2918a0747c9fSpatrick           (entry_point_file_addr & 1)) {
2919a0747c9fSpatrick         symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1);
2920061da546Spatrick         m_address_class_map[entry_point_file_addr ^ 1] =
2921061da546Spatrick             AddressClass::eCodeAlternateISA;
2922a0747c9fSpatrick       } else {
2923061da546Spatrick         m_address_class_map[entry_point_file_addr] = AddressClass::eCode;
2924061da546Spatrick       }
2925*101d251dSrobert       lldb_symtab.AddSymbol(symbol);
2926a0747c9fSpatrick     }
2927061da546Spatrick   }
2928061da546Spatrick }
2929061da546Spatrick 
RelocateSection(lldb_private::Section * section)2930061da546Spatrick void ObjectFileELF::RelocateSection(lldb_private::Section *section)
2931061da546Spatrick {
2932061da546Spatrick   static const char *debug_prefix = ".debug";
2933061da546Spatrick 
2934061da546Spatrick   // Set relocated bit so we stop getting called, regardless of whether we
2935061da546Spatrick   // actually relocate.
2936061da546Spatrick   section->SetIsRelocated(true);
2937061da546Spatrick 
2938061da546Spatrick   // We only relocate in ELF relocatable files
2939061da546Spatrick   if (CalculateType() != eTypeObjectFile)
2940061da546Spatrick     return;
2941061da546Spatrick 
2942061da546Spatrick   const char *section_name = section->GetName().GetCString();
2943061da546Spatrick   // Can't relocate that which can't be named
2944061da546Spatrick   if (section_name == nullptr)
2945061da546Spatrick     return;
2946061da546Spatrick 
2947061da546Spatrick   // We don't relocate non-debug sections at the moment
2948061da546Spatrick   if (strncmp(section_name, debug_prefix, strlen(debug_prefix)))
2949061da546Spatrick     return;
2950061da546Spatrick 
2951061da546Spatrick   // Relocation section names to look for
2952061da546Spatrick   std::string needle = std::string(".rel") + section_name;
2953061da546Spatrick   std::string needlea = std::string(".rela") + section_name;
2954061da546Spatrick 
2955061da546Spatrick   for (SectionHeaderCollIter I = m_section_headers.begin();
2956061da546Spatrick        I != m_section_headers.end(); ++I) {
2957061da546Spatrick     if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL) {
2958061da546Spatrick       const char *hay_name = I->section_name.GetCString();
2959061da546Spatrick       if (hay_name == nullptr)
2960061da546Spatrick         continue;
2961061da546Spatrick       if (needle == hay_name || needlea == hay_name) {
2962061da546Spatrick         const ELFSectionHeader &reloc_header = *I;
2963061da546Spatrick         user_id_t reloc_id = SectionIndex(I);
2964061da546Spatrick         RelocateDebugSections(&reloc_header, reloc_id, GetSymtab());
2965061da546Spatrick         break;
2966061da546Spatrick       }
2967061da546Spatrick     }
2968061da546Spatrick   }
2969061da546Spatrick }
2970061da546Spatrick 
ParseUnwindSymbols(Symtab * symbol_table,DWARFCallFrameInfo * eh_frame)2971061da546Spatrick void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
2972061da546Spatrick                                        DWARFCallFrameInfo *eh_frame) {
2973061da546Spatrick   SectionList *section_list = GetSectionList();
2974061da546Spatrick   if (!section_list)
2975061da546Spatrick     return;
2976061da546Spatrick 
2977061da546Spatrick   // First we save the new symbols into a separate list and add them to the
2978dda28197Spatrick   // symbol table after we collected all symbols we want to add. This is
2979061da546Spatrick   // neccessary because adding a new symbol invalidates the internal index of
2980061da546Spatrick   // the symtab what causing the next lookup to be slow because it have to
2981061da546Spatrick   // recalculate the index first.
2982061da546Spatrick   std::vector<Symbol> new_symbols;
2983061da546Spatrick 
2984a0747c9fSpatrick   size_t num_symbols = symbol_table->GetNumSymbols();
2985a0747c9fSpatrick   uint64_t last_symbol_id =
2986a0747c9fSpatrick       num_symbols ? symbol_table->SymbolAtIndex(num_symbols - 1)->GetID() : 0;
2987a0747c9fSpatrick   eh_frame->ForEachFDEEntries([&](lldb::addr_t file_addr, uint32_t size,
2988a0747c9fSpatrick                                   dw_offset_t) {
2989061da546Spatrick     Symbol *symbol = symbol_table->FindSymbolAtFileAddress(file_addr);
2990061da546Spatrick     if (symbol) {
2991061da546Spatrick       if (!symbol->GetByteSizeIsValid()) {
2992061da546Spatrick         symbol->SetByteSize(size);
2993061da546Spatrick         symbol->SetSizeIsSynthesized(true);
2994061da546Spatrick       }
2995061da546Spatrick     } else {
2996061da546Spatrick       SectionSP section_sp =
2997061da546Spatrick           section_list->FindSectionContainingFileAddress(file_addr);
2998061da546Spatrick       if (section_sp) {
2999061da546Spatrick         addr_t offset = file_addr - section_sp->GetFileAddress();
3000a0747c9fSpatrick         uint64_t symbol_id = ++last_symbol_id;
3001a0747c9fSpatrick         // Don't set the name for any synthetic symbols, the Symbol
3002a0747c9fSpatrick         // object will generate one if needed when the name is accessed
3003a0747c9fSpatrick         // via accessors.
3004061da546Spatrick         Symbol eh_symbol(
3005a0747c9fSpatrick             /*symID=*/symbol_id,
3006a0747c9fSpatrick             /*name=*/llvm::StringRef(), // Name will be auto generated.
3007a0747c9fSpatrick             /*type=*/eSymbolTypeCode,
3008a0747c9fSpatrick             /*external=*/true,
3009a0747c9fSpatrick             /*is_debug=*/false,
3010a0747c9fSpatrick             /*is_trampoline=*/false,
3011a0747c9fSpatrick             /*is_artificial=*/true,
3012a0747c9fSpatrick             /*section_sp=*/section_sp,
3013a0747c9fSpatrick             /*offset=*/offset,
3014a0747c9fSpatrick             /*size=*/0, // FDE can span multiple symbols so don't use its size.
3015a0747c9fSpatrick             /*size_is_valid=*/false,
3016a0747c9fSpatrick             /*contains_linker_annotations=*/false,
3017a0747c9fSpatrick             /*flags=*/0);
3018061da546Spatrick         new_symbols.push_back(eh_symbol);
3019061da546Spatrick       }
3020061da546Spatrick     }
3021061da546Spatrick     return true;
3022061da546Spatrick   });
3023061da546Spatrick 
3024061da546Spatrick   for (const Symbol &s : new_symbols)
3025061da546Spatrick     symbol_table->AddSymbol(s);
3026061da546Spatrick }
3027061da546Spatrick 
IsStripped()3028061da546Spatrick bool ObjectFileELF::IsStripped() {
3029061da546Spatrick   // TODO: determine this for ELF
3030061da546Spatrick   return false;
3031061da546Spatrick }
3032061da546Spatrick 
3033061da546Spatrick //===----------------------------------------------------------------------===//
3034061da546Spatrick // Dump
3035061da546Spatrick //
3036061da546Spatrick // Dump the specifics of the runtime file container (such as any headers
3037061da546Spatrick // segments, sections, etc).
Dump(Stream * s)3038061da546Spatrick void ObjectFileELF::Dump(Stream *s) {
3039061da546Spatrick   ModuleSP module_sp(GetModule());
3040061da546Spatrick   if (!module_sp) {
3041061da546Spatrick     return;
3042061da546Spatrick   }
3043061da546Spatrick 
3044061da546Spatrick   std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
3045061da546Spatrick   s->Printf("%p: ", static_cast<void *>(this));
3046061da546Spatrick   s->Indent();
3047061da546Spatrick   s->PutCString("ObjectFileELF");
3048061da546Spatrick 
3049061da546Spatrick   ArchSpec header_arch = GetArchitecture();
3050061da546Spatrick 
3051061da546Spatrick   *s << ", file = '" << m_file
3052061da546Spatrick      << "', arch = " << header_arch.GetArchitectureName() << "\n";
3053061da546Spatrick 
3054061da546Spatrick   DumpELFHeader(s, m_header);
3055061da546Spatrick   s->EOL();
3056061da546Spatrick   DumpELFProgramHeaders(s);
3057061da546Spatrick   s->EOL();
3058061da546Spatrick   DumpELFSectionHeaders(s);
3059061da546Spatrick   s->EOL();
3060061da546Spatrick   SectionList *section_list = GetSectionList();
3061061da546Spatrick   if (section_list)
3062dda28197Spatrick     section_list->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true,
3063dda28197Spatrick                        UINT32_MAX);
3064061da546Spatrick   Symtab *symtab = GetSymtab();
3065061da546Spatrick   if (symtab)
3066061da546Spatrick     symtab->Dump(s, nullptr, eSortOrderNone);
3067061da546Spatrick   s->EOL();
3068061da546Spatrick   DumpDependentModules(s);
3069061da546Spatrick   s->EOL();
3070061da546Spatrick }
3071061da546Spatrick 
3072061da546Spatrick // DumpELFHeader
3073061da546Spatrick //
3074061da546Spatrick // Dump the ELF header to the specified output stream
DumpELFHeader(Stream * s,const ELFHeader & header)3075061da546Spatrick void ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) {
3076061da546Spatrick   s->PutCString("ELF Header\n");
3077061da546Spatrick   s->Printf("e_ident[EI_MAG0   ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
3078061da546Spatrick   s->Printf("e_ident[EI_MAG1   ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG1],
3079061da546Spatrick             header.e_ident[EI_MAG1]);
3080061da546Spatrick   s->Printf("e_ident[EI_MAG2   ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG2],
3081061da546Spatrick             header.e_ident[EI_MAG2]);
3082061da546Spatrick   s->Printf("e_ident[EI_MAG3   ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG3],
3083061da546Spatrick             header.e_ident[EI_MAG3]);
3084061da546Spatrick 
3085061da546Spatrick   s->Printf("e_ident[EI_CLASS  ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
3086061da546Spatrick   s->Printf("e_ident[EI_DATA   ] = 0x%2.2x ", header.e_ident[EI_DATA]);
3087061da546Spatrick   DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
3088061da546Spatrick   s->Printf("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
3089061da546Spatrick   s->Printf("e_ident[EI_PAD    ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
3090061da546Spatrick 
3091061da546Spatrick   s->Printf("e_type      = 0x%4.4x ", header.e_type);
3092061da546Spatrick   DumpELFHeader_e_type(s, header.e_type);
3093061da546Spatrick   s->Printf("\ne_machine   = 0x%4.4x\n", header.e_machine);
3094061da546Spatrick   s->Printf("e_version   = 0x%8.8x\n", header.e_version);
3095061da546Spatrick   s->Printf("e_entry     = 0x%8.8" PRIx64 "\n", header.e_entry);
3096061da546Spatrick   s->Printf("e_phoff     = 0x%8.8" PRIx64 "\n", header.e_phoff);
3097061da546Spatrick   s->Printf("e_shoff     = 0x%8.8" PRIx64 "\n", header.e_shoff);
3098061da546Spatrick   s->Printf("e_flags     = 0x%8.8x\n", header.e_flags);
3099061da546Spatrick   s->Printf("e_ehsize    = 0x%4.4x\n", header.e_ehsize);
3100061da546Spatrick   s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
3101061da546Spatrick   s->Printf("e_phnum     = 0x%8.8x\n", header.e_phnum);
3102061da546Spatrick   s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
3103061da546Spatrick   s->Printf("e_shnum     = 0x%8.8x\n", header.e_shnum);
3104061da546Spatrick   s->Printf("e_shstrndx  = 0x%8.8x\n", header.e_shstrndx);
3105061da546Spatrick }
3106061da546Spatrick 
3107061da546Spatrick // DumpELFHeader_e_type
3108061da546Spatrick //
3109061da546Spatrick // Dump an token value for the ELF header member e_type
DumpELFHeader_e_type(Stream * s,elf_half e_type)3110061da546Spatrick void ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type) {
3111061da546Spatrick   switch (e_type) {
3112061da546Spatrick   case ET_NONE:
3113061da546Spatrick     *s << "ET_NONE";
3114061da546Spatrick     break;
3115061da546Spatrick   case ET_REL:
3116061da546Spatrick     *s << "ET_REL";
3117061da546Spatrick     break;
3118061da546Spatrick   case ET_EXEC:
3119061da546Spatrick     *s << "ET_EXEC";
3120061da546Spatrick     break;
3121061da546Spatrick   case ET_DYN:
3122061da546Spatrick     *s << "ET_DYN";
3123061da546Spatrick     break;
3124061da546Spatrick   case ET_CORE:
3125061da546Spatrick     *s << "ET_CORE";
3126061da546Spatrick     break;
3127061da546Spatrick   default:
3128061da546Spatrick     break;
3129061da546Spatrick   }
3130061da546Spatrick }
3131061da546Spatrick 
3132061da546Spatrick // DumpELFHeader_e_ident_EI_DATA
3133061da546Spatrick //
3134061da546Spatrick // Dump an token value for the ELF header member e_ident[EI_DATA]
DumpELFHeader_e_ident_EI_DATA(Stream * s,unsigned char ei_data)3135061da546Spatrick void ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s,
3136061da546Spatrick                                                   unsigned char ei_data) {
3137061da546Spatrick   switch (ei_data) {
3138061da546Spatrick   case ELFDATANONE:
3139061da546Spatrick     *s << "ELFDATANONE";
3140061da546Spatrick     break;
3141061da546Spatrick   case ELFDATA2LSB:
3142061da546Spatrick     *s << "ELFDATA2LSB - Little Endian";
3143061da546Spatrick     break;
3144061da546Spatrick   case ELFDATA2MSB:
3145061da546Spatrick     *s << "ELFDATA2MSB - Big Endian";
3146061da546Spatrick     break;
3147061da546Spatrick   default:
3148061da546Spatrick     break;
3149061da546Spatrick   }
3150061da546Spatrick }
3151061da546Spatrick 
3152061da546Spatrick // DumpELFProgramHeader
3153061da546Spatrick //
3154061da546Spatrick // Dump a single ELF program header to the specified output stream
DumpELFProgramHeader(Stream * s,const ELFProgramHeader & ph)3155061da546Spatrick void ObjectFileELF::DumpELFProgramHeader(Stream *s,
3156061da546Spatrick                                          const ELFProgramHeader &ph) {
3157061da546Spatrick   DumpELFProgramHeader_p_type(s, ph.p_type);
3158061da546Spatrick   s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset,
3159061da546Spatrick             ph.p_vaddr, ph.p_paddr);
3160061da546Spatrick   s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8x (", ph.p_filesz, ph.p_memsz,
3161061da546Spatrick             ph.p_flags);
3162061da546Spatrick 
3163061da546Spatrick   DumpELFProgramHeader_p_flags(s, ph.p_flags);
3164061da546Spatrick   s->Printf(") %8.8" PRIx64, ph.p_align);
3165061da546Spatrick }
3166061da546Spatrick 
3167061da546Spatrick // DumpELFProgramHeader_p_type
3168061da546Spatrick //
3169061da546Spatrick // Dump an token value for the ELF program header member p_type which describes
3170061da546Spatrick // the type of the program header
DumpELFProgramHeader_p_type(Stream * s,elf_word p_type)3171061da546Spatrick void ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) {
3172061da546Spatrick   const int kStrWidth = 15;
3173061da546Spatrick   switch (p_type) {
3174061da546Spatrick     CASE_AND_STREAM(s, PT_NULL, kStrWidth);
3175061da546Spatrick     CASE_AND_STREAM(s, PT_LOAD, kStrWidth);
3176061da546Spatrick     CASE_AND_STREAM(s, PT_DYNAMIC, kStrWidth);
3177061da546Spatrick     CASE_AND_STREAM(s, PT_INTERP, kStrWidth);
3178061da546Spatrick     CASE_AND_STREAM(s, PT_NOTE, kStrWidth);
3179061da546Spatrick     CASE_AND_STREAM(s, PT_SHLIB, kStrWidth);
3180061da546Spatrick     CASE_AND_STREAM(s, PT_PHDR, kStrWidth);
3181061da546Spatrick     CASE_AND_STREAM(s, PT_TLS, kStrWidth);
3182061da546Spatrick     CASE_AND_STREAM(s, PT_GNU_EH_FRAME, kStrWidth);
3183061da546Spatrick   default:
3184061da546Spatrick     s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
3185061da546Spatrick     break;
3186061da546Spatrick   }
3187061da546Spatrick }
3188061da546Spatrick 
3189061da546Spatrick // DumpELFProgramHeader_p_flags
3190061da546Spatrick //
3191061da546Spatrick // Dump an token value for the ELF program header member p_flags
DumpELFProgramHeader_p_flags(Stream * s,elf_word p_flags)3192061da546Spatrick void ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) {
3193061da546Spatrick   *s << ((p_flags & PF_X) ? "PF_X" : "    ")
3194061da546Spatrick      << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
3195061da546Spatrick      << ((p_flags & PF_W) ? "PF_W" : "    ")
3196061da546Spatrick      << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
3197061da546Spatrick      << ((p_flags & PF_R) ? "PF_R" : "    ");
3198061da546Spatrick }
3199061da546Spatrick 
3200061da546Spatrick // DumpELFProgramHeaders
3201061da546Spatrick //
3202061da546Spatrick // Dump all of the ELF program header to the specified output stream
DumpELFProgramHeaders(Stream * s)3203061da546Spatrick void ObjectFileELF::DumpELFProgramHeaders(Stream *s) {
3204061da546Spatrick   if (!ParseProgramHeaders())
3205061da546Spatrick     return;
3206061da546Spatrick 
3207061da546Spatrick   s->PutCString("Program Headers\n");
3208061da546Spatrick   s->PutCString("IDX  p_type          p_offset p_vaddr  p_paddr  "
3209061da546Spatrick                 "p_filesz p_memsz  p_flags                   p_align\n");
3210061da546Spatrick   s->PutCString("==== --------------- -------- -------- -------- "
3211061da546Spatrick                 "-------- -------- ------------------------- --------\n");
3212061da546Spatrick 
3213061da546Spatrick   for (const auto &H : llvm::enumerate(m_program_headers)) {
3214061da546Spatrick     s->Format("[{0,2}] ", H.index());
3215061da546Spatrick     ObjectFileELF::DumpELFProgramHeader(s, H.value());
3216061da546Spatrick     s->EOL();
3217061da546Spatrick   }
3218061da546Spatrick }
3219061da546Spatrick 
3220061da546Spatrick // DumpELFSectionHeader
3221061da546Spatrick //
3222061da546Spatrick // Dump a single ELF section header to the specified output stream
DumpELFSectionHeader(Stream * s,const ELFSectionHeaderInfo & sh)3223061da546Spatrick void ObjectFileELF::DumpELFSectionHeader(Stream *s,
3224061da546Spatrick                                          const ELFSectionHeaderInfo &sh) {
3225061da546Spatrick   s->Printf("%8.8x ", sh.sh_name);
3226061da546Spatrick   DumpELFSectionHeader_sh_type(s, sh.sh_type);
3227061da546Spatrick   s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
3228061da546Spatrick   DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
3229061da546Spatrick   s->Printf(") %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addr,
3230061da546Spatrick             sh.sh_offset, sh.sh_size);
3231061da546Spatrick   s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
3232061da546Spatrick   s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
3233061da546Spatrick }
3234061da546Spatrick 
3235061da546Spatrick // DumpELFSectionHeader_sh_type
3236061da546Spatrick //
3237061da546Spatrick // Dump an token value for the ELF section header member sh_type which
3238061da546Spatrick // describes the type of the section
DumpELFSectionHeader_sh_type(Stream * s,elf_word sh_type)3239061da546Spatrick void ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type) {
3240061da546Spatrick   const int kStrWidth = 12;
3241061da546Spatrick   switch (sh_type) {
3242061da546Spatrick     CASE_AND_STREAM(s, SHT_NULL, kStrWidth);
3243061da546Spatrick     CASE_AND_STREAM(s, SHT_PROGBITS, kStrWidth);
3244061da546Spatrick     CASE_AND_STREAM(s, SHT_SYMTAB, kStrWidth);
3245061da546Spatrick     CASE_AND_STREAM(s, SHT_STRTAB, kStrWidth);
3246061da546Spatrick     CASE_AND_STREAM(s, SHT_RELA, kStrWidth);
3247061da546Spatrick     CASE_AND_STREAM(s, SHT_HASH, kStrWidth);
3248061da546Spatrick     CASE_AND_STREAM(s, SHT_DYNAMIC, kStrWidth);
3249061da546Spatrick     CASE_AND_STREAM(s, SHT_NOTE, kStrWidth);
3250061da546Spatrick     CASE_AND_STREAM(s, SHT_NOBITS, kStrWidth);
3251061da546Spatrick     CASE_AND_STREAM(s, SHT_REL, kStrWidth);
3252061da546Spatrick     CASE_AND_STREAM(s, SHT_SHLIB, kStrWidth);
3253061da546Spatrick     CASE_AND_STREAM(s, SHT_DYNSYM, kStrWidth);
3254061da546Spatrick     CASE_AND_STREAM(s, SHT_LOPROC, kStrWidth);
3255061da546Spatrick     CASE_AND_STREAM(s, SHT_HIPROC, kStrWidth);
3256061da546Spatrick     CASE_AND_STREAM(s, SHT_LOUSER, kStrWidth);
3257061da546Spatrick     CASE_AND_STREAM(s, SHT_HIUSER, kStrWidth);
3258061da546Spatrick   default:
3259061da546Spatrick     s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
3260061da546Spatrick     break;
3261061da546Spatrick   }
3262061da546Spatrick }
3263061da546Spatrick 
3264061da546Spatrick // DumpELFSectionHeader_sh_flags
3265061da546Spatrick //
3266061da546Spatrick // Dump an token value for the ELF section header member sh_flags
DumpELFSectionHeader_sh_flags(Stream * s,elf_xword sh_flags)3267061da546Spatrick void ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s,
3268061da546Spatrick                                                   elf_xword sh_flags) {
3269061da546Spatrick   *s << ((sh_flags & SHF_WRITE) ? "WRITE" : "     ")
3270061da546Spatrick      << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
3271061da546Spatrick      << ((sh_flags & SHF_ALLOC) ? "ALLOC" : "     ")
3272061da546Spatrick      << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
3273061da546Spatrick      << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : "         ");
3274061da546Spatrick }
3275061da546Spatrick 
3276061da546Spatrick // DumpELFSectionHeaders
3277061da546Spatrick //
3278061da546Spatrick // Dump all of the ELF section header to the specified output stream
DumpELFSectionHeaders(Stream * s)3279061da546Spatrick void ObjectFileELF::DumpELFSectionHeaders(Stream *s) {
3280061da546Spatrick   if (!ParseSectionHeaders())
3281061da546Spatrick     return;
3282061da546Spatrick 
3283061da546Spatrick   s->PutCString("Section Headers\n");
3284061da546Spatrick   s->PutCString("IDX  name     type         flags                            "
3285061da546Spatrick                 "addr     offset   size     link     info     addralgn "
3286061da546Spatrick                 "entsize  Name\n");
3287061da546Spatrick   s->PutCString("==== -------- ------------ -------------------------------- "
3288061da546Spatrick                 "-------- -------- -------- -------- -------- -------- "
3289061da546Spatrick                 "-------- ====================\n");
3290061da546Spatrick 
3291061da546Spatrick   uint32_t idx = 0;
3292061da546Spatrick   for (SectionHeaderCollConstIter I = m_section_headers.begin();
3293061da546Spatrick        I != m_section_headers.end(); ++I, ++idx) {
3294061da546Spatrick     s->Printf("[%2u] ", idx);
3295061da546Spatrick     ObjectFileELF::DumpELFSectionHeader(s, *I);
3296061da546Spatrick     const char *section_name = I->section_name.AsCString("");
3297061da546Spatrick     if (section_name)
3298061da546Spatrick       *s << ' ' << section_name << "\n";
3299061da546Spatrick   }
3300061da546Spatrick }
3301061da546Spatrick 
DumpDependentModules(lldb_private::Stream * s)3302061da546Spatrick void ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) {
3303061da546Spatrick   size_t num_modules = ParseDependentModules();
3304061da546Spatrick 
3305061da546Spatrick   if (num_modules > 0) {
3306061da546Spatrick     s->PutCString("Dependent Modules:\n");
3307061da546Spatrick     for (unsigned i = 0; i < num_modules; ++i) {
3308061da546Spatrick       const FileSpec &spec = m_filespec_up->GetFileSpecAtIndex(i);
3309061da546Spatrick       s->Printf("   %s\n", spec.GetFilename().GetCString());
3310061da546Spatrick     }
3311061da546Spatrick   }
3312061da546Spatrick }
3313061da546Spatrick 
GetArchitecture()3314061da546Spatrick ArchSpec ObjectFileELF::GetArchitecture() {
3315061da546Spatrick   if (!ParseHeader())
3316061da546Spatrick     return ArchSpec();
3317061da546Spatrick 
3318061da546Spatrick   if (m_section_headers.empty()) {
3319061da546Spatrick     // Allow elf notes to be parsed which may affect the detected architecture.
3320061da546Spatrick     ParseSectionHeaders();
3321061da546Spatrick   }
3322061da546Spatrick 
3323061da546Spatrick   if (CalculateType() == eTypeCoreFile &&
3324061da546Spatrick       !m_arch_spec.TripleOSWasSpecified()) {
3325061da546Spatrick     // Core files don't have section headers yet they have PT_NOTE program
3326061da546Spatrick     // headers that might shed more light on the architecture
3327061da546Spatrick     for (const elf::ELFProgramHeader &H : ProgramHeaders()) {
3328061da546Spatrick       if (H.p_type != PT_NOTE || H.p_offset == 0 || H.p_filesz == 0)
3329061da546Spatrick         continue;
3330061da546Spatrick       DataExtractor data;
3331061da546Spatrick       if (data.SetData(m_data, H.p_offset, H.p_filesz) == H.p_filesz) {
3332061da546Spatrick         UUID uuid;
3333061da546Spatrick         RefineModuleDetailsFromNote(data, m_arch_spec, uuid);
3334061da546Spatrick       }
3335061da546Spatrick     }
3336061da546Spatrick   }
3337061da546Spatrick   return m_arch_spec;
3338061da546Spatrick }
3339061da546Spatrick 
CalculateType()3340061da546Spatrick ObjectFile::Type ObjectFileELF::CalculateType() {
3341061da546Spatrick   switch (m_header.e_type) {
3342061da546Spatrick   case llvm::ELF::ET_NONE:
3343061da546Spatrick     // 0 - No file type
3344061da546Spatrick     return eTypeUnknown;
3345061da546Spatrick 
3346061da546Spatrick   case llvm::ELF::ET_REL:
3347061da546Spatrick     // 1 - Relocatable file
3348061da546Spatrick     return eTypeObjectFile;
3349061da546Spatrick 
3350061da546Spatrick   case llvm::ELF::ET_EXEC:
3351061da546Spatrick     // 2 - Executable file
3352061da546Spatrick     return eTypeExecutable;
3353061da546Spatrick 
3354061da546Spatrick   case llvm::ELF::ET_DYN:
3355061da546Spatrick     // 3 - Shared object file
3356061da546Spatrick     return eTypeSharedLibrary;
3357061da546Spatrick 
3358061da546Spatrick   case ET_CORE:
3359061da546Spatrick     // 4 - Core file
3360061da546Spatrick     return eTypeCoreFile;
3361061da546Spatrick 
3362061da546Spatrick   default:
3363061da546Spatrick     break;
3364061da546Spatrick   }
3365061da546Spatrick   return eTypeUnknown;
3366061da546Spatrick }
3367061da546Spatrick 
CalculateStrata()3368061da546Spatrick ObjectFile::Strata ObjectFileELF::CalculateStrata() {
3369061da546Spatrick   switch (m_header.e_type) {
3370061da546Spatrick   case llvm::ELF::ET_NONE:
3371061da546Spatrick     // 0 - No file type
3372061da546Spatrick     return eStrataUnknown;
3373061da546Spatrick 
3374061da546Spatrick   case llvm::ELF::ET_REL:
3375061da546Spatrick     // 1 - Relocatable file
3376061da546Spatrick     return eStrataUnknown;
3377061da546Spatrick 
3378061da546Spatrick   case llvm::ELF::ET_EXEC:
3379061da546Spatrick     // 2 - Executable file
3380061da546Spatrick     // TODO: is there any way to detect that an executable is a kernel
3381061da546Spatrick     // related executable by inspecting the program headers, section headers,
3382061da546Spatrick     // symbols, or any other flag bits???
3383061da546Spatrick     return eStrataUser;
3384061da546Spatrick 
3385061da546Spatrick   case llvm::ELF::ET_DYN:
3386061da546Spatrick     // 3 - Shared object file
3387061da546Spatrick     // TODO: is there any way to detect that an shared library is a kernel
3388061da546Spatrick     // related executable by inspecting the program headers, section headers,
3389061da546Spatrick     // symbols, or any other flag bits???
3390061da546Spatrick     return eStrataUnknown;
3391061da546Spatrick 
3392061da546Spatrick   case ET_CORE:
3393061da546Spatrick     // 4 - Core file
3394061da546Spatrick     // TODO: is there any way to detect that an core file is a kernel
3395061da546Spatrick     // related executable by inspecting the program headers, section headers,
3396061da546Spatrick     // symbols, or any other flag bits???
3397061da546Spatrick     return eStrataUnknown;
3398061da546Spatrick 
3399061da546Spatrick   default:
3400061da546Spatrick     break;
3401061da546Spatrick   }
3402061da546Spatrick   return eStrataUnknown;
3403061da546Spatrick }
3404061da546Spatrick 
ReadSectionData(Section * section,lldb::offset_t section_offset,void * dst,size_t dst_len)3405061da546Spatrick size_t ObjectFileELF::ReadSectionData(Section *section,
3406061da546Spatrick                        lldb::offset_t section_offset, void *dst,
3407061da546Spatrick                        size_t dst_len) {
3408061da546Spatrick   // If some other objectfile owns this data, pass this to them.
3409061da546Spatrick   if (section->GetObjectFile() != this)
3410061da546Spatrick     return section->GetObjectFile()->ReadSectionData(section, section_offset,
3411061da546Spatrick                                                      dst, dst_len);
3412061da546Spatrick 
3413061da546Spatrick   if (!section->Test(SHF_COMPRESSED))
3414061da546Spatrick     return ObjectFile::ReadSectionData(section, section_offset, dst, dst_len);
3415061da546Spatrick 
3416061da546Spatrick   // For compressed sections we need to read to full data to be able to
3417061da546Spatrick   // decompress.
3418061da546Spatrick   DataExtractor data;
3419061da546Spatrick   ReadSectionData(section, data);
3420061da546Spatrick   return data.CopyData(section_offset, dst_len, dst);
3421061da546Spatrick }
3422061da546Spatrick 
ReadSectionData(Section * section,DataExtractor & section_data)3423061da546Spatrick size_t ObjectFileELF::ReadSectionData(Section *section,
3424061da546Spatrick                                       DataExtractor &section_data) {
3425061da546Spatrick   // If some other objectfile owns this data, pass this to them.
3426061da546Spatrick   if (section->GetObjectFile() != this)
3427061da546Spatrick     return section->GetObjectFile()->ReadSectionData(section, section_data);
3428061da546Spatrick 
3429061da546Spatrick   size_t result = ObjectFile::ReadSectionData(section, section_data);
3430*101d251dSrobert   if (result == 0 || !(section->Get() & llvm::ELF::SHF_COMPRESSED))
3431061da546Spatrick     return result;
3432061da546Spatrick 
3433061da546Spatrick   auto Decompressor = llvm::object::Decompressor::create(
3434061da546Spatrick       section->GetName().GetStringRef(),
3435061da546Spatrick       {reinterpret_cast<const char *>(section_data.GetDataStart()),
3436061da546Spatrick        size_t(section_data.GetByteSize())},
3437061da546Spatrick       GetByteOrder() == eByteOrderLittle, GetAddressByteSize() == 8);
3438061da546Spatrick   if (!Decompressor) {
3439061da546Spatrick     GetModule()->ReportWarning(
3440*101d251dSrobert         "Unable to initialize decompressor for section '{0}': {1}",
3441061da546Spatrick         section->GetName().GetCString(),
3442061da546Spatrick         llvm::toString(Decompressor.takeError()).c_str());
3443061da546Spatrick     section_data.Clear();
3444061da546Spatrick     return 0;
3445061da546Spatrick   }
3446061da546Spatrick 
3447061da546Spatrick   auto buffer_sp =
3448061da546Spatrick       std::make_shared<DataBufferHeap>(Decompressor->getDecompressedSize(), 0);
3449061da546Spatrick   if (auto error = Decompressor->decompress(
3450*101d251dSrobert           {buffer_sp->GetBytes(), size_t(buffer_sp->GetByteSize())})) {
3451*101d251dSrobert     GetModule()->ReportWarning("Decompression of section '{0}' failed: {1}",
3452061da546Spatrick                                section->GetName().GetCString(),
3453061da546Spatrick                                llvm::toString(std::move(error)).c_str());
3454061da546Spatrick     section_data.Clear();
3455061da546Spatrick     return 0;
3456061da546Spatrick   }
3457061da546Spatrick 
3458061da546Spatrick   section_data.SetData(buffer_sp);
3459061da546Spatrick   return buffer_sp->GetByteSize();
3460061da546Spatrick }
3461061da546Spatrick 
ProgramHeaders()3462061da546Spatrick llvm::ArrayRef<ELFProgramHeader> ObjectFileELF::ProgramHeaders() {
3463061da546Spatrick   ParseProgramHeaders();
3464061da546Spatrick   return m_program_headers;
3465061da546Spatrick }
3466061da546Spatrick 
GetSegmentData(const ELFProgramHeader & H)3467061da546Spatrick DataExtractor ObjectFileELF::GetSegmentData(const ELFProgramHeader &H) {
3468061da546Spatrick   return DataExtractor(m_data, H.p_offset, H.p_filesz);
3469061da546Spatrick }
3470061da546Spatrick 
AnySegmentHasPhysicalAddress()3471061da546Spatrick bool ObjectFileELF::AnySegmentHasPhysicalAddress() {
3472061da546Spatrick   for (const ELFProgramHeader &H : ProgramHeaders()) {
3473061da546Spatrick     if (H.p_paddr != 0)
3474061da546Spatrick       return true;
3475061da546Spatrick   }
3476061da546Spatrick   return false;
3477061da546Spatrick }
3478061da546Spatrick 
3479061da546Spatrick std::vector<ObjectFile::LoadableData>
GetLoadableData(Target & target)3480061da546Spatrick ObjectFileELF::GetLoadableData(Target &target) {
3481061da546Spatrick   // Create a list of loadable data from loadable segments, using physical
3482061da546Spatrick   // addresses if they aren't all null
3483061da546Spatrick   std::vector<LoadableData> loadables;
3484061da546Spatrick   bool should_use_paddr = AnySegmentHasPhysicalAddress();
3485061da546Spatrick   for (const ELFProgramHeader &H : ProgramHeaders()) {
3486061da546Spatrick     LoadableData loadable;
3487061da546Spatrick     if (H.p_type != llvm::ELF::PT_LOAD)
3488061da546Spatrick       continue;
3489061da546Spatrick     loadable.Dest = should_use_paddr ? H.p_paddr : H.p_vaddr;
3490061da546Spatrick     if (loadable.Dest == LLDB_INVALID_ADDRESS)
3491061da546Spatrick       continue;
3492061da546Spatrick     if (H.p_filesz == 0)
3493061da546Spatrick       continue;
3494061da546Spatrick     auto segment_data = GetSegmentData(H);
3495061da546Spatrick     loadable.Contents = llvm::ArrayRef<uint8_t>(segment_data.GetDataStart(),
3496061da546Spatrick                                                 segment_data.GetByteSize());
3497061da546Spatrick     loadables.push_back(loadable);
3498061da546Spatrick   }
3499061da546Spatrick   return loadables;
3500061da546Spatrick }
3501*101d251dSrobert 
3502*101d251dSrobert lldb::WritableDataBufferSP
MapFileDataWritable(const FileSpec & file,uint64_t Size,uint64_t Offset)3503*101d251dSrobert ObjectFileELF::MapFileDataWritable(const FileSpec &file, uint64_t Size,
3504*101d251dSrobert                                    uint64_t Offset) {
3505*101d251dSrobert   return FileSystem::Instance().CreateWritableDataBuffer(file.GetPath(), Size,
3506*101d251dSrobert                                                          Offset);
3507*101d251dSrobert }
3508