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 &sect_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 &section_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 &sect_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 &sect_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 &section_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