1ac7ddfbfSEd Maste //===-- ObjectFileELF.cpp ------------------------------------- -*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste // The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste
10ac7ddfbfSEd Maste #include "ObjectFileELF.h"
11ac7ddfbfSEd Maste
12ac7ddfbfSEd Maste #include <algorithm>
13435933ddSDimitry Andric #include <cassert>
149f2f44ceSEd Maste #include <unordered_map>
15ac7ddfbfSEd Maste
16ac7ddfbfSEd Maste #include "lldb/Core/FileSpecList.h"
17ac7ddfbfSEd Maste #include "lldb/Core/Module.h"
18ac7ddfbfSEd Maste #include "lldb/Core/ModuleSpec.h"
19ac7ddfbfSEd Maste #include "lldb/Core/PluginManager.h"
20*b5893f02SDimitry Andric #include "lldb/Core/RangeMap.h"
21ac7ddfbfSEd Maste #include "lldb/Core/Section.h"
22*b5893f02SDimitry Andric #include "lldb/Host/FileSystem.h"
2335617911SEd Maste #include "lldb/Symbol/DWARFCallFrameInfo.h"
24ac7ddfbfSEd Maste #include "lldb/Symbol/SymbolContext.h"
2512b93ac6SEd Maste #include "lldb/Target/SectionLoadList.h"
2635617911SEd Maste #include "lldb/Target/Target.h"
27acac075bSDimitry Andric #include "lldb/Utility/ArchSpec.h"
28acac075bSDimitry Andric #include "lldb/Utility/DataBufferHeap.h"
29f678e45dSDimitry Andric #include "lldb/Utility/Log.h"
305517e702SDimitry Andric #include "lldb/Utility/Status.h"
31f678e45dSDimitry Andric #include "lldb/Utility/Stream.h"
32a580b014SDimitry Andric #include "lldb/Utility/Timer.h"
33ac7ddfbfSEd Maste
34*b5893f02SDimitry Andric #include "llvm/ADT/IntervalMap.h"
35ac7ddfbfSEd Maste #include "llvm/ADT/PointerUnion.h"
360127ef0fSEd Maste #include "llvm/ADT/StringRef.h"
37acac075bSDimitry Andric #include "llvm/Object/Decompressor.h"
384bb0738eSEd Maste #include "llvm/Support/ARMBuildAttributes.h"
390127ef0fSEd Maste #include "llvm/Support/MathExtras.h"
40f678e45dSDimitry Andric #include "llvm/Support/MemoryBuffer.h"
414bb0738eSEd Maste #include "llvm/Support/MipsABIFlags.h"
42ac7ddfbfSEd Maste
43ac7ddfbfSEd Maste #define CASE_AND_STREAM(s, def, width) \
44435933ddSDimitry Andric case def: \
45435933ddSDimitry Andric s->Printf("%-*s", width, #def); \
46435933ddSDimitry Andric break;
47ac7ddfbfSEd Maste
48ac7ddfbfSEd Maste using namespace lldb;
49ac7ddfbfSEd Maste using namespace lldb_private;
50ac7ddfbfSEd Maste using namespace elf;
51ac7ddfbfSEd Maste using namespace llvm::ELF;
52ac7ddfbfSEd Maste
53ac7ddfbfSEd Maste namespace {
540127ef0fSEd Maste
550127ef0fSEd Maste // ELF note owner definitions
560127ef0fSEd Maste const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD";
570127ef0fSEd Maste const char *const LLDB_NT_OWNER_GNU = "GNU";
580127ef0fSEd Maste const char *const LLDB_NT_OWNER_NETBSD = "NetBSD";
59f678e45dSDimitry Andric const char *const LLDB_NT_OWNER_OPENBSD = "OpenBSD";
600127ef0fSEd Maste const char *const LLDB_NT_OWNER_CSR = "csr";
611c3bbb01SEd Maste const char *const LLDB_NT_OWNER_ANDROID = "Android";
629f2f44ceSEd Maste const char *const LLDB_NT_OWNER_CORE = "CORE";
639f2f44ceSEd Maste const char *const LLDB_NT_OWNER_LINUX = "LINUX";
640127ef0fSEd Maste
650127ef0fSEd Maste // ELF note type definitions
660127ef0fSEd Maste const elf_word LLDB_NT_FREEBSD_ABI_TAG = 0x01;
670127ef0fSEd Maste const elf_word LLDB_NT_FREEBSD_ABI_SIZE = 4;
680127ef0fSEd Maste
690127ef0fSEd Maste const elf_word LLDB_NT_GNU_ABI_TAG = 0x01;
700127ef0fSEd Maste const elf_word LLDB_NT_GNU_ABI_SIZE = 16;
710127ef0fSEd Maste
720127ef0fSEd Maste const elf_word LLDB_NT_GNU_BUILD_ID_TAG = 0x03;
730127ef0fSEd Maste
740127ef0fSEd Maste const elf_word LLDB_NT_NETBSD_ABI_TAG = 0x01;
750127ef0fSEd Maste const elf_word LLDB_NT_NETBSD_ABI_SIZE = 4;
760127ef0fSEd Maste
770127ef0fSEd Maste // GNU ABI note OS constants
780127ef0fSEd Maste const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00;
790127ef0fSEd Maste const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01;
800127ef0fSEd Maste const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02;
810127ef0fSEd Maste
829f2f44ceSEd Maste // LLDB_NT_OWNER_CORE and LLDB_NT_OWNER_LINUX note contants
839f2f44ceSEd Maste #define NT_PRSTATUS 1
849f2f44ceSEd Maste #define NT_PRFPREG 2
859f2f44ceSEd Maste #define NT_PRPSINFO 3
869f2f44ceSEd Maste #define NT_TASKSTRUCT 4
879f2f44ceSEd Maste #define NT_AUXV 6
889f2f44ceSEd Maste #define NT_SIGINFO 0x53494749
899f2f44ceSEd Maste #define NT_FILE 0x46494c45
909f2f44ceSEd Maste #define NT_PRXFPREG 0x46e62b7f
919f2f44ceSEd Maste #define NT_PPC_VMX 0x100
929f2f44ceSEd Maste #define NT_PPC_SPE 0x101
939f2f44ceSEd Maste #define NT_PPC_VSX 0x102
949f2f44ceSEd Maste #define NT_386_TLS 0x200
959f2f44ceSEd Maste #define NT_386_IOPERM 0x201
969f2f44ceSEd Maste #define NT_X86_XSTATE 0x202
979f2f44ceSEd Maste #define NT_S390_HIGH_GPRS 0x300
989f2f44ceSEd Maste #define NT_S390_TIMER 0x301
999f2f44ceSEd Maste #define NT_S390_TODCMP 0x302
1009f2f44ceSEd Maste #define NT_S390_TODPREG 0x303
1019f2f44ceSEd Maste #define NT_S390_CTRS 0x304
1029f2f44ceSEd Maste #define NT_S390_PREFIX 0x305
1039f2f44ceSEd Maste #define NT_S390_LAST_BREAK 0x306
1049f2f44ceSEd Maste #define NT_S390_SYSTEM_CALL 0x307
1059f2f44ceSEd Maste #define NT_S390_TDB 0x308
1069f2f44ceSEd Maste #define NT_S390_VXRS_LOW 0x309
1079f2f44ceSEd Maste #define NT_S390_VXRS_HIGH 0x30a
1089f2f44ceSEd Maste #define NT_ARM_VFP 0x400
1099f2f44ceSEd Maste #define NT_ARM_TLS 0x401
1109f2f44ceSEd Maste #define NT_ARM_HW_BREAK 0x402
1119f2f44ceSEd Maste #define NT_ARM_HW_WATCH 0x403
1129f2f44ceSEd Maste #define NT_ARM_SYSTEM_CALL 0x404
1139f2f44ceSEd Maste #define NT_METAG_CBUF 0x500
1149f2f44ceSEd Maste #define NT_METAG_RPIPE 0x501
1159f2f44ceSEd Maste #define NT_METAG_TLS 0x502
1169f2f44ceSEd Maste
117ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
118ac7ddfbfSEd Maste /// @class ELFRelocation
1194ba319b5SDimitry Andric /// Generic wrapper for ELFRel and ELFRela.
120ac7ddfbfSEd Maste ///
121ac7ddfbfSEd Maste /// This helper class allows us to parse both ELFRel and ELFRela relocation
122ac7ddfbfSEd Maste /// entries in a generic manner.
123435933ddSDimitry Andric class ELFRelocation {
124ac7ddfbfSEd Maste public:
125ac7ddfbfSEd Maste /// Constructs an ELFRelocation entry with a personality as given by @p
126ac7ddfbfSEd Maste /// type.
127ac7ddfbfSEd Maste ///
128ac7ddfbfSEd Maste /// @param type Either DT_REL or DT_RELA. Any other value is invalid.
129ac7ddfbfSEd Maste ELFRelocation(unsigned type);
130ac7ddfbfSEd Maste
131ac7ddfbfSEd Maste ~ELFRelocation();
132ac7ddfbfSEd Maste
133435933ddSDimitry Andric bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
134ac7ddfbfSEd Maste
135435933ddSDimitry Andric static unsigned RelocType32(const ELFRelocation &rel);
136ac7ddfbfSEd Maste
137435933ddSDimitry Andric static unsigned RelocType64(const ELFRelocation &rel);
138ac7ddfbfSEd Maste
139435933ddSDimitry Andric static unsigned RelocSymbol32(const ELFRelocation &rel);
140ac7ddfbfSEd Maste
141435933ddSDimitry Andric static unsigned RelocSymbol64(const ELFRelocation &rel);
142ac7ddfbfSEd Maste
143435933ddSDimitry Andric static unsigned RelocOffset32(const ELFRelocation &rel);
1440127ef0fSEd Maste
145435933ddSDimitry Andric static unsigned RelocOffset64(const ELFRelocation &rel);
1460127ef0fSEd Maste
147435933ddSDimitry Andric static unsigned RelocAddend32(const ELFRelocation &rel);
1480127ef0fSEd Maste
149435933ddSDimitry Andric static unsigned RelocAddend64(const ELFRelocation &rel);
1500127ef0fSEd Maste
151ac7ddfbfSEd Maste private:
152ac7ddfbfSEd Maste typedef llvm::PointerUnion<ELFRel *, ELFRela *> RelocUnion;
153ac7ddfbfSEd Maste
154ac7ddfbfSEd Maste RelocUnion reloc;
155ac7ddfbfSEd Maste };
156ac7ddfbfSEd Maste
ELFRelocation(unsigned type)157435933ddSDimitry Andric ELFRelocation::ELFRelocation(unsigned type) {
1580127ef0fSEd Maste if (type == DT_REL || type == SHT_REL)
159ac7ddfbfSEd Maste reloc = new ELFRel();
1600127ef0fSEd Maste else if (type == DT_RELA || type == SHT_RELA)
161ac7ddfbfSEd Maste reloc = new ELFRela();
162ac7ddfbfSEd Maste else {
163ac7ddfbfSEd Maste assert(false && "unexpected relocation type");
164ac7ddfbfSEd Maste reloc = static_cast<ELFRel *>(NULL);
165ac7ddfbfSEd Maste }
166ac7ddfbfSEd Maste }
167ac7ddfbfSEd Maste
~ELFRelocation()168435933ddSDimitry Andric ELFRelocation::~ELFRelocation() {
169ac7ddfbfSEd Maste if (reloc.is<ELFRel *>())
170ac7ddfbfSEd Maste delete reloc.get<ELFRel *>();
171ac7ddfbfSEd Maste else
172ac7ddfbfSEd Maste delete reloc.get<ELFRela *>();
173ac7ddfbfSEd Maste }
174ac7ddfbfSEd Maste
Parse(const lldb_private::DataExtractor & data,lldb::offset_t * offset)175435933ddSDimitry Andric bool ELFRelocation::Parse(const lldb_private::DataExtractor &data,
176435933ddSDimitry Andric lldb::offset_t *offset) {
177ac7ddfbfSEd Maste if (reloc.is<ELFRel *>())
178ac7ddfbfSEd Maste return reloc.get<ELFRel *>()->Parse(data, offset);
179ac7ddfbfSEd Maste else
180ac7ddfbfSEd Maste return reloc.get<ELFRela *>()->Parse(data, offset);
181ac7ddfbfSEd Maste }
182ac7ddfbfSEd Maste
RelocType32(const ELFRelocation & rel)183435933ddSDimitry Andric unsigned ELFRelocation::RelocType32(const ELFRelocation &rel) {
184ac7ddfbfSEd Maste if (rel.reloc.is<ELFRel *>())
185ac7ddfbfSEd Maste return ELFRel::RelocType32(*rel.reloc.get<ELFRel *>());
186ac7ddfbfSEd Maste else
187ac7ddfbfSEd Maste return ELFRela::RelocType32(*rel.reloc.get<ELFRela *>());
188ac7ddfbfSEd Maste }
189ac7ddfbfSEd Maste
RelocType64(const ELFRelocation & rel)190435933ddSDimitry Andric unsigned ELFRelocation::RelocType64(const ELFRelocation &rel) {
191ac7ddfbfSEd Maste if (rel.reloc.is<ELFRel *>())
192ac7ddfbfSEd Maste return ELFRel::RelocType64(*rel.reloc.get<ELFRel *>());
193ac7ddfbfSEd Maste else
194ac7ddfbfSEd Maste return ELFRela::RelocType64(*rel.reloc.get<ELFRela *>());
195ac7ddfbfSEd Maste }
196ac7ddfbfSEd Maste
RelocSymbol32(const ELFRelocation & rel)197435933ddSDimitry Andric unsigned ELFRelocation::RelocSymbol32(const ELFRelocation &rel) {
198ac7ddfbfSEd Maste if (rel.reloc.is<ELFRel *>())
199ac7ddfbfSEd Maste return ELFRel::RelocSymbol32(*rel.reloc.get<ELFRel *>());
200ac7ddfbfSEd Maste else
201ac7ddfbfSEd Maste return ELFRela::RelocSymbol32(*rel.reloc.get<ELFRela *>());
202ac7ddfbfSEd Maste }
203ac7ddfbfSEd Maste
RelocSymbol64(const ELFRelocation & rel)204435933ddSDimitry Andric unsigned ELFRelocation::RelocSymbol64(const ELFRelocation &rel) {
205ac7ddfbfSEd Maste if (rel.reloc.is<ELFRel *>())
206ac7ddfbfSEd Maste return ELFRel::RelocSymbol64(*rel.reloc.get<ELFRel *>());
207ac7ddfbfSEd Maste else
208ac7ddfbfSEd Maste return ELFRela::RelocSymbol64(*rel.reloc.get<ELFRela *>());
209ac7ddfbfSEd Maste }
210ac7ddfbfSEd Maste
RelocOffset32(const ELFRelocation & rel)211435933ddSDimitry Andric unsigned ELFRelocation::RelocOffset32(const ELFRelocation &rel) {
2120127ef0fSEd Maste if (rel.reloc.is<ELFRel *>())
2130127ef0fSEd Maste return rel.reloc.get<ELFRel *>()->r_offset;
2140127ef0fSEd Maste else
2150127ef0fSEd Maste return rel.reloc.get<ELFRela *>()->r_offset;
2160127ef0fSEd Maste }
2170127ef0fSEd Maste
RelocOffset64(const ELFRelocation & rel)218435933ddSDimitry Andric unsigned ELFRelocation::RelocOffset64(const ELFRelocation &rel) {
2190127ef0fSEd Maste if (rel.reloc.is<ELFRel *>())
2200127ef0fSEd Maste return rel.reloc.get<ELFRel *>()->r_offset;
2210127ef0fSEd Maste else
2220127ef0fSEd Maste return rel.reloc.get<ELFRela *>()->r_offset;
2230127ef0fSEd Maste }
2240127ef0fSEd Maste
RelocAddend32(const ELFRelocation & rel)225435933ddSDimitry Andric unsigned ELFRelocation::RelocAddend32(const ELFRelocation &rel) {
2260127ef0fSEd Maste if (rel.reloc.is<ELFRel *>())
2270127ef0fSEd Maste return 0;
2280127ef0fSEd Maste else
2290127ef0fSEd Maste return rel.reloc.get<ELFRela *>()->r_addend;
2300127ef0fSEd Maste }
2310127ef0fSEd Maste
RelocAddend64(const ELFRelocation & rel)232435933ddSDimitry Andric unsigned ELFRelocation::RelocAddend64(const ELFRelocation &rel) {
2330127ef0fSEd Maste if (rel.reloc.is<ELFRel *>())
2340127ef0fSEd Maste return 0;
2350127ef0fSEd Maste else
2360127ef0fSEd Maste return rel.reloc.get<ELFRela *>()->r_addend;
2370127ef0fSEd Maste }
2380127ef0fSEd Maste
239ac7ddfbfSEd Maste } // end anonymous namespace
240ac7ddfbfSEd Maste
SegmentID(size_t PHdrIndex)241*b5893f02SDimitry Andric static user_id_t SegmentID(size_t PHdrIndex) { return ~PHdrIndex; }
242*b5893f02SDimitry Andric
Parse(const DataExtractor & data,lldb::offset_t * offset)243435933ddSDimitry Andric bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) {
244b952cd58SEd Maste // Read all fields.
245b952cd58SEd Maste if (data.GetU32(offset, &n_namesz, 3) == NULL)
246b952cd58SEd Maste return false;
247b952cd58SEd Maste
2484ba319b5SDimitry Andric // The name field is required to be nul-terminated, and n_namesz includes the
2494ba319b5SDimitry Andric // terminating nul in observed implementations (contrary to the ELF-64 spec).
2504ba319b5SDimitry Andric // A special case is needed for cores generated by some older Linux versions,
2514ba319b5SDimitry Andric // which write a note named "CORE" without a nul terminator and n_namesz = 4.
252435933ddSDimitry Andric if (n_namesz == 4) {
253b952cd58SEd Maste char buf[4];
254b952cd58SEd Maste if (data.ExtractBytes(*offset, 4, data.GetByteOrder(), buf) != 4)
255b952cd58SEd Maste return false;
256435933ddSDimitry Andric if (strncmp(buf, "CORE", 4) == 0) {
257b952cd58SEd Maste n_name = "CORE";
258b952cd58SEd Maste *offset += 4;
259b952cd58SEd Maste return true;
260b952cd58SEd Maste }
261b952cd58SEd Maste }
262b952cd58SEd Maste
2634bb0738eSEd Maste const char *cstr = data.GetCStr(offset, llvm::alignTo(n_namesz, 4));
264435933ddSDimitry Andric if (cstr == NULL) {
265b952cd58SEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS));
266b952cd58SEd Maste if (log)
267b952cd58SEd Maste log->Printf("Failed to parse note name lacking nul terminator");
268b952cd58SEd Maste
269b952cd58SEd Maste return false;
270b952cd58SEd Maste }
271b952cd58SEd Maste n_name = cstr;
272b952cd58SEd Maste return true;
273b952cd58SEd Maste }
274b952cd58SEd Maste
kalimbaVariantFromElfFlags(const elf::elf_word e_flags)275435933ddSDimitry Andric static uint32_t kalimbaVariantFromElfFlags(const elf::elf_word e_flags) {
2760127ef0fSEd Maste const uint32_t dsp_rev = e_flags & 0xFF;
2770127ef0fSEd Maste uint32_t kal_arch_variant = LLDB_INVALID_CPUTYPE;
278435933ddSDimitry Andric switch (dsp_rev) {
2790127ef0fSEd Maste // TODO(mg11) Support more variants
2800127ef0fSEd Maste case 10:
2817aa51b79SEd Maste kal_arch_variant = llvm::Triple::KalimbaSubArch_v3;
2820127ef0fSEd Maste break;
2830127ef0fSEd Maste case 14:
2847aa51b79SEd Maste kal_arch_variant = llvm::Triple::KalimbaSubArch_v4;
2857aa51b79SEd Maste break;
2867aa51b79SEd Maste case 17:
2877aa51b79SEd Maste case 20:
2887aa51b79SEd Maste kal_arch_variant = llvm::Triple::KalimbaSubArch_v5;
2890127ef0fSEd Maste break;
2900127ef0fSEd Maste default:
2910127ef0fSEd Maste break;
2920127ef0fSEd Maste }
2930127ef0fSEd Maste return kal_arch_variant;
2940127ef0fSEd Maste }
2950127ef0fSEd Maste
mipsVariantFromElfFlags(const elf::ELFHeader & header)296f678e45dSDimitry Andric static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) {
297f678e45dSDimitry Andric const uint32_t mips_arch = header.e_flags & llvm::ELF::EF_MIPS_ARCH;
298f678e45dSDimitry Andric uint32_t endian = header.e_ident[EI_DATA];
2991c3bbb01SEd Maste uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown;
300f678e45dSDimitry Andric uint32_t fileclass = header.e_ident[EI_CLASS];
301f678e45dSDimitry Andric
3024ba319b5SDimitry Andric // If there aren't any elf flags available (e.g core elf file) then return
3034ba319b5SDimitry Andric // default
304f678e45dSDimitry Andric // 32 or 64 bit arch (without any architecture revision) based on object file's class.
305f678e45dSDimitry Andric if (header.e_type == ET_CORE) {
306f678e45dSDimitry Andric switch (fileclass) {
307f678e45dSDimitry Andric case llvm::ELF::ELFCLASS32:
308f678e45dSDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el
309f678e45dSDimitry Andric : ArchSpec::eMIPSSubType_mips32;
310f678e45dSDimitry Andric case llvm::ELF::ELFCLASS64:
311f678e45dSDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el
312f678e45dSDimitry Andric : ArchSpec::eMIPSSubType_mips64;
313f678e45dSDimitry Andric default:
314f678e45dSDimitry Andric return arch_variant;
315f678e45dSDimitry Andric }
316f678e45dSDimitry Andric }
3171c3bbb01SEd Maste
318435933ddSDimitry Andric switch (mips_arch) {
3199f2f44ceSEd Maste case llvm::ELF::EF_MIPS_ARCH_1:
3209f2f44ceSEd Maste case llvm::ELF::EF_MIPS_ARCH_2:
3211c3bbb01SEd Maste case llvm::ELF::EF_MIPS_ARCH_32:
322435933ddSDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el
323435933ddSDimitry Andric : ArchSpec::eMIPSSubType_mips32;
3241c3bbb01SEd Maste case llvm::ELF::EF_MIPS_ARCH_32R2:
325435933ddSDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r2el
326435933ddSDimitry Andric : ArchSpec::eMIPSSubType_mips32r2;
3271c3bbb01SEd Maste case llvm::ELF::EF_MIPS_ARCH_32R6:
328435933ddSDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r6el
329435933ddSDimitry Andric : ArchSpec::eMIPSSubType_mips32r6;
330444ed5c5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_3:
331444ed5c5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_4:
332444ed5c5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_5:
3331c3bbb01SEd Maste case llvm::ELF::EF_MIPS_ARCH_64:
334435933ddSDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el
335435933ddSDimitry Andric : ArchSpec::eMIPSSubType_mips64;
3361c3bbb01SEd Maste case llvm::ELF::EF_MIPS_ARCH_64R2:
337435933ddSDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r2el
338435933ddSDimitry Andric : ArchSpec::eMIPSSubType_mips64r2;
3391c3bbb01SEd Maste case llvm::ELF::EF_MIPS_ARCH_64R6:
340435933ddSDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r6el
341435933ddSDimitry Andric : ArchSpec::eMIPSSubType_mips64r6;
3421c3bbb01SEd Maste default:
3431c3bbb01SEd Maste break;
3441c3bbb01SEd Maste }
3451c3bbb01SEd Maste
3461c3bbb01SEd Maste return arch_variant;
3471c3bbb01SEd Maste }
3481c3bbb01SEd Maste
subTypeFromElfHeader(const elf::ELFHeader & header)349435933ddSDimitry Andric static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) {
3501c3bbb01SEd Maste if (header.e_machine == llvm::ELF::EM_MIPS)
351f678e45dSDimitry Andric return mipsVariantFromElfFlags(header);
3521c3bbb01SEd Maste
353435933ddSDimitry Andric return llvm::ELF::EM_CSR_KALIMBA == header.e_machine
354435933ddSDimitry Andric ? kalimbaVariantFromElfFlags(header.e_flags)
355435933ddSDimitry Andric : LLDB_INVALID_CPUTYPE;
3560127ef0fSEd Maste }
3570127ef0fSEd Maste
3587aa51b79SEd Maste //! The kalimba toolchain identifies a code section as being
3597aa51b79SEd Maste //! one with the SHT_PROGBITS set in the section sh_type and the top
3607aa51b79SEd Maste //! bit in the 32-bit address field set.
3617aa51b79SEd Maste static lldb::SectionType
kalimbaSectionType(const elf::ELFHeader & header,const elf::ELFSectionHeader & sect_hdr)362435933ddSDimitry Andric kalimbaSectionType(const elf::ELFHeader &header,
363435933ddSDimitry Andric const elf::ELFSectionHeader §_hdr) {
364435933ddSDimitry Andric if (llvm::ELF::EM_CSR_KALIMBA != header.e_machine) {
3657aa51b79SEd Maste return eSectionTypeOther;
3667aa51b79SEd Maste }
3677aa51b79SEd Maste
368435933ddSDimitry Andric if (llvm::ELF::SHT_NOBITS == sect_hdr.sh_type) {
3697aa51b79SEd Maste return eSectionTypeZeroFill;
3707aa51b79SEd Maste }
3717aa51b79SEd Maste
372435933ddSDimitry Andric if (llvm::ELF::SHT_PROGBITS == sect_hdr.sh_type) {
3737aa51b79SEd Maste const lldb::addr_t KAL_CODE_BIT = 1 << 31;
374435933ddSDimitry Andric return KAL_CODE_BIT & sect_hdr.sh_addr ? eSectionTypeCode
375435933ddSDimitry Andric : eSectionTypeData;
3767aa51b79SEd Maste }
3777aa51b79SEd Maste
3787aa51b79SEd Maste return eSectionTypeOther;
3797aa51b79SEd Maste }
3807aa51b79SEd Maste
3810127ef0fSEd Maste // Arbitrary constant used as UUID prefix for core files.
382435933ddSDimitry Andric const uint32_t ObjectFileELF::g_core_uuid_magic(0xE210C);
3830127ef0fSEd Maste
384ac7ddfbfSEd Maste //------------------------------------------------------------------
385ac7ddfbfSEd Maste // Static methods.
386ac7ddfbfSEd Maste //------------------------------------------------------------------
Initialize()387435933ddSDimitry Andric void ObjectFileELF::Initialize() {
388ac7ddfbfSEd Maste PluginManager::RegisterPlugin(GetPluginNameStatic(),
389435933ddSDimitry Andric GetPluginDescriptionStatic(), CreateInstance,
390435933ddSDimitry Andric CreateMemoryInstance, GetModuleSpecifications);
391ac7ddfbfSEd Maste }
392ac7ddfbfSEd Maste
Terminate()393435933ddSDimitry Andric void ObjectFileELF::Terminate() {
394ac7ddfbfSEd Maste PluginManager::UnregisterPlugin(CreateInstance);
395ac7ddfbfSEd Maste }
396ac7ddfbfSEd Maste
GetPluginNameStatic()397435933ddSDimitry Andric lldb_private::ConstString ObjectFileELF::GetPluginNameStatic() {
398ac7ddfbfSEd Maste static ConstString g_name("elf");
399ac7ddfbfSEd Maste return g_name;
400ac7ddfbfSEd Maste }
401ac7ddfbfSEd Maste
GetPluginDescriptionStatic()402435933ddSDimitry Andric const char *ObjectFileELF::GetPluginDescriptionStatic() {
403ac7ddfbfSEd Maste return "ELF object file reader.";
404ac7ddfbfSEd Maste }
405ac7ddfbfSEd 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)406435933ddSDimitry Andric ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp,
407ac7ddfbfSEd Maste DataBufferSP &data_sp,
408ac7ddfbfSEd Maste lldb::offset_t data_offset,
409ac7ddfbfSEd Maste const lldb_private::FileSpec *file,
410ac7ddfbfSEd Maste lldb::offset_t file_offset,
411435933ddSDimitry Andric lldb::offset_t length) {
412435933ddSDimitry Andric if (!data_sp) {
41338638513SDimitry Andric data_sp = MapFileData(*file, length, file_offset);
414f678e45dSDimitry Andric if (!data_sp)
415f678e45dSDimitry Andric return nullptr;
416ac7ddfbfSEd Maste data_offset = 0;
417ac7ddfbfSEd Maste }
418ac7ddfbfSEd Maste
419f678e45dSDimitry Andric assert(data_sp);
420f678e45dSDimitry Andric
421f678e45dSDimitry Andric if (data_sp->GetByteSize() <= (llvm::ELF::EI_NIDENT + data_offset))
422f678e45dSDimitry Andric return nullptr;
423f678e45dSDimitry Andric
424ac7ddfbfSEd Maste const uint8_t *magic = data_sp->GetBytes() + data_offset;
425f678e45dSDimitry Andric if (!ELFHeader::MagicBytesMatch(magic))
426f678e45dSDimitry Andric return nullptr;
427f678e45dSDimitry Andric
428ac7ddfbfSEd Maste // Update the data to contain the entire file if it doesn't already
429ac7ddfbfSEd Maste if (data_sp->GetByteSize() < length) {
43038638513SDimitry Andric data_sp = MapFileData(*file, length, file_offset);
431f678e45dSDimitry Andric if (!data_sp)
432f678e45dSDimitry Andric return nullptr;
433ac7ddfbfSEd Maste data_offset = 0;
434ac7ddfbfSEd Maste magic = data_sp->GetBytes();
435ac7ddfbfSEd Maste }
436f678e45dSDimitry Andric
437ac7ddfbfSEd Maste unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
438435933ddSDimitry Andric if (address_size == 4 || address_size == 8) {
439435933ddSDimitry Andric std::unique_ptr<ObjectFileELF> objfile_ap(new ObjectFileELF(
440435933ddSDimitry Andric module_sp, data_sp, data_offset, file, file_offset, length));
441*b5893f02SDimitry Andric ArchSpec spec = objfile_ap->GetArchitecture();
442*b5893f02SDimitry Andric if (spec && objfile_ap->SetModulesArchitecture(spec))
443ac7ddfbfSEd Maste return objfile_ap.release();
444ac7ddfbfSEd Maste }
445f678e45dSDimitry Andric
446ac7ddfbfSEd Maste return NULL;
447ac7ddfbfSEd Maste }
448ac7ddfbfSEd Maste
CreateMemoryInstance(const lldb::ModuleSP & module_sp,DataBufferSP & data_sp,const lldb::ProcessSP & process_sp,lldb::addr_t header_addr)449435933ddSDimitry Andric ObjectFile *ObjectFileELF::CreateMemoryInstance(
450435933ddSDimitry Andric const lldb::ModuleSP &module_sp, DataBufferSP &data_sp,
451435933ddSDimitry Andric const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) {
452435933ddSDimitry Andric if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT)) {
4530127ef0fSEd Maste const uint8_t *magic = data_sp->GetBytes();
454435933ddSDimitry Andric if (ELFHeader::MagicBytesMatch(magic)) {
4550127ef0fSEd Maste unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
456435933ddSDimitry Andric if (address_size == 4 || address_size == 8) {
457acac075bSDimitry Andric std::unique_ptr<ObjectFileELF> objfile_ap(
458435933ddSDimitry Andric new ObjectFileELF(module_sp, data_sp, process_sp, header_addr));
459*b5893f02SDimitry Andric ArchSpec spec = objfile_ap->GetArchitecture();
460*b5893f02SDimitry Andric if (spec && objfile_ap->SetModulesArchitecture(spec))
4610127ef0fSEd Maste return objfile_ap.release();
4620127ef0fSEd Maste }
4630127ef0fSEd Maste }
4640127ef0fSEd Maste }
465ac7ddfbfSEd Maste return NULL;
466ac7ddfbfSEd Maste }
467ac7ddfbfSEd Maste
MagicBytesMatch(DataBufferSP & data_sp,lldb::addr_t data_offset,lldb::addr_t data_length)468435933ddSDimitry Andric bool ObjectFileELF::MagicBytesMatch(DataBufferSP &data_sp,
469ac7ddfbfSEd Maste lldb::addr_t data_offset,
470435933ddSDimitry Andric lldb::addr_t data_length) {
471435933ddSDimitry Andric if (data_sp &&
472435933ddSDimitry Andric data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset)) {
473ac7ddfbfSEd Maste const uint8_t *magic = data_sp->GetBytes() + data_offset;
474ac7ddfbfSEd Maste return ELFHeader::MagicBytesMatch(magic);
475ac7ddfbfSEd Maste }
476ac7ddfbfSEd Maste return false;
477ac7ddfbfSEd Maste }
478ac7ddfbfSEd Maste
479ac7ddfbfSEd Maste /*
480ac7ddfbfSEd Maste * crc function from http://svnweb.freebsd.org/base/head/sys/libkern/crc32.c
481ac7ddfbfSEd Maste *
482ac7ddfbfSEd Maste * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
483ac7ddfbfSEd Maste * code or tables extracted from it, as desired without restriction.
484ac7ddfbfSEd Maste */
calc_crc32(uint32_t crc,const void * buf,size_t size)485435933ddSDimitry Andric static uint32_t calc_crc32(uint32_t crc, const void *buf, size_t size) {
486435933ddSDimitry Andric static const uint32_t g_crc32_tab[] = {
487ac7ddfbfSEd Maste 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
488ac7ddfbfSEd Maste 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
489ac7ddfbfSEd Maste 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
490ac7ddfbfSEd Maste 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
491ac7ddfbfSEd Maste 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
492ac7ddfbfSEd Maste 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
493ac7ddfbfSEd Maste 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
494ac7ddfbfSEd Maste 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
495ac7ddfbfSEd Maste 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
496ac7ddfbfSEd Maste 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
497ac7ddfbfSEd Maste 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
498ac7ddfbfSEd Maste 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
499ac7ddfbfSEd Maste 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
500ac7ddfbfSEd Maste 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
501ac7ddfbfSEd Maste 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
502ac7ddfbfSEd Maste 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
503ac7ddfbfSEd Maste 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
504ac7ddfbfSEd Maste 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
505ac7ddfbfSEd Maste 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
506ac7ddfbfSEd Maste 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
507ac7ddfbfSEd Maste 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
508ac7ddfbfSEd Maste 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
509ac7ddfbfSEd Maste 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
510ac7ddfbfSEd Maste 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
511ac7ddfbfSEd Maste 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
512ac7ddfbfSEd Maste 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
513ac7ddfbfSEd Maste 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
514ac7ddfbfSEd Maste 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
515ac7ddfbfSEd Maste 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
516ac7ddfbfSEd Maste 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
517ac7ddfbfSEd Maste 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
518ac7ddfbfSEd Maste 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
519ac7ddfbfSEd Maste 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
520ac7ddfbfSEd Maste 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
521ac7ddfbfSEd Maste 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
522ac7ddfbfSEd Maste 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
523ac7ddfbfSEd Maste 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
524ac7ddfbfSEd Maste 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
525ac7ddfbfSEd Maste 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
526ac7ddfbfSEd Maste 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
527ac7ddfbfSEd Maste 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
528ac7ddfbfSEd Maste 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
529435933ddSDimitry Andric 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d};
530ac7ddfbfSEd Maste const uint8_t *p = (const uint8_t *)buf;
531ac7ddfbfSEd Maste
5320127ef0fSEd Maste crc = crc ^ ~0U;
533ac7ddfbfSEd Maste while (size--)
534ac7ddfbfSEd Maste crc = g_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
535ac7ddfbfSEd Maste return crc ^ ~0U;
536ac7ddfbfSEd Maste }
537ac7ddfbfSEd Maste
calc_gnu_debuglink_crc32(const void * buf,size_t size)538435933ddSDimitry Andric static uint32_t calc_gnu_debuglink_crc32(const void *buf, size_t size) {
5390127ef0fSEd Maste return calc_crc32(0U, buf, size);
5400127ef0fSEd Maste }
5410127ef0fSEd Maste
CalculateELFNotesSegmentsCRC32(const ProgramHeaderColl & program_headers,DataExtractor & object_data)542435933ddSDimitry Andric uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32(
543435933ddSDimitry Andric const ProgramHeaderColl &program_headers, DataExtractor &object_data) {
5440127ef0fSEd Maste
5450127ef0fSEd Maste uint32_t core_notes_crc = 0;
5460127ef0fSEd Maste
547*b5893f02SDimitry Andric for (const ELFProgramHeader &H : program_headers) {
548*b5893f02SDimitry Andric if (H.p_type == llvm::ELF::PT_NOTE) {
549*b5893f02SDimitry Andric const elf_off ph_offset = H.p_offset;
550*b5893f02SDimitry Andric const size_t ph_size = H.p_filesz;
5510127ef0fSEd Maste
5520127ef0fSEd Maste DataExtractor segment_data;
553435933ddSDimitry Andric if (segment_data.SetData(object_data, ph_offset, ph_size) != ph_size) {
5544ba319b5SDimitry Andric // The ELF program header contained incorrect data, probably corefile
5554ba319b5SDimitry Andric // is incomplete or corrupted.
5560127ef0fSEd Maste break;
5570127ef0fSEd Maste }
5580127ef0fSEd Maste
559435933ddSDimitry Andric core_notes_crc = calc_crc32(core_notes_crc, segment_data.GetDataStart(),
5600127ef0fSEd Maste segment_data.GetByteSize());
5610127ef0fSEd Maste }
5620127ef0fSEd Maste }
5630127ef0fSEd Maste
5640127ef0fSEd Maste return core_notes_crc;
5650127ef0fSEd Maste }
5660127ef0fSEd Maste
OSABIAsCString(unsigned char osabi_byte)567435933ddSDimitry Andric static const char *OSABIAsCString(unsigned char osabi_byte) {
568435933ddSDimitry Andric #define _MAKE_OSABI_CASE(x) \
569435933ddSDimitry Andric case x: \
570435933ddSDimitry Andric return #x
571435933ddSDimitry Andric switch (osabi_byte) {
5720127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_NONE);
5730127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_HPUX);
5740127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_NETBSD);
5750127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_GNU);
5760127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_HURD);
5770127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_SOLARIS);
5780127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_AIX);
5790127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_IRIX);
5800127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_FREEBSD);
5810127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_TRU64);
5820127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_MODESTO);
5830127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_OPENBSD);
5840127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_OPENVMS);
5850127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_NSK);
5860127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_AROS);
5870127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_FENIXOS);
5880127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_C6000_ELFABI);
5890127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_C6000_LINUX);
5900127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_ARM);
5910127ef0fSEd Maste _MAKE_OSABI_CASE(ELFOSABI_STANDALONE);
5920127ef0fSEd Maste default:
5930127ef0fSEd Maste return "<unknown-osabi>";
5940127ef0fSEd Maste }
5950127ef0fSEd Maste #undef _MAKE_OSABI_CASE
5960127ef0fSEd Maste }
5970127ef0fSEd Maste
5981c3bbb01SEd Maste //
5991c3bbb01SEd Maste // WARNING : This function is being deprecated
6004ba319b5SDimitry Andric // It's functionality has moved to ArchSpec::SetArchitecture This function is
6014ba319b5SDimitry Andric // only being kept to validate the move.
6021c3bbb01SEd Maste //
6031c3bbb01SEd Maste // TODO : Remove this function
GetOsFromOSABI(unsigned char osabi_byte,llvm::Triple::OSType & ostype)604435933ddSDimitry Andric static bool GetOsFromOSABI(unsigned char osabi_byte,
605435933ddSDimitry Andric llvm::Triple::OSType &ostype) {
606435933ddSDimitry Andric switch (osabi_byte) {
607435933ddSDimitry Andric case ELFOSABI_AIX:
608435933ddSDimitry Andric ostype = llvm::Triple::OSType::AIX;
609435933ddSDimitry Andric break;
610435933ddSDimitry Andric case ELFOSABI_FREEBSD:
611435933ddSDimitry Andric ostype = llvm::Triple::OSType::FreeBSD;
612435933ddSDimitry Andric break;
613435933ddSDimitry Andric case ELFOSABI_GNU:
614435933ddSDimitry Andric ostype = llvm::Triple::OSType::Linux;
615435933ddSDimitry Andric break;
616435933ddSDimitry Andric case ELFOSABI_NETBSD:
617435933ddSDimitry Andric ostype = llvm::Triple::OSType::NetBSD;
618435933ddSDimitry Andric break;
619435933ddSDimitry Andric case ELFOSABI_OPENBSD:
620435933ddSDimitry Andric ostype = llvm::Triple::OSType::OpenBSD;
621435933ddSDimitry Andric break;
622435933ddSDimitry Andric case ELFOSABI_SOLARIS:
623435933ddSDimitry Andric ostype = llvm::Triple::OSType::Solaris;
624435933ddSDimitry Andric break;
6250127ef0fSEd Maste default:
6260127ef0fSEd Maste ostype = llvm::Triple::OSType::UnknownOS;
6270127ef0fSEd Maste }
6280127ef0fSEd Maste return ostype != llvm::Triple::OSType::UnknownOS;
6290127ef0fSEd Maste }
6300127ef0fSEd 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)631435933ddSDimitry Andric size_t ObjectFileELF::GetModuleSpecifications(
632435933ddSDimitry Andric const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
633435933ddSDimitry Andric lldb::offset_t data_offset, lldb::offset_t file_offset,
634435933ddSDimitry Andric lldb::offset_t length, lldb_private::ModuleSpecList &specs) {
6350127ef0fSEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
6360127ef0fSEd Maste
637ac7ddfbfSEd Maste const size_t initial_count = specs.GetSize();
638ac7ddfbfSEd Maste
639435933ddSDimitry Andric if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) {
640ac7ddfbfSEd Maste DataExtractor data;
641ac7ddfbfSEd Maste data.SetData(data_sp);
642ac7ddfbfSEd Maste elf::ELFHeader header;
643f678e45dSDimitry Andric lldb::offset_t header_offset = data_offset;
644f678e45dSDimitry Andric if (header.Parse(data, &header_offset)) {
645435933ddSDimitry Andric if (data_sp) {
6461c3bbb01SEd Maste ModuleSpec spec(file);
6470127ef0fSEd Maste
6480127ef0fSEd Maste const uint32_t sub_type = subTypeFromElfHeader(header);
649435933ddSDimitry Andric spec.GetArchitecture().SetArchitecture(
650435933ddSDimitry Andric eArchTypeELF, header.e_machine, sub_type, header.e_ident[EI_OSABI]);
6510127ef0fSEd Maste
652435933ddSDimitry Andric if (spec.GetArchitecture().IsValid()) {
6530127ef0fSEd Maste llvm::Triple::OSType ostype;
6541c3bbb01SEd Maste llvm::Triple::VendorType vendor;
655435933ddSDimitry Andric llvm::Triple::OSType spec_ostype =
656435933ddSDimitry Andric spec.GetArchitecture().GetTriple().getOS();
6570127ef0fSEd Maste
6580127ef0fSEd Maste if (log)
659435933ddSDimitry Andric log->Printf("ObjectFileELF::%s file '%s' module OSABI: %s",
660435933ddSDimitry Andric __FUNCTION__, file.GetPath().c_str(),
661435933ddSDimitry Andric OSABIAsCString(header.e_ident[EI_OSABI]));
6621c3bbb01SEd Maste
6631c3bbb01SEd Maste // SetArchitecture should have set the vendor to unknown
6641c3bbb01SEd Maste vendor = spec.GetArchitecture().GetTriple().getVendor();
6651c3bbb01SEd Maste assert(vendor == llvm::Triple::UnknownVendor);
666f678e45dSDimitry Andric UNUSED_IF_ASSERT_DISABLED(vendor);
6671c3bbb01SEd Maste
6681c3bbb01SEd Maste //
6691c3bbb01SEd Maste // Validate it is ok to remove GetOsFromOSABI
6701c3bbb01SEd Maste GetOsFromOSABI(header.e_ident[EI_OSABI], ostype);
6711c3bbb01SEd Maste assert(spec_ostype == ostype);
672435933ddSDimitry Andric if (spec_ostype != llvm::Triple::OSType::UnknownOS) {
6730127ef0fSEd Maste if (log)
674435933ddSDimitry Andric log->Printf("ObjectFileELF::%s file '%s' set ELF module OS type "
675435933ddSDimitry Andric "from ELF header OSABI.",
676435933ddSDimitry Andric __FUNCTION__, file.GetPath().c_str());
6770127ef0fSEd Maste }
678ac7ddfbfSEd Maste
6794ba319b5SDimitry Andric data_sp = MapFileData(file, -1, file_offset);
680f678e45dSDimitry Andric if (data_sp)
681ac7ddfbfSEd Maste data.SetData(data_sp);
6824ba319b5SDimitry Andric // In case there is header extension in the section #0, the header we
6834ba319b5SDimitry Andric // parsed above could have sentinel values for e_phnum, e_shnum, and
6844ba319b5SDimitry Andric // e_shstrndx. In this case we need to reparse the header with a
6854ba319b5SDimitry Andric // bigger data source to get the actual values.
6864ba319b5SDimitry Andric if (header.HasHeaderExtension()) {
6874ba319b5SDimitry Andric lldb::offset_t header_offset = data_offset;
6884ba319b5SDimitry Andric header.Parse(data, &header_offset);
689ac7ddfbfSEd Maste }
690ac7ddfbfSEd Maste
691ac7ddfbfSEd Maste uint32_t gnu_debuglink_crc = 0;
692ac7ddfbfSEd Maste std::string gnu_debuglink_file;
693ac7ddfbfSEd Maste SectionHeaderColl section_headers;
694ac7ddfbfSEd Maste lldb_private::UUID &uuid = spec.GetUUID();
6950127ef0fSEd Maste
696edd7eaddSDimitry Andric GetSectionHeaderInfo(section_headers, data, header, uuid,
697435933ddSDimitry Andric gnu_debuglink_file, gnu_debuglink_crc,
698435933ddSDimitry Andric spec.GetArchitecture());
6990127ef0fSEd Maste
7000127ef0fSEd Maste llvm::Triple &spec_triple = spec.GetArchitecture().GetTriple();
7010127ef0fSEd Maste
7020127ef0fSEd Maste if (log)
703435933ddSDimitry Andric log->Printf("ObjectFileELF::%s file '%s' module set to triple: %s "
704435933ddSDimitry Andric "(architecture %s)",
705435933ddSDimitry Andric __FUNCTION__, file.GetPath().c_str(),
706435933ddSDimitry Andric spec_triple.getTriple().c_str(),
707435933ddSDimitry Andric spec.GetArchitecture().GetArchitectureName());
708ac7ddfbfSEd Maste
709435933ddSDimitry Andric if (!uuid.IsValid()) {
7100127ef0fSEd Maste uint32_t core_notes_crc = 0;
7110127ef0fSEd Maste
712435933ddSDimitry Andric if (!gnu_debuglink_crc) {
7135517e702SDimitry Andric static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
714435933ddSDimitry Andric lldb_private::Timer scoped_timer(
7155517e702SDimitry Andric func_cat,
7160127ef0fSEd Maste "Calculating module crc32 %s with size %" PRIu64 " KiB",
7170127ef0fSEd Maste file.GetLastPathComponent().AsCString(),
718*b5893f02SDimitry Andric (FileSystem::Instance().GetByteSize(file) - file_offset) /
719*b5893f02SDimitry Andric 1024);
7200127ef0fSEd Maste
721435933ddSDimitry Andric // For core files - which usually don't happen to have a
722f678e45dSDimitry Andric // gnu_debuglink, and are pretty bulky - calculating whole
723f678e45dSDimitry Andric // contents crc32 would be too much of luxury. Thus we will need
724f678e45dSDimitry Andric // to fallback to something simpler.
725435933ddSDimitry Andric if (header.e_type == llvm::ELF::ET_CORE) {
7260127ef0fSEd Maste ProgramHeaderColl program_headers;
727edd7eaddSDimitry Andric GetProgramHeaderInfo(program_headers, data, header);
7280127ef0fSEd Maste
729435933ddSDimitry Andric core_notes_crc =
730435933ddSDimitry Andric CalculateELFNotesSegmentsCRC32(program_headers, data);
731435933ddSDimitry Andric } else {
732435933ddSDimitry Andric gnu_debuglink_crc = calc_gnu_debuglink_crc32(
733435933ddSDimitry Andric data.GetDataStart(), data.GetByteSize());
734ac7ddfbfSEd Maste }
7350127ef0fSEd Maste }
7364ba319b5SDimitry Andric using u32le = llvm::support::ulittle32_t;
737435933ddSDimitry Andric if (gnu_debuglink_crc) {
738ac7ddfbfSEd Maste // Use 4 bytes of crc from the .gnu_debuglink section.
7394ba319b5SDimitry Andric u32le data(gnu_debuglink_crc);
7404ba319b5SDimitry Andric uuid = UUID::fromData(&data, sizeof(data));
741435933ddSDimitry Andric } else if (core_notes_crc) {
742435933ddSDimitry Andric // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make
7434ba319b5SDimitry Andric // it look different form .gnu_debuglink crc followed by 4 bytes
7444ba319b5SDimitry Andric // of note segments crc.
7454ba319b5SDimitry Andric u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)};
7464ba319b5SDimitry Andric uuid = UUID::fromData(data, sizeof(data));
7470127ef0fSEd Maste }
748ac7ddfbfSEd Maste }
749ac7ddfbfSEd Maste
750ac7ddfbfSEd Maste specs.Append(spec);
751ac7ddfbfSEd Maste }
752ac7ddfbfSEd Maste }
753ac7ddfbfSEd Maste }
754ac7ddfbfSEd Maste }
755ac7ddfbfSEd Maste
756ac7ddfbfSEd Maste return specs.GetSize() - initial_count;
757ac7ddfbfSEd Maste }
758ac7ddfbfSEd Maste
759ac7ddfbfSEd Maste //------------------------------------------------------------------
760ac7ddfbfSEd Maste // PluginInterface protocol
761ac7ddfbfSEd Maste //------------------------------------------------------------------
GetPluginName()762435933ddSDimitry Andric lldb_private::ConstString ObjectFileELF::GetPluginName() {
763ac7ddfbfSEd Maste return GetPluginNameStatic();
764ac7ddfbfSEd Maste }
765ac7ddfbfSEd Maste
GetPluginVersion()766435933ddSDimitry Andric uint32_t ObjectFileELF::GetPluginVersion() { return m_plugin_version; }
767ac7ddfbfSEd Maste //------------------------------------------------------------------
768ac7ddfbfSEd Maste // ObjectFile protocol
769ac7ddfbfSEd Maste //------------------------------------------------------------------
770ac7ddfbfSEd 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)771ac7ddfbfSEd Maste ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
772435933ddSDimitry Andric DataBufferSP &data_sp, lldb::offset_t data_offset,
773435933ddSDimitry Andric const FileSpec *file, lldb::offset_t file_offset,
774435933ddSDimitry Andric lldb::offset_t length)
775435933ddSDimitry Andric : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
776435933ddSDimitry Andric m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0),
777435933ddSDimitry Andric m_program_headers(), m_section_headers(), m_dynamic_symbols(),
778435933ddSDimitry Andric m_filespec_ap(), m_entry_point_address(), m_arch_spec() {
779ac7ddfbfSEd Maste if (file)
780ac7ddfbfSEd Maste m_file = *file;
781ac7ddfbfSEd Maste ::memset(&m_header, 0, sizeof(m_header));
7820127ef0fSEd Maste }
7830127ef0fSEd Maste
ObjectFileELF(const lldb::ModuleSP & module_sp,DataBufferSP & header_data_sp,const lldb::ProcessSP & process_sp,addr_t header_addr)7840127ef0fSEd Maste ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp,
7851c3bbb01SEd Maste DataBufferSP &header_data_sp,
7860127ef0fSEd Maste const lldb::ProcessSP &process_sp,
787435933ddSDimitry Andric addr_t header_addr)
788435933ddSDimitry Andric : ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
789435933ddSDimitry Andric m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0),
790435933ddSDimitry Andric m_program_headers(), m_section_headers(), m_dynamic_symbols(),
791435933ddSDimitry Andric m_filespec_ap(), m_entry_point_address(), m_arch_spec() {
7920127ef0fSEd Maste ::memset(&m_header, 0, sizeof(m_header));
793ac7ddfbfSEd Maste }
794ac7ddfbfSEd Maste
~ObjectFileELF()795435933ddSDimitry Andric ObjectFileELF::~ObjectFileELF() {}
796ac7ddfbfSEd Maste
IsExecutable() const797435933ddSDimitry Andric bool ObjectFileELF::IsExecutable() const {
7980127ef0fSEd Maste return ((m_header.e_type & ET_EXEC) != 0) || (m_header.e_entry != 0);
799ac7ddfbfSEd Maste }
800ac7ddfbfSEd Maste
SetLoadAddress(Target & target,lldb::addr_t value,bool value_is_offset)801435933ddSDimitry Andric bool ObjectFileELF::SetLoadAddress(Target &target, lldb::addr_t value,
802435933ddSDimitry Andric bool value_is_offset) {
80312b93ac6SEd Maste ModuleSP module_sp = GetModule();
804435933ddSDimitry Andric if (module_sp) {
80512b93ac6SEd Maste size_t num_loaded_sections = 0;
80612b93ac6SEd Maste SectionList *section_list = GetSectionList();
807435933ddSDimitry Andric if (section_list) {
808435933ddSDimitry Andric if (!value_is_offset) {
809*b5893f02SDimitry Andric addr_t base = GetBaseAddress().GetFileAddress();
810*b5893f02SDimitry Andric if (base == LLDB_INVALID_ADDRESS)
8119f2f44ceSEd Maste return false;
812*b5893f02SDimitry Andric value -= base;
8139f2f44ceSEd Maste }
8149f2f44ceSEd Maste
81512b93ac6SEd Maste const size_t num_sections = section_list->GetSize();
81612b93ac6SEd Maste size_t sect_idx = 0;
81712b93ac6SEd Maste
818435933ddSDimitry Andric for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) {
8194ba319b5SDimitry Andric // Iterate through the object file sections to find all of the sections
8204ba319b5SDimitry Andric // that have SHF_ALLOC in their flag bits.
82112b93ac6SEd Maste SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx));
822*b5893f02SDimitry Andric if (section_sp->Test(SHF_ALLOC) ||
823*b5893f02SDimitry Andric section_sp->GetType() == eSectionTypeContainer) {
8244bb0738eSEd Maste lldb::addr_t load_addr = section_sp->GetFileAddress();
8254bb0738eSEd Maste // We don't want to update the load address of a section with type
826435933ddSDimitry Andric // eSectionTypeAbsoluteAddress as they already have the absolute load
8274ba319b5SDimitry Andric // address already specified
8284bb0738eSEd Maste if (section_sp->GetType() != eSectionTypeAbsoluteAddress)
8294bb0738eSEd Maste load_addr += value;
8301c3bbb01SEd Maste
831435933ddSDimitry Andric // On 32-bit systems the load address have to fit into 4 bytes. The
8324ba319b5SDimitry Andric // rest of the bytes are the overflow from the addition.
8331c3bbb01SEd Maste if (GetAddressByteSize() == 4)
8341c3bbb01SEd Maste load_addr &= 0xFFFFFFFF;
8351c3bbb01SEd Maste
836435933ddSDimitry Andric if (target.GetSectionLoadList().SetSectionLoadAddress(section_sp,
837435933ddSDimitry Andric load_addr))
83812b93ac6SEd Maste ++num_loaded_sections;
83912b93ac6SEd Maste }
84012b93ac6SEd Maste }
84112b93ac6SEd Maste return num_loaded_sections > 0;
84212b93ac6SEd Maste }
84312b93ac6SEd Maste }
8449f2f44ceSEd Maste return false;
84512b93ac6SEd Maste }
84612b93ac6SEd Maste
GetByteOrder() const847435933ddSDimitry Andric ByteOrder ObjectFileELF::GetByteOrder() const {
848ac7ddfbfSEd Maste if (m_header.e_ident[EI_DATA] == ELFDATA2MSB)
849ac7ddfbfSEd Maste return eByteOrderBig;
850ac7ddfbfSEd Maste if (m_header.e_ident[EI_DATA] == ELFDATA2LSB)
851ac7ddfbfSEd Maste return eByteOrderLittle;
852ac7ddfbfSEd Maste return eByteOrderInvalid;
853ac7ddfbfSEd Maste }
854ac7ddfbfSEd Maste
GetAddressByteSize() const855435933ddSDimitry Andric uint32_t ObjectFileELF::GetAddressByteSize() const {
856ac7ddfbfSEd Maste return m_data.GetAddressByteSize();
857ac7ddfbfSEd Maste }
858ac7ddfbfSEd Maste
GetAddressClass(addr_t file_addr)859435933ddSDimitry Andric AddressClass ObjectFileELF::GetAddressClass(addr_t file_addr) {
8609f2f44ceSEd Maste Symtab *symtab = GetSymtab();
8619f2f44ceSEd Maste if (!symtab)
8624ba319b5SDimitry Andric return AddressClass::eUnknown;
8637aa51b79SEd Maste
8644ba319b5SDimitry Andric // The address class is determined based on the symtab. Ask it from the
8654ba319b5SDimitry Andric // object file what contains the symtab information.
8669f2f44ceSEd Maste ObjectFile *symtab_objfile = symtab->GetObjectFile();
8679f2f44ceSEd Maste if (symtab_objfile != nullptr && symtab_objfile != this)
8689f2f44ceSEd Maste return symtab_objfile->GetAddressClass(file_addr);
8699f2f44ceSEd Maste
8709f2f44ceSEd Maste auto res = ObjectFile::GetAddressClass(file_addr);
8714ba319b5SDimitry Andric if (res != AddressClass::eCode)
8727aa51b79SEd Maste return res;
8737aa51b79SEd Maste
8741c3bbb01SEd Maste auto ub = m_address_class_map.upper_bound(file_addr);
875435933ddSDimitry Andric if (ub == m_address_class_map.begin()) {
8764ba319b5SDimitry Andric // No entry in the address class map before the address. Return default
8774ba319b5SDimitry Andric // address class for an address in a code section.
8784ba319b5SDimitry Andric return AddressClass::eCode;
8791c3bbb01SEd Maste }
8807aa51b79SEd Maste
8811c3bbb01SEd Maste // Move iterator to the address class entry preceding address
8821c3bbb01SEd Maste --ub;
8837aa51b79SEd Maste
8841c3bbb01SEd Maste return ub->second;
8857aa51b79SEd Maste }
8867aa51b79SEd Maste
SectionIndex(const SectionHeaderCollIter & I)887435933ddSDimitry Andric size_t ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I) {
888*b5893f02SDimitry Andric return std::distance(m_section_headers.begin(), I);
889ac7ddfbfSEd Maste }
890ac7ddfbfSEd Maste
SectionIndex(const SectionHeaderCollConstIter & I) const891435933ddSDimitry Andric size_t ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const {
892*b5893f02SDimitry Andric return std::distance(m_section_headers.begin(), I);
893ac7ddfbfSEd Maste }
894ac7ddfbfSEd Maste
ParseHeader()895435933ddSDimitry Andric bool ObjectFileELF::ParseHeader() {
896ac7ddfbfSEd Maste lldb::offset_t offset = 0;
897edd7eaddSDimitry Andric return m_header.Parse(m_data, &offset);
898ac7ddfbfSEd Maste }
899ac7ddfbfSEd Maste
GetUUID(lldb_private::UUID * uuid)900435933ddSDimitry Andric bool ObjectFileELF::GetUUID(lldb_private::UUID *uuid) {
901435933ddSDimitry Andric // Need to parse the section list to get the UUIDs, so make sure that's been
902435933ddSDimitry Andric // done.
9030127ef0fSEd Maste if (!ParseSectionHeaders() && GetType() != ObjectFile::eTypeCoreFile)
904ac7ddfbfSEd Maste return false;
905ac7ddfbfSEd Maste
9064ba319b5SDimitry Andric using u32le = llvm::support::ulittle32_t;
907435933ddSDimitry Andric if (m_uuid.IsValid()) {
908ac7ddfbfSEd Maste // We have the full build id uuid.
909ac7ddfbfSEd Maste *uuid = m_uuid;
910ac7ddfbfSEd Maste return true;
911435933ddSDimitry Andric } else if (GetType() == ObjectFile::eTypeCoreFile) {
9120127ef0fSEd Maste uint32_t core_notes_crc = 0;
9130127ef0fSEd Maste
9140127ef0fSEd Maste if (!ParseProgramHeaders())
9150127ef0fSEd Maste return false;
9160127ef0fSEd Maste
9170127ef0fSEd Maste core_notes_crc = CalculateELFNotesSegmentsCRC32(m_program_headers, m_data);
9180127ef0fSEd Maste
919435933ddSDimitry Andric if (core_notes_crc) {
9204ba319b5SDimitry Andric // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it look
9214ba319b5SDimitry Andric // different form .gnu_debuglink crc - followed by 4 bytes of note
9220127ef0fSEd Maste // segments crc.
9234ba319b5SDimitry Andric u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)};
9244ba319b5SDimitry Andric m_uuid = UUID::fromData(data, sizeof(data));
9250127ef0fSEd Maste }
926435933ddSDimitry Andric } else {
927ac7ddfbfSEd Maste if (!m_gnu_debuglink_crc)
928435933ddSDimitry Andric m_gnu_debuglink_crc =
929435933ddSDimitry Andric calc_gnu_debuglink_crc32(m_data.GetDataStart(), m_data.GetByteSize());
930435933ddSDimitry Andric if (m_gnu_debuglink_crc) {
931ac7ddfbfSEd Maste // Use 4 bytes of crc from the .gnu_debuglink section.
9324ba319b5SDimitry Andric u32le data(m_gnu_debuglink_crc);
9334ba319b5SDimitry Andric m_uuid = UUID::fromData(&data, sizeof(data));
934ac7ddfbfSEd Maste }
935ac7ddfbfSEd Maste }
936ac7ddfbfSEd Maste
937435933ddSDimitry Andric if (m_uuid.IsValid()) {
9380127ef0fSEd Maste *uuid = m_uuid;
9390127ef0fSEd Maste return true;
9400127ef0fSEd Maste }
9410127ef0fSEd Maste
942ac7ddfbfSEd Maste return false;
943ac7ddfbfSEd Maste }
944ac7ddfbfSEd Maste
GetDebugSymbolFilePaths()945435933ddSDimitry Andric lldb_private::FileSpecList ObjectFileELF::GetDebugSymbolFilePaths() {
946ac7ddfbfSEd Maste FileSpecList file_spec_list;
947ac7ddfbfSEd Maste
948435933ddSDimitry Andric if (!m_gnu_debuglink_file.empty()) {
949*b5893f02SDimitry Andric FileSpec file_spec(m_gnu_debuglink_file);
950ac7ddfbfSEd Maste file_spec_list.Append(file_spec);
951ac7ddfbfSEd Maste }
952ac7ddfbfSEd Maste return file_spec_list;
953ac7ddfbfSEd Maste }
954ac7ddfbfSEd Maste
GetDependentModules(FileSpecList & files)955435933ddSDimitry Andric uint32_t ObjectFileELF::GetDependentModules(FileSpecList &files) {
956ac7ddfbfSEd Maste size_t num_modules = ParseDependentModules();
957ac7ddfbfSEd Maste uint32_t num_specs = 0;
958ac7ddfbfSEd Maste
959435933ddSDimitry Andric for (unsigned i = 0; i < num_modules; ++i) {
960ac7ddfbfSEd Maste if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i)))
961ac7ddfbfSEd Maste num_specs++;
962ac7ddfbfSEd Maste }
963ac7ddfbfSEd Maste
964ac7ddfbfSEd Maste return num_specs;
965ac7ddfbfSEd Maste }
966ac7ddfbfSEd Maste
GetImageInfoAddress(Target * target)967435933ddSDimitry Andric Address ObjectFileELF::GetImageInfoAddress(Target *target) {
968ac7ddfbfSEd Maste if (!ParseDynamicSymbols())
969ac7ddfbfSEd Maste return Address();
970ac7ddfbfSEd Maste
971ac7ddfbfSEd Maste SectionList *section_list = GetSectionList();
972ac7ddfbfSEd Maste if (!section_list)
973ac7ddfbfSEd Maste return Address();
974ac7ddfbfSEd Maste
975ac7ddfbfSEd Maste // Find the SHT_DYNAMIC (.dynamic) section.
976435933ddSDimitry Andric SectionSP dynsym_section_sp(
977435933ddSDimitry Andric section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true));
978ac7ddfbfSEd Maste if (!dynsym_section_sp)
979ac7ddfbfSEd Maste return Address();
980ac7ddfbfSEd Maste assert(dynsym_section_sp->GetObjectFile() == this);
981ac7ddfbfSEd Maste
982ac7ddfbfSEd Maste user_id_t dynsym_id = dynsym_section_sp->GetID();
983ac7ddfbfSEd Maste const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id);
984ac7ddfbfSEd Maste if (!dynsym_hdr)
985ac7ddfbfSEd Maste return Address();
986ac7ddfbfSEd Maste
987435933ddSDimitry Andric for (size_t i = 0; i < m_dynamic_symbols.size(); ++i) {
988ac7ddfbfSEd Maste ELFDynamic &symbol = m_dynamic_symbols[i];
989ac7ddfbfSEd Maste
990435933ddSDimitry Andric if (symbol.d_tag == DT_DEBUG) {
9914ba319b5SDimitry Andric // Compute the offset as the number of previous entries plus the size of
9924ba319b5SDimitry Andric // d_tag.
993ac7ddfbfSEd Maste addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
994ac7ddfbfSEd Maste return Address(dynsym_section_sp, offset);
995ac7ddfbfSEd Maste }
996435933ddSDimitry Andric // MIPS executables uses DT_MIPS_RLD_MAP_REL to support PIE. DT_MIPS_RLD_MAP
997435933ddSDimitry Andric // exists in non-PIE.
998435933ddSDimitry Andric else if ((symbol.d_tag == DT_MIPS_RLD_MAP ||
999435933ddSDimitry Andric symbol.d_tag == DT_MIPS_RLD_MAP_REL) &&
1000435933ddSDimitry Andric target) {
100135617911SEd Maste addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize();
100235617911SEd Maste addr_t dyn_base = dynsym_section_sp->GetLoadBaseAddress(target);
100335617911SEd Maste if (dyn_base == LLDB_INVALID_ADDRESS)
100435617911SEd Maste return Address();
10059f2f44ceSEd Maste
10065517e702SDimitry Andric Status error;
1007435933ddSDimitry Andric if (symbol.d_tag == DT_MIPS_RLD_MAP) {
10089f2f44ceSEd Maste // DT_MIPS_RLD_MAP tag stores an absolute address of the debug pointer.
10099f2f44ceSEd Maste Address addr;
1010435933ddSDimitry Andric if (target->ReadPointerFromMemory(dyn_base + offset, false, error,
1011435933ddSDimitry Andric addr))
101235617911SEd Maste return addr;
101335617911SEd Maste }
1014435933ddSDimitry Andric if (symbol.d_tag == DT_MIPS_RLD_MAP_REL) {
1015435933ddSDimitry Andric // DT_MIPS_RLD_MAP_REL tag stores the offset to the debug pointer,
1016435933ddSDimitry Andric // relative to the address of the tag.
10179f2f44ceSEd Maste uint64_t rel_offset;
1018435933ddSDimitry Andric rel_offset = target->ReadUnsignedIntegerFromMemory(
1019435933ddSDimitry Andric dyn_base + offset, false, GetAddressByteSize(), UINT64_MAX, error);
1020435933ddSDimitry Andric if (error.Success() && rel_offset != UINT64_MAX) {
10219f2f44ceSEd Maste Address addr;
1022435933ddSDimitry Andric addr_t debug_ptr_address =
1023435933ddSDimitry Andric dyn_base + (offset - GetAddressByteSize()) + rel_offset;
10249f2f44ceSEd Maste addr.SetOffset(debug_ptr_address);
10259f2f44ceSEd Maste return addr;
10269f2f44ceSEd Maste }
10279f2f44ceSEd Maste }
10289f2f44ceSEd Maste }
1029ac7ddfbfSEd Maste }
1030ac7ddfbfSEd Maste
1031ac7ddfbfSEd Maste return Address();
1032ac7ddfbfSEd Maste }
1033ac7ddfbfSEd Maste
GetEntryPointAddress()1034435933ddSDimitry Andric lldb_private::Address ObjectFileELF::GetEntryPointAddress() {
1035ac7ddfbfSEd Maste if (m_entry_point_address.IsValid())
1036ac7ddfbfSEd Maste return m_entry_point_address;
1037ac7ddfbfSEd Maste
1038ac7ddfbfSEd Maste if (!ParseHeader() || !IsExecutable())
1039ac7ddfbfSEd Maste return m_entry_point_address;
1040ac7ddfbfSEd Maste
1041ac7ddfbfSEd Maste SectionList *section_list = GetSectionList();
1042ac7ddfbfSEd Maste addr_t offset = m_header.e_entry;
1043ac7ddfbfSEd Maste
1044ac7ddfbfSEd Maste if (!section_list)
1045ac7ddfbfSEd Maste m_entry_point_address.SetOffset(offset);
1046ac7ddfbfSEd Maste else
1047ac7ddfbfSEd Maste m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list);
1048ac7ddfbfSEd Maste return m_entry_point_address;
1049ac7ddfbfSEd Maste }
1050ac7ddfbfSEd Maste
GetBaseAddress()1051*b5893f02SDimitry Andric Address ObjectFileELF::GetBaseAddress() {
1052*b5893f02SDimitry Andric for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) {
1053*b5893f02SDimitry Andric const ELFProgramHeader &H = EnumPHdr.value();
1054*b5893f02SDimitry Andric if (H.p_type != PT_LOAD)
1055*b5893f02SDimitry Andric continue;
1056*b5893f02SDimitry Andric
1057*b5893f02SDimitry Andric return Address(
1058*b5893f02SDimitry Andric GetSectionList()->FindSectionByID(SegmentID(EnumPHdr.index())), 0);
1059*b5893f02SDimitry Andric }
1060*b5893f02SDimitry Andric return LLDB_INVALID_ADDRESS;
1061*b5893f02SDimitry Andric }
1062*b5893f02SDimitry Andric
1063ac7ddfbfSEd Maste //----------------------------------------------------------------------
1064ac7ddfbfSEd Maste // ParseDependentModules
1065ac7ddfbfSEd Maste //----------------------------------------------------------------------
ParseDependentModules()1066435933ddSDimitry Andric size_t ObjectFileELF::ParseDependentModules() {
1067ac7ddfbfSEd Maste if (m_filespec_ap.get())
1068ac7ddfbfSEd Maste return m_filespec_ap->GetSize();
1069ac7ddfbfSEd Maste
1070ac7ddfbfSEd Maste m_filespec_ap.reset(new FileSpecList());
1071ac7ddfbfSEd Maste
1072ac7ddfbfSEd Maste if (!ParseSectionHeaders())
1073ac7ddfbfSEd Maste return 0;
1074ac7ddfbfSEd Maste
1075ac7ddfbfSEd Maste SectionList *section_list = GetSectionList();
1076ac7ddfbfSEd Maste if (!section_list)
1077ac7ddfbfSEd Maste return 0;
1078ac7ddfbfSEd Maste
1079ac7ddfbfSEd Maste // Find the SHT_DYNAMIC section.
1080435933ddSDimitry Andric Section *dynsym =
1081435933ddSDimitry Andric section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true)
1082435933ddSDimitry Andric .get();
1083ac7ddfbfSEd Maste if (!dynsym)
1084ac7ddfbfSEd Maste return 0;
1085ac7ddfbfSEd Maste assert(dynsym->GetObjectFile() == this);
1086ac7ddfbfSEd Maste
1087ac7ddfbfSEd Maste const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex(dynsym->GetID());
1088ac7ddfbfSEd Maste if (!header)
1089ac7ddfbfSEd Maste return 0;
1090435933ddSDimitry Andric // sh_link: section header index of string table used by entries in the
1091435933ddSDimitry Andric // section.
1092*b5893f02SDimitry Andric Section *dynstr = section_list->FindSectionByID(header->sh_link).get();
1093ac7ddfbfSEd Maste if (!dynstr)
1094ac7ddfbfSEd Maste return 0;
1095ac7ddfbfSEd Maste
1096ac7ddfbfSEd Maste DataExtractor dynsym_data;
1097ac7ddfbfSEd Maste DataExtractor dynstr_data;
1098ac7ddfbfSEd Maste if (ReadSectionData(dynsym, dynsym_data) &&
1099435933ddSDimitry Andric ReadSectionData(dynstr, dynstr_data)) {
1100ac7ddfbfSEd Maste ELFDynamic symbol;
1101ac7ddfbfSEd Maste const lldb::offset_t section_size = dynsym_data.GetByteSize();
1102ac7ddfbfSEd Maste lldb::offset_t offset = 0;
1103ac7ddfbfSEd Maste
1104ac7ddfbfSEd Maste // The only type of entries we are concerned with are tagged DT_NEEDED,
1105ac7ddfbfSEd Maste // yielding the name of a required library.
1106435933ddSDimitry Andric while (offset < section_size) {
1107ac7ddfbfSEd Maste if (!symbol.Parse(dynsym_data, &offset))
1108ac7ddfbfSEd Maste break;
1109ac7ddfbfSEd Maste
1110ac7ddfbfSEd Maste if (symbol.d_tag != DT_NEEDED)
1111ac7ddfbfSEd Maste continue;
1112ac7ddfbfSEd Maste
1113ac7ddfbfSEd Maste uint32_t str_index = static_cast<uint32_t>(symbol.d_val);
1114ac7ddfbfSEd Maste const char *lib_name = dynstr_data.PeekCStr(str_index);
1115*b5893f02SDimitry Andric FileSpec file_spec(lib_name);
1116*b5893f02SDimitry Andric FileSystem::Instance().Resolve(file_spec);
1117*b5893f02SDimitry Andric m_filespec_ap->Append(file_spec);
1118ac7ddfbfSEd Maste }
1119ac7ddfbfSEd Maste }
1120ac7ddfbfSEd Maste
1121ac7ddfbfSEd Maste return m_filespec_ap->GetSize();
1122ac7ddfbfSEd Maste }
1123ac7ddfbfSEd Maste
1124ac7ddfbfSEd Maste //----------------------------------------------------------------------
11250127ef0fSEd Maste // GetProgramHeaderInfo
11260127ef0fSEd Maste //----------------------------------------------------------------------
GetProgramHeaderInfo(ProgramHeaderColl & program_headers,DataExtractor & object_data,const ELFHeader & header)1127435933ddSDimitry Andric size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers,
1128edd7eaddSDimitry Andric DataExtractor &object_data,
1129435933ddSDimitry Andric const ELFHeader &header) {
11300127ef0fSEd Maste // We have already parsed the program headers
11310127ef0fSEd Maste if (!program_headers.empty())
11320127ef0fSEd Maste return program_headers.size();
11330127ef0fSEd Maste
11340127ef0fSEd Maste // If there are no program headers to read we are done.
11350127ef0fSEd Maste if (header.e_phnum == 0)
11360127ef0fSEd Maste return 0;
11370127ef0fSEd Maste
11380127ef0fSEd Maste program_headers.resize(header.e_phnum);
11390127ef0fSEd Maste if (program_headers.size() != header.e_phnum)
11400127ef0fSEd Maste return 0;
11410127ef0fSEd Maste
11420127ef0fSEd Maste const size_t ph_size = header.e_phnum * header.e_phentsize;
11430127ef0fSEd Maste const elf_off ph_offset = header.e_phoff;
11440127ef0fSEd Maste DataExtractor data;
1145edd7eaddSDimitry Andric if (data.SetData(object_data, ph_offset, ph_size) != ph_size)
11460127ef0fSEd Maste return 0;
11470127ef0fSEd Maste
11480127ef0fSEd Maste uint32_t idx;
11490127ef0fSEd Maste lldb::offset_t offset;
1150435933ddSDimitry Andric for (idx = 0, offset = 0; idx < header.e_phnum; ++idx) {
1151*b5893f02SDimitry Andric if (!program_headers[idx].Parse(data, &offset))
11520127ef0fSEd Maste break;
11530127ef0fSEd Maste }
11540127ef0fSEd Maste
11550127ef0fSEd Maste if (idx < program_headers.size())
11560127ef0fSEd Maste program_headers.resize(idx);
11570127ef0fSEd Maste
11580127ef0fSEd Maste return program_headers.size();
11590127ef0fSEd Maste }
11600127ef0fSEd Maste
11610127ef0fSEd Maste //----------------------------------------------------------------------
1162ac7ddfbfSEd Maste // ParseProgramHeaders
1163ac7ddfbfSEd Maste //----------------------------------------------------------------------
ParseProgramHeaders()1164*b5893f02SDimitry Andric bool ObjectFileELF::ParseProgramHeaders() {
1165*b5893f02SDimitry Andric return GetProgramHeaderInfo(m_program_headers, m_data, m_header) != 0;
1166ac7ddfbfSEd Maste }
1167ac7ddfbfSEd Maste
11685517e702SDimitry Andric lldb_private::Status
RefineModuleDetailsFromNote(lldb_private::DataExtractor & data,lldb_private::ArchSpec & arch_spec,lldb_private::UUID & uuid)1169435933ddSDimitry Andric ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data,
1170435933ddSDimitry Andric lldb_private::ArchSpec &arch_spec,
1171435933ddSDimitry Andric lldb_private::UUID &uuid) {
11720127ef0fSEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
11735517e702SDimitry Andric Status error;
11740127ef0fSEd Maste
1175ac7ddfbfSEd Maste lldb::offset_t offset = 0;
1176ac7ddfbfSEd Maste
1177435933ddSDimitry Andric while (true) {
11780127ef0fSEd Maste // Parse the note header. If this fails, bail out.
11799f2f44ceSEd Maste const lldb::offset_t note_offset = offset;
1180b952cd58SEd Maste ELFNote note = ELFNote();
1181435933ddSDimitry Andric if (!note.Parse(data, &offset)) {
11820127ef0fSEd Maste // We're done.
11830127ef0fSEd Maste return error;
11840127ef0fSEd Maste }
11850127ef0fSEd Maste
11860127ef0fSEd Maste if (log)
1187435933ddSDimitry Andric log->Printf("ObjectFileELF::%s parsing note name='%s', type=%" PRIu32,
1188435933ddSDimitry Andric __FUNCTION__, note.n_name.c_str(), note.n_type);
11890127ef0fSEd Maste
11900127ef0fSEd Maste // Process FreeBSD ELF notes.
11910127ef0fSEd Maste if ((note.n_name == LLDB_NT_OWNER_FREEBSD) &&
11920127ef0fSEd Maste (note.n_type == LLDB_NT_FREEBSD_ABI_TAG) &&
1193435933ddSDimitry Andric (note.n_descsz == LLDB_NT_FREEBSD_ABI_SIZE)) {
11940127ef0fSEd Maste // Pull out the min version info.
11950127ef0fSEd Maste uint32_t version_info;
1196435933ddSDimitry Andric if (data.GetU32(&offset, &version_info, 1) == nullptr) {
11970127ef0fSEd Maste error.SetErrorString("failed to read FreeBSD ABI note payload");
11980127ef0fSEd Maste return error;
11990127ef0fSEd Maste }
12000127ef0fSEd Maste
12010127ef0fSEd Maste // Convert the version info into a major/minor number.
12020127ef0fSEd Maste const uint32_t version_major = version_info / 100000;
12030127ef0fSEd Maste const uint32_t version_minor = (version_info / 1000) % 100;
12040127ef0fSEd Maste
12050127ef0fSEd Maste char os_name[32];
1206435933ddSDimitry Andric snprintf(os_name, sizeof(os_name), "freebsd%" PRIu32 ".%" PRIu32,
1207435933ddSDimitry Andric version_major, version_minor);
12080127ef0fSEd Maste
12090127ef0fSEd Maste // Set the elf OS version to FreeBSD. Also clear the vendor.
12100127ef0fSEd Maste arch_spec.GetTriple().setOSName(os_name);
12110127ef0fSEd Maste arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
12120127ef0fSEd Maste
12130127ef0fSEd Maste if (log)
1214435933ddSDimitry Andric log->Printf("ObjectFileELF::%s detected FreeBSD %" PRIu32 ".%" PRIu32
1215435933ddSDimitry Andric ".%" PRIu32,
1216435933ddSDimitry Andric __FUNCTION__, version_major, version_minor,
1217435933ddSDimitry Andric static_cast<uint32_t>(version_info % 1000));
12180127ef0fSEd Maste }
12190127ef0fSEd Maste // Process GNU ELF notes.
1220435933ddSDimitry Andric else if (note.n_name == LLDB_NT_OWNER_GNU) {
1221435933ddSDimitry Andric switch (note.n_type) {
12220127ef0fSEd Maste case LLDB_NT_GNU_ABI_TAG:
1223435933ddSDimitry Andric if (note.n_descsz == LLDB_NT_GNU_ABI_SIZE) {
12240127ef0fSEd Maste // Pull out the min OS version supporting the ABI.
12250127ef0fSEd Maste uint32_t version_info[4];
1226435933ddSDimitry Andric if (data.GetU32(&offset, &version_info[0], note.n_descsz / 4) ==
1227435933ddSDimitry Andric nullptr) {
12280127ef0fSEd Maste error.SetErrorString("failed to read GNU ABI note payload");
12290127ef0fSEd Maste return error;
12300127ef0fSEd Maste }
12310127ef0fSEd Maste
12320127ef0fSEd Maste // Set the OS per the OS field.
1233435933ddSDimitry Andric switch (version_info[0]) {
12340127ef0fSEd Maste case LLDB_NT_GNU_ABI_OS_LINUX:
12350127ef0fSEd Maste arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
1236435933ddSDimitry Andric arch_spec.GetTriple().setVendor(
1237435933ddSDimitry Andric llvm::Triple::VendorType::UnknownVendor);
12380127ef0fSEd Maste if (log)
1239435933ddSDimitry Andric log->Printf(
1240435933ddSDimitry Andric "ObjectFileELF::%s detected Linux, min version %" PRIu32
1241435933ddSDimitry Andric ".%" PRIu32 ".%" PRIu32,
1242435933ddSDimitry Andric __FUNCTION__, version_info[1], version_info[2],
1243435933ddSDimitry Andric version_info[3]);
1244435933ddSDimitry Andric // FIXME we have the minimal version number, we could be propagating
1245435933ddSDimitry Andric // that. version_info[1] = OS Major, version_info[2] = OS Minor,
1246435933ddSDimitry Andric // version_info[3] = Revision.
12470127ef0fSEd Maste break;
12480127ef0fSEd Maste case LLDB_NT_GNU_ABI_OS_HURD:
12490127ef0fSEd Maste arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS);
1250435933ddSDimitry Andric arch_spec.GetTriple().setVendor(
1251435933ddSDimitry Andric llvm::Triple::VendorType::UnknownVendor);
12520127ef0fSEd Maste if (log)
1253435933ddSDimitry Andric log->Printf("ObjectFileELF::%s detected Hurd (unsupported), min "
1254435933ddSDimitry Andric "version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
1255435933ddSDimitry Andric __FUNCTION__, version_info[1], version_info[2],
1256435933ddSDimitry Andric version_info[3]);
12570127ef0fSEd Maste break;
12580127ef0fSEd Maste case LLDB_NT_GNU_ABI_OS_SOLARIS:
12590127ef0fSEd Maste arch_spec.GetTriple().setOS(llvm::Triple::OSType::Solaris);
1260435933ddSDimitry Andric arch_spec.GetTriple().setVendor(
1261435933ddSDimitry Andric llvm::Triple::VendorType::UnknownVendor);
12620127ef0fSEd Maste if (log)
1263435933ddSDimitry Andric log->Printf(
1264435933ddSDimitry Andric "ObjectFileELF::%s detected Solaris, min version %" PRIu32
1265435933ddSDimitry Andric ".%" PRIu32 ".%" PRIu32,
1266435933ddSDimitry Andric __FUNCTION__, version_info[1], version_info[2],
1267435933ddSDimitry Andric version_info[3]);
12680127ef0fSEd Maste break;
12690127ef0fSEd Maste default:
12700127ef0fSEd Maste if (log)
1271435933ddSDimitry Andric log->Printf(
1272435933ddSDimitry Andric "ObjectFileELF::%s unrecognized OS in note, id %" PRIu32
1273435933ddSDimitry Andric ", min version %" PRIu32 ".%" PRIu32 ".%" PRIu32,
1274435933ddSDimitry Andric __FUNCTION__, version_info[0], version_info[1],
1275435933ddSDimitry Andric version_info[2], version_info[3]);
12760127ef0fSEd Maste break;
12770127ef0fSEd Maste }
12780127ef0fSEd Maste }
12790127ef0fSEd Maste break;
12800127ef0fSEd Maste
12810127ef0fSEd Maste case LLDB_NT_GNU_BUILD_ID_TAG:
12820127ef0fSEd Maste // Only bother processing this if we don't already have the uuid set.
1283435933ddSDimitry Andric if (!uuid.IsValid()) {
1284435933ddSDimitry Andric // 16 bytes is UUID|MD5, 20 bytes is SHA1. Other linkers may produce a
12854ba319b5SDimitry Andric // build-id of a different length. Accept it as long as it's at least
12864ba319b5SDimitry Andric // 4 bytes as it will be better than our own crc32.
12874ba319b5SDimitry Andric if (note.n_descsz >= 4) {
12884ba319b5SDimitry Andric if (const uint8_t *buf = data.PeekData(offset, note.n_descsz)) {
12894ba319b5SDimitry Andric // Save the build id as the UUID for the module.
12904ba319b5SDimitry Andric uuid = UUID::fromData(buf, note.n_descsz);
12914ba319b5SDimitry Andric } else {
12920127ef0fSEd Maste error.SetErrorString("failed to read GNU_BUILD_ID note payload");
12930127ef0fSEd Maste return error;
1294ac7ddfbfSEd Maste }
12950127ef0fSEd Maste }
12960127ef0fSEd Maste }
12970127ef0fSEd Maste break;
12980127ef0fSEd Maste }
1299f678e45dSDimitry Andric if (arch_spec.IsMIPS() &&
1300f678e45dSDimitry Andric arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS)
1301f678e45dSDimitry Andric // The note.n_name == LLDB_NT_OWNER_GNU is valid for Linux platform
1302f678e45dSDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
13030127ef0fSEd Maste }
13040127ef0fSEd Maste // Process NetBSD ELF notes.
13050127ef0fSEd Maste else if ((note.n_name == LLDB_NT_OWNER_NETBSD) &&
13060127ef0fSEd Maste (note.n_type == LLDB_NT_NETBSD_ABI_TAG) &&
1307435933ddSDimitry Andric (note.n_descsz == LLDB_NT_NETBSD_ABI_SIZE)) {
13080127ef0fSEd Maste // Pull out the min version info.
13090127ef0fSEd Maste uint32_t version_info;
1310435933ddSDimitry Andric if (data.GetU32(&offset, &version_info, 1) == nullptr) {
13110127ef0fSEd Maste error.SetErrorString("failed to read NetBSD ABI note payload");
13120127ef0fSEd Maste return error;
13130127ef0fSEd Maste }
13140127ef0fSEd Maste
13150127ef0fSEd Maste // Set the elf OS version to NetBSD. Also clear the vendor.
13160127ef0fSEd Maste arch_spec.GetTriple().setOS(llvm::Triple::OSType::NetBSD);
13170127ef0fSEd Maste arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
13180127ef0fSEd Maste
13190127ef0fSEd Maste if (log)
1320435933ddSDimitry Andric log->Printf(
1321435933ddSDimitry Andric "ObjectFileELF::%s detected NetBSD, min version constant %" PRIu32,
1322435933ddSDimitry Andric __FUNCTION__, version_info);
13230127ef0fSEd Maste }
1324f678e45dSDimitry Andric // Process OpenBSD ELF notes.
1325f678e45dSDimitry Andric else if (note.n_name == LLDB_NT_OWNER_OPENBSD) {
1326f678e45dSDimitry Andric // Set the elf OS version to OpenBSD. Also clear the vendor.
1327f678e45dSDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::OpenBSD);
1328f678e45dSDimitry Andric arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor);
1329f678e45dSDimitry Andric }
13300127ef0fSEd Maste // Process CSR kalimba notes
13310127ef0fSEd Maste else if ((note.n_type == LLDB_NT_GNU_ABI_TAG) &&
1332435933ddSDimitry Andric (note.n_name == LLDB_NT_OWNER_CSR)) {
13330127ef0fSEd Maste arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS);
13340127ef0fSEd Maste arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::CSR);
13350127ef0fSEd Maste
13360127ef0fSEd Maste // TODO At some point the description string could be processed.
13374ba319b5SDimitry Andric // It could provide a steer towards the kalimba variant which this ELF
13384ba319b5SDimitry Andric // targets.
1339435933ddSDimitry Andric if (note.n_descsz) {
1340435933ddSDimitry Andric const char *cstr =
1341435933ddSDimitry Andric data.GetCStr(&offset, llvm::alignTo(note.n_descsz, 4));
13420127ef0fSEd Maste (void)cstr;
13430127ef0fSEd Maste }
1344435933ddSDimitry Andric } else if (note.n_name == LLDB_NT_OWNER_ANDROID) {
13451c3bbb01SEd Maste arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
1346435933ddSDimitry Andric arch_spec.GetTriple().setEnvironment(
1347435933ddSDimitry Andric llvm::Triple::EnvironmentType::Android);
1348435933ddSDimitry Andric } else if (note.n_name == LLDB_NT_OWNER_LINUX) {
1349435933ddSDimitry Andric // This is sometimes found in core files and usually contains extended
1350435933ddSDimitry Andric // register info
13519f2f44ceSEd Maste arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
1352435933ddSDimitry Andric } else if (note.n_name == LLDB_NT_OWNER_CORE) {
13534ba319b5SDimitry Andric // Parse the NT_FILE to look for stuff in paths to shared libraries As
13544ba319b5SDimitry Andric // the contents look like this in a 64 bit ELF core file: count =
13554ba319b5SDimitry Andric // 0x000000000000000a (10) page_size = 0x0000000000001000 (4096) Index
13564ba319b5SDimitry Andric // start end file_ofs path =====
13574ba319b5SDimitry Andric // ------------------ ------------------ ------------------
13584ba319b5SDimitry Andric // ------------------------------------- [ 0] 0x0000000000400000
13594ba319b5SDimitry Andric // 0x0000000000401000 0x0000000000000000 /tmp/a.out [ 1]
13604ba319b5SDimitry Andric // 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out [
13614ba319b5SDimitry Andric // 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out
1362435933ddSDimitry Andric // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000
13634ba319b5SDimitry Andric // /lib/x86_64-linux-gnu/libc-2.19.so [ 4] 0x00007fa79cba8000
13644ba319b5SDimitry Andric // 0x00007fa79cda7000 0x00000000000001bb /lib/x86_64-linux-
13654ba319b5SDimitry Andric // gnu/libc-2.19.so [ 5] 0x00007fa79cda7000 0x00007fa79cdab000
13664ba319b5SDimitry Andric // 0x00000000000001ba /lib/x86_64-linux-gnu/libc-2.19.so [ 6]
13674ba319b5SDimitry Andric // 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be /lib/x86_64
13684ba319b5SDimitry Andric // -linux-gnu/libc-2.19.so [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000
13694ba319b5SDimitry Andric // 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so [ 8]
13704ba319b5SDimitry Andric // 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 /lib/x86_64
13714ba319b5SDimitry Andric // -linux-gnu/ld-2.19.so [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000
13724ba319b5SDimitry Andric // 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so In the 32 bit ELFs
13734ba319b5SDimitry Andric // the count, page_size, start, end, file_ofs are uint32_t For reference:
13744ba319b5SDimitry Andric // see readelf source code (in binutils).
1375435933ddSDimitry Andric if (note.n_type == NT_FILE) {
1376435933ddSDimitry Andric uint64_t count = data.GetAddress(&offset);
1377435933ddSDimitry Andric const char *cstr;
1378435933ddSDimitry Andric data.GetAddress(&offset); // Skip page size
1379435933ddSDimitry Andric offset += count * 3 *
1380435933ddSDimitry Andric data.GetAddressByteSize(); // Skip all start/end/file_ofs
1381435933ddSDimitry Andric for (size_t i = 0; i < count; ++i) {
1382435933ddSDimitry Andric cstr = data.GetCStr(&offset);
1383435933ddSDimitry Andric if (cstr == nullptr) {
1384435933ddSDimitry Andric error.SetErrorStringWithFormat("ObjectFileELF::%s trying to read "
1385435933ddSDimitry Andric "at an offset after the end "
1386435933ddSDimitry Andric "(GetCStr returned nullptr)",
1387435933ddSDimitry Andric __FUNCTION__);
1388435933ddSDimitry Andric return error;
1389435933ddSDimitry Andric }
1390435933ddSDimitry Andric llvm::StringRef path(cstr);
1391435933ddSDimitry Andric if (path.contains("/lib/x86_64-linux-gnu") || path.contains("/lib/i386-linux-gnu")) {
13929f2f44ceSEd Maste arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
13939f2f44ceSEd Maste break;
13949f2f44ceSEd Maste }
13959f2f44ceSEd Maste }
1396f678e45dSDimitry Andric if (arch_spec.IsMIPS() &&
1397f678e45dSDimitry Andric arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS)
13984ba319b5SDimitry Andric // In case of MIPSR6, the LLDB_NT_OWNER_GNU note is missing for some
13994ba319b5SDimitry Andric // cases (e.g. compile with -nostdlib) Hence set OS to Linux
1400f678e45dSDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux);
14019f2f44ceSEd Maste }
14029f2f44ceSEd Maste }
14030127ef0fSEd Maste
14044ba319b5SDimitry Andric // Calculate the offset of the next note just in case "offset" has been
14054ba319b5SDimitry Andric // used to poke at the contents of the note data
14069f2f44ceSEd Maste offset = note_offset + note.GetByteSize();
1407ac7ddfbfSEd Maste }
14080127ef0fSEd Maste
14090127ef0fSEd Maste return error;
1410ac7ddfbfSEd Maste }
1411ac7ddfbfSEd Maste
ParseARMAttributes(DataExtractor & data,uint64_t length,ArchSpec & arch_spec)1412435933ddSDimitry Andric void ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length,
1413435933ddSDimitry Andric ArchSpec &arch_spec) {
14144bb0738eSEd Maste lldb::offset_t Offset = 0;
14154bb0738eSEd Maste
14164bb0738eSEd Maste uint8_t FormatVersion = data.GetU8(&Offset);
14174bb0738eSEd Maste if (FormatVersion != llvm::ARMBuildAttrs::Format_Version)
14184bb0738eSEd Maste return;
14194bb0738eSEd Maste
14204bb0738eSEd Maste Offset = Offset + sizeof(uint32_t); // Section Length
14214bb0738eSEd Maste llvm::StringRef VendorName = data.GetCStr(&Offset);
14224bb0738eSEd Maste
14234bb0738eSEd Maste if (VendorName != "aeabi")
14244bb0738eSEd Maste return;
14254bb0738eSEd Maste
1426435933ddSDimitry Andric if (arch_spec.GetTriple().getEnvironment() ==
1427435933ddSDimitry Andric llvm::Triple::UnknownEnvironment)
14284bb0738eSEd Maste arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI);
14294bb0738eSEd Maste
1430435933ddSDimitry Andric while (Offset < length) {
14314bb0738eSEd Maste uint8_t Tag = data.GetU8(&Offset);
14324bb0738eSEd Maste uint32_t Size = data.GetU32(&Offset);
14334bb0738eSEd Maste
14344bb0738eSEd Maste if (Tag != llvm::ARMBuildAttrs::File || Size == 0)
14354bb0738eSEd Maste continue;
14364bb0738eSEd Maste
1437435933ddSDimitry Andric while (Offset < length) {
14384bb0738eSEd Maste uint64_t Tag = data.GetULEB128(&Offset);
1439435933ddSDimitry Andric switch (Tag) {
14404bb0738eSEd Maste default:
14414bb0738eSEd Maste if (Tag < 32)
14424bb0738eSEd Maste data.GetULEB128(&Offset);
14434bb0738eSEd Maste else if (Tag % 2 == 0)
14444bb0738eSEd Maste data.GetULEB128(&Offset);
14454bb0738eSEd Maste else
14464bb0738eSEd Maste data.GetCStr(&Offset);
14474bb0738eSEd Maste
14484bb0738eSEd Maste break;
14494bb0738eSEd Maste
14504bb0738eSEd Maste case llvm::ARMBuildAttrs::CPU_raw_name:
14514bb0738eSEd Maste case llvm::ARMBuildAttrs::CPU_name:
14524bb0738eSEd Maste data.GetCStr(&Offset);
14534bb0738eSEd Maste
14544bb0738eSEd Maste break;
14554bb0738eSEd Maste
1456435933ddSDimitry Andric case llvm::ARMBuildAttrs::ABI_VFP_args: {
14574bb0738eSEd Maste uint64_t VFPArgs = data.GetULEB128(&Offset);
14584bb0738eSEd Maste
1459435933ddSDimitry Andric if (VFPArgs == llvm::ARMBuildAttrs::BaseAAPCS) {
1460435933ddSDimitry Andric if (arch_spec.GetTriple().getEnvironment() ==
1461435933ddSDimitry Andric llvm::Triple::UnknownEnvironment ||
14624bb0738eSEd Maste arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABIHF)
14634bb0738eSEd Maste arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI);
14644bb0738eSEd Maste
14654bb0738eSEd Maste arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float);
1466435933ddSDimitry Andric } else if (VFPArgs == llvm::ARMBuildAttrs::HardFPAAPCS) {
1467435933ddSDimitry Andric if (arch_spec.GetTriple().getEnvironment() ==
1468435933ddSDimitry Andric llvm::Triple::UnknownEnvironment ||
14694bb0738eSEd Maste arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABI)
14704bb0738eSEd Maste arch_spec.GetTriple().setEnvironment(llvm::Triple::EABIHF);
14714bb0738eSEd Maste
14724bb0738eSEd Maste arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float);
14734bb0738eSEd Maste }
14744bb0738eSEd Maste
14754bb0738eSEd Maste break;
14764bb0738eSEd Maste }
14774bb0738eSEd Maste }
14784bb0738eSEd Maste }
14794bb0738eSEd Maste }
14804bb0738eSEd Maste }
14810127ef0fSEd Maste
1482ac7ddfbfSEd Maste //----------------------------------------------------------------------
1483ac7ddfbfSEd Maste // GetSectionHeaderInfo
1484ac7ddfbfSEd Maste //----------------------------------------------------------------------
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)1485435933ddSDimitry Andric size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers,
1486edd7eaddSDimitry Andric DataExtractor &object_data,
1487ac7ddfbfSEd Maste const elf::ELFHeader &header,
1488ac7ddfbfSEd Maste lldb_private::UUID &uuid,
1489ac7ddfbfSEd Maste std::string &gnu_debuglink_file,
14900127ef0fSEd Maste uint32_t &gnu_debuglink_crc,
1491435933ddSDimitry Andric ArchSpec &arch_spec) {
14920127ef0fSEd Maste // Don't reparse the section headers if we already did that.
1493ac7ddfbfSEd Maste if (!section_headers.empty())
1494ac7ddfbfSEd Maste return section_headers.size();
1495ac7ddfbfSEd Maste
14960127ef0fSEd Maste // Only initialize the arch_spec to okay defaults if they're not already set.
14970127ef0fSEd Maste // We'll refine this with note data as we parse the notes.
1498435933ddSDimitry Andric if (arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) {
14991c3bbb01SEd Maste llvm::Triple::OSType ostype;
15001c3bbb01SEd Maste llvm::Triple::OSType spec_ostype;
15010127ef0fSEd Maste const uint32_t sub_type = subTypeFromElfHeader(header);
1502435933ddSDimitry Andric arch_spec.SetArchitecture(eArchTypeELF, header.e_machine, sub_type,
1503435933ddSDimitry Andric header.e_ident[EI_OSABI]);
1504435933ddSDimitry Andric
15054ba319b5SDimitry Andric // Validate if it is ok to remove GetOsFromOSABI. Note, that now the OS is
15064ba319b5SDimitry Andric // determined based on EI_OSABI flag and the info extracted from ELF notes
15074ba319b5SDimitry Andric // (see RefineModuleDetailsFromNote). However in some cases that still
15084ba319b5SDimitry Andric // might be not enough: for example a shared library might not have any
15094ba319b5SDimitry Andric // notes at all and have EI_OSABI flag set to System V, as result the OS
15104ba319b5SDimitry Andric // will be set to UnknownOS.
15111c3bbb01SEd Maste GetOsFromOSABI(header.e_ident[EI_OSABI], ostype);
15121c3bbb01SEd Maste spec_ostype = arch_spec.GetTriple().getOS();
15131c3bbb01SEd Maste assert(spec_ostype == ostype);
1514f678e45dSDimitry Andric UNUSED_IF_ASSERT_DISABLED(spec_ostype);
15150127ef0fSEd Maste }
15160127ef0fSEd Maste
1517435933ddSDimitry Andric if (arch_spec.GetMachine() == llvm::Triple::mips ||
1518435933ddSDimitry Andric arch_spec.GetMachine() == llvm::Triple::mipsel ||
1519435933ddSDimitry Andric arch_spec.GetMachine() == llvm::Triple::mips64 ||
1520435933ddSDimitry Andric arch_spec.GetMachine() == llvm::Triple::mips64el) {
1521435933ddSDimitry Andric switch (header.e_flags & llvm::ELF::EF_MIPS_ARCH_ASE) {
1522b6c25e0eSDimitry Andric case llvm::ELF::EF_MIPS_MICROMIPS:
1523b6c25e0eSDimitry Andric arch_spec.SetFlags(ArchSpec::eMIPSAse_micromips);
1524b6c25e0eSDimitry Andric break;
1525b6c25e0eSDimitry Andric case llvm::ELF::EF_MIPS_ARCH_ASE_M16:
1526b6c25e0eSDimitry Andric arch_spec.SetFlags(ArchSpec::eMIPSAse_mips16);
1527b6c25e0eSDimitry Andric break;
1528b6c25e0eSDimitry Andric case llvm::ELF::EF_MIPS_ARCH_ASE_MDMX:
1529b6c25e0eSDimitry Andric arch_spec.SetFlags(ArchSpec::eMIPSAse_mdmx);
1530b6c25e0eSDimitry Andric break;
1531b6c25e0eSDimitry Andric default:
1532b6c25e0eSDimitry Andric break;
1533b6c25e0eSDimitry Andric }
1534b6c25e0eSDimitry Andric }
1535b6c25e0eSDimitry Andric
15364bb0738eSEd Maste if (arch_spec.GetMachine() == llvm::Triple::arm ||
1537435933ddSDimitry Andric arch_spec.GetMachine() == llvm::Triple::thumb) {
15384bb0738eSEd Maste if (header.e_flags & llvm::ELF::EF_ARM_SOFT_FLOAT)
15394bb0738eSEd Maste arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float);
15404bb0738eSEd Maste else if (header.e_flags & llvm::ELF::EF_ARM_VFP_FLOAT)
15414bb0738eSEd Maste arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float);
15424bb0738eSEd Maste }
15434bb0738eSEd Maste
1544ac7ddfbfSEd Maste // If there are no section headers we are done.
1545435933ddSDimitry Andric if (header.e_shnum == 0)
1546ac7ddfbfSEd Maste return 0;
1547ac7ddfbfSEd Maste
15480127ef0fSEd Maste Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES));
15490127ef0fSEd Maste
1550ac7ddfbfSEd Maste section_headers.resize(header.e_shnum);
1551ac7ddfbfSEd Maste if (section_headers.size() != header.e_shnum)
1552ac7ddfbfSEd Maste return 0;
1553ac7ddfbfSEd Maste
1554ac7ddfbfSEd Maste const size_t sh_size = header.e_shnum * header.e_shentsize;
1555ac7ddfbfSEd Maste const elf_off sh_offset = header.e_shoff;
1556ac7ddfbfSEd Maste DataExtractor sh_data;
1557edd7eaddSDimitry Andric if (sh_data.SetData(object_data, sh_offset, sh_size) != sh_size)
1558ac7ddfbfSEd Maste return 0;
1559ac7ddfbfSEd Maste
1560ac7ddfbfSEd Maste uint32_t idx;
1561ac7ddfbfSEd Maste lldb::offset_t offset;
1562435933ddSDimitry Andric for (idx = 0, offset = 0; idx < header.e_shnum; ++idx) {
1563*b5893f02SDimitry Andric if (!section_headers[idx].Parse(sh_data, &offset))
1564ac7ddfbfSEd Maste break;
1565ac7ddfbfSEd Maste }
1566ac7ddfbfSEd Maste if (idx < section_headers.size())
1567ac7ddfbfSEd Maste section_headers.resize(idx);
1568ac7ddfbfSEd Maste
1569ac7ddfbfSEd Maste const unsigned strtab_idx = header.e_shstrndx;
1570435933ddSDimitry Andric if (strtab_idx && strtab_idx < section_headers.size()) {
1571ac7ddfbfSEd Maste const ELFSectionHeaderInfo &sheader = section_headers[strtab_idx];
1572ac7ddfbfSEd Maste const size_t byte_size = sheader.sh_size;
1573ac7ddfbfSEd Maste const Elf64_Off offset = sheader.sh_offset;
1574ac7ddfbfSEd Maste lldb_private::DataExtractor shstr_data;
1575ac7ddfbfSEd Maste
1576edd7eaddSDimitry Andric if (shstr_data.SetData(object_data, offset, byte_size) == byte_size) {
1577ac7ddfbfSEd Maste for (SectionHeaderCollIter I = section_headers.begin();
1578435933ddSDimitry Andric I != section_headers.end(); ++I) {
1579ac7ddfbfSEd Maste static ConstString g_sect_name_gnu_debuglink(".gnu_debuglink");
15809f2f44ceSEd Maste const ELFSectionHeaderInfo &sheader = *I;
1581435933ddSDimitry Andric const uint64_t section_size =
1582435933ddSDimitry Andric sheader.sh_type == SHT_NOBITS ? 0 : sheader.sh_size;
1583ac7ddfbfSEd Maste ConstString name(shstr_data.PeekCStr(I->sh_name));
1584ac7ddfbfSEd Maste
1585ac7ddfbfSEd Maste I->section_name = name;
1586ac7ddfbfSEd Maste
1587435933ddSDimitry Andric if (arch_spec.IsMIPS()) {
15889f2f44ceSEd Maste uint32_t arch_flags = arch_spec.GetFlags();
1589b6c25e0eSDimitry Andric DataExtractor data;
1590435933ddSDimitry Andric if (sheader.sh_type == SHT_MIPS_ABIFLAGS) {
15919f2f44ceSEd Maste
1592edd7eaddSDimitry Andric if (section_size && (data.SetData(object_data, sheader.sh_offset,
1593435933ddSDimitry Andric section_size) == section_size)) {
15944bb0738eSEd Maste // MIPS ASE Mask is at offset 12 in MIPS.abiflags section
15954bb0738eSEd Maste lldb::offset_t offset = 12; // MIPS ABI Flags Version: 0
15964bb0738eSEd Maste arch_flags |= data.GetU32(&offset);
15974bb0738eSEd Maste
15984bb0738eSEd Maste // The floating point ABI is at offset 7
15994bb0738eSEd Maste offset = 7;
1600435933ddSDimitry Andric switch (data.GetU8(&offset)) {
16014bb0738eSEd Maste case llvm::Mips::Val_GNU_MIPS_ABI_FP_ANY:
16024bb0738eSEd Maste arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_ANY;
16034bb0738eSEd Maste break;
16044bb0738eSEd Maste case llvm::Mips::Val_GNU_MIPS_ABI_FP_DOUBLE:
16054bb0738eSEd Maste arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_DOUBLE;
16064bb0738eSEd Maste break;
16074bb0738eSEd Maste case llvm::Mips::Val_GNU_MIPS_ABI_FP_SINGLE:
16084bb0738eSEd Maste arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SINGLE;
16094bb0738eSEd Maste break;
16104bb0738eSEd Maste case llvm::Mips::Val_GNU_MIPS_ABI_FP_SOFT:
16114bb0738eSEd Maste arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT;
16124bb0738eSEd Maste break;
16134bb0738eSEd Maste case llvm::Mips::Val_GNU_MIPS_ABI_FP_OLD_64:
16144bb0738eSEd Maste arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_OLD_64;
16154bb0738eSEd Maste break;
16164bb0738eSEd Maste case llvm::Mips::Val_GNU_MIPS_ABI_FP_XX:
16174bb0738eSEd Maste arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_XX;
16184bb0738eSEd Maste break;
16194bb0738eSEd Maste case llvm::Mips::Val_GNU_MIPS_ABI_FP_64:
16204bb0738eSEd Maste arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64;
16214bb0738eSEd Maste break;
16224bb0738eSEd Maste case llvm::Mips::Val_GNU_MIPS_ABI_FP_64A:
16234bb0738eSEd Maste arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64A;
16244bb0738eSEd Maste break;
16254bb0738eSEd Maste }
16269f2f44ceSEd Maste }
16279f2f44ceSEd Maste }
16289f2f44ceSEd Maste // Settings appropriate ArchSpec ABI Flags
1629435933ddSDimitry Andric switch (header.e_flags & llvm::ELF::EF_MIPS_ABI) {
16304bb0738eSEd Maste case llvm::ELF::EF_MIPS_ABI_O32:
16319f2f44ceSEd Maste arch_flags |= lldb_private::ArchSpec::eMIPSABI_O32;
16324bb0738eSEd Maste break;
16334bb0738eSEd Maste case EF_MIPS_ABI_O64:
16344bb0738eSEd Maste arch_flags |= lldb_private::ArchSpec::eMIPSABI_O64;
16354bb0738eSEd Maste break;
16364bb0738eSEd Maste case EF_MIPS_ABI_EABI32:
16374bb0738eSEd Maste arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI32;
16384bb0738eSEd Maste break;
16394bb0738eSEd Maste case EF_MIPS_ABI_EABI64:
16404bb0738eSEd Maste arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI64;
16414bb0738eSEd Maste break;
16424bb0738eSEd Maste default:
16434bb0738eSEd Maste // ABI Mask doesn't cover N32 and N64 ABI.
16444bb0738eSEd Maste if (header.e_ident[EI_CLASS] == llvm::ELF::ELFCLASS64)
16454bb0738eSEd Maste arch_flags |= lldb_private::ArchSpec::eMIPSABI_N64;
1646edd7eaddSDimitry Andric else if (header.e_flags & llvm::ELF::EF_MIPS_ABI2)
16474bb0738eSEd Maste arch_flags |= lldb_private::ArchSpec::eMIPSABI_N32;
16484bb0738eSEd Maste break;
16499f2f44ceSEd Maste }
1650b6c25e0eSDimitry Andric arch_spec.SetFlags(arch_flags);
1651b6c25e0eSDimitry Andric }
1652b6c25e0eSDimitry Andric
1653435933ddSDimitry Andric if (arch_spec.GetMachine() == llvm::Triple::arm ||
1654435933ddSDimitry Andric arch_spec.GetMachine() == llvm::Triple::thumb) {
16554bb0738eSEd Maste DataExtractor data;
16564bb0738eSEd Maste
16574bb0738eSEd Maste if (sheader.sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 &&
1658edd7eaddSDimitry Andric data.SetData(object_data, sheader.sh_offset, section_size) == section_size)
16594bb0738eSEd Maste ParseARMAttributes(data, section_size, arch_spec);
16604bb0738eSEd Maste }
16614bb0738eSEd Maste
1662435933ddSDimitry Andric if (name == g_sect_name_gnu_debuglink) {
1663ac7ddfbfSEd Maste DataExtractor data;
1664edd7eaddSDimitry Andric if (section_size && (data.SetData(object_data, sheader.sh_offset,
1665435933ddSDimitry Andric section_size) == section_size)) {
1666ac7ddfbfSEd Maste lldb::offset_t gnu_debuglink_offset = 0;
1667ac7ddfbfSEd Maste gnu_debuglink_file = data.GetCStr(&gnu_debuglink_offset);
16684bb0738eSEd Maste gnu_debuglink_offset = llvm::alignTo(gnu_debuglink_offset, 4);
1669ac7ddfbfSEd Maste data.GetU32(&gnu_debuglink_offset, &gnu_debuglink_crc, 1);
1670ac7ddfbfSEd Maste }
1671ac7ddfbfSEd Maste }
1672ac7ddfbfSEd Maste
16730127ef0fSEd Maste // Process ELF note section entries.
16749f2f44ceSEd Maste bool is_note_header = (sheader.sh_type == SHT_NOTE);
16751c3bbb01SEd Maste
16761c3bbb01SEd Maste // The section header ".note.android.ident" is stored as a
16771c3bbb01SEd Maste // PROGBITS type header but it is actually a note header.
16781c3bbb01SEd Maste static ConstString g_sect_name_android_ident(".note.android.ident");
16791c3bbb01SEd Maste if (!is_note_header && name == g_sect_name_android_ident)
16801c3bbb01SEd Maste is_note_header = true;
16811c3bbb01SEd Maste
1682435933ddSDimitry Andric if (is_note_header) {
16830127ef0fSEd Maste // Allow notes to refine module info.
1684ac7ddfbfSEd Maste DataExtractor data;
1685edd7eaddSDimitry Andric if (section_size && (data.SetData(object_data, sheader.sh_offset,
1686435933ddSDimitry Andric section_size) == section_size)) {
16875517e702SDimitry Andric Status error = RefineModuleDetailsFromNote(data, arch_spec, uuid);
1688435933ddSDimitry Andric if (error.Fail()) {
16890127ef0fSEd Maste if (log)
1690435933ddSDimitry Andric log->Printf("ObjectFileELF::%s ELF note processing failed: %s",
1691435933ddSDimitry Andric __FUNCTION__, error.AsCString());
16920127ef0fSEd Maste }
1693ac7ddfbfSEd Maste }
1694ac7ddfbfSEd Maste }
1695ac7ddfbfSEd Maste }
1696ac7ddfbfSEd Maste
16979f2f44ceSEd Maste // Make any unknown triple components to be unspecified unknowns.
16989f2f44ceSEd Maste if (arch_spec.GetTriple().getVendor() == llvm::Triple::UnknownVendor)
16999f2f44ceSEd Maste arch_spec.GetTriple().setVendorName(llvm::StringRef());
17009f2f44ceSEd Maste if (arch_spec.GetTriple().getOS() == llvm::Triple::UnknownOS)
17019f2f44ceSEd Maste arch_spec.GetTriple().setOSName(llvm::StringRef());
17029f2f44ceSEd Maste
1703ac7ddfbfSEd Maste return section_headers.size();
1704ac7ddfbfSEd Maste }
1705ac7ddfbfSEd Maste }
1706ac7ddfbfSEd Maste
1707ac7ddfbfSEd Maste section_headers.clear();
1708ac7ddfbfSEd Maste return 0;
1709ac7ddfbfSEd Maste }
1710ac7ddfbfSEd Maste
1711f37b6182SDimitry Andric llvm::StringRef
StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const1712435933ddSDimitry Andric ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const {
1713b91a7dfcSDimitry Andric size_t pos = symbol_name.find('@');
1714f37b6182SDimitry Andric return symbol_name.substr(0, pos);
17151c3bbb01SEd Maste }
17161c3bbb01SEd Maste
1717ac7ddfbfSEd Maste //----------------------------------------------------------------------
1718ac7ddfbfSEd Maste // ParseSectionHeaders
1719ac7ddfbfSEd Maste //----------------------------------------------------------------------
ParseSectionHeaders()1720435933ddSDimitry Andric size_t ObjectFileELF::ParseSectionHeaders() {
1721edd7eaddSDimitry Andric return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid,
1722edd7eaddSDimitry Andric m_gnu_debuglink_file, m_gnu_debuglink_crc,
1723edd7eaddSDimitry Andric m_arch_spec);
1724ac7ddfbfSEd Maste }
1725ac7ddfbfSEd Maste
1726ac7ddfbfSEd Maste const ObjectFileELF::ELFSectionHeaderInfo *
GetSectionHeaderByIndex(lldb::user_id_t id)1727435933ddSDimitry Andric ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) {
1728*b5893f02SDimitry Andric if (!ParseSectionHeaders())
1729ac7ddfbfSEd Maste return NULL;
1730ac7ddfbfSEd Maste
1731*b5893f02SDimitry Andric if (id < m_section_headers.size())
1732ac7ddfbfSEd Maste return &m_section_headers[id];
1733ac7ddfbfSEd Maste
1734ac7ddfbfSEd Maste return NULL;
1735ac7ddfbfSEd Maste }
1736ac7ddfbfSEd Maste
GetSectionIndexByName(const char * name)1737435933ddSDimitry Andric lldb::user_id_t ObjectFileELF::GetSectionIndexByName(const char *name) {
17381c3bbb01SEd Maste if (!name || !name[0] || !ParseSectionHeaders())
17391c3bbb01SEd Maste return 0;
17401c3bbb01SEd Maste for (size_t i = 1; i < m_section_headers.size(); ++i)
17411c3bbb01SEd Maste if (m_section_headers[i].section_name == ConstString(name))
17421c3bbb01SEd Maste return i;
17431c3bbb01SEd Maste return 0;
17441c3bbb01SEd Maste }
17451c3bbb01SEd Maste
GetSectionTypeFromName(llvm::StringRef Name)1746*b5893f02SDimitry Andric static SectionType GetSectionTypeFromName(llvm::StringRef Name) {
1747*b5893f02SDimitry Andric return llvm::StringSwitch<SectionType>(Name)
1748*b5893f02SDimitry Andric .Case(".ARM.exidx", eSectionTypeARMexidx)
1749*b5893f02SDimitry Andric .Case(".ARM.extab", eSectionTypeARMextab)
1750*b5893f02SDimitry Andric .Cases(".bss", ".tbss", eSectionTypeZeroFill)
1751*b5893f02SDimitry Andric .Cases(".data", ".tdata", eSectionTypeData)
1752*b5893f02SDimitry Andric .Case(".debug_abbrev", eSectionTypeDWARFDebugAbbrev)
1753*b5893f02SDimitry Andric .Case(".debug_abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo)
1754*b5893f02SDimitry Andric .Case(".debug_addr", eSectionTypeDWARFDebugAddr)
1755*b5893f02SDimitry Andric .Case(".debug_aranges", eSectionTypeDWARFDebugAranges)
1756*b5893f02SDimitry Andric .Case(".debug_cu_index", eSectionTypeDWARFDebugCuIndex)
1757*b5893f02SDimitry Andric .Case(".debug_frame", eSectionTypeDWARFDebugFrame)
1758*b5893f02SDimitry Andric .Case(".debug_info", eSectionTypeDWARFDebugInfo)
1759*b5893f02SDimitry Andric .Case(".debug_info.dwo", eSectionTypeDWARFDebugInfoDwo)
1760*b5893f02SDimitry Andric .Cases(".debug_line", ".debug_line.dwo", eSectionTypeDWARFDebugLine)
1761*b5893f02SDimitry Andric .Cases(".debug_line_str", ".debug_line_str.dwo",
1762*b5893f02SDimitry Andric eSectionTypeDWARFDebugLineStr)
1763*b5893f02SDimitry Andric .Cases(".debug_loc", ".debug_loc.dwo", eSectionTypeDWARFDebugLoc)
1764*b5893f02SDimitry Andric .Cases(".debug_loclists", ".debug_loclists.dwo",
1765*b5893f02SDimitry Andric eSectionTypeDWARFDebugLocLists)
1766*b5893f02SDimitry Andric .Case(".debug_macinfo", eSectionTypeDWARFDebugMacInfo)
1767*b5893f02SDimitry Andric .Cases(".debug_macro", ".debug_macro.dwo", eSectionTypeDWARFDebugMacro)
1768*b5893f02SDimitry Andric .Case(".debug_names", eSectionTypeDWARFDebugNames)
1769*b5893f02SDimitry Andric .Case(".debug_pubnames", eSectionTypeDWARFDebugPubNames)
1770*b5893f02SDimitry Andric .Case(".debug_pubtypes", eSectionTypeDWARFDebugPubTypes)
1771*b5893f02SDimitry Andric .Case(".debug_ranges", eSectionTypeDWARFDebugRanges)
1772*b5893f02SDimitry Andric .Case(".debug_rnglists", eSectionTypeDWARFDebugRngLists)
1773*b5893f02SDimitry Andric .Case(".debug_str", eSectionTypeDWARFDebugStr)
1774*b5893f02SDimitry Andric .Case(".debug_str.dwo", eSectionTypeDWARFDebugStrDwo)
1775*b5893f02SDimitry Andric .Case(".debug_str_offsets", eSectionTypeDWARFDebugStrOffsets)
1776*b5893f02SDimitry Andric .Case(".debug_str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo)
1777*b5893f02SDimitry Andric .Case(".debug_types", eSectionTypeDWARFDebugTypes)
1778*b5893f02SDimitry Andric .Case(".eh_frame", eSectionTypeEHFrame)
1779*b5893f02SDimitry Andric .Case(".gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink)
1780*b5893f02SDimitry Andric .Case(".gosymtab", eSectionTypeGoSymtab)
1781*b5893f02SDimitry Andric .Case(".text", eSectionTypeCode)
1782*b5893f02SDimitry Andric .Default(eSectionTypeOther);
1783*b5893f02SDimitry Andric }
1784*b5893f02SDimitry Andric
GetSectionType(const ELFSectionHeaderInfo & H) const1785*b5893f02SDimitry Andric SectionType ObjectFileELF::GetSectionType(const ELFSectionHeaderInfo &H) const {
1786*b5893f02SDimitry Andric switch (H.sh_type) {
1787*b5893f02SDimitry Andric case SHT_PROGBITS:
1788*b5893f02SDimitry Andric if (H.sh_flags & SHF_EXECINSTR)
1789*b5893f02SDimitry Andric return eSectionTypeCode;
1790*b5893f02SDimitry Andric break;
1791*b5893f02SDimitry Andric case SHT_SYMTAB:
1792*b5893f02SDimitry Andric return eSectionTypeELFSymbolTable;
1793*b5893f02SDimitry Andric case SHT_DYNSYM:
1794*b5893f02SDimitry Andric return eSectionTypeELFDynamicSymbols;
1795*b5893f02SDimitry Andric case SHT_RELA:
1796*b5893f02SDimitry Andric case SHT_REL:
1797*b5893f02SDimitry Andric return eSectionTypeELFRelocationEntries;
1798*b5893f02SDimitry Andric case SHT_DYNAMIC:
1799*b5893f02SDimitry Andric return eSectionTypeELFDynamicLinkInfo;
1800*b5893f02SDimitry Andric }
1801*b5893f02SDimitry Andric SectionType Type = GetSectionTypeFromName(H.section_name.GetStringRef());
1802*b5893f02SDimitry Andric if (Type == eSectionTypeOther) {
1803*b5893f02SDimitry Andric // the kalimba toolchain assumes that ELF section names are free-form.
1804*b5893f02SDimitry Andric // It does support linkscripts which (can) give rise to various
1805*b5893f02SDimitry Andric // arbitrarily named sections being "Code" or "Data".
1806*b5893f02SDimitry Andric Type = kalimbaSectionType(m_header, H);
1807*b5893f02SDimitry Andric }
1808*b5893f02SDimitry Andric return Type;
1809*b5893f02SDimitry Andric }
1810*b5893f02SDimitry Andric
GetTargetByteSize(SectionType Type,const ArchSpec & arch)1811*b5893f02SDimitry Andric static uint32_t GetTargetByteSize(SectionType Type, const ArchSpec &arch) {
1812*b5893f02SDimitry Andric switch (Type) {
1813*b5893f02SDimitry Andric case eSectionTypeData:
1814*b5893f02SDimitry Andric case eSectionTypeZeroFill:
1815*b5893f02SDimitry Andric return arch.GetDataByteSize();
1816*b5893f02SDimitry Andric case eSectionTypeCode:
1817*b5893f02SDimitry Andric return arch.GetCodeByteSize();
1818*b5893f02SDimitry Andric default:
1819*b5893f02SDimitry Andric return 1;
1820*b5893f02SDimitry Andric }
1821*b5893f02SDimitry Andric }
1822*b5893f02SDimitry Andric
GetPermissions(const ELFSectionHeader & H)1823*b5893f02SDimitry Andric static Permissions GetPermissions(const ELFSectionHeader &H) {
1824*b5893f02SDimitry Andric Permissions Perm = Permissions(0);
1825*b5893f02SDimitry Andric if (H.sh_flags & SHF_ALLOC)
1826*b5893f02SDimitry Andric Perm |= ePermissionsReadable;
1827*b5893f02SDimitry Andric if (H.sh_flags & SHF_WRITE)
1828*b5893f02SDimitry Andric Perm |= ePermissionsWritable;
1829*b5893f02SDimitry Andric if (H.sh_flags & SHF_EXECINSTR)
1830*b5893f02SDimitry Andric Perm |= ePermissionsExecutable;
1831*b5893f02SDimitry Andric return Perm;
1832*b5893f02SDimitry Andric }
1833*b5893f02SDimitry Andric
GetPermissions(const ELFProgramHeader & H)1834*b5893f02SDimitry Andric static Permissions GetPermissions(const ELFProgramHeader &H) {
1835*b5893f02SDimitry Andric Permissions Perm = Permissions(0);
1836*b5893f02SDimitry Andric if (H.p_flags & PF_R)
1837*b5893f02SDimitry Andric Perm |= ePermissionsReadable;
1838*b5893f02SDimitry Andric if (H.p_flags & PF_W)
1839*b5893f02SDimitry Andric Perm |= ePermissionsWritable;
1840*b5893f02SDimitry Andric if (H.p_flags & PF_X)
1841*b5893f02SDimitry Andric Perm |= ePermissionsExecutable;
1842*b5893f02SDimitry Andric return Perm;
1843*b5893f02SDimitry Andric }
1844*b5893f02SDimitry Andric
1845*b5893f02SDimitry Andric namespace {
1846*b5893f02SDimitry Andric
1847*b5893f02SDimitry Andric using VMRange = lldb_private::Range<addr_t, addr_t>;
1848*b5893f02SDimitry Andric
1849*b5893f02SDimitry Andric struct SectionAddressInfo {
1850*b5893f02SDimitry Andric SectionSP Segment;
1851*b5893f02SDimitry Andric VMRange Range;
1852*b5893f02SDimitry Andric };
1853*b5893f02SDimitry Andric
1854*b5893f02SDimitry Andric // (Unlinked) ELF object files usually have 0 for every section address, meaning
1855*b5893f02SDimitry Andric // we need to compute synthetic addresses in order for "file addresses" from
1856*b5893f02SDimitry Andric // different sections to not overlap. This class handles that logic.
1857*b5893f02SDimitry Andric class VMAddressProvider {
1858*b5893f02SDimitry Andric using VMMap = llvm::IntervalMap<addr_t, SectionSP, 4,
1859*b5893f02SDimitry Andric llvm::IntervalMapHalfOpenInfo<addr_t>>;
1860*b5893f02SDimitry Andric
1861*b5893f02SDimitry Andric ObjectFile::Type ObjectType;
1862*b5893f02SDimitry Andric addr_t NextVMAddress = 0;
1863*b5893f02SDimitry Andric VMMap::Allocator Alloc;
1864*b5893f02SDimitry Andric VMMap Segments = VMMap(Alloc);
1865*b5893f02SDimitry Andric VMMap Sections = VMMap(Alloc);
1866*b5893f02SDimitry Andric lldb_private::Log *Log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES);
1867*b5893f02SDimitry Andric
GetVMRange(const ELFSectionHeader & H)1868*b5893f02SDimitry Andric VMRange GetVMRange(const ELFSectionHeader &H) {
1869*b5893f02SDimitry Andric addr_t Address = H.sh_addr;
1870*b5893f02SDimitry Andric addr_t Size = H.sh_flags & SHF_ALLOC ? H.sh_size : 0;
1871*b5893f02SDimitry Andric if (ObjectType == ObjectFile::Type::eTypeObjectFile && Segments.empty() && (H.sh_flags & SHF_ALLOC)) {
1872*b5893f02SDimitry Andric NextVMAddress =
1873*b5893f02SDimitry Andric llvm::alignTo(NextVMAddress, std::max<addr_t>(H.sh_addralign, 1));
1874*b5893f02SDimitry Andric Address = NextVMAddress;
1875*b5893f02SDimitry Andric NextVMAddress += Size;
1876*b5893f02SDimitry Andric }
1877*b5893f02SDimitry Andric return VMRange(Address, Size);
1878*b5893f02SDimitry Andric }
1879*b5893f02SDimitry Andric
1880*b5893f02SDimitry Andric public:
VMAddressProvider(ObjectFile::Type Type)1881*b5893f02SDimitry Andric VMAddressProvider(ObjectFile::Type Type) : ObjectType(Type) {}
1882*b5893f02SDimitry Andric
GetAddressInfo(const ELFProgramHeader & H)1883*b5893f02SDimitry Andric llvm::Optional<VMRange> GetAddressInfo(const ELFProgramHeader &H) {
1884*b5893f02SDimitry Andric if (H.p_memsz == 0) {
1885*b5893f02SDimitry Andric LLDB_LOG(Log,
1886*b5893f02SDimitry Andric "Ignoring zero-sized PT_LOAD segment. Corrupt object file?");
1887*b5893f02SDimitry Andric return llvm::None;
1888*b5893f02SDimitry Andric }
1889*b5893f02SDimitry Andric
1890*b5893f02SDimitry Andric if (Segments.overlaps(H.p_vaddr, H.p_vaddr + H.p_memsz)) {
1891*b5893f02SDimitry Andric LLDB_LOG(Log,
1892*b5893f02SDimitry Andric "Ignoring overlapping PT_LOAD segment. Corrupt object file?");
1893*b5893f02SDimitry Andric return llvm::None;
1894*b5893f02SDimitry Andric }
1895*b5893f02SDimitry Andric return VMRange(H.p_vaddr, H.p_memsz);
1896*b5893f02SDimitry Andric }
1897*b5893f02SDimitry Andric
GetAddressInfo(const ELFSectionHeader & H)1898*b5893f02SDimitry Andric llvm::Optional<SectionAddressInfo> GetAddressInfo(const ELFSectionHeader &H) {
1899*b5893f02SDimitry Andric VMRange Range = GetVMRange(H);
1900*b5893f02SDimitry Andric SectionSP Segment;
1901*b5893f02SDimitry Andric auto It = Segments.find(Range.GetRangeBase());
1902*b5893f02SDimitry Andric if ((H.sh_flags & SHF_ALLOC) && It.valid()) {
1903*b5893f02SDimitry Andric addr_t MaxSize;
1904*b5893f02SDimitry Andric if (It.start() <= Range.GetRangeBase()) {
1905*b5893f02SDimitry Andric MaxSize = It.stop() - Range.GetRangeBase();
1906*b5893f02SDimitry Andric Segment = *It;
1907*b5893f02SDimitry Andric } else
1908*b5893f02SDimitry Andric MaxSize = It.start() - Range.GetRangeBase();
1909*b5893f02SDimitry Andric if (Range.GetByteSize() > MaxSize) {
1910*b5893f02SDimitry Andric LLDB_LOG(Log, "Shortening section crossing segment boundaries. "
1911*b5893f02SDimitry Andric "Corrupt object file?");
1912*b5893f02SDimitry Andric Range.SetByteSize(MaxSize);
1913*b5893f02SDimitry Andric }
1914*b5893f02SDimitry Andric }
1915*b5893f02SDimitry Andric if (Range.GetByteSize() > 0 &&
1916*b5893f02SDimitry Andric Sections.overlaps(Range.GetRangeBase(), Range.GetRangeEnd())) {
1917*b5893f02SDimitry Andric LLDB_LOG(Log, "Ignoring overlapping section. Corrupt object file?");
1918*b5893f02SDimitry Andric return llvm::None;
1919*b5893f02SDimitry Andric }
1920*b5893f02SDimitry Andric if (Segment)
1921*b5893f02SDimitry Andric Range.Slide(-Segment->GetFileAddress());
1922*b5893f02SDimitry Andric return SectionAddressInfo{Segment, Range};
1923*b5893f02SDimitry Andric }
1924*b5893f02SDimitry Andric
AddSegment(const VMRange & Range,SectionSP Seg)1925*b5893f02SDimitry Andric void AddSegment(const VMRange &Range, SectionSP Seg) {
1926*b5893f02SDimitry Andric Segments.insert(Range.GetRangeBase(), Range.GetRangeEnd(), std::move(Seg));
1927*b5893f02SDimitry Andric }
1928*b5893f02SDimitry Andric
AddSection(SectionAddressInfo Info,SectionSP Sect)1929*b5893f02SDimitry Andric void AddSection(SectionAddressInfo Info, SectionSP Sect) {
1930*b5893f02SDimitry Andric if (Info.Range.GetByteSize() == 0)
1931*b5893f02SDimitry Andric return;
1932*b5893f02SDimitry Andric if (Info.Segment)
1933*b5893f02SDimitry Andric Info.Range.Slide(Info.Segment->GetFileAddress());
1934*b5893f02SDimitry Andric Sections.insert(Info.Range.GetRangeBase(), Info.Range.GetRangeEnd(),
1935*b5893f02SDimitry Andric std::move(Sect));
1936*b5893f02SDimitry Andric }
1937*b5893f02SDimitry Andric };
1938*b5893f02SDimitry Andric }
1939*b5893f02SDimitry Andric
CreateSections(SectionList & unified_section_list)1940435933ddSDimitry Andric void ObjectFileELF::CreateSections(SectionList &unified_section_list) {
1941*b5893f02SDimitry Andric if (m_sections_ap)
1942*b5893f02SDimitry Andric return;
1943ac7ddfbfSEd Maste
1944*b5893f02SDimitry Andric m_sections_ap = llvm::make_unique<SectionList>();
1945*b5893f02SDimitry Andric VMAddressProvider address_provider(CalculateType());
1946acac075bSDimitry Andric
1947*b5893f02SDimitry Andric size_t LoadID = 0;
1948*b5893f02SDimitry Andric for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) {
1949*b5893f02SDimitry Andric const ELFProgramHeader &PHdr = EnumPHdr.value();
1950*b5893f02SDimitry Andric if (PHdr.p_type != PT_LOAD)
1951*b5893f02SDimitry Andric continue;
1952*b5893f02SDimitry Andric
1953*b5893f02SDimitry Andric auto InfoOr = address_provider.GetAddressInfo(PHdr);
1954*b5893f02SDimitry Andric if (!InfoOr)
1955*b5893f02SDimitry Andric continue;
1956*b5893f02SDimitry Andric
1957*b5893f02SDimitry Andric ConstString Name(("PT_LOAD[" + llvm::Twine(LoadID++) + "]").str());
1958*b5893f02SDimitry Andric uint32_t Log2Align = llvm::Log2_64(std::max<elf_xword>(PHdr.p_align, 1));
1959*b5893f02SDimitry Andric SectionSP Segment = std::make_shared<Section>(
1960*b5893f02SDimitry Andric GetModule(), this, SegmentID(EnumPHdr.index()), Name,
1961*b5893f02SDimitry Andric eSectionTypeContainer, InfoOr->GetRangeBase(), InfoOr->GetByteSize(),
1962*b5893f02SDimitry Andric PHdr.p_offset, PHdr.p_filesz, Log2Align, /*flags*/ 0);
1963*b5893f02SDimitry Andric Segment->SetPermissions(GetPermissions(PHdr));
1964*b5893f02SDimitry Andric m_sections_ap->AddSection(Segment);
1965*b5893f02SDimitry Andric
1966*b5893f02SDimitry Andric address_provider.AddSegment(*InfoOr, std::move(Segment));
1967*b5893f02SDimitry Andric }
1968*b5893f02SDimitry Andric
1969*b5893f02SDimitry Andric ParseSectionHeaders();
1970*b5893f02SDimitry Andric if (m_section_headers.empty())
1971*b5893f02SDimitry Andric return;
1972*b5893f02SDimitry Andric
1973*b5893f02SDimitry Andric for (SectionHeaderCollIter I = std::next(m_section_headers.begin());
1974435933ddSDimitry Andric I != m_section_headers.end(); ++I) {
1975ac7ddfbfSEd Maste const ELFSectionHeaderInfo &header = *I;
1976ac7ddfbfSEd Maste
1977ac7ddfbfSEd Maste ConstString &name = I->section_name;
1978435933ddSDimitry Andric const uint64_t file_size =
1979435933ddSDimitry Andric header.sh_type == SHT_NOBITS ? 0 : header.sh_size;
1980ac7ddfbfSEd Maste
1981*b5893f02SDimitry Andric auto InfoOr = address_provider.GetAddressInfo(header);
1982*b5893f02SDimitry Andric if (!InfoOr)
1983*b5893f02SDimitry Andric continue;
1984ac7ddfbfSEd Maste
1985*b5893f02SDimitry Andric SectionType sect_type = GetSectionType(header);
19864ba319b5SDimitry Andric
19877aa51b79SEd Maste const uint32_t target_bytes_size =
1988*b5893f02SDimitry Andric GetTargetByteSize(sect_type, m_arch_spec);
1989*b5893f02SDimitry Andric
1990435933ddSDimitry Andric elf::elf_xword log2align =
1991435933ddSDimitry Andric (header.sh_addralign == 0) ? 0 : llvm::Log2_64(header.sh_addralign);
1992acac075bSDimitry Andric
1993435933ddSDimitry Andric SectionSP section_sp(new Section(
1994*b5893f02SDimitry Andric InfoOr->Segment, GetModule(), // Module to which this section belongs.
1995*b5893f02SDimitry Andric this, // ObjectFile to which this section belongs and should
1996*b5893f02SDimitry Andric // read section data from.
1997ac7ddfbfSEd Maste SectionIndex(I), // Section ID.
1998ac7ddfbfSEd Maste name, // Section name.
1999ac7ddfbfSEd Maste sect_type, // Section type.
2000*b5893f02SDimitry Andric InfoOr->Range.GetRangeBase(), // VM address.
2001*b5893f02SDimitry Andric InfoOr->Range.GetByteSize(), // VM size in bytes of this section.
2002ac7ddfbfSEd Maste header.sh_offset, // Offset of this section in the file.
2003ac7ddfbfSEd Maste file_size, // Size of the section as found in the file.
20040127ef0fSEd Maste log2align, // Alignment of the section
20057aa51b79SEd Maste header.sh_flags, // Flags for this section.
20067aa51b79SEd Maste target_bytes_size)); // Number of host bytes per target byte
2007ac7ddfbfSEd Maste
2008*b5893f02SDimitry Andric section_sp->SetPermissions(GetPermissions(header));
2009*b5893f02SDimitry Andric section_sp->SetIsThreadSpecific(header.sh_flags & SHF_TLS);
2010*b5893f02SDimitry Andric (InfoOr->Segment ? InfoOr->Segment->GetChildren() : *m_sections_ap)
2011*b5893f02SDimitry Andric .AddSection(section_sp);
2012*b5893f02SDimitry Andric address_provider.AddSection(std::move(*InfoOr), std::move(section_sp));
2013ac7ddfbfSEd Maste }
2014ac7ddfbfSEd Maste
20154ba319b5SDimitry Andric // For eTypeDebugInfo files, the Symbol Vendor will take care of updating the
20164ba319b5SDimitry Andric // unified section list.
20174ba319b5SDimitry Andric if (GetType() != eTypeDebugInfo)
2018ac7ddfbfSEd Maste unified_section_list = *m_sections_ap;
2019ac7ddfbfSEd Maste }
2020ac7ddfbfSEd Maste
2021435933ddSDimitry Andric // Find the arm/aarch64 mapping symbol character in the given symbol name.
20224ba319b5SDimitry Andric // Mapping symbols have the form of "$<char>[.<any>]*". Additionally we
20234ba319b5SDimitry Andric // recognize cases when the mapping symbol prefixed by an arbitrary string
20244ba319b5SDimitry Andric // because if a symbol prefix added to each symbol in the object file with
20259f2f44ceSEd Maste // objcopy then the mapping symbols are also prefixed.
FindArmAarch64MappingSymbol(const char * symbol_name)2026435933ddSDimitry Andric static char FindArmAarch64MappingSymbol(const char *symbol_name) {
20279f2f44ceSEd Maste if (!symbol_name)
20289f2f44ceSEd Maste return '\0';
20299f2f44ceSEd Maste
20309f2f44ceSEd Maste const char *dollar_pos = ::strchr(symbol_name, '$');
20319f2f44ceSEd Maste if (!dollar_pos || dollar_pos[1] == '\0')
20329f2f44ceSEd Maste return '\0';
20339f2f44ceSEd Maste
20349f2f44ceSEd Maste if (dollar_pos[2] == '\0' || dollar_pos[2] == '.')
20359f2f44ceSEd Maste return dollar_pos[1];
20369f2f44ceSEd Maste return '\0';
20379f2f44ceSEd Maste }
20389f2f44ceSEd Maste
20399f2f44ceSEd Maste #define STO_MIPS_ISA (3 << 6)
20409f2f44ceSEd Maste #define STO_MICROMIPS (2 << 6)
20419f2f44ceSEd Maste #define IS_MICROMIPS(ST_OTHER) (((ST_OTHER)&STO_MIPS_ISA) == STO_MICROMIPS)
20429f2f44ceSEd Maste
2043ac7ddfbfSEd Maste // private
ParseSymbols(Symtab * symtab,user_id_t start_id,SectionList * section_list,const size_t num_symbols,const DataExtractor & symtab_data,const DataExtractor & strtab_data)2044435933ddSDimitry Andric unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id,
2045ac7ddfbfSEd Maste SectionList *section_list,
2046ac7ddfbfSEd Maste const size_t num_symbols,
2047ac7ddfbfSEd Maste const DataExtractor &symtab_data,
2048435933ddSDimitry Andric const DataExtractor &strtab_data) {
2049ac7ddfbfSEd Maste ELFSymbol symbol;
2050ac7ddfbfSEd Maste lldb::offset_t offset = 0;
2051ac7ddfbfSEd Maste
2052ac7ddfbfSEd Maste static ConstString text_section_name(".text");
2053ac7ddfbfSEd Maste static ConstString init_section_name(".init");
2054ac7ddfbfSEd Maste static ConstString fini_section_name(".fini");
2055ac7ddfbfSEd Maste static ConstString ctors_section_name(".ctors");
2056ac7ddfbfSEd Maste static ConstString dtors_section_name(".dtors");
2057ac7ddfbfSEd Maste
2058ac7ddfbfSEd Maste static ConstString data_section_name(".data");
2059ac7ddfbfSEd Maste static ConstString rodata_section_name(".rodata");
2060ac7ddfbfSEd Maste static ConstString rodata1_section_name(".rodata1");
2061ac7ddfbfSEd Maste static ConstString data2_section_name(".data1");
2062ac7ddfbfSEd Maste static ConstString bss_section_name(".bss");
20637aa51b79SEd Maste static ConstString opd_section_name(".opd"); // For ppc64
2064ac7ddfbfSEd Maste
2065435933ddSDimitry Andric // On Android the oatdata and the oatexec symbols in the oat and odex files
20664ba319b5SDimitry Andric // covers the full .text section what causes issues with displaying unusable
20674ba319b5SDimitry Andric // symbol name to the user and very slow unwinding speed because the
20684ba319b5SDimitry Andric // instruction emulation based unwind plans try to emulate all instructions
20694ba319b5SDimitry Andric // in these symbols. Don't add these symbols to the symbol list as they have
20704ba319b5SDimitry Andric // no use for the debugger and they are causing a lot of trouble. Filtering
20714ba319b5SDimitry Andric // can't be restricted to Android because this special object file don't
20724ba319b5SDimitry Andric // contain the note section specifying the environment to Android but the
20734ba319b5SDimitry Andric // custom extension and file name makes it highly unlikely that this will
20744ba319b5SDimitry Andric // collide with anything else.
20754bb0738eSEd Maste ConstString file_extension = m_file.GetFileNameExtension();
20764ba319b5SDimitry Andric bool skip_oatdata_oatexec = file_extension == ConstString(".oat") ||
20774ba319b5SDimitry Andric file_extension == ConstString(".odex");
2078b91a7dfcSDimitry Andric
2079*b5893f02SDimitry Andric ArchSpec arch = GetArchitecture();
20804bb0738eSEd Maste ModuleSP module_sp(GetModule());
2081435933ddSDimitry Andric SectionList *module_section_list =
2082435933ddSDimitry Andric module_sp ? module_sp->GetSectionList() : nullptr;
20839f2f44ceSEd Maste
2084435933ddSDimitry Andric // Local cache to avoid doing a FindSectionByName for each symbol. The "const
20854ba319b5SDimitry Andric // char*" key must came from a ConstString object so they can be compared by
20864ba319b5SDimitry Andric // pointer
20879f2f44ceSEd Maste std::unordered_map<const char *, lldb::SectionSP> section_name_to_section;
20889f2f44ceSEd Maste
2089ac7ddfbfSEd Maste unsigned i;
2090435933ddSDimitry Andric for (i = 0; i < num_symbols; ++i) {
2091*b5893f02SDimitry Andric if (!symbol.Parse(symtab_data, &offset))
2092ac7ddfbfSEd Maste break;
2093ac7ddfbfSEd Maste
2094ac7ddfbfSEd Maste const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
2095435933ddSDimitry Andric if (!symbol_name)
2096435933ddSDimitry Andric symbol_name = "";
2097ac7ddfbfSEd Maste
20980127ef0fSEd Maste // No need to add non-section symbols that have no names
20990127ef0fSEd Maste if (symbol.getType() != STT_SECTION &&
2100435933ddSDimitry Andric (symbol_name == nullptr || symbol_name[0] == '\0'))
2101ac7ddfbfSEd Maste continue;
2102ac7ddfbfSEd Maste
2103435933ddSDimitry Andric // Skipping oatdata and oatexec sections if it is requested. See details
21044ba319b5SDimitry Andric // above the definition of skip_oatdata_oatexec for the reasons.
2105435933ddSDimitry Andric if (skip_oatdata_oatexec && (::strcmp(symbol_name, "oatdata") == 0 ||
2106435933ddSDimitry Andric ::strcmp(symbol_name, "oatexec") == 0))
2107b91a7dfcSDimitry Andric continue;
2108ac7ddfbfSEd Maste
2109ac7ddfbfSEd Maste SectionSP symbol_section_sp;
2110ac7ddfbfSEd Maste SymbolType symbol_type = eSymbolTypeInvalid;
2111*b5893f02SDimitry Andric Elf64_Half shndx = symbol.st_shndx;
2112ac7ddfbfSEd Maste
2113*b5893f02SDimitry Andric switch (shndx) {
2114ac7ddfbfSEd Maste case SHN_ABS:
2115ac7ddfbfSEd Maste symbol_type = eSymbolTypeAbsolute;
2116ac7ddfbfSEd Maste break;
2117ac7ddfbfSEd Maste case SHN_UNDEF:
2118ac7ddfbfSEd Maste symbol_type = eSymbolTypeUndefined;
2119ac7ddfbfSEd Maste break;
2120ac7ddfbfSEd Maste default:
2121*b5893f02SDimitry Andric symbol_section_sp = section_list->FindSectionByID(shndx);
2122ac7ddfbfSEd Maste break;
2123ac7ddfbfSEd Maste }
2124ac7ddfbfSEd Maste
2125435933ddSDimitry Andric // If a symbol is undefined do not process it further even if it has a STT
2126435933ddSDimitry Andric // type
2127435933ddSDimitry Andric if (symbol_type != eSymbolTypeUndefined) {
2128435933ddSDimitry Andric switch (symbol.getType()) {
2129ac7ddfbfSEd Maste default:
2130ac7ddfbfSEd Maste case STT_NOTYPE:
2131ac7ddfbfSEd Maste // The symbol's type is not specified.
2132ac7ddfbfSEd Maste break;
2133ac7ddfbfSEd Maste
2134ac7ddfbfSEd Maste case STT_OBJECT:
21354ba319b5SDimitry Andric // The symbol is associated with a data object, such as a variable, an
21364ba319b5SDimitry Andric // array, etc.
2137ac7ddfbfSEd Maste symbol_type = eSymbolTypeData;
2138ac7ddfbfSEd Maste break;
2139ac7ddfbfSEd Maste
2140ac7ddfbfSEd Maste case STT_FUNC:
2141ac7ddfbfSEd Maste // The symbol is associated with a function or other executable code.
2142ac7ddfbfSEd Maste symbol_type = eSymbolTypeCode;
2143ac7ddfbfSEd Maste break;
2144ac7ddfbfSEd Maste
2145ac7ddfbfSEd Maste case STT_SECTION:
2146ac7ddfbfSEd Maste // The symbol is associated with a section. Symbol table entries of
21474ba319b5SDimitry Andric // this type exist primarily for relocation and normally have STB_LOCAL
21484ba319b5SDimitry Andric // binding.
2149ac7ddfbfSEd Maste break;
2150ac7ddfbfSEd Maste
2151ac7ddfbfSEd Maste case STT_FILE:
21524ba319b5SDimitry Andric // Conventionally, the symbol's name gives the name of the source file
21534ba319b5SDimitry Andric // associated with the object file. A file symbol has STB_LOCAL
2154ac7ddfbfSEd Maste // binding, its section index is SHN_ABS, and it precedes the other
2155ac7ddfbfSEd Maste // STB_LOCAL symbols for the file, if it is present.
2156ac7ddfbfSEd Maste symbol_type = eSymbolTypeSourceFile;
2157ac7ddfbfSEd Maste break;
2158ac7ddfbfSEd Maste
2159ac7ddfbfSEd Maste case STT_GNU_IFUNC:
2160ac7ddfbfSEd Maste // The symbol is associated with an indirect function. The actual
2161ac7ddfbfSEd Maste // function will be resolved if it is referenced.
2162ac7ddfbfSEd Maste symbol_type = eSymbolTypeResolver;
2163ac7ddfbfSEd Maste break;
2164ac7ddfbfSEd Maste }
2165ac7ddfbfSEd Maste }
2166ac7ddfbfSEd Maste
2167435933ddSDimitry Andric if (symbol_type == eSymbolTypeInvalid && symbol.getType() != STT_SECTION) {
2168435933ddSDimitry Andric if (symbol_section_sp) {
2169ac7ddfbfSEd Maste const ConstString §_name = symbol_section_sp->GetName();
2170435933ddSDimitry Andric if (sect_name == text_section_name || sect_name == init_section_name ||
2171435933ddSDimitry Andric sect_name == fini_section_name || sect_name == ctors_section_name ||
2172435933ddSDimitry Andric sect_name == dtors_section_name) {
2173ac7ddfbfSEd Maste symbol_type = eSymbolTypeCode;
2174435933ddSDimitry Andric } else if (sect_name == data_section_name ||
2175ac7ddfbfSEd Maste sect_name == data2_section_name ||
2176ac7ddfbfSEd Maste sect_name == rodata_section_name ||
2177ac7ddfbfSEd Maste sect_name == rodata1_section_name ||
2178435933ddSDimitry Andric sect_name == bss_section_name) {
2179ac7ddfbfSEd Maste symbol_type = eSymbolTypeData;
2180ac7ddfbfSEd Maste }
2181ac7ddfbfSEd Maste }
2182ac7ddfbfSEd Maste }
2183ac7ddfbfSEd Maste
21847aa51b79SEd Maste int64_t symbol_value_offset = 0;
21857aa51b79SEd Maste uint32_t additional_flags = 0;
21867aa51b79SEd Maste
2187435933ddSDimitry Andric if (arch.IsValid()) {
2188435933ddSDimitry Andric if (arch.GetMachine() == llvm::Triple::arm) {
2189435933ddSDimitry Andric if (symbol.getBinding() == STB_LOCAL) {
21909f2f44ceSEd Maste char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);
2191435933ddSDimitry Andric if (symbol_type == eSymbolTypeCode) {
2192435933ddSDimitry Andric switch (mapping_symbol) {
21939f2f44ceSEd Maste case 'a':
21941c3bbb01SEd Maste // $a[.<any>]* - marks an ARM instruction sequence
21954ba319b5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCode;
21969f2f44ceSEd Maste break;
21979f2f44ceSEd Maste case 'b':
21989f2f44ceSEd Maste case 't':
21991c3bbb01SEd Maste // $b[.<any>]* - marks a THUMB BL instruction sequence
22001c3bbb01SEd Maste // $t[.<any>]* - marks a THUMB instruction sequence
2201435933ddSDimitry Andric m_address_class_map[symbol.st_value] =
22024ba319b5SDimitry Andric AddressClass::eCodeAlternateISA;
22039f2f44ceSEd Maste break;
22049f2f44ceSEd Maste case 'd':
22051c3bbb01SEd Maste // $d[.<any>]* - marks a data item sequence (e.g. lit pool)
22064ba319b5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eData;
22079f2f44ceSEd Maste break;
22081c3bbb01SEd Maste }
22091c3bbb01SEd Maste }
22109f2f44ceSEd Maste if (mapping_symbol)
22111c3bbb01SEd Maste continue;
22121c3bbb01SEd Maste }
2213435933ddSDimitry Andric } else if (arch.GetMachine() == llvm::Triple::aarch64) {
2214435933ddSDimitry Andric if (symbol.getBinding() == STB_LOCAL) {
22159f2f44ceSEd Maste char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name);
2216435933ddSDimitry Andric if (symbol_type == eSymbolTypeCode) {
2217435933ddSDimitry Andric switch (mapping_symbol) {
22189f2f44ceSEd Maste case 'x':
22191c3bbb01SEd Maste // $x[.<any>]* - marks an A64 instruction sequence
22204ba319b5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCode;
22219f2f44ceSEd Maste break;
22229f2f44ceSEd Maste case 'd':
22231c3bbb01SEd Maste // $d[.<any>]* - marks a data item sequence (e.g. lit pool)
22244ba319b5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eData;
22259f2f44ceSEd Maste break;
22261c3bbb01SEd Maste }
22271c3bbb01SEd Maste }
22289f2f44ceSEd Maste if (mapping_symbol)
22291c3bbb01SEd Maste continue;
22301c3bbb01SEd Maste }
22311c3bbb01SEd Maste }
22321c3bbb01SEd Maste
2233435933ddSDimitry Andric if (arch.GetMachine() == llvm::Triple::arm) {
2234435933ddSDimitry Andric if (symbol_type == eSymbolTypeCode) {
2235435933ddSDimitry Andric if (symbol.st_value & 1) {
22364ba319b5SDimitry Andric // Subtracting 1 from the address effectively unsets the low order
22374ba319b5SDimitry Andric // bit, which results in the address actually pointing to the
22384ba319b5SDimitry Andric // beginning of the symbol. This delta will be used below in
22394ba319b5SDimitry Andric // conjunction with symbol.st_value to produce the final
22404ba319b5SDimitry Andric // symbol_value that we store in the symtab.
22417aa51b79SEd Maste symbol_value_offset = -1;
2242435933ddSDimitry Andric m_address_class_map[symbol.st_value ^ 1] =
22434ba319b5SDimitry Andric AddressClass::eCodeAlternateISA;
2244435933ddSDimitry Andric } else {
22451c3bbb01SEd Maste // This address is ARM
22464ba319b5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCode;
22471c3bbb01SEd Maste }
22481c3bbb01SEd Maste }
22497aa51b79SEd Maste }
22507aa51b79SEd Maste
22519f2f44ceSEd Maste /*
22529f2f44ceSEd Maste * MIPS:
2253435933ddSDimitry Andric * The bit #0 of an address is used for ISA mode (1 for microMIPS, 0 for
2254435933ddSDimitry Andric * MIPS).
2255435933ddSDimitry Andric * This allows processor to switch between microMIPS and MIPS without any
2256435933ddSDimitry Andric * need
2257435933ddSDimitry Andric * for special mode-control register. However, apart from .debug_line,
2258435933ddSDimitry Andric * none of
2259435933ddSDimitry Andric * the ELF/DWARF sections set the ISA bit (for symbol or section). Use
2260435933ddSDimitry Andric * st_other
2261435933ddSDimitry Andric * flag to check whether the symbol is microMIPS and then set the address
2262435933ddSDimitry Andric * class
22639f2f44ceSEd Maste * accordingly.
22649f2f44ceSEd Maste */
22659f2f44ceSEd Maste const llvm::Triple::ArchType llvm_arch = arch.GetMachine();
2266435933ddSDimitry Andric if (llvm_arch == llvm::Triple::mips ||
2267435933ddSDimitry Andric llvm_arch == llvm::Triple::mipsel ||
2268435933ddSDimitry Andric llvm_arch == llvm::Triple::mips64 ||
2269435933ddSDimitry Andric llvm_arch == llvm::Triple::mips64el) {
22709f2f44ceSEd Maste if (IS_MICROMIPS(symbol.st_other))
22714ba319b5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
2272435933ddSDimitry Andric else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode)) {
22739f2f44ceSEd Maste symbol.st_value = symbol.st_value & (~1ull);
22744ba319b5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA;
2275435933ddSDimitry Andric } else {
22769f2f44ceSEd Maste if (symbol_type == eSymbolTypeCode)
22774ba319b5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCode;
22789f2f44ceSEd Maste else if (symbol_type == eSymbolTypeData)
22794ba319b5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eData;
22809f2f44ceSEd Maste else
22814ba319b5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eUnknown;
2282ac7ddfbfSEd Maste }
2283ac7ddfbfSEd Maste }
2284ac7ddfbfSEd Maste }
2285ac7ddfbfSEd Maste
2286435933ddSDimitry Andric // symbol_value_offset may contain 0 for ARM symbols or -1 for THUMB
22874ba319b5SDimitry Andric // symbols. See above for more details.
22881c3bbb01SEd Maste uint64_t symbol_value = symbol.st_value + symbol_value_offset;
22894bb0738eSEd Maste
2290*b5893f02SDimitry Andric if (symbol_section_sp == nullptr && shndx == SHN_ABS &&
2291435933ddSDimitry Andric symbol.st_size != 0) {
2292435933ddSDimitry Andric // We don't have a section for a symbol with non-zero size. Create a new
22934ba319b5SDimitry Andric // section for it so the address range covered by the symbol is also
22944ba319b5SDimitry Andric // covered by the module (represented through the section list). It is
22954ba319b5SDimitry Andric // needed so module lookup for the addresses covered by this symbol will
22964ba319b5SDimitry Andric // be successfull. This case happens for absolute symbols.
22974bb0738eSEd Maste ConstString fake_section_name(std::string(".absolute.") + symbol_name);
2298435933ddSDimitry Andric symbol_section_sp =
2299435933ddSDimitry Andric std::make_shared<Section>(module_sp, this, SHN_ABS, fake_section_name,
2300435933ddSDimitry Andric eSectionTypeAbsoluteAddress, symbol_value,
2301435933ddSDimitry Andric symbol.st_size, 0, 0, 0, SHF_ALLOC);
23024bb0738eSEd Maste
23034bb0738eSEd Maste module_section_list->AddSection(symbol_section_sp);
23044bb0738eSEd Maste section_list->AddSection(symbol_section_sp);
23054bb0738eSEd Maste }
23064bb0738eSEd Maste
2307435933ddSDimitry Andric if (symbol_section_sp &&
2308435933ddSDimitry Andric CalculateType() != ObjectFile::Type::eTypeObjectFile)
2309ac7ddfbfSEd Maste symbol_value -= symbol_section_sp->GetFileAddress();
23109f2f44ceSEd Maste
2311435933ddSDimitry Andric if (symbol_section_sp && module_section_list &&
2312435933ddSDimitry Andric module_section_list != section_list) {
23139f2f44ceSEd Maste const ConstString §_name = symbol_section_sp->GetName();
23149f2f44ceSEd Maste auto section_it = section_name_to_section.find(sect_name.GetCString());
23159f2f44ceSEd Maste if (section_it == section_name_to_section.end())
2316435933ddSDimitry Andric section_it =
2317435933ddSDimitry Andric section_name_to_section
2318435933ddSDimitry Andric .emplace(sect_name.GetCString(),
2319435933ddSDimitry Andric module_section_list->FindSectionByName(sect_name))
2320435933ddSDimitry Andric .first;
2321f37b6182SDimitry Andric if (section_it->second)
23229f2f44ceSEd Maste symbol_section_sp = section_it->second;
23239f2f44ceSEd Maste }
23249f2f44ceSEd Maste
2325ac7ddfbfSEd Maste bool is_global = symbol.getBinding() == STB_GLOBAL;
23267aa51b79SEd Maste uint32_t flags = symbol.st_other << 8 | symbol.st_info | additional_flags;
2327435933ddSDimitry Andric bool is_mangled = (symbol_name[0] == '_' && symbol_name[1] == 'Z');
23287aa51b79SEd Maste
23291c3bbb01SEd Maste llvm::StringRef symbol_ref(symbol_name);
23301c3bbb01SEd Maste
2331435933ddSDimitry Andric // Symbol names may contain @VERSION suffixes. Find those and strip them
2332435933ddSDimitry Andric // temporarily.
23331c3bbb01SEd Maste size_t version_pos = symbol_ref.find('@');
23341c3bbb01SEd Maste bool has_suffix = version_pos != llvm::StringRef::npos;
23351c3bbb01SEd Maste llvm::StringRef symbol_bare = symbol_ref.substr(0, version_pos);
23361c3bbb01SEd Maste Mangled mangled(ConstString(symbol_bare), is_mangled);
23371c3bbb01SEd Maste
2338435933ddSDimitry Andric // Now append the suffix back to mangled and unmangled names. Only do it if
23394ba319b5SDimitry Andric // the demangling was successful (string is not empty).
2340435933ddSDimitry Andric if (has_suffix) {
23411c3bbb01SEd Maste llvm::StringRef suffix = symbol_ref.substr(version_pos);
23421c3bbb01SEd Maste
23431c3bbb01SEd Maste llvm::StringRef mangled_name = mangled.GetMangledName().GetStringRef();
23441c3bbb01SEd Maste if (!mangled_name.empty())
23451c3bbb01SEd Maste mangled.SetMangledName(ConstString((mangled_name + suffix).str()));
23461c3bbb01SEd Maste
2347435933ddSDimitry Andric ConstString demangled =
2348435933ddSDimitry Andric mangled.GetDemangledName(lldb::eLanguageTypeUnknown);
2349b91a7dfcSDimitry Andric llvm::StringRef demangled_name = demangled.GetStringRef();
23501c3bbb01SEd Maste if (!demangled_name.empty())
23511c3bbb01SEd Maste mangled.SetDemangledName(ConstString((demangled_name + suffix).str()));
23521c3bbb01SEd Maste }
23531c3bbb01SEd Maste
2354435933ddSDimitry Andric // In ELF all symbol should have a valid size but it is not true for some
23554ba319b5SDimitry Andric // function symbols coming from hand written assembly. As none of the
23564ba319b5SDimitry Andric // function symbol should have 0 size we try to calculate the size for
23574ba319b5SDimitry Andric // these symbols in the symtab with saying that their original size is not
23584ba319b5SDimitry Andric // valid.
2359435933ddSDimitry Andric bool symbol_size_valid =
2360435933ddSDimitry Andric symbol.st_size != 0 || symbol.getType() != STT_FUNC;
23614bb0738eSEd Maste
2362ac7ddfbfSEd Maste Symbol dc_symbol(
2363ac7ddfbfSEd Maste i + start_id, // ID is the original symbol table index.
23641c3bbb01SEd Maste mangled,
2365ac7ddfbfSEd Maste symbol_type, // Type of this symbol
2366ac7ddfbfSEd Maste is_global, // Is this globally visible?
2367ac7ddfbfSEd Maste false, // Is this symbol debug info?
2368ac7ddfbfSEd Maste false, // Is this symbol a trampoline?
2369ac7ddfbfSEd Maste false, // Is this symbol artificial?
2370435933ddSDimitry Andric AddressRange(symbol_section_sp, // Section in which this symbol is
2371435933ddSDimitry Andric // defined or null.
2372ac7ddfbfSEd Maste symbol_value, // Offset in section or symbol value.
23731c3bbb01SEd Maste symbol.st_size), // Size in bytes of this symbol.
23744bb0738eSEd Maste symbol_size_valid, // Symbol size is valid
23751c3bbb01SEd Maste has_suffix, // Contains linker annotations?
2376ac7ddfbfSEd Maste flags); // Symbol flags.
2377ac7ddfbfSEd Maste symtab->AddSymbol(dc_symbol);
2378ac7ddfbfSEd Maste }
2379ac7ddfbfSEd Maste return i;
2380ac7ddfbfSEd Maste }
2381ac7ddfbfSEd Maste
ParseSymbolTable(Symtab * symbol_table,user_id_t start_id,lldb_private::Section * symtab)2382435933ddSDimitry Andric unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table,
23834bb0738eSEd Maste user_id_t start_id,
2384435933ddSDimitry Andric lldb_private::Section *symtab) {
2385435933ddSDimitry Andric if (symtab->GetObjectFile() != this) {
2386435933ddSDimitry Andric // If the symbol table section is owned by a different object file, have it
23874ba319b5SDimitry Andric // do the parsing.
2388435933ddSDimitry Andric ObjectFileELF *obj_file_elf =
2389435933ddSDimitry Andric static_cast<ObjectFileELF *>(symtab->GetObjectFile());
2390ac7ddfbfSEd Maste return obj_file_elf->ParseSymbolTable(symbol_table, start_id, symtab);
2391ac7ddfbfSEd Maste }
2392ac7ddfbfSEd Maste
2393ac7ddfbfSEd Maste // Get section list for this object file.
2394ac7ddfbfSEd Maste SectionList *section_list = m_sections_ap.get();
2395ac7ddfbfSEd Maste if (!section_list)
2396ac7ddfbfSEd Maste return 0;
2397ac7ddfbfSEd Maste
2398ac7ddfbfSEd Maste user_id_t symtab_id = symtab->GetID();
2399ac7ddfbfSEd Maste const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
2400ac7ddfbfSEd Maste assert(symtab_hdr->sh_type == SHT_SYMTAB ||
2401ac7ddfbfSEd Maste symtab_hdr->sh_type == SHT_DYNSYM);
2402ac7ddfbfSEd Maste
2403*b5893f02SDimitry Andric // sh_link: section header index of associated string table.
2404*b5893f02SDimitry Andric user_id_t strtab_id = symtab_hdr->sh_link;
2405ac7ddfbfSEd Maste Section *strtab = section_list->FindSectionByID(strtab_id).get();
2406ac7ddfbfSEd Maste
2407435933ddSDimitry Andric if (symtab && strtab) {
2408ac7ddfbfSEd Maste assert(symtab->GetObjectFile() == this);
2409ac7ddfbfSEd Maste assert(strtab->GetObjectFile() == this);
2410ac7ddfbfSEd Maste
2411ac7ddfbfSEd Maste DataExtractor symtab_data;
2412ac7ddfbfSEd Maste DataExtractor strtab_data;
2413ac7ddfbfSEd Maste if (ReadSectionData(symtab, symtab_data) &&
2414435933ddSDimitry Andric ReadSectionData(strtab, strtab_data)) {
2415ac7ddfbfSEd Maste size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize;
2416ac7ddfbfSEd Maste
2417435933ddSDimitry Andric return ParseSymbols(symbol_table, start_id, section_list, num_symbols,
2418435933ddSDimitry Andric symtab_data, strtab_data);
2419ac7ddfbfSEd Maste }
2420ac7ddfbfSEd Maste }
2421ac7ddfbfSEd Maste
24220127ef0fSEd Maste return 0;
2423ac7ddfbfSEd Maste }
2424ac7ddfbfSEd Maste
ParseDynamicSymbols()2425435933ddSDimitry Andric size_t ObjectFileELF::ParseDynamicSymbols() {
2426ac7ddfbfSEd Maste if (m_dynamic_symbols.size())
2427ac7ddfbfSEd Maste return m_dynamic_symbols.size();
2428ac7ddfbfSEd Maste
2429ac7ddfbfSEd Maste SectionList *section_list = GetSectionList();
2430ac7ddfbfSEd Maste if (!section_list)
2431ac7ddfbfSEd Maste return 0;
2432ac7ddfbfSEd Maste
2433ac7ddfbfSEd Maste // Find the SHT_DYNAMIC section.
2434435933ddSDimitry Andric Section *dynsym =
2435435933ddSDimitry Andric section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true)
2436435933ddSDimitry Andric .get();
2437ac7ddfbfSEd Maste if (!dynsym)
2438ac7ddfbfSEd Maste return 0;
2439ac7ddfbfSEd Maste assert(dynsym->GetObjectFile() == this);
2440ac7ddfbfSEd Maste
2441ac7ddfbfSEd Maste ELFDynamic symbol;
2442ac7ddfbfSEd Maste DataExtractor dynsym_data;
2443435933ddSDimitry Andric if (ReadSectionData(dynsym, dynsym_data)) {
2444ac7ddfbfSEd Maste const lldb::offset_t section_size = dynsym_data.GetByteSize();
2445ac7ddfbfSEd Maste lldb::offset_t cursor = 0;
2446ac7ddfbfSEd Maste
2447435933ddSDimitry Andric while (cursor < section_size) {
2448ac7ddfbfSEd Maste if (!symbol.Parse(dynsym_data, &cursor))
2449ac7ddfbfSEd Maste break;
2450ac7ddfbfSEd Maste
2451ac7ddfbfSEd Maste m_dynamic_symbols.push_back(symbol);
2452ac7ddfbfSEd Maste }
2453ac7ddfbfSEd Maste }
2454ac7ddfbfSEd Maste
2455ac7ddfbfSEd Maste return m_dynamic_symbols.size();
2456ac7ddfbfSEd Maste }
2457ac7ddfbfSEd Maste
FindDynamicSymbol(unsigned tag)2458435933ddSDimitry Andric const ELFDynamic *ObjectFileELF::FindDynamicSymbol(unsigned tag) {
2459ac7ddfbfSEd Maste if (!ParseDynamicSymbols())
2460ac7ddfbfSEd Maste return NULL;
2461ac7ddfbfSEd Maste
2462ac7ddfbfSEd Maste DynamicSymbolCollIter I = m_dynamic_symbols.begin();
2463ac7ddfbfSEd Maste DynamicSymbolCollIter E = m_dynamic_symbols.end();
2464435933ddSDimitry Andric for (; I != E; ++I) {
2465ac7ddfbfSEd Maste ELFDynamic *symbol = &*I;
2466ac7ddfbfSEd Maste
2467ac7ddfbfSEd Maste if (symbol->d_tag == tag)
2468ac7ddfbfSEd Maste return symbol;
2469ac7ddfbfSEd Maste }
2470ac7ddfbfSEd Maste
2471ac7ddfbfSEd Maste return NULL;
2472ac7ddfbfSEd Maste }
2473ac7ddfbfSEd Maste
PLTRelocationType()2474435933ddSDimitry Andric unsigned ObjectFileELF::PLTRelocationType() {
247535617911SEd Maste // DT_PLTREL
247635617911SEd Maste // This member specifies the type of relocation entry to which the
247735617911SEd Maste // procedure linkage table refers. The d_val member holds DT_REL or
247835617911SEd Maste // DT_RELA, as appropriate. All relocations in a procedure linkage table
247935617911SEd Maste // must use the same relocation.
2480ac7ddfbfSEd Maste const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL);
2481ac7ddfbfSEd Maste
2482ac7ddfbfSEd Maste if (symbol)
2483ac7ddfbfSEd Maste return symbol->d_val;
2484ac7ddfbfSEd Maste
2485ac7ddfbfSEd Maste return 0;
2486ac7ddfbfSEd Maste }
2487ac7ddfbfSEd Maste
24884ba319b5SDimitry Andric // Returns the size of the normal plt entries and the offset of the first
24894ba319b5SDimitry Andric // normal plt entry. The 0th entry in the plt table is usually a resolution
24904ba319b5SDimitry Andric // entry which have different size in some architectures then the rest of the
24914ba319b5SDimitry Andric // plt entries.
24921c3bbb01SEd Maste static std::pair<uint64_t, uint64_t>
GetPltEntrySizeAndOffset(const ELFSectionHeader * rel_hdr,const ELFSectionHeader * plt_hdr)2493435933ddSDimitry Andric GetPltEntrySizeAndOffset(const ELFSectionHeader *rel_hdr,
2494435933ddSDimitry Andric const ELFSectionHeader *plt_hdr) {
24951c3bbb01SEd Maste const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
24961c3bbb01SEd Maste
24974ba319b5SDimitry Andric // Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are
24984ba319b5SDimitry Andric // 16 bytes. So round the entsize up by the alignment if addralign is set.
2499435933ddSDimitry Andric elf_xword plt_entsize =
2500435933ddSDimitry Andric plt_hdr->sh_addralign
2501435933ddSDimitry Andric ? llvm::alignTo(plt_hdr->sh_entsize, plt_hdr->sh_addralign)
2502435933ddSDimitry Andric : plt_hdr->sh_entsize;
25031c3bbb01SEd Maste
25044bb0738eSEd Maste // Some linkers e.g ld for arm, fill plt_hdr->sh_entsize field incorrectly.
25054bb0738eSEd Maste // PLT entries relocation code in general requires multiple instruction and
2506435933ddSDimitry Andric // should be greater than 4 bytes in most cases. Try to guess correct size
2507435933ddSDimitry Andric // just in case.
2508435933ddSDimitry Andric if (plt_entsize <= 4) {
2509435933ddSDimitry Andric // The linker haven't set the plt_hdr->sh_entsize field. Try to guess the
25104ba319b5SDimitry Andric // size of the plt entries based on the number of entries and the size of
25114ba319b5SDimitry Andric // the plt section with the assumption that the size of the 0th entry is at
25124ba319b5SDimitry Andric // least as big as the size of the normal entries and it isn't much bigger
25134ba319b5SDimitry Andric // then that.
25141c3bbb01SEd Maste if (plt_hdr->sh_addralign)
2515435933ddSDimitry Andric plt_entsize = plt_hdr->sh_size / plt_hdr->sh_addralign /
2516435933ddSDimitry Andric (num_relocations + 1) * plt_hdr->sh_addralign;
25171c3bbb01SEd Maste else
25181c3bbb01SEd Maste plt_entsize = plt_hdr->sh_size / (num_relocations + 1);
25191c3bbb01SEd Maste }
25201c3bbb01SEd Maste
25211c3bbb01SEd Maste elf_xword plt_offset = plt_hdr->sh_size - num_relocations * plt_entsize;
25221c3bbb01SEd Maste
25231c3bbb01SEd Maste return std::make_pair(plt_entsize, plt_offset);
25241c3bbb01SEd Maste }
25251c3bbb01SEd 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)2526435933ddSDimitry Andric static unsigned ParsePLTRelocations(
2527435933ddSDimitry Andric Symtab *symbol_table, user_id_t start_id, unsigned rel_type,
2528435933ddSDimitry Andric const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
2529435933ddSDimitry Andric const ELFSectionHeader *plt_hdr, const ELFSectionHeader *sym_hdr,
2530435933ddSDimitry Andric const lldb::SectionSP &plt_section_sp, DataExtractor &rel_data,
2531435933ddSDimitry Andric DataExtractor &symtab_data, DataExtractor &strtab_data) {
2532ac7ddfbfSEd Maste ELFRelocation rel(rel_type);
2533ac7ddfbfSEd Maste ELFSymbol symbol;
2534ac7ddfbfSEd Maste lldb::offset_t offset = 0;
25351c3bbb01SEd Maste
25361c3bbb01SEd Maste uint64_t plt_offset, plt_entsize;
2537435933ddSDimitry Andric std::tie(plt_entsize, plt_offset) =
2538435933ddSDimitry Andric GetPltEntrySizeAndOffset(rel_hdr, plt_hdr);
2539ac7ddfbfSEd Maste const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
2540ac7ddfbfSEd Maste
2541ac7ddfbfSEd Maste typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
2542ac7ddfbfSEd Maste reloc_info_fn reloc_type;
2543ac7ddfbfSEd Maste reloc_info_fn reloc_symbol;
2544ac7ddfbfSEd Maste
2545435933ddSDimitry Andric if (hdr->Is32Bit()) {
2546ac7ddfbfSEd Maste reloc_type = ELFRelocation::RelocType32;
2547ac7ddfbfSEd Maste reloc_symbol = ELFRelocation::RelocSymbol32;
2548435933ddSDimitry Andric } else {
2549ac7ddfbfSEd Maste reloc_type = ELFRelocation::RelocType64;
2550ac7ddfbfSEd Maste reloc_symbol = ELFRelocation::RelocSymbol64;
2551ac7ddfbfSEd Maste }
2552ac7ddfbfSEd Maste
2553ac7ddfbfSEd Maste unsigned slot_type = hdr->GetRelocationJumpSlotType();
2554ac7ddfbfSEd Maste unsigned i;
2555435933ddSDimitry Andric for (i = 0; i < num_relocations; ++i) {
2556*b5893f02SDimitry Andric if (!rel.Parse(rel_data, &offset))
2557ac7ddfbfSEd Maste break;
2558ac7ddfbfSEd Maste
2559ac7ddfbfSEd Maste if (reloc_type(rel) != slot_type)
2560ac7ddfbfSEd Maste continue;
2561ac7ddfbfSEd Maste
2562ac7ddfbfSEd Maste lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
2563ac7ddfbfSEd Maste if (!symbol.Parse(symtab_data, &symbol_offset))
2564ac7ddfbfSEd Maste break;
2565ac7ddfbfSEd Maste
2566ac7ddfbfSEd Maste const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
2567435933ddSDimitry Andric bool is_mangled =
2568435933ddSDimitry Andric symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
25691c3bbb01SEd Maste uint64_t plt_index = plt_offset + i * plt_entsize;
2570ac7ddfbfSEd Maste
2571ac7ddfbfSEd Maste Symbol jump_symbol(
2572ac7ddfbfSEd Maste i + start_id, // Symbol table index
2573ac7ddfbfSEd Maste symbol_name, // symbol name.
2574ac7ddfbfSEd Maste is_mangled, // is the symbol name mangled?
2575ac7ddfbfSEd Maste eSymbolTypeTrampoline, // Type of this symbol
2576ac7ddfbfSEd Maste false, // Is this globally visible?
2577ac7ddfbfSEd Maste false, // Is this symbol debug info?
2578ac7ddfbfSEd Maste true, // Is this symbol a trampoline?
2579ac7ddfbfSEd Maste true, // Is this symbol artificial?
2580ac7ddfbfSEd Maste plt_section_sp, // Section in which this symbol is defined or null.
2581ac7ddfbfSEd Maste plt_index, // Offset in section or symbol value.
2582ac7ddfbfSEd Maste plt_entsize, // Size in bytes of this symbol.
2583ac7ddfbfSEd Maste true, // Size is valid
25841c3bbb01SEd Maste false, // Contains linker annotations?
2585ac7ddfbfSEd Maste 0); // Symbol flags.
2586ac7ddfbfSEd Maste
2587ac7ddfbfSEd Maste symbol_table->AddSymbol(jump_symbol);
2588ac7ddfbfSEd Maste }
2589ac7ddfbfSEd Maste
2590ac7ddfbfSEd Maste return i;
2591ac7ddfbfSEd Maste }
2592ac7ddfbfSEd Maste
2593ac7ddfbfSEd Maste unsigned
ParseTrampolineSymbols(Symtab * symbol_table,user_id_t start_id,const ELFSectionHeaderInfo * rel_hdr,user_id_t rel_id)2594435933ddSDimitry Andric ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id,
2595ac7ddfbfSEd Maste const ELFSectionHeaderInfo *rel_hdr,
2596435933ddSDimitry Andric user_id_t rel_id) {
2597ac7ddfbfSEd Maste assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
2598ac7ddfbfSEd Maste
25994bb0738eSEd Maste // The link field points to the associated symbol table.
2600ac7ddfbfSEd Maste user_id_t symtab_id = rel_hdr->sh_link;
2601ac7ddfbfSEd Maste
26021c3bbb01SEd Maste // If the link field doesn't point to the appropriate symbol name table then
26031c3bbb01SEd Maste // try to find it by name as some compiler don't fill in the link fields.
26041c3bbb01SEd Maste if (!symtab_id)
26051c3bbb01SEd Maste symtab_id = GetSectionIndexByName(".dynsym");
26064bb0738eSEd Maste
26074bb0738eSEd Maste // Get PLT section. We cannot use rel_hdr->sh_info, since current linkers
26084bb0738eSEd Maste // point that to the .got.plt or .got section instead of .plt.
26094bb0738eSEd Maste user_id_t plt_id = GetSectionIndexByName(".plt");
26101c3bbb01SEd Maste
2611ac7ddfbfSEd Maste if (!symtab_id || !plt_id)
2612ac7ddfbfSEd Maste return 0;
2613ac7ddfbfSEd Maste
2614ac7ddfbfSEd Maste const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id);
2615ac7ddfbfSEd Maste if (!plt_hdr)
2616ac7ddfbfSEd Maste return 0;
2617ac7ddfbfSEd Maste
2618ac7ddfbfSEd Maste const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id);
2619ac7ddfbfSEd Maste if (!sym_hdr)
2620ac7ddfbfSEd Maste return 0;
2621ac7ddfbfSEd Maste
2622ac7ddfbfSEd Maste SectionList *section_list = m_sections_ap.get();
2623ac7ddfbfSEd Maste if (!section_list)
2624ac7ddfbfSEd Maste return 0;
2625ac7ddfbfSEd Maste
2626ac7ddfbfSEd Maste Section *rel_section = section_list->FindSectionByID(rel_id).get();
2627ac7ddfbfSEd Maste if (!rel_section)
2628ac7ddfbfSEd Maste return 0;
2629ac7ddfbfSEd Maste
2630ac7ddfbfSEd Maste SectionSP plt_section_sp(section_list->FindSectionByID(plt_id));
2631ac7ddfbfSEd Maste if (!plt_section_sp)
2632ac7ddfbfSEd Maste return 0;
2633ac7ddfbfSEd Maste
2634ac7ddfbfSEd Maste Section *symtab = section_list->FindSectionByID(symtab_id).get();
2635ac7ddfbfSEd Maste if (!symtab)
2636ac7ddfbfSEd Maste return 0;
2637ac7ddfbfSEd Maste
2638ac7ddfbfSEd Maste // sh_link points to associated string table.
2639*b5893f02SDimitry Andric Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link).get();
2640ac7ddfbfSEd Maste if (!strtab)
2641ac7ddfbfSEd Maste return 0;
2642ac7ddfbfSEd Maste
2643ac7ddfbfSEd Maste DataExtractor rel_data;
2644ac7ddfbfSEd Maste if (!ReadSectionData(rel_section, rel_data))
2645ac7ddfbfSEd Maste return 0;
2646ac7ddfbfSEd Maste
2647ac7ddfbfSEd Maste DataExtractor symtab_data;
2648ac7ddfbfSEd Maste if (!ReadSectionData(symtab, symtab_data))
2649ac7ddfbfSEd Maste return 0;
2650ac7ddfbfSEd Maste
2651ac7ddfbfSEd Maste DataExtractor strtab_data;
2652ac7ddfbfSEd Maste if (!ReadSectionData(strtab, strtab_data))
2653ac7ddfbfSEd Maste return 0;
2654ac7ddfbfSEd Maste
2655ac7ddfbfSEd Maste unsigned rel_type = PLTRelocationType();
2656ac7ddfbfSEd Maste if (!rel_type)
2657ac7ddfbfSEd Maste return 0;
2658ac7ddfbfSEd Maste
2659435933ddSDimitry Andric return ParsePLTRelocations(symbol_table, start_id, rel_type, &m_header,
2660435933ddSDimitry Andric rel_hdr, plt_hdr, sym_hdr, plt_section_sp,
2661435933ddSDimitry Andric rel_data, symtab_data, strtab_data);
2662ac7ddfbfSEd Maste }
2663ac7ddfbfSEd Maste
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)2664acac075bSDimitry Andric unsigned ObjectFileELF::ApplyRelocations(
2665435933ddSDimitry Andric Symtab *symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr,
26660127ef0fSEd Maste const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr,
26670127ef0fSEd Maste DataExtractor &rel_data, DataExtractor &symtab_data,
2668435933ddSDimitry Andric DataExtractor &debug_data, Section *rel_section) {
26690127ef0fSEd Maste ELFRelocation rel(rel_hdr->sh_type);
26700127ef0fSEd Maste lldb::addr_t offset = 0;
26710127ef0fSEd Maste const unsigned num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
26720127ef0fSEd Maste typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
26730127ef0fSEd Maste reloc_info_fn reloc_type;
26740127ef0fSEd Maste reloc_info_fn reloc_symbol;
26750127ef0fSEd Maste
2676435933ddSDimitry Andric if (hdr->Is32Bit()) {
26770127ef0fSEd Maste reloc_type = ELFRelocation::RelocType32;
26780127ef0fSEd Maste reloc_symbol = ELFRelocation::RelocSymbol32;
2679435933ddSDimitry Andric } else {
26800127ef0fSEd Maste reloc_type = ELFRelocation::RelocType64;
26810127ef0fSEd Maste reloc_symbol = ELFRelocation::RelocSymbol64;
26820127ef0fSEd Maste }
26830127ef0fSEd Maste
2684435933ddSDimitry Andric for (unsigned i = 0; i < num_relocations; ++i) {
2685*b5893f02SDimitry Andric if (!rel.Parse(rel_data, &offset))
26860127ef0fSEd Maste break;
26870127ef0fSEd Maste
26880127ef0fSEd Maste Symbol *symbol = NULL;
26890127ef0fSEd Maste
2690435933ddSDimitry Andric if (hdr->Is32Bit()) {
26910127ef0fSEd Maste switch (reloc_type(rel)) {
26920127ef0fSEd Maste case R_386_32:
26930127ef0fSEd Maste case R_386_PC32:
26940127ef0fSEd Maste default:
2695acac075bSDimitry Andric // FIXME: This asserts with this input:
2696acac075bSDimitry Andric //
2697acac075bSDimitry Andric // foo.cpp
2698acac075bSDimitry Andric // int main(int argc, char **argv) { return 0; }
2699acac075bSDimitry Andric //
2700acac075bSDimitry Andric // clang++.exe --target=i686-unknown-linux-gnu -g -c foo.cpp -o foo.o
2701acac075bSDimitry Andric //
2702acac075bSDimitry Andric // and running this on the foo.o module.
27030127ef0fSEd Maste assert(false && "unexpected relocation type");
27040127ef0fSEd Maste }
27050127ef0fSEd Maste } else {
27060127ef0fSEd Maste switch (reloc_type(rel)) {
2707*b5893f02SDimitry Andric case R_AARCH64_ABS64:
2708435933ddSDimitry Andric case R_X86_64_64: {
27090127ef0fSEd Maste symbol = symtab->FindSymbolByID(reloc_symbol(rel));
2710435933ddSDimitry Andric if (symbol) {
27111c3bbb01SEd Maste addr_t value = symbol->GetAddressRef().GetFileAddress();
27120127ef0fSEd Maste DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
2713435933ddSDimitry Andric uint64_t *dst = reinterpret_cast<uint64_t *>(
2714435933ddSDimitry Andric data_buffer_sp->GetBytes() + rel_section->GetFileOffset() +
2715435933ddSDimitry Andric ELFRelocation::RelocOffset64(rel));
2716*b5893f02SDimitry Andric uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel);
2717*b5893f02SDimitry Andric memcpy(dst, &val_offset, sizeof(uint64_t));
27180127ef0fSEd Maste }
27190127ef0fSEd Maste break;
27200127ef0fSEd Maste }
27210127ef0fSEd Maste case R_X86_64_32:
2722*b5893f02SDimitry Andric case R_X86_64_32S:
2723*b5893f02SDimitry Andric case R_AARCH64_ABS32: {
27240127ef0fSEd Maste symbol = symtab->FindSymbolByID(reloc_symbol(rel));
2725435933ddSDimitry Andric if (symbol) {
27261c3bbb01SEd Maste addr_t value = symbol->GetAddressRef().GetFileAddress();
27270127ef0fSEd Maste value += ELFRelocation::RelocAddend32(rel);
2728*b5893f02SDimitry Andric if ((reloc_type(rel) == R_X86_64_32 && (value > UINT32_MAX)) ||
27290127ef0fSEd Maste (reloc_type(rel) == R_X86_64_32S &&
2730*b5893f02SDimitry Andric ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN)) ||
2731*b5893f02SDimitry Andric (reloc_type(rel) == R_AARCH64_ABS32 &&
2732*b5893f02SDimitry Andric ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN))) {
2733*b5893f02SDimitry Andric Log *log =
2734*b5893f02SDimitry Andric lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES);
2735*b5893f02SDimitry Andric log->Printf("Failed to apply debug info relocations");
2736*b5893f02SDimitry Andric break;
2737*b5893f02SDimitry Andric }
27380127ef0fSEd Maste uint32_t truncated_addr = (value & 0xFFFFFFFF);
27390127ef0fSEd Maste DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer();
2740435933ddSDimitry Andric uint32_t *dst = reinterpret_cast<uint32_t *>(
2741435933ddSDimitry Andric data_buffer_sp->GetBytes() + rel_section->GetFileOffset() +
2742435933ddSDimitry Andric ELFRelocation::RelocOffset32(rel));
2743*b5893f02SDimitry Andric memcpy(dst, &truncated_addr, sizeof(uint32_t));
27440127ef0fSEd Maste }
27450127ef0fSEd Maste break;
27460127ef0fSEd Maste }
27470127ef0fSEd Maste case R_X86_64_PC32:
27480127ef0fSEd Maste default:
27490127ef0fSEd Maste assert(false && "unexpected relocation type");
27500127ef0fSEd Maste }
27510127ef0fSEd Maste }
27520127ef0fSEd Maste }
27530127ef0fSEd Maste
27540127ef0fSEd Maste return 0;
27550127ef0fSEd Maste }
27560127ef0fSEd Maste
RelocateDebugSections(const ELFSectionHeader * rel_hdr,user_id_t rel_id,lldb_private::Symtab * thetab)2757435933ddSDimitry Andric unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr,
2758acac075bSDimitry Andric user_id_t rel_id,
2759acac075bSDimitry Andric lldb_private::Symtab *thetab) {
27600127ef0fSEd Maste assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL);
27610127ef0fSEd Maste
27620127ef0fSEd Maste // Parse in the section list if needed.
27630127ef0fSEd Maste SectionList *section_list = GetSectionList();
27640127ef0fSEd Maste if (!section_list)
27650127ef0fSEd Maste return 0;
27660127ef0fSEd Maste
2767*b5893f02SDimitry Andric user_id_t symtab_id = rel_hdr->sh_link;
2768*b5893f02SDimitry Andric user_id_t debug_id = rel_hdr->sh_info;
27690127ef0fSEd Maste
27700127ef0fSEd Maste const ELFSectionHeader *symtab_hdr = GetSectionHeaderByIndex(symtab_id);
27710127ef0fSEd Maste if (!symtab_hdr)
27720127ef0fSEd Maste return 0;
27730127ef0fSEd Maste
27740127ef0fSEd Maste const ELFSectionHeader *debug_hdr = GetSectionHeaderByIndex(debug_id);
27750127ef0fSEd Maste if (!debug_hdr)
27760127ef0fSEd Maste return 0;
27770127ef0fSEd Maste
27780127ef0fSEd Maste Section *rel = section_list->FindSectionByID(rel_id).get();
27790127ef0fSEd Maste if (!rel)
27800127ef0fSEd Maste return 0;
27810127ef0fSEd Maste
27820127ef0fSEd Maste Section *symtab = section_list->FindSectionByID(symtab_id).get();
27830127ef0fSEd Maste if (!symtab)
27840127ef0fSEd Maste return 0;
27850127ef0fSEd Maste
27860127ef0fSEd Maste Section *debug = section_list->FindSectionByID(debug_id).get();
27870127ef0fSEd Maste if (!debug)
27880127ef0fSEd Maste return 0;
27890127ef0fSEd Maste
27900127ef0fSEd Maste DataExtractor rel_data;
27910127ef0fSEd Maste DataExtractor symtab_data;
27920127ef0fSEd Maste DataExtractor debug_data;
27930127ef0fSEd Maste
2794acac075bSDimitry Andric if (GetData(rel->GetFileOffset(), rel->GetFileSize(), rel_data) &&
2795acac075bSDimitry Andric GetData(symtab->GetFileOffset(), symtab->GetFileSize(), symtab_data) &&
2796acac075bSDimitry Andric GetData(debug->GetFileOffset(), debug->GetFileSize(), debug_data)) {
2797acac075bSDimitry Andric ApplyRelocations(thetab, &m_header, rel_hdr, symtab_hdr, debug_hdr,
2798acac075bSDimitry Andric rel_data, symtab_data, debug_data, debug);
27990127ef0fSEd Maste }
28000127ef0fSEd Maste
28010127ef0fSEd Maste return 0;
28020127ef0fSEd Maste }
28030127ef0fSEd Maste
GetSymtab()2804435933ddSDimitry Andric Symtab *ObjectFileELF::GetSymtab() {
2805ac7ddfbfSEd Maste ModuleSP module_sp(GetModule());
2806ac7ddfbfSEd Maste if (!module_sp)
2807ac7ddfbfSEd Maste return NULL;
2808ac7ddfbfSEd Maste
2809435933ddSDimitry Andric // We always want to use the main object file so we (hopefully) only have one
28104ba319b5SDimitry Andric // cached copy of our symtab, dynamic sections, etc.
2811ac7ddfbfSEd Maste ObjectFile *module_obj_file = module_sp->GetObjectFile();
2812ac7ddfbfSEd Maste if (module_obj_file && module_obj_file != this)
2813ac7ddfbfSEd Maste return module_obj_file->GetSymtab();
2814ac7ddfbfSEd Maste
2815435933ddSDimitry Andric if (m_symtab_ap.get() == NULL) {
28161c3bbb01SEd Maste SectionList *section_list = module_sp->GetSectionList();
2817ac7ddfbfSEd Maste if (!section_list)
2818ac7ddfbfSEd Maste return NULL;
2819ac7ddfbfSEd Maste
2820ac7ddfbfSEd Maste uint64_t symbol_id = 0;
28214bb0738eSEd Maste std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
2822ac7ddfbfSEd Maste
2823ac7ddfbfSEd Maste // Sharable objects and dynamic executables usually have 2 distinct symbol
2824435933ddSDimitry Andric // tables, one named ".symtab", and the other ".dynsym". The dynsym is a
28254ba319b5SDimitry Andric // smaller version of the symtab that only contains global symbols. The
28264ba319b5SDimitry Andric // information found in the dynsym is therefore also found in the symtab,
28274ba319b5SDimitry Andric // while the reverse is not necessarily true.
2828435933ddSDimitry Andric Section *symtab =
2829435933ddSDimitry Andric section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get();
2830435933ddSDimitry Andric if (!symtab) {
2831435933ddSDimitry Andric // The symtab section is non-allocable and can be stripped, so if it
28324ba319b5SDimitry Andric // doesn't exist then use the dynsym section which should always be
28334ba319b5SDimitry Andric // there.
2834435933ddSDimitry Andric symtab =
2835435933ddSDimitry Andric section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true)
2836435933ddSDimitry Andric .get();
2837ac7ddfbfSEd Maste }
2838435933ddSDimitry Andric if (symtab) {
28399f2f44ceSEd Maste m_symtab_ap.reset(new Symtab(symtab->GetObjectFile()));
2840ac7ddfbfSEd Maste symbol_id += ParseSymbolTable(m_symtab_ap.get(), symbol_id, symtab);
28419f2f44ceSEd Maste }
2842ac7ddfbfSEd Maste
284335617911SEd Maste // DT_JMPREL
2844435933ddSDimitry Andric // If present, this entry's d_ptr member holds the address of
2845435933ddSDimitry Andric // relocation
2846435933ddSDimitry Andric // entries associated solely with the procedure linkage table.
2847435933ddSDimitry Andric // Separating
284835617911SEd Maste // these relocation entries lets the dynamic linker ignore them during
284935617911SEd Maste // process initialization, if lazy binding is enabled. If this entry is
285035617911SEd Maste // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must
285135617911SEd Maste // also be present.
2852ac7ddfbfSEd Maste const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL);
2853435933ddSDimitry Andric if (symbol) {
285435617911SEd Maste // Synthesize trampoline symbols to help navigate the PLT.
2855ac7ddfbfSEd Maste addr_t addr = symbol->d_ptr;
2856435933ddSDimitry Andric Section *reloc_section =
2857435933ddSDimitry Andric section_list->FindSectionContainingFileAddress(addr).get();
2858435933ddSDimitry Andric if (reloc_section) {
2859ac7ddfbfSEd Maste user_id_t reloc_id = reloc_section->GetID();
2860435933ddSDimitry Andric const ELFSectionHeaderInfo *reloc_header =
2861435933ddSDimitry Andric GetSectionHeaderByIndex(reloc_id);
2862ac7ddfbfSEd Maste assert(reloc_header);
2863ac7ddfbfSEd Maste
28649f2f44ceSEd Maste if (m_symtab_ap == nullptr)
28659f2f44ceSEd Maste m_symtab_ap.reset(new Symtab(reloc_section->GetObjectFile()));
28669f2f44ceSEd Maste
2867435933ddSDimitry Andric ParseTrampolineSymbols(m_symtab_ap.get(), symbol_id, reloc_header,
2868435933ddSDimitry Andric reloc_id);
2869ac7ddfbfSEd Maste }
2870ac7ddfbfSEd Maste }
28719f2f44ceSEd Maste
28724bb0738eSEd Maste DWARFCallFrameInfo *eh_frame = GetUnwindTable().GetEHFrameInfo();
2873435933ddSDimitry Andric if (eh_frame) {
28744bb0738eSEd Maste if (m_symtab_ap == nullptr)
28754bb0738eSEd Maste m_symtab_ap.reset(new Symtab(this));
28764bb0738eSEd Maste ParseUnwindSymbols(m_symtab_ap.get(), eh_frame);
28774bb0738eSEd Maste }
28784bb0738eSEd Maste
2879435933ddSDimitry Andric // If we still don't have any symtab then create an empty instance to avoid
28804ba319b5SDimitry Andric // do the section lookup next time.
28819f2f44ceSEd Maste if (m_symtab_ap == nullptr)
28829f2f44ceSEd Maste m_symtab_ap.reset(new Symtab(this));
28839f2f44ceSEd Maste
28841c3bbb01SEd Maste m_symtab_ap->CalculateSymbolSizes();
2885ac7ddfbfSEd Maste }
28860127ef0fSEd Maste
2887acac075bSDimitry Andric return m_symtab_ap.get();
2888acac075bSDimitry Andric }
2889acac075bSDimitry Andric
RelocateSection(lldb_private::Section * section)2890acac075bSDimitry Andric void ObjectFileELF::RelocateSection(lldb_private::Section *section)
2891acac075bSDimitry Andric {
2892acac075bSDimitry Andric static const char *debug_prefix = ".debug";
2893acac075bSDimitry Andric
28944ba319b5SDimitry Andric // Set relocated bit so we stop getting called, regardless of whether we
28954ba319b5SDimitry Andric // actually relocate.
2896acac075bSDimitry Andric section->SetIsRelocated(true);
2897acac075bSDimitry Andric
2898acac075bSDimitry Andric // We only relocate in ELF relocatable files
2899acac075bSDimitry Andric if (CalculateType() != eTypeObjectFile)
2900acac075bSDimitry Andric return;
2901acac075bSDimitry Andric
2902acac075bSDimitry Andric const char *section_name = section->GetName().GetCString();
2903acac075bSDimitry Andric // Can't relocate that which can't be named
2904acac075bSDimitry Andric if (section_name == nullptr)
2905acac075bSDimitry Andric return;
2906acac075bSDimitry Andric
2907acac075bSDimitry Andric // We don't relocate non-debug sections at the moment
2908acac075bSDimitry Andric if (strncmp(section_name, debug_prefix, strlen(debug_prefix)))
2909acac075bSDimitry Andric return;
2910acac075bSDimitry Andric
2911acac075bSDimitry Andric // Relocation section names to look for
2912acac075bSDimitry Andric std::string needle = std::string(".rel") + section_name;
2913acac075bSDimitry Andric std::string needlea = std::string(".rela") + section_name;
2914acac075bSDimitry Andric
29150127ef0fSEd Maste for (SectionHeaderCollIter I = m_section_headers.begin();
2916435933ddSDimitry Andric I != m_section_headers.end(); ++I) {
2917435933ddSDimitry Andric if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL) {
2918acac075bSDimitry Andric const char *hay_name = I->section_name.GetCString();
2919acac075bSDimitry Andric if (hay_name == nullptr)
2920acac075bSDimitry Andric continue;
2921acac075bSDimitry Andric if (needle == hay_name || needlea == hay_name) {
29220127ef0fSEd Maste const ELFSectionHeader &reloc_header = *I;
29230127ef0fSEd Maste user_id_t reloc_id = SectionIndex(I);
2924acac075bSDimitry Andric RelocateDebugSections(&reloc_header, reloc_id, GetSymtab());
2925acac075bSDimitry Andric break;
29260127ef0fSEd Maste }
29270127ef0fSEd Maste }
29280127ef0fSEd Maste }
29290127ef0fSEd Maste }
2930ac7ddfbfSEd Maste
ParseUnwindSymbols(Symtab * symbol_table,DWARFCallFrameInfo * eh_frame)2931435933ddSDimitry Andric void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table,
2932435933ddSDimitry Andric DWARFCallFrameInfo *eh_frame) {
29334bb0738eSEd Maste SectionList *section_list = GetSectionList();
293435617911SEd Maste if (!section_list)
29354bb0738eSEd Maste return;
293635617911SEd Maste
2937435933ddSDimitry Andric // First we save the new symbols into a separate list and add them to the
29384ba319b5SDimitry Andric // symbol table after we colleced all symbols we want to add. This is
29394ba319b5SDimitry Andric // neccessary because adding a new symbol invalidates the internal index of
29404ba319b5SDimitry Andric // the symtab what causing the next lookup to be slow because it have to
29414ba319b5SDimitry Andric // recalculate the index first.
29424bb0738eSEd Maste std::vector<Symbol> new_symbols;
29434bb0738eSEd Maste
2944435933ddSDimitry Andric eh_frame->ForEachFDEEntries([this, symbol_table, section_list, &new_symbols](
2945435933ddSDimitry Andric lldb::addr_t file_addr, uint32_t size, dw_offset_t) {
29464bb0738eSEd Maste Symbol *symbol = symbol_table->FindSymbolAtFileAddress(file_addr);
2947435933ddSDimitry Andric if (symbol) {
2948435933ddSDimitry Andric if (!symbol->GetByteSizeIsValid()) {
29494bb0738eSEd Maste symbol->SetByteSize(size);
29504bb0738eSEd Maste symbol->SetSizeIsSynthesized(true);
29514bb0738eSEd Maste }
2952435933ddSDimitry Andric } else {
2953435933ddSDimitry Andric SectionSP section_sp =
2954435933ddSDimitry Andric section_list->FindSectionContainingFileAddress(file_addr);
2955435933ddSDimitry Andric if (section_sp) {
29564bb0738eSEd Maste addr_t offset = file_addr - section_sp->GetFileAddress();
29574bb0738eSEd Maste const char *symbol_name = GetNextSyntheticSymbolName().GetCString();
29584bb0738eSEd Maste uint64_t symbol_id = symbol_table->GetNumSymbols();
295935617911SEd Maste Symbol eh_symbol(
296035617911SEd Maste symbol_id, // Symbol table index.
29614bb0738eSEd Maste symbol_name, // Symbol name.
296235617911SEd Maste false, // Is the symbol name mangled?
296335617911SEd Maste eSymbolTypeCode, // Type of this symbol.
296435617911SEd Maste true, // Is this globally visible?
296535617911SEd Maste false, // Is this symbol debug info?
296635617911SEd Maste false, // Is this symbol a trampoline?
296735617911SEd Maste true, // Is this symbol artificial?
29684bb0738eSEd Maste section_sp, // Section in which this symbol is defined or null.
296935617911SEd Maste offset, // Offset in section or symbol value.
29704bb0738eSEd Maste 0, // Size: Don't specify the size as an FDE can
29714bb0738eSEd Maste false, // Size is valid: cover multiple symbols.
29721c3bbb01SEd Maste false, // Contains linker annotations?
297335617911SEd Maste 0); // Symbol flags.
29744bb0738eSEd Maste new_symbols.push_back(eh_symbol);
297535617911SEd Maste }
297635617911SEd Maste }
29774bb0738eSEd Maste return true;
29784bb0738eSEd Maste });
297935617911SEd Maste
29804bb0738eSEd Maste for (const Symbol &s : new_symbols)
29814bb0738eSEd Maste symbol_table->AddSymbol(s);
29824bb0738eSEd Maste }
298335617911SEd Maste
IsStripped()2984435933ddSDimitry Andric bool ObjectFileELF::IsStripped() {
2985ac7ddfbfSEd Maste // TODO: determine this for ELF
2986ac7ddfbfSEd Maste return false;
2987ac7ddfbfSEd Maste }
2988ac7ddfbfSEd Maste
2989ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
2990ac7ddfbfSEd Maste // Dump
2991ac7ddfbfSEd Maste //
2992ac7ddfbfSEd Maste // Dump the specifics of the runtime file container (such as any headers
2993ac7ddfbfSEd Maste // segments, sections, etc).
2994ac7ddfbfSEd Maste //----------------------------------------------------------------------
Dump(Stream * s)2995435933ddSDimitry Andric void ObjectFileELF::Dump(Stream *s) {
29964bb0738eSEd Maste ModuleSP module_sp(GetModule());
2997435933ddSDimitry Andric if (!module_sp) {
29984bb0738eSEd Maste return;
29994bb0738eSEd Maste }
30004bb0738eSEd Maste
30014bb0738eSEd Maste std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
30024bb0738eSEd Maste s->Printf("%p: ", static_cast<void *>(this));
30034bb0738eSEd Maste s->Indent();
30044bb0738eSEd Maste s->PutCString("ObjectFileELF");
30054bb0738eSEd Maste
3006*b5893f02SDimitry Andric ArchSpec header_arch = GetArchitecture();
30074bb0738eSEd Maste
3008435933ddSDimitry Andric *s << ", file = '" << m_file
3009435933ddSDimitry Andric << "', arch = " << header_arch.GetArchitectureName() << "\n";
30104bb0738eSEd Maste
3011ac7ddfbfSEd Maste DumpELFHeader(s, m_header);
3012ac7ddfbfSEd Maste s->EOL();
3013ac7ddfbfSEd Maste DumpELFProgramHeaders(s);
3014ac7ddfbfSEd Maste s->EOL();
3015ac7ddfbfSEd Maste DumpELFSectionHeaders(s);
3016ac7ddfbfSEd Maste s->EOL();
3017ac7ddfbfSEd Maste SectionList *section_list = GetSectionList();
3018ac7ddfbfSEd Maste if (section_list)
3019ac7ddfbfSEd Maste section_list->Dump(s, NULL, true, UINT32_MAX);
3020ac7ddfbfSEd Maste Symtab *symtab = GetSymtab();
3021ac7ddfbfSEd Maste if (symtab)
3022ac7ddfbfSEd Maste symtab->Dump(s, NULL, eSortOrderNone);
3023ac7ddfbfSEd Maste s->EOL();
3024ac7ddfbfSEd Maste DumpDependentModules(s);
3025ac7ddfbfSEd Maste s->EOL();
3026ac7ddfbfSEd Maste }
3027ac7ddfbfSEd Maste
3028ac7ddfbfSEd Maste //----------------------------------------------------------------------
3029ac7ddfbfSEd Maste // DumpELFHeader
3030ac7ddfbfSEd Maste //
3031ac7ddfbfSEd Maste // Dump the ELF header to the specified output stream
3032ac7ddfbfSEd Maste //----------------------------------------------------------------------
DumpELFHeader(Stream * s,const ELFHeader & header)3033435933ddSDimitry Andric void ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) {
3034ac7ddfbfSEd Maste s->PutCString("ELF Header\n");
3035ac7ddfbfSEd Maste s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]);
3036435933ddSDimitry Andric s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG1],
3037435933ddSDimitry Andric header.e_ident[EI_MAG1]);
3038435933ddSDimitry Andric s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG2],
3039435933ddSDimitry Andric header.e_ident[EI_MAG2]);
3040435933ddSDimitry Andric s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG3],
3041435933ddSDimitry Andric header.e_ident[EI_MAG3]);
3042ac7ddfbfSEd Maste
3043ac7ddfbfSEd Maste s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]);
3044ac7ddfbfSEd Maste s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]);
3045ac7ddfbfSEd Maste DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]);
3046ac7ddfbfSEd Maste s->Printf("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]);
3047ac7ddfbfSEd Maste s->Printf("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]);
3048ac7ddfbfSEd Maste
3049ac7ddfbfSEd Maste s->Printf("e_type = 0x%4.4x ", header.e_type);
3050ac7ddfbfSEd Maste DumpELFHeader_e_type(s, header.e_type);
3051ac7ddfbfSEd Maste s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine);
3052ac7ddfbfSEd Maste s->Printf("e_version = 0x%8.8x\n", header.e_version);
3053ac7ddfbfSEd Maste s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry);
3054ac7ddfbfSEd Maste s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff);
3055ac7ddfbfSEd Maste s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff);
3056ac7ddfbfSEd Maste s->Printf("e_flags = 0x%8.8x\n", header.e_flags);
3057ac7ddfbfSEd Maste s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize);
3058ac7ddfbfSEd Maste s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize);
3059f678e45dSDimitry Andric s->Printf("e_phnum = 0x%8.8x\n", header.e_phnum);
3060ac7ddfbfSEd Maste s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize);
3061f678e45dSDimitry Andric s->Printf("e_shnum = 0x%8.8x\n", header.e_shnum);
3062f678e45dSDimitry Andric s->Printf("e_shstrndx = 0x%8.8x\n", header.e_shstrndx);
3063ac7ddfbfSEd Maste }
3064ac7ddfbfSEd Maste
3065ac7ddfbfSEd Maste //----------------------------------------------------------------------
3066ac7ddfbfSEd Maste // DumpELFHeader_e_type
3067ac7ddfbfSEd Maste //
3068ac7ddfbfSEd Maste // Dump an token value for the ELF header member e_type
3069ac7ddfbfSEd Maste //----------------------------------------------------------------------
DumpELFHeader_e_type(Stream * s,elf_half e_type)3070435933ddSDimitry Andric void ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type) {
3071435933ddSDimitry Andric switch (e_type) {
3072435933ddSDimitry Andric case ET_NONE:
3073435933ddSDimitry Andric *s << "ET_NONE";
3074435933ddSDimitry Andric break;
3075435933ddSDimitry Andric case ET_REL:
3076435933ddSDimitry Andric *s << "ET_REL";
3077435933ddSDimitry Andric break;
3078435933ddSDimitry Andric case ET_EXEC:
3079435933ddSDimitry Andric *s << "ET_EXEC";
3080435933ddSDimitry Andric break;
3081435933ddSDimitry Andric case ET_DYN:
3082435933ddSDimitry Andric *s << "ET_DYN";
3083435933ddSDimitry Andric break;
3084435933ddSDimitry Andric case ET_CORE:
3085435933ddSDimitry Andric *s << "ET_CORE";
3086435933ddSDimitry Andric break;
3087ac7ddfbfSEd Maste default:
3088ac7ddfbfSEd Maste break;
3089ac7ddfbfSEd Maste }
3090ac7ddfbfSEd Maste }
3091ac7ddfbfSEd Maste
3092ac7ddfbfSEd Maste //----------------------------------------------------------------------
3093ac7ddfbfSEd Maste // DumpELFHeader_e_ident_EI_DATA
3094ac7ddfbfSEd Maste //
3095ac7ddfbfSEd Maste // Dump an token value for the ELF header member e_ident[EI_DATA]
3096ac7ddfbfSEd Maste //----------------------------------------------------------------------
DumpELFHeader_e_ident_EI_DATA(Stream * s,unsigned char ei_data)3097435933ddSDimitry Andric void ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s,
3098435933ddSDimitry Andric unsigned char ei_data) {
3099435933ddSDimitry Andric switch (ei_data) {
3100435933ddSDimitry Andric case ELFDATANONE:
3101435933ddSDimitry Andric *s << "ELFDATANONE";
3102435933ddSDimitry Andric break;
3103435933ddSDimitry Andric case ELFDATA2LSB:
3104435933ddSDimitry Andric *s << "ELFDATA2LSB - Little Endian";
3105435933ddSDimitry Andric break;
3106435933ddSDimitry Andric case ELFDATA2MSB:
3107435933ddSDimitry Andric *s << "ELFDATA2MSB - Big Endian";
3108435933ddSDimitry Andric break;
3109ac7ddfbfSEd Maste default:
3110ac7ddfbfSEd Maste break;
3111ac7ddfbfSEd Maste }
3112ac7ddfbfSEd Maste }
3113ac7ddfbfSEd Maste
3114ac7ddfbfSEd Maste //----------------------------------------------------------------------
3115ac7ddfbfSEd Maste // DumpELFProgramHeader
3116ac7ddfbfSEd Maste //
3117ac7ddfbfSEd Maste // Dump a single ELF program header to the specified output stream
3118ac7ddfbfSEd Maste //----------------------------------------------------------------------
DumpELFProgramHeader(Stream * s,const ELFProgramHeader & ph)3119435933ddSDimitry Andric void ObjectFileELF::DumpELFProgramHeader(Stream *s,
3120435933ddSDimitry Andric const ELFProgramHeader &ph) {
3121ac7ddfbfSEd Maste DumpELFProgramHeader_p_type(s, ph.p_type);
3122435933ddSDimitry Andric s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset,
3123435933ddSDimitry Andric ph.p_vaddr, ph.p_paddr);
3124435933ddSDimitry Andric s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8x (", ph.p_filesz, ph.p_memsz,
3125435933ddSDimitry Andric ph.p_flags);
3126ac7ddfbfSEd Maste
3127ac7ddfbfSEd Maste DumpELFProgramHeader_p_flags(s, ph.p_flags);
3128ac7ddfbfSEd Maste s->Printf(") %8.8" PRIx64, ph.p_align);
3129ac7ddfbfSEd Maste }
3130ac7ddfbfSEd Maste
3131ac7ddfbfSEd Maste //----------------------------------------------------------------------
3132ac7ddfbfSEd Maste // DumpELFProgramHeader_p_type
3133ac7ddfbfSEd Maste //
31344ba319b5SDimitry Andric // Dump an token value for the ELF program header member p_type which describes
31354ba319b5SDimitry Andric // the type of the program header
3136ac7ddfbfSEd Maste // ----------------------------------------------------------------------
DumpELFProgramHeader_p_type(Stream * s,elf_word p_type)3137435933ddSDimitry Andric void ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) {
3138ac7ddfbfSEd Maste const int kStrWidth = 15;
3139435933ddSDimitry Andric switch (p_type) {
3140ac7ddfbfSEd Maste CASE_AND_STREAM(s, PT_NULL, kStrWidth);
3141ac7ddfbfSEd Maste CASE_AND_STREAM(s, PT_LOAD, kStrWidth);
3142ac7ddfbfSEd Maste CASE_AND_STREAM(s, PT_DYNAMIC, kStrWidth);
3143ac7ddfbfSEd Maste CASE_AND_STREAM(s, PT_INTERP, kStrWidth);
3144ac7ddfbfSEd Maste CASE_AND_STREAM(s, PT_NOTE, kStrWidth);
3145ac7ddfbfSEd Maste CASE_AND_STREAM(s, PT_SHLIB, kStrWidth);
3146ac7ddfbfSEd Maste CASE_AND_STREAM(s, PT_PHDR, kStrWidth);
3147ac7ddfbfSEd Maste CASE_AND_STREAM(s, PT_TLS, kStrWidth);
3148ac7ddfbfSEd Maste CASE_AND_STREAM(s, PT_GNU_EH_FRAME, kStrWidth);
3149ac7ddfbfSEd Maste default:
3150ac7ddfbfSEd Maste s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, "");
3151ac7ddfbfSEd Maste break;
3152ac7ddfbfSEd Maste }
3153ac7ddfbfSEd Maste }
3154ac7ddfbfSEd Maste
3155ac7ddfbfSEd Maste //----------------------------------------------------------------------
3156ac7ddfbfSEd Maste // DumpELFProgramHeader_p_flags
3157ac7ddfbfSEd Maste //
3158ac7ddfbfSEd Maste // Dump an token value for the ELF program header member p_flags
3159ac7ddfbfSEd Maste //----------------------------------------------------------------------
DumpELFProgramHeader_p_flags(Stream * s,elf_word p_flags)3160435933ddSDimitry Andric void ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) {
3161ac7ddfbfSEd Maste *s << ((p_flags & PF_X) ? "PF_X" : " ")
3162ac7ddfbfSEd Maste << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ')
3163ac7ddfbfSEd Maste << ((p_flags & PF_W) ? "PF_W" : " ")
3164ac7ddfbfSEd Maste << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ')
3165ac7ddfbfSEd Maste << ((p_flags & PF_R) ? "PF_R" : " ");
3166ac7ddfbfSEd Maste }
3167ac7ddfbfSEd Maste
3168ac7ddfbfSEd Maste //----------------------------------------------------------------------
3169ac7ddfbfSEd Maste // DumpELFProgramHeaders
3170ac7ddfbfSEd Maste //
3171ac7ddfbfSEd Maste // Dump all of the ELF program header to the specified output stream
3172ac7ddfbfSEd Maste //----------------------------------------------------------------------
DumpELFProgramHeaders(Stream * s)3173435933ddSDimitry Andric void ObjectFileELF::DumpELFProgramHeaders(Stream *s) {
31741c3bbb01SEd Maste if (!ParseProgramHeaders())
31751c3bbb01SEd Maste return;
31761c3bbb01SEd Maste
3177ac7ddfbfSEd Maste s->PutCString("Program Headers\n");
3178ac7ddfbfSEd Maste s->PutCString("IDX p_type p_offset p_vaddr p_paddr "
3179ac7ddfbfSEd Maste "p_filesz p_memsz p_flags p_align\n");
3180ac7ddfbfSEd Maste s->PutCString("==== --------------- -------- -------- -------- "
3181ac7ddfbfSEd Maste "-------- -------- ------------------------- --------\n");
3182ac7ddfbfSEd Maste
3183*b5893f02SDimitry Andric for (const auto &H : llvm::enumerate(m_program_headers)) {
3184*b5893f02SDimitry Andric s->Format("[{0,2}] ", H.index());
3185*b5893f02SDimitry Andric ObjectFileELF::DumpELFProgramHeader(s, H.value());
3186ac7ddfbfSEd Maste s->EOL();
3187ac7ddfbfSEd Maste }
3188ac7ddfbfSEd Maste }
3189ac7ddfbfSEd Maste
3190ac7ddfbfSEd Maste //----------------------------------------------------------------------
3191ac7ddfbfSEd Maste // DumpELFSectionHeader
3192ac7ddfbfSEd Maste //
3193ac7ddfbfSEd Maste // Dump a single ELF section header to the specified output stream
3194ac7ddfbfSEd Maste //----------------------------------------------------------------------
DumpELFSectionHeader(Stream * s,const ELFSectionHeaderInfo & sh)3195435933ddSDimitry Andric void ObjectFileELF::DumpELFSectionHeader(Stream *s,
3196435933ddSDimitry Andric const ELFSectionHeaderInfo &sh) {
3197ac7ddfbfSEd Maste s->Printf("%8.8x ", sh.sh_name);
3198ac7ddfbfSEd Maste DumpELFSectionHeader_sh_type(s, sh.sh_type);
3199ac7ddfbfSEd Maste s->Printf(" %8.8" PRIx64 " (", sh.sh_flags);
3200ac7ddfbfSEd Maste DumpELFSectionHeader_sh_flags(s, sh.sh_flags);
3201435933ddSDimitry Andric s->Printf(") %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addr,
3202435933ddSDimitry Andric sh.sh_offset, sh.sh_size);
3203ac7ddfbfSEd Maste s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info);
3204ac7ddfbfSEd Maste s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize);
3205ac7ddfbfSEd Maste }
3206ac7ddfbfSEd Maste
3207ac7ddfbfSEd Maste //----------------------------------------------------------------------
3208ac7ddfbfSEd Maste // DumpELFSectionHeader_sh_type
3209ac7ddfbfSEd Maste //
3210ac7ddfbfSEd Maste // Dump an token value for the ELF section header member sh_type which
3211ac7ddfbfSEd Maste // describes the type of the section
3212ac7ddfbfSEd Maste //----------------------------------------------------------------------
DumpELFSectionHeader_sh_type(Stream * s,elf_word sh_type)3213435933ddSDimitry Andric void ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type) {
3214ac7ddfbfSEd Maste const int kStrWidth = 12;
3215435933ddSDimitry Andric switch (sh_type) {
3216ac7ddfbfSEd Maste CASE_AND_STREAM(s, SHT_NULL, kStrWidth);
3217ac7ddfbfSEd Maste CASE_AND_STREAM(s, SHT_PROGBITS, kStrWidth);
3218ac7ddfbfSEd Maste CASE_AND_STREAM(s, SHT_SYMTAB, kStrWidth);
3219ac7ddfbfSEd Maste CASE_AND_STREAM(s, SHT_STRTAB, kStrWidth);
3220ac7ddfbfSEd Maste CASE_AND_STREAM(s, SHT_RELA, kStrWidth);
3221ac7ddfbfSEd Maste CASE_AND_STREAM(s, SHT_HASH, kStrWidth);
3222ac7ddfbfSEd Maste CASE_AND_STREAM(s, SHT_DYNAMIC, kStrWidth);
3223ac7ddfbfSEd Maste CASE_AND_STREAM(s, SHT_NOTE, kStrWidth);
3224ac7ddfbfSEd Maste CASE_AND_STREAM(s, SHT_NOBITS, kStrWidth);
3225ac7ddfbfSEd Maste CASE_AND_STREAM(s, SHT_REL, kStrWidth);
3226ac7ddfbfSEd Maste CASE_AND_STREAM(s, SHT_SHLIB, kStrWidth);
3227ac7ddfbfSEd Maste CASE_AND_STREAM(s, SHT_DYNSYM, kStrWidth);
3228ac7ddfbfSEd Maste CASE_AND_STREAM(s, SHT_LOPROC, kStrWidth);
3229ac7ddfbfSEd Maste CASE_AND_STREAM(s, SHT_HIPROC, kStrWidth);
3230ac7ddfbfSEd Maste CASE_AND_STREAM(s, SHT_LOUSER, kStrWidth);
3231ac7ddfbfSEd Maste CASE_AND_STREAM(s, SHT_HIUSER, kStrWidth);
3232ac7ddfbfSEd Maste default:
3233ac7ddfbfSEd Maste s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, "");
3234ac7ddfbfSEd Maste break;
3235ac7ddfbfSEd Maste }
3236ac7ddfbfSEd Maste }
3237ac7ddfbfSEd Maste
3238ac7ddfbfSEd Maste //----------------------------------------------------------------------
3239ac7ddfbfSEd Maste // DumpELFSectionHeader_sh_flags
3240ac7ddfbfSEd Maste //
3241ac7ddfbfSEd Maste // Dump an token value for the ELF section header member sh_flags
3242ac7ddfbfSEd Maste //----------------------------------------------------------------------
DumpELFSectionHeader_sh_flags(Stream * s,elf_xword sh_flags)3243435933ddSDimitry Andric void ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s,
3244435933ddSDimitry Andric elf_xword sh_flags) {
3245ac7ddfbfSEd Maste *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
3246ac7ddfbfSEd Maste << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
3247ac7ddfbfSEd Maste << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ")
3248ac7ddfbfSEd Maste << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ')
3249ac7ddfbfSEd Maste << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " ");
3250ac7ddfbfSEd Maste }
3251ac7ddfbfSEd Maste
3252ac7ddfbfSEd Maste //----------------------------------------------------------------------
3253ac7ddfbfSEd Maste // DumpELFSectionHeaders
3254ac7ddfbfSEd Maste //
3255ac7ddfbfSEd Maste // Dump all of the ELF section header to the specified output stream
3256ac7ddfbfSEd Maste //----------------------------------------------------------------------
DumpELFSectionHeaders(Stream * s)3257435933ddSDimitry Andric void ObjectFileELF::DumpELFSectionHeaders(Stream *s) {
3258ac7ddfbfSEd Maste if (!ParseSectionHeaders())
3259ac7ddfbfSEd Maste return;
3260ac7ddfbfSEd Maste
3261ac7ddfbfSEd Maste s->PutCString("Section Headers\n");
3262ac7ddfbfSEd Maste s->PutCString("IDX name type flags "
3263ac7ddfbfSEd Maste "addr offset size link info addralgn "
3264ac7ddfbfSEd Maste "entsize Name\n");
3265ac7ddfbfSEd Maste s->PutCString("==== -------- ------------ -------------------------------- "
3266ac7ddfbfSEd Maste "-------- -------- -------- -------- -------- -------- "
3267ac7ddfbfSEd Maste "-------- ====================\n");
3268ac7ddfbfSEd Maste
3269ac7ddfbfSEd Maste uint32_t idx = 0;
3270ac7ddfbfSEd Maste for (SectionHeaderCollConstIter I = m_section_headers.begin();
3271435933ddSDimitry Andric I != m_section_headers.end(); ++I, ++idx) {
3272ac7ddfbfSEd Maste s->Printf("[%2u] ", idx);
3273ac7ddfbfSEd Maste ObjectFileELF::DumpELFSectionHeader(s, *I);
3274ac7ddfbfSEd Maste const char *section_name = I->section_name.AsCString("");
3275ac7ddfbfSEd Maste if (section_name)
3276ac7ddfbfSEd Maste *s << ' ' << section_name << "\n";
3277ac7ddfbfSEd Maste }
3278ac7ddfbfSEd Maste }
3279ac7ddfbfSEd Maste
DumpDependentModules(lldb_private::Stream * s)3280435933ddSDimitry Andric void ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) {
3281ac7ddfbfSEd Maste size_t num_modules = ParseDependentModules();
3282ac7ddfbfSEd Maste
3283435933ddSDimitry Andric if (num_modules > 0) {
3284ac7ddfbfSEd Maste s->PutCString("Dependent Modules:\n");
3285435933ddSDimitry Andric for (unsigned i = 0; i < num_modules; ++i) {
3286ac7ddfbfSEd Maste const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i);
3287ac7ddfbfSEd Maste s->Printf(" %s\n", spec.GetFilename().GetCString());
3288ac7ddfbfSEd Maste }
3289ac7ddfbfSEd Maste }
3290ac7ddfbfSEd Maste }
3291ac7ddfbfSEd Maste
GetArchitecture()3292*b5893f02SDimitry Andric ArchSpec ObjectFileELF::GetArchitecture() {
3293ac7ddfbfSEd Maste if (!ParseHeader())
3294*b5893f02SDimitry Andric return ArchSpec();
3295ac7ddfbfSEd Maste
3296435933ddSDimitry Andric if (m_section_headers.empty()) {
32970127ef0fSEd Maste // Allow elf notes to be parsed which may affect the detected architecture.
32980127ef0fSEd Maste ParseSectionHeaders();
32990127ef0fSEd Maste }
33000127ef0fSEd Maste
3301435933ddSDimitry Andric if (CalculateType() == eTypeCoreFile &&
3302435933ddSDimitry Andric m_arch_spec.TripleOSIsUnspecifiedUnknown()) {
3303435933ddSDimitry Andric // Core files don't have section headers yet they have PT_NOTE program
33044ba319b5SDimitry Andric // headers that might shed more light on the architecture
3305*b5893f02SDimitry Andric for (const elf::ELFProgramHeader &H : ProgramHeaders()) {
3306*b5893f02SDimitry Andric if (H.p_type != PT_NOTE || H.p_offset == 0 || H.p_filesz == 0)
3307*b5893f02SDimitry Andric continue;
33089f2f44ceSEd Maste DataExtractor data;
3309*b5893f02SDimitry Andric if (data.SetData(m_data, H.p_offset, H.p_filesz) == H.p_filesz) {
3310*b5893f02SDimitry Andric UUID uuid;
33119f2f44ceSEd Maste RefineModuleDetailsFromNote(data, m_arch_spec, uuid);
33129f2f44ceSEd Maste }
33139f2f44ceSEd Maste }
33149f2f44ceSEd Maste }
3315*b5893f02SDimitry Andric return m_arch_spec;
3316ac7ddfbfSEd Maste }
3317ac7ddfbfSEd Maste
CalculateType()3318435933ddSDimitry Andric ObjectFile::Type ObjectFileELF::CalculateType() {
3319435933ddSDimitry Andric switch (m_header.e_type) {
3320ac7ddfbfSEd Maste case llvm::ELF::ET_NONE:
3321ac7ddfbfSEd Maste // 0 - No file type
3322ac7ddfbfSEd Maste return eTypeUnknown;
3323ac7ddfbfSEd Maste
3324ac7ddfbfSEd Maste case llvm::ELF::ET_REL:
3325ac7ddfbfSEd Maste // 1 - Relocatable file
3326ac7ddfbfSEd Maste return eTypeObjectFile;
3327ac7ddfbfSEd Maste
3328ac7ddfbfSEd Maste case llvm::ELF::ET_EXEC:
3329ac7ddfbfSEd Maste // 2 - Executable file
3330ac7ddfbfSEd Maste return eTypeExecutable;
3331ac7ddfbfSEd Maste
3332ac7ddfbfSEd Maste case llvm::ELF::ET_DYN:
3333ac7ddfbfSEd Maste // 3 - Shared object file
3334ac7ddfbfSEd Maste return eTypeSharedLibrary;
3335ac7ddfbfSEd Maste
3336ac7ddfbfSEd Maste case ET_CORE:
3337ac7ddfbfSEd Maste // 4 - Core file
3338ac7ddfbfSEd Maste return eTypeCoreFile;
3339ac7ddfbfSEd Maste
3340ac7ddfbfSEd Maste default:
3341ac7ddfbfSEd Maste break;
3342ac7ddfbfSEd Maste }
3343ac7ddfbfSEd Maste return eTypeUnknown;
3344ac7ddfbfSEd Maste }
3345ac7ddfbfSEd Maste
CalculateStrata()3346435933ddSDimitry Andric ObjectFile::Strata ObjectFileELF::CalculateStrata() {
3347435933ddSDimitry Andric switch (m_header.e_type) {
3348ac7ddfbfSEd Maste case llvm::ELF::ET_NONE:
3349ac7ddfbfSEd Maste // 0 - No file type
3350ac7ddfbfSEd Maste return eStrataUnknown;
3351ac7ddfbfSEd Maste
3352ac7ddfbfSEd Maste case llvm::ELF::ET_REL:
3353ac7ddfbfSEd Maste // 1 - Relocatable file
3354ac7ddfbfSEd Maste return eStrataUnknown;
3355ac7ddfbfSEd Maste
3356ac7ddfbfSEd Maste case llvm::ELF::ET_EXEC:
3357ac7ddfbfSEd Maste // 2 - Executable file
3358ac7ddfbfSEd Maste // TODO: is there any way to detect that an executable is a kernel
33594ba319b5SDimitry Andric // related executable by inspecting the program headers, section headers,
33604ba319b5SDimitry Andric // symbols, or any other flag bits???
3361ac7ddfbfSEd Maste return eStrataUser;
3362ac7ddfbfSEd Maste
3363ac7ddfbfSEd Maste case llvm::ELF::ET_DYN:
3364ac7ddfbfSEd Maste // 3 - Shared object file
3365ac7ddfbfSEd Maste // TODO: is there any way to detect that an shared library is a kernel
33664ba319b5SDimitry Andric // related executable by inspecting the program headers, section headers,
33674ba319b5SDimitry Andric // symbols, or any other flag bits???
3368ac7ddfbfSEd Maste return eStrataUnknown;
3369ac7ddfbfSEd Maste
3370ac7ddfbfSEd Maste case ET_CORE:
3371ac7ddfbfSEd Maste // 4 - Core file
3372ac7ddfbfSEd Maste // TODO: is there any way to detect that an core file is a kernel
33734ba319b5SDimitry Andric // related executable by inspecting the program headers, section headers,
33744ba319b5SDimitry Andric // symbols, or any other flag bits???
3375ac7ddfbfSEd Maste return eStrataUnknown;
3376ac7ddfbfSEd Maste
3377ac7ddfbfSEd Maste default:
3378ac7ddfbfSEd Maste break;
3379ac7ddfbfSEd Maste }
3380ac7ddfbfSEd Maste return eStrataUnknown;
3381ac7ddfbfSEd Maste }
3382acac075bSDimitry Andric
ReadSectionData(Section * section,lldb::offset_t section_offset,void * dst,size_t dst_len)3383acac075bSDimitry Andric size_t ObjectFileELF::ReadSectionData(Section *section,
3384acac075bSDimitry Andric lldb::offset_t section_offset, void *dst,
3385acac075bSDimitry Andric size_t dst_len) {
3386acac075bSDimitry Andric // If some other objectfile owns this data, pass this to them.
3387acac075bSDimitry Andric if (section->GetObjectFile() != this)
3388acac075bSDimitry Andric return section->GetObjectFile()->ReadSectionData(section, section_offset,
3389acac075bSDimitry Andric dst, dst_len);
3390acac075bSDimitry Andric
3391acac075bSDimitry Andric if (!section->Test(SHF_COMPRESSED))
3392acac075bSDimitry Andric return ObjectFile::ReadSectionData(section, section_offset, dst, dst_len);
3393acac075bSDimitry Andric
3394acac075bSDimitry Andric // For compressed sections we need to read to full data to be able to
3395acac075bSDimitry Andric // decompress.
3396acac075bSDimitry Andric DataExtractor data;
3397acac075bSDimitry Andric ReadSectionData(section, data);
3398acac075bSDimitry Andric return data.CopyData(section_offset, dst_len, dst);
3399acac075bSDimitry Andric }
3400acac075bSDimitry Andric
ReadSectionData(Section * section,DataExtractor & section_data)3401acac075bSDimitry Andric size_t ObjectFileELF::ReadSectionData(Section *section,
3402acac075bSDimitry Andric DataExtractor §ion_data) {
3403acac075bSDimitry Andric // If some other objectfile owns this data, pass this to them.
3404acac075bSDimitry Andric if (section->GetObjectFile() != this)
3405acac075bSDimitry Andric return section->GetObjectFile()->ReadSectionData(section, section_data);
3406acac075bSDimitry Andric
3407acac075bSDimitry Andric size_t result = ObjectFile::ReadSectionData(section, section_data);
3408acac075bSDimitry Andric if (result == 0 || !section->Test(SHF_COMPRESSED))
3409acac075bSDimitry Andric return result;
3410acac075bSDimitry Andric
3411acac075bSDimitry Andric auto Decompressor = llvm::object::Decompressor::create(
3412acac075bSDimitry Andric section->GetName().GetStringRef(),
3413acac075bSDimitry Andric {reinterpret_cast<const char *>(section_data.GetDataStart()),
3414acac075bSDimitry Andric size_t(section_data.GetByteSize())},
3415acac075bSDimitry Andric GetByteOrder() == eByteOrderLittle, GetAddressByteSize() == 8);
3416acac075bSDimitry Andric if (!Decompressor) {
3417*b5893f02SDimitry Andric GetModule()->ReportWarning(
3418*b5893f02SDimitry Andric "Unable to initialize decompressor for section '%s': %s",
3419*b5893f02SDimitry Andric section->GetName().GetCString(),
3420*b5893f02SDimitry Andric llvm::toString(Decompressor.takeError()).c_str());
3421*b5893f02SDimitry Andric section_data.Clear();
3422*b5893f02SDimitry Andric return 0;
3423acac075bSDimitry Andric }
3424*b5893f02SDimitry Andric
3425acac075bSDimitry Andric auto buffer_sp =
3426acac075bSDimitry Andric std::make_shared<DataBufferHeap>(Decompressor->getDecompressedSize(), 0);
3427*b5893f02SDimitry Andric if (auto error = Decompressor->decompress(
3428acac075bSDimitry Andric {reinterpret_cast<char *>(buffer_sp->GetBytes()),
3429acac075bSDimitry Andric size_t(buffer_sp->GetByteSize())})) {
3430*b5893f02SDimitry Andric GetModule()->ReportWarning(
3431*b5893f02SDimitry Andric "Decompression of section '%s' failed: %s",
3432*b5893f02SDimitry Andric section->GetName().GetCString(),
3433*b5893f02SDimitry Andric llvm::toString(std::move(error)).c_str());
3434*b5893f02SDimitry Andric section_data.Clear();
3435*b5893f02SDimitry Andric return 0;
3436acac075bSDimitry Andric }
3437*b5893f02SDimitry Andric
3438acac075bSDimitry Andric section_data.SetData(buffer_sp);
3439acac075bSDimitry Andric return buffer_sp->GetByteSize();
3440acac075bSDimitry Andric }
34414ba319b5SDimitry Andric
ProgramHeaders()3442*b5893f02SDimitry Andric llvm::ArrayRef<ELFProgramHeader> ObjectFileELF::ProgramHeaders() {
3443*b5893f02SDimitry Andric ParseProgramHeaders();
3444*b5893f02SDimitry Andric return m_program_headers;
3445*b5893f02SDimitry Andric }
3446*b5893f02SDimitry Andric
GetSegmentData(const ELFProgramHeader & H)3447*b5893f02SDimitry Andric DataExtractor ObjectFileELF::GetSegmentData(const ELFProgramHeader &H) {
3448*b5893f02SDimitry Andric return DataExtractor(m_data, H.p_offset, H.p_filesz);
3449*b5893f02SDimitry Andric }
3450*b5893f02SDimitry Andric
AnySegmentHasPhysicalAddress()34514ba319b5SDimitry Andric bool ObjectFileELF::AnySegmentHasPhysicalAddress() {
3452*b5893f02SDimitry Andric for (const ELFProgramHeader &H : ProgramHeaders()) {
3453*b5893f02SDimitry Andric if (H.p_paddr != 0)
34544ba319b5SDimitry Andric return true;
34554ba319b5SDimitry Andric }
34564ba319b5SDimitry Andric return false;
34574ba319b5SDimitry Andric }
34584ba319b5SDimitry Andric
34594ba319b5SDimitry Andric std::vector<ObjectFile::LoadableData>
GetLoadableData(Target & target)34604ba319b5SDimitry Andric ObjectFileELF::GetLoadableData(Target &target) {
34614ba319b5SDimitry Andric // Create a list of loadable data from loadable segments, using physical
34624ba319b5SDimitry Andric // addresses if they aren't all null
34634ba319b5SDimitry Andric std::vector<LoadableData> loadables;
34644ba319b5SDimitry Andric bool should_use_paddr = AnySegmentHasPhysicalAddress();
3465*b5893f02SDimitry Andric for (const ELFProgramHeader &H : ProgramHeaders()) {
34664ba319b5SDimitry Andric LoadableData loadable;
3467*b5893f02SDimitry Andric if (H.p_type != llvm::ELF::PT_LOAD)
34684ba319b5SDimitry Andric continue;
3469*b5893f02SDimitry Andric loadable.Dest = should_use_paddr ? H.p_paddr : H.p_vaddr;
34704ba319b5SDimitry Andric if (loadable.Dest == LLDB_INVALID_ADDRESS)
34714ba319b5SDimitry Andric continue;
3472*b5893f02SDimitry Andric if (H.p_filesz == 0)
34734ba319b5SDimitry Andric continue;
3474*b5893f02SDimitry Andric auto segment_data = GetSegmentData(H);
34754ba319b5SDimitry Andric loadable.Contents = llvm::ArrayRef<uint8_t>(segment_data.GetDataStart(),
34764ba319b5SDimitry Andric segment_data.GetByteSize());
34774ba319b5SDimitry Andric loadables.push_back(loadable);
34784ba319b5SDimitry Andric }
34794ba319b5SDimitry Andric return loadables;
34804ba319b5SDimitry Andric }
3481