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 §ion_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 §ion_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