1cfca06d7SDimitry Andric //===-- ObjectFileELF.cpp -------------------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste
9f034231aSEd Maste #include "ObjectFileELF.h"
10f034231aSEd Maste
11f034231aSEd Maste #include <algorithm>
1214f1b3e8SDimitry Andric #include <cassert>
13e3b55780SDimitry Andric #include <optional>
14e81d9d49SDimitry Andric #include <unordered_map>
15f034231aSEd Maste
16f034231aSEd Maste #include "lldb/Core/Module.h"
17f034231aSEd Maste #include "lldb/Core/ModuleSpec.h"
18f034231aSEd Maste #include "lldb/Core/PluginManager.h"
19344a3780SDimitry Andric #include "lldb/Core/Progress.h"
20f034231aSEd Maste #include "lldb/Core/Section.h"
2194994d37SDimitry Andric #include "lldb/Host/FileSystem.h"
22ead24645SDimitry Andric #include "lldb/Host/LZMA.h"
23f21a844fSEd Maste #include "lldb/Symbol/DWARFCallFrameInfo.h"
24f034231aSEd Maste #include "lldb/Symbol/SymbolContext.h"
25866dcdacSEd Maste #include "lldb/Target/SectionLoadList.h"
26f21a844fSEd Maste #include "lldb/Target/Target.h"
27ef5d0b5eSDimitry Andric #include "lldb/Utility/ArchSpec.h"
28ef5d0b5eSDimitry Andric #include "lldb/Utility/DataBufferHeap.h"
297fa27ce4SDimitry Andric #include "lldb/Utility/FileSpecList.h"
30145449b1SDimitry Andric #include "lldb/Utility/LLDBLog.h"
3174a628f7SDimitry Andric #include "lldb/Utility/Log.h"
325f29bb8aSDimitry Andric #include "lldb/Utility/RangeMap.h"
33b76161e4SDimitry Andric #include "lldb/Utility/Status.h"
3474a628f7SDimitry Andric #include "lldb/Utility/Stream.h"
351b306c26SDimitry Andric #include "lldb/Utility/Timer.h"
3694994d37SDimitry Andric #include "llvm/ADT/IntervalMap.h"
37f034231aSEd Maste #include "llvm/ADT/PointerUnion.h"
380cac4ca3SEd Maste #include "llvm/ADT/StringRef.h"
39ead24645SDimitry Andric #include "llvm/BinaryFormat/ELF.h"
40ef5d0b5eSDimitry Andric #include "llvm/Object/Decompressor.h"
41f3fbd1c0SDimitry Andric #include "llvm/Support/ARMBuildAttributes.h"
42ead24645SDimitry Andric #include "llvm/Support/CRC.h"
43344a3780SDimitry Andric #include "llvm/Support/FormatVariadic.h"
440cac4ca3SEd Maste #include "llvm/Support/MathExtras.h"
4574a628f7SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
46f3fbd1c0SDimitry Andric #include "llvm/Support/MipsABIFlags.h"
47f034231aSEd Maste
48f034231aSEd Maste #define CASE_AND_STREAM(s, def, width) \
4914f1b3e8SDimitry Andric case def: \
5014f1b3e8SDimitry Andric s->Printf("%-*s", width, #def); \
5114f1b3e8SDimitry Andric break;
52f034231aSEd Maste
53f034231aSEd Maste using namespace lldb;
54f034231aSEd Maste using namespace lldb_private;
55f034231aSEd Maste using namespace elf;
56f034231aSEd Maste using namespace llvm::ELF;
57f034231aSEd Maste
58cfca06d7SDimitry Andric LLDB_PLUGIN_DEFINE(ObjectFileELF)
59cfca06d7SDimitry Andric
600cac4ca3SEd Maste // ELF note owner definitions
61c0981da4SDimitry Andric static const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD";
62c0981da4SDimitry Andric static const char *const LLDB_NT_OWNER_GNU = "GNU";
63c0981da4SDimitry Andric static const char *const LLDB_NT_OWNER_NETBSD = "NetBSD";
64c0981da4SDimitry Andric static const char *const LLDB_NT_OWNER_NETBSDCORE = "NetBSD-CORE";
65c0981da4SDimitry Andric static const char *const LLDB_NT_OWNER_OPENBSD = "OpenBSD";
66c0981da4SDimitry Andric static const char *const LLDB_NT_OWNER_ANDROID = "Android";
67c0981da4SDimitry Andric static const char *const LLDB_NT_OWNER_CORE = "CORE";
68c0981da4SDimitry Andric static const char *const LLDB_NT_OWNER_LINUX = "LINUX";
690cac4ca3SEd Maste
700cac4ca3SEd Maste // ELF note type definitions
71c0981da4SDimitry Andric static const elf_word LLDB_NT_FREEBSD_ABI_TAG = 0x01;
72c0981da4SDimitry Andric static const elf_word LLDB_NT_FREEBSD_ABI_SIZE = 4;
730cac4ca3SEd Maste
74c0981da4SDimitry Andric static const elf_word LLDB_NT_GNU_ABI_TAG = 0x01;
75c0981da4SDimitry Andric static const elf_word LLDB_NT_GNU_ABI_SIZE = 16;
760cac4ca3SEd Maste
77c0981da4SDimitry Andric static const elf_word LLDB_NT_GNU_BUILD_ID_TAG = 0x03;
780cac4ca3SEd Maste
79c0981da4SDimitry Andric static const elf_word LLDB_NT_NETBSD_IDENT_TAG = 1;
80c0981da4SDimitry Andric static const elf_word LLDB_NT_NETBSD_IDENT_DESCSZ = 4;
81c0981da4SDimitry Andric static const elf_word LLDB_NT_NETBSD_IDENT_NAMESZ = 7;
82c0981da4SDimitry Andric static const elf_word LLDB_NT_NETBSD_PROCINFO = 1;
830cac4ca3SEd Maste
840cac4ca3SEd Maste // GNU ABI note OS constants
85c0981da4SDimitry Andric static const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00;
86c0981da4SDimitry Andric static const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01;
87c0981da4SDimitry Andric static const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02;
88c0981da4SDimitry Andric
89c0981da4SDimitry Andric namespace {
900cac4ca3SEd Maste
91f034231aSEd Maste //===----------------------------------------------------------------------===//
925f29bb8aSDimitry Andric /// \class ELFRelocation
93f73363f1SDimitry Andric /// Generic wrapper for ELFRel and ELFRela.
94f034231aSEd Maste ///
95f034231aSEd Maste /// This helper class allows us to parse both ELFRel and ELFRela relocation
96f034231aSEd Maste /// entries in a generic manner.
9714f1b3e8SDimitry Andric class ELFRelocation {
98f034231aSEd Maste public:
99f034231aSEd Maste /// Constructs an ELFRelocation entry with a personality as given by @p
100f034231aSEd Maste /// type.
101f034231aSEd Maste ///
1025f29bb8aSDimitry Andric /// \param type Either DT_REL or DT_RELA. Any other value is invalid.
103f034231aSEd Maste ELFRelocation(unsigned type);
104f034231aSEd Maste
105f034231aSEd Maste ~ELFRelocation();
106f034231aSEd Maste
10714f1b3e8SDimitry Andric bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
108f034231aSEd Maste
10914f1b3e8SDimitry Andric static unsigned RelocType32(const ELFRelocation &rel);
110f034231aSEd Maste
11114f1b3e8SDimitry Andric static unsigned RelocType64(const ELFRelocation &rel);
112f034231aSEd Maste
11314f1b3e8SDimitry Andric static unsigned RelocSymbol32(const ELFRelocation &rel);
114f034231aSEd Maste
11514f1b3e8SDimitry Andric static unsigned RelocSymbol64(const ELFRelocation &rel);
116f034231aSEd Maste
1177fa27ce4SDimitry Andric static elf_addr RelocOffset32(const ELFRelocation &rel);
1180cac4ca3SEd Maste
1197fa27ce4SDimitry Andric static elf_addr RelocOffset64(const ELFRelocation &rel);
1200cac4ca3SEd Maste
1217fa27ce4SDimitry Andric static elf_sxword RelocAddend32(const ELFRelocation &rel);
1220cac4ca3SEd Maste
1237fa27ce4SDimitry Andric static elf_sxword RelocAddend64(const ELFRelocation &rel);
1240cac4ca3SEd Maste
IsRela()125e3b55780SDimitry Andric bool IsRela() { return (reloc.is<ELFRela *>()); }
126e3b55780SDimitry Andric
127f034231aSEd Maste private:
128f034231aSEd Maste typedef llvm::PointerUnion<ELFRel *, ELFRela *> RelocUnion;
129f034231aSEd Maste
130f034231aSEd Maste RelocUnion reloc;
131f034231aSEd Maste };
132c0981da4SDimitry Andric } // end anonymous namespace
133f034231aSEd Maste
ELFRelocation(unsigned type)13414f1b3e8SDimitry Andric ELFRelocation::ELFRelocation(unsigned type) {
1350cac4ca3SEd Maste if (type == DT_REL || type == SHT_REL)
136f034231aSEd Maste reloc = new ELFRel();
1370cac4ca3SEd Maste else if (type == DT_RELA || type == SHT_RELA)
138f034231aSEd Maste reloc = new ELFRela();
139f034231aSEd Maste else {
140f034231aSEd Maste assert(false && "unexpected relocation type");
1415f29bb8aSDimitry Andric reloc = static_cast<ELFRel *>(nullptr);
142f034231aSEd Maste }
143f034231aSEd Maste }
144f034231aSEd Maste
~ELFRelocation()14514f1b3e8SDimitry Andric ELFRelocation::~ELFRelocation() {
146f034231aSEd Maste if (reloc.is<ELFRel *>())
147f034231aSEd Maste delete reloc.get<ELFRel *>();
148f034231aSEd Maste else
149f034231aSEd Maste delete reloc.get<ELFRela *>();
150f034231aSEd Maste }
151f034231aSEd Maste
Parse(const lldb_private::DataExtractor & data,lldb::offset_t * offset)15214f1b3e8SDimitry Andric bool ELFRelocation::Parse(const lldb_private::DataExtractor &data,
15314f1b3e8SDimitry Andric lldb::offset_t *offset) {
154f034231aSEd Maste if (reloc.is<ELFRel *>())
155f034231aSEd Maste return reloc.get<ELFRel *>()->Parse(data, offset);
156f034231aSEd Maste else
157f034231aSEd Maste return reloc.get<ELFRela *>()->Parse(data, offset);
158f034231aSEd Maste }
159f034231aSEd Maste
RelocType32(const ELFRelocation & rel)16014f1b3e8SDimitry Andric unsigned ELFRelocation::RelocType32(const ELFRelocation &rel) {
161f034231aSEd Maste if (rel.reloc.is<ELFRel *>())
162f034231aSEd Maste return ELFRel::RelocType32(*rel.reloc.get<ELFRel *>());
163f034231aSEd Maste else
164f034231aSEd Maste return ELFRela::RelocType32(*rel.reloc.get<ELFRela *>());
165f034231aSEd Maste }
166f034231aSEd Maste
RelocType64(const ELFRelocation & rel)16714f1b3e8SDimitry Andric unsigned ELFRelocation::RelocType64(const ELFRelocation &rel) {
168f034231aSEd Maste if (rel.reloc.is<ELFRel *>())
169f034231aSEd Maste return ELFRel::RelocType64(*rel.reloc.get<ELFRel *>());
170f034231aSEd Maste else
171f034231aSEd Maste return ELFRela::RelocType64(*rel.reloc.get<ELFRela *>());
172f034231aSEd Maste }
173f034231aSEd Maste
RelocSymbol32(const ELFRelocation & rel)17414f1b3e8SDimitry Andric unsigned ELFRelocation::RelocSymbol32(const ELFRelocation &rel) {
175f034231aSEd Maste if (rel.reloc.is<ELFRel *>())
176f034231aSEd Maste return ELFRel::RelocSymbol32(*rel.reloc.get<ELFRel *>());
177f034231aSEd Maste else
178f034231aSEd Maste return ELFRela::RelocSymbol32(*rel.reloc.get<ELFRela *>());
179f034231aSEd Maste }
180f034231aSEd Maste
RelocSymbol64(const ELFRelocation & rel)18114f1b3e8SDimitry Andric unsigned ELFRelocation::RelocSymbol64(const ELFRelocation &rel) {
182f034231aSEd Maste if (rel.reloc.is<ELFRel *>())
183f034231aSEd Maste return ELFRel::RelocSymbol64(*rel.reloc.get<ELFRel *>());
184f034231aSEd Maste else
185f034231aSEd Maste return ELFRela::RelocSymbol64(*rel.reloc.get<ELFRela *>());
186f034231aSEd Maste }
187f034231aSEd Maste
RelocOffset32(const ELFRelocation & rel)1887fa27ce4SDimitry Andric elf_addr ELFRelocation::RelocOffset32(const ELFRelocation &rel) {
1890cac4ca3SEd Maste if (rel.reloc.is<ELFRel *>())
1900cac4ca3SEd Maste return rel.reloc.get<ELFRel *>()->r_offset;
1910cac4ca3SEd Maste else
1920cac4ca3SEd Maste return rel.reloc.get<ELFRela *>()->r_offset;
1930cac4ca3SEd Maste }
1940cac4ca3SEd Maste
RelocOffset64(const ELFRelocation & rel)1957fa27ce4SDimitry Andric elf_addr ELFRelocation::RelocOffset64(const ELFRelocation &rel) {
1960cac4ca3SEd Maste if (rel.reloc.is<ELFRel *>())
1970cac4ca3SEd Maste return rel.reloc.get<ELFRel *>()->r_offset;
1980cac4ca3SEd Maste else
1990cac4ca3SEd Maste return rel.reloc.get<ELFRela *>()->r_offset;
2000cac4ca3SEd Maste }
2010cac4ca3SEd Maste
RelocAddend32(const ELFRelocation & rel)2027fa27ce4SDimitry Andric elf_sxword ELFRelocation::RelocAddend32(const ELFRelocation &rel) {
2030cac4ca3SEd Maste if (rel.reloc.is<ELFRel *>())
2040cac4ca3SEd Maste return 0;
2050cac4ca3SEd Maste else
2060cac4ca3SEd Maste return rel.reloc.get<ELFRela *>()->r_addend;
2070cac4ca3SEd Maste }
2080cac4ca3SEd Maste
RelocAddend64(const ELFRelocation & rel)2097fa27ce4SDimitry Andric elf_sxword ELFRelocation::RelocAddend64(const ELFRelocation &rel) {
2100cac4ca3SEd Maste if (rel.reloc.is<ELFRel *>())
2110cac4ca3SEd Maste return 0;
2120cac4ca3SEd Maste else
2130cac4ca3SEd Maste return rel.reloc.get<ELFRela *>()->r_addend;
2140cac4ca3SEd Maste }
2150cac4ca3SEd Maste
SegmentID(size_t PHdrIndex)216cfca06d7SDimitry Andric static user_id_t SegmentID(size_t PHdrIndex) {
217cfca06d7SDimitry Andric return ~user_id_t(PHdrIndex);
218cfca06d7SDimitry Andric }
21994994d37SDimitry Andric
Parse(const DataExtractor & data,lldb::offset_t * offset)22014f1b3e8SDimitry Andric bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {
22186758c71SEd Maste // Read all fields.
2225f29bb8aSDimitry Andric if (data.GetU32(offset, &n_namesz, 3) == nullptr)
22386758c71SEd Maste return false;
22486758c71SEd Maste
225f73363f1SDimitry Andric // The name field is required to be nul-terminated, and n_namesz includes the
226f73363f1SDimitry Andric // terminating nul in observed implementations (contrary to the ELF-64 spec).
227f73363f1SDimitry Andric // A special case is needed for cores generated by some older Linux versions,
228f73363f1SDimitry Andric // which write a note named "CORE" without a nul terminator and n_namesz = 4.
22914f1b3e8SDimitry Andric if (n_namesz == 4) {
23086758c71SEd Maste char buf[4];
23186758c71SEd Maste if (data.ExtractBytes(*offset, 4, data.GetByteOrder(), buf) != 4)
23286758c71SEd Maste return false;
23314f1b3e8SDimitry Andric if (strncmp(buf, "CORE", 4) == 0) {
23486758c71SEd Maste n_name = "CORE";
23586758c71SEd Maste *offset += 4;
23686758c71SEd Maste return true;
23786758c71SEd Maste }
23886758c71SEd Maste }
23986758c71SEd Maste
240f3fbd1c0SDimitry Andric const char *cstr = data.GetCStr(offset, llvm::alignTo(n_namesz, 4));
2415f29bb8aSDimitry Andric if (cstr == nullptr) {
242145449b1SDimitry Andric Log *log = GetLog(LLDBLog::Symbols);
243ead24645SDimitry Andric LLDB_LOGF(log, "Failed to parse note name lacking nul terminator");
24486758c71SEd Maste
24586758c71SEd Maste return false;
24686758c71SEd Maste }
24786758c71SEd Maste n_name = cstr;
24886758c71SEd Maste return true;
24986758c71SEd Maste }
25086758c71SEd Maste
mipsVariantFromElfFlags(const elf::ELFHeader & header)25174a628f7SDimitry Andric static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) {
25274a628f7SDimitry Andric const uint32_t mips_arch = header.e_flags & llvm::ELF::EF_MIPS_ARCH;
25374a628f7SDimitry Andric uint32_t endian = header.e_ident[EI_DATA];
2545e95aa85SEd Maste uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown;
25574a628f7SDimitry Andric uint32_t fileclass = header.e_ident[EI_CLASS];
25674a628f7SDimitry Andric
257f73363f1SDimitry Andric // If there aren't any elf flags available (e.g core elf file) then return
258f73363f1SDimitry Andric // default
25974a628f7SDimitry Andric // 32 or 64 bit arch (without any architecture revision) based on object file's class.
26074a628f7SDimitry Andric if (header.e_type == ET_CORE) {
26174a628f7SDimitry Andric switch (fileclass) {
26274a628f7SDimitry Andric case llvm::ELF::ELFCLASS32:
26374a628f7SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el
26474a628f7SDimitry Andric : ArchSpec::eMIPSSubType_mips32;
26574a628f7SDimitry Andric case llvm::ELF::ELFCLASS64:
26674a628f7SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el
26774a628f7SDimitry Andric : ArchSpec::eMIPSSubType_mips64;
26874a628f7SDimitry Andric default:
26974a628f7SDimitry Andric return arch_variant;
27074a628f7SDimitry Andric }
27174a628f7SDimitry Andric }
2725e95aa85SEd Maste
27314f1b3e8SDimitry Andric switch (mips_arch) {
274e81d9d49SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_1:
275e81d9d49SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_2:
2765e95aa85SEd Maste case llvm::ELF::EF_MIPS_ARCH_32:
27714f1b3e8SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el
27814f1b3e8SDimitry Andric : ArchSpec::eMIPSSubType_mips32;
2795e95aa85SEd Maste case llvm::ELF::EF_MIPS_ARCH_32R2:
28014f1b3e8SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r2el
28114f1b3e8SDimitry Andric : ArchSpec::eMIPSSubType_mips32r2;
2825e95aa85SEd Maste case llvm::ELF::EF_MIPS_ARCH_32R6:
28314f1b3e8SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r6el
28414f1b3e8SDimitry Andric : ArchSpec::eMIPSSubType_mips32r6;
2857fed546dSDimitry Andric case llvm::ELF::EF_MIPS_ARCH_3:
2867fed546dSDimitry Andric case llvm::ELF::EF_MIPS_ARCH_4:
2877fed546dSDimitry Andric case llvm::ELF::EF_MIPS_ARCH_5:
2885e95aa85SEd Maste case llvm::ELF::EF_MIPS_ARCH_64:
28914f1b3e8SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el
29014f1b3e8SDimitry Andric : ArchSpec::eMIPSSubType_mips64;
2915e95aa85SEd Maste case llvm::ELF::EF_MIPS_ARCH_64R2:
29214f1b3e8SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r2el
29314f1b3e8SDimitry Andric : ArchSpec::eMIPSSubType_mips64r2;
2945e95aa85SEd Maste case llvm::ELF::EF_MIPS_ARCH_64R6:
29514f1b3e8SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r6el
29614f1b3e8SDimitry Andric : ArchSpec::eMIPSSubType_mips64r6;
2975e95aa85SEd Maste default:
2985e95aa85SEd Maste break;
2995e95aa85SEd Maste }
3005e95aa85SEd Maste
3015e95aa85SEd Maste return arch_variant;
3025e95aa85SEd Maste }
3035e95aa85SEd Maste
riscvVariantFromElfFlags(const elf::ELFHeader & header)304b60736ecSDimitry Andric static uint32_t riscvVariantFromElfFlags(const elf::ELFHeader &header) {
305b60736ecSDimitry Andric uint32_t fileclass = header.e_ident[EI_CLASS];
306b60736ecSDimitry Andric switch (fileclass) {
307b60736ecSDimitry Andric case llvm::ELF::ELFCLASS32:
308b60736ecSDimitry Andric return ArchSpec::eRISCVSubType_riscv32;
309b60736ecSDimitry Andric case llvm::ELF::ELFCLASS64:
310b60736ecSDimitry Andric return ArchSpec::eRISCVSubType_riscv64;
311b60736ecSDimitry Andric default:
312b60736ecSDimitry Andric return ArchSpec::eRISCVSubType_unknown;
313b60736ecSDimitry Andric }
314b60736ecSDimitry Andric }
315b60736ecSDimitry Andric
ppc64VariantFromElfFlags(const elf::ELFHeader & header)316145449b1SDimitry Andric static uint32_t ppc64VariantFromElfFlags(const elf::ELFHeader &header) {
317145449b1SDimitry Andric uint32_t endian = header.e_ident[EI_DATA];
318145449b1SDimitry Andric if (endian == ELFDATA2LSB)
319145449b1SDimitry Andric return ArchSpec::eCore_ppc64le_generic;
320145449b1SDimitry Andric else
321145449b1SDimitry Andric return ArchSpec::eCore_ppc64_generic;
322145449b1SDimitry Andric }
323145449b1SDimitry Andric
loongarchVariantFromElfFlags(const elf::ELFHeader & header)324e3b55780SDimitry Andric static uint32_t loongarchVariantFromElfFlags(const elf::ELFHeader &header) {
325e3b55780SDimitry Andric uint32_t fileclass = header.e_ident[EI_CLASS];
326e3b55780SDimitry Andric switch (fileclass) {
327e3b55780SDimitry Andric case llvm::ELF::ELFCLASS32:
328e3b55780SDimitry Andric return ArchSpec::eLoongArchSubType_loongarch32;
329e3b55780SDimitry Andric case llvm::ELF::ELFCLASS64:
330e3b55780SDimitry Andric return ArchSpec::eLoongArchSubType_loongarch64;
331e3b55780SDimitry Andric default:
332e3b55780SDimitry Andric return ArchSpec::eLoongArchSubType_unknown;
333e3b55780SDimitry Andric }
334e3b55780SDimitry Andric }
335e3b55780SDimitry Andric
subTypeFromElfHeader(const elf::ELFHeader & header)33614f1b3e8SDimitry Andric static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) {
3375e95aa85SEd Maste if (header.e_machine == llvm::ELF::EM_MIPS)
33874a628f7SDimitry Andric return mipsVariantFromElfFlags(header);
339145449b1SDimitry Andric else if (header.e_machine == llvm::ELF::EM_PPC64)
340145449b1SDimitry Andric return ppc64VariantFromElfFlags(header);
341b60736ecSDimitry Andric else if (header.e_machine == llvm::ELF::EM_RISCV)
342b60736ecSDimitry Andric return riscvVariantFromElfFlags(header);
343e3b55780SDimitry Andric else if (header.e_machine == llvm::ELF::EM_LOONGARCH)
344e3b55780SDimitry Andric return loongarchVariantFromElfFlags(header);
3455e95aa85SEd Maste
3465f29bb8aSDimitry Andric return LLDB_INVALID_CPUTYPE;
347205afe67SEd Maste }
348205afe67SEd Maste
349ead24645SDimitry Andric char ObjectFileELF::ID;
350ead24645SDimitry Andric
3510cac4ca3SEd Maste // Arbitrary constant used as UUID prefix for core files.
35214f1b3e8SDimitry Andric const uint32_t ObjectFileELF::g_core_uuid_magic(0xE210C);
3530cac4ca3SEd Maste
354f034231aSEd Maste // Static methods.
Initialize()35514f1b3e8SDimitry Andric void ObjectFileELF::Initialize() {
356f034231aSEd Maste PluginManager::RegisterPlugin(GetPluginNameStatic(),
35714f1b3e8SDimitry Andric GetPluginDescriptionStatic(), CreateInstance,
35814f1b3e8SDimitry Andric CreateMemoryInstance, GetModuleSpecifications);
359f034231aSEd Maste }
360f034231aSEd Maste
Terminate()36114f1b3e8SDimitry Andric void ObjectFileELF::Terminate() {
362f034231aSEd Maste PluginManager::UnregisterPlugin(CreateInstance);
363f034231aSEd Maste }
364f034231aSEd Maste
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)36514f1b3e8SDimitry Andric ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
366145449b1SDimitry Andric DataBufferSP data_sp,
367f034231aSEd Maste lldb::offset_t data_offset,
368f034231aSEd Maste const lldb_private::FileSpec *file,
369f034231aSEd Maste lldb::offset_t file_offset,
37014f1b3e8SDimitry Andric lldb::offset_t length) {
371145449b1SDimitry Andric bool mapped_writable = false;
37214f1b3e8SDimitry Andric if (!data_sp) {
373145449b1SDimitry Andric data_sp = MapFileDataWritable(*file, length, file_offset);
37474a628f7SDimitry Andric if (!data_sp)
37574a628f7SDimitry Andric return nullptr;
376f034231aSEd Maste data_offset = 0;
377145449b1SDimitry Andric mapped_writable = true;
378f034231aSEd Maste }
379f034231aSEd Maste
38074a628f7SDimitry Andric assert(data_sp);
38174a628f7SDimitry Andric
38274a628f7SDimitry Andric if (data_sp->GetByteSize() <= (llvm::ELF::EI_NIDENT + data_offset))
38374a628f7SDimitry Andric return nullptr;
38474a628f7SDimitry Andric
385f034231aSEd Maste const uint8_t *magic = data_sp->GetBytes() + data_offset;
38674a628f7SDimitry Andric if (!ELFHeader::MagicBytesMatch(magic))
38774a628f7SDimitry Andric return nullptr;
38874a628f7SDimitry Andric
389f034231aSEd Maste // Update the data to contain the entire file if it doesn't already
390f034231aSEd Maste if (data_sp->GetByteSize() < length) {
391145449b1SDimitry Andric data_sp = MapFileDataWritable(*file, length, file_offset);
39274a628f7SDimitry Andric if (!data_sp)
39374a628f7SDimitry Andric return nullptr;
394f034231aSEd Maste data_offset = 0;
395145449b1SDimitry Andric mapped_writable = true;
396145449b1SDimitry Andric magic = data_sp->GetBytes();
397145449b1SDimitry Andric }
398145449b1SDimitry Andric
399145449b1SDimitry Andric // If we didn't map the data as writable take ownership of the buffer.
400145449b1SDimitry Andric if (!mapped_writable) {
401145449b1SDimitry Andric data_sp = std::make_shared<DataBufferHeap>(data_sp->GetBytes(),
402145449b1SDimitry Andric data_sp->GetByteSize());
403145449b1SDimitry Andric data_offset = 0;
404f034231aSEd Maste magic = data_sp->GetBytes();
405f034231aSEd Maste }
40674a628f7SDimitry Andric
407f034231aSEd Maste unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
40814f1b3e8SDimitry Andric if (address_size == 4 || address_size == 8) {
4095f29bb8aSDimitry Andric std::unique_ptr<ObjectFileELF> objfile_up(new ObjectFileELF(
41014f1b3e8SDimitry Andric module_sp, data_sp, data_offset, file, file_offset, length));
4115f29bb8aSDimitry Andric ArchSpec spec = objfile_up->GetArchitecture();
4125f29bb8aSDimitry Andric if (spec && objfile_up->SetModulesArchitecture(spec))
4135f29bb8aSDimitry Andric return objfile_up.release();
414f034231aSEd Maste }
41574a628f7SDimitry Andric
4165f29bb8aSDimitry Andric return nullptr;
417f034231aSEd Maste }
418f034231aSEd Maste
CreateMemoryInstance(const lldb::ModuleSP & module_sp,WritableDataBufferSP data_sp,const lldb::ProcessSP & process_sp,lldb::addr_t header_addr)41914f1b3e8SDimitry Andric ObjectFile *ObjectFileELF::CreateMemoryInstance(
420145449b1SDimitry Andric const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp,
42114f1b3e8SDimitry Andric const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) {
42214f1b3e8SDimitry Andric if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT)) {
4230cac4ca3SEd Maste const uint8_t *magic = data_sp->GetBytes();
42414f1b3e8SDimitry Andric if (ELFHeader::MagicBytesMatch(magic)) {
4250cac4ca3SEd Maste unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
42614f1b3e8SDimitry Andric if (address_size == 4 || address_size == 8) {
4275f29bb8aSDimitry Andric std::unique_ptr<ObjectFileELF> objfile_up(
42814f1b3e8SDimitry Andric new ObjectFileELF(module_sp, data_sp, process_sp, header_addr));
4295f29bb8aSDimitry Andric ArchSpec spec = objfile_up->GetArchitecture();
4305f29bb8aSDimitry Andric if (spec && objfile_up->SetModulesArchitecture(spec))
4315f29bb8aSDimitry Andric return objfile_up.release();
4320cac4ca3SEd Maste }
4330cac4ca3SEd Maste }
4340cac4ca3SEd Maste }
4355f29bb8aSDimitry Andric return nullptr;
436f034231aSEd Maste }
437f034231aSEd Maste
MagicBytesMatch(DataBufferSP & data_sp,lldb::addr_t data_offset,lldb::addr_t data_length)43814f1b3e8SDimitry Andric bool ObjectFileELF::MagicBytesMatch(DataBufferSP &data_sp,
439f034231aSEd Maste lldb::addr_t data_offset,
44014f1b3e8SDimitry Andric lldb::addr_t data_length) {
44114f1b3e8SDimitry Andric if (data_sp &&
44214f1b3e8SDimitry Andric data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset)) {
443f034231aSEd Maste const uint8_t *magic = data_sp->GetBytes() + data_offset;
444f034231aSEd Maste return ELFHeader::MagicBytesMatch(magic);
445f034231aSEd Maste }
446f034231aSEd Maste return false;
447f034231aSEd Maste }
448f034231aSEd Maste
calc_crc32(uint32_t init,const DataExtractor & data)449ead24645SDimitry Andric static uint32_t calc_crc32(uint32_t init, const DataExtractor &data) {
450e3b55780SDimitry Andric return llvm::crc32(init,
451e3b55780SDimitry Andric llvm::ArrayRef(data.GetDataStart(), data.GetByteSize()));
4520cac4ca3SEd Maste }
4530cac4ca3SEd Maste
CalculateELFNotesSegmentsCRC32(const ProgramHeaderColl & program_headers,DataExtractor & object_data)45414f1b3e8SDimitry Andric uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32(
45514f1b3e8SDimitry Andric const ProgramHeaderColl &program_headers, DataExtractor &object_data) {
4560cac4ca3SEd Maste
4570cac4ca3SEd Maste uint32_t core_notes_crc = 0;
4580cac4ca3SEd Maste
45994994d37SDimitry Andric for (const ELFProgramHeader &H : program_headers) {
46094994d37SDimitry Andric if (H.p_type == llvm::ELF::PT_NOTE) {
46194994d37SDimitry Andric const elf_off ph_offset = H.p_offset;
46294994d37SDimitry Andric const size_t ph_size = H.p_filesz;
4630cac4ca3SEd Maste
4640cac4ca3SEd Maste DataExtractor segment_data;
46514f1b3e8SDimitry Andric if (segment_data.SetData(object_data, ph_offset, ph_size) != ph_size) {
466f73363f1SDimitry Andric // The ELF program header contained incorrect data, probably corefile
467f73363f1SDimitry Andric // is incomplete or corrupted.
4680cac4ca3SEd Maste break;
4690cac4ca3SEd Maste }
4700cac4ca3SEd Maste
471ead24645SDimitry Andric core_notes_crc = calc_crc32(core_notes_crc, segment_data);
4720cac4ca3SEd Maste }
4730cac4ca3SEd Maste }
4740cac4ca3SEd Maste
4750cac4ca3SEd Maste return core_notes_crc;
4760cac4ca3SEd Maste }
4770cac4ca3SEd Maste
OSABIAsCString(unsigned char osabi_byte)47814f1b3e8SDimitry Andric static const char *OSABIAsCString(unsigned char osabi_byte) {
47914f1b3e8SDimitry Andric #define _MAKE_OSABI_CASE(x) \
48014f1b3e8SDimitry Andric case x: \
48114f1b3e8SDimitry Andric return #x
48214f1b3e8SDimitry Andric switch (osabi_byte) {
4830cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_NONE);
4840cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_HPUX);
4850cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_NETBSD);
4860cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_GNU);
4870cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_HURD);
4880cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_SOLARIS);
4890cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_AIX);
4900cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_IRIX);
4910cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_FREEBSD);
4920cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_TRU64);
4930cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_MODESTO);
4940cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_OPENBSD);
4950cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_OPENVMS);
4960cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_NSK);
4970cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_AROS);
4980cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_FENIXOS);
4990cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_C6000_ELFABI);
5000cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_C6000_LINUX);
5010cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_ARM);
5020cac4ca3SEd Maste _MAKE_OSABI_CASE(ELFOSABI_STANDALONE);
5030cac4ca3SEd Maste default:
5040cac4ca3SEd Maste return "<unknown-osabi>";
5050cac4ca3SEd Maste }
5060cac4ca3SEd Maste #undef _MAKE_OSABI_CASE
5070cac4ca3SEd Maste }
5080cac4ca3SEd Maste
5095e95aa85SEd Maste //
5105e95aa85SEd Maste // WARNING : This function is being deprecated
511f73363f1SDimitry Andric // It's functionality has moved to ArchSpec::SetArchitecture This function is
512f73363f1SDimitry Andric // only being kept to validate the move.
5135e95aa85SEd Maste //
5145e95aa85SEd Maste // TODO : Remove this function
GetOsFromOSABI(unsigned char osabi_byte,llvm::Triple::OSType & ostype)51514f1b3e8SDimitry Andric static bool GetOsFromOSABI(unsigned char osabi_byte,
51614f1b3e8SDimitry Andric llvm::Triple::OSType &ostype) {
51714f1b3e8SDimitry Andric switch (osabi_byte) {
51814f1b3e8SDimitry Andric case ELFOSABI_AIX:
51914f1b3e8SDimitry Andric ostype = llvm::Triple::OSType::AIX;
52014f1b3e8SDimitry Andric break;
52114f1b3e8SDimitry Andric case ELFOSABI_FREEBSD:
52214f1b3e8SDimitry Andric ostype = llvm::Triple::OSType::FreeBSD;
52314f1b3e8SDimitry Andric break;
52414f1b3e8SDimitry Andric case ELFOSABI_GNU:
52514f1b3e8SDimitry Andric ostype = llvm::Triple::OSType::Linux;
52614f1b3e8SDimitry Andric break;
52714f1b3e8SDimitry Andric case ELFOSABI_NETBSD:
52814f1b3e8SDimitry Andric ostype = llvm::Triple::OSType::NetBSD;
52914f1b3e8SDimitry Andric break;
53014f1b3e8SDimitry Andric case ELFOSABI_OPENBSD:
53114f1b3e8SDimitry Andric ostype = llvm::Triple::OSType::OpenBSD;
53214f1b3e8SDimitry Andric break;
53314f1b3e8SDimitry Andric case ELFOSABI_SOLARIS:
53414f1b3e8SDimitry Andric ostype = llvm::Triple::OSType::Solaris;
53514f1b3e8SDimitry Andric break;
5360cac4ca3SEd Maste default:
5370cac4ca3SEd Maste ostype = llvm::Triple::OSType::UnknownOS;
5380cac4ca3SEd Maste }
5390cac4ca3SEd Maste return ostype != llvm::Triple::OSType::UnknownOS;
5400cac4ca3SEd Maste }
5410cac4ca3SEd Maste
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)54214f1b3e8SDimitry Andric size_t ObjectFileELF::GetModuleSpecifications(
54314f1b3e8SDimitry Andric const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
54414f1b3e8SDimitry Andric lldb::offset_t data_offset, lldb::offset_t file_offset,
54514f1b3e8SDimitry Andric lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
546145449b1SDimitry Andric Log *log = GetLog(LLDBLog::Modules);
5470cac4ca3SEd Maste
548f034231aSEd Maste const size_t initial_count = specs.GetSize();
549f034231aSEd Maste
55014f1b3e8SDimitry Andric if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
551f034231aSEd Maste DataExtractor data;
552f034231aSEd Maste data.SetData(data_sp);
553f034231aSEd Maste elf::ELFHeader header;
55474a628f7SDimitry Andric lldb::offset_t header_offset = data_offset;
55574a628f7SDimitry Andric if (header.Parse(data, &header_offset)) {
55614f1b3e8SDimitry Andric if (data_sp) {
5575e95aa85SEd Maste ModuleSpec spec(file);
5587fa27ce4SDimitry Andric // In Android API level 23 and above, bionic dynamic linker is able to
5597fa27ce4SDimitry Andric // load .so file directly from zip file. In that case, .so file is
5607fa27ce4SDimitry Andric // page aligned and uncompressed, and this module spec should retain the
5617fa27ce4SDimitry Andric // .so file offset and file size to pass through the information from
5627fa27ce4SDimitry Andric // lldb-server to LLDB. For normal file, file_offset should be 0,
5637fa27ce4SDimitry Andric // length should be the size of the file.
5647fa27ce4SDimitry Andric spec.SetObjectOffset(file_offset);
5657fa27ce4SDimitry Andric spec.SetObjectSize(length);
5660cac4ca3SEd Maste
5670cac4ca3SEd Maste const uint32_t sub_type = subTypeFromElfHeader(header);
56814f1b3e8SDimitry Andric spec.GetArchitecture().SetArchitecture(
56914f1b3e8SDimitry Andric eArchTypeELF, header.e_machine, sub_type, header.e_ident[EI_OSABI]);
5700cac4ca3SEd Maste
57114f1b3e8SDimitry Andric if (spec.GetArchitecture().IsValid()) {
5720cac4ca3SEd Maste llvm::Triple::OSType ostype;
5735e95aa85SEd Maste llvm::Triple::VendorType vendor;
57414f1b3e8SDimitry Andric llvm::Triple::OSType spec_ostype =
57514f1b3e8SDimitry Andric spec.GetArchitecture().GetTriple().getOS();
5760cac4ca3SEd Maste
577ead24645SDimitry Andric LLDB_LOGF(log, "ObjectFileELF::%s file '%s' module OSABI: %s",
57814f1b3e8SDimitry Andric __FUNCTION__, file.GetPath().c_str(),
57914f1b3e8SDimitry Andric OSABIAsCString(header.e_ident[EI_OSABI]));
5805e95aa85SEd Maste
5815e95aa85SEd Maste // SetArchitecture should have set the vendor to unknown
5825e95aa85SEd Maste vendor = spec.GetArchitecture().GetTriple().getVendor();
5835e95aa85SEd Maste assert(vendor == llvm::Triple::UnknownVendor);
58474a628f7SDimitry Andric UNUSED_IF_ASSERT_DISABLED(vendor);
5855e95aa85SEd Maste
5865e95aa85SEd Maste //
5875e95aa85SEd Maste // Validate it is ok to remove GetOsFromOSABI
5885e95aa85SEd Maste GetOsFromOSABI(header.e_ident[EI_OSABI], ostype);
5895e95aa85SEd Maste assert(spec_ostype == ostype);
59014f1b3e8SDimitry Andric if (spec_ostype != llvm::Triple::OSType::UnknownOS) {
591ead24645SDimitry Andric LLDB_LOGF(log,
592ead24645SDimitry Andric "ObjectFileELF::%s file '%s' set ELF module OS type "
59314f1b3e8SDimitry Andric "from ELF header OSABI.",
59414f1b3e8SDimitry Andric __FUNCTION__, file.GetPath().c_str());
5950cac4ca3SEd Maste }
596f034231aSEd Maste
5977fa27ce4SDimitry Andric // When ELF file does not contain GNU build ID, the later code will
5987fa27ce4SDimitry Andric // calculate CRC32 with this data_sp file_offset and length. It is
5997fa27ce4SDimitry Andric // important for Android zip .so file, which is a slice of a file,
6007fa27ce4SDimitry Andric // to not access the outside of the file slice range.
601cfca06d7SDimitry Andric if (data_sp->GetByteSize() < length)
6027fa27ce4SDimitry Andric data_sp = MapFileData(file, length, file_offset);
60374a628f7SDimitry Andric if (data_sp)
604f034231aSEd Maste data.SetData(data_sp);
605f73363f1SDimitry Andric // In case there is header extension in the section #0, the header we
606f73363f1SDimitry Andric // parsed above could have sentinel values for e_phnum, e_shnum, and
607f73363f1SDimitry Andric // e_shstrndx. In this case we need to reparse the header with a
608f73363f1SDimitry Andric // bigger data source to get the actual values.
609f73363f1SDimitry Andric if (header.HasHeaderExtension()) {
610f73363f1SDimitry Andric lldb::offset_t header_offset = data_offset;
611f73363f1SDimitry Andric header.Parse(data, &header_offset);
612f034231aSEd Maste }
613f034231aSEd Maste
614f034231aSEd Maste uint32_t gnu_debuglink_crc = 0;
615f034231aSEd Maste std::string gnu_debuglink_file;
616f034231aSEd Maste SectionHeaderColl section_headers;
617f034231aSEd Maste lldb_private::UUID &uuid = spec.GetUUID();
6180cac4ca3SEd Maste
619fdea456aSDimitry Andric GetSectionHeaderInfo(section_headers, data, header, uuid,
62014f1b3e8SDimitry Andric gnu_debuglink_file, gnu_debuglink_crc,
62114f1b3e8SDimitry Andric spec.GetArchitecture());
6220cac4ca3SEd Maste
6230cac4ca3SEd Maste llvm::Triple &spec_triple = spec.GetArchitecture().GetTriple();
6240cac4ca3SEd Maste
625ead24645SDimitry Andric LLDB_LOGF(log,
626ead24645SDimitry Andric "ObjectFileELF::%s file '%s' module set to triple: %s "
62714f1b3e8SDimitry Andric "(architecture %s)",
62814f1b3e8SDimitry Andric __FUNCTION__, file.GetPath().c_str(),
62914f1b3e8SDimitry Andric spec_triple.getTriple().c_str(),
63014f1b3e8SDimitry Andric spec.GetArchitecture().GetArchitectureName());
631f034231aSEd Maste
63214f1b3e8SDimitry Andric if (!uuid.IsValid()) {
6330cac4ca3SEd Maste uint32_t core_notes_crc = 0;
6340cac4ca3SEd Maste
63514f1b3e8SDimitry Andric if (!gnu_debuglink_crc) {
636b60736ecSDimitry Andric LLDB_SCOPED_TIMERF(
6370cac4ca3SEd Maste "Calculating module crc32 %s with size %" PRIu64 " KiB",
6387fa27ce4SDimitry Andric file.GetFilename().AsCString(),
639cfca06d7SDimitry Andric (length - file_offset) / 1024);
6400cac4ca3SEd Maste
64114f1b3e8SDimitry Andric // For core files - which usually don't happen to have a
64274a628f7SDimitry Andric // gnu_debuglink, and are pretty bulky - calculating whole
64374a628f7SDimitry Andric // contents crc32 would be too much of luxury. Thus we will need
64474a628f7SDimitry Andric // to fallback to something simpler.
64514f1b3e8SDimitry Andric if (header.e_type == llvm::ELF::ET_CORE) {
6460cac4ca3SEd Maste ProgramHeaderColl program_headers;
647fdea456aSDimitry Andric GetProgramHeaderInfo(program_headers, data, header);
6480cac4ca3SEd Maste
64914f1b3e8SDimitry Andric core_notes_crc =
65014f1b3e8SDimitry Andric CalculateELFNotesSegmentsCRC32(program_headers, data);
65114f1b3e8SDimitry Andric } else {
652ead24645SDimitry Andric gnu_debuglink_crc = calc_crc32(0, data);
653f034231aSEd Maste }
6540cac4ca3SEd Maste }
655f73363f1SDimitry Andric using u32le = llvm::support::ulittle32_t;
65614f1b3e8SDimitry Andric if (gnu_debuglink_crc) {
657f034231aSEd Maste // Use 4 bytes of crc from the .gnu_debuglink section.
658f73363f1SDimitry Andric u32le data(gnu_debuglink_crc);
659e3b55780SDimitry Andric uuid = UUID(&data, sizeof(data));
66014f1b3e8SDimitry Andric } else if (core_notes_crc) {
66114f1b3e8SDimitry Andric // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make
662f73363f1SDimitry Andric // it look different form .gnu_debuglink crc followed by 4 bytes
663f73363f1SDimitry Andric // of note segments crc.
664f73363f1SDimitry Andric u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)};
665e3b55780SDimitry Andric uuid = UUID(data, sizeof(data));
6660cac4ca3SEd Maste }
667f034231aSEd Maste }
668f034231aSEd Maste
669f034231aSEd Maste specs.Append(spec);
670f034231aSEd Maste }
671f034231aSEd Maste }
672f034231aSEd Maste }
673f034231aSEd Maste }
674f034231aSEd Maste
675f034231aSEd Maste return specs.GetSize() - initial_count;
676f034231aSEd Maste }
677f034231aSEd Maste
678f034231aSEd Maste // ObjectFile protocol
679f034231aSEd Maste
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)680f034231aSEd Maste ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
681145449b1SDimitry Andric DataBufferSP data_sp, lldb::offset_t data_offset,
68214f1b3e8SDimitry Andric const FileSpec *file, lldb::offset_t file_offset,
68314f1b3e8SDimitry Andric lldb::offset_t length)
684ead24645SDimitry Andric : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset) {
685f034231aSEd Maste if (file)
686f034231aSEd Maste m_file = *file;
6870cac4ca3SEd Maste }
6880cac4ca3SEd Maste
ObjectFileELF(const lldb::ModuleSP & module_sp,DataBufferSP header_data_sp,const lldb::ProcessSP & process_sp,addr_t header_addr)6890cac4ca3SEd Maste ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
690145449b1SDimitry Andric DataBufferSP header_data_sp,
6910cac4ca3SEd Maste const lldb::ProcessSP &process_sp,
69214f1b3e8SDimitry Andric addr_t header_addr)
693ead24645SDimitry Andric : ObjectFile(module_sp, process_sp, header_addr, header_data_sp) {}
694f034231aSEd Maste
IsExecutable() const69514f1b3e8SDimitry Andric bool ObjectFileELF::IsExecutable() const {
6960cac4ca3SEd Maste return ((m_header.e_type & ET_EXEC) != 0) || (m_header.e_entry != 0);
697f034231aSEd Maste }
698f034231aSEd Maste
SetLoadAddress(Target & target,lldb::addr_t value,bool value_is_offset)69914f1b3e8SDimitry Andric bool ObjectFileELF::SetLoadAddress(Target &target, lldb::addr_t value,
70014f1b3e8SDimitry Andric bool value_is_offset) {
701866dcdacSEd Maste ModuleSP module_sp = GetModule();
70214f1b3e8SDimitry Andric if (module_sp) {
703866dcdacSEd Maste size_t num_loaded_sections = 0;
704866dcdacSEd Maste SectionList *section_list = GetSectionList();
70514f1b3e8SDimitry Andric if (section_list) {
70614f1b3e8SDimitry Andric if (!value_is_offset) {
70794994d37SDimitry Andric addr_t base = GetBaseAddress().GetFileAddress();
70894994d37SDimitry Andric if (base == LLDB_INVALID_ADDRESS)
709e81d9d49SDimitry Andric return false;
71094994d37SDimitry Andric value -= base;
711e81d9d49SDimitry Andric }
712e81d9d49SDimitry Andric
713866dcdacSEd Maste const size_t num_sections = section_list->GetSize();
714866dcdacSEd Maste size_t sect_idx = 0;
715866dcdacSEd Maste
71614f1b3e8SDimitry Andric for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
717f73363f1SDimitry Andric // Iterate through the object file sections to find all of the sections
718f73363f1SDimitry Andric // that have SHF_ALLOC in their flag bits.
719866dcdacSEd Maste SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
720ac9a064cSDimitry Andric
721ac9a064cSDimitry Andric // PT_TLS segments can have the same p_vaddr and p_paddr as other
722ac9a064cSDimitry Andric // PT_LOAD segments so we shouldn't load them. If we do load them, then
723ac9a064cSDimitry Andric // the SectionLoadList will incorrectly fill in the instance variable
724ac9a064cSDimitry Andric // SectionLoadList::m_addr_to_sect with the same address as a PT_LOAD
725ac9a064cSDimitry Andric // segment and we won't be able to resolve addresses in the PT_LOAD
726ac9a064cSDimitry Andric // segment whose p_vaddr entry matches that of the PT_TLS. Any variables
727ac9a064cSDimitry Andric // that appear in the PT_TLS segments get resolved by the DWARF
728ac9a064cSDimitry Andric // expressions. If this ever changes we will need to fix all object
729ac9a064cSDimitry Andric // file plug-ins, but until then, we don't want PT_TLS segments to
730ac9a064cSDimitry Andric // remove the entry from SectionLoadList::m_addr_to_sect when we call
731ac9a064cSDimitry Andric // SetSectionLoadAddress() below.
732ac9a064cSDimitry Andric if (section_sp->IsThreadSpecific())
733ac9a064cSDimitry Andric continue;
73494994d37SDimitry Andric if (section_sp->Test(SHF_ALLOC) ||
73594994d37SDimitry Andric section_sp->GetType() == eSectionTypeContainer) {
736f3fbd1c0SDimitry Andric lldb::addr_t load_addr = section_sp->GetFileAddress();
737f3fbd1c0SDimitry Andric // We don't want to update the load address of a section with type
73814f1b3e8SDimitry Andric // eSectionTypeAbsoluteAddress as they already have the absolute load
739f73363f1SDimitry Andric // address already specified
740f3fbd1c0SDimitry Andric if (section_sp->GetType() != eSectionTypeAbsoluteAddress)
741f3fbd1c0SDimitry Andric load_addr += value;
7425e95aa85SEd Maste
74314f1b3e8SDimitry Andric // On 32-bit systems the load address have to fit into 4 bytes. The
744f73363f1SDimitry Andric // rest of the bytes are the overflow from the addition.
7455e95aa85SEd Maste if (GetAddressByteSize() == 4)
7465e95aa85SEd Maste load_addr &= 0xFFFFFFFF;
7475e95aa85SEd Maste
74814f1b3e8SDimitry Andric if (target.GetSectionLoadList().SetSectionLoadAddress(section_sp,
74914f1b3e8SDimitry Andric load_addr))
750866dcdacSEd Maste ++num_loaded_sections;
751866dcdacSEd Maste }
752866dcdacSEd Maste }
753866dcdacSEd Maste return num_loaded_sections > 0;
754866dcdacSEd Maste }
755866dcdacSEd Maste }
756e81d9d49SDimitry Andric return false;
757866dcdacSEd Maste }
758866dcdacSEd Maste
GetByteOrder() const75914f1b3e8SDimitry Andric ByteOrder ObjectFileELF::GetByteOrder() const {
760f034231aSEd Maste if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
761f034231aSEd Maste return eByteOrderBig;
762f034231aSEd Maste if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
763f034231aSEd Maste return eByteOrderLittle;
764f034231aSEd Maste return eByteOrderInvalid;
765f034231aSEd Maste }
766f034231aSEd Maste
GetAddressByteSize() const76714f1b3e8SDimitry Andric uint32_t ObjectFileELF::GetAddressByteSize() const {
768f034231aSEd Maste return m_data.GetAddressByteSize();
769f034231aSEd Maste }
770f034231aSEd Maste
GetAddressClass(addr_t file_addr)77114f1b3e8SDimitry Andric AddressClass ObjectFileELF::GetAddressClass(addr_t file_addr) {
772e81d9d49SDimitry Andric Symtab *symtab = GetSymtab();
773e81d9d49SDimitry Andric if (!symtab)
774f73363f1SDimitry Andric return AddressClass::eUnknown;
775205afe67SEd Maste
776f73363f1SDimitry Andric // The address class is determined based on the symtab. Ask it from the
777f73363f1SDimitry Andric // object file what contains the symtab information.
778e81d9d49SDimitry Andric ObjectFile *symtab_objfile = symtab->GetObjectFile();
779e81d9d49SDimitry Andric if (symtab_objfile != nullptr && symtab_objfile != this)
780e81d9d49SDimitry Andric return symtab_objfile->GetAddressClass(file_addr);
781e81d9d49SDimitry Andric
782e81d9d49SDimitry Andric auto res = ObjectFile::GetAddressClass(file_addr);
783f73363f1SDimitry Andric if (res != AddressClass::eCode)
784205afe67SEd Maste return res;
785205afe67SEd Maste
7865e95aa85SEd Maste auto ub = m_address_class_map.upper_bound(file_addr);
78714f1b3e8SDimitry Andric if (ub == m_address_class_map.begin()) {
788f73363f1SDimitry Andric // No entry in the address class map before the address. Return default
789f73363f1SDimitry Andric // address class for an address in a code section.
790f73363f1SDimitry Andric return AddressClass::eCode;
7915e95aa85SEd Maste }
792205afe67SEd Maste
7935e95aa85SEd Maste // Move iterator to the address class entry preceding address
7945e95aa85SEd Maste --ub;
795205afe67SEd Maste
7965e95aa85SEd Maste return ub->second;
797205afe67SEd Maste }
798205afe67SEd Maste
SectionIndex(const SectionHeaderCollIter & I)79914f1b3e8SDimitry Andric size_t ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I) {
80094994d37SDimitry Andric return std::distance(m_section_headers.begin(), I);
801f034231aSEd Maste }
802f034231aSEd Maste
SectionIndex(const SectionHeaderCollConstIter & I) const80314f1b3e8SDimitry Andric size_t ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const {
80494994d37SDimitry Andric return std::distance(m_section_headers.begin(), I);
805f034231aSEd Maste }
806f034231aSEd Maste
ParseHeader()80714f1b3e8SDimitry Andric bool ObjectFileELF::ParseHeader() {
808f034231aSEd Maste lldb::offset_t offset = 0;
809fdea456aSDimitry Andric return m_header.Parse(m_data, &offset);
810f034231aSEd Maste }
811f034231aSEd Maste
GetUUID()8125f29bb8aSDimitry Andric UUID ObjectFileELF::GetUUID() {
81314f1b3e8SDimitry Andric // Need to parse the section list to get the UUIDs, so make sure that's been
81414f1b3e8SDimitry Andric // done.
8150cac4ca3SEd Maste if (!ParseSectionHeaders() && GetType() != ObjectFile::eTypeCoreFile)
8165f29bb8aSDimitry Andric return UUID();
817f034231aSEd Maste
8185f29bb8aSDimitry Andric if (!m_uuid) {
819f73363f1SDimitry Andric using u32le = llvm::support::ulittle32_t;
8205f29bb8aSDimitry Andric if (GetType() == ObjectFile::eTypeCoreFile) {
8210cac4ca3SEd Maste uint32_t core_notes_crc = 0;
8220cac4ca3SEd Maste
8230cac4ca3SEd Maste if (!ParseProgramHeaders())
8245f29bb8aSDimitry Andric return UUID();
8250cac4ca3SEd Maste
8265f29bb8aSDimitry Andric core_notes_crc =
8275f29bb8aSDimitry Andric CalculateELFNotesSegmentsCRC32(m_program_headers, m_data);
8280cac4ca3SEd Maste
82914f1b3e8SDimitry Andric if (core_notes_crc) {
8305f29bb8aSDimitry Andric // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it
8315f29bb8aSDimitry Andric // look different form .gnu_debuglink crc - followed by 4 bytes of note
8320cac4ca3SEd Maste // segments crc.
833f73363f1SDimitry Andric u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)};
834e3b55780SDimitry Andric m_uuid = UUID(data, sizeof(data));
8350cac4ca3SEd Maste }
83614f1b3e8SDimitry Andric } else {
837f034231aSEd Maste if (!m_gnu_debuglink_crc)
838ead24645SDimitry Andric m_gnu_debuglink_crc = calc_crc32(0, m_data);
83914f1b3e8SDimitry Andric if (m_gnu_debuglink_crc) {
840f034231aSEd Maste // Use 4 bytes of crc from the .gnu_debuglink section.
841f73363f1SDimitry Andric u32le data(m_gnu_debuglink_crc);
842e3b55780SDimitry Andric m_uuid = UUID(&data, sizeof(data));
843f034231aSEd Maste }
844f034231aSEd Maste }
8450cac4ca3SEd Maste }
8460cac4ca3SEd Maste
8475f29bb8aSDimitry Andric return m_uuid;
848f034231aSEd Maste }
849f034231aSEd Maste
GetDebugLink()850e3b55780SDimitry Andric std::optional<FileSpec> ObjectFileELF::GetDebugLink() {
851ead24645SDimitry Andric if (m_gnu_debuglink_file.empty())
852e3b55780SDimitry Andric return std::nullopt;
853ead24645SDimitry Andric return FileSpec(m_gnu_debuglink_file);
854f034231aSEd Maste }
855f034231aSEd Maste
GetDependentModules(FileSpecList & files)85614f1b3e8SDimitry Andric uint32_t ObjectFileELF::GetDependentModules(FileSpecList &files) {
857f034231aSEd Maste size_t num_modules = ParseDependentModules();
858f034231aSEd Maste uint32_t num_specs = 0;
859f034231aSEd Maste
86014f1b3e8SDimitry Andric for (unsigned i = 0; i < num_modules; ++i) {
8615f29bb8aSDimitry Andric if (files.AppendIfUnique(m_filespec_up->GetFileSpecAtIndex(i)))
862f034231aSEd Maste num_specs++;
863f034231aSEd Maste }
864f034231aSEd Maste
865f034231aSEd Maste return num_specs;
866f034231aSEd Maste }
867f034231aSEd Maste
GetImageInfoAddress(Target * target)86814f1b3e8SDimitry Andric Address ObjectFileELF::GetImageInfoAddress(Target *target) {
869f034231aSEd Maste if (!ParseDynamicSymbols())
870f034231aSEd Maste return Address();
871f034231aSEd Maste
872f034231aSEd Maste SectionList *section_list = GetSectionList();
873f034231aSEd Maste if (!section_list)
874f034231aSEd Maste return Address();
875f034231aSEd Maste
876f034231aSEd Maste // Find the SHT_DYNAMIC (.dynamic) section.
87714f1b3e8SDimitry Andric SectionSP dynsym_section_sp(
87814f1b3e8SDimitry Andric section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true));
879f034231aSEd Maste if (!dynsym_section_sp)
880f034231aSEd Maste return Address();
881f034231aSEd Maste assert(dynsym_section_sp->GetObjectFile() == this);
882f034231aSEd Maste
883f034231aSEd Maste user_id_t dynsym_id = dynsym_section_sp->GetID();
884f034231aSEd Maste const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
885f034231aSEd Maste if (!dynsym_hdr)
886f034231aSEd Maste return Address();
887f034231aSEd Maste
88814f1b3e8SDimitry Andric for (size_t i = 0; i < m_dynamic_symbols.size(); ++i) {
889f034231aSEd Maste ELFDynamic &symbol = m_dynamic_symbols[i];
890f034231aSEd Maste
89114f1b3e8SDimitry Andric if (symbol.d_tag == DT_DEBUG) {
892f73363f1SDimitry Andric // Compute the offset as the number of previous entries plus the size of
893f73363f1SDimitry Andric // d_tag.
894f034231aSEd Maste addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
895f034231aSEd Maste return Address(dynsym_section_sp, offset);
896f034231aSEd Maste }
89714f1b3e8SDimitry Andric // MIPS executables uses DT_MIPS_RLD_MAP_REL to support PIE. DT_MIPS_RLD_MAP
89814f1b3e8SDimitry Andric // exists in non-PIE.
89914f1b3e8SDimitry Andric else if ((symbol.d_tag == DT_MIPS_RLD_MAP ||
90014f1b3e8SDimitry Andric symbol.d_tag == DT_MIPS_RLD_MAP_REL) &&
90114f1b3e8SDimitry Andric target) {
902f21a844fSEd Maste addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
903f21a844fSEd Maste addr_t dyn_base = dynsym_section_sp->GetLoadBaseAddress(target);
904f21a844fSEd Maste if (dyn_base == LLDB_INVALID_ADDRESS)
905f21a844fSEd Maste return Address();
906e81d9d49SDimitry Andric
907b76161e4SDimitry Andric Status error;
90814f1b3e8SDimitry Andric if (symbol.d_tag == DT_MIPS_RLD_MAP) {
909e81d9d49SDimitry Andric // DT_MIPS_RLD_MAP tag stores an absolute address of the debug pointer.
910e81d9d49SDimitry Andric Address addr;
911344a3780SDimitry Andric if (target->ReadPointerFromMemory(dyn_base + offset, error, addr, true))
912f21a844fSEd Maste return addr;
913f21a844fSEd Maste }
91414f1b3e8SDimitry Andric if (symbol.d_tag == DT_MIPS_RLD_MAP_REL) {
91514f1b3e8SDimitry Andric // DT_MIPS_RLD_MAP_REL tag stores the offset to the debug pointer,
91614f1b3e8SDimitry Andric // relative to the address of the tag.
917e81d9d49SDimitry Andric uint64_t rel_offset;
91814f1b3e8SDimitry Andric rel_offset = target->ReadUnsignedIntegerFromMemory(
919344a3780SDimitry Andric dyn_base + offset, GetAddressByteSize(), UINT64_MAX, error, true);
92014f1b3e8SDimitry Andric if (error.Success() && rel_offset != UINT64_MAX) {
921e81d9d49SDimitry Andric Address addr;
92214f1b3e8SDimitry Andric addr_t debug_ptr_address =
92314f1b3e8SDimitry Andric dyn_base + (offset - GetAddressByteSize()) + rel_offset;
924e81d9d49SDimitry Andric addr.SetOffset(debug_ptr_address);
925e81d9d49SDimitry Andric return addr;
926e81d9d49SDimitry Andric }
927e81d9d49SDimitry Andric }
928e81d9d49SDimitry Andric }
929f034231aSEd Maste }
930f034231aSEd Maste
931f034231aSEd Maste return Address();
932f034231aSEd Maste }
933f034231aSEd Maste
GetEntryPointAddress()93414f1b3e8SDimitry Andric lldb_private::Address ObjectFileELF::GetEntryPointAddress() {
935f034231aSEd Maste if (m_entry_point_address.IsValid())
936f034231aSEd Maste return m_entry_point_address;
937f034231aSEd Maste
938f034231aSEd Maste if (!ParseHeader() || !IsExecutable())
939f034231aSEd Maste return m_entry_point_address;
940f034231aSEd Maste
941f034231aSEd Maste SectionList *section_list = GetSectionList();
942f034231aSEd Maste addr_t offset = m_header.e_entry;
943f034231aSEd Maste
944f034231aSEd Maste if (!section_list)
945f034231aSEd Maste m_entry_point_address.SetOffset(offset);
946f034231aSEd Maste else
947f034231aSEd Maste m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
948f034231aSEd Maste return m_entry_point_address;
949f034231aSEd Maste }
950f034231aSEd Maste
GetBaseAddress()95194994d37SDimitry Andric Address ObjectFileELF::GetBaseAddress() {
952b1c73532SDimitry Andric if (GetType() == ObjectFile::eTypeObjectFile) {
953b1c73532SDimitry Andric for (SectionHeaderCollIter I = std::next(m_section_headers.begin());
954b1c73532SDimitry Andric I != m_section_headers.end(); ++I) {
955b1c73532SDimitry Andric const ELFSectionHeaderInfo &header = *I;
956b1c73532SDimitry Andric if (header.sh_flags & SHF_ALLOC)
957b1c73532SDimitry Andric return Address(GetSectionList()->FindSectionByID(SectionIndex(I)), 0);
958b1c73532SDimitry Andric }
959b1c73532SDimitry Andric return LLDB_INVALID_ADDRESS;
960b1c73532SDimitry Andric }
961b1c73532SDimitry Andric
96294994d37SDimitry Andric for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) {
96394994d37SDimitry Andric const ELFProgramHeader &H = EnumPHdr.value();
96494994d37SDimitry Andric if (H.p_type != PT_LOAD)
96594994d37SDimitry Andric continue;
96694994d37SDimitry Andric
96794994d37SDimitry Andric return Address(
96894994d37SDimitry Andric GetSectionList()->FindSectionByID(SegmentID(EnumPHdr.index())), 0);
96994994d37SDimitry Andric }
97094994d37SDimitry Andric return LLDB_INVALID_ADDRESS;
97194994d37SDimitry Andric }
97294994d37SDimitry Andric
973f034231aSEd Maste // ParseDependentModules
ParseDependentModules()97414f1b3e8SDimitry Andric size_t ObjectFileELF::ParseDependentModules() {
9755f29bb8aSDimitry Andric if (m_filespec_up)
9765f29bb8aSDimitry Andric return m_filespec_up->GetSize();
977f034231aSEd Maste
978cfca06d7SDimitry Andric m_filespec_up = std::make_unique<FileSpecList>();
979f034231aSEd Maste
980f034231aSEd Maste if (!ParseSectionHeaders())
981f034231aSEd Maste return 0;
982f034231aSEd Maste
983f034231aSEd Maste SectionList *section_list = GetSectionList();
984f034231aSEd Maste if (!section_list)
985f034231aSEd Maste return 0;
986f034231aSEd Maste
987f034231aSEd Maste // Find the SHT_DYNAMIC section.
98814f1b3e8SDimitry Andric Section *dynsym =
98914f1b3e8SDimitry Andric section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true)
99014f1b3e8SDimitry Andric .get();
991f034231aSEd Maste if (!dynsym)
992f034231aSEd Maste return 0;
993f034231aSEd Maste assert(dynsym->GetObjectFile() == this);
994f034231aSEd Maste
995f034231aSEd Maste const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex(dynsym->GetID());
996f034231aSEd Maste if (!header)
997f034231aSEd Maste return 0;
99814f1b3e8SDimitry Andric // sh_link: section header index of string table used by entries in the
99914f1b3e8SDimitry Andric // section.
100094994d37SDimitry Andric Section *dynstr = section_list->FindSectionByID(header->sh_link).get();
1001f034231aSEd Maste if (!dynstr)
1002f034231aSEd Maste return 0;
1003f034231aSEd Maste
1004f034231aSEd Maste DataExtractor dynsym_data;
1005f034231aSEd Maste DataExtractor dynstr_data;
1006f034231aSEd Maste if (ReadSectionData(dynsym, dynsym_data) &&
100714f1b3e8SDimitry Andric ReadSectionData(dynstr, dynstr_data)) {
1008f034231aSEd Maste ELFDynamic symbol;
1009f034231aSEd Maste const lldb::offset_t section_size = dynsym_data.GetByteSize();
1010f034231aSEd Maste lldb::offset_t offset = 0;
1011f034231aSEd Maste
1012f034231aSEd Maste // The only type of entries we are concerned with are tagged DT_NEEDED,
1013f034231aSEd Maste // yielding the name of a required library.
101414f1b3e8SDimitry Andric while (offset < section_size) {
1015f034231aSEd Maste if (!symbol.Parse(dynsym_data, &offset))
1016f034231aSEd Maste break;
1017f034231aSEd Maste
1018f034231aSEd Maste if (symbol.d_tag != DT_NEEDED)
1019f034231aSEd Maste continue;
1020f034231aSEd Maste
1021f034231aSEd Maste uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
1022f034231aSEd Maste const char *lib_name = dynstr_data.PeekCStr(str_index);
102394994d37SDimitry Andric FileSpec file_spec(lib_name);
102494994d37SDimitry Andric FileSystem::Instance().Resolve(file_spec);
10255f29bb8aSDimitry Andric m_filespec_up->Append(file_spec);
1026f034231aSEd Maste }
1027f034231aSEd Maste }
1028f034231aSEd Maste
10295f29bb8aSDimitry Andric return m_filespec_up->GetSize();
1030f034231aSEd Maste }
1031f034231aSEd Maste
10320cac4ca3SEd Maste // GetProgramHeaderInfo
GetProgramHeaderInfo(ProgramHeaderColl & program_headers,DataExtractor & object_data,const ELFHeader & header)103314f1b3e8SDimitry Andric size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
1034fdea456aSDimitry Andric DataExtractor &object_data,
103514f1b3e8SDimitry Andric const ELFHeader &header) {
10360cac4ca3SEd Maste // We have already parsed the program headers
10370cac4ca3SEd Maste if (!program_headers.empty())
10380cac4ca3SEd Maste return program_headers.size();
10390cac4ca3SEd Maste
10400cac4ca3SEd Maste // If there are no program headers to read we are done.
10410cac4ca3SEd Maste if (header.e_phnum == 0)
10420cac4ca3SEd Maste return 0;
10430cac4ca3SEd Maste
10440cac4ca3SEd Maste program_headers.resize(header.e_phnum);
10450cac4ca3SEd Maste if (program_headers.size() != header.e_phnum)
10460cac4ca3SEd Maste return 0;
10470cac4ca3SEd Maste
10480cac4ca3SEd Maste const size_t ph_size = header.e_phnum * header.e_phentsize;
10490cac4ca3SEd Maste const elf_off ph_offset = header.e_phoff;
10500cac4ca3SEd Maste DataExtractor data;
1051fdea456aSDimitry Andric if (data.SetData(object_data, ph_offset, ph_size) != ph_size)
10520cac4ca3SEd Maste return 0;
10530cac4ca3SEd Maste
10540cac4ca3SEd Maste uint32_t idx;
10550cac4ca3SEd Maste lldb::offset_t offset;
105614f1b3e8SDimitry Andric for (idx = 0, offset = 0; idx < header.e_phnum; ++idx) {
105794994d37SDimitry Andric if (!program_headers[idx].Parse(data, &offset))
10580cac4ca3SEd Maste break;
10590cac4ca3SEd Maste }
10600cac4ca3SEd Maste
10610cac4ca3SEd Maste if (idx < program_headers.size())
10620cac4ca3SEd Maste program_headers.resize(idx);
10630cac4ca3SEd Maste
10640cac4ca3SEd Maste return program_headers.size();
10650cac4ca3SEd Maste }
10660cac4ca3SEd Maste
1067f034231aSEd Maste // ParseProgramHeaders
ParseProgramHeaders()106894994d37SDimitry Andric bool ObjectFileELF::ParseProgramHeaders() {
106994994d37SDimitry Andric return GetProgramHeaderInfo(m_program_headers, m_data, m_header) != 0;
1070f034231aSEd Maste }
1071f034231aSEd Maste
1072b76161e4SDimitry Andric lldb_private::Status
RefineModuleDetailsFromNote(lldb_private::DataExtractor & data,lldb_private::ArchSpec & arch_spec,lldb_private::UUID & uuid)107314f1b3e8SDimitry Andric ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
107414f1b3e8SDimitry Andric lldb_private::ArchSpec &arch_spec,
107514f1b3e8SDimitry Andric lldb_private::UUID &uuid) {
1076145449b1SDimitry Andric Log *log = GetLog(LLDBLog::Modules);
1077b76161e4SDimitry Andric Status error;
10780cac4ca3SEd Maste
1079f034231aSEd Maste lldb::offset_t offset = 0;
1080f034231aSEd Maste
108114f1b3e8SDimitry Andric while (true) {
10820cac4ca3SEd Maste // Parse the note header. If this fails, bail out.
1083e81d9d49SDimitry Andric const lldb::offset_t note_offset = offset;
108486758c71SEd Maste ELFNote note = ELFNote();
108514f1b3e8SDimitry Andric if (!note.Parse(data, &offset)) {
10860cac4ca3SEd Maste // We're done.
10870cac4ca3SEd Maste return error;
10880cac4ca3SEd Maste }
10890cac4ca3SEd Maste
1090ead24645SDimitry Andric LLDB_LOGF(log, "ObjectFileELF::%s parsing note name='%s', type=%" PRIu32,
109114f1b3e8SDimitry Andric __FUNCTION__, note.n_name.c_str(), note.n_type);
10920cac4ca3SEd Maste
10930cac4ca3SEd Maste // Process FreeBSD ELF notes.
10940cac4ca3SEd Maste if ((note.n_name == LLDB_NT_OWNER_FREEBSD) &&
10950cac4ca3SEd Maste (note.n_type == LLDB_NT_FREEBSD_ABI_TAG) &&
109614f1b3e8SDimitry Andric (note.n_descsz == LLDB_NT_FREEBSD_ABI_SIZE)) {
10970cac4ca3SEd Maste // Pull out the min version info.
10980cac4ca3SEd Maste uint32_t version_info;
109914f1b3e8SDimitry Andric if (data.GetU32(&offset, &version_info, 1) == nullptr) {
11000cac4ca3SEd Maste error.SetErrorString("failed to read FreeBSD ABI note payload");
11010cac4ca3SEd Maste return error;
11020cac4ca3SEd Maste }
11030cac4ca3SEd Maste
11040cac4ca3SEd Maste // Convert the version info into a major/minor number.
11050cac4ca3SEd Maste const uint32_t version_major = version_info / 100000;
11060cac4ca3SEd Maste const uint32_t version_minor = (version_info / 1000) % 100;
11070cac4ca3SEd Maste
11080cac4ca3SEd Maste char os_name[32];
110914f1b3e8SDimitry Andric snprintf(os_name, sizeof(os_name), "freebsd%" PRIu32 ".%" PRIu32,
111014f1b3e8SDimitry Andric version_major, version_minor);
11110cac4ca3SEd Maste
11120cac4ca3SEd Maste // Set the elf OS version to FreeBSD. Also clear the vendor.
11130cac4ca3SEd Maste arch_spec.GetTriple().setOSName(os_name);
11140cac4ca3SEd Maste arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
11150cac4ca3SEd Maste
1116ead24645SDimitry Andric LLDB_LOGF(log,
1117ead24645SDimitry Andric "ObjectFileELF::%s detected FreeBSD %" PRIu32 ".%" PRIu32
111814f1b3e8SDimitry Andric ".%" PRIu32,
111914f1b3e8SDimitry Andric __FUNCTION__, version_major, version_minor,
112014f1b3e8SDimitry Andric static_cast<uint32_t>(version_info % 1000));
11210cac4ca3SEd Maste }
11220cac4ca3SEd Maste // Process GNU ELF notes.
112314f1b3e8SDimitry Andric else if (note.n_name == LLDB_NT_OWNER_GNU) {
112414f1b3e8SDimitry Andric switch (note.n_type) {
11250cac4ca3SEd Maste case LLDB_NT_GNU_ABI_TAG:
112614f1b3e8SDimitry Andric if (note.n_descsz == LLDB_NT_GNU_ABI_SIZE) {
11270cac4ca3SEd Maste // Pull out the min OS version supporting the ABI.
11280cac4ca3SEd Maste uint32_t version_info[4];
112914f1b3e8SDimitry Andric if (data.GetU32(&offset, &version_info[0], note.n_descsz / 4) ==
113014f1b3e8SDimitry Andric nullptr) {
11310cac4ca3SEd Maste error.SetErrorString("failed to read GNU ABI note payload");
11320cac4ca3SEd Maste return error;
11330cac4ca3SEd Maste }
11340cac4ca3SEd Maste
11350cac4ca3SEd Maste // Set the OS per the OS field.
113614f1b3e8SDimitry Andric switch (version_info[0]) {
11370cac4ca3SEd Maste case LLDB_NT_GNU_ABI_OS_LINUX:
11380cac4ca3SEd Maste arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
113914f1b3e8SDimitry Andric arch_spec.GetTriple().setVendor(
114014f1b3e8SDimitry Andric llvm::Triple::VendorType::UnknownVendor);
1141ead24645SDimitry Andric LLDB_LOGF(log,
114214f1b3e8SDimitry Andric "ObjectFileELF::%s detected Linux, min version %" PRIu32
114314f1b3e8SDimitry Andric ".%" PRIu32 ".%" PRIu32,
114414f1b3e8SDimitry Andric __FUNCTION__, version_info[1], version_info[2],
114514f1b3e8SDimitry Andric version_info[3]);
114614f1b3e8SDimitry Andric // FIXME we have the minimal version number, we could be propagating
114714f1b3e8SDimitry Andric // that. version_info[1] = OS Major, version_info[2] = OS Minor,
114814f1b3e8SDimitry Andric // version_info[3] = Revision.
11490cac4ca3SEd Maste break;
11500cac4ca3SEd Maste case LLDB_NT_GNU_ABI_OS_HURD:
11510cac4ca3SEd Maste arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS);
115214f1b3e8SDimitry Andric arch_spec.GetTriple().setVendor(
115314f1b3e8SDimitry Andric llvm::Triple::VendorType::UnknownVendor);
1154ead24645SDimitry Andric LLDB_LOGF(log,
1155ead24645SDimitry Andric "ObjectFileELF::%s detected Hurd (unsupported), min "
115614f1b3e8SDimitry Andric "version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
115714f1b3e8SDimitry Andric __FUNCTION__, version_info[1], version_info[2],
115814f1b3e8SDimitry Andric version_info[3]);
11590cac4ca3SEd Maste break;
11600cac4ca3SEd Maste case LLDB_NT_GNU_ABI_OS_SOLARIS:
11610cac4ca3SEd Maste arch_spec.GetTriple().setOS(llvm::Triple::OSType::Solaris);
116214f1b3e8SDimitry Andric arch_spec.GetTriple().setVendor(
116314f1b3e8SDimitry Andric llvm::Triple::VendorType::UnknownVendor);
1164ead24645SDimitry Andric LLDB_LOGF(log,
116514f1b3e8SDimitry Andric "ObjectFileELF::%s detected Solaris, min version %" PRIu32
116614f1b3e8SDimitry Andric ".%" PRIu32 ".%" PRIu32,
116714f1b3e8SDimitry Andric __FUNCTION__, version_info[1], version_info[2],
116814f1b3e8SDimitry Andric version_info[3]);
11690cac4ca3SEd Maste break;
11700cac4ca3SEd Maste default:
1171ead24645SDimitry Andric LLDB_LOGF(log,
117214f1b3e8SDimitry Andric "ObjectFileELF::%s unrecognized OS in note, id %" PRIu32
117314f1b3e8SDimitry Andric ", min version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
117414f1b3e8SDimitry Andric __FUNCTION__, version_info[0], version_info[1],
117514f1b3e8SDimitry Andric version_info[2], version_info[3]);
11760cac4ca3SEd Maste break;
11770cac4ca3SEd Maste }
11780cac4ca3SEd Maste }
11790cac4ca3SEd Maste break;
11800cac4ca3SEd Maste
11810cac4ca3SEd Maste case LLDB_NT_GNU_BUILD_ID_TAG:
11820cac4ca3SEd Maste // Only bother processing this if we don't already have the uuid set.
118314f1b3e8SDimitry Andric if (!uuid.IsValid()) {
118414f1b3e8SDimitry Andric // 16 bytes is UUID|MD5, 20 bytes is SHA1. Other linkers may produce a
1185f73363f1SDimitry Andric // build-id of a different length. Accept it as long as it's at least
1186f73363f1SDimitry Andric // 4 bytes as it will be better than our own crc32.
1187f73363f1SDimitry Andric if (note.n_descsz >= 4) {
1188f73363f1SDimitry Andric if (const uint8_t *buf = data.PeekData(offset, note.n_descsz)) {
1189f73363f1SDimitry Andric // Save the build id as the UUID for the module.
1190e3b55780SDimitry Andric uuid = UUID(buf, note.n_descsz);
1191f73363f1SDimitry Andric } else {
11920cac4ca3SEd Maste error.SetErrorString("failed to read GNU_BUILD_ID note payload");
11930cac4ca3SEd Maste return error;
1194f034231aSEd Maste }
11950cac4ca3SEd Maste }
11960cac4ca3SEd Maste }
11970cac4ca3SEd Maste break;
11980cac4ca3SEd Maste }
119974a628f7SDimitry Andric if (arch_spec.IsMIPS() &&
120074a628f7SDimitry Andric arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS)
120174a628f7SDimitry Andric // The note.n_name == LLDB_NT_OWNER_GNU is valid for Linux platform
120274a628f7SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
12030cac4ca3SEd Maste }
12045f29bb8aSDimitry Andric // Process NetBSD ELF executables and shared libraries
12050cac4ca3SEd Maste else if ((note.n_name == LLDB_NT_OWNER_NETBSD) &&
12065f29bb8aSDimitry Andric (note.n_type == LLDB_NT_NETBSD_IDENT_TAG) &&
12075f29bb8aSDimitry Andric (note.n_descsz == LLDB_NT_NETBSD_IDENT_DESCSZ) &&
12085f29bb8aSDimitry Andric (note.n_namesz == LLDB_NT_NETBSD_IDENT_NAMESZ)) {
12095f29bb8aSDimitry Andric // Pull out the version info.
12100cac4ca3SEd Maste uint32_t version_info;
121114f1b3e8SDimitry Andric if (data.GetU32(&offset, &version_info, 1) == nullptr) {
12120cac4ca3SEd Maste error.SetErrorString("failed to read NetBSD ABI note payload");
12130cac4ca3SEd Maste return error;
12140cac4ca3SEd Maste }
12155f29bb8aSDimitry Andric // Convert the version info into a major/minor/patch number.
12165f29bb8aSDimitry Andric // #define __NetBSD_Version__ MMmmrrpp00
12175f29bb8aSDimitry Andric //
12185f29bb8aSDimitry Andric // M = major version
12195f29bb8aSDimitry Andric // m = minor version; a minor number of 99 indicates current.
12205f29bb8aSDimitry Andric // r = 0 (since NetBSD 3.0 not used)
12215f29bb8aSDimitry Andric // p = patchlevel
12225f29bb8aSDimitry Andric const uint32_t version_major = version_info / 100000000;
12235f29bb8aSDimitry Andric const uint32_t version_minor = (version_info % 100000000) / 1000000;
12245f29bb8aSDimitry Andric const uint32_t version_patch = (version_info % 10000) / 100;
12255f29bb8aSDimitry Andric // Set the elf OS version to NetBSD. Also clear the vendor.
12265f29bb8aSDimitry Andric arch_spec.GetTriple().setOSName(
12275f29bb8aSDimitry Andric llvm::formatv("netbsd{0}.{1}.{2}", version_major, version_minor,
12285f29bb8aSDimitry Andric version_patch).str());
12295f29bb8aSDimitry Andric arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
12305f29bb8aSDimitry Andric }
12315f29bb8aSDimitry Andric // Process NetBSD ELF core(5) notes
12325f29bb8aSDimitry Andric else if ((note.n_name == LLDB_NT_OWNER_NETBSDCORE) &&
12335f29bb8aSDimitry Andric (note.n_type == LLDB_NT_NETBSD_PROCINFO)) {
12340cac4ca3SEd Maste // Set the elf OS version to NetBSD. Also clear the vendor.
12350cac4ca3SEd Maste arch_spec.GetTriple().setOS(llvm::Triple::OSType::NetBSD);
12360cac4ca3SEd Maste arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
12370cac4ca3SEd Maste }
123874a628f7SDimitry Andric // Process OpenBSD ELF notes.
123974a628f7SDimitry Andric else if (note.n_name == LLDB_NT_OWNER_OPENBSD) {
124074a628f7SDimitry Andric // Set the elf OS version to OpenBSD. Also clear the vendor.
124174a628f7SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::OpenBSD);
124274a628f7SDimitry Andric arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
124314f1b3e8SDimitry Andric } else if (note.n_name == LLDB_NT_OWNER_ANDROID) {
12445e95aa85SEd Maste arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
124514f1b3e8SDimitry Andric arch_spec.GetTriple().setEnvironment(
124614f1b3e8SDimitry Andric llvm::Triple::EnvironmentType::Android);
124714f1b3e8SDimitry Andric } else if (note.n_name == LLDB_NT_OWNER_LINUX) {
124814f1b3e8SDimitry Andric // This is sometimes found in core files and usually contains extended
124914f1b3e8SDimitry Andric // register info
1250e81d9d49SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
125114f1b3e8SDimitry Andric } else if (note.n_name == LLDB_NT_OWNER_CORE) {
1252145449b1SDimitry Andric // Parse the NT_FILE to look for stuff in paths to shared libraries
1253145449b1SDimitry Andric // The contents look like this in a 64 bit ELF core file:
1254145449b1SDimitry Andric //
1255145449b1SDimitry Andric // count = 0x000000000000000a (10)
1256145449b1SDimitry Andric // page_size = 0x0000000000001000 (4096)
1257145449b1SDimitry Andric // Index start end file_ofs path
1258145449b1SDimitry Andric // ===== ------------------ ------------------ ------------------ -------------------------------------
1259145449b1SDimitry Andric // [ 0] 0x0000000000401000 0x0000000000000000 /tmp/a.out
1260145449b1SDimitry Andric // [ 1] 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out
1261145449b1SDimitry Andric // [ 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out
1262145449b1SDimitry Andric // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000 /lib/x86_64-linux-gnu/libc-2.19.so
1263145449b1SDimitry Andric // [ 4] 0x00007fa79cba8000 0x00007fa79cda7000 0x00000000000001bb /lib/x86_64-linux-gnu/libc-2.19.so
1264145449b1SDimitry Andric // [ 5] 0x00007fa79cda7000 0x00007fa79cdab000 0x00000000000001ba /lib/x86_64-linux-gnu/libc-2.19.so
1265145449b1SDimitry Andric // [ 6] 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be /lib/x86_64-linux-gnu/libc-2.19.so
1266145449b1SDimitry Andric // [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so
1267145449b1SDimitry Andric // [ 8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 /lib/x86_64-linux-gnu/ld-2.19.so
1268145449b1SDimitry Andric // [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so
1269145449b1SDimitry Andric //
1270145449b1SDimitry Andric // In the 32 bit ELFs the count, page_size, start, end, file_ofs are
1271145449b1SDimitry Andric // uint32_t.
1272145449b1SDimitry Andric //
1273145449b1SDimitry Andric // For reference: see readelf source code (in binutils).
127414f1b3e8SDimitry Andric if (note.n_type == NT_FILE) {
127514f1b3e8SDimitry Andric uint64_t count = data.GetAddress(&offset);
127614f1b3e8SDimitry Andric const char *cstr;
127714f1b3e8SDimitry Andric data.GetAddress(&offset); // Skip page size
127814f1b3e8SDimitry Andric offset += count * 3 *
127914f1b3e8SDimitry Andric data.GetAddressByteSize(); // Skip all start/end/file_ofs
128014f1b3e8SDimitry Andric for (size_t i = 0; i < count; ++i) {
128114f1b3e8SDimitry Andric cstr = data.GetCStr(&offset);
128214f1b3e8SDimitry Andric if (cstr == nullptr) {
128314f1b3e8SDimitry Andric error.SetErrorStringWithFormat("ObjectFileELF::%s trying to read "
128414f1b3e8SDimitry Andric "at an offset after the end "
128514f1b3e8SDimitry Andric "(GetCStr returned nullptr)",
128614f1b3e8SDimitry Andric __FUNCTION__);
128714f1b3e8SDimitry Andric return error;
128814f1b3e8SDimitry Andric }
128914f1b3e8SDimitry Andric llvm::StringRef path(cstr);
129014f1b3e8SDimitry Andric if (path.contains("/lib/x86_64-linux-gnu") || path.contains("/lib/i386-linux-gnu")) {
1291e81d9d49SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
1292e81d9d49SDimitry Andric break;
1293e81d9d49SDimitry Andric }
1294e81d9d49SDimitry Andric }
129574a628f7SDimitry Andric if (arch_spec.IsMIPS() &&
129674a628f7SDimitry Andric arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS)
1297f73363f1SDimitry Andric // In case of MIPSR6, the LLDB_NT_OWNER_GNU note is missing for some
1298f73363f1SDimitry Andric // cases (e.g. compile with -nostdlib) Hence set OS to Linux
129974a628f7SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
1300e81d9d49SDimitry Andric }
1301e81d9d49SDimitry Andric }
13020cac4ca3SEd Maste
1303f73363f1SDimitry Andric // Calculate the offset of the next note just in case "offset" has been
1304f73363f1SDimitry Andric // used to poke at the contents of the note data
1305e81d9d49SDimitry Andric offset = note_offset + note.GetByteSize();
1306f034231aSEd Maste }
13070cac4ca3SEd Maste
13080cac4ca3SEd Maste return error;
1309f034231aSEd Maste }
1310f034231aSEd Maste
ParseARMAttributes(DataExtractor & data,uint64_t length,ArchSpec & arch_spec)131114f1b3e8SDimitry Andric void ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length,
131214f1b3e8SDimitry Andric ArchSpec &arch_spec) {
1313f3fbd1c0SDimitry Andric lldb::offset_t Offset = 0;
1314f3fbd1c0SDimitry Andric
1315f3fbd1c0SDimitry Andric uint8_t FormatVersion = data.GetU8(&Offset);
1316cfca06d7SDimitry Andric if (FormatVersion != llvm::ELFAttrs::Format_Version)
1317f3fbd1c0SDimitry Andric return;
1318f3fbd1c0SDimitry Andric
1319f3fbd1c0SDimitry Andric Offset = Offset + sizeof(uint32_t); // Section Length
1320f3fbd1c0SDimitry Andric llvm::StringRef VendorName = data.GetCStr(&Offset);
1321f3fbd1c0SDimitry Andric
1322f3fbd1c0SDimitry Andric if (VendorName != "aeabi")
1323f3fbd1c0SDimitry Andric return;
1324f3fbd1c0SDimitry Andric
132514f1b3e8SDimitry Andric if (arch_spec.GetTriple().getEnvironment() ==
132614f1b3e8SDimitry Andric llvm::Triple::UnknownEnvironment)
1327f3fbd1c0SDimitry Andric arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI);
1328f3fbd1c0SDimitry Andric
132914f1b3e8SDimitry Andric while (Offset < length) {
1330f3fbd1c0SDimitry Andric uint8_t Tag = data.GetU8(&Offset);
1331f3fbd1c0SDimitry Andric uint32_t Size = data.GetU32(&Offset);
1332f3fbd1c0SDimitry Andric
1333f3fbd1c0SDimitry Andric if (Tag != llvm::ARMBuildAttrs::File || Size == 0)
1334f3fbd1c0SDimitry Andric continue;
1335f3fbd1c0SDimitry Andric
133614f1b3e8SDimitry Andric while (Offset < length) {
1337f3fbd1c0SDimitry Andric uint64_t Tag = data.GetULEB128(&Offset);
133814f1b3e8SDimitry Andric switch (Tag) {
1339f3fbd1c0SDimitry Andric default:
1340f3fbd1c0SDimitry Andric if (Tag < 32)
1341f3fbd1c0SDimitry Andric data.GetULEB128(&Offset);
1342f3fbd1c0SDimitry Andric else if (Tag % 2 == 0)
1343f3fbd1c0SDimitry Andric data.GetULEB128(&Offset);
1344f3fbd1c0SDimitry Andric else
1345f3fbd1c0SDimitry Andric data.GetCStr(&Offset);
1346f3fbd1c0SDimitry Andric
1347f3fbd1c0SDimitry Andric break;
1348f3fbd1c0SDimitry Andric
1349f3fbd1c0SDimitry Andric case llvm::ARMBuildAttrs::CPU_raw_name:
1350f3fbd1c0SDimitry Andric case llvm::ARMBuildAttrs::CPU_name:
1351f3fbd1c0SDimitry Andric data.GetCStr(&Offset);
1352f3fbd1c0SDimitry Andric
1353f3fbd1c0SDimitry Andric break;
1354f3fbd1c0SDimitry Andric
135514f1b3e8SDimitry Andric case llvm::ARMBuildAttrs::ABI_VFP_args: {
1356f3fbd1c0SDimitry Andric uint64_t VFPArgs = data.GetULEB128(&Offset);
1357f3fbd1c0SDimitry Andric
135814f1b3e8SDimitry Andric if (VFPArgs == llvm::ARMBuildAttrs::BaseAAPCS) {
135914f1b3e8SDimitry Andric if (arch_spec.GetTriple().getEnvironment() ==
136014f1b3e8SDimitry Andric llvm::Triple::UnknownEnvironment ||
1361f3fbd1c0SDimitry Andric arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABIHF)
1362f3fbd1c0SDimitry Andric arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI);
1363f3fbd1c0SDimitry Andric
1364f3fbd1c0SDimitry Andric arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float);
136514f1b3e8SDimitry Andric } else if (VFPArgs == llvm::ARMBuildAttrs::HardFPAAPCS) {
136614f1b3e8SDimitry Andric if (arch_spec.GetTriple().getEnvironment() ==
136714f1b3e8SDimitry Andric llvm::Triple::UnknownEnvironment ||
1368f3fbd1c0SDimitry Andric arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABI)
1369f3fbd1c0SDimitry Andric arch_spec.GetTriple().setEnvironment(llvm::Triple::EABIHF);
1370f3fbd1c0SDimitry Andric
1371f3fbd1c0SDimitry Andric arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float);
1372f3fbd1c0SDimitry Andric }
1373f3fbd1c0SDimitry Andric
1374f3fbd1c0SDimitry Andric break;
1375f3fbd1c0SDimitry Andric }
1376f3fbd1c0SDimitry Andric }
1377f3fbd1c0SDimitry Andric }
1378f3fbd1c0SDimitry Andric }
1379f3fbd1c0SDimitry Andric }
13800cac4ca3SEd Maste
1381f034231aSEd Maste // 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)138214f1b3e8SDimitry Andric size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,
1383fdea456aSDimitry Andric DataExtractor &object_data,
1384f034231aSEd Maste const elf::ELFHeader &header,
1385f034231aSEd Maste lldb_private::UUID &uuid,
1386f034231aSEd Maste std::string &gnu_debuglink_file,
13870cac4ca3SEd Maste uint32_t &gnu_debuglink_crc,
138814f1b3e8SDimitry Andric ArchSpec &arch_spec) {
13890cac4ca3SEd Maste // Don't reparse the section headers if we already did that.
1390f034231aSEd Maste if (!section_headers.empty())
1391f034231aSEd Maste return section_headers.size();
1392f034231aSEd Maste
13930cac4ca3SEd Maste // Only initialize the arch_spec to okay defaults if they're not already set.
13940cac4ca3SEd Maste // We'll refine this with note data as we parse the notes.
139514f1b3e8SDimitry Andric if (arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) {
13965e95aa85SEd Maste llvm::Triple::OSType ostype;
13975e95aa85SEd Maste llvm::Triple::OSType spec_ostype;
13980cac4ca3SEd Maste const uint32_t sub_type = subTypeFromElfHeader(header);
139914f1b3e8SDimitry Andric arch_spec.SetArchitecture(eArchTypeELF, header.e_machine, sub_type,
140014f1b3e8SDimitry Andric header.e_ident[EI_OSABI]);
140114f1b3e8SDimitry Andric
1402f73363f1SDimitry Andric // Validate if it is ok to remove GetOsFromOSABI. Note, that now the OS is
1403f73363f1SDimitry Andric // determined based on EI_OSABI flag and the info extracted from ELF notes
1404f73363f1SDimitry Andric // (see RefineModuleDetailsFromNote). However in some cases that still
1405f73363f1SDimitry Andric // might be not enough: for example a shared library might not have any
1406f73363f1SDimitry Andric // notes at all and have EI_OSABI flag set to System V, as result the OS
1407f73363f1SDimitry Andric // will be set to UnknownOS.
14085e95aa85SEd Maste GetOsFromOSABI(header.e_ident[EI_OSABI], ostype);
14095e95aa85SEd Maste spec_ostype = arch_spec.GetTriple().getOS();
14105e95aa85SEd Maste assert(spec_ostype == ostype);
141174a628f7SDimitry Andric UNUSED_IF_ASSERT_DISABLED(spec_ostype);
14120cac4ca3SEd Maste }
14130cac4ca3SEd Maste
141414f1b3e8SDimitry Andric if (arch_spec.GetMachine() == llvm::Triple::mips ||
141514f1b3e8SDimitry Andric arch_spec.GetMachine() == llvm::Triple::mipsel ||
141614f1b3e8SDimitry Andric arch_spec.GetMachine() == llvm::Triple::mips64 ||
141714f1b3e8SDimitry Andric arch_spec.GetMachine() == llvm::Triple::mips64el) {
141814f1b3e8SDimitry Andric switch (header.e_flags & llvm::ELF::EF_MIPS_ARCH_ASE) {
141985d8ef8fSDimitry Andric case llvm::ELF::EF_MIPS_MICROMIPS:
142085d8ef8fSDimitry Andric arch_spec.SetFlags(ArchSpec::eMIPSAse_micromips);
142185d8ef8fSDimitry Andric break;
142285d8ef8fSDimitry Andric case llvm::ELF::EF_MIPS_ARCH_ASE_M16:
142385d8ef8fSDimitry Andric arch_spec.SetFlags(ArchSpec::eMIPSAse_mips16);
142485d8ef8fSDimitry Andric break;
142585d8ef8fSDimitry Andric case llvm::ELF::EF_MIPS_ARCH_ASE_MDMX:
142685d8ef8fSDimitry Andric arch_spec.SetFlags(ArchSpec::eMIPSAse_mdmx);
142785d8ef8fSDimitry Andric break;
142885d8ef8fSDimitry Andric default:
142985d8ef8fSDimitry Andric break;
143085d8ef8fSDimitry Andric }
143185d8ef8fSDimitry Andric }
143285d8ef8fSDimitry Andric
1433f3fbd1c0SDimitry Andric if (arch_spec.GetMachine() == llvm::Triple::arm ||
143414f1b3e8SDimitry Andric arch_spec.GetMachine() == llvm::Triple::thumb) {
1435f3fbd1c0SDimitry Andric if (header.e_flags & llvm::ELF::EF_ARM_SOFT_FLOAT)
1436f3fbd1c0SDimitry Andric arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float);
1437f3fbd1c0SDimitry Andric else if (header.e_flags & llvm::ELF::EF_ARM_VFP_FLOAT)
1438f3fbd1c0SDimitry Andric arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float);
1439f3fbd1c0SDimitry Andric }
1440f3fbd1c0SDimitry Andric
1441145449b1SDimitry Andric if (arch_spec.GetMachine() == llvm::Triple::riscv32 ||
1442145449b1SDimitry Andric arch_spec.GetMachine() == llvm::Triple::riscv64) {
1443145449b1SDimitry Andric uint32_t flags = arch_spec.GetFlags();
1444145449b1SDimitry Andric
1445145449b1SDimitry Andric if (header.e_flags & llvm::ELF::EF_RISCV_RVC)
1446145449b1SDimitry Andric flags |= ArchSpec::eRISCV_rvc;
1447145449b1SDimitry Andric if (header.e_flags & llvm::ELF::EF_RISCV_RVE)
1448145449b1SDimitry Andric flags |= ArchSpec::eRISCV_rve;
1449145449b1SDimitry Andric
1450145449b1SDimitry Andric if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE) ==
1451145449b1SDimitry Andric llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE)
1452145449b1SDimitry Andric flags |= ArchSpec::eRISCV_float_abi_single;
1453145449b1SDimitry Andric else if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE) ==
1454145449b1SDimitry Andric llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE)
1455145449b1SDimitry Andric flags |= ArchSpec::eRISCV_float_abi_double;
1456145449b1SDimitry Andric else if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD) ==
1457145449b1SDimitry Andric llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD)
1458145449b1SDimitry Andric flags |= ArchSpec::eRISCV_float_abi_quad;
1459145449b1SDimitry Andric
1460145449b1SDimitry Andric arch_spec.SetFlags(flags);
1461145449b1SDimitry Andric }
1462145449b1SDimitry Andric
1463f034231aSEd Maste // If there are no section headers we are done.
1464f034231aSEd Maste if (header.e_shnum == 0)
1465f034231aSEd Maste return 0;
1466f034231aSEd Maste
1467145449b1SDimitry Andric Log *log = GetLog(LLDBLog::Modules);
14680cac4ca3SEd Maste
1469f034231aSEd Maste section_headers.resize(header.e_shnum);
1470f034231aSEd Maste if (section_headers.size() != header.e_shnum)
1471f034231aSEd Maste return 0;
1472f034231aSEd Maste
1473f034231aSEd Maste const size_t sh_size = header.e_shnum * header.e_shentsize;
1474f034231aSEd Maste const elf_off sh_offset = header.e_shoff;
1475f034231aSEd Maste DataExtractor sh_data;
1476fdea456aSDimitry Andric if (sh_data.SetData(object_data, sh_offset, sh_size) != sh_size)
1477f034231aSEd Maste return 0;
1478f034231aSEd Maste
1479f034231aSEd Maste uint32_t idx;
1480f034231aSEd Maste lldb::offset_t offset;
148114f1b3e8SDimitry Andric for (idx = 0, offset = 0; idx < header.e_shnum; ++idx) {
148294994d37SDimitry Andric if (!section_headers[idx].Parse(sh_data, &offset))
1483f034231aSEd Maste break;
1484f034231aSEd Maste }
1485f034231aSEd Maste if (idx < section_headers.size())
1486f034231aSEd Maste section_headers.resize(idx);
1487f034231aSEd Maste
1488f034231aSEd Maste const unsigned strtab_idx = header.e_shstrndx;
148914f1b3e8SDimitry Andric if (strtab_idx && strtab_idx < section_headers.size()) {
1490f034231aSEd Maste const ELFSectionHeaderInfo &sheader = section_headers[strtab_idx];
1491f034231aSEd Maste const size_t byte_size = sheader.sh_size;
1492f034231aSEd Maste const Elf64_Off offset = sheader.sh_offset;
1493f034231aSEd Maste lldb_private::DataExtractor shstr_data;
1494f034231aSEd Maste
1495fdea456aSDimitry Andric if (shstr_data.SetData(object_data, offset, byte_size) == byte_size) {
1496f034231aSEd Maste for (SectionHeaderCollIter I = section_headers.begin();
149714f1b3e8SDimitry Andric I != section_headers.end(); ++I) {
1498f034231aSEd Maste static ConstString g_sect_name_gnu_debuglink(".gnu_debuglink");
1499e81d9d49SDimitry Andric const ELFSectionHeaderInfo &sheader = *I;
150014f1b3e8SDimitry Andric const uint64_t section_size =
150114f1b3e8SDimitry Andric sheader.sh_type == SHT_NOBITS ? 0 : sheader.sh_size;
1502f034231aSEd Maste ConstString name(shstr_data.PeekCStr(I->sh_name));
1503f034231aSEd Maste
1504f034231aSEd Maste I->section_name = name;
1505f034231aSEd Maste
150614f1b3e8SDimitry Andric if (arch_spec.IsMIPS()) {
1507e81d9d49SDimitry Andric uint32_t arch_flags = arch_spec.GetFlags();
150885d8ef8fSDimitry Andric DataExtractor data;
150914f1b3e8SDimitry Andric if (sheader.sh_type == SHT_MIPS_ABIFLAGS) {
1510e81d9d49SDimitry Andric
1511fdea456aSDimitry Andric if (section_size && (data.SetData(object_data, sheader.sh_offset,
151214f1b3e8SDimitry Andric section_size) == section_size)) {
1513f3fbd1c0SDimitry Andric // MIPS ASE Mask is at offset 12 in MIPS.abiflags section
1514f3fbd1c0SDimitry Andric lldb::offset_t offset = 12; // MIPS ABI Flags Version: 0
1515f3fbd1c0SDimitry Andric arch_flags |= data.GetU32(&offset);
1516f3fbd1c0SDimitry Andric
1517f3fbd1c0SDimitry Andric // The floating point ABI is at offset 7
1518f3fbd1c0SDimitry Andric offset = 7;
151914f1b3e8SDimitry Andric switch (data.GetU8(&offset)) {
1520f3fbd1c0SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_ANY:
1521f3fbd1c0SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_ANY;
1522f3fbd1c0SDimitry Andric break;
1523f3fbd1c0SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_DOUBLE:
1524f3fbd1c0SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_DOUBLE;
1525f3fbd1c0SDimitry Andric break;
1526f3fbd1c0SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_SINGLE:
1527f3fbd1c0SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SINGLE;
1528f3fbd1c0SDimitry Andric break;
1529f3fbd1c0SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_SOFT:
1530f3fbd1c0SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT;
1531f3fbd1c0SDimitry Andric break;
1532f3fbd1c0SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_OLD_64:
1533f3fbd1c0SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_OLD_64;
1534f3fbd1c0SDimitry Andric break;
1535f3fbd1c0SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_XX:
1536f3fbd1c0SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_XX;
1537f3fbd1c0SDimitry Andric break;
1538f3fbd1c0SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_64:
1539f3fbd1c0SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64;
1540f3fbd1c0SDimitry Andric break;
1541f3fbd1c0SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_64A:
1542f3fbd1c0SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64A;
1543f3fbd1c0SDimitry Andric break;
1544f3fbd1c0SDimitry Andric }
1545e81d9d49SDimitry Andric }
1546e81d9d49SDimitry Andric }
1547e81d9d49SDimitry Andric // Settings appropriate ArchSpec ABI Flags
154814f1b3e8SDimitry Andric switch (header.e_flags & llvm::ELF::EF_MIPS_ABI) {
1549f3fbd1c0SDimitry Andric case llvm::ELF::EF_MIPS_ABI_O32:
1550e81d9d49SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_O32;
1551f3fbd1c0SDimitry Andric break;
1552f3fbd1c0SDimitry Andric case EF_MIPS_ABI_O64:
1553f3fbd1c0SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_O64;
1554f3fbd1c0SDimitry Andric break;
1555f3fbd1c0SDimitry Andric case EF_MIPS_ABI_EABI32:
1556f3fbd1c0SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI32;
1557f3fbd1c0SDimitry Andric break;
1558f3fbd1c0SDimitry Andric case EF_MIPS_ABI_EABI64:
1559f3fbd1c0SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI64;
1560f3fbd1c0SDimitry Andric break;
1561f3fbd1c0SDimitry Andric default:
1562f3fbd1c0SDimitry Andric // ABI Mask doesn't cover N32 and N64 ABI.
1563f3fbd1c0SDimitry Andric if (header.e_ident[EI_CLASS] == llvm::ELF::ELFCLASS64)
1564f3fbd1c0SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_N64;
1565fdea456aSDimitry Andric else if (header.e_flags & llvm::ELF::EF_MIPS_ABI2)
1566f3fbd1c0SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_N32;
1567f3fbd1c0SDimitry Andric break;
1568e81d9d49SDimitry Andric }
156985d8ef8fSDimitry Andric arch_spec.SetFlags(arch_flags);
157085d8ef8fSDimitry Andric }
157185d8ef8fSDimitry Andric
157214f1b3e8SDimitry Andric if (arch_spec.GetMachine() == llvm::Triple::arm ||
157314f1b3e8SDimitry Andric arch_spec.GetMachine() == llvm::Triple::thumb) {
1574f3fbd1c0SDimitry Andric DataExtractor data;
1575f3fbd1c0SDimitry Andric
1576f3fbd1c0SDimitry Andric if (sheader.sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 &&
1577fdea456aSDimitry Andric data.SetData(object_data, sheader.sh_offset, section_size) == section_size)
1578f3fbd1c0SDimitry Andric ParseARMAttributes(data, section_size, arch_spec);
1579f3fbd1c0SDimitry Andric }
1580f3fbd1c0SDimitry Andric
158114f1b3e8SDimitry Andric if (name == g_sect_name_gnu_debuglink) {
1582f034231aSEd Maste DataExtractor data;
1583fdea456aSDimitry Andric if (section_size && (data.SetData(object_data, sheader.sh_offset,
158414f1b3e8SDimitry Andric section_size) == section_size)) {
1585f034231aSEd Maste lldb::offset_t gnu_debuglink_offset = 0;
1586f034231aSEd Maste gnu_debuglink_file = data.GetCStr(&gnu_debuglink_offset);
1587f3fbd1c0SDimitry Andric gnu_debuglink_offset = llvm::alignTo(gnu_debuglink_offset, 4);
1588f034231aSEd Maste data.GetU32(&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
1589f034231aSEd Maste }
1590f034231aSEd Maste }
1591f034231aSEd Maste
15920cac4ca3SEd Maste // Process ELF note section entries.
1593e81d9d49SDimitry Andric bool is_note_header = (sheader.sh_type == SHT_NOTE);
15945e95aa85SEd Maste
15955e95aa85SEd Maste // The section header ".note.android.ident" is stored as a
15965e95aa85SEd Maste // PROGBITS type header but it is actually a note header.
15975e95aa85SEd Maste static ConstString g_sect_name_android_ident(".note.android.ident");
15985e95aa85SEd Maste if (!is_note_header && name == g_sect_name_android_ident)
15995e95aa85SEd Maste is_note_header = true;
16005e95aa85SEd Maste
160114f1b3e8SDimitry Andric if (is_note_header) {
16020cac4ca3SEd Maste // Allow notes to refine module info.
1603f034231aSEd Maste DataExtractor data;
1604fdea456aSDimitry Andric if (section_size && (data.SetData(object_data, sheader.sh_offset,
160514f1b3e8SDimitry Andric section_size) == section_size)) {
1606b76161e4SDimitry Andric Status error = RefineModuleDetailsFromNote(data, arch_spec, uuid);
160714f1b3e8SDimitry Andric if (error.Fail()) {
1608ead24645SDimitry Andric LLDB_LOGF(log, "ObjectFileELF::%s ELF note processing failed: %s",
160914f1b3e8SDimitry Andric __FUNCTION__, error.AsCString());
16100cac4ca3SEd Maste }
1611f034231aSEd Maste }
1612f034231aSEd Maste }
1613f034231aSEd Maste }
1614f034231aSEd Maste
1615e81d9d49SDimitry Andric // Make any unknown triple components to be unspecified unknowns.
1616e81d9d49SDimitry Andric if (arch_spec.GetTriple().getVendor() == llvm::Triple::UnknownVendor)
1617e81d9d49SDimitry Andric arch_spec.GetTriple().setVendorName(llvm::StringRef());
1618e81d9d49SDimitry Andric if (arch_spec.GetTriple().getOS() == llvm::Triple::UnknownOS)
1619e81d9d49SDimitry Andric arch_spec.GetTriple().setOSName(llvm::StringRef());
1620e81d9d49SDimitry Andric
1621f034231aSEd Maste return section_headers.size();
1622f034231aSEd Maste }
1623f034231aSEd Maste }
1624f034231aSEd Maste
1625f034231aSEd Maste section_headers.clear();
1626f034231aSEd Maste return 0;
1627f034231aSEd Maste }
1628f034231aSEd Maste
1629773dd0e6SDimitry Andric llvm::StringRef
StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const163014f1b3e8SDimitry Andric ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const {
1631027f1c96SDimitry Andric size_t pos = symbol_name.find('@');
1632773dd0e6SDimitry Andric return symbol_name.substr(0, pos);
16335e95aa85SEd Maste }
16345e95aa85SEd Maste
1635f034231aSEd Maste // ParseSectionHeaders
ParseSectionHeaders()163614f1b3e8SDimitry Andric size_t ObjectFileELF::ParseSectionHeaders() {
1637fdea456aSDimitry Andric return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid,
1638fdea456aSDimitry Andric m_gnu_debuglink_file, m_gnu_debuglink_crc,
1639fdea456aSDimitry Andric m_arch_spec);
1640f034231aSEd Maste }
1641f034231aSEd Maste
1642f034231aSEd Maste const ObjectFileELF::ELFSectionHeaderInfo *
GetSectionHeaderByIndex(lldb::user_id_t id)164314f1b3e8SDimitry Andric ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) {
164494994d37SDimitry Andric if (!ParseSectionHeaders())
16455f29bb8aSDimitry Andric return nullptr;
1646f034231aSEd Maste
164794994d37SDimitry Andric if (id < m_section_headers.size())
1648f034231aSEd Maste return &m_section_headers[id];
1649f034231aSEd Maste
16505f29bb8aSDimitry Andric return nullptr;
1651f034231aSEd Maste }
1652f034231aSEd Maste
GetSectionIndexByName(const char * name)165314f1b3e8SDimitry Andric lldb::user_id_t ObjectFileELF::GetSectionIndexByName(const char *name) {
16545e95aa85SEd Maste if (!name || !name[0] || !ParseSectionHeaders())
16555e95aa85SEd Maste return 0;
16565e95aa85SEd Maste for (size_t i = 1; i < m_section_headers.size(); ++i)
16575e95aa85SEd Maste if (m_section_headers[i].section_name == ConstString(name))
16585e95aa85SEd Maste return i;
16595e95aa85SEd Maste return 0;
16605e95aa85SEd Maste }
16615e95aa85SEd Maste
GetSectionTypeFromName(llvm::StringRef Name)166294994d37SDimitry Andric static SectionType GetSectionTypeFromName(llvm::StringRef Name) {
16634b4fe385SDimitry Andric if (Name.consume_front(".debug_")) {
16645f29bb8aSDimitry Andric return llvm::StringSwitch<SectionType>(Name)
16655f29bb8aSDimitry Andric .Case("abbrev", eSectionTypeDWARFDebugAbbrev)
16665f29bb8aSDimitry Andric .Case("abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo)
16675f29bb8aSDimitry Andric .Case("addr", eSectionTypeDWARFDebugAddr)
16685f29bb8aSDimitry Andric .Case("aranges", eSectionTypeDWARFDebugAranges)
16695f29bb8aSDimitry Andric .Case("cu_index", eSectionTypeDWARFDebugCuIndex)
16705f29bb8aSDimitry Andric .Case("frame", eSectionTypeDWARFDebugFrame)
16715f29bb8aSDimitry Andric .Case("info", eSectionTypeDWARFDebugInfo)
16725f29bb8aSDimitry Andric .Case("info.dwo", eSectionTypeDWARFDebugInfoDwo)
16735f29bb8aSDimitry Andric .Cases("line", "line.dwo", eSectionTypeDWARFDebugLine)
16745f29bb8aSDimitry Andric .Cases("line_str", "line_str.dwo", eSectionTypeDWARFDebugLineStr)
1675706b4fc4SDimitry Andric .Case("loc", eSectionTypeDWARFDebugLoc)
1676706b4fc4SDimitry Andric .Case("loc.dwo", eSectionTypeDWARFDebugLocDwo)
1677706b4fc4SDimitry Andric .Case("loclists", eSectionTypeDWARFDebugLocLists)
1678706b4fc4SDimitry Andric .Case("loclists.dwo", eSectionTypeDWARFDebugLocListsDwo)
16795f29bb8aSDimitry Andric .Case("macinfo", eSectionTypeDWARFDebugMacInfo)
16805f29bb8aSDimitry Andric .Cases("macro", "macro.dwo", eSectionTypeDWARFDebugMacro)
16815f29bb8aSDimitry Andric .Case("names", eSectionTypeDWARFDebugNames)
16825f29bb8aSDimitry Andric .Case("pubnames", eSectionTypeDWARFDebugPubNames)
16835f29bb8aSDimitry Andric .Case("pubtypes", eSectionTypeDWARFDebugPubTypes)
16845f29bb8aSDimitry Andric .Case("ranges", eSectionTypeDWARFDebugRanges)
16855f29bb8aSDimitry Andric .Case("rnglists", eSectionTypeDWARFDebugRngLists)
1686706b4fc4SDimitry Andric .Case("rnglists.dwo", eSectionTypeDWARFDebugRngListsDwo)
16875f29bb8aSDimitry Andric .Case("str", eSectionTypeDWARFDebugStr)
16885f29bb8aSDimitry Andric .Case("str.dwo", eSectionTypeDWARFDebugStrDwo)
16895f29bb8aSDimitry Andric .Case("str_offsets", eSectionTypeDWARFDebugStrOffsets)
16905f29bb8aSDimitry Andric .Case("str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo)
1691cfca06d7SDimitry Andric .Case("tu_index", eSectionTypeDWARFDebugTuIndex)
16925f29bb8aSDimitry Andric .Case("types", eSectionTypeDWARFDebugTypes)
16935f29bb8aSDimitry Andric .Case("types.dwo", eSectionTypeDWARFDebugTypesDwo)
16945f29bb8aSDimitry Andric .Default(eSectionTypeOther);
16955f29bb8aSDimitry Andric }
169694994d37SDimitry Andric return llvm::StringSwitch<SectionType>(Name)
169794994d37SDimitry Andric .Case(".ARM.exidx", eSectionTypeARMexidx)
169894994d37SDimitry Andric .Case(".ARM.extab", eSectionTypeARMextab)
16997fa27ce4SDimitry Andric .Case(".ctf", eSectionTypeDebug)
170094994d37SDimitry Andric .Cases(".data", ".tdata", eSectionTypeData)
170194994d37SDimitry Andric .Case(".eh_frame", eSectionTypeEHFrame)
170294994d37SDimitry Andric .Case(".gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink)
170394994d37SDimitry Andric .Case(".gosymtab", eSectionTypeGoSymtab)
170494994d37SDimitry Andric .Case(".text", eSectionTypeCode)
1705b1c73532SDimitry Andric .Case(".swift_ast", eSectionTypeSwiftModules)
170694994d37SDimitry Andric .Default(eSectionTypeOther);
170794994d37SDimitry Andric }
170894994d37SDimitry Andric
GetSectionType(const ELFSectionHeaderInfo & H) const170994994d37SDimitry Andric SectionType ObjectFileELF::GetSectionType(const ELFSectionHeaderInfo &H) const {
171094994d37SDimitry Andric switch (H.sh_type) {
171194994d37SDimitry Andric case SHT_PROGBITS:
171294994d37SDimitry Andric if (H.sh_flags & SHF_EXECINSTR)
171394994d37SDimitry Andric return eSectionTypeCode;
171494994d37SDimitry Andric break;
1715ac9a064cSDimitry Andric case SHT_NOBITS:
1716ac9a064cSDimitry Andric if (H.sh_flags & SHF_ALLOC)
1717ac9a064cSDimitry Andric return eSectionTypeZeroFill;
1718ac9a064cSDimitry Andric break;
171994994d37SDimitry Andric case SHT_SYMTAB:
172094994d37SDimitry Andric return eSectionTypeELFSymbolTable;
172194994d37SDimitry Andric case SHT_DYNSYM:
172294994d37SDimitry Andric return eSectionTypeELFDynamicSymbols;
172394994d37SDimitry Andric case SHT_RELA:
172494994d37SDimitry Andric case SHT_REL:
172594994d37SDimitry Andric return eSectionTypeELFRelocationEntries;
172694994d37SDimitry Andric case SHT_DYNAMIC:
172794994d37SDimitry Andric return eSectionTypeELFDynamicLinkInfo;
172894994d37SDimitry Andric }
17295f29bb8aSDimitry Andric return GetSectionTypeFromName(H.section_name.GetStringRef());
173094994d37SDimitry Andric }
173194994d37SDimitry Andric
GetTargetByteSize(SectionType Type,const ArchSpec & arch)173294994d37SDimitry Andric static uint32_t GetTargetByteSize(SectionType Type, const ArchSpec &arch) {
173394994d37SDimitry Andric switch (Type) {
173494994d37SDimitry Andric case eSectionTypeData:
173594994d37SDimitry Andric case eSectionTypeZeroFill:
173694994d37SDimitry Andric return arch.GetDataByteSize();
173794994d37SDimitry Andric case eSectionTypeCode:
173894994d37SDimitry Andric return arch.GetCodeByteSize();
173994994d37SDimitry Andric default:
174094994d37SDimitry Andric return 1;
174194994d37SDimitry Andric }
174294994d37SDimitry Andric }
174394994d37SDimitry Andric
GetPermissions(const ELFSectionHeader & H)174494994d37SDimitry Andric static Permissions GetPermissions(const ELFSectionHeader &H) {
174594994d37SDimitry Andric Permissions Perm = Permissions(0);
174694994d37SDimitry Andric if (H.sh_flags & SHF_ALLOC)
174794994d37SDimitry Andric Perm |= ePermissionsReadable;
174894994d37SDimitry Andric if (H.sh_flags & SHF_WRITE)
174994994d37SDimitry Andric Perm |= ePermissionsWritable;
175094994d37SDimitry Andric if (H.sh_flags & SHF_EXECINSTR)
175194994d37SDimitry Andric Perm |= ePermissionsExecutable;
175294994d37SDimitry Andric return Perm;
175394994d37SDimitry Andric }
175494994d37SDimitry Andric
GetPermissions(const ELFProgramHeader & H)175594994d37SDimitry Andric static Permissions GetPermissions(const ELFProgramHeader &H) {
175694994d37SDimitry Andric Permissions Perm = Permissions(0);
175794994d37SDimitry Andric if (H.p_flags & PF_R)
175894994d37SDimitry Andric Perm |= ePermissionsReadable;
175994994d37SDimitry Andric if (H.p_flags & PF_W)
176094994d37SDimitry Andric Perm |= ePermissionsWritable;
176194994d37SDimitry Andric if (H.p_flags & PF_X)
176294994d37SDimitry Andric Perm |= ePermissionsExecutable;
176394994d37SDimitry Andric return Perm;
176494994d37SDimitry Andric }
176594994d37SDimitry Andric
176694994d37SDimitry Andric namespace {
176794994d37SDimitry Andric
176894994d37SDimitry Andric using VMRange = lldb_private::Range<addr_t, addr_t>;
176994994d37SDimitry Andric
177094994d37SDimitry Andric struct SectionAddressInfo {
177194994d37SDimitry Andric SectionSP Segment;
177294994d37SDimitry Andric VMRange Range;
177394994d37SDimitry Andric };
177494994d37SDimitry Andric
177594994d37SDimitry Andric // (Unlinked) ELF object files usually have 0 for every section address, meaning
177694994d37SDimitry Andric // we need to compute synthetic addresses in order for "file addresses" from
177794994d37SDimitry Andric // different sections to not overlap. This class handles that logic.
177894994d37SDimitry Andric class VMAddressProvider {
177994994d37SDimitry Andric using VMMap = llvm::IntervalMap<addr_t, SectionSP, 4,
178094994d37SDimitry Andric llvm::IntervalMapHalfOpenInfo<addr_t>>;
178194994d37SDimitry Andric
178294994d37SDimitry Andric ObjectFile::Type ObjectType;
178394994d37SDimitry Andric addr_t NextVMAddress = 0;
178494994d37SDimitry Andric VMMap::Allocator Alloc;
1785145449b1SDimitry Andric VMMap Segments{Alloc};
1786145449b1SDimitry Andric VMMap Sections{Alloc};
1787145449b1SDimitry Andric lldb_private::Log *Log = GetLog(LLDBLog::Modules);
1788ead24645SDimitry Andric size_t SegmentCount = 0;
1789ead24645SDimitry Andric std::string SegmentName;
179094994d37SDimitry Andric
GetVMRange(const ELFSectionHeader & H)179194994d37SDimitry Andric VMRange GetVMRange(const ELFSectionHeader &H) {
179294994d37SDimitry Andric addr_t Address = H.sh_addr;
179394994d37SDimitry Andric addr_t Size = H.sh_flags & SHF_ALLOC ? H.sh_size : 0;
1794b1c73532SDimitry Andric
1795b1c73532SDimitry Andric // When this is a debug file for relocatable file, the address is all zero
1796b1c73532SDimitry Andric // and thus needs to use accumulate method
1797b1c73532SDimitry Andric if ((ObjectType == ObjectFile::Type::eTypeObjectFile ||
1798b1c73532SDimitry Andric (ObjectType == ObjectFile::Type::eTypeDebugInfo && H.sh_addr == 0)) &&
1799b1c73532SDimitry Andric Segments.empty() && (H.sh_flags & SHF_ALLOC)) {
180094994d37SDimitry Andric NextVMAddress =
180194994d37SDimitry Andric llvm::alignTo(NextVMAddress, std::max<addr_t>(H.sh_addralign, 1));
180294994d37SDimitry Andric Address = NextVMAddress;
180394994d37SDimitry Andric NextVMAddress += Size;
180494994d37SDimitry Andric }
180594994d37SDimitry Andric return VMRange(Address, Size);
180694994d37SDimitry Andric }
180794994d37SDimitry Andric
180894994d37SDimitry Andric public:
VMAddressProvider(ObjectFile::Type Type,llvm::StringRef SegmentName)1809ead24645SDimitry Andric VMAddressProvider(ObjectFile::Type Type, llvm::StringRef SegmentName)
1810cfca06d7SDimitry Andric : ObjectType(Type), SegmentName(std::string(SegmentName)) {}
1811ead24645SDimitry Andric
GetNextSegmentName() const1812ead24645SDimitry Andric std::string GetNextSegmentName() const {
1813ead24645SDimitry Andric return llvm::formatv("{0}[{1}]", SegmentName, SegmentCount).str();
1814ead24645SDimitry Andric }
181594994d37SDimitry Andric
GetAddressInfo(const ELFProgramHeader & H)1816e3b55780SDimitry Andric std::optional<VMRange> GetAddressInfo(const ELFProgramHeader &H) {
181794994d37SDimitry Andric if (H.p_memsz == 0) {
1818ead24645SDimitry Andric LLDB_LOG(Log, "Ignoring zero-sized {0} segment. Corrupt object file?",
1819ead24645SDimitry Andric SegmentName);
1820e3b55780SDimitry Andric return std::nullopt;
182194994d37SDimitry Andric }
182294994d37SDimitry Andric
182394994d37SDimitry Andric if (Segments.overlaps(H.p_vaddr, H.p_vaddr + H.p_memsz)) {
1824ead24645SDimitry Andric LLDB_LOG(Log, "Ignoring overlapping {0} segment. Corrupt object file?",
1825ead24645SDimitry Andric SegmentName);
1826e3b55780SDimitry Andric return std::nullopt;
182794994d37SDimitry Andric }
182894994d37SDimitry Andric return VMRange(H.p_vaddr, H.p_memsz);
182994994d37SDimitry Andric }
183094994d37SDimitry Andric
GetAddressInfo(const ELFSectionHeader & H)1831e3b55780SDimitry Andric std::optional<SectionAddressInfo> GetAddressInfo(const ELFSectionHeader &H) {
183294994d37SDimitry Andric VMRange Range = GetVMRange(H);
183394994d37SDimitry Andric SectionSP Segment;
183494994d37SDimitry Andric auto It = Segments.find(Range.GetRangeBase());
183594994d37SDimitry Andric if ((H.sh_flags & SHF_ALLOC) && It.valid()) {
183694994d37SDimitry Andric addr_t MaxSize;
183794994d37SDimitry Andric if (It.start() <= Range.GetRangeBase()) {
183894994d37SDimitry Andric MaxSize = It.stop() - Range.GetRangeBase();
183994994d37SDimitry Andric Segment = *It;
184094994d37SDimitry Andric } else
184194994d37SDimitry Andric MaxSize = It.start() - Range.GetRangeBase();
184294994d37SDimitry Andric if (Range.GetByteSize() > MaxSize) {
184394994d37SDimitry Andric LLDB_LOG(Log, "Shortening section crossing segment boundaries. "
184494994d37SDimitry Andric "Corrupt object file?");
184594994d37SDimitry Andric Range.SetByteSize(MaxSize);
184694994d37SDimitry Andric }
184794994d37SDimitry Andric }
184894994d37SDimitry Andric if (Range.GetByteSize() > 0 &&
184994994d37SDimitry Andric Sections.overlaps(Range.GetRangeBase(), Range.GetRangeEnd())) {
185094994d37SDimitry Andric LLDB_LOG(Log, "Ignoring overlapping section. Corrupt object file?");
1851e3b55780SDimitry Andric return std::nullopt;
185294994d37SDimitry Andric }
185394994d37SDimitry Andric if (Segment)
185494994d37SDimitry Andric Range.Slide(-Segment->GetFileAddress());
185594994d37SDimitry Andric return SectionAddressInfo{Segment, Range};
185694994d37SDimitry Andric }
185794994d37SDimitry Andric
AddSegment(const VMRange & Range,SectionSP Seg)185894994d37SDimitry Andric void AddSegment(const VMRange &Range, SectionSP Seg) {
185994994d37SDimitry Andric Segments.insert(Range.GetRangeBase(), Range.GetRangeEnd(), std::move(Seg));
1860ead24645SDimitry Andric ++SegmentCount;
186194994d37SDimitry Andric }
186294994d37SDimitry Andric
AddSection(SectionAddressInfo Info,SectionSP Sect)186394994d37SDimitry Andric void AddSection(SectionAddressInfo Info, SectionSP Sect) {
186494994d37SDimitry Andric if (Info.Range.GetByteSize() == 0)
186594994d37SDimitry Andric return;
186694994d37SDimitry Andric if (Info.Segment)
186794994d37SDimitry Andric Info.Range.Slide(Info.Segment->GetFileAddress());
186894994d37SDimitry Andric Sections.insert(Info.Range.GetRangeBase(), Info.Range.GetRangeEnd(),
186994994d37SDimitry Andric std::move(Sect));
187094994d37SDimitry Andric }
187194994d37SDimitry Andric };
187294994d37SDimitry Andric }
187394994d37SDimitry Andric
1874ac9a064cSDimitry Andric // We have to do this because ELF doesn't have section IDs, and also
1875ac9a064cSDimitry Andric // doesn't require section names to be unique. (We use the section index
1876ac9a064cSDimitry Andric // for section IDs, but that isn't guaranteed to be the same in separate
1877ac9a064cSDimitry Andric // debug images.)
FindMatchingSection(const SectionList & section_list,SectionSP section)1878ac9a064cSDimitry Andric static SectionSP FindMatchingSection(const SectionList §ion_list,
1879ac9a064cSDimitry Andric SectionSP section) {
1880ac9a064cSDimitry Andric SectionSP sect_sp;
1881ac9a064cSDimitry Andric
1882ac9a064cSDimitry Andric addr_t vm_addr = section->GetFileAddress();
1883ac9a064cSDimitry Andric ConstString name = section->GetName();
1884ac9a064cSDimitry Andric offset_t byte_size = section->GetByteSize();
1885ac9a064cSDimitry Andric bool thread_specific = section->IsThreadSpecific();
1886ac9a064cSDimitry Andric uint32_t permissions = section->GetPermissions();
1887ac9a064cSDimitry Andric uint32_t alignment = section->GetLog2Align();
1888ac9a064cSDimitry Andric
1889ac9a064cSDimitry Andric for (auto sect : section_list) {
1890ac9a064cSDimitry Andric if (sect->GetName() == name &&
1891ac9a064cSDimitry Andric sect->IsThreadSpecific() == thread_specific &&
1892ac9a064cSDimitry Andric sect->GetPermissions() == permissions &&
1893ac9a064cSDimitry Andric sect->GetByteSize() == byte_size && sect->GetFileAddress() == vm_addr &&
1894ac9a064cSDimitry Andric sect->GetLog2Align() == alignment) {
1895ac9a064cSDimitry Andric sect_sp = sect;
1896ac9a064cSDimitry Andric break;
1897ac9a064cSDimitry Andric } else {
1898ac9a064cSDimitry Andric sect_sp = FindMatchingSection(sect->GetChildren(), section);
1899ac9a064cSDimitry Andric if (sect_sp)
1900ac9a064cSDimitry Andric break;
1901ac9a064cSDimitry Andric }
1902ac9a064cSDimitry Andric }
1903ac9a064cSDimitry Andric
1904ac9a064cSDimitry Andric return sect_sp;
1905ac9a064cSDimitry Andric }
1906ac9a064cSDimitry Andric
CreateSections(SectionList & unified_section_list)190714f1b3e8SDimitry Andric void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
19085f29bb8aSDimitry Andric if (m_sections_up)
190994994d37SDimitry Andric return;
1910f034231aSEd Maste
1911ead24645SDimitry Andric m_sections_up = std::make_unique<SectionList>();
1912ead24645SDimitry Andric VMAddressProvider regular_provider(GetType(), "PT_LOAD");
1913ead24645SDimitry Andric VMAddressProvider tls_provider(GetType(), "PT_TLS");
1914ef5d0b5eSDimitry Andric
191594994d37SDimitry Andric for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) {
191694994d37SDimitry Andric const ELFProgramHeader &PHdr = EnumPHdr.value();
1917ead24645SDimitry Andric if (PHdr.p_type != PT_LOAD && PHdr.p_type != PT_TLS)
191894994d37SDimitry Andric continue;
191994994d37SDimitry Andric
1920ead24645SDimitry Andric VMAddressProvider &provider =
1921ead24645SDimitry Andric PHdr.p_type == PT_TLS ? tls_provider : regular_provider;
1922ead24645SDimitry Andric auto InfoOr = provider.GetAddressInfo(PHdr);
192394994d37SDimitry Andric if (!InfoOr)
192494994d37SDimitry Andric continue;
192594994d37SDimitry Andric
192694994d37SDimitry Andric uint32_t Log2Align = llvm::Log2_64(std::max<elf_xword>(PHdr.p_align, 1));
192794994d37SDimitry Andric SectionSP Segment = std::make_shared<Section>(
1928ead24645SDimitry Andric GetModule(), this, SegmentID(EnumPHdr.index()),
1929ead24645SDimitry Andric ConstString(provider.GetNextSegmentName()), eSectionTypeContainer,
1930ead24645SDimitry Andric InfoOr->GetRangeBase(), InfoOr->GetByteSize(), PHdr.p_offset,
1931ead24645SDimitry Andric PHdr.p_filesz, Log2Align, /*flags*/ 0);
193294994d37SDimitry Andric Segment->SetPermissions(GetPermissions(PHdr));
1933ead24645SDimitry Andric Segment->SetIsThreadSpecific(PHdr.p_type == PT_TLS);
19345f29bb8aSDimitry Andric m_sections_up->AddSection(Segment);
193594994d37SDimitry Andric
1936ead24645SDimitry Andric provider.AddSegment(*InfoOr, std::move(Segment));
193794994d37SDimitry Andric }
193894994d37SDimitry Andric
193994994d37SDimitry Andric ParseSectionHeaders();
194094994d37SDimitry Andric if (m_section_headers.empty())
194194994d37SDimitry Andric return;
194294994d37SDimitry Andric
194394994d37SDimitry Andric for (SectionHeaderCollIter I = std::next(m_section_headers.begin());
194414f1b3e8SDimitry Andric I != m_section_headers.end(); ++I) {
1945f034231aSEd Maste const ELFSectionHeaderInfo &header = *I;
1946f034231aSEd Maste
1947f034231aSEd Maste ConstString &name = I->section_name;
194814f1b3e8SDimitry Andric const uint64_t file_size =
194914f1b3e8SDimitry Andric header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
1950f034231aSEd Maste
1951ead24645SDimitry Andric VMAddressProvider &provider =
1952ead24645SDimitry Andric header.sh_flags & SHF_TLS ? tls_provider : regular_provider;
1953ead24645SDimitry Andric auto InfoOr = provider.GetAddressInfo(header);
195494994d37SDimitry Andric if (!InfoOr)
195594994d37SDimitry Andric continue;
1956f034231aSEd Maste
195794994d37SDimitry Andric SectionType sect_type = GetSectionType(header);
1958f73363f1SDimitry Andric
1959205afe67SEd Maste const uint32_t target_bytes_size =
196094994d37SDimitry Andric GetTargetByteSize(sect_type, m_arch_spec);
196194994d37SDimitry Andric
196214f1b3e8SDimitry Andric elf::elf_xword log2align =
196314f1b3e8SDimitry Andric (header.sh_addralign == 0) ? 0 : llvm::Log2_64(header.sh_addralign);
1964ef5d0b5eSDimitry Andric
196514f1b3e8SDimitry Andric SectionSP section_sp(new Section(
196694994d37SDimitry Andric InfoOr->Segment, GetModule(), // Module to which this section belongs.
196794994d37SDimitry Andric this, // ObjectFile to which this section belongs and should
196894994d37SDimitry Andric // read section data from.
1969f034231aSEd Maste SectionIndex(I), // Section ID.
1970f034231aSEd Maste name, // Section name.
1971f034231aSEd Maste sect_type, // Section type.
197294994d37SDimitry Andric InfoOr->Range.GetRangeBase(), // VM address.
197394994d37SDimitry Andric InfoOr->Range.GetByteSize(), // VM size in bytes of this section.
1974f034231aSEd Maste header.sh_offset, // Offset of this section in the file.
1975f034231aSEd Maste file_size, // Size of the section as found in the file.
19760cac4ca3SEd Maste log2align, // Alignment of the section
1977205afe67SEd Maste header.sh_flags, // Flags for this section.
1978205afe67SEd Maste target_bytes_size)); // Number of host bytes per target byte
1979f034231aSEd Maste
198094994d37SDimitry Andric section_sp->SetPermissions(GetPermissions(header));
198194994d37SDimitry Andric section_sp->SetIsThreadSpecific(header.sh_flags & SHF_TLS);
19825f29bb8aSDimitry Andric (InfoOr->Segment ? InfoOr->Segment->GetChildren() : *m_sections_up)
198394994d37SDimitry Andric .AddSection(section_sp);
1984ead24645SDimitry Andric provider.AddSection(std::move(*InfoOr), std::move(section_sp));
1985f034231aSEd Maste }
1986f034231aSEd Maste
1987f73363f1SDimitry Andric // For eTypeDebugInfo files, the Symbol Vendor will take care of updating the
1988f73363f1SDimitry Andric // unified section list.
1989f73363f1SDimitry Andric if (GetType() != eTypeDebugInfo)
19905f29bb8aSDimitry Andric unified_section_list = *m_sections_up;
1991ead24645SDimitry Andric
1992ead24645SDimitry Andric // If there's a .gnu_debugdata section, we'll try to read the .symtab that's
1993ead24645SDimitry Andric // embedded in there and replace the one in the original object file (if any).
1994ead24645SDimitry Andric // If there's none in the orignal object file, we add it to it.
1995ead24645SDimitry Andric if (auto gdd_obj_file = GetGnuDebugDataObjectFile()) {
1996ead24645SDimitry Andric if (auto gdd_objfile_section_list = gdd_obj_file->GetSectionList()) {
1997ead24645SDimitry Andric if (SectionSP symtab_section_sp =
1998ead24645SDimitry Andric gdd_objfile_section_list->FindSectionByType(
1999ead24645SDimitry Andric eSectionTypeELFSymbolTable, true)) {
2000ead24645SDimitry Andric SectionSP module_section_sp = unified_section_list.FindSectionByType(
2001ead24645SDimitry Andric eSectionTypeELFSymbolTable, true);
2002ead24645SDimitry Andric if (module_section_sp)
2003ead24645SDimitry Andric unified_section_list.ReplaceSection(module_section_sp->GetID(),
2004ead24645SDimitry Andric symtab_section_sp);
2005ead24645SDimitry Andric else
2006ead24645SDimitry Andric unified_section_list.AddSection(symtab_section_sp);
2007ead24645SDimitry Andric }
2008ead24645SDimitry Andric }
2009ead24645SDimitry Andric }
2010ead24645SDimitry Andric }
2011ead24645SDimitry Andric
GetGnuDebugDataObjectFile()2012ead24645SDimitry Andric std::shared_ptr<ObjectFileELF> ObjectFileELF::GetGnuDebugDataObjectFile() {
2013ead24645SDimitry Andric if (m_gnu_debug_data_object_file != nullptr)
2014ead24645SDimitry Andric return m_gnu_debug_data_object_file;
2015ead24645SDimitry Andric
2016ead24645SDimitry Andric SectionSP section =
2017ead24645SDimitry Andric GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"));
2018ead24645SDimitry Andric if (!section)
2019ead24645SDimitry Andric return nullptr;
2020ead24645SDimitry Andric
2021ead24645SDimitry Andric if (!lldb_private::lzma::isAvailable()) {
2022ead24645SDimitry Andric GetModule()->ReportWarning(
2023ead24645SDimitry Andric "No LZMA support found for reading .gnu_debugdata section");
2024ead24645SDimitry Andric return nullptr;
2025ead24645SDimitry Andric }
2026ead24645SDimitry Andric
2027ead24645SDimitry Andric // Uncompress the data
2028ead24645SDimitry Andric DataExtractor data;
2029ead24645SDimitry Andric section->GetSectionData(data);
2030ead24645SDimitry Andric llvm::SmallVector<uint8_t, 0> uncompressedData;
2031ead24645SDimitry Andric auto err = lldb_private::lzma::uncompress(data.GetData(), uncompressedData);
2032ead24645SDimitry Andric if (err) {
2033ead24645SDimitry Andric GetModule()->ReportWarning(
2034e3b55780SDimitry Andric "An error occurred while decompression the section {0}: {1}",
2035ead24645SDimitry Andric section->GetName().AsCString(), llvm::toString(std::move(err)).c_str());
2036ead24645SDimitry Andric return nullptr;
2037ead24645SDimitry Andric }
2038ead24645SDimitry Andric
2039ead24645SDimitry Andric // Construct ObjectFileELF object from decompressed buffer
2040ead24645SDimitry Andric DataBufferSP gdd_data_buf(
2041ead24645SDimitry Andric new DataBufferHeap(uncompressedData.data(), uncompressedData.size()));
2042ead24645SDimitry Andric auto fspec = GetFileSpec().CopyByAppendingPathComponent(
2043ead24645SDimitry Andric llvm::StringRef("gnu_debugdata"));
2044ead24645SDimitry Andric m_gnu_debug_data_object_file.reset(new ObjectFileELF(
2045ead24645SDimitry Andric GetModule(), gdd_data_buf, 0, &fspec, 0, gdd_data_buf->GetByteSize()));
2046ead24645SDimitry Andric
2047ead24645SDimitry Andric // This line is essential; otherwise a breakpoint can be set but not hit.
2048ead24645SDimitry Andric m_gnu_debug_data_object_file->SetType(ObjectFile::eTypeDebugInfo);
2049ead24645SDimitry Andric
2050ead24645SDimitry Andric ArchSpec spec = m_gnu_debug_data_object_file->GetArchitecture();
2051ead24645SDimitry Andric if (spec && m_gnu_debug_data_object_file->SetModulesArchitecture(spec))
2052ead24645SDimitry Andric return m_gnu_debug_data_object_file;
2053ead24645SDimitry Andric
2054ead24645SDimitry Andric return nullptr;
2055f034231aSEd Maste }
2056f034231aSEd Maste
205714f1b3e8SDimitry Andric // Find the arm/aarch64 mapping symbol character in the given symbol name.
2058f73363f1SDimitry Andric // Mapping symbols have the form of "$<char>[.<any>]*". Additionally we
2059f73363f1SDimitry Andric // recognize cases when the mapping symbol prefixed by an arbitrary string
2060f73363f1SDimitry Andric // because if a symbol prefix added to each symbol in the object file with
2061e81d9d49SDimitry Andric // objcopy then the mapping symbols are also prefixed.
FindArmAarch64MappingSymbol(const char * symbol_name)206214f1b3e8SDimitry Andric static char FindArmAarch64MappingSymbol(const char *symbol_name) {
2063e81d9d49SDimitry Andric if (!symbol_name)
2064e81d9d49SDimitry Andric return '\0';
2065e81d9d49SDimitry Andric
2066e81d9d49SDimitry Andric const char *dollar_pos = ::strchr(symbol_name, '$');
2067e81d9d49SDimitry Andric if (!dollar_pos || dollar_pos[1] == '\0')
2068e81d9d49SDimitry Andric return '\0';
2069e81d9d49SDimitry Andric
2070e81d9d49SDimitry Andric if (dollar_pos[2] == '\0' || dollar_pos[2] == '.')
2071e81d9d49SDimitry Andric return dollar_pos[1];
2072e81d9d49SDimitry Andric return '\0';
2073e81d9d49SDimitry Andric }
2074e81d9d49SDimitry Andric
2075e81d9d49SDimitry Andric #define STO_MIPS_ISA (3 << 6)
2076e81d9d49SDimitry Andric #define STO_MICROMIPS (2 << 6)
2077e81d9d49SDimitry Andric #define IS_MICROMIPS(ST_OTHER) (((ST_OTHER)&STO_MIPS_ISA) == STO_MICROMIPS)
2078e81d9d49SDimitry Andric
2079f034231aSEd Maste // private
2080ac9a064cSDimitry Andric std::pair<unsigned, ObjectFileELF::FileAddressToAddressClassMap>
ParseSymbols(Symtab * symtab,user_id_t start_id,SectionList * section_list,const size_t num_symbols,const DataExtractor & symtab_data,const DataExtractor & strtab_data)2081ac9a064cSDimitry Andric ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
2082ac9a064cSDimitry Andric SectionList *section_list, const size_t num_symbols,
2083f034231aSEd Maste const DataExtractor &symtab_data,
208414f1b3e8SDimitry Andric const DataExtractor &strtab_data) {
2085f034231aSEd Maste ELFSymbol symbol;
2086f034231aSEd Maste lldb::offset_t offset = 0;
2087ac9a064cSDimitry Andric // The changes these symbols would make to the class map. We will also update
2088ac9a064cSDimitry Andric // m_address_class_map but need to tell the caller what changed because the
2089ac9a064cSDimitry Andric // caller may be another object file.
2090ac9a064cSDimitry Andric FileAddressToAddressClassMap address_class_map;
2091f034231aSEd Maste
2092f034231aSEd Maste static ConstString text_section_name(".text");
2093f034231aSEd Maste static ConstString init_section_name(".init");
2094f034231aSEd Maste static ConstString fini_section_name(".fini");
2095f034231aSEd Maste static ConstString ctors_section_name(".ctors");
2096f034231aSEd Maste static ConstString dtors_section_name(".dtors");
2097f034231aSEd Maste
2098f034231aSEd Maste static ConstString data_section_name(".data");
2099f034231aSEd Maste static ConstString rodata_section_name(".rodata");
2100f034231aSEd Maste static ConstString rodata1_section_name(".rodata1");
2101f034231aSEd Maste static ConstString data2_section_name(".data1");
2102f034231aSEd Maste static ConstString bss_section_name(".bss");
2103205afe67SEd Maste static ConstString opd_section_name(".opd"); // For ppc64
2104f034231aSEd Maste
210514f1b3e8SDimitry Andric // On Android the oatdata and the oatexec symbols in the oat and odex files
2106f73363f1SDimitry Andric // covers the full .text section what causes issues with displaying unusable
2107f73363f1SDimitry Andric // symbol name to the user and very slow unwinding speed because the
2108f73363f1SDimitry Andric // instruction emulation based unwind plans try to emulate all instructions
2109f73363f1SDimitry Andric // in these symbols. Don't add these symbols to the symbol list as they have
2110f73363f1SDimitry Andric // no use for the debugger and they are causing a lot of trouble. Filtering
2111f73363f1SDimitry Andric // can't be restricted to Android because this special object file don't
2112f73363f1SDimitry Andric // contain the note section specifying the environment to Android but the
2113f73363f1SDimitry Andric // custom extension and file name makes it highly unlikely that this will
2114f73363f1SDimitry Andric // collide with anything else.
21157fa27ce4SDimitry Andric llvm::StringRef file_extension = m_file.GetFileNameExtension();
21165f29bb8aSDimitry Andric bool skip_oatdata_oatexec =
21175f29bb8aSDimitry Andric file_extension == ".oat" || file_extension == ".odex";
2118027f1c96SDimitry Andric
211994994d37SDimitry Andric ArchSpec arch = GetArchitecture();
2120f3fbd1c0SDimitry Andric ModuleSP module_sp(GetModule());
212114f1b3e8SDimitry Andric SectionList *module_section_list =
212214f1b3e8SDimitry Andric module_sp ? module_sp->GetSectionList() : nullptr;
2123e81d9d49SDimitry Andric
2124ac9a064cSDimitry Andric // We might have debug information in a separate object, in which case
2125ac9a064cSDimitry Andric // we need to map the sections from that object to the sections in the
2126ac9a064cSDimitry Andric // main object during symbol lookup. If we had to compare the sections
2127ac9a064cSDimitry Andric // for every single symbol, that would be expensive, so this map is
2128ac9a064cSDimitry Andric // used to accelerate the process.
2129ac9a064cSDimitry Andric std::unordered_map<lldb::SectionSP, lldb::SectionSP> section_map;
2130e81d9d49SDimitry Andric
2131f034231aSEd Maste unsigned i;
213214f1b3e8SDimitry Andric for (i = 0; i < num_symbols; ++i) {
213394994d37SDimitry Andric if (!symbol.Parse(symtab_data, &offset))
2134f034231aSEd Maste break;
2135f034231aSEd Maste
2136f034231aSEd Maste const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
213714f1b3e8SDimitry Andric if (!symbol_name)
213814f1b3e8SDimitry Andric symbol_name = "";
2139f034231aSEd Maste
21400cac4ca3SEd Maste // No need to add non-section symbols that have no names
21410cac4ca3SEd Maste if (symbol.getType() != STT_SECTION &&
214214f1b3e8SDimitry Andric (symbol_name == nullptr || symbol_name[0] == '\0'))
2143f034231aSEd Maste continue;
2144f034231aSEd Maste
214514f1b3e8SDimitry Andric // Skipping oatdata and oatexec sections if it is requested. See details
2146f73363f1SDimitry Andric // above the definition of skip_oatdata_oatexec for the reasons.
214714f1b3e8SDimitry Andric if (skip_oatdata_oatexec && (::strcmp(symbol_name, "oatdata") == 0 ||
214814f1b3e8SDimitry Andric ::strcmp(symbol_name, "oatexec") == 0))
2149027f1c96SDimitry Andric continue;
2150f034231aSEd Maste
2151f034231aSEd Maste SectionSP symbol_section_sp;
2152f034231aSEd Maste SymbolType symbol_type = eSymbolTypeInvalid;
215394994d37SDimitry Andric Elf64_Half shndx = symbol.st_shndx;
2154f034231aSEd Maste
215594994d37SDimitry Andric switch (shndx) {
2156f034231aSEd Maste case SHN_ABS:
2157f034231aSEd Maste symbol_type = eSymbolTypeAbsolute;
2158f034231aSEd Maste break;
2159f034231aSEd Maste case SHN_UNDEF:
2160f034231aSEd Maste symbol_type = eSymbolTypeUndefined;
2161f034231aSEd Maste break;
2162f034231aSEd Maste default:
216394994d37SDimitry Andric symbol_section_sp = section_list->FindSectionByID(shndx);
2164f034231aSEd Maste break;
2165f034231aSEd Maste }
2166f034231aSEd Maste
216714f1b3e8SDimitry Andric // If a symbol is undefined do not process it further even if it has a STT
216814f1b3e8SDimitry Andric // type
216914f1b3e8SDimitry Andric if (symbol_type != eSymbolTypeUndefined) {
217014f1b3e8SDimitry Andric switch (symbol.getType()) {
2171f034231aSEd Maste default:
2172f034231aSEd Maste case STT_NOTYPE:
2173f034231aSEd Maste // The symbol's type is not specified.
2174f034231aSEd Maste break;
2175f034231aSEd Maste
2176f034231aSEd Maste case STT_OBJECT:
2177f73363f1SDimitry Andric // The symbol is associated with a data object, such as a variable, an
2178f73363f1SDimitry Andric // array, etc.
2179f034231aSEd Maste symbol_type = eSymbolTypeData;
2180f034231aSEd Maste break;
2181f034231aSEd Maste
2182f034231aSEd Maste case STT_FUNC:
2183f034231aSEd Maste // The symbol is associated with a function or other executable code.
2184f034231aSEd Maste symbol_type = eSymbolTypeCode;
2185f034231aSEd Maste break;
2186f034231aSEd Maste
2187f034231aSEd Maste case STT_SECTION:
2188f034231aSEd Maste // The symbol is associated with a section. Symbol table entries of
2189f73363f1SDimitry Andric // this type exist primarily for relocation and normally have STB_LOCAL
2190f73363f1SDimitry Andric // binding.
2191f034231aSEd Maste break;
2192f034231aSEd Maste
2193f034231aSEd Maste case STT_FILE:
2194f73363f1SDimitry Andric // Conventionally, the symbol's name gives the name of the source file
2195f73363f1SDimitry Andric // associated with the object file. A file symbol has STB_LOCAL
2196f034231aSEd Maste // binding, its section index is SHN_ABS, and it precedes the other
2197f034231aSEd Maste // STB_LOCAL symbols for the file, if it is present.
2198f034231aSEd Maste symbol_type = eSymbolTypeSourceFile;
2199f034231aSEd Maste break;
2200f034231aSEd Maste
2201f034231aSEd Maste case STT_GNU_IFUNC:
2202f034231aSEd Maste // The symbol is associated with an indirect function. The actual
2203f034231aSEd Maste // function will be resolved if it is referenced.
2204f034231aSEd Maste symbol_type = eSymbolTypeResolver;
2205f034231aSEd Maste break;
2206f034231aSEd Maste }
2207f034231aSEd Maste }
2208f034231aSEd Maste
220914f1b3e8SDimitry Andric if (symbol_type == eSymbolTypeInvalid && symbol.getType() != STT_SECTION) {
221014f1b3e8SDimitry Andric if (symbol_section_sp) {
22115f29bb8aSDimitry Andric ConstString sect_name = symbol_section_sp->GetName();
221214f1b3e8SDimitry Andric if (sect_name == text_section_name || sect_name == init_section_name ||
221314f1b3e8SDimitry Andric sect_name == fini_section_name || sect_name == ctors_section_name ||
221414f1b3e8SDimitry Andric sect_name == dtors_section_name) {
2215f034231aSEd Maste symbol_type = eSymbolTypeCode;
221614f1b3e8SDimitry Andric } else if (sect_name == data_section_name ||
2217f034231aSEd Maste sect_name == data2_section_name ||
2218f034231aSEd Maste sect_name == rodata_section_name ||
2219f034231aSEd Maste sect_name == rodata1_section_name ||
222014f1b3e8SDimitry Andric sect_name == bss_section_name) {
2221f034231aSEd Maste symbol_type = eSymbolTypeData;
2222f034231aSEd Maste }
2223f034231aSEd Maste }
2224f034231aSEd Maste }
2225f034231aSEd Maste
2226205afe67SEd Maste int64_t symbol_value_offset = 0;
2227205afe67SEd Maste uint32_t additional_flags = 0;
2228205afe67SEd Maste
222914f1b3e8SDimitry Andric if (arch.IsValid()) {
223014f1b3e8SDimitry Andric if (arch.GetMachine() == llvm::Triple::arm) {
223114f1b3e8SDimitry Andric if (symbol.getBinding() == STB_LOCAL) {
2232e81d9d49SDimitry Andric char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);
223314f1b3e8SDimitry Andric if (symbol_type == eSymbolTypeCode) {
223414f1b3e8SDimitry Andric switch (mapping_symbol) {
2235e81d9d49SDimitry Andric case 'a':
22365e95aa85SEd Maste // $a[.<any>]* - marks an ARM instruction sequence
2237ac9a064cSDimitry Andric address_class_map[symbol.st_value] = AddressClass::eCode;
2238e81d9d49SDimitry Andric break;
2239e81d9d49SDimitry Andric case 'b':
2240e81d9d49SDimitry Andric case 't':
22415e95aa85SEd Maste // $b[.<any>]* - marks a THUMB BL instruction sequence
22425e95aa85SEd Maste // $t[.<any>]* - marks a THUMB instruction sequence
2243ac9a064cSDimitry Andric address_class_map[symbol.st_value] =
2244f73363f1SDimitry Andric AddressClass::eCodeAlternateISA;
2245e81d9d49SDimitry Andric break;
2246e81d9d49SDimitry Andric case 'd':
22475e95aa85SEd Maste // $d[.<any>]* - marks a data item sequence (e.g. lit pool)
2248ac9a064cSDimitry Andric address_class_map[symbol.st_value] = AddressClass::eData;
2249e81d9d49SDimitry Andric break;
22505e95aa85SEd Maste }
22515e95aa85SEd Maste }
2252e81d9d49SDimitry Andric if (mapping_symbol)
22535e95aa85SEd Maste continue;
22545e95aa85SEd Maste }
225514f1b3e8SDimitry Andric } else if (arch.GetMachine() == llvm::Triple::aarch64) {
225614f1b3e8SDimitry Andric if (symbol.getBinding() == STB_LOCAL) {
2257e81d9d49SDimitry Andric char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);
225814f1b3e8SDimitry Andric if (symbol_type == eSymbolTypeCode) {
225914f1b3e8SDimitry Andric switch (mapping_symbol) {
2260e81d9d49SDimitry Andric case 'x':
22615e95aa85SEd Maste // $x[.<any>]* - marks an A64 instruction sequence
2262ac9a064cSDimitry Andric address_class_map[symbol.st_value] = AddressClass::eCode;
2263e81d9d49SDimitry Andric break;
2264e81d9d49SDimitry Andric case 'd':
22655e95aa85SEd Maste // $d[.<any>]* - marks a data item sequence (e.g. lit pool)
2266ac9a064cSDimitry Andric address_class_map[symbol.st_value] = AddressClass::eData;
2267e81d9d49SDimitry Andric break;
22685e95aa85SEd Maste }
22695e95aa85SEd Maste }
2270e81d9d49SDimitry Andric if (mapping_symbol)
22715e95aa85SEd Maste continue;
22725e95aa85SEd Maste }
22735e95aa85SEd Maste }
22745e95aa85SEd Maste
227514f1b3e8SDimitry Andric if (arch.GetMachine() == llvm::Triple::arm) {
227614f1b3e8SDimitry Andric if (symbol_type == eSymbolTypeCode) {
227714f1b3e8SDimitry Andric if (symbol.st_value & 1) {
2278f73363f1SDimitry Andric // Subtracting 1 from the address effectively unsets the low order
2279f73363f1SDimitry Andric // bit, which results in the address actually pointing to the
2280f73363f1SDimitry Andric // beginning of the symbol. This delta will be used below in
2281f73363f1SDimitry Andric // conjunction with symbol.st_value to produce the final
2282f73363f1SDimitry Andric // symbol_value that we store in the symtab.
2283205afe67SEd Maste symbol_value_offset = -1;
2284ac9a064cSDimitry Andric address_class_map[symbol.st_value ^ 1] =
2285f73363f1SDimitry Andric AddressClass::eCodeAlternateISA;
228614f1b3e8SDimitry Andric } else {
22875e95aa85SEd Maste // This address is ARM
2288ac9a064cSDimitry Andric address_class_map[symbol.st_value] = AddressClass::eCode;
22895e95aa85SEd Maste }
22905e95aa85SEd Maste }
2291205afe67SEd Maste }
2292205afe67SEd Maste
2293e81d9d49SDimitry Andric /*
2294e81d9d49SDimitry Andric * MIPS:
229514f1b3e8SDimitry Andric * The bit #0 of an address is used for ISA mode (1 for microMIPS, 0 for
229614f1b3e8SDimitry Andric * MIPS).
229714f1b3e8SDimitry Andric * This allows processor to switch between microMIPS and MIPS without any
229814f1b3e8SDimitry Andric * need
229914f1b3e8SDimitry Andric * for special mode-control register. However, apart from .debug_line,
230014f1b3e8SDimitry Andric * none of
230114f1b3e8SDimitry Andric * the ELF/DWARF sections set the ISA bit (for symbol or section). Use
230214f1b3e8SDimitry Andric * st_other
230314f1b3e8SDimitry Andric * flag to check whether the symbol is microMIPS and then set the address
230414f1b3e8SDimitry Andric * class
2305e81d9d49SDimitry Andric * accordingly.
2306e81d9d49SDimitry Andric */
23075f29bb8aSDimitry Andric if (arch.IsMIPS()) {
2308e81d9d49SDimitry Andric if (IS_MICROMIPS(symbol.st_other))
2309ac9a064cSDimitry Andric address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
231014f1b3e8SDimitry Andric else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode)) {
2311e81d9d49SDimitry Andric symbol.st_value = symbol.st_value & (~1ull);
2312ac9a064cSDimitry Andric address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
231314f1b3e8SDimitry Andric } else {
2314e81d9d49SDimitry Andric if (symbol_type == eSymbolTypeCode)
2315ac9a064cSDimitry Andric address_class_map[symbol.st_value] = AddressClass::eCode;
2316e81d9d49SDimitry Andric else if (symbol_type == eSymbolTypeData)
2317ac9a064cSDimitry Andric address_class_map[symbol.st_value] = AddressClass::eData;
2318e81d9d49SDimitry Andric else
2319ac9a064cSDimitry Andric address_class_map[symbol.st_value] = AddressClass::eUnknown;
2320f034231aSEd Maste }
2321f034231aSEd Maste }
2322f034231aSEd Maste }
2323f034231aSEd Maste
232414f1b3e8SDimitry Andric // symbol_value_offset may contain 0 for ARM symbols or -1 for THUMB
2325f73363f1SDimitry Andric // symbols. See above for more details.
23265e95aa85SEd Maste uint64_t symbol_value = symbol.st_value + symbol_value_offset;
2327f3fbd1c0SDimitry Andric
232814f1b3e8SDimitry Andric if (symbol_section_sp &&
232914f1b3e8SDimitry Andric CalculateType() != ObjectFile::Type::eTypeObjectFile)
2330f034231aSEd Maste symbol_value -= symbol_section_sp->GetFileAddress();
2331e81d9d49SDimitry Andric
233214f1b3e8SDimitry Andric if (symbol_section_sp && module_section_list &&
233314f1b3e8SDimitry Andric module_section_list != section_list) {
2334ac9a064cSDimitry Andric auto section_it = section_map.find(symbol_section_sp);
2335ac9a064cSDimitry Andric if (section_it == section_map.end()) {
2336ac9a064cSDimitry Andric section_it = section_map
2337ac9a064cSDimitry Andric .emplace(symbol_section_sp,
2338ac9a064cSDimitry Andric FindMatchingSection(*module_section_list,
2339ac9a064cSDimitry Andric symbol_section_sp))
234014f1b3e8SDimitry Andric .first;
2341ac9a064cSDimitry Andric }
2342773dd0e6SDimitry Andric if (section_it->second)
2343e81d9d49SDimitry Andric symbol_section_sp = section_it->second;
2344e81d9d49SDimitry Andric }
2345e81d9d49SDimitry Andric
2346f034231aSEd Maste bool is_global = symbol.getBinding() == STB_GLOBAL;
2347205afe67SEd Maste uint32_t flags = symbol.st_other << 8 | symbol.st_info | additional_flags;
23485e95aa85SEd Maste llvm::StringRef symbol_ref(symbol_name);
23495e95aa85SEd Maste
235014f1b3e8SDimitry Andric // Symbol names may contain @VERSION suffixes. Find those and strip them
235114f1b3e8SDimitry Andric // temporarily.
23525e95aa85SEd Maste size_t version_pos = symbol_ref.find('@');
23535e95aa85SEd Maste bool has_suffix = version_pos != llvm::StringRef::npos;
23545e95aa85SEd Maste llvm::StringRef symbol_bare = symbol_ref.substr(0, version_pos);
2355ead24645SDimitry Andric Mangled mangled(symbol_bare);
23565e95aa85SEd Maste
235714f1b3e8SDimitry Andric // Now append the suffix back to mangled and unmangled names. Only do it if
2358f73363f1SDimitry Andric // the demangling was successful (string is not empty).
235914f1b3e8SDimitry Andric if (has_suffix) {
23605e95aa85SEd Maste llvm::StringRef suffix = symbol_ref.substr(version_pos);
23615e95aa85SEd Maste
23625e95aa85SEd Maste llvm::StringRef mangled_name = mangled.GetMangledName().GetStringRef();
23635e95aa85SEd Maste if (!mangled_name.empty())
23645e95aa85SEd Maste mangled.SetMangledName(ConstString((mangled_name + suffix).str()));
23655e95aa85SEd Maste
2366cfca06d7SDimitry Andric ConstString demangled = mangled.GetDemangledName();
2367027f1c96SDimitry Andric llvm::StringRef demangled_name = demangled.GetStringRef();
23685e95aa85SEd Maste if (!demangled_name.empty())
23695e95aa85SEd Maste mangled.SetDemangledName(ConstString((demangled_name + suffix).str()));
23705e95aa85SEd Maste }
23715e95aa85SEd Maste
237214f1b3e8SDimitry Andric // In ELF all symbol should have a valid size but it is not true for some
2373f73363f1SDimitry Andric // function symbols coming from hand written assembly. As none of the
2374f73363f1SDimitry Andric // function symbol should have 0 size we try to calculate the size for
2375f73363f1SDimitry Andric // these symbols in the symtab with saying that their original size is not
2376f73363f1SDimitry Andric // valid.
237714f1b3e8SDimitry Andric bool symbol_size_valid =
237814f1b3e8SDimitry Andric symbol.st_size != 0 || symbol.getType() != STT_FUNC;
2379f3fbd1c0SDimitry Andric
2380ac9a064cSDimitry Andric bool is_trampoline = false;
2381ac9a064cSDimitry Andric if (arch.IsValid() && (arch.GetMachine() == llvm::Triple::aarch64)) {
2382ac9a064cSDimitry Andric // On AArch64, trampolines are registered as code.
2383ac9a064cSDimitry Andric // If we detect a trampoline (which starts with __AArch64ADRPThunk_ or
2384ac9a064cSDimitry Andric // __AArch64AbsLongThunk_) we register the symbol as a trampoline. This
2385ac9a064cSDimitry Andric // way we will be able to detect the trampoline when we step in a function
2386ac9a064cSDimitry Andric // and step through the trampoline.
2387ac9a064cSDimitry Andric if (symbol_type == eSymbolTypeCode) {
2388ac9a064cSDimitry Andric llvm::StringRef trampoline_name = mangled.GetName().GetStringRef();
2389ac9a064cSDimitry Andric if (trampoline_name.starts_with("__AArch64ADRPThunk_") ||
2390ac9a064cSDimitry Andric trampoline_name.starts_with("__AArch64AbsLongThunk_")) {
2391ac9a064cSDimitry Andric symbol_type = eSymbolTypeTrampoline;
2392ac9a064cSDimitry Andric is_trampoline = true;
2393ac9a064cSDimitry Andric }
2394ac9a064cSDimitry Andric }
2395ac9a064cSDimitry Andric }
2396ac9a064cSDimitry Andric
2397f034231aSEd Maste Symbol dc_symbol(
2398f034231aSEd Maste i + start_id, // ID is the original symbol table index.
23995e95aa85SEd Maste mangled,
2400f034231aSEd Maste symbol_type, // Type of this symbol
2401f034231aSEd Maste is_global, // Is this globally visible?
2402f034231aSEd Maste false, // Is this symbol debug info?
2403ac9a064cSDimitry Andric is_trampoline, // Is this symbol a trampoline?
2404f034231aSEd Maste false, // Is this symbol artificial?
240514f1b3e8SDimitry Andric AddressRange(symbol_section_sp, // Section in which this symbol is
240614f1b3e8SDimitry Andric // defined or null.
2407f034231aSEd Maste symbol_value, // Offset in section or symbol value.
24085e95aa85SEd Maste symbol.st_size), // Size in bytes of this symbol.
2409f3fbd1c0SDimitry Andric symbol_size_valid, // Symbol size is valid
24105e95aa85SEd Maste has_suffix, // Contains linker annotations?
2411f034231aSEd Maste flags); // Symbol flags.
2412706b4fc4SDimitry Andric if (symbol.getBinding() == STB_WEAK)
2413706b4fc4SDimitry Andric dc_symbol.SetIsWeak(true);
2414f034231aSEd Maste symtab->AddSymbol(dc_symbol);
2415f034231aSEd Maste }
2416ac9a064cSDimitry Andric
2417ac9a064cSDimitry Andric m_address_class_map.merge(address_class_map);
2418ac9a064cSDimitry Andric return {i, address_class_map};
2419f034231aSEd Maste }
2420f034231aSEd Maste
2421ac9a064cSDimitry Andric std::pair<unsigned, ObjectFileELF::FileAddressToAddressClassMap>
ParseSymbolTable(Symtab * symbol_table,user_id_t start_id,lldb_private::Section * symtab)2422ac9a064cSDimitry Andric ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, user_id_t start_id,
242314f1b3e8SDimitry Andric lldb_private::Section *symtab) {
242414f1b3e8SDimitry Andric if (symtab->GetObjectFile() != this) {
242514f1b3e8SDimitry Andric // If the symbol table section is owned by a different object file, have it
2426f73363f1SDimitry Andric // do the parsing.
242714f1b3e8SDimitry Andric ObjectFileELF *obj_file_elf =
242814f1b3e8SDimitry Andric static_cast<ObjectFileELF *>(symtab->GetObjectFile());
2429ac9a064cSDimitry Andric auto [num_symbols, address_class_map] =
2430ac9a064cSDimitry Andric obj_file_elf->ParseSymbolTable(symbol_table, start_id, symtab);
2431ac9a064cSDimitry Andric
2432ac9a064cSDimitry Andric // The other object file returned the changes it made to its address
2433ac9a064cSDimitry Andric // class map, make the same changes to ours.
2434ac9a064cSDimitry Andric m_address_class_map.merge(address_class_map);
2435ac9a064cSDimitry Andric
2436ac9a064cSDimitry Andric return {num_symbols, address_class_map};
2437f034231aSEd Maste }
2438f034231aSEd Maste
2439f034231aSEd Maste // Get section list for this object file.
24405f29bb8aSDimitry Andric SectionList *section_list = m_sections_up.get();
2441f034231aSEd Maste if (!section_list)
2442ac9a064cSDimitry Andric return {};
2443f034231aSEd Maste
2444f034231aSEd Maste user_id_t symtab_id = symtab->GetID();
2445f034231aSEd Maste const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
2446f034231aSEd Maste assert(symtab_hdr->sh_type == SHT_SYMTAB ||
2447f034231aSEd Maste symtab_hdr->sh_type == SHT_DYNSYM);
2448f034231aSEd Maste
244994994d37SDimitry Andric // sh_link: section header index of associated string table.
245094994d37SDimitry Andric user_id_t strtab_id = symtab_hdr->sh_link;
2451f034231aSEd Maste Section *strtab = section_list->FindSectionByID(strtab_id).get();
2452f034231aSEd Maste
245314f1b3e8SDimitry Andric if (symtab && strtab) {
2454f034231aSEd Maste assert(symtab->GetObjectFile() == this);
2455f034231aSEd Maste assert(strtab->GetObjectFile() == this);
2456f034231aSEd Maste
2457f034231aSEd Maste DataExtractor symtab_data;
2458f034231aSEd Maste DataExtractor strtab_data;
2459f034231aSEd Maste if (ReadSectionData(symtab, symtab_data) &&
246014f1b3e8SDimitry Andric ReadSectionData(strtab, strtab_data)) {
2461f034231aSEd Maste size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize;
2462f034231aSEd Maste
246314f1b3e8SDimitry Andric return ParseSymbols(symbol_table, start_id, section_list, num_symbols,
246414f1b3e8SDimitry Andric symtab_data, strtab_data);
2465f034231aSEd Maste }
2466f034231aSEd Maste }
2467f034231aSEd Maste
2468ac9a064cSDimitry Andric return {0, {}};
2469f034231aSEd Maste }
2470f034231aSEd Maste
ParseDynamicSymbols()247114f1b3e8SDimitry Andric size_t ObjectFileELF::ParseDynamicSymbols() {
2472f034231aSEd Maste if (m_dynamic_symbols.size())
2473f034231aSEd Maste return m_dynamic_symbols.size();
2474f034231aSEd Maste
2475f034231aSEd Maste SectionList *section_list = GetSectionList();
2476f034231aSEd Maste if (!section_list)
2477f034231aSEd Maste return 0;
2478f034231aSEd Maste
2479f034231aSEd Maste // Find the SHT_DYNAMIC section.
248014f1b3e8SDimitry Andric Section *dynsym =
248114f1b3e8SDimitry Andric section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true)
248214f1b3e8SDimitry Andric .get();
2483f034231aSEd Maste if (!dynsym)
2484f034231aSEd Maste return 0;
2485f034231aSEd Maste assert(dynsym->GetObjectFile() == this);
2486f034231aSEd Maste
2487f034231aSEd Maste ELFDynamic symbol;
2488f034231aSEd Maste DataExtractor dynsym_data;
248914f1b3e8SDimitry Andric if (ReadSectionData(dynsym, dynsym_data)) {
2490f034231aSEd Maste const lldb::offset_t section_size = dynsym_data.GetByteSize();
2491f034231aSEd Maste lldb::offset_t cursor = 0;
2492f034231aSEd Maste
249314f1b3e8SDimitry Andric while (cursor < section_size) {
2494f034231aSEd Maste if (!symbol.Parse(dynsym_data, &cursor))
2495f034231aSEd Maste break;
2496f034231aSEd Maste
2497f034231aSEd Maste m_dynamic_symbols.push_back(symbol);
2498f034231aSEd Maste }
2499f034231aSEd Maste }
2500f034231aSEd Maste
2501f034231aSEd Maste return m_dynamic_symbols.size();
2502f034231aSEd Maste }
2503f034231aSEd Maste
FindDynamicSymbol(unsigned tag)250414f1b3e8SDimitry Andric const ELFDynamic *ObjectFileELF::FindDynamicSymbol(unsigned tag) {
2505f034231aSEd Maste if (!ParseDynamicSymbols())
25065f29bb8aSDimitry Andric return nullptr;
2507f034231aSEd Maste
2508f034231aSEd Maste DynamicSymbolCollIter I = m_dynamic_symbols.begin();
2509f034231aSEd Maste DynamicSymbolCollIter E = m_dynamic_symbols.end();
251014f1b3e8SDimitry Andric for (; I != E; ++I) {
2511f034231aSEd Maste ELFDynamic *symbol = &*I;
2512f034231aSEd Maste
2513f034231aSEd Maste if (symbol->d_tag == tag)
2514f034231aSEd Maste return symbol;
2515f034231aSEd Maste }
2516f034231aSEd Maste
25175f29bb8aSDimitry Andric return nullptr;
2518f034231aSEd Maste }
2519f034231aSEd Maste
PLTRelocationType()252014f1b3e8SDimitry Andric unsigned ObjectFileELF::PLTRelocationType() {
2521f21a844fSEd Maste // DT_PLTREL
2522f21a844fSEd Maste // This member specifies the type of relocation entry to which the
2523f21a844fSEd Maste // procedure linkage table refers. The d_val member holds DT_REL or
2524f21a844fSEd Maste // DT_RELA, as appropriate. All relocations in a procedure linkage table
2525f21a844fSEd Maste // must use the same relocation.
2526f034231aSEd Maste const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
2527f034231aSEd Maste
2528f034231aSEd Maste if (symbol)
2529f034231aSEd Maste return symbol->d_val;
2530f034231aSEd Maste
2531f034231aSEd Maste return 0;
2532f034231aSEd Maste }
2533f034231aSEd Maste
2534f73363f1SDimitry Andric // Returns the size of the normal plt entries and the offset of the first
2535f73363f1SDimitry Andric // normal plt entry. The 0th entry in the plt table is usually a resolution
2536f73363f1SDimitry Andric // entry which have different size in some architectures then the rest of the
2537f73363f1SDimitry Andric // plt entries.
25385e95aa85SEd Maste static std::pair<uint64_t, uint64_t>
GetPltEntrySizeAndOffset(const ELFSectionHeader * rel_hdr,const ELFSectionHeader * plt_hdr)253914f1b3e8SDimitry Andric GetPltEntrySizeAndOffset(const ELFSectionHeader *rel_hdr,
254014f1b3e8SDimitry Andric const ELFSectionHeader *plt_hdr) {
25415e95aa85SEd Maste const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
25425e95aa85SEd Maste
2543f73363f1SDimitry Andric // Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are
2544f73363f1SDimitry Andric // 16 bytes. So round the entsize up by the alignment if addralign is set.
254514f1b3e8SDimitry Andric elf_xword plt_entsize =
254614f1b3e8SDimitry Andric plt_hdr->sh_addralign
254714f1b3e8SDimitry Andric ? llvm::alignTo(plt_hdr->sh_entsize, plt_hdr->sh_addralign)
254814f1b3e8SDimitry Andric : plt_hdr->sh_entsize;
25495e95aa85SEd Maste
2550f3fbd1c0SDimitry Andric // Some linkers e.g ld for arm, fill plt_hdr->sh_entsize field incorrectly.
2551f3fbd1c0SDimitry Andric // PLT entries relocation code in general requires multiple instruction and
255214f1b3e8SDimitry Andric // should be greater than 4 bytes in most cases. Try to guess correct size
255314f1b3e8SDimitry Andric // just in case.
255414f1b3e8SDimitry Andric if (plt_entsize <= 4) {
255514f1b3e8SDimitry Andric // The linker haven't set the plt_hdr->sh_entsize field. Try to guess the
2556f73363f1SDimitry Andric // size of the plt entries based on the number of entries and the size of
2557f73363f1SDimitry Andric // the plt section with the assumption that the size of the 0th entry is at
2558f73363f1SDimitry Andric // least as big as the size of the normal entries and it isn't much bigger
2559f73363f1SDimitry Andric // then that.
25605e95aa85SEd Maste if (plt_hdr->sh_addralign)
256114f1b3e8SDimitry Andric plt_entsize = plt_hdr->sh_size / plt_hdr->sh_addralign /
256214f1b3e8SDimitry Andric (num_relocations + 1) * plt_hdr->sh_addralign;
25635e95aa85SEd Maste else
25645e95aa85SEd Maste plt_entsize = plt_hdr->sh_size / (num_relocations + 1);
25655e95aa85SEd Maste }
25665e95aa85SEd Maste
25675e95aa85SEd Maste elf_xword plt_offset = plt_hdr->sh_size - num_relocations * plt_entsize;
25685e95aa85SEd Maste
25695e95aa85SEd Maste return std::make_pair(plt_entsize, plt_offset);
25705e95aa85SEd Maste }
25715e95aa85SEd Maste
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)257214f1b3e8SDimitry Andric static unsigned ParsePLTRelocations(
257314f1b3e8SDimitry Andric Symtab *symbol_table, user_id_t start_id, unsigned rel_type,
257414f1b3e8SDimitry Andric const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
257514f1b3e8SDimitry Andric const ELFSectionHeader *plt_hdr, const ELFSectionHeader *sym_hdr,
257614f1b3e8SDimitry Andric const lldb::SectionSP &plt_section_sp, DataExtractor &rel_data,
257714f1b3e8SDimitry Andric DataExtractor &symtab_data, DataExtractor &strtab_data) {
2578f034231aSEd Maste ELFRelocation rel(rel_type);
2579f034231aSEd Maste ELFSymbol symbol;
2580f034231aSEd Maste lldb::offset_t offset = 0;
25815e95aa85SEd Maste
25825e95aa85SEd Maste uint64_t plt_offset, plt_entsize;
258314f1b3e8SDimitry Andric std::tie(plt_entsize, plt_offset) =
258414f1b3e8SDimitry Andric GetPltEntrySizeAndOffset(rel_hdr, plt_hdr);
2585f034231aSEd Maste const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
2586f034231aSEd Maste
2587f034231aSEd Maste typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
2588f034231aSEd Maste reloc_info_fn reloc_type;
2589f034231aSEd Maste reloc_info_fn reloc_symbol;
2590f034231aSEd Maste
259114f1b3e8SDimitry Andric if (hdr->Is32Bit()) {
2592f034231aSEd Maste reloc_type = ELFRelocation::RelocType32;
2593f034231aSEd Maste reloc_symbol = ELFRelocation::RelocSymbol32;
259414f1b3e8SDimitry Andric } else {
2595f034231aSEd Maste reloc_type = ELFRelocation::RelocType64;
2596f034231aSEd Maste reloc_symbol = ELFRelocation::RelocSymbol64;
2597f034231aSEd Maste }
2598f034231aSEd Maste
2599f034231aSEd Maste unsigned slot_type = hdr->GetRelocationJumpSlotType();
2600f034231aSEd Maste unsigned i;
260114f1b3e8SDimitry Andric for (i = 0; i < num_relocations; ++i) {
260294994d37SDimitry Andric if (!rel.Parse(rel_data, &offset))
2603f034231aSEd Maste break;
2604f034231aSEd Maste
2605f034231aSEd Maste if (reloc_type(rel) != slot_type)
2606f034231aSEd Maste continue;
2607f034231aSEd Maste
2608f034231aSEd Maste lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
2609f034231aSEd Maste if (!symbol.Parse(symtab_data, &symbol_offset))
2610f034231aSEd Maste break;
2611f034231aSEd Maste
2612f034231aSEd Maste const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
26135e95aa85SEd Maste uint64_t plt_index = plt_offset + i * plt_entsize;
2614f034231aSEd Maste
2615f034231aSEd Maste Symbol jump_symbol(
2616f034231aSEd Maste i + start_id, // Symbol table index
2617f034231aSEd Maste symbol_name, // symbol name.
2618f034231aSEd Maste eSymbolTypeTrampoline, // Type of this symbol
2619f034231aSEd Maste false, // Is this globally visible?
2620f034231aSEd Maste false, // Is this symbol debug info?
2621f034231aSEd Maste true, // Is this symbol a trampoline?
2622f034231aSEd Maste true, // Is this symbol artificial?
2623f034231aSEd Maste plt_section_sp, // Section in which this symbol is defined or null.
2624f034231aSEd Maste plt_index, // Offset in section or symbol value.
2625f034231aSEd Maste plt_entsize, // Size in bytes of this symbol.
2626f034231aSEd Maste true, // Size is valid
26275e95aa85SEd Maste false, // Contains linker annotations?
2628f034231aSEd Maste 0); // Symbol flags.
2629f034231aSEd Maste
2630f034231aSEd Maste symbol_table->AddSymbol(jump_symbol);
2631f034231aSEd Maste }
2632f034231aSEd Maste
2633f034231aSEd Maste return i;
2634f034231aSEd Maste }
2635f034231aSEd Maste
2636f034231aSEd Maste unsigned
ParseTrampolineSymbols(Symtab * symbol_table,user_id_t start_id,const ELFSectionHeaderInfo * rel_hdr,user_id_t rel_id)263714f1b3e8SDimitry Andric ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id,
2638f034231aSEd Maste const ELFSectionHeaderInfo *rel_hdr,
263914f1b3e8SDimitry Andric user_id_t rel_id) {
2640f034231aSEd Maste assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
2641f034231aSEd Maste
2642f3fbd1c0SDimitry Andric // The link field points to the associated symbol table.
2643f034231aSEd Maste user_id_t symtab_id = rel_hdr->sh_link;
2644f034231aSEd Maste
26455e95aa85SEd Maste // If the link field doesn't point to the appropriate symbol name table then
26465e95aa85SEd Maste // try to find it by name as some compiler don't fill in the link fields.
26475e95aa85SEd Maste if (!symtab_id)
26485e95aa85SEd Maste symtab_id = GetSectionIndexByName(".dynsym");
2649f3fbd1c0SDimitry Andric
2650f3fbd1c0SDimitry Andric // Get PLT section. We cannot use rel_hdr->sh_info, since current linkers
2651f3fbd1c0SDimitry Andric // point that to the .got.plt or .got section instead of .plt.
2652f3fbd1c0SDimitry Andric user_id_t plt_id = GetSectionIndexByName(".plt");
26535e95aa85SEd Maste
2654f034231aSEd Maste if (!symtab_id || !plt_id)
2655f034231aSEd Maste return 0;
2656f034231aSEd Maste
2657f034231aSEd Maste const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id);
2658f034231aSEd Maste if (!plt_hdr)
2659f034231aSEd Maste return 0;
2660f034231aSEd Maste
2661f034231aSEd Maste const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id);
2662f034231aSEd Maste if (!sym_hdr)
2663f034231aSEd Maste return 0;
2664f034231aSEd Maste
26655f29bb8aSDimitry Andric SectionList *section_list = m_sections_up.get();
2666f034231aSEd Maste if (!section_list)
2667f034231aSEd Maste return 0;
2668f034231aSEd Maste
2669f034231aSEd Maste Section *rel_section = section_list->FindSectionByID(rel_id).get();
2670f034231aSEd Maste if (!rel_section)
2671f034231aSEd Maste return 0;
2672f034231aSEd Maste
2673f034231aSEd Maste SectionSP plt_section_sp(section_list->FindSectionByID(plt_id));
2674f034231aSEd Maste if (!plt_section_sp)
2675f034231aSEd Maste return 0;
2676f034231aSEd Maste
2677f034231aSEd Maste Section *symtab = section_list->FindSectionByID(symtab_id).get();
2678f034231aSEd Maste if (!symtab)
2679f034231aSEd Maste return 0;
2680f034231aSEd Maste
2681f034231aSEd Maste // sh_link points to associated string table.
268294994d37SDimitry Andric Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link).get();
2683f034231aSEd Maste if (!strtab)
2684f034231aSEd Maste return 0;
2685f034231aSEd Maste
2686f034231aSEd Maste DataExtractor rel_data;
2687f034231aSEd Maste if (!ReadSectionData(rel_section, rel_data))
2688f034231aSEd Maste return 0;
2689f034231aSEd Maste
2690f034231aSEd Maste DataExtractor symtab_data;
2691f034231aSEd Maste if (!ReadSectionData(symtab, symtab_data))
2692f034231aSEd Maste return 0;
2693f034231aSEd Maste
2694f034231aSEd Maste DataExtractor strtab_data;
2695f034231aSEd Maste if (!ReadSectionData(strtab, strtab_data))
2696f034231aSEd Maste return 0;
2697f034231aSEd Maste
2698f034231aSEd Maste unsigned rel_type = PLTRelocationType();
2699f034231aSEd Maste if (!rel_type)
2700f034231aSEd Maste return 0;
2701f034231aSEd Maste
270214f1b3e8SDimitry Andric return ParsePLTRelocations(symbol_table, start_id, rel_type, &m_header,
270314f1b3e8SDimitry Andric rel_hdr, plt_hdr, sym_hdr, plt_section_sp,
270414f1b3e8SDimitry Andric rel_data, symtab_data, strtab_data);
2705f034231aSEd Maste }
2706f034231aSEd Maste
ApplyELF64ABS64Relocation(Symtab * symtab,ELFRelocation & rel,DataExtractor & debug_data,Section * rel_section)27077fa27ce4SDimitry Andric static void ApplyELF64ABS64Relocation(Symtab *symtab, ELFRelocation &rel,
27087fa27ce4SDimitry Andric DataExtractor &debug_data,
27097fa27ce4SDimitry Andric Section *rel_section) {
27107fa27ce4SDimitry Andric Symbol *symbol = symtab->FindSymbolByID(ELFRelocation::RelocSymbol64(rel));
27117fa27ce4SDimitry Andric if (symbol) {
27127fa27ce4SDimitry Andric addr_t value = symbol->GetAddressRef().GetFileAddress();
27137fa27ce4SDimitry Andric DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
27147fa27ce4SDimitry Andric // ObjectFileELF creates a WritableDataBuffer in CreateInstance.
27157fa27ce4SDimitry Andric WritableDataBuffer *data_buffer =
27167fa27ce4SDimitry Andric llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
27177fa27ce4SDimitry Andric uint64_t *dst = reinterpret_cast<uint64_t *>(
27187fa27ce4SDimitry Andric data_buffer->GetBytes() + rel_section->GetFileOffset() +
27197fa27ce4SDimitry Andric ELFRelocation::RelocOffset64(rel));
27207fa27ce4SDimitry Andric uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel);
27217fa27ce4SDimitry Andric memcpy(dst, &val_offset, sizeof(uint64_t));
27227fa27ce4SDimitry Andric }
27237fa27ce4SDimitry Andric }
27247fa27ce4SDimitry Andric
ApplyELF64ABS32Relocation(Symtab * symtab,ELFRelocation & rel,DataExtractor & debug_data,Section * rel_section,bool is_signed)27257fa27ce4SDimitry Andric static void ApplyELF64ABS32Relocation(Symtab *symtab, ELFRelocation &rel,
27267fa27ce4SDimitry Andric DataExtractor &debug_data,
27277fa27ce4SDimitry Andric Section *rel_section, bool is_signed) {
27287fa27ce4SDimitry Andric Symbol *symbol = symtab->FindSymbolByID(ELFRelocation::RelocSymbol64(rel));
27297fa27ce4SDimitry Andric if (symbol) {
27307fa27ce4SDimitry Andric addr_t value = symbol->GetAddressRef().GetFileAddress();
27317fa27ce4SDimitry Andric value += ELFRelocation::RelocAddend32(rel);
27327fa27ce4SDimitry Andric if ((!is_signed && (value > UINT32_MAX)) ||
27337fa27ce4SDimitry Andric (is_signed &&
27347fa27ce4SDimitry Andric ((int64_t)value > INT32_MAX || (int64_t)value < INT32_MIN))) {
27357fa27ce4SDimitry Andric Log *log = GetLog(LLDBLog::Modules);
27367fa27ce4SDimitry Andric LLDB_LOGF(log, "Failed to apply debug info relocations");
27377fa27ce4SDimitry Andric return;
27387fa27ce4SDimitry Andric }
27397fa27ce4SDimitry Andric uint32_t truncated_addr = (value & 0xFFFFFFFF);
27407fa27ce4SDimitry Andric DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
27417fa27ce4SDimitry Andric // ObjectFileELF creates a WritableDataBuffer in CreateInstance.
27427fa27ce4SDimitry Andric WritableDataBuffer *data_buffer =
27437fa27ce4SDimitry Andric llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
27447fa27ce4SDimitry Andric uint32_t *dst = reinterpret_cast<uint32_t *>(
27457fa27ce4SDimitry Andric data_buffer->GetBytes() + rel_section->GetFileOffset() +
27467fa27ce4SDimitry Andric ELFRelocation::RelocOffset32(rel));
27477fa27ce4SDimitry Andric memcpy(dst, &truncated_addr, sizeof(uint32_t));
27487fa27ce4SDimitry Andric }
27497fa27ce4SDimitry Andric }
27507fa27ce4SDimitry Andric
ApplyELF32ABS32RelRelocation(Symtab * symtab,ELFRelocation & rel,DataExtractor & debug_data,Section * rel_section)27517fa27ce4SDimitry Andric static void ApplyELF32ABS32RelRelocation(Symtab *symtab, ELFRelocation &rel,
27527fa27ce4SDimitry Andric DataExtractor &debug_data,
27537fa27ce4SDimitry Andric Section *rel_section) {
27547fa27ce4SDimitry Andric Log *log = GetLog(LLDBLog::Modules);
27557fa27ce4SDimitry Andric Symbol *symbol = symtab->FindSymbolByID(ELFRelocation::RelocSymbol32(rel));
27567fa27ce4SDimitry Andric if (symbol) {
27577fa27ce4SDimitry Andric addr_t value = symbol->GetAddressRef().GetFileAddress();
27587fa27ce4SDimitry Andric if (value == LLDB_INVALID_ADDRESS) {
27597fa27ce4SDimitry Andric const char *name = symbol->GetName().GetCString();
27607fa27ce4SDimitry Andric LLDB_LOGF(log, "Debug info symbol invalid: %s", name);
27617fa27ce4SDimitry Andric return;
27627fa27ce4SDimitry Andric }
27637fa27ce4SDimitry Andric assert(llvm::isUInt<32>(value) && "Valid addresses are 32-bit");
27647fa27ce4SDimitry Andric DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
27657fa27ce4SDimitry Andric // ObjectFileELF creates a WritableDataBuffer in CreateInstance.
27667fa27ce4SDimitry Andric WritableDataBuffer *data_buffer =
27677fa27ce4SDimitry Andric llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
27687fa27ce4SDimitry Andric uint8_t *dst = data_buffer->GetBytes() + rel_section->GetFileOffset() +
27697fa27ce4SDimitry Andric ELFRelocation::RelocOffset32(rel);
27707fa27ce4SDimitry Andric // Implicit addend is stored inline as a signed value.
27717fa27ce4SDimitry Andric int32_t addend;
27727fa27ce4SDimitry Andric memcpy(&addend, dst, sizeof(int32_t));
27737fa27ce4SDimitry Andric // The sum must be positive. This extra check prevents UB from overflow in
27747fa27ce4SDimitry Andric // the actual range check below.
27757fa27ce4SDimitry Andric if (addend < 0 && static_cast<uint32_t>(-addend) > value) {
27767fa27ce4SDimitry Andric LLDB_LOGF(log, "Debug info relocation overflow: 0x%" PRIx64,
27777fa27ce4SDimitry Andric static_cast<int64_t>(value) + addend);
27787fa27ce4SDimitry Andric return;
27797fa27ce4SDimitry Andric }
27807fa27ce4SDimitry Andric if (!llvm::isUInt<32>(value + addend)) {
27817fa27ce4SDimitry Andric LLDB_LOGF(log, "Debug info relocation out of range: 0x%" PRIx64, value);
27827fa27ce4SDimitry Andric return;
27837fa27ce4SDimitry Andric }
27847fa27ce4SDimitry Andric uint32_t addr = value + addend;
27857fa27ce4SDimitry Andric memcpy(dst, &addr, sizeof(uint32_t));
27867fa27ce4SDimitry Andric }
27877fa27ce4SDimitry Andric }
27887fa27ce4SDimitry Andric
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)2789ef5d0b5eSDimitry Andric unsigned ObjectFileELF::ApplyRelocations(
279014f1b3e8SDimitry Andric Symtab *symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
27910cac4ca3SEd Maste const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr,
27920cac4ca3SEd Maste DataExtractor &rel_data, DataExtractor &symtab_data,
279314f1b3e8SDimitry Andric DataExtractor &debug_data, Section *rel_section) {
27940cac4ca3SEd Maste ELFRelocation rel(rel_hdr->sh_type);
27950cac4ca3SEd Maste lldb::addr_t offset = 0;
27960cac4ca3SEd Maste const unsigned num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
27970cac4ca3SEd Maste typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
27980cac4ca3SEd Maste reloc_info_fn reloc_type;
27990cac4ca3SEd Maste reloc_info_fn reloc_symbol;
28000cac4ca3SEd Maste
280114f1b3e8SDimitry Andric if (hdr->Is32Bit()) {
28020cac4ca3SEd Maste reloc_type = ELFRelocation::RelocType32;
28030cac4ca3SEd Maste reloc_symbol = ELFRelocation::RelocSymbol32;
280414f1b3e8SDimitry Andric } else {
28050cac4ca3SEd Maste reloc_type = ELFRelocation::RelocType64;
28060cac4ca3SEd Maste reloc_symbol = ELFRelocation::RelocSymbol64;
28070cac4ca3SEd Maste }
28080cac4ca3SEd Maste
280914f1b3e8SDimitry Andric for (unsigned i = 0; i < num_relocations; ++i) {
2810e3b55780SDimitry Andric if (!rel.Parse(rel_data, &offset)) {
2811e3b55780SDimitry Andric GetModule()->ReportError(".rel{0}[{1:d}] failed to parse relocation",
2812e3b55780SDimitry Andric rel_section->GetName().AsCString(), i);
28130cac4ca3SEd Maste break;
2814e3b55780SDimitry Andric }
28155f29bb8aSDimitry Andric Symbol *symbol = nullptr;
28160cac4ca3SEd Maste
281714f1b3e8SDimitry Andric if (hdr->Is32Bit()) {
28187fa27ce4SDimitry Andric switch (hdr->e_machine) {
28197fa27ce4SDimitry Andric case llvm::ELF::EM_ARM:
28207fa27ce4SDimitry Andric switch (reloc_type(rel)) {
28217fa27ce4SDimitry Andric case R_ARM_ABS32:
28227fa27ce4SDimitry Andric ApplyELF32ABS32RelRelocation(symtab, rel, debug_data, rel_section);
28237fa27ce4SDimitry Andric break;
28247fa27ce4SDimitry Andric case R_ARM_REL32:
28257fa27ce4SDimitry Andric GetModule()->ReportError("unsupported AArch32 relocation:"
28267fa27ce4SDimitry Andric " .rel{0}[{1}], type {2}",
28277fa27ce4SDimitry Andric rel_section->GetName().AsCString(), i,
28287fa27ce4SDimitry Andric reloc_type(rel));
28297fa27ce4SDimitry Andric break;
28307fa27ce4SDimitry Andric default:
28317fa27ce4SDimitry Andric assert(false && "unexpected relocation type");
28327fa27ce4SDimitry Andric }
28337fa27ce4SDimitry Andric break;
28347fa27ce4SDimitry Andric case llvm::ELF::EM_386:
28350cac4ca3SEd Maste switch (reloc_type(rel)) {
28360cac4ca3SEd Maste case R_386_32:
2837e3b55780SDimitry Andric symbol = symtab->FindSymbolByID(reloc_symbol(rel));
2838e3b55780SDimitry Andric if (symbol) {
2839e3b55780SDimitry Andric addr_t f_offset =
2840e3b55780SDimitry Andric rel_section->GetFileOffset() + ELFRelocation::RelocOffset32(rel);
2841e3b55780SDimitry Andric DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
2842e3b55780SDimitry Andric // ObjectFileELF creates a WritableDataBuffer in CreateInstance.
2843e3b55780SDimitry Andric WritableDataBuffer *data_buffer =
2844e3b55780SDimitry Andric llvm::cast<WritableDataBuffer>(data_buffer_sp.get());
2845e3b55780SDimitry Andric uint32_t *dst = reinterpret_cast<uint32_t *>(
2846e3b55780SDimitry Andric data_buffer->GetBytes() + f_offset);
2847e3b55780SDimitry Andric
2848e3b55780SDimitry Andric addr_t value = symbol->GetAddressRef().GetFileAddress();
2849e3b55780SDimitry Andric if (rel.IsRela()) {
2850e3b55780SDimitry Andric value += ELFRelocation::RelocAddend32(rel);
2851e3b55780SDimitry Andric } else {
2852e3b55780SDimitry Andric value += *dst;
2853e3b55780SDimitry Andric }
2854e3b55780SDimitry Andric *dst = value;
2855e3b55780SDimitry Andric } else {
2856e3b55780SDimitry Andric GetModule()->ReportError(".rel{0}[{1}] unknown symbol id: {2:d}",
2857e3b55780SDimitry Andric rel_section->GetName().AsCString(), i,
2858e3b55780SDimitry Andric reloc_symbol(rel));
2859e3b55780SDimitry Andric }
2860e3b55780SDimitry Andric break;
28617fa27ce4SDimitry Andric case R_386_NONE:
28620cac4ca3SEd Maste case R_386_PC32:
28637fa27ce4SDimitry Andric GetModule()->ReportError("unsupported i386 relocation:"
2864e3b55780SDimitry Andric " .rel{0}[{1}], type {2}",
2865e3b55780SDimitry Andric rel_section->GetName().AsCString(), i,
2866e3b55780SDimitry Andric reloc_type(rel));
28677fa27ce4SDimitry Andric break;
28687fa27ce4SDimitry Andric default:
28697fa27ce4SDimitry Andric assert(false && "unexpected relocation type");
28707fa27ce4SDimitry Andric break;
28717fa27ce4SDimitry Andric }
28727fa27ce4SDimitry Andric break;
28737fa27ce4SDimitry Andric default:
28747fa27ce4SDimitry Andric GetModule()->ReportError("unsupported 32-bit ELF machine arch: {0}", hdr->e_machine);
28757fa27ce4SDimitry Andric break;
28760cac4ca3SEd Maste }
28770cac4ca3SEd Maste } else {
28787fa27ce4SDimitry Andric switch (hdr->e_machine) {
28797fa27ce4SDimitry Andric case llvm::ELF::EM_AARCH64:
28800cac4ca3SEd Maste switch (reloc_type(rel)) {
288194994d37SDimitry Andric case R_AARCH64_ABS64:
28827fa27ce4SDimitry Andric ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section);
28837fa27ce4SDimitry Andric break;
28847fa27ce4SDimitry Andric case R_AARCH64_ABS32:
28857fa27ce4SDimitry Andric ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, true);
28867fa27ce4SDimitry Andric break;
28877fa27ce4SDimitry Andric default:
28887fa27ce4SDimitry Andric assert(false && "unexpected relocation type");
28890cac4ca3SEd Maste }
28900cac4ca3SEd Maste break;
28917fa27ce4SDimitry Andric case llvm::ELF::EM_LOONGARCH:
28927fa27ce4SDimitry Andric switch (reloc_type(rel)) {
28937fa27ce4SDimitry Andric case R_LARCH_64:
28947fa27ce4SDimitry Andric ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section);
28957fa27ce4SDimitry Andric break;
28967fa27ce4SDimitry Andric case R_LARCH_32:
28977fa27ce4SDimitry Andric ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, true);
28987fa27ce4SDimitry Andric break;
28997fa27ce4SDimitry Andric default:
29007fa27ce4SDimitry Andric assert(false && "unexpected relocation type");
29010cac4ca3SEd Maste }
29027fa27ce4SDimitry Andric break;
29037fa27ce4SDimitry Andric case llvm::ELF::EM_X86_64:
29047fa27ce4SDimitry Andric switch (reloc_type(rel)) {
29057fa27ce4SDimitry Andric case R_X86_64_64:
29067fa27ce4SDimitry Andric ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section);
29077fa27ce4SDimitry Andric break;
29080cac4ca3SEd Maste case R_X86_64_32:
29097fa27ce4SDimitry Andric ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section,
29107fa27ce4SDimitry Andric false);
29117fa27ce4SDimitry Andric break;
291294994d37SDimitry Andric case R_X86_64_32S:
29137fa27ce4SDimitry Andric ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, true);
291494994d37SDimitry Andric break;
29150cac4ca3SEd Maste case R_X86_64_PC32:
29160cac4ca3SEd Maste default:
29170cac4ca3SEd Maste assert(false && "unexpected relocation type");
29180cac4ca3SEd Maste }
29197fa27ce4SDimitry Andric break;
29207fa27ce4SDimitry Andric default:
29217fa27ce4SDimitry Andric GetModule()->ReportError("unsupported 64-bit ELF machine arch: {0}", hdr->e_machine);
29227fa27ce4SDimitry Andric break;
29237fa27ce4SDimitry Andric }
29240cac4ca3SEd Maste }
29250cac4ca3SEd Maste }
29260cac4ca3SEd Maste
29270cac4ca3SEd Maste return 0;
29280cac4ca3SEd Maste }
29290cac4ca3SEd Maste
RelocateDebugSections(const ELFSectionHeader * rel_hdr,user_id_t rel_id,lldb_private::Symtab * thetab)293014f1b3e8SDimitry Andric unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,
2931ef5d0b5eSDimitry Andric user_id_t rel_id,
2932ef5d0b5eSDimitry Andric lldb_private::Symtab *thetab) {
29330cac4ca3SEd Maste assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
29340cac4ca3SEd Maste
29350cac4ca3SEd Maste // Parse in the section list if needed.
29360cac4ca3SEd Maste SectionList *section_list = GetSectionList();
29370cac4ca3SEd Maste if (!section_list)
29380cac4ca3SEd Maste return 0;
29390cac4ca3SEd Maste
294094994d37SDimitry Andric user_id_t symtab_id = rel_hdr->sh_link;
294194994d37SDimitry Andric user_id_t debug_id = rel_hdr->sh_info;
29420cac4ca3SEd Maste
29430cac4ca3SEd Maste const ELFSectionHeader *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
29440cac4ca3SEd Maste if (!symtab_hdr)
29450cac4ca3SEd Maste return 0;
29460cac4ca3SEd Maste
29470cac4ca3SEd Maste const ELFSectionHeader *debug_hdr = GetSectionHeaderByIndex(debug_id);
29480cac4ca3SEd Maste if (!debug_hdr)
29490cac4ca3SEd Maste return 0;
29500cac4ca3SEd Maste
29510cac4ca3SEd Maste Section *rel = section_list->FindSectionByID(rel_id).get();
29520cac4ca3SEd Maste if (!rel)
29530cac4ca3SEd Maste return 0;
29540cac4ca3SEd Maste
29550cac4ca3SEd Maste Section *symtab = section_list->FindSectionByID(symtab_id).get();
29560cac4ca3SEd Maste if (!symtab)
29570cac4ca3SEd Maste return 0;
29580cac4ca3SEd Maste
29590cac4ca3SEd Maste Section *debug = section_list->FindSectionByID(debug_id).get();
29600cac4ca3SEd Maste if (!debug)
29610cac4ca3SEd Maste return 0;
29620cac4ca3SEd Maste
29630cac4ca3SEd Maste DataExtractor rel_data;
29640cac4ca3SEd Maste DataExtractor symtab_data;
29650cac4ca3SEd Maste DataExtractor debug_data;
29660cac4ca3SEd Maste
2967ef5d0b5eSDimitry Andric if (GetData(rel->GetFileOffset(), rel->GetFileSize(), rel_data) &&
2968ef5d0b5eSDimitry Andric GetData(symtab->GetFileOffset(), symtab->GetFileSize(), symtab_data) &&
2969ef5d0b5eSDimitry Andric GetData(debug->GetFileOffset(), debug->GetFileSize(), debug_data)) {
2970ef5d0b5eSDimitry Andric ApplyRelocations(thetab, &m_header, rel_hdr, symtab_hdr, debug_hdr,
2971ef5d0b5eSDimitry Andric rel_data, symtab_data, debug_data, debug);
29720cac4ca3SEd Maste }
29730cac4ca3SEd Maste
29740cac4ca3SEd Maste return 0;
29750cac4ca3SEd Maste }
29760cac4ca3SEd Maste
ParseSymtab(Symtab & lldb_symtab)2977f65dcba8SDimitry Andric void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) {
2978f034231aSEd Maste ModuleSP module_sp(GetModule());
2979f034231aSEd Maste if (!module_sp)
2980f65dcba8SDimitry Andric return;
2981f65dcba8SDimitry Andric
29824df029ccSDimitry Andric Progress progress("Parsing symbol table",
29834df029ccSDimitry Andric m_file.GetFilename().AsCString("<Unknown>"));
2984f65dcba8SDimitry Andric ElapsedTime elapsed(module_sp->GetSymtabParseTime());
2985f034231aSEd Maste
298614f1b3e8SDimitry Andric // We always want to use the main object file so we (hopefully) only have one
2987f73363f1SDimitry Andric // cached copy of our symtab, dynamic sections, etc.
2988f034231aSEd Maste ObjectFile *module_obj_file = module_sp->GetObjectFile();
2989f034231aSEd Maste if (module_obj_file && module_obj_file != this)
2990f65dcba8SDimitry Andric return module_obj_file->ParseSymtab(lldb_symtab);
2991f034231aSEd Maste
29925e95aa85SEd Maste SectionList *section_list = module_sp->GetSectionList();
2993f034231aSEd Maste if (!section_list)
2994f65dcba8SDimitry Andric return;
2995f034231aSEd Maste
2996f034231aSEd Maste uint64_t symbol_id = 0;
2997f034231aSEd Maste
2998f034231aSEd Maste // Sharable objects and dynamic executables usually have 2 distinct symbol
299914f1b3e8SDimitry Andric // tables, one named ".symtab", and the other ".dynsym". The dynsym is a
3000f73363f1SDimitry Andric // smaller version of the symtab that only contains global symbols. The
3001f73363f1SDimitry Andric // information found in the dynsym is therefore also found in the symtab,
3002f73363f1SDimitry Andric // while the reverse is not necessarily true.
300314f1b3e8SDimitry Andric Section *symtab =
300414f1b3e8SDimitry Andric section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
3005ac9a064cSDimitry Andric if (symtab) {
3006ac9a064cSDimitry Andric auto [num_symbols, address_class_map] =
3007ac9a064cSDimitry Andric ParseSymbolTable(&lldb_symtab, symbol_id, symtab);
3008ac9a064cSDimitry Andric m_address_class_map.merge(address_class_map);
3009ac9a064cSDimitry Andric symbol_id += num_symbols;
3010ac9a064cSDimitry Andric }
3011f034231aSEd Maste
3012ead24645SDimitry Andric // The symtab section is non-allocable and can be stripped, while the
3013ead24645SDimitry Andric // .dynsym section which should always be always be there. To support the
3014ead24645SDimitry Andric // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo
3015ead24645SDimitry Andric // section, nomatter if .symtab was already parsed or not. This is because
3016ead24645SDimitry Andric // minidebuginfo normally removes the .symtab symbols which have their
3017ead24645SDimitry Andric // matching .dynsym counterparts.
3018ead24645SDimitry Andric if (!symtab ||
3019ead24645SDimitry Andric GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) {
3020ead24645SDimitry Andric Section *dynsym =
3021ead24645SDimitry Andric section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
3022ead24645SDimitry Andric .get();
3023ac9a064cSDimitry Andric if (dynsym) {
3024ac9a064cSDimitry Andric auto [num_symbols, address_class_map] =
3025ac9a064cSDimitry Andric ParseSymbolTable(&lldb_symtab, symbol_id, dynsym);
3026ac9a064cSDimitry Andric symbol_id += num_symbols;
3027ac9a064cSDimitry Andric m_address_class_map.merge(address_class_map);
3028ac9a064cSDimitry Andric }
3029ead24645SDimitry Andric }
3030ead24645SDimitry Andric
3031f21a844fSEd Maste // DT_JMPREL
303214f1b3e8SDimitry Andric // If present, this entry's d_ptr member holds the address of
303314f1b3e8SDimitry Andric // relocation
303414f1b3e8SDimitry Andric // entries associated solely with the procedure linkage table.
303514f1b3e8SDimitry Andric // Separating
3036f21a844fSEd Maste // these relocation entries lets the dynamic linker ignore them during
3037f21a844fSEd Maste // process initialization, if lazy binding is enabled. If this entry is
3038f21a844fSEd Maste // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
3039f21a844fSEd Maste // also be present.
3040f034231aSEd Maste const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
304114f1b3e8SDimitry Andric if (symbol) {
3042f21a844fSEd Maste // Synthesize trampoline symbols to help navigate the PLT.
3043f034231aSEd Maste addr_t addr = symbol->d_ptr;
304414f1b3e8SDimitry Andric Section *reloc_section =
304514f1b3e8SDimitry Andric section_list->FindSectionContainingFileAddress(addr).get();
304614f1b3e8SDimitry Andric if (reloc_section) {
3047f034231aSEd Maste user_id_t reloc_id = reloc_section->GetID();
304814f1b3e8SDimitry Andric const ELFSectionHeaderInfo *reloc_header =
304914f1b3e8SDimitry Andric GetSectionHeaderByIndex(reloc_id);
3050f65dcba8SDimitry Andric if (reloc_header)
3051f65dcba8SDimitry Andric ParseTrampolineSymbols(&lldb_symtab, symbol_id, reloc_header, reloc_id);
3052f034231aSEd Maste }
3053344a3780SDimitry Andric }
3054e81d9d49SDimitry Andric
30555f29bb8aSDimitry Andric if (DWARFCallFrameInfo *eh_frame =
30565f29bb8aSDimitry Andric GetModule()->GetUnwindTable().GetEHFrameInfo()) {
3057f65dcba8SDimitry Andric ParseUnwindSymbols(&lldb_symtab, eh_frame);
3058f3fbd1c0SDimitry Andric }
3059f3fbd1c0SDimitry Andric
3060ead24645SDimitry Andric // In the event that there's no symbol entry for the entry point we'll
3061cfca06d7SDimitry Andric // artificially create one. We delegate to the symtab object the figuring
3062ead24645SDimitry Andric // out of the proper size, this will usually make it span til the next
3063ead24645SDimitry Andric // symbol it finds in the section. This means that if there are missing
3064ead24645SDimitry Andric // symbols the entry point might span beyond its function definition.
3065ead24645SDimitry Andric // We're fine with this as it doesn't make it worse than not having a
3066ead24645SDimitry Andric // symbol entry at all.
3067ead24645SDimitry Andric if (CalculateType() == eTypeExecutable) {
3068ead24645SDimitry Andric ArchSpec arch = GetArchitecture();
3069ead24645SDimitry Andric auto entry_point_addr = GetEntryPointAddress();
3070ead24645SDimitry Andric bool is_valid_entry_point =
3071ead24645SDimitry Andric entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset();
3072ead24645SDimitry Andric addr_t entry_point_file_addr = entry_point_addr.GetFileAddress();
3073f65dcba8SDimitry Andric if (is_valid_entry_point && !lldb_symtab.FindSymbolContainingFileAddress(
3074ead24645SDimitry Andric entry_point_file_addr)) {
3075f65dcba8SDimitry Andric uint64_t symbol_id = lldb_symtab.GetNumSymbols();
3076344a3780SDimitry Andric // Don't set the name for any synthetic symbols, the Symbol
3077344a3780SDimitry Andric // object will generate one if needed when the name is accessed
3078344a3780SDimitry Andric // via accessors.
3079344a3780SDimitry Andric SectionSP section_sp = entry_point_addr.GetSection();
3080344a3780SDimitry Andric Symbol symbol(
3081344a3780SDimitry Andric /*symID=*/symbol_id,
3082344a3780SDimitry Andric /*name=*/llvm::StringRef(), // Name will be auto generated.
3083344a3780SDimitry Andric /*type=*/eSymbolTypeCode,
3084344a3780SDimitry Andric /*external=*/true,
3085344a3780SDimitry Andric /*is_debug=*/false,
3086344a3780SDimitry Andric /*is_trampoline=*/false,
3087344a3780SDimitry Andric /*is_artificial=*/true,
3088344a3780SDimitry Andric /*section_sp=*/section_sp,
3089344a3780SDimitry Andric /*offset=*/0,
3090344a3780SDimitry Andric /*size=*/0, // FDE can span multiple symbols so don't use its size.
3091344a3780SDimitry Andric /*size_is_valid=*/false,
3092344a3780SDimitry Andric /*contains_linker_annotations=*/false,
3093344a3780SDimitry Andric /*flags=*/0);
3094ead24645SDimitry Andric // When the entry point is arm thumb we need to explicitly set its
3095ead24645SDimitry Andric // class address to reflect that. This is important because expression
3096ead24645SDimitry Andric // evaluation relies on correctly setting a breakpoint at this
3097ead24645SDimitry Andric // address.
3098ead24645SDimitry Andric if (arch.GetMachine() == llvm::Triple::arm &&
3099344a3780SDimitry Andric (entry_point_file_addr & 1)) {
3100344a3780SDimitry Andric symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1);
3101ead24645SDimitry Andric m_address_class_map[entry_point_file_addr ^ 1] =
3102ead24645SDimitry Andric AddressClass::eCodeAlternateISA;
3103344a3780SDimitry Andric } else {
3104ead24645SDimitry Andric m_address_class_map[entry_point_file_addr] = AddressClass::eCode;
3105ead24645SDimitry Andric }
3106f65dcba8SDimitry Andric lldb_symtab.AddSymbol(symbol);
3107344a3780SDimitry Andric }
3108ead24645SDimitry Andric }
3109ef5d0b5eSDimitry Andric }
3110ef5d0b5eSDimitry Andric
RelocateSection(lldb_private::Section * section)3111ef5d0b5eSDimitry Andric void ObjectFileELF::RelocateSection(lldb_private::Section *section)
3112ef5d0b5eSDimitry Andric {
3113ef5d0b5eSDimitry Andric static const char *debug_prefix = ".debug";
3114ef5d0b5eSDimitry Andric
3115f73363f1SDimitry Andric // Set relocated bit so we stop getting called, regardless of whether we
3116f73363f1SDimitry Andric // actually relocate.
3117ef5d0b5eSDimitry Andric section->SetIsRelocated(true);
3118ef5d0b5eSDimitry Andric
3119ef5d0b5eSDimitry Andric // We only relocate in ELF relocatable files
3120ef5d0b5eSDimitry Andric if (CalculateType() != eTypeObjectFile)
3121ef5d0b5eSDimitry Andric return;
3122ef5d0b5eSDimitry Andric
3123ef5d0b5eSDimitry Andric const char *section_name = section->GetName().GetCString();
3124ef5d0b5eSDimitry Andric // Can't relocate that which can't be named
3125ef5d0b5eSDimitry Andric if (section_name == nullptr)
3126ef5d0b5eSDimitry Andric return;
3127ef5d0b5eSDimitry Andric
3128ef5d0b5eSDimitry Andric // We don't relocate non-debug sections at the moment
3129ef5d0b5eSDimitry Andric if (strncmp(section_name, debug_prefix, strlen(debug_prefix)))
3130ef5d0b5eSDimitry Andric return;
3131ef5d0b5eSDimitry Andric
3132ef5d0b5eSDimitry Andric // Relocation section names to look for
3133ef5d0b5eSDimitry Andric std::string needle = std::string(".rel") + section_name;
3134ef5d0b5eSDimitry Andric std::string needlea = std::string(".rela") + section_name;
3135ef5d0b5eSDimitry Andric
31360cac4ca3SEd Maste for (SectionHeaderCollIter I = m_section_headers.begin();
313714f1b3e8SDimitry Andric I != m_section_headers.end(); ++I) {
313814f1b3e8SDimitry Andric if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL) {
3139ef5d0b5eSDimitry Andric const char *hay_name = I->section_name.GetCString();
3140ef5d0b5eSDimitry Andric if (hay_name == nullptr)
3141ef5d0b5eSDimitry Andric continue;
3142ef5d0b5eSDimitry Andric if (needle == hay_name || needlea == hay_name) {
31430cac4ca3SEd Maste const ELFSectionHeader &reloc_header = *I;
31440cac4ca3SEd Maste user_id_t reloc_id = SectionIndex(I);
3145ef5d0b5eSDimitry Andric RelocateDebugSections(&reloc_header, reloc_id, GetSymtab());
3146ef5d0b5eSDimitry Andric break;
31470cac4ca3SEd Maste }
31480cac4ca3SEd Maste }
31490cac4ca3SEd Maste }
31500cac4ca3SEd Maste }
3151f034231aSEd Maste
ParseUnwindSymbols(Symtab * symbol_table,DWARFCallFrameInfo * eh_frame)315214f1b3e8SDimitry Andric void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
315314f1b3e8SDimitry Andric DWARFCallFrameInfo *eh_frame) {
3154f3fbd1c0SDimitry Andric SectionList *section_list = GetSectionList();
3155f21a844fSEd Maste if (!section_list)
3156f3fbd1c0SDimitry Andric return;
3157f21a844fSEd Maste
315814f1b3e8SDimitry Andric // First we save the new symbols into a separate list and add them to the
3159cfca06d7SDimitry Andric // symbol table after we collected all symbols we want to add. This is
3160f73363f1SDimitry Andric // neccessary because adding a new symbol invalidates the internal index of
3161f73363f1SDimitry Andric // the symtab what causing the next lookup to be slow because it have to
3162f73363f1SDimitry Andric // recalculate the index first.
3163f3fbd1c0SDimitry Andric std::vector<Symbol> new_symbols;
3164f3fbd1c0SDimitry Andric
3165344a3780SDimitry Andric size_t num_symbols = symbol_table->GetNumSymbols();
3166344a3780SDimitry Andric uint64_t last_symbol_id =
3167344a3780SDimitry Andric num_symbols ? symbol_table->SymbolAtIndex(num_symbols - 1)->GetID() : 0;
3168344a3780SDimitry Andric eh_frame->ForEachFDEEntries([&](lldb::addr_t file_addr, uint32_t size,
3169344a3780SDimitry Andric dw_offset_t) {
3170f3fbd1c0SDimitry Andric Symbol *symbol = symbol_table->FindSymbolAtFileAddress(file_addr);
317114f1b3e8SDimitry Andric if (symbol) {
317214f1b3e8SDimitry Andric if (!symbol->GetByteSizeIsValid()) {
3173f3fbd1c0SDimitry Andric symbol->SetByteSize(size);
3174f3fbd1c0SDimitry Andric symbol->SetSizeIsSynthesized(true);
3175f3fbd1c0SDimitry Andric }
317614f1b3e8SDimitry Andric } else {
317714f1b3e8SDimitry Andric SectionSP section_sp =
317814f1b3e8SDimitry Andric section_list->FindSectionContainingFileAddress(file_addr);
317914f1b3e8SDimitry Andric if (section_sp) {
3180f3fbd1c0SDimitry Andric addr_t offset = file_addr - section_sp->GetFileAddress();
3181344a3780SDimitry Andric uint64_t symbol_id = ++last_symbol_id;
3182344a3780SDimitry Andric // Don't set the name for any synthetic symbols, the Symbol
3183344a3780SDimitry Andric // object will generate one if needed when the name is accessed
3184344a3780SDimitry Andric // via accessors.
3185f21a844fSEd Maste Symbol eh_symbol(
3186344a3780SDimitry Andric /*symID=*/symbol_id,
3187344a3780SDimitry Andric /*name=*/llvm::StringRef(), // Name will be auto generated.
3188344a3780SDimitry Andric /*type=*/eSymbolTypeCode,
3189344a3780SDimitry Andric /*external=*/true,
3190344a3780SDimitry Andric /*is_debug=*/false,
3191344a3780SDimitry Andric /*is_trampoline=*/false,
3192344a3780SDimitry Andric /*is_artificial=*/true,
3193344a3780SDimitry Andric /*section_sp=*/section_sp,
3194344a3780SDimitry Andric /*offset=*/offset,
3195344a3780SDimitry Andric /*size=*/0, // FDE can span multiple symbols so don't use its size.
3196344a3780SDimitry Andric /*size_is_valid=*/false,
3197344a3780SDimitry Andric /*contains_linker_annotations=*/false,
3198344a3780SDimitry Andric /*flags=*/0);
3199f3fbd1c0SDimitry Andric new_symbols.push_back(eh_symbol);
3200f21a844fSEd Maste }
3201f21a844fSEd Maste }
3202f3fbd1c0SDimitry Andric return true;
3203f3fbd1c0SDimitry Andric });
3204f21a844fSEd Maste
3205f3fbd1c0SDimitry Andric for (const Symbol &s : new_symbols)
3206f3fbd1c0SDimitry Andric symbol_table->AddSymbol(s);
3207f3fbd1c0SDimitry Andric }
3208f21a844fSEd Maste
IsStripped()320914f1b3e8SDimitry Andric bool ObjectFileELF::IsStripped() {
3210f034231aSEd Maste // TODO: determine this for ELF
3211f034231aSEd Maste return false;
3212f034231aSEd Maste }
3213f034231aSEd Maste
3214f034231aSEd Maste //===----------------------------------------------------------------------===//
3215f034231aSEd Maste // Dump
3216f034231aSEd Maste //
3217f034231aSEd Maste // Dump the specifics of the runtime file container (such as any headers
3218f034231aSEd Maste // segments, sections, etc).
Dump(Stream * s)321914f1b3e8SDimitry Andric void ObjectFileELF::Dump(Stream *s) {
3220f3fbd1c0SDimitry Andric ModuleSP module_sp(GetModule());
322114f1b3e8SDimitry Andric if (!module_sp) {
3222f3fbd1c0SDimitry Andric return;
3223f3fbd1c0SDimitry Andric }
3224f3fbd1c0SDimitry Andric
3225f3fbd1c0SDimitry Andric std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
3226f3fbd1c0SDimitry Andric s->Printf("%p: ", static_cast<void *>(this));
3227f3fbd1c0SDimitry Andric s->Indent();
3228f3fbd1c0SDimitry Andric s->PutCString("ObjectFileELF");
3229f3fbd1c0SDimitry Andric
323094994d37SDimitry Andric ArchSpec header_arch = GetArchitecture();
3231f3fbd1c0SDimitry Andric
323214f1b3e8SDimitry Andric *s << ", file = '" << m_file
323314f1b3e8SDimitry Andric << "', arch = " << header_arch.GetArchitectureName() << "\n";
3234f3fbd1c0SDimitry Andric
3235f034231aSEd Maste DumpELFHeader(s, m_header);
3236f034231aSEd Maste s->EOL();
3237f034231aSEd Maste DumpELFProgramHeaders(s);
3238f034231aSEd Maste s->EOL();
3239f034231aSEd Maste DumpELFSectionHeaders(s);
3240f034231aSEd Maste s->EOL();
3241f034231aSEd Maste SectionList *section_list = GetSectionList();
3242f034231aSEd Maste if (section_list)
3243cfca06d7SDimitry Andric section_list->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true,
3244cfca06d7SDimitry Andric UINT32_MAX);
3245f034231aSEd Maste Symtab *symtab = GetSymtab();
3246f034231aSEd Maste if (symtab)
32475f29bb8aSDimitry Andric symtab->Dump(s, nullptr, eSortOrderNone);
3248f034231aSEd Maste s->EOL();
3249f034231aSEd Maste DumpDependentModules(s);
3250f034231aSEd Maste s->EOL();
3251f034231aSEd Maste }
3252f034231aSEd Maste
3253f034231aSEd Maste // DumpELFHeader
3254f034231aSEd Maste //
3255f034231aSEd Maste // Dump the ELF header to the specified output stream
DumpELFHeader(Stream * s,const ELFHeader & header)325614f1b3e8SDimitry Andric void ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) {
3257f034231aSEd Maste s->PutCString("ELF Header\n");
3258f034231aSEd Maste s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
325914f1b3e8SDimitry Andric s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG1],
326014f1b3e8SDimitry Andric header.e_ident[EI_MAG1]);
326114f1b3e8SDimitry Andric s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG2],
326214f1b3e8SDimitry Andric header.e_ident[EI_MAG2]);
326314f1b3e8SDimitry Andric s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG3],
326414f1b3e8SDimitry Andric header.e_ident[EI_MAG3]);
3265f034231aSEd Maste
3266f034231aSEd Maste s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
3267f034231aSEd Maste s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
3268f034231aSEd Maste DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
3269f034231aSEd Maste s->Printf("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
3270f034231aSEd Maste s->Printf("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
3271f034231aSEd Maste
3272f034231aSEd Maste s->Printf("e_type = 0x%4.4x ", header.e_type);
3273f034231aSEd Maste DumpELFHeader_e_type(s, header.e_type);
3274f034231aSEd Maste s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
3275f034231aSEd Maste s->Printf("e_version = 0x%8.8x\n", header.e_version);
3276f034231aSEd Maste s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry);
3277f034231aSEd Maste s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff);
3278f034231aSEd Maste s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff);
3279f034231aSEd Maste s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
3280f034231aSEd Maste s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
3281f034231aSEd Maste s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
328274a628f7SDimitry Andric s->Printf("e_phnum = 0x%8.8x\n", header.e_phnum);
3283f034231aSEd Maste s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
328474a628f7SDimitry Andric s->Printf("e_shnum = 0x%8.8x\n", header.e_shnum);
328574a628f7SDimitry Andric s->Printf("e_shstrndx = 0x%8.8x\n", header.e_shstrndx);
3286f034231aSEd Maste }
3287f034231aSEd Maste
3288f034231aSEd Maste // DumpELFHeader_e_type
3289f034231aSEd Maste //
3290f034231aSEd Maste // Dump an token value for the ELF header member e_type
DumpELFHeader_e_type(Stream * s,elf_half e_type)329114f1b3e8SDimitry Andric void ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type) {
329214f1b3e8SDimitry Andric switch (e_type) {
329314f1b3e8SDimitry Andric case ET_NONE:
329414f1b3e8SDimitry Andric *s << "ET_NONE";
329514f1b3e8SDimitry Andric break;
329614f1b3e8SDimitry Andric case ET_REL:
329714f1b3e8SDimitry Andric *s << "ET_REL";
329814f1b3e8SDimitry Andric break;
329914f1b3e8SDimitry Andric case ET_EXEC:
330014f1b3e8SDimitry Andric *s << "ET_EXEC";
330114f1b3e8SDimitry Andric break;
330214f1b3e8SDimitry Andric case ET_DYN:
330314f1b3e8SDimitry Andric *s << "ET_DYN";
330414f1b3e8SDimitry Andric break;
330514f1b3e8SDimitry Andric case ET_CORE:
330614f1b3e8SDimitry Andric *s << "ET_CORE";
330714f1b3e8SDimitry Andric break;
3308f034231aSEd Maste default:
3309f034231aSEd Maste break;
3310f034231aSEd Maste }
3311f034231aSEd Maste }
3312f034231aSEd Maste
3313f034231aSEd Maste // DumpELFHeader_e_ident_EI_DATA
3314f034231aSEd Maste //
3315f034231aSEd Maste // Dump an token value for the ELF header member e_ident[EI_DATA]
DumpELFHeader_e_ident_EI_DATA(Stream * s,unsigned char ei_data)331614f1b3e8SDimitry Andric void ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s,
331714f1b3e8SDimitry Andric unsigned char ei_data) {
331814f1b3e8SDimitry Andric switch (ei_data) {
331914f1b3e8SDimitry Andric case ELFDATANONE:
332014f1b3e8SDimitry Andric *s << "ELFDATANONE";
332114f1b3e8SDimitry Andric break;
332214f1b3e8SDimitry Andric case ELFDATA2LSB:
332314f1b3e8SDimitry Andric *s << "ELFDATA2LSB - Little Endian";
332414f1b3e8SDimitry Andric break;
332514f1b3e8SDimitry Andric case ELFDATA2MSB:
332614f1b3e8SDimitry Andric *s << "ELFDATA2MSB - Big Endian";
332714f1b3e8SDimitry Andric break;
3328f034231aSEd Maste default:
3329f034231aSEd Maste break;
3330f034231aSEd Maste }
3331f034231aSEd Maste }
3332f034231aSEd Maste
3333f034231aSEd Maste // DumpELFProgramHeader
3334f034231aSEd Maste //
3335f034231aSEd Maste // Dump a single ELF program header to the specified output stream
DumpELFProgramHeader(Stream * s,const ELFProgramHeader & ph)333614f1b3e8SDimitry Andric void ObjectFileELF::DumpELFProgramHeader(Stream *s,
333714f1b3e8SDimitry Andric const ELFProgramHeader &ph) {
3338f034231aSEd Maste DumpELFProgramHeader_p_type(s, ph.p_type);
333914f1b3e8SDimitry Andric s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset,
334014f1b3e8SDimitry Andric ph.p_vaddr, ph.p_paddr);
334114f1b3e8SDimitry Andric s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8x (", ph.p_filesz, ph.p_memsz,
334214f1b3e8SDimitry Andric ph.p_flags);
3343f034231aSEd Maste
3344f034231aSEd Maste DumpELFProgramHeader_p_flags(s, ph.p_flags);
3345f034231aSEd Maste s->Printf(") %8.8" PRIx64, ph.p_align);
3346f034231aSEd Maste }
3347f034231aSEd Maste
3348f034231aSEd Maste // DumpELFProgramHeader_p_type
3349f034231aSEd Maste //
3350f73363f1SDimitry Andric // Dump an token value for the ELF program header member p_type which describes
3351f73363f1SDimitry Andric // the type of the program header
DumpELFProgramHeader_p_type(Stream * s,elf_word p_type)335214f1b3e8SDimitry Andric void ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) {
3353f034231aSEd Maste const int kStrWidth = 15;
335414f1b3e8SDimitry Andric switch (p_type) {
3355f034231aSEd Maste CASE_AND_STREAM(s, PT_NULL, kStrWidth);
3356f034231aSEd Maste CASE_AND_STREAM(s, PT_LOAD, kStrWidth);
3357f034231aSEd Maste CASE_AND_STREAM(s, PT_DYNAMIC, kStrWidth);
3358f034231aSEd Maste CASE_AND_STREAM(s, PT_INTERP, kStrWidth);
3359f034231aSEd Maste CASE_AND_STREAM(s, PT_NOTE, kStrWidth);
3360f034231aSEd Maste CASE_AND_STREAM(s, PT_SHLIB, kStrWidth);
3361f034231aSEd Maste CASE_AND_STREAM(s, PT_PHDR, kStrWidth);
3362f034231aSEd Maste CASE_AND_STREAM(s, PT_TLS, kStrWidth);
3363f034231aSEd Maste CASE_AND_STREAM(s, PT_GNU_EH_FRAME, kStrWidth);
3364f034231aSEd Maste default:
3365f034231aSEd Maste s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
3366f034231aSEd Maste break;
3367f034231aSEd Maste }
3368f034231aSEd Maste }
3369f034231aSEd Maste
3370f034231aSEd Maste // DumpELFProgramHeader_p_flags
3371f034231aSEd Maste //
3372f034231aSEd Maste // Dump an token value for the ELF program header member p_flags
DumpELFProgramHeader_p_flags(Stream * s,elf_word p_flags)337314f1b3e8SDimitry Andric void ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) {
3374f034231aSEd Maste *s << ((p_flags & PF_X) ? "PF_X" : " ")
3375f034231aSEd Maste << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
3376f034231aSEd Maste << ((p_flags & PF_W) ? "PF_W" : " ")
3377f034231aSEd Maste << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
3378f034231aSEd Maste << ((p_flags & PF_R) ? "PF_R" : " ");
3379f034231aSEd Maste }
3380f034231aSEd Maste
3381f034231aSEd Maste // DumpELFProgramHeaders
3382f034231aSEd Maste //
3383f034231aSEd Maste // Dump all of the ELF program header to the specified output stream
DumpELFProgramHeaders(Stream * s)338414f1b3e8SDimitry Andric void ObjectFileELF::DumpELFProgramHeaders(Stream *s) {
33855e95aa85SEd Maste if (!ParseProgramHeaders())
33865e95aa85SEd Maste return;
33875e95aa85SEd Maste
3388f034231aSEd Maste s->PutCString("Program Headers\n");
3389f034231aSEd Maste s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
3390f034231aSEd Maste "p_filesz p_memsz p_flags p_align\n");
3391f034231aSEd Maste s->PutCString("==== --------------- -------- -------- -------- "
3392f034231aSEd Maste "-------- -------- ------------------------- --------\n");
3393f034231aSEd Maste
339494994d37SDimitry Andric for (const auto &H : llvm::enumerate(m_program_headers)) {
339594994d37SDimitry Andric s->Format("[{0,2}] ", H.index());
339694994d37SDimitry Andric ObjectFileELF::DumpELFProgramHeader(s, H.value());
3397f034231aSEd Maste s->EOL();
3398f034231aSEd Maste }
3399f034231aSEd Maste }
3400f034231aSEd Maste
3401f034231aSEd Maste // DumpELFSectionHeader
3402f034231aSEd Maste //
3403f034231aSEd Maste // Dump a single ELF section header to the specified output stream
DumpELFSectionHeader(Stream * s,const ELFSectionHeaderInfo & sh)340414f1b3e8SDimitry Andric void ObjectFileELF::DumpELFSectionHeader(Stream *s,
340514f1b3e8SDimitry Andric const ELFSectionHeaderInfo &sh) {
3406f034231aSEd Maste s->Printf("%8.8x ", sh.sh_name);
3407f034231aSEd Maste DumpELFSectionHeader_sh_type(s, sh.sh_type);
3408f034231aSEd Maste s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
3409f034231aSEd Maste DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
341014f1b3e8SDimitry Andric s->Printf(") %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addr,
341114f1b3e8SDimitry Andric sh.sh_offset, sh.sh_size);
3412f034231aSEd Maste s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
3413f034231aSEd Maste s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
3414f034231aSEd Maste }
3415f034231aSEd Maste
3416f034231aSEd Maste // DumpELFSectionHeader_sh_type
3417f034231aSEd Maste //
3418f034231aSEd Maste // Dump an token value for the ELF section header member sh_type which
3419f034231aSEd Maste // describes the type of the section
DumpELFSectionHeader_sh_type(Stream * s,elf_word sh_type)342014f1b3e8SDimitry Andric void ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type) {
3421f034231aSEd Maste const int kStrWidth = 12;
342214f1b3e8SDimitry Andric switch (sh_type) {
3423f034231aSEd Maste CASE_AND_STREAM(s, SHT_NULL, kStrWidth);
3424f034231aSEd Maste CASE_AND_STREAM(s, SHT_PROGBITS, kStrWidth);
3425f034231aSEd Maste CASE_AND_STREAM(s, SHT_SYMTAB, kStrWidth);
3426f034231aSEd Maste CASE_AND_STREAM(s, SHT_STRTAB, kStrWidth);
3427f034231aSEd Maste CASE_AND_STREAM(s, SHT_RELA, kStrWidth);
3428f034231aSEd Maste CASE_AND_STREAM(s, SHT_HASH, kStrWidth);
3429f034231aSEd Maste CASE_AND_STREAM(s, SHT_DYNAMIC, kStrWidth);
3430f034231aSEd Maste CASE_AND_STREAM(s, SHT_NOTE, kStrWidth);
3431f034231aSEd Maste CASE_AND_STREAM(s, SHT_NOBITS, kStrWidth);
3432f034231aSEd Maste CASE_AND_STREAM(s, SHT_REL, kStrWidth);
3433f034231aSEd Maste CASE_AND_STREAM(s, SHT_SHLIB, kStrWidth);
3434f034231aSEd Maste CASE_AND_STREAM(s, SHT_DYNSYM, kStrWidth);
3435f034231aSEd Maste CASE_AND_STREAM(s, SHT_LOPROC, kStrWidth);
3436f034231aSEd Maste CASE_AND_STREAM(s, SHT_HIPROC, kStrWidth);
3437f034231aSEd Maste CASE_AND_STREAM(s, SHT_LOUSER, kStrWidth);
3438f034231aSEd Maste CASE_AND_STREAM(s, SHT_HIUSER, kStrWidth);
3439f034231aSEd Maste default:
3440f034231aSEd Maste s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
3441f034231aSEd Maste break;
3442f034231aSEd Maste }
3443f034231aSEd Maste }
3444f034231aSEd Maste
3445f034231aSEd Maste // DumpELFSectionHeader_sh_flags
3446f034231aSEd Maste //
3447f034231aSEd Maste // Dump an token value for the ELF section header member sh_flags
DumpELFSectionHeader_sh_flags(Stream * s,elf_xword sh_flags)344814f1b3e8SDimitry Andric void ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s,
344914f1b3e8SDimitry Andric elf_xword sh_flags) {
3450f034231aSEd Maste *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
3451f034231aSEd Maste << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
3452f034231aSEd Maste << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
3453f034231aSEd Maste << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
3454f034231aSEd Maste << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
3455f034231aSEd Maste }
3456f034231aSEd Maste
3457f034231aSEd Maste // DumpELFSectionHeaders
3458f034231aSEd Maste //
3459f034231aSEd Maste // Dump all of the ELF section header to the specified output stream
DumpELFSectionHeaders(Stream * s)346014f1b3e8SDimitry Andric void ObjectFileELF::DumpELFSectionHeaders(Stream *s) {
3461f034231aSEd Maste if (!ParseSectionHeaders())
3462f034231aSEd Maste return;
3463f034231aSEd Maste
3464f034231aSEd Maste s->PutCString("Section Headers\n");
3465f034231aSEd Maste s->PutCString("IDX name type flags "
3466f034231aSEd Maste "addr offset size link info addralgn "
3467f034231aSEd Maste "entsize Name\n");
3468f034231aSEd Maste s->PutCString("==== -------- ------------ -------------------------------- "
3469f034231aSEd Maste "-------- -------- -------- -------- -------- -------- "
3470f034231aSEd Maste "-------- ====================\n");
3471f034231aSEd Maste
3472f034231aSEd Maste uint32_t idx = 0;
3473f034231aSEd Maste for (SectionHeaderCollConstIter I = m_section_headers.begin();
347414f1b3e8SDimitry Andric I != m_section_headers.end(); ++I, ++idx) {
3475f034231aSEd Maste s->Printf("[%2u] ", idx);
3476f034231aSEd Maste ObjectFileELF::DumpELFSectionHeader(s, *I);
3477f034231aSEd Maste const char *section_name = I->section_name.AsCString("");
3478f034231aSEd Maste if (section_name)
3479f034231aSEd Maste *s << ' ' << section_name << "\n";
3480f034231aSEd Maste }
3481f034231aSEd Maste }
3482f034231aSEd Maste
DumpDependentModules(lldb_private::Stream * s)348314f1b3e8SDimitry Andric void ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) {
3484f034231aSEd Maste size_t num_modules = ParseDependentModules();
3485f034231aSEd Maste
348614f1b3e8SDimitry Andric if (num_modules > 0) {
3487f034231aSEd Maste s->PutCString("Dependent Modules:\n");
348814f1b3e8SDimitry Andric for (unsigned i = 0; i < num_modules; ++i) {
34895f29bb8aSDimitry Andric const FileSpec &spec = m_filespec_up->GetFileSpecAtIndex(i);
3490f034231aSEd Maste s->Printf(" %s\n", spec.GetFilename().GetCString());
3491f034231aSEd Maste }
3492f034231aSEd Maste }
3493f034231aSEd Maste }
3494f034231aSEd Maste
GetArchitecture()349594994d37SDimitry Andric ArchSpec ObjectFileELF::GetArchitecture() {
3496f034231aSEd Maste if (!ParseHeader())
349794994d37SDimitry Andric return ArchSpec();
3498f034231aSEd Maste
349914f1b3e8SDimitry Andric if (m_section_headers.empty()) {
35000cac4ca3SEd Maste // Allow elf notes to be parsed which may affect the detected architecture.
35010cac4ca3SEd Maste ParseSectionHeaders();
35020cac4ca3SEd Maste }
35030cac4ca3SEd Maste
350414f1b3e8SDimitry Andric if (CalculateType() == eTypeCoreFile &&
35055f29bb8aSDimitry Andric !m_arch_spec.TripleOSWasSpecified()) {
350614f1b3e8SDimitry Andric // Core files don't have section headers yet they have PT_NOTE program
3507f73363f1SDimitry Andric // headers that might shed more light on the architecture
350894994d37SDimitry Andric for (const elf::ELFProgramHeader &H : ProgramHeaders()) {
350994994d37SDimitry Andric if (H.p_type != PT_NOTE || H.p_offset == 0 || H.p_filesz == 0)
351094994d37SDimitry Andric continue;
3511e81d9d49SDimitry Andric DataExtractor data;
351294994d37SDimitry Andric if (data.SetData(m_data, H.p_offset, H.p_filesz) == H.p_filesz) {
351394994d37SDimitry Andric UUID uuid;
3514e81d9d49SDimitry Andric RefineModuleDetailsFromNote(data, m_arch_spec, uuid);
3515e81d9d49SDimitry Andric }
3516e81d9d49SDimitry Andric }
3517e81d9d49SDimitry Andric }
351894994d37SDimitry Andric return m_arch_spec;
3519f034231aSEd Maste }
3520f034231aSEd Maste
CalculateType()352114f1b3e8SDimitry Andric ObjectFile::Type ObjectFileELF::CalculateType() {
352214f1b3e8SDimitry Andric switch (m_header.e_type) {
3523f034231aSEd Maste case llvm::ELF::ET_NONE:
3524f034231aSEd Maste // 0 - No file type
3525f034231aSEd Maste return eTypeUnknown;
3526f034231aSEd Maste
3527f034231aSEd Maste case llvm::ELF::ET_REL:
3528f034231aSEd Maste // 1 - Relocatable file
3529f034231aSEd Maste return eTypeObjectFile;
3530f034231aSEd Maste
3531f034231aSEd Maste case llvm::ELF::ET_EXEC:
3532f034231aSEd Maste // 2 - Executable file
3533f034231aSEd Maste return eTypeExecutable;
3534f034231aSEd Maste
3535f034231aSEd Maste case llvm::ELF::ET_DYN:
3536f034231aSEd Maste // 3 - Shared object file
3537f034231aSEd Maste return eTypeSharedLibrary;
3538f034231aSEd Maste
3539f034231aSEd Maste case ET_CORE:
3540f034231aSEd Maste // 4 - Core file
3541f034231aSEd Maste return eTypeCoreFile;
3542f034231aSEd Maste
3543f034231aSEd Maste default:
3544f034231aSEd Maste break;
3545f034231aSEd Maste }
3546f034231aSEd Maste return eTypeUnknown;
3547f034231aSEd Maste }
3548f034231aSEd Maste
CalculateStrata()354914f1b3e8SDimitry Andric ObjectFile::Strata ObjectFileELF::CalculateStrata() {
355014f1b3e8SDimitry Andric switch (m_header.e_type) {
3551f034231aSEd Maste case llvm::ELF::ET_NONE:
3552f034231aSEd Maste // 0 - No file type
3553f034231aSEd Maste return eStrataUnknown;
3554f034231aSEd Maste
3555f034231aSEd Maste case llvm::ELF::ET_REL:
3556f034231aSEd Maste // 1 - Relocatable file
3557f034231aSEd Maste return eStrataUnknown;
3558f034231aSEd Maste
3559f034231aSEd Maste case llvm::ELF::ET_EXEC:
3560f034231aSEd Maste // 2 - Executable file
3561b1c73532SDimitry Andric {
3562b1c73532SDimitry Andric SectionList *section_list = GetSectionList();
3563b1c73532SDimitry Andric if (section_list) {
3564b1c73532SDimitry Andric static ConstString loader_section_name(".interp");
3565b1c73532SDimitry Andric SectionSP loader_section =
3566b1c73532SDimitry Andric section_list->FindSectionByName(loader_section_name);
3567b1c73532SDimitry Andric if (loader_section) {
3568b1c73532SDimitry Andric char buffer[256];
3569b1c73532SDimitry Andric size_t read_size =
3570b1c73532SDimitry Andric ReadSectionData(loader_section.get(), 0, buffer, sizeof(buffer));
3571b1c73532SDimitry Andric
3572b1c73532SDimitry Andric // We compare the content of .interp section
3573b1c73532SDimitry Andric // It will contains \0 when counting read_size, so the size needs to
3574b1c73532SDimitry Andric // decrease by one
3575b1c73532SDimitry Andric llvm::StringRef loader_name(buffer, read_size - 1);
3576b1c73532SDimitry Andric llvm::StringRef freebsd_kernel_loader_name("/red/herring");
3577ac9a064cSDimitry Andric if (loader_name == freebsd_kernel_loader_name)
3578b1c73532SDimitry Andric return eStrataKernel;
3579b1c73532SDimitry Andric }
3580b1c73532SDimitry Andric }
3581f034231aSEd Maste return eStrataUser;
3582b1c73532SDimitry Andric }
3583f034231aSEd Maste
3584f034231aSEd Maste case llvm::ELF::ET_DYN:
3585f034231aSEd Maste // 3 - Shared object file
3586f034231aSEd Maste // TODO: is there any way to detect that an shared library is a kernel
3587f73363f1SDimitry Andric // related executable by inspecting the program headers, section headers,
3588f73363f1SDimitry Andric // symbols, or any other flag bits???
3589f034231aSEd Maste return eStrataUnknown;
3590f034231aSEd Maste
3591f034231aSEd Maste case ET_CORE:
3592f034231aSEd Maste // 4 - Core file
3593f034231aSEd Maste // TODO: is there any way to detect that an core file is a kernel
3594f73363f1SDimitry Andric // related executable by inspecting the program headers, section headers,
3595f73363f1SDimitry Andric // symbols, or any other flag bits???
3596f034231aSEd Maste return eStrataUnknown;
3597f034231aSEd Maste
3598f034231aSEd Maste default:
3599f034231aSEd Maste break;
3600f034231aSEd Maste }
3601f034231aSEd Maste return eStrataUnknown;
3602f034231aSEd Maste }
3603ef5d0b5eSDimitry Andric
ReadSectionData(Section * section,lldb::offset_t section_offset,void * dst,size_t dst_len)3604ef5d0b5eSDimitry Andric size_t ObjectFileELF::ReadSectionData(Section *section,
3605ef5d0b5eSDimitry Andric lldb::offset_t section_offset, void *dst,
3606ef5d0b5eSDimitry Andric size_t dst_len) {
3607ef5d0b5eSDimitry Andric // If some other objectfile owns this data, pass this to them.
3608ef5d0b5eSDimitry Andric if (section->GetObjectFile() != this)
3609ef5d0b5eSDimitry Andric return section->GetObjectFile()->ReadSectionData(section, section_offset,
3610ef5d0b5eSDimitry Andric dst, dst_len);
3611ef5d0b5eSDimitry Andric
3612ef5d0b5eSDimitry Andric if (!section->Test(SHF_COMPRESSED))
3613ef5d0b5eSDimitry Andric return ObjectFile::ReadSectionData(section, section_offset, dst, dst_len);
3614ef5d0b5eSDimitry Andric
3615ef5d0b5eSDimitry Andric // For compressed sections we need to read to full data to be able to
3616ef5d0b5eSDimitry Andric // decompress.
3617ef5d0b5eSDimitry Andric DataExtractor data;
3618ef5d0b5eSDimitry Andric ReadSectionData(section, data);
3619ef5d0b5eSDimitry Andric return data.CopyData(section_offset, dst_len, dst);
3620ef5d0b5eSDimitry Andric }
3621ef5d0b5eSDimitry Andric
ReadSectionData(Section * section,DataExtractor & section_data)3622ef5d0b5eSDimitry Andric size_t ObjectFileELF::ReadSectionData(Section *section,
3623ef5d0b5eSDimitry Andric DataExtractor §ion_data) {
3624ef5d0b5eSDimitry Andric // If some other objectfile owns this data, pass this to them.
3625ef5d0b5eSDimitry Andric if (section->GetObjectFile() != this)
3626ef5d0b5eSDimitry Andric return section->GetObjectFile()->ReadSectionData(section, section_data);
3627ef5d0b5eSDimitry Andric
3628ef5d0b5eSDimitry Andric size_t result = ObjectFile::ReadSectionData(section, section_data);
36294b4fe385SDimitry Andric if (result == 0 || !(section->Get() & llvm::ELF::SHF_COMPRESSED))
3630ef5d0b5eSDimitry Andric return result;
3631ef5d0b5eSDimitry Andric
3632ef5d0b5eSDimitry Andric auto Decompressor = llvm::object::Decompressor::create(
3633ef5d0b5eSDimitry Andric section->GetName().GetStringRef(),
3634ef5d0b5eSDimitry Andric {reinterpret_cast<const char *>(section_data.GetDataStart()),
3635ef5d0b5eSDimitry Andric size_t(section_data.GetByteSize())},
3636ef5d0b5eSDimitry Andric GetByteOrder() == eByteOrderLittle, GetAddressByteSize() == 8);
3637ef5d0b5eSDimitry Andric if (!Decompressor) {
363894994d37SDimitry Andric GetModule()->ReportWarning(
3639e3b55780SDimitry Andric "Unable to initialize decompressor for section '{0}': {1}",
364094994d37SDimitry Andric section->GetName().GetCString(),
364194994d37SDimitry Andric llvm::toString(Decompressor.takeError()).c_str());
364294994d37SDimitry Andric section_data.Clear();
364394994d37SDimitry Andric return 0;
3644ef5d0b5eSDimitry Andric }
364594994d37SDimitry Andric
3646ef5d0b5eSDimitry Andric auto buffer_sp =
3647ef5d0b5eSDimitry Andric std::make_shared<DataBufferHeap>(Decompressor->getDecompressedSize(), 0);
364894994d37SDimitry Andric if (auto error = Decompressor->decompress(
36491f917f69SDimitry Andric {buffer_sp->GetBytes(), size_t(buffer_sp->GetByteSize())})) {
3650e3b55780SDimitry Andric GetModule()->ReportWarning("Decompression of section '{0}' failed: {1}",
365194994d37SDimitry Andric section->GetName().GetCString(),
365294994d37SDimitry Andric llvm::toString(std::move(error)).c_str());
365394994d37SDimitry Andric section_data.Clear();
365494994d37SDimitry Andric return 0;
3655ef5d0b5eSDimitry Andric }
365694994d37SDimitry Andric
3657ef5d0b5eSDimitry Andric section_data.SetData(buffer_sp);
3658ef5d0b5eSDimitry Andric return buffer_sp->GetByteSize();
3659ef5d0b5eSDimitry Andric }
3660f73363f1SDimitry Andric
ProgramHeaders()366194994d37SDimitry Andric llvm::ArrayRef<ELFProgramHeader> ObjectFileELF::ProgramHeaders() {
366294994d37SDimitry Andric ParseProgramHeaders();
366394994d37SDimitry Andric return m_program_headers;
366494994d37SDimitry Andric }
366594994d37SDimitry Andric
GetSegmentData(const ELFProgramHeader & H)366694994d37SDimitry Andric DataExtractor ObjectFileELF::GetSegmentData(const ELFProgramHeader &H) {
366794994d37SDimitry Andric return DataExtractor(m_data, H.p_offset, H.p_filesz);
366894994d37SDimitry Andric }
366994994d37SDimitry Andric
AnySegmentHasPhysicalAddress()3670f73363f1SDimitry Andric bool ObjectFileELF::AnySegmentHasPhysicalAddress() {
367194994d37SDimitry Andric for (const ELFProgramHeader &H : ProgramHeaders()) {
367294994d37SDimitry Andric if (H.p_paddr != 0)
3673f73363f1SDimitry Andric return true;
3674f73363f1SDimitry Andric }
3675f73363f1SDimitry Andric return false;
3676f73363f1SDimitry Andric }
3677f73363f1SDimitry Andric
3678f73363f1SDimitry Andric std::vector<ObjectFile::LoadableData>
GetLoadableData(Target & target)3679f73363f1SDimitry Andric ObjectFileELF::GetLoadableData(Target &target) {
3680f73363f1SDimitry Andric // Create a list of loadable data from loadable segments, using physical
3681f73363f1SDimitry Andric // addresses if they aren't all null
3682f73363f1SDimitry Andric std::vector<LoadableData> loadables;
3683f73363f1SDimitry Andric bool should_use_paddr = AnySegmentHasPhysicalAddress();
368494994d37SDimitry Andric for (const ELFProgramHeader &H : ProgramHeaders()) {
3685f73363f1SDimitry Andric LoadableData loadable;
368694994d37SDimitry Andric if (H.p_type != llvm::ELF::PT_LOAD)
3687f73363f1SDimitry Andric continue;
368894994d37SDimitry Andric loadable.Dest = should_use_paddr ? H.p_paddr : H.p_vaddr;
3689f73363f1SDimitry Andric if (loadable.Dest == LLDB_INVALID_ADDRESS)
3690f73363f1SDimitry Andric continue;
369194994d37SDimitry Andric if (H.p_filesz == 0)
3692f73363f1SDimitry Andric continue;
369394994d37SDimitry Andric auto segment_data = GetSegmentData(H);
3694f73363f1SDimitry Andric loadable.Contents = llvm::ArrayRef<uint8_t>(segment_data.GetDataStart(),
3695f73363f1SDimitry Andric segment_data.GetByteSize());
3696f73363f1SDimitry Andric loadables.push_back(loadable);
3697f73363f1SDimitry Andric }
3698f73363f1SDimitry Andric return loadables;
3699f73363f1SDimitry Andric }
3700145449b1SDimitry Andric
3701145449b1SDimitry Andric lldb::WritableDataBufferSP
MapFileDataWritable(const FileSpec & file,uint64_t Size,uint64_t Offset)3702145449b1SDimitry Andric ObjectFileELF::MapFileDataWritable(const FileSpec &file, uint64_t Size,
3703145449b1SDimitry Andric uint64_t Offset) {
3704145449b1SDimitry Andric return FileSystem::Instance().CreateWritableDataBuffer(file.GetPath(), Size,
3705145449b1SDimitry Andric Offset);
3706145449b1SDimitry Andric }
3707