15ffd83dbSDimitry Andric //===-- ObjectFileELF.cpp -------------------------------------------------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric 9*0b57cec5SDimitry Andric #include "ObjectFileELF.h" 10*0b57cec5SDimitry Andric 11*0b57cec5SDimitry Andric #include <algorithm> 12*0b57cec5SDimitry Andric #include <cassert> 13bdd1243dSDimitry Andric #include <optional> 14*0b57cec5SDimitry Andric #include <unordered_map> 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric #include "lldb/Core/FileSpecList.h" 17*0b57cec5SDimitry Andric #include "lldb/Core/Module.h" 18*0b57cec5SDimitry Andric #include "lldb/Core/ModuleSpec.h" 19*0b57cec5SDimitry Andric #include "lldb/Core/PluginManager.h" 20fe6060f1SDimitry Andric #include "lldb/Core/Progress.h" 21*0b57cec5SDimitry Andric #include "lldb/Core/Section.h" 22*0b57cec5SDimitry Andric #include "lldb/Host/FileSystem.h" 239dba64beSDimitry Andric #include "lldb/Host/LZMA.h" 24*0b57cec5SDimitry Andric #include "lldb/Symbol/DWARFCallFrameInfo.h" 25*0b57cec5SDimitry Andric #include "lldb/Symbol/SymbolContext.h" 26*0b57cec5SDimitry Andric #include "lldb/Target/SectionLoadList.h" 27*0b57cec5SDimitry Andric #include "lldb/Target/Target.h" 28*0b57cec5SDimitry Andric #include "lldb/Utility/ArchSpec.h" 29*0b57cec5SDimitry Andric #include "lldb/Utility/DataBufferHeap.h" 3081ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h" 31*0b57cec5SDimitry Andric #include "lldb/Utility/Log.h" 32*0b57cec5SDimitry Andric #include "lldb/Utility/RangeMap.h" 33*0b57cec5SDimitry Andric #include "lldb/Utility/Status.h" 34*0b57cec5SDimitry Andric #include "lldb/Utility/Stream.h" 35*0b57cec5SDimitry Andric #include "lldb/Utility/Timer.h" 36*0b57cec5SDimitry Andric #include "llvm/ADT/IntervalMap.h" 37*0b57cec5SDimitry Andric #include "llvm/ADT/PointerUnion.h" 38*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 399dba64beSDimitry Andric #include "llvm/BinaryFormat/ELF.h" 40*0b57cec5SDimitry Andric #include "llvm/Object/Decompressor.h" 41*0b57cec5SDimitry Andric #include "llvm/Support/ARMBuildAttributes.h" 429dba64beSDimitry Andric #include "llvm/Support/CRC.h" 43fe6060f1SDimitry Andric #include "llvm/Support/FormatVariadic.h" 44*0b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 45*0b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 46*0b57cec5SDimitry Andric #include "llvm/Support/MipsABIFlags.h" 47*0b57cec5SDimitry Andric 48*0b57cec5SDimitry Andric #define CASE_AND_STREAM(s, def, width) \ 49*0b57cec5SDimitry Andric case def: \ 50*0b57cec5SDimitry Andric s->Printf("%-*s", width, #def); \ 51*0b57cec5SDimitry Andric break; 52*0b57cec5SDimitry Andric 53*0b57cec5SDimitry Andric using namespace lldb; 54*0b57cec5SDimitry Andric using namespace lldb_private; 55*0b57cec5SDimitry Andric using namespace elf; 56*0b57cec5SDimitry Andric using namespace llvm::ELF; 57*0b57cec5SDimitry Andric 585ffd83dbSDimitry Andric LLDB_PLUGIN_DEFINE(ObjectFileELF) 595ffd83dbSDimitry Andric 60*0b57cec5SDimitry Andric // ELF note owner definitions 61349cc55cSDimitry Andric static const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD"; 62349cc55cSDimitry Andric static const char *const LLDB_NT_OWNER_GNU = "GNU"; 63349cc55cSDimitry Andric static const char *const LLDB_NT_OWNER_NETBSD = "NetBSD"; 64349cc55cSDimitry Andric static const char *const LLDB_NT_OWNER_NETBSDCORE = "NetBSD-CORE"; 65349cc55cSDimitry Andric static const char *const LLDB_NT_OWNER_OPENBSD = "OpenBSD"; 66349cc55cSDimitry Andric static const char *const LLDB_NT_OWNER_ANDROID = "Android"; 67349cc55cSDimitry Andric static const char *const LLDB_NT_OWNER_CORE = "CORE"; 68349cc55cSDimitry Andric static const char *const LLDB_NT_OWNER_LINUX = "LINUX"; 69*0b57cec5SDimitry Andric 70*0b57cec5SDimitry Andric // ELF note type definitions 71349cc55cSDimitry Andric static const elf_word LLDB_NT_FREEBSD_ABI_TAG = 0x01; 72349cc55cSDimitry Andric static const elf_word LLDB_NT_FREEBSD_ABI_SIZE = 4; 73*0b57cec5SDimitry Andric 74349cc55cSDimitry Andric static const elf_word LLDB_NT_GNU_ABI_TAG = 0x01; 75349cc55cSDimitry Andric static const elf_word LLDB_NT_GNU_ABI_SIZE = 16; 76*0b57cec5SDimitry Andric 77349cc55cSDimitry Andric static const elf_word LLDB_NT_GNU_BUILD_ID_TAG = 0x03; 78*0b57cec5SDimitry Andric 79349cc55cSDimitry Andric static const elf_word LLDB_NT_NETBSD_IDENT_TAG = 1; 80349cc55cSDimitry Andric static const elf_word LLDB_NT_NETBSD_IDENT_DESCSZ = 4; 81349cc55cSDimitry Andric static const elf_word LLDB_NT_NETBSD_IDENT_NAMESZ = 7; 82349cc55cSDimitry Andric static const elf_word LLDB_NT_NETBSD_PROCINFO = 1; 83*0b57cec5SDimitry Andric 84*0b57cec5SDimitry Andric // GNU ABI note OS constants 85349cc55cSDimitry Andric static const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00; 86349cc55cSDimitry Andric static const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01; 87349cc55cSDimitry Andric static const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02; 88349cc55cSDimitry Andric 89349cc55cSDimitry Andric namespace { 90*0b57cec5SDimitry Andric 91*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 92*0b57cec5SDimitry Andric /// \class ELFRelocation 93*0b57cec5SDimitry Andric /// Generic wrapper for ELFRel and ELFRela. 94*0b57cec5SDimitry Andric /// 95*0b57cec5SDimitry Andric /// This helper class allows us to parse both ELFRel and ELFRela relocation 96*0b57cec5SDimitry Andric /// entries in a generic manner. 97*0b57cec5SDimitry Andric class ELFRelocation { 98*0b57cec5SDimitry Andric public: 99*0b57cec5SDimitry Andric /// Constructs an ELFRelocation entry with a personality as given by @p 100*0b57cec5SDimitry Andric /// type. 101*0b57cec5SDimitry Andric /// 102*0b57cec5SDimitry Andric /// \param type Either DT_REL or DT_RELA. Any other value is invalid. 103*0b57cec5SDimitry Andric ELFRelocation(unsigned type); 104*0b57cec5SDimitry Andric 105*0b57cec5SDimitry Andric ~ELFRelocation(); 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); 108*0b57cec5SDimitry Andric 109*0b57cec5SDimitry Andric static unsigned RelocType32(const ELFRelocation &rel); 110*0b57cec5SDimitry Andric 111*0b57cec5SDimitry Andric static unsigned RelocType64(const ELFRelocation &rel); 112*0b57cec5SDimitry Andric 113*0b57cec5SDimitry Andric static unsigned RelocSymbol32(const ELFRelocation &rel); 114*0b57cec5SDimitry Andric 115*0b57cec5SDimitry Andric static unsigned RelocSymbol64(const ELFRelocation &rel); 116*0b57cec5SDimitry Andric 117*0b57cec5SDimitry Andric static unsigned RelocOffset32(const ELFRelocation &rel); 118*0b57cec5SDimitry Andric 119*0b57cec5SDimitry Andric static unsigned RelocOffset64(const ELFRelocation &rel); 120*0b57cec5SDimitry Andric 121*0b57cec5SDimitry Andric static unsigned RelocAddend32(const ELFRelocation &rel); 122*0b57cec5SDimitry Andric 123*0b57cec5SDimitry Andric static unsigned RelocAddend64(const ELFRelocation &rel); 124*0b57cec5SDimitry Andric 125bdd1243dSDimitry Andric bool IsRela() { return (reloc.is<ELFRela *>()); } 126bdd1243dSDimitry Andric 127*0b57cec5SDimitry Andric private: 128*0b57cec5SDimitry Andric typedef llvm::PointerUnion<ELFRel *, ELFRela *> RelocUnion; 129*0b57cec5SDimitry Andric 130*0b57cec5SDimitry Andric RelocUnion reloc; 131*0b57cec5SDimitry Andric }; 132349cc55cSDimitry Andric } // end anonymous namespace 133*0b57cec5SDimitry Andric 134*0b57cec5SDimitry Andric ELFRelocation::ELFRelocation(unsigned type) { 135*0b57cec5SDimitry Andric if (type == DT_REL || type == SHT_REL) 136*0b57cec5SDimitry Andric reloc = new ELFRel(); 137*0b57cec5SDimitry Andric else if (type == DT_RELA || type == SHT_RELA) 138*0b57cec5SDimitry Andric reloc = new ELFRela(); 139*0b57cec5SDimitry Andric else { 140*0b57cec5SDimitry Andric assert(false && "unexpected relocation type"); 141*0b57cec5SDimitry Andric reloc = static_cast<ELFRel *>(nullptr); 142*0b57cec5SDimitry Andric } 143*0b57cec5SDimitry Andric } 144*0b57cec5SDimitry Andric 145*0b57cec5SDimitry Andric ELFRelocation::~ELFRelocation() { 146*0b57cec5SDimitry Andric if (reloc.is<ELFRel *>()) 147*0b57cec5SDimitry Andric delete reloc.get<ELFRel *>(); 148*0b57cec5SDimitry Andric else 149*0b57cec5SDimitry Andric delete reloc.get<ELFRela *>(); 150*0b57cec5SDimitry Andric } 151*0b57cec5SDimitry Andric 152*0b57cec5SDimitry Andric bool ELFRelocation::Parse(const lldb_private::DataExtractor &data, 153*0b57cec5SDimitry Andric lldb::offset_t *offset) { 154*0b57cec5SDimitry Andric if (reloc.is<ELFRel *>()) 155*0b57cec5SDimitry Andric return reloc.get<ELFRel *>()->Parse(data, offset); 156*0b57cec5SDimitry Andric else 157*0b57cec5SDimitry Andric return reloc.get<ELFRela *>()->Parse(data, offset); 158*0b57cec5SDimitry Andric } 159*0b57cec5SDimitry Andric 160*0b57cec5SDimitry Andric unsigned ELFRelocation::RelocType32(const ELFRelocation &rel) { 161*0b57cec5SDimitry Andric if (rel.reloc.is<ELFRel *>()) 162*0b57cec5SDimitry Andric return ELFRel::RelocType32(*rel.reloc.get<ELFRel *>()); 163*0b57cec5SDimitry Andric else 164*0b57cec5SDimitry Andric return ELFRela::RelocType32(*rel.reloc.get<ELFRela *>()); 165*0b57cec5SDimitry Andric } 166*0b57cec5SDimitry Andric 167*0b57cec5SDimitry Andric unsigned ELFRelocation::RelocType64(const ELFRelocation &rel) { 168*0b57cec5SDimitry Andric if (rel.reloc.is<ELFRel *>()) 169*0b57cec5SDimitry Andric return ELFRel::RelocType64(*rel.reloc.get<ELFRel *>()); 170*0b57cec5SDimitry Andric else 171*0b57cec5SDimitry Andric return ELFRela::RelocType64(*rel.reloc.get<ELFRela *>()); 172*0b57cec5SDimitry Andric } 173*0b57cec5SDimitry Andric 174*0b57cec5SDimitry Andric unsigned ELFRelocation::RelocSymbol32(const ELFRelocation &rel) { 175*0b57cec5SDimitry Andric if (rel.reloc.is<ELFRel *>()) 176*0b57cec5SDimitry Andric return ELFRel::RelocSymbol32(*rel.reloc.get<ELFRel *>()); 177*0b57cec5SDimitry Andric else 178*0b57cec5SDimitry Andric return ELFRela::RelocSymbol32(*rel.reloc.get<ELFRela *>()); 179*0b57cec5SDimitry Andric } 180*0b57cec5SDimitry Andric 181*0b57cec5SDimitry Andric unsigned ELFRelocation::RelocSymbol64(const ELFRelocation &rel) { 182*0b57cec5SDimitry Andric if (rel.reloc.is<ELFRel *>()) 183*0b57cec5SDimitry Andric return ELFRel::RelocSymbol64(*rel.reloc.get<ELFRel *>()); 184*0b57cec5SDimitry Andric else 185*0b57cec5SDimitry Andric return ELFRela::RelocSymbol64(*rel.reloc.get<ELFRela *>()); 186*0b57cec5SDimitry Andric } 187*0b57cec5SDimitry Andric 188*0b57cec5SDimitry Andric unsigned ELFRelocation::RelocOffset32(const ELFRelocation &rel) { 189*0b57cec5SDimitry Andric if (rel.reloc.is<ELFRel *>()) 190*0b57cec5SDimitry Andric return rel.reloc.get<ELFRel *>()->r_offset; 191*0b57cec5SDimitry Andric else 192*0b57cec5SDimitry Andric return rel.reloc.get<ELFRela *>()->r_offset; 193*0b57cec5SDimitry Andric } 194*0b57cec5SDimitry Andric 195*0b57cec5SDimitry Andric unsigned ELFRelocation::RelocOffset64(const ELFRelocation &rel) { 196*0b57cec5SDimitry Andric if (rel.reloc.is<ELFRel *>()) 197*0b57cec5SDimitry Andric return rel.reloc.get<ELFRel *>()->r_offset; 198*0b57cec5SDimitry Andric else 199*0b57cec5SDimitry Andric return rel.reloc.get<ELFRela *>()->r_offset; 200*0b57cec5SDimitry Andric } 201*0b57cec5SDimitry Andric 202*0b57cec5SDimitry Andric unsigned ELFRelocation::RelocAddend32(const ELFRelocation &rel) { 203*0b57cec5SDimitry Andric if (rel.reloc.is<ELFRel *>()) 204*0b57cec5SDimitry Andric return 0; 205*0b57cec5SDimitry Andric else 206*0b57cec5SDimitry Andric return rel.reloc.get<ELFRela *>()->r_addend; 207*0b57cec5SDimitry Andric } 208*0b57cec5SDimitry Andric 209*0b57cec5SDimitry Andric unsigned ELFRelocation::RelocAddend64(const ELFRelocation &rel) { 210*0b57cec5SDimitry Andric if (rel.reloc.is<ELFRel *>()) 211*0b57cec5SDimitry Andric return 0; 212*0b57cec5SDimitry Andric else 213*0b57cec5SDimitry Andric return rel.reloc.get<ELFRela *>()->r_addend; 214*0b57cec5SDimitry Andric } 215*0b57cec5SDimitry Andric 2165ffd83dbSDimitry Andric static user_id_t SegmentID(size_t PHdrIndex) { 2175ffd83dbSDimitry Andric return ~user_id_t(PHdrIndex); 2185ffd83dbSDimitry Andric } 219*0b57cec5SDimitry Andric 220*0b57cec5SDimitry Andric bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) { 221*0b57cec5SDimitry Andric // Read all fields. 222*0b57cec5SDimitry Andric if (data.GetU32(offset, &n_namesz, 3) == nullptr) 223*0b57cec5SDimitry Andric return false; 224*0b57cec5SDimitry Andric 225*0b57cec5SDimitry Andric // The name field is required to be nul-terminated, and n_namesz includes the 226*0b57cec5SDimitry Andric // terminating nul in observed implementations (contrary to the ELF-64 spec). 227*0b57cec5SDimitry Andric // A special case is needed for cores generated by some older Linux versions, 228*0b57cec5SDimitry Andric // which write a note named "CORE" without a nul terminator and n_namesz = 4. 229*0b57cec5SDimitry Andric if (n_namesz == 4) { 230*0b57cec5SDimitry Andric char buf[4]; 231*0b57cec5SDimitry Andric if (data.ExtractBytes(*offset, 4, data.GetByteOrder(), buf) != 4) 232*0b57cec5SDimitry Andric return false; 233*0b57cec5SDimitry Andric if (strncmp(buf, "CORE", 4) == 0) { 234*0b57cec5SDimitry Andric n_name = "CORE"; 235*0b57cec5SDimitry Andric *offset += 4; 236*0b57cec5SDimitry Andric return true; 237*0b57cec5SDimitry Andric } 238*0b57cec5SDimitry Andric } 239*0b57cec5SDimitry Andric 240*0b57cec5SDimitry Andric const char *cstr = data.GetCStr(offset, llvm::alignTo(n_namesz, 4)); 241*0b57cec5SDimitry Andric if (cstr == nullptr) { 24281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Symbols); 2439dba64beSDimitry Andric LLDB_LOGF(log, "Failed to parse note name lacking nul terminator"); 244*0b57cec5SDimitry Andric 245*0b57cec5SDimitry Andric return false; 246*0b57cec5SDimitry Andric } 247*0b57cec5SDimitry Andric n_name = cstr; 248*0b57cec5SDimitry Andric return true; 249*0b57cec5SDimitry Andric } 250*0b57cec5SDimitry Andric 251*0b57cec5SDimitry Andric static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) { 252*0b57cec5SDimitry Andric const uint32_t mips_arch = header.e_flags & llvm::ELF::EF_MIPS_ARCH; 253*0b57cec5SDimitry Andric uint32_t endian = header.e_ident[EI_DATA]; 254*0b57cec5SDimitry Andric uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown; 255*0b57cec5SDimitry Andric uint32_t fileclass = header.e_ident[EI_CLASS]; 256*0b57cec5SDimitry Andric 257*0b57cec5SDimitry Andric // If there aren't any elf flags available (e.g core elf file) then return 258*0b57cec5SDimitry Andric // default 259*0b57cec5SDimitry Andric // 32 or 64 bit arch (without any architecture revision) based on object file's class. 260*0b57cec5SDimitry Andric if (header.e_type == ET_CORE) { 261*0b57cec5SDimitry Andric switch (fileclass) { 262*0b57cec5SDimitry Andric case llvm::ELF::ELFCLASS32: 263*0b57cec5SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el 264*0b57cec5SDimitry Andric : ArchSpec::eMIPSSubType_mips32; 265*0b57cec5SDimitry Andric case llvm::ELF::ELFCLASS64: 266*0b57cec5SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el 267*0b57cec5SDimitry Andric : ArchSpec::eMIPSSubType_mips64; 268*0b57cec5SDimitry Andric default: 269*0b57cec5SDimitry Andric return arch_variant; 270*0b57cec5SDimitry Andric } 271*0b57cec5SDimitry Andric } 272*0b57cec5SDimitry Andric 273*0b57cec5SDimitry Andric switch (mips_arch) { 274*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_1: 275*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_2: 276*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_32: 277*0b57cec5SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el 278*0b57cec5SDimitry Andric : ArchSpec::eMIPSSubType_mips32; 279*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_32R2: 280*0b57cec5SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r2el 281*0b57cec5SDimitry Andric : ArchSpec::eMIPSSubType_mips32r2; 282*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_32R6: 283*0b57cec5SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r6el 284*0b57cec5SDimitry Andric : ArchSpec::eMIPSSubType_mips32r6; 285*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_3: 286*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_4: 287*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_5: 288*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_64: 289*0b57cec5SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el 290*0b57cec5SDimitry Andric : ArchSpec::eMIPSSubType_mips64; 291*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_64R2: 292*0b57cec5SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r2el 293*0b57cec5SDimitry Andric : ArchSpec::eMIPSSubType_mips64r2; 294*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_64R6: 295*0b57cec5SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r6el 296*0b57cec5SDimitry Andric : ArchSpec::eMIPSSubType_mips64r6; 297*0b57cec5SDimitry Andric default: 298*0b57cec5SDimitry Andric break; 299*0b57cec5SDimitry Andric } 300*0b57cec5SDimitry Andric 301*0b57cec5SDimitry Andric return arch_variant; 302*0b57cec5SDimitry Andric } 303*0b57cec5SDimitry Andric 304e8d8bef9SDimitry Andric static uint32_t riscvVariantFromElfFlags(const elf::ELFHeader &header) { 305e8d8bef9SDimitry Andric uint32_t fileclass = header.e_ident[EI_CLASS]; 306e8d8bef9SDimitry Andric switch (fileclass) { 307e8d8bef9SDimitry Andric case llvm::ELF::ELFCLASS32: 308e8d8bef9SDimitry Andric return ArchSpec::eRISCVSubType_riscv32; 309e8d8bef9SDimitry Andric case llvm::ELF::ELFCLASS64: 310e8d8bef9SDimitry Andric return ArchSpec::eRISCVSubType_riscv64; 311e8d8bef9SDimitry Andric default: 312e8d8bef9SDimitry Andric return ArchSpec::eRISCVSubType_unknown; 313e8d8bef9SDimitry Andric } 314e8d8bef9SDimitry Andric } 315e8d8bef9SDimitry Andric 31681ad6265SDimitry Andric static uint32_t ppc64VariantFromElfFlags(const elf::ELFHeader &header) { 31781ad6265SDimitry Andric uint32_t endian = header.e_ident[EI_DATA]; 31881ad6265SDimitry Andric if (endian == ELFDATA2LSB) 31981ad6265SDimitry Andric return ArchSpec::eCore_ppc64le_generic; 32081ad6265SDimitry Andric else 32181ad6265SDimitry Andric return ArchSpec::eCore_ppc64_generic; 32281ad6265SDimitry Andric } 32381ad6265SDimitry Andric 324bdd1243dSDimitry Andric static uint32_t loongarchVariantFromElfFlags(const elf::ELFHeader &header) { 325bdd1243dSDimitry Andric uint32_t fileclass = header.e_ident[EI_CLASS]; 326bdd1243dSDimitry Andric switch (fileclass) { 327bdd1243dSDimitry Andric case llvm::ELF::ELFCLASS32: 328bdd1243dSDimitry Andric return ArchSpec::eLoongArchSubType_loongarch32; 329bdd1243dSDimitry Andric case llvm::ELF::ELFCLASS64: 330bdd1243dSDimitry Andric return ArchSpec::eLoongArchSubType_loongarch64; 331bdd1243dSDimitry Andric default: 332bdd1243dSDimitry Andric return ArchSpec::eLoongArchSubType_unknown; 333bdd1243dSDimitry Andric } 334bdd1243dSDimitry Andric } 335bdd1243dSDimitry Andric 336*0b57cec5SDimitry Andric static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) { 337*0b57cec5SDimitry Andric if (header.e_machine == llvm::ELF::EM_MIPS) 338*0b57cec5SDimitry Andric return mipsVariantFromElfFlags(header); 33981ad6265SDimitry Andric else if (header.e_machine == llvm::ELF::EM_PPC64) 34081ad6265SDimitry Andric return ppc64VariantFromElfFlags(header); 341e8d8bef9SDimitry Andric else if (header.e_machine == llvm::ELF::EM_RISCV) 342e8d8bef9SDimitry Andric return riscvVariantFromElfFlags(header); 343bdd1243dSDimitry Andric else if (header.e_machine == llvm::ELF::EM_LOONGARCH) 344bdd1243dSDimitry Andric return loongarchVariantFromElfFlags(header); 345*0b57cec5SDimitry Andric 346*0b57cec5SDimitry Andric return LLDB_INVALID_CPUTYPE; 347*0b57cec5SDimitry Andric } 348*0b57cec5SDimitry Andric 3499dba64beSDimitry Andric char ObjectFileELF::ID; 3509dba64beSDimitry Andric 351*0b57cec5SDimitry Andric // Arbitrary constant used as UUID prefix for core files. 352*0b57cec5SDimitry Andric const uint32_t ObjectFileELF::g_core_uuid_magic(0xE210C); 353*0b57cec5SDimitry Andric 354*0b57cec5SDimitry Andric // Static methods. 355*0b57cec5SDimitry Andric void ObjectFileELF::Initialize() { 356*0b57cec5SDimitry Andric PluginManager::RegisterPlugin(GetPluginNameStatic(), 357*0b57cec5SDimitry Andric GetPluginDescriptionStatic(), CreateInstance, 358*0b57cec5SDimitry Andric CreateMemoryInstance, GetModuleSpecifications); 359*0b57cec5SDimitry Andric } 360*0b57cec5SDimitry Andric 361*0b57cec5SDimitry Andric void ObjectFileELF::Terminate() { 362*0b57cec5SDimitry Andric PluginManager::UnregisterPlugin(CreateInstance); 363*0b57cec5SDimitry Andric } 364*0b57cec5SDimitry Andric 365*0b57cec5SDimitry Andric ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp, 36681ad6265SDimitry Andric DataBufferSP data_sp, 367*0b57cec5SDimitry Andric lldb::offset_t data_offset, 368*0b57cec5SDimitry Andric const lldb_private::FileSpec *file, 369*0b57cec5SDimitry Andric lldb::offset_t file_offset, 370*0b57cec5SDimitry Andric lldb::offset_t length) { 37181ad6265SDimitry Andric bool mapped_writable = false; 372*0b57cec5SDimitry Andric if (!data_sp) { 37381ad6265SDimitry Andric data_sp = MapFileDataWritable(*file, length, file_offset); 374*0b57cec5SDimitry Andric if (!data_sp) 375*0b57cec5SDimitry Andric return nullptr; 376*0b57cec5SDimitry Andric data_offset = 0; 37781ad6265SDimitry Andric mapped_writable = true; 378*0b57cec5SDimitry Andric } 379*0b57cec5SDimitry Andric 380*0b57cec5SDimitry Andric assert(data_sp); 381*0b57cec5SDimitry Andric 382*0b57cec5SDimitry Andric if (data_sp->GetByteSize() <= (llvm::ELF::EI_NIDENT + data_offset)) 383*0b57cec5SDimitry Andric return nullptr; 384*0b57cec5SDimitry Andric 385*0b57cec5SDimitry Andric const uint8_t *magic = data_sp->GetBytes() + data_offset; 386*0b57cec5SDimitry Andric if (!ELFHeader::MagicBytesMatch(magic)) 387*0b57cec5SDimitry Andric return nullptr; 388*0b57cec5SDimitry Andric 389*0b57cec5SDimitry Andric // Update the data to contain the entire file if it doesn't already 390*0b57cec5SDimitry Andric if (data_sp->GetByteSize() < length) { 39181ad6265SDimitry Andric data_sp = MapFileDataWritable(*file, length, file_offset); 392*0b57cec5SDimitry Andric if (!data_sp) 393*0b57cec5SDimitry Andric return nullptr; 394*0b57cec5SDimitry Andric data_offset = 0; 39581ad6265SDimitry Andric mapped_writable = true; 39681ad6265SDimitry Andric magic = data_sp->GetBytes(); 39781ad6265SDimitry Andric } 39881ad6265SDimitry Andric 39981ad6265SDimitry Andric // If we didn't map the data as writable take ownership of the buffer. 40081ad6265SDimitry Andric if (!mapped_writable) { 40181ad6265SDimitry Andric data_sp = std::make_shared<DataBufferHeap>(data_sp->GetBytes(), 40281ad6265SDimitry Andric data_sp->GetByteSize()); 40381ad6265SDimitry Andric data_offset = 0; 404*0b57cec5SDimitry Andric magic = data_sp->GetBytes(); 405*0b57cec5SDimitry Andric } 406*0b57cec5SDimitry Andric 407*0b57cec5SDimitry Andric unsigned address_size = ELFHeader::AddressSizeInBytes(magic); 408*0b57cec5SDimitry Andric if (address_size == 4 || address_size == 8) { 409*0b57cec5SDimitry Andric std::unique_ptr<ObjectFileELF> objfile_up(new ObjectFileELF( 410*0b57cec5SDimitry Andric module_sp, data_sp, data_offset, file, file_offset, length)); 411*0b57cec5SDimitry Andric ArchSpec spec = objfile_up->GetArchitecture(); 412*0b57cec5SDimitry Andric if (spec && objfile_up->SetModulesArchitecture(spec)) 413*0b57cec5SDimitry Andric return objfile_up.release(); 414*0b57cec5SDimitry Andric } 415*0b57cec5SDimitry Andric 416*0b57cec5SDimitry Andric return nullptr; 417*0b57cec5SDimitry Andric } 418*0b57cec5SDimitry Andric 419*0b57cec5SDimitry Andric ObjectFile *ObjectFileELF::CreateMemoryInstance( 42081ad6265SDimitry Andric const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp, 421*0b57cec5SDimitry Andric const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) { 422*0b57cec5SDimitry Andric if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT)) { 423*0b57cec5SDimitry Andric const uint8_t *magic = data_sp->GetBytes(); 424*0b57cec5SDimitry Andric if (ELFHeader::MagicBytesMatch(magic)) { 425*0b57cec5SDimitry Andric unsigned address_size = ELFHeader::AddressSizeInBytes(magic); 426*0b57cec5SDimitry Andric if (address_size == 4 || address_size == 8) { 427*0b57cec5SDimitry Andric std::unique_ptr<ObjectFileELF> objfile_up( 428*0b57cec5SDimitry Andric new ObjectFileELF(module_sp, data_sp, process_sp, header_addr)); 429*0b57cec5SDimitry Andric ArchSpec spec = objfile_up->GetArchitecture(); 430*0b57cec5SDimitry Andric if (spec && objfile_up->SetModulesArchitecture(spec)) 431*0b57cec5SDimitry Andric return objfile_up.release(); 432*0b57cec5SDimitry Andric } 433*0b57cec5SDimitry Andric } 434*0b57cec5SDimitry Andric } 435*0b57cec5SDimitry Andric return nullptr; 436*0b57cec5SDimitry Andric } 437*0b57cec5SDimitry Andric 438*0b57cec5SDimitry Andric bool ObjectFileELF::MagicBytesMatch(DataBufferSP &data_sp, 439*0b57cec5SDimitry Andric lldb::addr_t data_offset, 440*0b57cec5SDimitry Andric lldb::addr_t data_length) { 441*0b57cec5SDimitry Andric if (data_sp && 442*0b57cec5SDimitry Andric data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset)) { 443*0b57cec5SDimitry Andric const uint8_t *magic = data_sp->GetBytes() + data_offset; 444*0b57cec5SDimitry Andric return ELFHeader::MagicBytesMatch(magic); 445*0b57cec5SDimitry Andric } 446*0b57cec5SDimitry Andric return false; 447*0b57cec5SDimitry Andric } 448*0b57cec5SDimitry Andric 4499dba64beSDimitry Andric static uint32_t calc_crc32(uint32_t init, const DataExtractor &data) { 450bdd1243dSDimitry Andric return llvm::crc32(init, 451bdd1243dSDimitry Andric llvm::ArrayRef(data.GetDataStart(), data.GetByteSize())); 452*0b57cec5SDimitry Andric } 453*0b57cec5SDimitry Andric 454*0b57cec5SDimitry Andric uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32( 455*0b57cec5SDimitry Andric const ProgramHeaderColl &program_headers, DataExtractor &object_data) { 456*0b57cec5SDimitry Andric 457*0b57cec5SDimitry Andric uint32_t core_notes_crc = 0; 458*0b57cec5SDimitry Andric 459*0b57cec5SDimitry Andric for (const ELFProgramHeader &H : program_headers) { 460*0b57cec5SDimitry Andric if (H.p_type == llvm::ELF::PT_NOTE) { 461*0b57cec5SDimitry Andric const elf_off ph_offset = H.p_offset; 462*0b57cec5SDimitry Andric const size_t ph_size = H.p_filesz; 463*0b57cec5SDimitry Andric 464*0b57cec5SDimitry Andric DataExtractor segment_data; 465*0b57cec5SDimitry Andric if (segment_data.SetData(object_data, ph_offset, ph_size) != ph_size) { 466*0b57cec5SDimitry Andric // The ELF program header contained incorrect data, probably corefile 467*0b57cec5SDimitry Andric // is incomplete or corrupted. 468*0b57cec5SDimitry Andric break; 469*0b57cec5SDimitry Andric } 470*0b57cec5SDimitry Andric 4719dba64beSDimitry Andric core_notes_crc = calc_crc32(core_notes_crc, segment_data); 472*0b57cec5SDimitry Andric } 473*0b57cec5SDimitry Andric } 474*0b57cec5SDimitry Andric 475*0b57cec5SDimitry Andric return core_notes_crc; 476*0b57cec5SDimitry Andric } 477*0b57cec5SDimitry Andric 478*0b57cec5SDimitry Andric static const char *OSABIAsCString(unsigned char osabi_byte) { 479*0b57cec5SDimitry Andric #define _MAKE_OSABI_CASE(x) \ 480*0b57cec5SDimitry Andric case x: \ 481*0b57cec5SDimitry Andric return #x 482*0b57cec5SDimitry Andric switch (osabi_byte) { 483*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_NONE); 484*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_HPUX); 485*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_NETBSD); 486*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_GNU); 487*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_HURD); 488*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_SOLARIS); 489*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_AIX); 490*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_IRIX); 491*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_FREEBSD); 492*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_TRU64); 493*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_MODESTO); 494*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_OPENBSD); 495*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_OPENVMS); 496*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_NSK); 497*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_AROS); 498*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_FENIXOS); 499*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_C6000_ELFABI); 500*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_C6000_LINUX); 501*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_ARM); 502*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_STANDALONE); 503*0b57cec5SDimitry Andric default: 504*0b57cec5SDimitry Andric return "<unknown-osabi>"; 505*0b57cec5SDimitry Andric } 506*0b57cec5SDimitry Andric #undef _MAKE_OSABI_CASE 507*0b57cec5SDimitry Andric } 508*0b57cec5SDimitry Andric 509*0b57cec5SDimitry Andric // 510*0b57cec5SDimitry Andric // WARNING : This function is being deprecated 511*0b57cec5SDimitry Andric // It's functionality has moved to ArchSpec::SetArchitecture This function is 512*0b57cec5SDimitry Andric // only being kept to validate the move. 513*0b57cec5SDimitry Andric // 514*0b57cec5SDimitry Andric // TODO : Remove this function 515*0b57cec5SDimitry Andric static bool GetOsFromOSABI(unsigned char osabi_byte, 516*0b57cec5SDimitry Andric llvm::Triple::OSType &ostype) { 517*0b57cec5SDimitry Andric switch (osabi_byte) { 518*0b57cec5SDimitry Andric case ELFOSABI_AIX: 519*0b57cec5SDimitry Andric ostype = llvm::Triple::OSType::AIX; 520*0b57cec5SDimitry Andric break; 521*0b57cec5SDimitry Andric case ELFOSABI_FREEBSD: 522*0b57cec5SDimitry Andric ostype = llvm::Triple::OSType::FreeBSD; 523*0b57cec5SDimitry Andric break; 524*0b57cec5SDimitry Andric case ELFOSABI_GNU: 525*0b57cec5SDimitry Andric ostype = llvm::Triple::OSType::Linux; 526*0b57cec5SDimitry Andric break; 527*0b57cec5SDimitry Andric case ELFOSABI_NETBSD: 528*0b57cec5SDimitry Andric ostype = llvm::Triple::OSType::NetBSD; 529*0b57cec5SDimitry Andric break; 530*0b57cec5SDimitry Andric case ELFOSABI_OPENBSD: 531*0b57cec5SDimitry Andric ostype = llvm::Triple::OSType::OpenBSD; 532*0b57cec5SDimitry Andric break; 533*0b57cec5SDimitry Andric case ELFOSABI_SOLARIS: 534*0b57cec5SDimitry Andric ostype = llvm::Triple::OSType::Solaris; 535*0b57cec5SDimitry Andric break; 536*0b57cec5SDimitry Andric default: 537*0b57cec5SDimitry Andric ostype = llvm::Triple::OSType::UnknownOS; 538*0b57cec5SDimitry Andric } 539*0b57cec5SDimitry Andric return ostype != llvm::Triple::OSType::UnknownOS; 540*0b57cec5SDimitry Andric } 541*0b57cec5SDimitry Andric 542*0b57cec5SDimitry Andric size_t ObjectFileELF::GetModuleSpecifications( 543*0b57cec5SDimitry Andric const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp, 544*0b57cec5SDimitry Andric lldb::offset_t data_offset, lldb::offset_t file_offset, 545*0b57cec5SDimitry Andric lldb::offset_t length, lldb_private::ModuleSpecList &specs) { 54681ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Modules); 547*0b57cec5SDimitry Andric 548*0b57cec5SDimitry Andric const size_t initial_count = specs.GetSize(); 549*0b57cec5SDimitry Andric 550*0b57cec5SDimitry Andric if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) { 551*0b57cec5SDimitry Andric DataExtractor data; 552*0b57cec5SDimitry Andric data.SetData(data_sp); 553*0b57cec5SDimitry Andric elf::ELFHeader header; 554*0b57cec5SDimitry Andric lldb::offset_t header_offset = data_offset; 555*0b57cec5SDimitry Andric if (header.Parse(data, &header_offset)) { 556*0b57cec5SDimitry Andric if (data_sp) { 557*0b57cec5SDimitry Andric ModuleSpec spec(file); 558*0b57cec5SDimitry Andric 559*0b57cec5SDimitry Andric const uint32_t sub_type = subTypeFromElfHeader(header); 560*0b57cec5SDimitry Andric spec.GetArchitecture().SetArchitecture( 561*0b57cec5SDimitry Andric eArchTypeELF, header.e_machine, sub_type, header.e_ident[EI_OSABI]); 562*0b57cec5SDimitry Andric 563*0b57cec5SDimitry Andric if (spec.GetArchitecture().IsValid()) { 564*0b57cec5SDimitry Andric llvm::Triple::OSType ostype; 565*0b57cec5SDimitry Andric llvm::Triple::VendorType vendor; 566*0b57cec5SDimitry Andric llvm::Triple::OSType spec_ostype = 567*0b57cec5SDimitry Andric spec.GetArchitecture().GetTriple().getOS(); 568*0b57cec5SDimitry Andric 5699dba64beSDimitry Andric LLDB_LOGF(log, "ObjectFileELF::%s file '%s' module OSABI: %s", 570*0b57cec5SDimitry Andric __FUNCTION__, file.GetPath().c_str(), 571*0b57cec5SDimitry Andric OSABIAsCString(header.e_ident[EI_OSABI])); 572*0b57cec5SDimitry Andric 573*0b57cec5SDimitry Andric // SetArchitecture should have set the vendor to unknown 574*0b57cec5SDimitry Andric vendor = spec.GetArchitecture().GetTriple().getVendor(); 575*0b57cec5SDimitry Andric assert(vendor == llvm::Triple::UnknownVendor); 576*0b57cec5SDimitry Andric UNUSED_IF_ASSERT_DISABLED(vendor); 577*0b57cec5SDimitry Andric 578*0b57cec5SDimitry Andric // 579*0b57cec5SDimitry Andric // Validate it is ok to remove GetOsFromOSABI 580*0b57cec5SDimitry Andric GetOsFromOSABI(header.e_ident[EI_OSABI], ostype); 581*0b57cec5SDimitry Andric assert(spec_ostype == ostype); 582*0b57cec5SDimitry Andric if (spec_ostype != llvm::Triple::OSType::UnknownOS) { 5839dba64beSDimitry Andric LLDB_LOGF(log, 5849dba64beSDimitry Andric "ObjectFileELF::%s file '%s' set ELF module OS type " 585*0b57cec5SDimitry Andric "from ELF header OSABI.", 586*0b57cec5SDimitry Andric __FUNCTION__, file.GetPath().c_str()); 587*0b57cec5SDimitry Andric } 588*0b57cec5SDimitry Andric 5895ffd83dbSDimitry Andric if (data_sp->GetByteSize() < length) 590*0b57cec5SDimitry Andric data_sp = MapFileData(file, -1, file_offset); 591*0b57cec5SDimitry Andric if (data_sp) 592*0b57cec5SDimitry Andric data.SetData(data_sp); 593*0b57cec5SDimitry Andric // In case there is header extension in the section #0, the header we 594*0b57cec5SDimitry Andric // parsed above could have sentinel values for e_phnum, e_shnum, and 595*0b57cec5SDimitry Andric // e_shstrndx. In this case we need to reparse the header with a 596*0b57cec5SDimitry Andric // bigger data source to get the actual values. 597*0b57cec5SDimitry Andric if (header.HasHeaderExtension()) { 598*0b57cec5SDimitry Andric lldb::offset_t header_offset = data_offset; 599*0b57cec5SDimitry Andric header.Parse(data, &header_offset); 600*0b57cec5SDimitry Andric } 601*0b57cec5SDimitry Andric 602*0b57cec5SDimitry Andric uint32_t gnu_debuglink_crc = 0; 603*0b57cec5SDimitry Andric std::string gnu_debuglink_file; 604*0b57cec5SDimitry Andric SectionHeaderColl section_headers; 605*0b57cec5SDimitry Andric lldb_private::UUID &uuid = spec.GetUUID(); 606*0b57cec5SDimitry Andric 607*0b57cec5SDimitry Andric GetSectionHeaderInfo(section_headers, data, header, uuid, 608*0b57cec5SDimitry Andric gnu_debuglink_file, gnu_debuglink_crc, 609*0b57cec5SDimitry Andric spec.GetArchitecture()); 610*0b57cec5SDimitry Andric 611*0b57cec5SDimitry Andric llvm::Triple &spec_triple = spec.GetArchitecture().GetTriple(); 612*0b57cec5SDimitry Andric 6139dba64beSDimitry Andric LLDB_LOGF(log, 6149dba64beSDimitry Andric "ObjectFileELF::%s file '%s' module set to triple: %s " 615*0b57cec5SDimitry Andric "(architecture %s)", 616*0b57cec5SDimitry Andric __FUNCTION__, file.GetPath().c_str(), 617*0b57cec5SDimitry Andric spec_triple.getTriple().c_str(), 618*0b57cec5SDimitry Andric spec.GetArchitecture().GetArchitectureName()); 619*0b57cec5SDimitry Andric 620*0b57cec5SDimitry Andric if (!uuid.IsValid()) { 621*0b57cec5SDimitry Andric uint32_t core_notes_crc = 0; 622*0b57cec5SDimitry Andric 623*0b57cec5SDimitry Andric if (!gnu_debuglink_crc) { 624e8d8bef9SDimitry Andric LLDB_SCOPED_TIMERF( 625*0b57cec5SDimitry Andric "Calculating module crc32 %s with size %" PRIu64 " KiB", 626*0b57cec5SDimitry Andric file.GetLastPathComponent().AsCString(), 6275ffd83dbSDimitry Andric (length - file_offset) / 1024); 628*0b57cec5SDimitry Andric 629*0b57cec5SDimitry Andric // For core files - which usually don't happen to have a 630*0b57cec5SDimitry Andric // gnu_debuglink, and are pretty bulky - calculating whole 631*0b57cec5SDimitry Andric // contents crc32 would be too much of luxury. Thus we will need 632*0b57cec5SDimitry Andric // to fallback to something simpler. 633*0b57cec5SDimitry Andric if (header.e_type == llvm::ELF::ET_CORE) { 634*0b57cec5SDimitry Andric ProgramHeaderColl program_headers; 635*0b57cec5SDimitry Andric GetProgramHeaderInfo(program_headers, data, header); 636*0b57cec5SDimitry Andric 637*0b57cec5SDimitry Andric core_notes_crc = 638*0b57cec5SDimitry Andric CalculateELFNotesSegmentsCRC32(program_headers, data); 639*0b57cec5SDimitry Andric } else { 6409dba64beSDimitry Andric gnu_debuglink_crc = calc_crc32(0, data); 641*0b57cec5SDimitry Andric } 642*0b57cec5SDimitry Andric } 643*0b57cec5SDimitry Andric using u32le = llvm::support::ulittle32_t; 644*0b57cec5SDimitry Andric if (gnu_debuglink_crc) { 645*0b57cec5SDimitry Andric // Use 4 bytes of crc from the .gnu_debuglink section. 646*0b57cec5SDimitry Andric u32le data(gnu_debuglink_crc); 647bdd1243dSDimitry Andric uuid = UUID(&data, sizeof(data)); 648*0b57cec5SDimitry Andric } else if (core_notes_crc) { 649*0b57cec5SDimitry Andric // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make 650*0b57cec5SDimitry Andric // it look different form .gnu_debuglink crc followed by 4 bytes 651*0b57cec5SDimitry Andric // of note segments crc. 652*0b57cec5SDimitry Andric u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)}; 653bdd1243dSDimitry Andric uuid = UUID(data, sizeof(data)); 654*0b57cec5SDimitry Andric } 655*0b57cec5SDimitry Andric } 656*0b57cec5SDimitry Andric 657*0b57cec5SDimitry Andric specs.Append(spec); 658*0b57cec5SDimitry Andric } 659*0b57cec5SDimitry Andric } 660*0b57cec5SDimitry Andric } 661*0b57cec5SDimitry Andric } 662*0b57cec5SDimitry Andric 663*0b57cec5SDimitry Andric return specs.GetSize() - initial_count; 664*0b57cec5SDimitry Andric } 665*0b57cec5SDimitry Andric 666*0b57cec5SDimitry Andric // ObjectFile protocol 667*0b57cec5SDimitry Andric 668*0b57cec5SDimitry Andric ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, 66981ad6265SDimitry Andric DataBufferSP data_sp, lldb::offset_t data_offset, 670*0b57cec5SDimitry Andric const FileSpec *file, lldb::offset_t file_offset, 671*0b57cec5SDimitry Andric lldb::offset_t length) 6729dba64beSDimitry Andric : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset) { 673*0b57cec5SDimitry Andric if (file) 674*0b57cec5SDimitry Andric m_file = *file; 675*0b57cec5SDimitry Andric } 676*0b57cec5SDimitry Andric 677*0b57cec5SDimitry Andric ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, 67881ad6265SDimitry Andric DataBufferSP header_data_sp, 679*0b57cec5SDimitry Andric const lldb::ProcessSP &process_sp, 680*0b57cec5SDimitry Andric addr_t header_addr) 6819dba64beSDimitry Andric : ObjectFile(module_sp, process_sp, header_addr, header_data_sp) {} 682*0b57cec5SDimitry Andric 683*0b57cec5SDimitry Andric bool ObjectFileELF::IsExecutable() const { 684*0b57cec5SDimitry Andric return ((m_header.e_type & ET_EXEC) != 0) || (m_header.e_entry != 0); 685*0b57cec5SDimitry Andric } 686*0b57cec5SDimitry Andric 687*0b57cec5SDimitry Andric bool ObjectFileELF::SetLoadAddress(Target &target, lldb::addr_t value, 688*0b57cec5SDimitry Andric bool value_is_offset) { 689*0b57cec5SDimitry Andric ModuleSP module_sp = GetModule(); 690*0b57cec5SDimitry Andric if (module_sp) { 691*0b57cec5SDimitry Andric size_t num_loaded_sections = 0; 692*0b57cec5SDimitry Andric SectionList *section_list = GetSectionList(); 693*0b57cec5SDimitry Andric if (section_list) { 694*0b57cec5SDimitry Andric if (!value_is_offset) { 695*0b57cec5SDimitry Andric addr_t base = GetBaseAddress().GetFileAddress(); 696*0b57cec5SDimitry Andric if (base == LLDB_INVALID_ADDRESS) 697*0b57cec5SDimitry Andric return false; 698*0b57cec5SDimitry Andric value -= base; 699*0b57cec5SDimitry Andric } 700*0b57cec5SDimitry Andric 701*0b57cec5SDimitry Andric const size_t num_sections = section_list->GetSize(); 702*0b57cec5SDimitry Andric size_t sect_idx = 0; 703*0b57cec5SDimitry Andric 704*0b57cec5SDimitry Andric for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) { 705*0b57cec5SDimitry Andric // Iterate through the object file sections to find all of the sections 706*0b57cec5SDimitry Andric // that have SHF_ALLOC in their flag bits. 707*0b57cec5SDimitry Andric SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx)); 708*0b57cec5SDimitry Andric if (section_sp->Test(SHF_ALLOC) || 709*0b57cec5SDimitry Andric section_sp->GetType() == eSectionTypeContainer) { 710*0b57cec5SDimitry Andric lldb::addr_t load_addr = section_sp->GetFileAddress(); 711*0b57cec5SDimitry Andric // We don't want to update the load address of a section with type 712*0b57cec5SDimitry Andric // eSectionTypeAbsoluteAddress as they already have the absolute load 713*0b57cec5SDimitry Andric // address already specified 714*0b57cec5SDimitry Andric if (section_sp->GetType() != eSectionTypeAbsoluteAddress) 715*0b57cec5SDimitry Andric load_addr += value; 716*0b57cec5SDimitry Andric 717*0b57cec5SDimitry Andric // On 32-bit systems the load address have to fit into 4 bytes. The 718*0b57cec5SDimitry Andric // rest of the bytes are the overflow from the addition. 719*0b57cec5SDimitry Andric if (GetAddressByteSize() == 4) 720*0b57cec5SDimitry Andric load_addr &= 0xFFFFFFFF; 721*0b57cec5SDimitry Andric 722*0b57cec5SDimitry Andric if (target.GetSectionLoadList().SetSectionLoadAddress(section_sp, 723*0b57cec5SDimitry Andric load_addr)) 724*0b57cec5SDimitry Andric ++num_loaded_sections; 725*0b57cec5SDimitry Andric } 726*0b57cec5SDimitry Andric } 727*0b57cec5SDimitry Andric return num_loaded_sections > 0; 728*0b57cec5SDimitry Andric } 729*0b57cec5SDimitry Andric } 730*0b57cec5SDimitry Andric return false; 731*0b57cec5SDimitry Andric } 732*0b57cec5SDimitry Andric 733*0b57cec5SDimitry Andric ByteOrder ObjectFileELF::GetByteOrder() const { 734*0b57cec5SDimitry Andric if (m_header.e_ident[EI_DATA] == ELFDATA2MSB) 735*0b57cec5SDimitry Andric return eByteOrderBig; 736*0b57cec5SDimitry Andric if (m_header.e_ident[EI_DATA] == ELFDATA2LSB) 737*0b57cec5SDimitry Andric return eByteOrderLittle; 738*0b57cec5SDimitry Andric return eByteOrderInvalid; 739*0b57cec5SDimitry Andric } 740*0b57cec5SDimitry Andric 741*0b57cec5SDimitry Andric uint32_t ObjectFileELF::GetAddressByteSize() const { 742*0b57cec5SDimitry Andric return m_data.GetAddressByteSize(); 743*0b57cec5SDimitry Andric } 744*0b57cec5SDimitry Andric 745*0b57cec5SDimitry Andric AddressClass ObjectFileELF::GetAddressClass(addr_t file_addr) { 746*0b57cec5SDimitry Andric Symtab *symtab = GetSymtab(); 747*0b57cec5SDimitry Andric if (!symtab) 748*0b57cec5SDimitry Andric return AddressClass::eUnknown; 749*0b57cec5SDimitry Andric 750*0b57cec5SDimitry Andric // The address class is determined based on the symtab. Ask it from the 751*0b57cec5SDimitry Andric // object file what contains the symtab information. 752*0b57cec5SDimitry Andric ObjectFile *symtab_objfile = symtab->GetObjectFile(); 753*0b57cec5SDimitry Andric if (symtab_objfile != nullptr && symtab_objfile != this) 754*0b57cec5SDimitry Andric return symtab_objfile->GetAddressClass(file_addr); 755*0b57cec5SDimitry Andric 756*0b57cec5SDimitry Andric auto res = ObjectFile::GetAddressClass(file_addr); 757*0b57cec5SDimitry Andric if (res != AddressClass::eCode) 758*0b57cec5SDimitry Andric return res; 759*0b57cec5SDimitry Andric 760*0b57cec5SDimitry Andric auto ub = m_address_class_map.upper_bound(file_addr); 761*0b57cec5SDimitry Andric if (ub == m_address_class_map.begin()) { 762*0b57cec5SDimitry Andric // No entry in the address class map before the address. Return default 763*0b57cec5SDimitry Andric // address class for an address in a code section. 764*0b57cec5SDimitry Andric return AddressClass::eCode; 765*0b57cec5SDimitry Andric } 766*0b57cec5SDimitry Andric 767*0b57cec5SDimitry Andric // Move iterator to the address class entry preceding address 768*0b57cec5SDimitry Andric --ub; 769*0b57cec5SDimitry Andric 770*0b57cec5SDimitry Andric return ub->second; 771*0b57cec5SDimitry Andric } 772*0b57cec5SDimitry Andric 773*0b57cec5SDimitry Andric size_t ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I) { 774*0b57cec5SDimitry Andric return std::distance(m_section_headers.begin(), I); 775*0b57cec5SDimitry Andric } 776*0b57cec5SDimitry Andric 777*0b57cec5SDimitry Andric size_t ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const { 778*0b57cec5SDimitry Andric return std::distance(m_section_headers.begin(), I); 779*0b57cec5SDimitry Andric } 780*0b57cec5SDimitry Andric 781*0b57cec5SDimitry Andric bool ObjectFileELF::ParseHeader() { 782*0b57cec5SDimitry Andric lldb::offset_t offset = 0; 783*0b57cec5SDimitry Andric return m_header.Parse(m_data, &offset); 784*0b57cec5SDimitry Andric } 785*0b57cec5SDimitry Andric 786*0b57cec5SDimitry Andric UUID ObjectFileELF::GetUUID() { 787*0b57cec5SDimitry Andric // Need to parse the section list to get the UUIDs, so make sure that's been 788*0b57cec5SDimitry Andric // done. 789*0b57cec5SDimitry Andric if (!ParseSectionHeaders() && GetType() != ObjectFile::eTypeCoreFile) 790*0b57cec5SDimitry Andric return UUID(); 791*0b57cec5SDimitry Andric 792*0b57cec5SDimitry Andric if (!m_uuid) { 793*0b57cec5SDimitry Andric using u32le = llvm::support::ulittle32_t; 794*0b57cec5SDimitry Andric if (GetType() == ObjectFile::eTypeCoreFile) { 795*0b57cec5SDimitry Andric uint32_t core_notes_crc = 0; 796*0b57cec5SDimitry Andric 797*0b57cec5SDimitry Andric if (!ParseProgramHeaders()) 798*0b57cec5SDimitry Andric return UUID(); 799*0b57cec5SDimitry Andric 800*0b57cec5SDimitry Andric core_notes_crc = 801*0b57cec5SDimitry Andric CalculateELFNotesSegmentsCRC32(m_program_headers, m_data); 802*0b57cec5SDimitry Andric 803*0b57cec5SDimitry Andric if (core_notes_crc) { 804*0b57cec5SDimitry Andric // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it 805*0b57cec5SDimitry Andric // look different form .gnu_debuglink crc - followed by 4 bytes of note 806*0b57cec5SDimitry Andric // segments crc. 807*0b57cec5SDimitry Andric u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)}; 808bdd1243dSDimitry Andric m_uuid = UUID(data, sizeof(data)); 809*0b57cec5SDimitry Andric } 810*0b57cec5SDimitry Andric } else { 811*0b57cec5SDimitry Andric if (!m_gnu_debuglink_crc) 8129dba64beSDimitry Andric m_gnu_debuglink_crc = calc_crc32(0, m_data); 813*0b57cec5SDimitry Andric if (m_gnu_debuglink_crc) { 814*0b57cec5SDimitry Andric // Use 4 bytes of crc from the .gnu_debuglink section. 815*0b57cec5SDimitry Andric u32le data(m_gnu_debuglink_crc); 816bdd1243dSDimitry Andric m_uuid = UUID(&data, sizeof(data)); 817*0b57cec5SDimitry Andric } 818*0b57cec5SDimitry Andric } 819*0b57cec5SDimitry Andric } 820*0b57cec5SDimitry Andric 821*0b57cec5SDimitry Andric return m_uuid; 822*0b57cec5SDimitry Andric } 823*0b57cec5SDimitry Andric 824bdd1243dSDimitry Andric std::optional<FileSpec> ObjectFileELF::GetDebugLink() { 8259dba64beSDimitry Andric if (m_gnu_debuglink_file.empty()) 826bdd1243dSDimitry Andric return std::nullopt; 8279dba64beSDimitry Andric return FileSpec(m_gnu_debuglink_file); 828*0b57cec5SDimitry Andric } 829*0b57cec5SDimitry Andric 830*0b57cec5SDimitry Andric uint32_t ObjectFileELF::GetDependentModules(FileSpecList &files) { 831*0b57cec5SDimitry Andric size_t num_modules = ParseDependentModules(); 832*0b57cec5SDimitry Andric uint32_t num_specs = 0; 833*0b57cec5SDimitry Andric 834*0b57cec5SDimitry Andric for (unsigned i = 0; i < num_modules; ++i) { 835*0b57cec5SDimitry Andric if (files.AppendIfUnique(m_filespec_up->GetFileSpecAtIndex(i))) 836*0b57cec5SDimitry Andric num_specs++; 837*0b57cec5SDimitry Andric } 838*0b57cec5SDimitry Andric 839*0b57cec5SDimitry Andric return num_specs; 840*0b57cec5SDimitry Andric } 841*0b57cec5SDimitry Andric 842*0b57cec5SDimitry Andric Address ObjectFileELF::GetImageInfoAddress(Target *target) { 843*0b57cec5SDimitry Andric if (!ParseDynamicSymbols()) 844*0b57cec5SDimitry Andric return Address(); 845*0b57cec5SDimitry Andric 846*0b57cec5SDimitry Andric SectionList *section_list = GetSectionList(); 847*0b57cec5SDimitry Andric if (!section_list) 848*0b57cec5SDimitry Andric return Address(); 849*0b57cec5SDimitry Andric 850*0b57cec5SDimitry Andric // Find the SHT_DYNAMIC (.dynamic) section. 851*0b57cec5SDimitry Andric SectionSP dynsym_section_sp( 852*0b57cec5SDimitry Andric section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true)); 853*0b57cec5SDimitry Andric if (!dynsym_section_sp) 854*0b57cec5SDimitry Andric return Address(); 855*0b57cec5SDimitry Andric assert(dynsym_section_sp->GetObjectFile() == this); 856*0b57cec5SDimitry Andric 857*0b57cec5SDimitry Andric user_id_t dynsym_id = dynsym_section_sp->GetID(); 858*0b57cec5SDimitry Andric const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id); 859*0b57cec5SDimitry Andric if (!dynsym_hdr) 860*0b57cec5SDimitry Andric return Address(); 861*0b57cec5SDimitry Andric 862*0b57cec5SDimitry Andric for (size_t i = 0; i < m_dynamic_symbols.size(); ++i) { 863*0b57cec5SDimitry Andric ELFDynamic &symbol = m_dynamic_symbols[i]; 864*0b57cec5SDimitry Andric 865*0b57cec5SDimitry Andric if (symbol.d_tag == DT_DEBUG) { 866*0b57cec5SDimitry Andric // Compute the offset as the number of previous entries plus the size of 867*0b57cec5SDimitry Andric // d_tag. 868*0b57cec5SDimitry Andric addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize(); 869*0b57cec5SDimitry Andric return Address(dynsym_section_sp, offset); 870*0b57cec5SDimitry Andric } 871*0b57cec5SDimitry Andric // MIPS executables uses DT_MIPS_RLD_MAP_REL to support PIE. DT_MIPS_RLD_MAP 872*0b57cec5SDimitry Andric // exists in non-PIE. 873*0b57cec5SDimitry Andric else if ((symbol.d_tag == DT_MIPS_RLD_MAP || 874*0b57cec5SDimitry Andric symbol.d_tag == DT_MIPS_RLD_MAP_REL) && 875*0b57cec5SDimitry Andric target) { 876*0b57cec5SDimitry Andric addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize(); 877*0b57cec5SDimitry Andric addr_t dyn_base = dynsym_section_sp->GetLoadBaseAddress(target); 878*0b57cec5SDimitry Andric if (dyn_base == LLDB_INVALID_ADDRESS) 879*0b57cec5SDimitry Andric return Address(); 880*0b57cec5SDimitry Andric 881*0b57cec5SDimitry Andric Status error; 882*0b57cec5SDimitry Andric if (symbol.d_tag == DT_MIPS_RLD_MAP) { 883*0b57cec5SDimitry Andric // DT_MIPS_RLD_MAP tag stores an absolute address of the debug pointer. 884*0b57cec5SDimitry Andric Address addr; 885fe6060f1SDimitry Andric if (target->ReadPointerFromMemory(dyn_base + offset, error, addr, true)) 886*0b57cec5SDimitry Andric return addr; 887*0b57cec5SDimitry Andric } 888*0b57cec5SDimitry Andric if (symbol.d_tag == DT_MIPS_RLD_MAP_REL) { 889*0b57cec5SDimitry Andric // DT_MIPS_RLD_MAP_REL tag stores the offset to the debug pointer, 890*0b57cec5SDimitry Andric // relative to the address of the tag. 891*0b57cec5SDimitry Andric uint64_t rel_offset; 892*0b57cec5SDimitry Andric rel_offset = target->ReadUnsignedIntegerFromMemory( 893fe6060f1SDimitry Andric dyn_base + offset, GetAddressByteSize(), UINT64_MAX, error, true); 894*0b57cec5SDimitry Andric if (error.Success() && rel_offset != UINT64_MAX) { 895*0b57cec5SDimitry Andric Address addr; 896*0b57cec5SDimitry Andric addr_t debug_ptr_address = 897*0b57cec5SDimitry Andric dyn_base + (offset - GetAddressByteSize()) + rel_offset; 898*0b57cec5SDimitry Andric addr.SetOffset(debug_ptr_address); 899*0b57cec5SDimitry Andric return addr; 900*0b57cec5SDimitry Andric } 901*0b57cec5SDimitry Andric } 902*0b57cec5SDimitry Andric } 903*0b57cec5SDimitry Andric } 904*0b57cec5SDimitry Andric 905*0b57cec5SDimitry Andric return Address(); 906*0b57cec5SDimitry Andric } 907*0b57cec5SDimitry Andric 908*0b57cec5SDimitry Andric lldb_private::Address ObjectFileELF::GetEntryPointAddress() { 909*0b57cec5SDimitry Andric if (m_entry_point_address.IsValid()) 910*0b57cec5SDimitry Andric return m_entry_point_address; 911*0b57cec5SDimitry Andric 912*0b57cec5SDimitry Andric if (!ParseHeader() || !IsExecutable()) 913*0b57cec5SDimitry Andric return m_entry_point_address; 914*0b57cec5SDimitry Andric 915*0b57cec5SDimitry Andric SectionList *section_list = GetSectionList(); 916*0b57cec5SDimitry Andric addr_t offset = m_header.e_entry; 917*0b57cec5SDimitry Andric 918*0b57cec5SDimitry Andric if (!section_list) 919*0b57cec5SDimitry Andric m_entry_point_address.SetOffset(offset); 920*0b57cec5SDimitry Andric else 921*0b57cec5SDimitry Andric m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list); 922*0b57cec5SDimitry Andric return m_entry_point_address; 923*0b57cec5SDimitry Andric } 924*0b57cec5SDimitry Andric 925*0b57cec5SDimitry Andric Address ObjectFileELF::GetBaseAddress() { 926*0b57cec5SDimitry Andric for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) { 927*0b57cec5SDimitry Andric const ELFProgramHeader &H = EnumPHdr.value(); 928*0b57cec5SDimitry Andric if (H.p_type != PT_LOAD) 929*0b57cec5SDimitry Andric continue; 930*0b57cec5SDimitry Andric 931*0b57cec5SDimitry Andric return Address( 932*0b57cec5SDimitry Andric GetSectionList()->FindSectionByID(SegmentID(EnumPHdr.index())), 0); 933*0b57cec5SDimitry Andric } 934*0b57cec5SDimitry Andric return LLDB_INVALID_ADDRESS; 935*0b57cec5SDimitry Andric } 936*0b57cec5SDimitry Andric 937*0b57cec5SDimitry Andric // ParseDependentModules 938*0b57cec5SDimitry Andric size_t ObjectFileELF::ParseDependentModules() { 939*0b57cec5SDimitry Andric if (m_filespec_up) 940*0b57cec5SDimitry Andric return m_filespec_up->GetSize(); 941*0b57cec5SDimitry Andric 9425ffd83dbSDimitry Andric m_filespec_up = std::make_unique<FileSpecList>(); 943*0b57cec5SDimitry Andric 944*0b57cec5SDimitry Andric if (!ParseSectionHeaders()) 945*0b57cec5SDimitry Andric return 0; 946*0b57cec5SDimitry Andric 947*0b57cec5SDimitry Andric SectionList *section_list = GetSectionList(); 948*0b57cec5SDimitry Andric if (!section_list) 949*0b57cec5SDimitry Andric return 0; 950*0b57cec5SDimitry Andric 951*0b57cec5SDimitry Andric // Find the SHT_DYNAMIC section. 952*0b57cec5SDimitry Andric Section *dynsym = 953*0b57cec5SDimitry Andric section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true) 954*0b57cec5SDimitry Andric .get(); 955*0b57cec5SDimitry Andric if (!dynsym) 956*0b57cec5SDimitry Andric return 0; 957*0b57cec5SDimitry Andric assert(dynsym->GetObjectFile() == this); 958*0b57cec5SDimitry Andric 959*0b57cec5SDimitry Andric const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex(dynsym->GetID()); 960*0b57cec5SDimitry Andric if (!header) 961*0b57cec5SDimitry Andric return 0; 962*0b57cec5SDimitry Andric // sh_link: section header index of string table used by entries in the 963*0b57cec5SDimitry Andric // section. 964*0b57cec5SDimitry Andric Section *dynstr = section_list->FindSectionByID(header->sh_link).get(); 965*0b57cec5SDimitry Andric if (!dynstr) 966*0b57cec5SDimitry Andric return 0; 967*0b57cec5SDimitry Andric 968*0b57cec5SDimitry Andric DataExtractor dynsym_data; 969*0b57cec5SDimitry Andric DataExtractor dynstr_data; 970*0b57cec5SDimitry Andric if (ReadSectionData(dynsym, dynsym_data) && 971*0b57cec5SDimitry Andric ReadSectionData(dynstr, dynstr_data)) { 972*0b57cec5SDimitry Andric ELFDynamic symbol; 973*0b57cec5SDimitry Andric const lldb::offset_t section_size = dynsym_data.GetByteSize(); 974*0b57cec5SDimitry Andric lldb::offset_t offset = 0; 975*0b57cec5SDimitry Andric 976*0b57cec5SDimitry Andric // The only type of entries we are concerned with are tagged DT_NEEDED, 977*0b57cec5SDimitry Andric // yielding the name of a required library. 978*0b57cec5SDimitry Andric while (offset < section_size) { 979*0b57cec5SDimitry Andric if (!symbol.Parse(dynsym_data, &offset)) 980*0b57cec5SDimitry Andric break; 981*0b57cec5SDimitry Andric 982*0b57cec5SDimitry Andric if (symbol.d_tag != DT_NEEDED) 983*0b57cec5SDimitry Andric continue; 984*0b57cec5SDimitry Andric 985*0b57cec5SDimitry Andric uint32_t str_index = static_cast<uint32_t>(symbol.d_val); 986*0b57cec5SDimitry Andric const char *lib_name = dynstr_data.PeekCStr(str_index); 987*0b57cec5SDimitry Andric FileSpec file_spec(lib_name); 988*0b57cec5SDimitry Andric FileSystem::Instance().Resolve(file_spec); 989*0b57cec5SDimitry Andric m_filespec_up->Append(file_spec); 990*0b57cec5SDimitry Andric } 991*0b57cec5SDimitry Andric } 992*0b57cec5SDimitry Andric 993*0b57cec5SDimitry Andric return m_filespec_up->GetSize(); 994*0b57cec5SDimitry Andric } 995*0b57cec5SDimitry Andric 996*0b57cec5SDimitry Andric // GetProgramHeaderInfo 997*0b57cec5SDimitry Andric size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers, 998*0b57cec5SDimitry Andric DataExtractor &object_data, 999*0b57cec5SDimitry Andric const ELFHeader &header) { 1000*0b57cec5SDimitry Andric // We have already parsed the program headers 1001*0b57cec5SDimitry Andric if (!program_headers.empty()) 1002*0b57cec5SDimitry Andric return program_headers.size(); 1003*0b57cec5SDimitry Andric 1004*0b57cec5SDimitry Andric // If there are no program headers to read we are done. 1005*0b57cec5SDimitry Andric if (header.e_phnum == 0) 1006*0b57cec5SDimitry Andric return 0; 1007*0b57cec5SDimitry Andric 1008*0b57cec5SDimitry Andric program_headers.resize(header.e_phnum); 1009*0b57cec5SDimitry Andric if (program_headers.size() != header.e_phnum) 1010*0b57cec5SDimitry Andric return 0; 1011*0b57cec5SDimitry Andric 1012*0b57cec5SDimitry Andric const size_t ph_size = header.e_phnum * header.e_phentsize; 1013*0b57cec5SDimitry Andric const elf_off ph_offset = header.e_phoff; 1014*0b57cec5SDimitry Andric DataExtractor data; 1015*0b57cec5SDimitry Andric if (data.SetData(object_data, ph_offset, ph_size) != ph_size) 1016*0b57cec5SDimitry Andric return 0; 1017*0b57cec5SDimitry Andric 1018*0b57cec5SDimitry Andric uint32_t idx; 1019*0b57cec5SDimitry Andric lldb::offset_t offset; 1020*0b57cec5SDimitry Andric for (idx = 0, offset = 0; idx < header.e_phnum; ++idx) { 1021*0b57cec5SDimitry Andric if (!program_headers[idx].Parse(data, &offset)) 1022*0b57cec5SDimitry Andric break; 1023*0b57cec5SDimitry Andric } 1024*0b57cec5SDimitry Andric 1025*0b57cec5SDimitry Andric if (idx < program_headers.size()) 1026*0b57cec5SDimitry Andric program_headers.resize(idx); 1027*0b57cec5SDimitry Andric 1028*0b57cec5SDimitry Andric return program_headers.size(); 1029*0b57cec5SDimitry Andric } 1030*0b57cec5SDimitry Andric 1031*0b57cec5SDimitry Andric // ParseProgramHeaders 1032*0b57cec5SDimitry Andric bool ObjectFileELF::ParseProgramHeaders() { 1033*0b57cec5SDimitry Andric return GetProgramHeaderInfo(m_program_headers, m_data, m_header) != 0; 1034*0b57cec5SDimitry Andric } 1035*0b57cec5SDimitry Andric 1036*0b57cec5SDimitry Andric lldb_private::Status 1037*0b57cec5SDimitry Andric ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, 1038*0b57cec5SDimitry Andric lldb_private::ArchSpec &arch_spec, 1039*0b57cec5SDimitry Andric lldb_private::UUID &uuid) { 104081ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Modules); 1041*0b57cec5SDimitry Andric Status error; 1042*0b57cec5SDimitry Andric 1043*0b57cec5SDimitry Andric lldb::offset_t offset = 0; 1044*0b57cec5SDimitry Andric 1045*0b57cec5SDimitry Andric while (true) { 1046*0b57cec5SDimitry Andric // Parse the note header. If this fails, bail out. 1047*0b57cec5SDimitry Andric const lldb::offset_t note_offset = offset; 1048*0b57cec5SDimitry Andric ELFNote note = ELFNote(); 1049*0b57cec5SDimitry Andric if (!note.Parse(data, &offset)) { 1050*0b57cec5SDimitry Andric // We're done. 1051*0b57cec5SDimitry Andric return error; 1052*0b57cec5SDimitry Andric } 1053*0b57cec5SDimitry Andric 10549dba64beSDimitry Andric LLDB_LOGF(log, "ObjectFileELF::%s parsing note name='%s', type=%" PRIu32, 1055*0b57cec5SDimitry Andric __FUNCTION__, note.n_name.c_str(), note.n_type); 1056*0b57cec5SDimitry Andric 1057*0b57cec5SDimitry Andric // Process FreeBSD ELF notes. 1058*0b57cec5SDimitry Andric if ((note.n_name == LLDB_NT_OWNER_FREEBSD) && 1059*0b57cec5SDimitry Andric (note.n_type == LLDB_NT_FREEBSD_ABI_TAG) && 1060*0b57cec5SDimitry Andric (note.n_descsz == LLDB_NT_FREEBSD_ABI_SIZE)) { 1061*0b57cec5SDimitry Andric // Pull out the min version info. 1062*0b57cec5SDimitry Andric uint32_t version_info; 1063*0b57cec5SDimitry Andric if (data.GetU32(&offset, &version_info, 1) == nullptr) { 1064*0b57cec5SDimitry Andric error.SetErrorString("failed to read FreeBSD ABI note payload"); 1065*0b57cec5SDimitry Andric return error; 1066*0b57cec5SDimitry Andric } 1067*0b57cec5SDimitry Andric 1068*0b57cec5SDimitry Andric // Convert the version info into a major/minor number. 1069*0b57cec5SDimitry Andric const uint32_t version_major = version_info / 100000; 1070*0b57cec5SDimitry Andric const uint32_t version_minor = (version_info / 1000) % 100; 1071*0b57cec5SDimitry Andric 1072*0b57cec5SDimitry Andric char os_name[32]; 1073*0b57cec5SDimitry Andric snprintf(os_name, sizeof(os_name), "freebsd%" PRIu32 ".%" PRIu32, 1074*0b57cec5SDimitry Andric version_major, version_minor); 1075*0b57cec5SDimitry Andric 1076*0b57cec5SDimitry Andric // Set the elf OS version to FreeBSD. Also clear the vendor. 1077*0b57cec5SDimitry Andric arch_spec.GetTriple().setOSName(os_name); 1078*0b57cec5SDimitry Andric arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); 1079*0b57cec5SDimitry Andric 10809dba64beSDimitry Andric LLDB_LOGF(log, 10819dba64beSDimitry Andric "ObjectFileELF::%s detected FreeBSD %" PRIu32 ".%" PRIu32 1082*0b57cec5SDimitry Andric ".%" PRIu32, 1083*0b57cec5SDimitry Andric __FUNCTION__, version_major, version_minor, 1084*0b57cec5SDimitry Andric static_cast<uint32_t>(version_info % 1000)); 1085*0b57cec5SDimitry Andric } 1086*0b57cec5SDimitry Andric // Process GNU ELF notes. 1087*0b57cec5SDimitry Andric else if (note.n_name == LLDB_NT_OWNER_GNU) { 1088*0b57cec5SDimitry Andric switch (note.n_type) { 1089*0b57cec5SDimitry Andric case LLDB_NT_GNU_ABI_TAG: 1090*0b57cec5SDimitry Andric if (note.n_descsz == LLDB_NT_GNU_ABI_SIZE) { 1091*0b57cec5SDimitry Andric // Pull out the min OS version supporting the ABI. 1092*0b57cec5SDimitry Andric uint32_t version_info[4]; 1093*0b57cec5SDimitry Andric if (data.GetU32(&offset, &version_info[0], note.n_descsz / 4) == 1094*0b57cec5SDimitry Andric nullptr) { 1095*0b57cec5SDimitry Andric error.SetErrorString("failed to read GNU ABI note payload"); 1096*0b57cec5SDimitry Andric return error; 1097*0b57cec5SDimitry Andric } 1098*0b57cec5SDimitry Andric 1099*0b57cec5SDimitry Andric // Set the OS per the OS field. 1100*0b57cec5SDimitry Andric switch (version_info[0]) { 1101*0b57cec5SDimitry Andric case LLDB_NT_GNU_ABI_OS_LINUX: 1102*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); 1103*0b57cec5SDimitry Andric arch_spec.GetTriple().setVendor( 1104*0b57cec5SDimitry Andric llvm::Triple::VendorType::UnknownVendor); 11059dba64beSDimitry Andric LLDB_LOGF(log, 1106*0b57cec5SDimitry Andric "ObjectFileELF::%s detected Linux, min version %" PRIu32 1107*0b57cec5SDimitry Andric ".%" PRIu32 ".%" PRIu32, 1108*0b57cec5SDimitry Andric __FUNCTION__, version_info[1], version_info[2], 1109*0b57cec5SDimitry Andric version_info[3]); 1110*0b57cec5SDimitry Andric // FIXME we have the minimal version number, we could be propagating 1111*0b57cec5SDimitry Andric // that. version_info[1] = OS Major, version_info[2] = OS Minor, 1112*0b57cec5SDimitry Andric // version_info[3] = Revision. 1113*0b57cec5SDimitry Andric break; 1114*0b57cec5SDimitry Andric case LLDB_NT_GNU_ABI_OS_HURD: 1115*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS); 1116*0b57cec5SDimitry Andric arch_spec.GetTriple().setVendor( 1117*0b57cec5SDimitry Andric llvm::Triple::VendorType::UnknownVendor); 11189dba64beSDimitry Andric LLDB_LOGF(log, 11199dba64beSDimitry Andric "ObjectFileELF::%s detected Hurd (unsupported), min " 1120*0b57cec5SDimitry Andric "version %" PRIu32 ".%" PRIu32 ".%" PRIu32, 1121*0b57cec5SDimitry Andric __FUNCTION__, version_info[1], version_info[2], 1122*0b57cec5SDimitry Andric version_info[3]); 1123*0b57cec5SDimitry Andric break; 1124*0b57cec5SDimitry Andric case LLDB_NT_GNU_ABI_OS_SOLARIS: 1125*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Solaris); 1126*0b57cec5SDimitry Andric arch_spec.GetTriple().setVendor( 1127*0b57cec5SDimitry Andric llvm::Triple::VendorType::UnknownVendor); 11289dba64beSDimitry Andric LLDB_LOGF(log, 1129*0b57cec5SDimitry Andric "ObjectFileELF::%s detected Solaris, min version %" PRIu32 1130*0b57cec5SDimitry Andric ".%" PRIu32 ".%" PRIu32, 1131*0b57cec5SDimitry Andric __FUNCTION__, version_info[1], version_info[2], 1132*0b57cec5SDimitry Andric version_info[3]); 1133*0b57cec5SDimitry Andric break; 1134*0b57cec5SDimitry Andric default: 11359dba64beSDimitry Andric LLDB_LOGF(log, 1136*0b57cec5SDimitry Andric "ObjectFileELF::%s unrecognized OS in note, id %" PRIu32 1137*0b57cec5SDimitry Andric ", min version %" PRIu32 ".%" PRIu32 ".%" PRIu32, 1138*0b57cec5SDimitry Andric __FUNCTION__, version_info[0], version_info[1], 1139*0b57cec5SDimitry Andric version_info[2], version_info[3]); 1140*0b57cec5SDimitry Andric break; 1141*0b57cec5SDimitry Andric } 1142*0b57cec5SDimitry Andric } 1143*0b57cec5SDimitry Andric break; 1144*0b57cec5SDimitry Andric 1145*0b57cec5SDimitry Andric case LLDB_NT_GNU_BUILD_ID_TAG: 1146*0b57cec5SDimitry Andric // Only bother processing this if we don't already have the uuid set. 1147*0b57cec5SDimitry Andric if (!uuid.IsValid()) { 1148*0b57cec5SDimitry Andric // 16 bytes is UUID|MD5, 20 bytes is SHA1. Other linkers may produce a 1149*0b57cec5SDimitry Andric // build-id of a different length. Accept it as long as it's at least 1150*0b57cec5SDimitry Andric // 4 bytes as it will be better than our own crc32. 1151*0b57cec5SDimitry Andric if (note.n_descsz >= 4) { 1152*0b57cec5SDimitry Andric if (const uint8_t *buf = data.PeekData(offset, note.n_descsz)) { 1153*0b57cec5SDimitry Andric // Save the build id as the UUID for the module. 1154bdd1243dSDimitry Andric uuid = UUID(buf, note.n_descsz); 1155*0b57cec5SDimitry Andric } else { 1156*0b57cec5SDimitry Andric error.SetErrorString("failed to read GNU_BUILD_ID note payload"); 1157*0b57cec5SDimitry Andric return error; 1158*0b57cec5SDimitry Andric } 1159*0b57cec5SDimitry Andric } 1160*0b57cec5SDimitry Andric } 1161*0b57cec5SDimitry Andric break; 1162*0b57cec5SDimitry Andric } 1163*0b57cec5SDimitry Andric if (arch_spec.IsMIPS() && 1164*0b57cec5SDimitry Andric arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) 1165*0b57cec5SDimitry Andric // The note.n_name == LLDB_NT_OWNER_GNU is valid for Linux platform 1166*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); 1167*0b57cec5SDimitry Andric } 1168*0b57cec5SDimitry Andric // Process NetBSD ELF executables and shared libraries 1169*0b57cec5SDimitry Andric else if ((note.n_name == LLDB_NT_OWNER_NETBSD) && 1170*0b57cec5SDimitry Andric (note.n_type == LLDB_NT_NETBSD_IDENT_TAG) && 1171*0b57cec5SDimitry Andric (note.n_descsz == LLDB_NT_NETBSD_IDENT_DESCSZ) && 1172*0b57cec5SDimitry Andric (note.n_namesz == LLDB_NT_NETBSD_IDENT_NAMESZ)) { 1173*0b57cec5SDimitry Andric // Pull out the version info. 1174*0b57cec5SDimitry Andric uint32_t version_info; 1175*0b57cec5SDimitry Andric if (data.GetU32(&offset, &version_info, 1) == nullptr) { 1176*0b57cec5SDimitry Andric error.SetErrorString("failed to read NetBSD ABI note payload"); 1177*0b57cec5SDimitry Andric return error; 1178*0b57cec5SDimitry Andric } 1179*0b57cec5SDimitry Andric // Convert the version info into a major/minor/patch number. 1180*0b57cec5SDimitry Andric // #define __NetBSD_Version__ MMmmrrpp00 1181*0b57cec5SDimitry Andric // 1182*0b57cec5SDimitry Andric // M = major version 1183*0b57cec5SDimitry Andric // m = minor version; a minor number of 99 indicates current. 1184*0b57cec5SDimitry Andric // r = 0 (since NetBSD 3.0 not used) 1185*0b57cec5SDimitry Andric // p = patchlevel 1186*0b57cec5SDimitry Andric const uint32_t version_major = version_info / 100000000; 1187*0b57cec5SDimitry Andric const uint32_t version_minor = (version_info % 100000000) / 1000000; 1188*0b57cec5SDimitry Andric const uint32_t version_patch = (version_info % 10000) / 100; 1189*0b57cec5SDimitry Andric // Set the elf OS version to NetBSD. Also clear the vendor. 1190*0b57cec5SDimitry Andric arch_spec.GetTriple().setOSName( 1191*0b57cec5SDimitry Andric llvm::formatv("netbsd{0}.{1}.{2}", version_major, version_minor, 1192*0b57cec5SDimitry Andric version_patch).str()); 1193*0b57cec5SDimitry Andric arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); 1194*0b57cec5SDimitry Andric } 1195*0b57cec5SDimitry Andric // Process NetBSD ELF core(5) notes 1196*0b57cec5SDimitry Andric else if ((note.n_name == LLDB_NT_OWNER_NETBSDCORE) && 1197*0b57cec5SDimitry Andric (note.n_type == LLDB_NT_NETBSD_PROCINFO)) { 1198*0b57cec5SDimitry Andric // Set the elf OS version to NetBSD. Also clear the vendor. 1199*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::NetBSD); 1200*0b57cec5SDimitry Andric arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); 1201*0b57cec5SDimitry Andric } 1202*0b57cec5SDimitry Andric // Process OpenBSD ELF notes. 1203*0b57cec5SDimitry Andric else if (note.n_name == LLDB_NT_OWNER_OPENBSD) { 1204*0b57cec5SDimitry Andric // Set the elf OS version to OpenBSD. Also clear the vendor. 1205*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::OpenBSD); 1206*0b57cec5SDimitry Andric arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); 1207*0b57cec5SDimitry Andric } else if (note.n_name == LLDB_NT_OWNER_ANDROID) { 1208*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); 1209*0b57cec5SDimitry Andric arch_spec.GetTriple().setEnvironment( 1210*0b57cec5SDimitry Andric llvm::Triple::EnvironmentType::Android); 1211*0b57cec5SDimitry Andric } else if (note.n_name == LLDB_NT_OWNER_LINUX) { 1212*0b57cec5SDimitry Andric // This is sometimes found in core files and usually contains extended 1213*0b57cec5SDimitry Andric // register info 1214*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); 1215*0b57cec5SDimitry Andric } else if (note.n_name == LLDB_NT_OWNER_CORE) { 121681ad6265SDimitry Andric // Parse the NT_FILE to look for stuff in paths to shared libraries 121781ad6265SDimitry Andric // The contents look like this in a 64 bit ELF core file: 121881ad6265SDimitry Andric // 121981ad6265SDimitry Andric // count = 0x000000000000000a (10) 122081ad6265SDimitry Andric // page_size = 0x0000000000001000 (4096) 122181ad6265SDimitry Andric // Index start end file_ofs path 122281ad6265SDimitry Andric // ===== ------------------ ------------------ ------------------ ------------------------------------- 122381ad6265SDimitry Andric // [ 0] 0x0000000000401000 0x0000000000000000 /tmp/a.out 122481ad6265SDimitry Andric // [ 1] 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out 122581ad6265SDimitry Andric // [ 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out 122681ad6265SDimitry Andric // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000 /lib/x86_64-linux-gnu/libc-2.19.so 122781ad6265SDimitry Andric // [ 4] 0x00007fa79cba8000 0x00007fa79cda7000 0x00000000000001bb /lib/x86_64-linux-gnu/libc-2.19.so 122881ad6265SDimitry Andric // [ 5] 0x00007fa79cda7000 0x00007fa79cdab000 0x00000000000001ba /lib/x86_64-linux-gnu/libc-2.19.so 122981ad6265SDimitry Andric // [ 6] 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be /lib/x86_64-linux-gnu/libc-2.19.so 123081ad6265SDimitry Andric // [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so 123181ad6265SDimitry Andric // [ 8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 /lib/x86_64-linux-gnu/ld-2.19.so 123281ad6265SDimitry Andric // [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so 123381ad6265SDimitry Andric // 123481ad6265SDimitry Andric // In the 32 bit ELFs the count, page_size, start, end, file_ofs are 123581ad6265SDimitry Andric // uint32_t. 123681ad6265SDimitry Andric // 123781ad6265SDimitry Andric // For reference: see readelf source code (in binutils). 1238*0b57cec5SDimitry Andric if (note.n_type == NT_FILE) { 1239*0b57cec5SDimitry Andric uint64_t count = data.GetAddress(&offset); 1240*0b57cec5SDimitry Andric const char *cstr; 1241*0b57cec5SDimitry Andric data.GetAddress(&offset); // Skip page size 1242*0b57cec5SDimitry Andric offset += count * 3 * 1243*0b57cec5SDimitry Andric data.GetAddressByteSize(); // Skip all start/end/file_ofs 1244*0b57cec5SDimitry Andric for (size_t i = 0; i < count; ++i) { 1245*0b57cec5SDimitry Andric cstr = data.GetCStr(&offset); 1246*0b57cec5SDimitry Andric if (cstr == nullptr) { 1247*0b57cec5SDimitry Andric error.SetErrorStringWithFormat("ObjectFileELF::%s trying to read " 1248*0b57cec5SDimitry Andric "at an offset after the end " 1249*0b57cec5SDimitry Andric "(GetCStr returned nullptr)", 1250*0b57cec5SDimitry Andric __FUNCTION__); 1251*0b57cec5SDimitry Andric return error; 1252*0b57cec5SDimitry Andric } 1253*0b57cec5SDimitry Andric llvm::StringRef path(cstr); 1254*0b57cec5SDimitry Andric if (path.contains("/lib/x86_64-linux-gnu") || path.contains("/lib/i386-linux-gnu")) { 1255*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); 1256*0b57cec5SDimitry Andric break; 1257*0b57cec5SDimitry Andric } 1258*0b57cec5SDimitry Andric } 1259*0b57cec5SDimitry Andric if (arch_spec.IsMIPS() && 1260*0b57cec5SDimitry Andric arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) 1261*0b57cec5SDimitry Andric // In case of MIPSR6, the LLDB_NT_OWNER_GNU note is missing for some 1262*0b57cec5SDimitry Andric // cases (e.g. compile with -nostdlib) Hence set OS to Linux 1263*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); 1264*0b57cec5SDimitry Andric } 1265*0b57cec5SDimitry Andric } 1266*0b57cec5SDimitry Andric 1267*0b57cec5SDimitry Andric // Calculate the offset of the next note just in case "offset" has been 1268*0b57cec5SDimitry Andric // used to poke at the contents of the note data 1269*0b57cec5SDimitry Andric offset = note_offset + note.GetByteSize(); 1270*0b57cec5SDimitry Andric } 1271*0b57cec5SDimitry Andric 1272*0b57cec5SDimitry Andric return error; 1273*0b57cec5SDimitry Andric } 1274*0b57cec5SDimitry Andric 1275*0b57cec5SDimitry Andric void ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length, 1276*0b57cec5SDimitry Andric ArchSpec &arch_spec) { 1277*0b57cec5SDimitry Andric lldb::offset_t Offset = 0; 1278*0b57cec5SDimitry Andric 1279*0b57cec5SDimitry Andric uint8_t FormatVersion = data.GetU8(&Offset); 12805ffd83dbSDimitry Andric if (FormatVersion != llvm::ELFAttrs::Format_Version) 1281*0b57cec5SDimitry Andric return; 1282*0b57cec5SDimitry Andric 1283*0b57cec5SDimitry Andric Offset = Offset + sizeof(uint32_t); // Section Length 1284*0b57cec5SDimitry Andric llvm::StringRef VendorName = data.GetCStr(&Offset); 1285*0b57cec5SDimitry Andric 1286*0b57cec5SDimitry Andric if (VendorName != "aeabi") 1287*0b57cec5SDimitry Andric return; 1288*0b57cec5SDimitry Andric 1289*0b57cec5SDimitry Andric if (arch_spec.GetTriple().getEnvironment() == 1290*0b57cec5SDimitry Andric llvm::Triple::UnknownEnvironment) 1291*0b57cec5SDimitry Andric arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI); 1292*0b57cec5SDimitry Andric 1293*0b57cec5SDimitry Andric while (Offset < length) { 1294*0b57cec5SDimitry Andric uint8_t Tag = data.GetU8(&Offset); 1295*0b57cec5SDimitry Andric uint32_t Size = data.GetU32(&Offset); 1296*0b57cec5SDimitry Andric 1297*0b57cec5SDimitry Andric if (Tag != llvm::ARMBuildAttrs::File || Size == 0) 1298*0b57cec5SDimitry Andric continue; 1299*0b57cec5SDimitry Andric 1300*0b57cec5SDimitry Andric while (Offset < length) { 1301*0b57cec5SDimitry Andric uint64_t Tag = data.GetULEB128(&Offset); 1302*0b57cec5SDimitry Andric switch (Tag) { 1303*0b57cec5SDimitry Andric default: 1304*0b57cec5SDimitry Andric if (Tag < 32) 1305*0b57cec5SDimitry Andric data.GetULEB128(&Offset); 1306*0b57cec5SDimitry Andric else if (Tag % 2 == 0) 1307*0b57cec5SDimitry Andric data.GetULEB128(&Offset); 1308*0b57cec5SDimitry Andric else 1309*0b57cec5SDimitry Andric data.GetCStr(&Offset); 1310*0b57cec5SDimitry Andric 1311*0b57cec5SDimitry Andric break; 1312*0b57cec5SDimitry Andric 1313*0b57cec5SDimitry Andric case llvm::ARMBuildAttrs::CPU_raw_name: 1314*0b57cec5SDimitry Andric case llvm::ARMBuildAttrs::CPU_name: 1315*0b57cec5SDimitry Andric data.GetCStr(&Offset); 1316*0b57cec5SDimitry Andric 1317*0b57cec5SDimitry Andric break; 1318*0b57cec5SDimitry Andric 1319*0b57cec5SDimitry Andric case llvm::ARMBuildAttrs::ABI_VFP_args: { 1320*0b57cec5SDimitry Andric uint64_t VFPArgs = data.GetULEB128(&Offset); 1321*0b57cec5SDimitry Andric 1322*0b57cec5SDimitry Andric if (VFPArgs == llvm::ARMBuildAttrs::BaseAAPCS) { 1323*0b57cec5SDimitry Andric if (arch_spec.GetTriple().getEnvironment() == 1324*0b57cec5SDimitry Andric llvm::Triple::UnknownEnvironment || 1325*0b57cec5SDimitry Andric arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABIHF) 1326*0b57cec5SDimitry Andric arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI); 1327*0b57cec5SDimitry Andric 1328*0b57cec5SDimitry Andric arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float); 1329*0b57cec5SDimitry Andric } else if (VFPArgs == llvm::ARMBuildAttrs::HardFPAAPCS) { 1330*0b57cec5SDimitry Andric if (arch_spec.GetTriple().getEnvironment() == 1331*0b57cec5SDimitry Andric llvm::Triple::UnknownEnvironment || 1332*0b57cec5SDimitry Andric arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABI) 1333*0b57cec5SDimitry Andric arch_spec.GetTriple().setEnvironment(llvm::Triple::EABIHF); 1334*0b57cec5SDimitry Andric 1335*0b57cec5SDimitry Andric arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float); 1336*0b57cec5SDimitry Andric } 1337*0b57cec5SDimitry Andric 1338*0b57cec5SDimitry Andric break; 1339*0b57cec5SDimitry Andric } 1340*0b57cec5SDimitry Andric } 1341*0b57cec5SDimitry Andric } 1342*0b57cec5SDimitry Andric } 1343*0b57cec5SDimitry Andric } 1344*0b57cec5SDimitry Andric 1345*0b57cec5SDimitry Andric // GetSectionHeaderInfo 1346*0b57cec5SDimitry Andric size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, 1347*0b57cec5SDimitry Andric DataExtractor &object_data, 1348*0b57cec5SDimitry Andric const elf::ELFHeader &header, 1349*0b57cec5SDimitry Andric lldb_private::UUID &uuid, 1350*0b57cec5SDimitry Andric std::string &gnu_debuglink_file, 1351*0b57cec5SDimitry Andric uint32_t &gnu_debuglink_crc, 1352*0b57cec5SDimitry Andric ArchSpec &arch_spec) { 1353*0b57cec5SDimitry Andric // Don't reparse the section headers if we already did that. 1354*0b57cec5SDimitry Andric if (!section_headers.empty()) 1355*0b57cec5SDimitry Andric return section_headers.size(); 1356*0b57cec5SDimitry Andric 1357*0b57cec5SDimitry Andric // Only initialize the arch_spec to okay defaults if they're not already set. 1358*0b57cec5SDimitry Andric // We'll refine this with note data as we parse the notes. 1359*0b57cec5SDimitry Andric if (arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) { 1360*0b57cec5SDimitry Andric llvm::Triple::OSType ostype; 1361*0b57cec5SDimitry Andric llvm::Triple::OSType spec_ostype; 1362*0b57cec5SDimitry Andric const uint32_t sub_type = subTypeFromElfHeader(header); 1363*0b57cec5SDimitry Andric arch_spec.SetArchitecture(eArchTypeELF, header.e_machine, sub_type, 1364*0b57cec5SDimitry Andric header.e_ident[EI_OSABI]); 1365*0b57cec5SDimitry Andric 1366*0b57cec5SDimitry Andric // Validate if it is ok to remove GetOsFromOSABI. Note, that now the OS is 1367*0b57cec5SDimitry Andric // determined based on EI_OSABI flag and the info extracted from ELF notes 1368*0b57cec5SDimitry Andric // (see RefineModuleDetailsFromNote). However in some cases that still 1369*0b57cec5SDimitry Andric // might be not enough: for example a shared library might not have any 1370*0b57cec5SDimitry Andric // notes at all and have EI_OSABI flag set to System V, as result the OS 1371*0b57cec5SDimitry Andric // will be set to UnknownOS. 1372*0b57cec5SDimitry Andric GetOsFromOSABI(header.e_ident[EI_OSABI], ostype); 1373*0b57cec5SDimitry Andric spec_ostype = arch_spec.GetTriple().getOS(); 1374*0b57cec5SDimitry Andric assert(spec_ostype == ostype); 1375*0b57cec5SDimitry Andric UNUSED_IF_ASSERT_DISABLED(spec_ostype); 1376*0b57cec5SDimitry Andric } 1377*0b57cec5SDimitry Andric 1378*0b57cec5SDimitry Andric if (arch_spec.GetMachine() == llvm::Triple::mips || 1379*0b57cec5SDimitry Andric arch_spec.GetMachine() == llvm::Triple::mipsel || 1380*0b57cec5SDimitry Andric arch_spec.GetMachine() == llvm::Triple::mips64 || 1381*0b57cec5SDimitry Andric arch_spec.GetMachine() == llvm::Triple::mips64el) { 1382*0b57cec5SDimitry Andric switch (header.e_flags & llvm::ELF::EF_MIPS_ARCH_ASE) { 1383*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_MICROMIPS: 1384*0b57cec5SDimitry Andric arch_spec.SetFlags(ArchSpec::eMIPSAse_micromips); 1385*0b57cec5SDimitry Andric break; 1386*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_ASE_M16: 1387*0b57cec5SDimitry Andric arch_spec.SetFlags(ArchSpec::eMIPSAse_mips16); 1388*0b57cec5SDimitry Andric break; 1389*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_ASE_MDMX: 1390*0b57cec5SDimitry Andric arch_spec.SetFlags(ArchSpec::eMIPSAse_mdmx); 1391*0b57cec5SDimitry Andric break; 1392*0b57cec5SDimitry Andric default: 1393*0b57cec5SDimitry Andric break; 1394*0b57cec5SDimitry Andric } 1395*0b57cec5SDimitry Andric } 1396*0b57cec5SDimitry Andric 1397*0b57cec5SDimitry Andric if (arch_spec.GetMachine() == llvm::Triple::arm || 1398*0b57cec5SDimitry Andric arch_spec.GetMachine() == llvm::Triple::thumb) { 1399*0b57cec5SDimitry Andric if (header.e_flags & llvm::ELF::EF_ARM_SOFT_FLOAT) 1400*0b57cec5SDimitry Andric arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float); 1401*0b57cec5SDimitry Andric else if (header.e_flags & llvm::ELF::EF_ARM_VFP_FLOAT) 1402*0b57cec5SDimitry Andric arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float); 1403*0b57cec5SDimitry Andric } 1404*0b57cec5SDimitry Andric 140581ad6265SDimitry Andric if (arch_spec.GetMachine() == llvm::Triple::riscv32 || 140681ad6265SDimitry Andric arch_spec.GetMachine() == llvm::Triple::riscv64) { 140781ad6265SDimitry Andric uint32_t flags = arch_spec.GetFlags(); 140881ad6265SDimitry Andric 140981ad6265SDimitry Andric if (header.e_flags & llvm::ELF::EF_RISCV_RVC) 141081ad6265SDimitry Andric flags |= ArchSpec::eRISCV_rvc; 141181ad6265SDimitry Andric if (header.e_flags & llvm::ELF::EF_RISCV_RVE) 141281ad6265SDimitry Andric flags |= ArchSpec::eRISCV_rve; 141381ad6265SDimitry Andric 141481ad6265SDimitry Andric if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE) == 141581ad6265SDimitry Andric llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE) 141681ad6265SDimitry Andric flags |= ArchSpec::eRISCV_float_abi_single; 141781ad6265SDimitry Andric else if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE) == 141881ad6265SDimitry Andric llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE) 141981ad6265SDimitry Andric flags |= ArchSpec::eRISCV_float_abi_double; 142081ad6265SDimitry Andric else if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD) == 142181ad6265SDimitry Andric llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD) 142281ad6265SDimitry Andric flags |= ArchSpec::eRISCV_float_abi_quad; 142381ad6265SDimitry Andric 142481ad6265SDimitry Andric arch_spec.SetFlags(flags); 142581ad6265SDimitry Andric } 142681ad6265SDimitry Andric 1427*0b57cec5SDimitry Andric // If there are no section headers we are done. 1428*0b57cec5SDimitry Andric if (header.e_shnum == 0) 1429*0b57cec5SDimitry Andric return 0; 1430*0b57cec5SDimitry Andric 143181ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Modules); 1432*0b57cec5SDimitry Andric 1433*0b57cec5SDimitry Andric section_headers.resize(header.e_shnum); 1434*0b57cec5SDimitry Andric if (section_headers.size() != header.e_shnum) 1435*0b57cec5SDimitry Andric return 0; 1436*0b57cec5SDimitry Andric 1437*0b57cec5SDimitry Andric const size_t sh_size = header.e_shnum * header.e_shentsize; 1438*0b57cec5SDimitry Andric const elf_off sh_offset = header.e_shoff; 1439*0b57cec5SDimitry Andric DataExtractor sh_data; 1440*0b57cec5SDimitry Andric if (sh_data.SetData(object_data, sh_offset, sh_size) != sh_size) 1441*0b57cec5SDimitry Andric return 0; 1442*0b57cec5SDimitry Andric 1443*0b57cec5SDimitry Andric uint32_t idx; 1444*0b57cec5SDimitry Andric lldb::offset_t offset; 1445*0b57cec5SDimitry Andric for (idx = 0, offset = 0; idx < header.e_shnum; ++idx) { 1446*0b57cec5SDimitry Andric if (!section_headers[idx].Parse(sh_data, &offset)) 1447*0b57cec5SDimitry Andric break; 1448*0b57cec5SDimitry Andric } 1449*0b57cec5SDimitry Andric if (idx < section_headers.size()) 1450*0b57cec5SDimitry Andric section_headers.resize(idx); 1451*0b57cec5SDimitry Andric 1452*0b57cec5SDimitry Andric const unsigned strtab_idx = header.e_shstrndx; 1453*0b57cec5SDimitry Andric if (strtab_idx && strtab_idx < section_headers.size()) { 1454*0b57cec5SDimitry Andric const ELFSectionHeaderInfo &sheader = section_headers[strtab_idx]; 1455*0b57cec5SDimitry Andric const size_t byte_size = sheader.sh_size; 1456*0b57cec5SDimitry Andric const Elf64_Off offset = sheader.sh_offset; 1457*0b57cec5SDimitry Andric lldb_private::DataExtractor shstr_data; 1458*0b57cec5SDimitry Andric 1459*0b57cec5SDimitry Andric if (shstr_data.SetData(object_data, offset, byte_size) == byte_size) { 1460*0b57cec5SDimitry Andric for (SectionHeaderCollIter I = section_headers.begin(); 1461*0b57cec5SDimitry Andric I != section_headers.end(); ++I) { 1462*0b57cec5SDimitry Andric static ConstString g_sect_name_gnu_debuglink(".gnu_debuglink"); 1463*0b57cec5SDimitry Andric const ELFSectionHeaderInfo &sheader = *I; 1464*0b57cec5SDimitry Andric const uint64_t section_size = 1465*0b57cec5SDimitry Andric sheader.sh_type == SHT_NOBITS ? 0 : sheader.sh_size; 1466*0b57cec5SDimitry Andric ConstString name(shstr_data.PeekCStr(I->sh_name)); 1467*0b57cec5SDimitry Andric 1468*0b57cec5SDimitry Andric I->section_name = name; 1469*0b57cec5SDimitry Andric 1470*0b57cec5SDimitry Andric if (arch_spec.IsMIPS()) { 1471*0b57cec5SDimitry Andric uint32_t arch_flags = arch_spec.GetFlags(); 1472*0b57cec5SDimitry Andric DataExtractor data; 1473*0b57cec5SDimitry Andric if (sheader.sh_type == SHT_MIPS_ABIFLAGS) { 1474*0b57cec5SDimitry Andric 1475*0b57cec5SDimitry Andric if (section_size && (data.SetData(object_data, sheader.sh_offset, 1476*0b57cec5SDimitry Andric section_size) == section_size)) { 1477*0b57cec5SDimitry Andric // MIPS ASE Mask is at offset 12 in MIPS.abiflags section 1478*0b57cec5SDimitry Andric lldb::offset_t offset = 12; // MIPS ABI Flags Version: 0 1479*0b57cec5SDimitry Andric arch_flags |= data.GetU32(&offset); 1480*0b57cec5SDimitry Andric 1481*0b57cec5SDimitry Andric // The floating point ABI is at offset 7 1482*0b57cec5SDimitry Andric offset = 7; 1483*0b57cec5SDimitry Andric switch (data.GetU8(&offset)) { 1484*0b57cec5SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_ANY: 1485*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_ANY; 1486*0b57cec5SDimitry Andric break; 1487*0b57cec5SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_DOUBLE: 1488*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_DOUBLE; 1489*0b57cec5SDimitry Andric break; 1490*0b57cec5SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_SINGLE: 1491*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SINGLE; 1492*0b57cec5SDimitry Andric break; 1493*0b57cec5SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_SOFT: 1494*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT; 1495*0b57cec5SDimitry Andric break; 1496*0b57cec5SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_OLD_64: 1497*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_OLD_64; 1498*0b57cec5SDimitry Andric break; 1499*0b57cec5SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_XX: 1500*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_XX; 1501*0b57cec5SDimitry Andric break; 1502*0b57cec5SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_64: 1503*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64; 1504*0b57cec5SDimitry Andric break; 1505*0b57cec5SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_64A: 1506*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64A; 1507*0b57cec5SDimitry Andric break; 1508*0b57cec5SDimitry Andric } 1509*0b57cec5SDimitry Andric } 1510*0b57cec5SDimitry Andric } 1511*0b57cec5SDimitry Andric // Settings appropriate ArchSpec ABI Flags 1512*0b57cec5SDimitry Andric switch (header.e_flags & llvm::ELF::EF_MIPS_ABI) { 1513*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ABI_O32: 1514*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_O32; 1515*0b57cec5SDimitry Andric break; 1516*0b57cec5SDimitry Andric case EF_MIPS_ABI_O64: 1517*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_O64; 1518*0b57cec5SDimitry Andric break; 1519*0b57cec5SDimitry Andric case EF_MIPS_ABI_EABI32: 1520*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI32; 1521*0b57cec5SDimitry Andric break; 1522*0b57cec5SDimitry Andric case EF_MIPS_ABI_EABI64: 1523*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI64; 1524*0b57cec5SDimitry Andric break; 1525*0b57cec5SDimitry Andric default: 1526*0b57cec5SDimitry Andric // ABI Mask doesn't cover N32 and N64 ABI. 1527*0b57cec5SDimitry Andric if (header.e_ident[EI_CLASS] == llvm::ELF::ELFCLASS64) 1528*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_N64; 1529*0b57cec5SDimitry Andric else if (header.e_flags & llvm::ELF::EF_MIPS_ABI2) 1530*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_N32; 1531*0b57cec5SDimitry Andric break; 1532*0b57cec5SDimitry Andric } 1533*0b57cec5SDimitry Andric arch_spec.SetFlags(arch_flags); 1534*0b57cec5SDimitry Andric } 1535*0b57cec5SDimitry Andric 1536*0b57cec5SDimitry Andric if (arch_spec.GetMachine() == llvm::Triple::arm || 1537*0b57cec5SDimitry Andric arch_spec.GetMachine() == llvm::Triple::thumb) { 1538*0b57cec5SDimitry Andric DataExtractor data; 1539*0b57cec5SDimitry Andric 1540*0b57cec5SDimitry Andric if (sheader.sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 && 1541*0b57cec5SDimitry Andric data.SetData(object_data, sheader.sh_offset, section_size) == section_size) 1542*0b57cec5SDimitry Andric ParseARMAttributes(data, section_size, arch_spec); 1543*0b57cec5SDimitry Andric } 1544*0b57cec5SDimitry Andric 1545*0b57cec5SDimitry Andric if (name == g_sect_name_gnu_debuglink) { 1546*0b57cec5SDimitry Andric DataExtractor data; 1547*0b57cec5SDimitry Andric if (section_size && (data.SetData(object_data, sheader.sh_offset, 1548*0b57cec5SDimitry Andric section_size) == section_size)) { 1549*0b57cec5SDimitry Andric lldb::offset_t gnu_debuglink_offset = 0; 1550*0b57cec5SDimitry Andric gnu_debuglink_file = data.GetCStr(&gnu_debuglink_offset); 1551*0b57cec5SDimitry Andric gnu_debuglink_offset = llvm::alignTo(gnu_debuglink_offset, 4); 1552*0b57cec5SDimitry Andric data.GetU32(&gnu_debuglink_offset, &gnu_debuglink_crc, 1); 1553*0b57cec5SDimitry Andric } 1554*0b57cec5SDimitry Andric } 1555*0b57cec5SDimitry Andric 1556*0b57cec5SDimitry Andric // Process ELF note section entries. 1557*0b57cec5SDimitry Andric bool is_note_header = (sheader.sh_type == SHT_NOTE); 1558*0b57cec5SDimitry Andric 1559*0b57cec5SDimitry Andric // The section header ".note.android.ident" is stored as a 1560*0b57cec5SDimitry Andric // PROGBITS type header but it is actually a note header. 1561*0b57cec5SDimitry Andric static ConstString g_sect_name_android_ident(".note.android.ident"); 1562*0b57cec5SDimitry Andric if (!is_note_header && name == g_sect_name_android_ident) 1563*0b57cec5SDimitry Andric is_note_header = true; 1564*0b57cec5SDimitry Andric 1565*0b57cec5SDimitry Andric if (is_note_header) { 1566*0b57cec5SDimitry Andric // Allow notes to refine module info. 1567*0b57cec5SDimitry Andric DataExtractor data; 1568*0b57cec5SDimitry Andric if (section_size && (data.SetData(object_data, sheader.sh_offset, 1569*0b57cec5SDimitry Andric section_size) == section_size)) { 1570*0b57cec5SDimitry Andric Status error = RefineModuleDetailsFromNote(data, arch_spec, uuid); 1571*0b57cec5SDimitry Andric if (error.Fail()) { 15729dba64beSDimitry Andric LLDB_LOGF(log, "ObjectFileELF::%s ELF note processing failed: %s", 1573*0b57cec5SDimitry Andric __FUNCTION__, error.AsCString()); 1574*0b57cec5SDimitry Andric } 1575*0b57cec5SDimitry Andric } 1576*0b57cec5SDimitry Andric } 1577*0b57cec5SDimitry Andric } 1578*0b57cec5SDimitry Andric 1579*0b57cec5SDimitry Andric // Make any unknown triple components to be unspecified unknowns. 1580*0b57cec5SDimitry Andric if (arch_spec.GetTriple().getVendor() == llvm::Triple::UnknownVendor) 1581*0b57cec5SDimitry Andric arch_spec.GetTriple().setVendorName(llvm::StringRef()); 1582*0b57cec5SDimitry Andric if (arch_spec.GetTriple().getOS() == llvm::Triple::UnknownOS) 1583*0b57cec5SDimitry Andric arch_spec.GetTriple().setOSName(llvm::StringRef()); 1584*0b57cec5SDimitry Andric 1585*0b57cec5SDimitry Andric return section_headers.size(); 1586*0b57cec5SDimitry Andric } 1587*0b57cec5SDimitry Andric } 1588*0b57cec5SDimitry Andric 1589*0b57cec5SDimitry Andric section_headers.clear(); 1590*0b57cec5SDimitry Andric return 0; 1591*0b57cec5SDimitry Andric } 1592*0b57cec5SDimitry Andric 1593*0b57cec5SDimitry Andric llvm::StringRef 1594*0b57cec5SDimitry Andric ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const { 1595*0b57cec5SDimitry Andric size_t pos = symbol_name.find('@'); 1596*0b57cec5SDimitry Andric return symbol_name.substr(0, pos); 1597*0b57cec5SDimitry Andric } 1598*0b57cec5SDimitry Andric 1599*0b57cec5SDimitry Andric // ParseSectionHeaders 1600*0b57cec5SDimitry Andric size_t ObjectFileELF::ParseSectionHeaders() { 1601*0b57cec5SDimitry Andric return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, 1602*0b57cec5SDimitry Andric m_gnu_debuglink_file, m_gnu_debuglink_crc, 1603*0b57cec5SDimitry Andric m_arch_spec); 1604*0b57cec5SDimitry Andric } 1605*0b57cec5SDimitry Andric 1606*0b57cec5SDimitry Andric const ObjectFileELF::ELFSectionHeaderInfo * 1607*0b57cec5SDimitry Andric ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) { 1608*0b57cec5SDimitry Andric if (!ParseSectionHeaders()) 1609*0b57cec5SDimitry Andric return nullptr; 1610*0b57cec5SDimitry Andric 1611*0b57cec5SDimitry Andric if (id < m_section_headers.size()) 1612*0b57cec5SDimitry Andric return &m_section_headers[id]; 1613*0b57cec5SDimitry Andric 1614*0b57cec5SDimitry Andric return nullptr; 1615*0b57cec5SDimitry Andric } 1616*0b57cec5SDimitry Andric 1617*0b57cec5SDimitry Andric lldb::user_id_t ObjectFileELF::GetSectionIndexByName(const char *name) { 1618*0b57cec5SDimitry Andric if (!name || !name[0] || !ParseSectionHeaders()) 1619*0b57cec5SDimitry Andric return 0; 1620*0b57cec5SDimitry Andric for (size_t i = 1; i < m_section_headers.size(); ++i) 1621*0b57cec5SDimitry Andric if (m_section_headers[i].section_name == ConstString(name)) 1622*0b57cec5SDimitry Andric return i; 1623*0b57cec5SDimitry Andric return 0; 1624*0b57cec5SDimitry Andric } 1625*0b57cec5SDimitry Andric 1626*0b57cec5SDimitry Andric static SectionType GetSectionTypeFromName(llvm::StringRef Name) { 1627fcaf7f86SDimitry Andric if (Name.consume_front(".debug_")) { 1628*0b57cec5SDimitry Andric return llvm::StringSwitch<SectionType>(Name) 1629*0b57cec5SDimitry Andric .Case("abbrev", eSectionTypeDWARFDebugAbbrev) 1630*0b57cec5SDimitry Andric .Case("abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo) 1631*0b57cec5SDimitry Andric .Case("addr", eSectionTypeDWARFDebugAddr) 1632*0b57cec5SDimitry Andric .Case("aranges", eSectionTypeDWARFDebugAranges) 1633*0b57cec5SDimitry Andric .Case("cu_index", eSectionTypeDWARFDebugCuIndex) 1634*0b57cec5SDimitry Andric .Case("frame", eSectionTypeDWARFDebugFrame) 1635*0b57cec5SDimitry Andric .Case("info", eSectionTypeDWARFDebugInfo) 1636*0b57cec5SDimitry Andric .Case("info.dwo", eSectionTypeDWARFDebugInfoDwo) 1637*0b57cec5SDimitry Andric .Cases("line", "line.dwo", eSectionTypeDWARFDebugLine) 1638*0b57cec5SDimitry Andric .Cases("line_str", "line_str.dwo", eSectionTypeDWARFDebugLineStr) 1639480093f4SDimitry Andric .Case("loc", eSectionTypeDWARFDebugLoc) 1640480093f4SDimitry Andric .Case("loc.dwo", eSectionTypeDWARFDebugLocDwo) 1641480093f4SDimitry Andric .Case("loclists", eSectionTypeDWARFDebugLocLists) 1642480093f4SDimitry Andric .Case("loclists.dwo", eSectionTypeDWARFDebugLocListsDwo) 1643*0b57cec5SDimitry Andric .Case("macinfo", eSectionTypeDWARFDebugMacInfo) 1644*0b57cec5SDimitry Andric .Cases("macro", "macro.dwo", eSectionTypeDWARFDebugMacro) 1645*0b57cec5SDimitry Andric .Case("names", eSectionTypeDWARFDebugNames) 1646*0b57cec5SDimitry Andric .Case("pubnames", eSectionTypeDWARFDebugPubNames) 1647*0b57cec5SDimitry Andric .Case("pubtypes", eSectionTypeDWARFDebugPubTypes) 1648*0b57cec5SDimitry Andric .Case("ranges", eSectionTypeDWARFDebugRanges) 1649*0b57cec5SDimitry Andric .Case("rnglists", eSectionTypeDWARFDebugRngLists) 1650480093f4SDimitry Andric .Case("rnglists.dwo", eSectionTypeDWARFDebugRngListsDwo) 1651*0b57cec5SDimitry Andric .Case("str", eSectionTypeDWARFDebugStr) 1652*0b57cec5SDimitry Andric .Case("str.dwo", eSectionTypeDWARFDebugStrDwo) 1653*0b57cec5SDimitry Andric .Case("str_offsets", eSectionTypeDWARFDebugStrOffsets) 1654*0b57cec5SDimitry Andric .Case("str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo) 16555ffd83dbSDimitry Andric .Case("tu_index", eSectionTypeDWARFDebugTuIndex) 1656*0b57cec5SDimitry Andric .Case("types", eSectionTypeDWARFDebugTypes) 1657*0b57cec5SDimitry Andric .Case("types.dwo", eSectionTypeDWARFDebugTypesDwo) 1658*0b57cec5SDimitry Andric .Default(eSectionTypeOther); 1659*0b57cec5SDimitry Andric } 1660*0b57cec5SDimitry Andric return llvm::StringSwitch<SectionType>(Name) 1661*0b57cec5SDimitry Andric .Case(".ARM.exidx", eSectionTypeARMexidx) 1662*0b57cec5SDimitry Andric .Case(".ARM.extab", eSectionTypeARMextab) 1663*0b57cec5SDimitry Andric .Cases(".bss", ".tbss", eSectionTypeZeroFill) 1664*0b57cec5SDimitry Andric .Cases(".data", ".tdata", eSectionTypeData) 1665*0b57cec5SDimitry Andric .Case(".eh_frame", eSectionTypeEHFrame) 1666*0b57cec5SDimitry Andric .Case(".gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink) 1667*0b57cec5SDimitry Andric .Case(".gosymtab", eSectionTypeGoSymtab) 1668*0b57cec5SDimitry Andric .Case(".text", eSectionTypeCode) 1669*0b57cec5SDimitry Andric .Default(eSectionTypeOther); 1670*0b57cec5SDimitry Andric } 1671*0b57cec5SDimitry Andric 1672*0b57cec5SDimitry Andric SectionType ObjectFileELF::GetSectionType(const ELFSectionHeaderInfo &H) const { 1673*0b57cec5SDimitry Andric switch (H.sh_type) { 1674*0b57cec5SDimitry Andric case SHT_PROGBITS: 1675*0b57cec5SDimitry Andric if (H.sh_flags & SHF_EXECINSTR) 1676*0b57cec5SDimitry Andric return eSectionTypeCode; 1677*0b57cec5SDimitry Andric break; 1678*0b57cec5SDimitry Andric case SHT_SYMTAB: 1679*0b57cec5SDimitry Andric return eSectionTypeELFSymbolTable; 1680*0b57cec5SDimitry Andric case SHT_DYNSYM: 1681*0b57cec5SDimitry Andric return eSectionTypeELFDynamicSymbols; 1682*0b57cec5SDimitry Andric case SHT_RELA: 1683*0b57cec5SDimitry Andric case SHT_REL: 1684*0b57cec5SDimitry Andric return eSectionTypeELFRelocationEntries; 1685*0b57cec5SDimitry Andric case SHT_DYNAMIC: 1686*0b57cec5SDimitry Andric return eSectionTypeELFDynamicLinkInfo; 1687*0b57cec5SDimitry Andric } 1688*0b57cec5SDimitry Andric return GetSectionTypeFromName(H.section_name.GetStringRef()); 1689*0b57cec5SDimitry Andric } 1690*0b57cec5SDimitry Andric 1691*0b57cec5SDimitry Andric static uint32_t GetTargetByteSize(SectionType Type, const ArchSpec &arch) { 1692*0b57cec5SDimitry Andric switch (Type) { 1693*0b57cec5SDimitry Andric case eSectionTypeData: 1694*0b57cec5SDimitry Andric case eSectionTypeZeroFill: 1695*0b57cec5SDimitry Andric return arch.GetDataByteSize(); 1696*0b57cec5SDimitry Andric case eSectionTypeCode: 1697*0b57cec5SDimitry Andric return arch.GetCodeByteSize(); 1698*0b57cec5SDimitry Andric default: 1699*0b57cec5SDimitry Andric return 1; 1700*0b57cec5SDimitry Andric } 1701*0b57cec5SDimitry Andric } 1702*0b57cec5SDimitry Andric 1703*0b57cec5SDimitry Andric static Permissions GetPermissions(const ELFSectionHeader &H) { 1704*0b57cec5SDimitry Andric Permissions Perm = Permissions(0); 1705*0b57cec5SDimitry Andric if (H.sh_flags & SHF_ALLOC) 1706*0b57cec5SDimitry Andric Perm |= ePermissionsReadable; 1707*0b57cec5SDimitry Andric if (H.sh_flags & SHF_WRITE) 1708*0b57cec5SDimitry Andric Perm |= ePermissionsWritable; 1709*0b57cec5SDimitry Andric if (H.sh_flags & SHF_EXECINSTR) 1710*0b57cec5SDimitry Andric Perm |= ePermissionsExecutable; 1711*0b57cec5SDimitry Andric return Perm; 1712*0b57cec5SDimitry Andric } 1713*0b57cec5SDimitry Andric 1714*0b57cec5SDimitry Andric static Permissions GetPermissions(const ELFProgramHeader &H) { 1715*0b57cec5SDimitry Andric Permissions Perm = Permissions(0); 1716*0b57cec5SDimitry Andric if (H.p_flags & PF_R) 1717*0b57cec5SDimitry Andric Perm |= ePermissionsReadable; 1718*0b57cec5SDimitry Andric if (H.p_flags & PF_W) 1719*0b57cec5SDimitry Andric Perm |= ePermissionsWritable; 1720*0b57cec5SDimitry Andric if (H.p_flags & PF_X) 1721*0b57cec5SDimitry Andric Perm |= ePermissionsExecutable; 1722*0b57cec5SDimitry Andric return Perm; 1723*0b57cec5SDimitry Andric } 1724*0b57cec5SDimitry Andric 1725*0b57cec5SDimitry Andric namespace { 1726*0b57cec5SDimitry Andric 1727*0b57cec5SDimitry Andric using VMRange = lldb_private::Range<addr_t, addr_t>; 1728*0b57cec5SDimitry Andric 1729*0b57cec5SDimitry Andric struct SectionAddressInfo { 1730*0b57cec5SDimitry Andric SectionSP Segment; 1731*0b57cec5SDimitry Andric VMRange Range; 1732*0b57cec5SDimitry Andric }; 1733*0b57cec5SDimitry Andric 1734*0b57cec5SDimitry Andric // (Unlinked) ELF object files usually have 0 for every section address, meaning 1735*0b57cec5SDimitry Andric // we need to compute synthetic addresses in order for "file addresses" from 1736*0b57cec5SDimitry Andric // different sections to not overlap. This class handles that logic. 1737*0b57cec5SDimitry Andric class VMAddressProvider { 1738*0b57cec5SDimitry Andric using VMMap = llvm::IntervalMap<addr_t, SectionSP, 4, 1739*0b57cec5SDimitry Andric llvm::IntervalMapHalfOpenInfo<addr_t>>; 1740*0b57cec5SDimitry Andric 1741*0b57cec5SDimitry Andric ObjectFile::Type ObjectType; 1742*0b57cec5SDimitry Andric addr_t NextVMAddress = 0; 1743*0b57cec5SDimitry Andric VMMap::Allocator Alloc; 174481ad6265SDimitry Andric VMMap Segments{Alloc}; 174581ad6265SDimitry Andric VMMap Sections{Alloc}; 174681ad6265SDimitry Andric lldb_private::Log *Log = GetLog(LLDBLog::Modules); 17479dba64beSDimitry Andric size_t SegmentCount = 0; 17489dba64beSDimitry Andric std::string SegmentName; 1749*0b57cec5SDimitry Andric 1750*0b57cec5SDimitry Andric VMRange GetVMRange(const ELFSectionHeader &H) { 1751*0b57cec5SDimitry Andric addr_t Address = H.sh_addr; 1752*0b57cec5SDimitry Andric addr_t Size = H.sh_flags & SHF_ALLOC ? H.sh_size : 0; 1753*0b57cec5SDimitry Andric if (ObjectType == ObjectFile::Type::eTypeObjectFile && Segments.empty() && (H.sh_flags & SHF_ALLOC)) { 1754*0b57cec5SDimitry Andric NextVMAddress = 1755*0b57cec5SDimitry Andric llvm::alignTo(NextVMAddress, std::max<addr_t>(H.sh_addralign, 1)); 1756*0b57cec5SDimitry Andric Address = NextVMAddress; 1757*0b57cec5SDimitry Andric NextVMAddress += Size; 1758*0b57cec5SDimitry Andric } 1759*0b57cec5SDimitry Andric return VMRange(Address, Size); 1760*0b57cec5SDimitry Andric } 1761*0b57cec5SDimitry Andric 1762*0b57cec5SDimitry Andric public: 17639dba64beSDimitry Andric VMAddressProvider(ObjectFile::Type Type, llvm::StringRef SegmentName) 17645ffd83dbSDimitry Andric : ObjectType(Type), SegmentName(std::string(SegmentName)) {} 17659dba64beSDimitry Andric 17669dba64beSDimitry Andric std::string GetNextSegmentName() const { 17679dba64beSDimitry Andric return llvm::formatv("{0}[{1}]", SegmentName, SegmentCount).str(); 17689dba64beSDimitry Andric } 1769*0b57cec5SDimitry Andric 1770bdd1243dSDimitry Andric std::optional<VMRange> GetAddressInfo(const ELFProgramHeader &H) { 1771*0b57cec5SDimitry Andric if (H.p_memsz == 0) { 17729dba64beSDimitry Andric LLDB_LOG(Log, "Ignoring zero-sized {0} segment. Corrupt object file?", 17739dba64beSDimitry Andric SegmentName); 1774bdd1243dSDimitry Andric return std::nullopt; 1775*0b57cec5SDimitry Andric } 1776*0b57cec5SDimitry Andric 1777*0b57cec5SDimitry Andric if (Segments.overlaps(H.p_vaddr, H.p_vaddr + H.p_memsz)) { 17789dba64beSDimitry Andric LLDB_LOG(Log, "Ignoring overlapping {0} segment. Corrupt object file?", 17799dba64beSDimitry Andric SegmentName); 1780bdd1243dSDimitry Andric return std::nullopt; 1781*0b57cec5SDimitry Andric } 1782*0b57cec5SDimitry Andric return VMRange(H.p_vaddr, H.p_memsz); 1783*0b57cec5SDimitry Andric } 1784*0b57cec5SDimitry Andric 1785bdd1243dSDimitry Andric std::optional<SectionAddressInfo> GetAddressInfo(const ELFSectionHeader &H) { 1786*0b57cec5SDimitry Andric VMRange Range = GetVMRange(H); 1787*0b57cec5SDimitry Andric SectionSP Segment; 1788*0b57cec5SDimitry Andric auto It = Segments.find(Range.GetRangeBase()); 1789*0b57cec5SDimitry Andric if ((H.sh_flags & SHF_ALLOC) && It.valid()) { 1790*0b57cec5SDimitry Andric addr_t MaxSize; 1791*0b57cec5SDimitry Andric if (It.start() <= Range.GetRangeBase()) { 1792*0b57cec5SDimitry Andric MaxSize = It.stop() - Range.GetRangeBase(); 1793*0b57cec5SDimitry Andric Segment = *It; 1794*0b57cec5SDimitry Andric } else 1795*0b57cec5SDimitry Andric MaxSize = It.start() - Range.GetRangeBase(); 1796*0b57cec5SDimitry Andric if (Range.GetByteSize() > MaxSize) { 1797*0b57cec5SDimitry Andric LLDB_LOG(Log, "Shortening section crossing segment boundaries. " 1798*0b57cec5SDimitry Andric "Corrupt object file?"); 1799*0b57cec5SDimitry Andric Range.SetByteSize(MaxSize); 1800*0b57cec5SDimitry Andric } 1801*0b57cec5SDimitry Andric } 1802*0b57cec5SDimitry Andric if (Range.GetByteSize() > 0 && 1803*0b57cec5SDimitry Andric Sections.overlaps(Range.GetRangeBase(), Range.GetRangeEnd())) { 1804*0b57cec5SDimitry Andric LLDB_LOG(Log, "Ignoring overlapping section. Corrupt object file?"); 1805bdd1243dSDimitry Andric return std::nullopt; 1806*0b57cec5SDimitry Andric } 1807*0b57cec5SDimitry Andric if (Segment) 1808*0b57cec5SDimitry Andric Range.Slide(-Segment->GetFileAddress()); 1809*0b57cec5SDimitry Andric return SectionAddressInfo{Segment, Range}; 1810*0b57cec5SDimitry Andric } 1811*0b57cec5SDimitry Andric 1812*0b57cec5SDimitry Andric void AddSegment(const VMRange &Range, SectionSP Seg) { 1813*0b57cec5SDimitry Andric Segments.insert(Range.GetRangeBase(), Range.GetRangeEnd(), std::move(Seg)); 18149dba64beSDimitry Andric ++SegmentCount; 1815*0b57cec5SDimitry Andric } 1816*0b57cec5SDimitry Andric 1817*0b57cec5SDimitry Andric void AddSection(SectionAddressInfo Info, SectionSP Sect) { 1818*0b57cec5SDimitry Andric if (Info.Range.GetByteSize() == 0) 1819*0b57cec5SDimitry Andric return; 1820*0b57cec5SDimitry Andric if (Info.Segment) 1821*0b57cec5SDimitry Andric Info.Range.Slide(Info.Segment->GetFileAddress()); 1822*0b57cec5SDimitry Andric Sections.insert(Info.Range.GetRangeBase(), Info.Range.GetRangeEnd(), 1823*0b57cec5SDimitry Andric std::move(Sect)); 1824*0b57cec5SDimitry Andric } 1825*0b57cec5SDimitry Andric }; 1826*0b57cec5SDimitry Andric } 1827*0b57cec5SDimitry Andric 1828*0b57cec5SDimitry Andric void ObjectFileELF::CreateSections(SectionList &unified_section_list) { 1829*0b57cec5SDimitry Andric if (m_sections_up) 1830*0b57cec5SDimitry Andric return; 1831*0b57cec5SDimitry Andric 18329dba64beSDimitry Andric m_sections_up = std::make_unique<SectionList>(); 18339dba64beSDimitry Andric VMAddressProvider regular_provider(GetType(), "PT_LOAD"); 18349dba64beSDimitry Andric VMAddressProvider tls_provider(GetType(), "PT_TLS"); 1835*0b57cec5SDimitry Andric 1836*0b57cec5SDimitry Andric for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) { 1837*0b57cec5SDimitry Andric const ELFProgramHeader &PHdr = EnumPHdr.value(); 18389dba64beSDimitry Andric if (PHdr.p_type != PT_LOAD && PHdr.p_type != PT_TLS) 1839*0b57cec5SDimitry Andric continue; 1840*0b57cec5SDimitry Andric 18419dba64beSDimitry Andric VMAddressProvider &provider = 18429dba64beSDimitry Andric PHdr.p_type == PT_TLS ? tls_provider : regular_provider; 18439dba64beSDimitry Andric auto InfoOr = provider.GetAddressInfo(PHdr); 1844*0b57cec5SDimitry Andric if (!InfoOr) 1845*0b57cec5SDimitry Andric continue; 1846*0b57cec5SDimitry Andric 1847*0b57cec5SDimitry Andric uint32_t Log2Align = llvm::Log2_64(std::max<elf_xword>(PHdr.p_align, 1)); 1848*0b57cec5SDimitry Andric SectionSP Segment = std::make_shared<Section>( 18499dba64beSDimitry Andric GetModule(), this, SegmentID(EnumPHdr.index()), 18509dba64beSDimitry Andric ConstString(provider.GetNextSegmentName()), eSectionTypeContainer, 18519dba64beSDimitry Andric InfoOr->GetRangeBase(), InfoOr->GetByteSize(), PHdr.p_offset, 18529dba64beSDimitry Andric PHdr.p_filesz, Log2Align, /*flags*/ 0); 1853*0b57cec5SDimitry Andric Segment->SetPermissions(GetPermissions(PHdr)); 18549dba64beSDimitry Andric Segment->SetIsThreadSpecific(PHdr.p_type == PT_TLS); 1855*0b57cec5SDimitry Andric m_sections_up->AddSection(Segment); 1856*0b57cec5SDimitry Andric 18579dba64beSDimitry Andric provider.AddSegment(*InfoOr, std::move(Segment)); 1858*0b57cec5SDimitry Andric } 1859*0b57cec5SDimitry Andric 1860*0b57cec5SDimitry Andric ParseSectionHeaders(); 1861*0b57cec5SDimitry Andric if (m_section_headers.empty()) 1862*0b57cec5SDimitry Andric return; 1863*0b57cec5SDimitry Andric 1864*0b57cec5SDimitry Andric for (SectionHeaderCollIter I = std::next(m_section_headers.begin()); 1865*0b57cec5SDimitry Andric I != m_section_headers.end(); ++I) { 1866*0b57cec5SDimitry Andric const ELFSectionHeaderInfo &header = *I; 1867*0b57cec5SDimitry Andric 1868*0b57cec5SDimitry Andric ConstString &name = I->section_name; 1869*0b57cec5SDimitry Andric const uint64_t file_size = 1870*0b57cec5SDimitry Andric header.sh_type == SHT_NOBITS ? 0 : header.sh_size; 1871*0b57cec5SDimitry Andric 18729dba64beSDimitry Andric VMAddressProvider &provider = 18739dba64beSDimitry Andric header.sh_flags & SHF_TLS ? tls_provider : regular_provider; 18749dba64beSDimitry Andric auto InfoOr = provider.GetAddressInfo(header); 1875*0b57cec5SDimitry Andric if (!InfoOr) 1876*0b57cec5SDimitry Andric continue; 1877*0b57cec5SDimitry Andric 1878*0b57cec5SDimitry Andric SectionType sect_type = GetSectionType(header); 1879*0b57cec5SDimitry Andric 1880*0b57cec5SDimitry Andric const uint32_t target_bytes_size = 1881*0b57cec5SDimitry Andric GetTargetByteSize(sect_type, m_arch_spec); 1882*0b57cec5SDimitry Andric 1883*0b57cec5SDimitry Andric elf::elf_xword log2align = 1884*0b57cec5SDimitry Andric (header.sh_addralign == 0) ? 0 : llvm::Log2_64(header.sh_addralign); 1885*0b57cec5SDimitry Andric 1886*0b57cec5SDimitry Andric SectionSP section_sp(new Section( 1887*0b57cec5SDimitry Andric InfoOr->Segment, GetModule(), // Module to which this section belongs. 1888*0b57cec5SDimitry Andric this, // ObjectFile to which this section belongs and should 1889*0b57cec5SDimitry Andric // read section data from. 1890*0b57cec5SDimitry Andric SectionIndex(I), // Section ID. 1891*0b57cec5SDimitry Andric name, // Section name. 1892*0b57cec5SDimitry Andric sect_type, // Section type. 1893*0b57cec5SDimitry Andric InfoOr->Range.GetRangeBase(), // VM address. 1894*0b57cec5SDimitry Andric InfoOr->Range.GetByteSize(), // VM size in bytes of this section. 1895*0b57cec5SDimitry Andric header.sh_offset, // Offset of this section in the file. 1896*0b57cec5SDimitry Andric file_size, // Size of the section as found in the file. 1897*0b57cec5SDimitry Andric log2align, // Alignment of the section 1898*0b57cec5SDimitry Andric header.sh_flags, // Flags for this section. 1899*0b57cec5SDimitry Andric target_bytes_size)); // Number of host bytes per target byte 1900*0b57cec5SDimitry Andric 1901*0b57cec5SDimitry Andric section_sp->SetPermissions(GetPermissions(header)); 1902*0b57cec5SDimitry Andric section_sp->SetIsThreadSpecific(header.sh_flags & SHF_TLS); 1903*0b57cec5SDimitry Andric (InfoOr->Segment ? InfoOr->Segment->GetChildren() : *m_sections_up) 1904*0b57cec5SDimitry Andric .AddSection(section_sp); 19059dba64beSDimitry Andric provider.AddSection(std::move(*InfoOr), std::move(section_sp)); 1906*0b57cec5SDimitry Andric } 1907*0b57cec5SDimitry Andric 1908*0b57cec5SDimitry Andric // For eTypeDebugInfo files, the Symbol Vendor will take care of updating the 1909*0b57cec5SDimitry Andric // unified section list. 1910*0b57cec5SDimitry Andric if (GetType() != eTypeDebugInfo) 1911*0b57cec5SDimitry Andric unified_section_list = *m_sections_up; 19129dba64beSDimitry Andric 19139dba64beSDimitry Andric // If there's a .gnu_debugdata section, we'll try to read the .symtab that's 19149dba64beSDimitry Andric // embedded in there and replace the one in the original object file (if any). 19159dba64beSDimitry Andric // If there's none in the orignal object file, we add it to it. 19169dba64beSDimitry Andric if (auto gdd_obj_file = GetGnuDebugDataObjectFile()) { 19179dba64beSDimitry Andric if (auto gdd_objfile_section_list = gdd_obj_file->GetSectionList()) { 19189dba64beSDimitry Andric if (SectionSP symtab_section_sp = 19199dba64beSDimitry Andric gdd_objfile_section_list->FindSectionByType( 19209dba64beSDimitry Andric eSectionTypeELFSymbolTable, true)) { 19219dba64beSDimitry Andric SectionSP module_section_sp = unified_section_list.FindSectionByType( 19229dba64beSDimitry Andric eSectionTypeELFSymbolTable, true); 19239dba64beSDimitry Andric if (module_section_sp) 19249dba64beSDimitry Andric unified_section_list.ReplaceSection(module_section_sp->GetID(), 19259dba64beSDimitry Andric symtab_section_sp); 19269dba64beSDimitry Andric else 19279dba64beSDimitry Andric unified_section_list.AddSection(symtab_section_sp); 19289dba64beSDimitry Andric } 19299dba64beSDimitry Andric } 19309dba64beSDimitry Andric } 19319dba64beSDimitry Andric } 19329dba64beSDimitry Andric 19339dba64beSDimitry Andric std::shared_ptr<ObjectFileELF> ObjectFileELF::GetGnuDebugDataObjectFile() { 19349dba64beSDimitry Andric if (m_gnu_debug_data_object_file != nullptr) 19359dba64beSDimitry Andric return m_gnu_debug_data_object_file; 19369dba64beSDimitry Andric 19379dba64beSDimitry Andric SectionSP section = 19389dba64beSDimitry Andric GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata")); 19399dba64beSDimitry Andric if (!section) 19409dba64beSDimitry Andric return nullptr; 19419dba64beSDimitry Andric 19429dba64beSDimitry Andric if (!lldb_private::lzma::isAvailable()) { 19439dba64beSDimitry Andric GetModule()->ReportWarning( 19449dba64beSDimitry Andric "No LZMA support found for reading .gnu_debugdata section"); 19459dba64beSDimitry Andric return nullptr; 19469dba64beSDimitry Andric } 19479dba64beSDimitry Andric 19489dba64beSDimitry Andric // Uncompress the data 19499dba64beSDimitry Andric DataExtractor data; 19509dba64beSDimitry Andric section->GetSectionData(data); 19519dba64beSDimitry Andric llvm::SmallVector<uint8_t, 0> uncompressedData; 19529dba64beSDimitry Andric auto err = lldb_private::lzma::uncompress(data.GetData(), uncompressedData); 19539dba64beSDimitry Andric if (err) { 19549dba64beSDimitry Andric GetModule()->ReportWarning( 1955bdd1243dSDimitry Andric "An error occurred while decompression the section {0}: {1}", 19569dba64beSDimitry Andric section->GetName().AsCString(), llvm::toString(std::move(err)).c_str()); 19579dba64beSDimitry Andric return nullptr; 19589dba64beSDimitry Andric } 19599dba64beSDimitry Andric 19609dba64beSDimitry Andric // Construct ObjectFileELF object from decompressed buffer 19619dba64beSDimitry Andric DataBufferSP gdd_data_buf( 19629dba64beSDimitry Andric new DataBufferHeap(uncompressedData.data(), uncompressedData.size())); 19639dba64beSDimitry Andric auto fspec = GetFileSpec().CopyByAppendingPathComponent( 19649dba64beSDimitry Andric llvm::StringRef("gnu_debugdata")); 19659dba64beSDimitry Andric m_gnu_debug_data_object_file.reset(new ObjectFileELF( 19669dba64beSDimitry Andric GetModule(), gdd_data_buf, 0, &fspec, 0, gdd_data_buf->GetByteSize())); 19679dba64beSDimitry Andric 19689dba64beSDimitry Andric // This line is essential; otherwise a breakpoint can be set but not hit. 19699dba64beSDimitry Andric m_gnu_debug_data_object_file->SetType(ObjectFile::eTypeDebugInfo); 19709dba64beSDimitry Andric 19719dba64beSDimitry Andric ArchSpec spec = m_gnu_debug_data_object_file->GetArchitecture(); 19729dba64beSDimitry Andric if (spec && m_gnu_debug_data_object_file->SetModulesArchitecture(spec)) 19739dba64beSDimitry Andric return m_gnu_debug_data_object_file; 19749dba64beSDimitry Andric 19759dba64beSDimitry Andric return nullptr; 1976*0b57cec5SDimitry Andric } 1977*0b57cec5SDimitry Andric 1978*0b57cec5SDimitry Andric // Find the arm/aarch64 mapping symbol character in the given symbol name. 1979*0b57cec5SDimitry Andric // Mapping symbols have the form of "$<char>[.<any>]*". Additionally we 1980*0b57cec5SDimitry Andric // recognize cases when the mapping symbol prefixed by an arbitrary string 1981*0b57cec5SDimitry Andric // because if a symbol prefix added to each symbol in the object file with 1982*0b57cec5SDimitry Andric // objcopy then the mapping symbols are also prefixed. 1983*0b57cec5SDimitry Andric static char FindArmAarch64MappingSymbol(const char *symbol_name) { 1984*0b57cec5SDimitry Andric if (!symbol_name) 1985*0b57cec5SDimitry Andric return '\0'; 1986*0b57cec5SDimitry Andric 1987*0b57cec5SDimitry Andric const char *dollar_pos = ::strchr(symbol_name, '$'); 1988*0b57cec5SDimitry Andric if (!dollar_pos || dollar_pos[1] == '\0') 1989*0b57cec5SDimitry Andric return '\0'; 1990*0b57cec5SDimitry Andric 1991*0b57cec5SDimitry Andric if (dollar_pos[2] == '\0' || dollar_pos[2] == '.') 1992*0b57cec5SDimitry Andric return dollar_pos[1]; 1993*0b57cec5SDimitry Andric return '\0'; 1994*0b57cec5SDimitry Andric } 1995*0b57cec5SDimitry Andric 1996*0b57cec5SDimitry Andric #define STO_MIPS_ISA (3 << 6) 1997*0b57cec5SDimitry Andric #define STO_MICROMIPS (2 << 6) 1998*0b57cec5SDimitry Andric #define IS_MICROMIPS(ST_OTHER) (((ST_OTHER)&STO_MIPS_ISA) == STO_MICROMIPS) 1999*0b57cec5SDimitry Andric 2000*0b57cec5SDimitry Andric // private 2001*0b57cec5SDimitry Andric unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, 2002*0b57cec5SDimitry Andric SectionList *section_list, 2003*0b57cec5SDimitry Andric const size_t num_symbols, 2004*0b57cec5SDimitry Andric const DataExtractor &symtab_data, 2005*0b57cec5SDimitry Andric const DataExtractor &strtab_data) { 2006*0b57cec5SDimitry Andric ELFSymbol symbol; 2007*0b57cec5SDimitry Andric lldb::offset_t offset = 0; 2008*0b57cec5SDimitry Andric 2009*0b57cec5SDimitry Andric static ConstString text_section_name(".text"); 2010*0b57cec5SDimitry Andric static ConstString init_section_name(".init"); 2011*0b57cec5SDimitry Andric static ConstString fini_section_name(".fini"); 2012*0b57cec5SDimitry Andric static ConstString ctors_section_name(".ctors"); 2013*0b57cec5SDimitry Andric static ConstString dtors_section_name(".dtors"); 2014*0b57cec5SDimitry Andric 2015*0b57cec5SDimitry Andric static ConstString data_section_name(".data"); 2016*0b57cec5SDimitry Andric static ConstString rodata_section_name(".rodata"); 2017*0b57cec5SDimitry Andric static ConstString rodata1_section_name(".rodata1"); 2018*0b57cec5SDimitry Andric static ConstString data2_section_name(".data1"); 2019*0b57cec5SDimitry Andric static ConstString bss_section_name(".bss"); 2020*0b57cec5SDimitry Andric static ConstString opd_section_name(".opd"); // For ppc64 2021*0b57cec5SDimitry Andric 2022*0b57cec5SDimitry Andric // On Android the oatdata and the oatexec symbols in the oat and odex files 2023*0b57cec5SDimitry Andric // covers the full .text section what causes issues with displaying unusable 2024*0b57cec5SDimitry Andric // symbol name to the user and very slow unwinding speed because the 2025*0b57cec5SDimitry Andric // instruction emulation based unwind plans try to emulate all instructions 2026*0b57cec5SDimitry Andric // in these symbols. Don't add these symbols to the symbol list as they have 2027*0b57cec5SDimitry Andric // no use for the debugger and they are causing a lot of trouble. Filtering 2028*0b57cec5SDimitry Andric // can't be restricted to Android because this special object file don't 2029*0b57cec5SDimitry Andric // contain the note section specifying the environment to Android but the 2030*0b57cec5SDimitry Andric // custom extension and file name makes it highly unlikely that this will 2031*0b57cec5SDimitry Andric // collide with anything else. 2032*0b57cec5SDimitry Andric ConstString file_extension = m_file.GetFileNameExtension(); 2033*0b57cec5SDimitry Andric bool skip_oatdata_oatexec = 2034*0b57cec5SDimitry Andric file_extension == ".oat" || file_extension == ".odex"; 2035*0b57cec5SDimitry Andric 2036*0b57cec5SDimitry Andric ArchSpec arch = GetArchitecture(); 2037*0b57cec5SDimitry Andric ModuleSP module_sp(GetModule()); 2038*0b57cec5SDimitry Andric SectionList *module_section_list = 2039*0b57cec5SDimitry Andric module_sp ? module_sp->GetSectionList() : nullptr; 2040*0b57cec5SDimitry Andric 2041*0b57cec5SDimitry Andric // Local cache to avoid doing a FindSectionByName for each symbol. The "const 2042*0b57cec5SDimitry Andric // char*" key must came from a ConstString object so they can be compared by 2043*0b57cec5SDimitry Andric // pointer 2044*0b57cec5SDimitry Andric std::unordered_map<const char *, lldb::SectionSP> section_name_to_section; 2045*0b57cec5SDimitry Andric 2046*0b57cec5SDimitry Andric unsigned i; 2047*0b57cec5SDimitry Andric for (i = 0; i < num_symbols; ++i) { 2048*0b57cec5SDimitry Andric if (!symbol.Parse(symtab_data, &offset)) 2049*0b57cec5SDimitry Andric break; 2050*0b57cec5SDimitry Andric 2051*0b57cec5SDimitry Andric const char *symbol_name = strtab_data.PeekCStr(symbol.st_name); 2052*0b57cec5SDimitry Andric if (!symbol_name) 2053*0b57cec5SDimitry Andric symbol_name = ""; 2054*0b57cec5SDimitry Andric 2055*0b57cec5SDimitry Andric // No need to add non-section symbols that have no names 2056*0b57cec5SDimitry Andric if (symbol.getType() != STT_SECTION && 2057*0b57cec5SDimitry Andric (symbol_name == nullptr || symbol_name[0] == '\0')) 2058*0b57cec5SDimitry Andric continue; 2059*0b57cec5SDimitry Andric 2060*0b57cec5SDimitry Andric // Skipping oatdata and oatexec sections if it is requested. See details 2061*0b57cec5SDimitry Andric // above the definition of skip_oatdata_oatexec for the reasons. 2062*0b57cec5SDimitry Andric if (skip_oatdata_oatexec && (::strcmp(symbol_name, "oatdata") == 0 || 2063*0b57cec5SDimitry Andric ::strcmp(symbol_name, "oatexec") == 0)) 2064*0b57cec5SDimitry Andric continue; 2065*0b57cec5SDimitry Andric 2066*0b57cec5SDimitry Andric SectionSP symbol_section_sp; 2067*0b57cec5SDimitry Andric SymbolType symbol_type = eSymbolTypeInvalid; 2068*0b57cec5SDimitry Andric Elf64_Half shndx = symbol.st_shndx; 2069*0b57cec5SDimitry Andric 2070*0b57cec5SDimitry Andric switch (shndx) { 2071*0b57cec5SDimitry Andric case SHN_ABS: 2072*0b57cec5SDimitry Andric symbol_type = eSymbolTypeAbsolute; 2073*0b57cec5SDimitry Andric break; 2074*0b57cec5SDimitry Andric case SHN_UNDEF: 2075*0b57cec5SDimitry Andric symbol_type = eSymbolTypeUndefined; 2076*0b57cec5SDimitry Andric break; 2077*0b57cec5SDimitry Andric default: 2078*0b57cec5SDimitry Andric symbol_section_sp = section_list->FindSectionByID(shndx); 2079*0b57cec5SDimitry Andric break; 2080*0b57cec5SDimitry Andric } 2081*0b57cec5SDimitry Andric 2082*0b57cec5SDimitry Andric // If a symbol is undefined do not process it further even if it has a STT 2083*0b57cec5SDimitry Andric // type 2084*0b57cec5SDimitry Andric if (symbol_type != eSymbolTypeUndefined) { 2085*0b57cec5SDimitry Andric switch (symbol.getType()) { 2086*0b57cec5SDimitry Andric default: 2087*0b57cec5SDimitry Andric case STT_NOTYPE: 2088*0b57cec5SDimitry Andric // The symbol's type is not specified. 2089*0b57cec5SDimitry Andric break; 2090*0b57cec5SDimitry Andric 2091*0b57cec5SDimitry Andric case STT_OBJECT: 2092*0b57cec5SDimitry Andric // The symbol is associated with a data object, such as a variable, an 2093*0b57cec5SDimitry Andric // array, etc. 2094*0b57cec5SDimitry Andric symbol_type = eSymbolTypeData; 2095*0b57cec5SDimitry Andric break; 2096*0b57cec5SDimitry Andric 2097*0b57cec5SDimitry Andric case STT_FUNC: 2098*0b57cec5SDimitry Andric // The symbol is associated with a function or other executable code. 2099*0b57cec5SDimitry Andric symbol_type = eSymbolTypeCode; 2100*0b57cec5SDimitry Andric break; 2101*0b57cec5SDimitry Andric 2102*0b57cec5SDimitry Andric case STT_SECTION: 2103*0b57cec5SDimitry Andric // The symbol is associated with a section. Symbol table entries of 2104*0b57cec5SDimitry Andric // this type exist primarily for relocation and normally have STB_LOCAL 2105*0b57cec5SDimitry Andric // binding. 2106*0b57cec5SDimitry Andric break; 2107*0b57cec5SDimitry Andric 2108*0b57cec5SDimitry Andric case STT_FILE: 2109*0b57cec5SDimitry Andric // Conventionally, the symbol's name gives the name of the source file 2110*0b57cec5SDimitry Andric // associated with the object file. A file symbol has STB_LOCAL 2111*0b57cec5SDimitry Andric // binding, its section index is SHN_ABS, and it precedes the other 2112*0b57cec5SDimitry Andric // STB_LOCAL symbols for the file, if it is present. 2113*0b57cec5SDimitry Andric symbol_type = eSymbolTypeSourceFile; 2114*0b57cec5SDimitry Andric break; 2115*0b57cec5SDimitry Andric 2116*0b57cec5SDimitry Andric case STT_GNU_IFUNC: 2117*0b57cec5SDimitry Andric // The symbol is associated with an indirect function. The actual 2118*0b57cec5SDimitry Andric // function will be resolved if it is referenced. 2119*0b57cec5SDimitry Andric symbol_type = eSymbolTypeResolver; 2120*0b57cec5SDimitry Andric break; 2121*0b57cec5SDimitry Andric } 2122*0b57cec5SDimitry Andric } 2123*0b57cec5SDimitry Andric 2124*0b57cec5SDimitry Andric if (symbol_type == eSymbolTypeInvalid && symbol.getType() != STT_SECTION) { 2125*0b57cec5SDimitry Andric if (symbol_section_sp) { 2126*0b57cec5SDimitry Andric ConstString sect_name = symbol_section_sp->GetName(); 2127*0b57cec5SDimitry Andric if (sect_name == text_section_name || sect_name == init_section_name || 2128*0b57cec5SDimitry Andric sect_name == fini_section_name || sect_name == ctors_section_name || 2129*0b57cec5SDimitry Andric sect_name == dtors_section_name) { 2130*0b57cec5SDimitry Andric symbol_type = eSymbolTypeCode; 2131*0b57cec5SDimitry Andric } else if (sect_name == data_section_name || 2132*0b57cec5SDimitry Andric sect_name == data2_section_name || 2133*0b57cec5SDimitry Andric sect_name == rodata_section_name || 2134*0b57cec5SDimitry Andric sect_name == rodata1_section_name || 2135*0b57cec5SDimitry Andric sect_name == bss_section_name) { 2136*0b57cec5SDimitry Andric symbol_type = eSymbolTypeData; 2137*0b57cec5SDimitry Andric } 2138*0b57cec5SDimitry Andric } 2139*0b57cec5SDimitry Andric } 2140*0b57cec5SDimitry Andric 2141*0b57cec5SDimitry Andric int64_t symbol_value_offset = 0; 2142*0b57cec5SDimitry Andric uint32_t additional_flags = 0; 2143*0b57cec5SDimitry Andric 2144*0b57cec5SDimitry Andric if (arch.IsValid()) { 2145*0b57cec5SDimitry Andric if (arch.GetMachine() == llvm::Triple::arm) { 2146*0b57cec5SDimitry Andric if (symbol.getBinding() == STB_LOCAL) { 2147*0b57cec5SDimitry Andric char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name); 2148*0b57cec5SDimitry Andric if (symbol_type == eSymbolTypeCode) { 2149*0b57cec5SDimitry Andric switch (mapping_symbol) { 2150*0b57cec5SDimitry Andric case 'a': 2151*0b57cec5SDimitry Andric // $a[.<any>]* - marks an ARM instruction sequence 2152*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCode; 2153*0b57cec5SDimitry Andric break; 2154*0b57cec5SDimitry Andric case 'b': 2155*0b57cec5SDimitry Andric case 't': 2156*0b57cec5SDimitry Andric // $b[.<any>]* - marks a THUMB BL instruction sequence 2157*0b57cec5SDimitry Andric // $t[.<any>]* - marks a THUMB instruction sequence 2158*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = 2159*0b57cec5SDimitry Andric AddressClass::eCodeAlternateISA; 2160*0b57cec5SDimitry Andric break; 2161*0b57cec5SDimitry Andric case 'd': 2162*0b57cec5SDimitry Andric // $d[.<any>]* - marks a data item sequence (e.g. lit pool) 2163*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eData; 2164*0b57cec5SDimitry Andric break; 2165*0b57cec5SDimitry Andric } 2166*0b57cec5SDimitry Andric } 2167*0b57cec5SDimitry Andric if (mapping_symbol) 2168*0b57cec5SDimitry Andric continue; 2169*0b57cec5SDimitry Andric } 2170*0b57cec5SDimitry Andric } else if (arch.GetMachine() == llvm::Triple::aarch64) { 2171*0b57cec5SDimitry Andric if (symbol.getBinding() == STB_LOCAL) { 2172*0b57cec5SDimitry Andric char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name); 2173*0b57cec5SDimitry Andric if (symbol_type == eSymbolTypeCode) { 2174*0b57cec5SDimitry Andric switch (mapping_symbol) { 2175*0b57cec5SDimitry Andric case 'x': 2176*0b57cec5SDimitry Andric // $x[.<any>]* - marks an A64 instruction sequence 2177*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCode; 2178*0b57cec5SDimitry Andric break; 2179*0b57cec5SDimitry Andric case 'd': 2180*0b57cec5SDimitry Andric // $d[.<any>]* - marks a data item sequence (e.g. lit pool) 2181*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eData; 2182*0b57cec5SDimitry Andric break; 2183*0b57cec5SDimitry Andric } 2184*0b57cec5SDimitry Andric } 2185*0b57cec5SDimitry Andric if (mapping_symbol) 2186*0b57cec5SDimitry Andric continue; 2187*0b57cec5SDimitry Andric } 2188*0b57cec5SDimitry Andric } 2189*0b57cec5SDimitry Andric 2190*0b57cec5SDimitry Andric if (arch.GetMachine() == llvm::Triple::arm) { 2191*0b57cec5SDimitry Andric if (symbol_type == eSymbolTypeCode) { 2192*0b57cec5SDimitry Andric if (symbol.st_value & 1) { 2193*0b57cec5SDimitry Andric // Subtracting 1 from the address effectively unsets the low order 2194*0b57cec5SDimitry Andric // bit, which results in the address actually pointing to the 2195*0b57cec5SDimitry Andric // beginning of the symbol. This delta will be used below in 2196*0b57cec5SDimitry Andric // conjunction with symbol.st_value to produce the final 2197*0b57cec5SDimitry Andric // symbol_value that we store in the symtab. 2198*0b57cec5SDimitry Andric symbol_value_offset = -1; 2199*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value ^ 1] = 2200*0b57cec5SDimitry Andric AddressClass::eCodeAlternateISA; 2201*0b57cec5SDimitry Andric } else { 2202*0b57cec5SDimitry Andric // This address is ARM 2203*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCode; 2204*0b57cec5SDimitry Andric } 2205*0b57cec5SDimitry Andric } 2206*0b57cec5SDimitry Andric } 2207*0b57cec5SDimitry Andric 2208*0b57cec5SDimitry Andric /* 2209*0b57cec5SDimitry Andric * MIPS: 2210*0b57cec5SDimitry Andric * The bit #0 of an address is used for ISA mode (1 for microMIPS, 0 for 2211*0b57cec5SDimitry Andric * MIPS). 2212*0b57cec5SDimitry Andric * This allows processor to switch between microMIPS and MIPS without any 2213*0b57cec5SDimitry Andric * need 2214*0b57cec5SDimitry Andric * for special mode-control register. However, apart from .debug_line, 2215*0b57cec5SDimitry Andric * none of 2216*0b57cec5SDimitry Andric * the ELF/DWARF sections set the ISA bit (for symbol or section). Use 2217*0b57cec5SDimitry Andric * st_other 2218*0b57cec5SDimitry Andric * flag to check whether the symbol is microMIPS and then set the address 2219*0b57cec5SDimitry Andric * class 2220*0b57cec5SDimitry Andric * accordingly. 2221*0b57cec5SDimitry Andric */ 2222*0b57cec5SDimitry Andric if (arch.IsMIPS()) { 2223*0b57cec5SDimitry Andric if (IS_MICROMIPS(symbol.st_other)) 2224*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA; 2225*0b57cec5SDimitry Andric else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode)) { 2226*0b57cec5SDimitry Andric symbol.st_value = symbol.st_value & (~1ull); 2227*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA; 2228*0b57cec5SDimitry Andric } else { 2229*0b57cec5SDimitry Andric if (symbol_type == eSymbolTypeCode) 2230*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCode; 2231*0b57cec5SDimitry Andric else if (symbol_type == eSymbolTypeData) 2232*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eData; 2233*0b57cec5SDimitry Andric else 2234*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eUnknown; 2235*0b57cec5SDimitry Andric } 2236*0b57cec5SDimitry Andric } 2237*0b57cec5SDimitry Andric } 2238*0b57cec5SDimitry Andric 2239*0b57cec5SDimitry Andric // symbol_value_offset may contain 0 for ARM symbols or -1 for THUMB 2240*0b57cec5SDimitry Andric // symbols. See above for more details. 2241*0b57cec5SDimitry Andric uint64_t symbol_value = symbol.st_value + symbol_value_offset; 2242*0b57cec5SDimitry Andric 2243*0b57cec5SDimitry Andric if (symbol_section_sp && 2244*0b57cec5SDimitry Andric CalculateType() != ObjectFile::Type::eTypeObjectFile) 2245*0b57cec5SDimitry Andric symbol_value -= symbol_section_sp->GetFileAddress(); 2246*0b57cec5SDimitry Andric 2247*0b57cec5SDimitry Andric if (symbol_section_sp && module_section_list && 2248*0b57cec5SDimitry Andric module_section_list != section_list) { 2249*0b57cec5SDimitry Andric ConstString sect_name = symbol_section_sp->GetName(); 2250*0b57cec5SDimitry Andric auto section_it = section_name_to_section.find(sect_name.GetCString()); 2251*0b57cec5SDimitry Andric if (section_it == section_name_to_section.end()) 2252*0b57cec5SDimitry Andric section_it = 2253*0b57cec5SDimitry Andric section_name_to_section 2254*0b57cec5SDimitry Andric .emplace(sect_name.GetCString(), 2255*0b57cec5SDimitry Andric module_section_list->FindSectionByName(sect_name)) 2256*0b57cec5SDimitry Andric .first; 2257*0b57cec5SDimitry Andric if (section_it->second) 2258*0b57cec5SDimitry Andric symbol_section_sp = section_it->second; 2259*0b57cec5SDimitry Andric } 2260*0b57cec5SDimitry Andric 2261*0b57cec5SDimitry Andric bool is_global = symbol.getBinding() == STB_GLOBAL; 2262*0b57cec5SDimitry Andric uint32_t flags = symbol.st_other << 8 | symbol.st_info | additional_flags; 2263*0b57cec5SDimitry Andric llvm::StringRef symbol_ref(symbol_name); 2264*0b57cec5SDimitry Andric 2265*0b57cec5SDimitry Andric // Symbol names may contain @VERSION suffixes. Find those and strip them 2266*0b57cec5SDimitry Andric // temporarily. 2267*0b57cec5SDimitry Andric size_t version_pos = symbol_ref.find('@'); 2268*0b57cec5SDimitry Andric bool has_suffix = version_pos != llvm::StringRef::npos; 2269*0b57cec5SDimitry Andric llvm::StringRef symbol_bare = symbol_ref.substr(0, version_pos); 22709dba64beSDimitry Andric Mangled mangled(symbol_bare); 2271*0b57cec5SDimitry Andric 2272*0b57cec5SDimitry Andric // Now append the suffix back to mangled and unmangled names. Only do it if 2273*0b57cec5SDimitry Andric // the demangling was successful (string is not empty). 2274*0b57cec5SDimitry Andric if (has_suffix) { 2275*0b57cec5SDimitry Andric llvm::StringRef suffix = symbol_ref.substr(version_pos); 2276*0b57cec5SDimitry Andric 2277*0b57cec5SDimitry Andric llvm::StringRef mangled_name = mangled.GetMangledName().GetStringRef(); 2278*0b57cec5SDimitry Andric if (!mangled_name.empty()) 2279*0b57cec5SDimitry Andric mangled.SetMangledName(ConstString((mangled_name + suffix).str())); 2280*0b57cec5SDimitry Andric 22815ffd83dbSDimitry Andric ConstString demangled = mangled.GetDemangledName(); 2282*0b57cec5SDimitry Andric llvm::StringRef demangled_name = demangled.GetStringRef(); 2283*0b57cec5SDimitry Andric if (!demangled_name.empty()) 2284*0b57cec5SDimitry Andric mangled.SetDemangledName(ConstString((demangled_name + suffix).str())); 2285*0b57cec5SDimitry Andric } 2286*0b57cec5SDimitry Andric 2287*0b57cec5SDimitry Andric // In ELF all symbol should have a valid size but it is not true for some 2288*0b57cec5SDimitry Andric // function symbols coming from hand written assembly. As none of the 2289*0b57cec5SDimitry Andric // function symbol should have 0 size we try to calculate the size for 2290*0b57cec5SDimitry Andric // these symbols in the symtab with saying that their original size is not 2291*0b57cec5SDimitry Andric // valid. 2292*0b57cec5SDimitry Andric bool symbol_size_valid = 2293*0b57cec5SDimitry Andric symbol.st_size != 0 || symbol.getType() != STT_FUNC; 2294*0b57cec5SDimitry Andric 2295*0b57cec5SDimitry Andric Symbol dc_symbol( 2296*0b57cec5SDimitry Andric i + start_id, // ID is the original symbol table index. 2297*0b57cec5SDimitry Andric mangled, 2298*0b57cec5SDimitry Andric symbol_type, // Type of this symbol 2299*0b57cec5SDimitry Andric is_global, // Is this globally visible? 2300*0b57cec5SDimitry Andric false, // Is this symbol debug info? 2301*0b57cec5SDimitry Andric false, // Is this symbol a trampoline? 2302*0b57cec5SDimitry Andric false, // Is this symbol artificial? 2303*0b57cec5SDimitry Andric AddressRange(symbol_section_sp, // Section in which this symbol is 2304*0b57cec5SDimitry Andric // defined or null. 2305*0b57cec5SDimitry Andric symbol_value, // Offset in section or symbol value. 2306*0b57cec5SDimitry Andric symbol.st_size), // Size in bytes of this symbol. 2307*0b57cec5SDimitry Andric symbol_size_valid, // Symbol size is valid 2308*0b57cec5SDimitry Andric has_suffix, // Contains linker annotations? 2309*0b57cec5SDimitry Andric flags); // Symbol flags. 2310480093f4SDimitry Andric if (symbol.getBinding() == STB_WEAK) 2311480093f4SDimitry Andric dc_symbol.SetIsWeak(true); 2312*0b57cec5SDimitry Andric symtab->AddSymbol(dc_symbol); 2313*0b57cec5SDimitry Andric } 2314*0b57cec5SDimitry Andric return i; 2315*0b57cec5SDimitry Andric } 2316*0b57cec5SDimitry Andric 2317*0b57cec5SDimitry Andric unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, 2318*0b57cec5SDimitry Andric user_id_t start_id, 2319*0b57cec5SDimitry Andric lldb_private::Section *symtab) { 2320*0b57cec5SDimitry Andric if (symtab->GetObjectFile() != this) { 2321*0b57cec5SDimitry Andric // If the symbol table section is owned by a different object file, have it 2322*0b57cec5SDimitry Andric // do the parsing. 2323*0b57cec5SDimitry Andric ObjectFileELF *obj_file_elf = 2324*0b57cec5SDimitry Andric static_cast<ObjectFileELF *>(symtab->GetObjectFile()); 2325*0b57cec5SDimitry Andric return obj_file_elf->ParseSymbolTable(symbol_table, start_id, symtab); 2326*0b57cec5SDimitry Andric } 2327*0b57cec5SDimitry Andric 2328*0b57cec5SDimitry Andric // Get section list for this object file. 2329*0b57cec5SDimitry Andric SectionList *section_list = m_sections_up.get(); 2330*0b57cec5SDimitry Andric if (!section_list) 2331*0b57cec5SDimitry Andric return 0; 2332*0b57cec5SDimitry Andric 2333*0b57cec5SDimitry Andric user_id_t symtab_id = symtab->GetID(); 2334*0b57cec5SDimitry Andric const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id); 2335*0b57cec5SDimitry Andric assert(symtab_hdr->sh_type == SHT_SYMTAB || 2336*0b57cec5SDimitry Andric symtab_hdr->sh_type == SHT_DYNSYM); 2337*0b57cec5SDimitry Andric 2338*0b57cec5SDimitry Andric // sh_link: section header index of associated string table. 2339*0b57cec5SDimitry Andric user_id_t strtab_id = symtab_hdr->sh_link; 2340*0b57cec5SDimitry Andric Section *strtab = section_list->FindSectionByID(strtab_id).get(); 2341*0b57cec5SDimitry Andric 2342*0b57cec5SDimitry Andric if (symtab && strtab) { 2343*0b57cec5SDimitry Andric assert(symtab->GetObjectFile() == this); 2344*0b57cec5SDimitry Andric assert(strtab->GetObjectFile() == this); 2345*0b57cec5SDimitry Andric 2346*0b57cec5SDimitry Andric DataExtractor symtab_data; 2347*0b57cec5SDimitry Andric DataExtractor strtab_data; 2348*0b57cec5SDimitry Andric if (ReadSectionData(symtab, symtab_data) && 2349*0b57cec5SDimitry Andric ReadSectionData(strtab, strtab_data)) { 2350*0b57cec5SDimitry Andric size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize; 2351*0b57cec5SDimitry Andric 2352*0b57cec5SDimitry Andric return ParseSymbols(symbol_table, start_id, section_list, num_symbols, 2353*0b57cec5SDimitry Andric symtab_data, strtab_data); 2354*0b57cec5SDimitry Andric } 2355*0b57cec5SDimitry Andric } 2356*0b57cec5SDimitry Andric 2357*0b57cec5SDimitry Andric return 0; 2358*0b57cec5SDimitry Andric } 2359*0b57cec5SDimitry Andric 2360*0b57cec5SDimitry Andric size_t ObjectFileELF::ParseDynamicSymbols() { 2361*0b57cec5SDimitry Andric if (m_dynamic_symbols.size()) 2362*0b57cec5SDimitry Andric return m_dynamic_symbols.size(); 2363*0b57cec5SDimitry Andric 2364*0b57cec5SDimitry Andric SectionList *section_list = GetSectionList(); 2365*0b57cec5SDimitry Andric if (!section_list) 2366*0b57cec5SDimitry Andric return 0; 2367*0b57cec5SDimitry Andric 2368*0b57cec5SDimitry Andric // Find the SHT_DYNAMIC section. 2369*0b57cec5SDimitry Andric Section *dynsym = 2370*0b57cec5SDimitry Andric section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true) 2371*0b57cec5SDimitry Andric .get(); 2372*0b57cec5SDimitry Andric if (!dynsym) 2373*0b57cec5SDimitry Andric return 0; 2374*0b57cec5SDimitry Andric assert(dynsym->GetObjectFile() == this); 2375*0b57cec5SDimitry Andric 2376*0b57cec5SDimitry Andric ELFDynamic symbol; 2377*0b57cec5SDimitry Andric DataExtractor dynsym_data; 2378*0b57cec5SDimitry Andric if (ReadSectionData(dynsym, dynsym_data)) { 2379*0b57cec5SDimitry Andric const lldb::offset_t section_size = dynsym_data.GetByteSize(); 2380*0b57cec5SDimitry Andric lldb::offset_t cursor = 0; 2381*0b57cec5SDimitry Andric 2382*0b57cec5SDimitry Andric while (cursor < section_size) { 2383*0b57cec5SDimitry Andric if (!symbol.Parse(dynsym_data, &cursor)) 2384*0b57cec5SDimitry Andric break; 2385*0b57cec5SDimitry Andric 2386*0b57cec5SDimitry Andric m_dynamic_symbols.push_back(symbol); 2387*0b57cec5SDimitry Andric } 2388*0b57cec5SDimitry Andric } 2389*0b57cec5SDimitry Andric 2390*0b57cec5SDimitry Andric return m_dynamic_symbols.size(); 2391*0b57cec5SDimitry Andric } 2392*0b57cec5SDimitry Andric 2393*0b57cec5SDimitry Andric const ELFDynamic *ObjectFileELF::FindDynamicSymbol(unsigned tag) { 2394*0b57cec5SDimitry Andric if (!ParseDynamicSymbols()) 2395*0b57cec5SDimitry Andric return nullptr; 2396*0b57cec5SDimitry Andric 2397*0b57cec5SDimitry Andric DynamicSymbolCollIter I = m_dynamic_symbols.begin(); 2398*0b57cec5SDimitry Andric DynamicSymbolCollIter E = m_dynamic_symbols.end(); 2399*0b57cec5SDimitry Andric for (; I != E; ++I) { 2400*0b57cec5SDimitry Andric ELFDynamic *symbol = &*I; 2401*0b57cec5SDimitry Andric 2402*0b57cec5SDimitry Andric if (symbol->d_tag == tag) 2403*0b57cec5SDimitry Andric return symbol; 2404*0b57cec5SDimitry Andric } 2405*0b57cec5SDimitry Andric 2406*0b57cec5SDimitry Andric return nullptr; 2407*0b57cec5SDimitry Andric } 2408*0b57cec5SDimitry Andric 2409*0b57cec5SDimitry Andric unsigned ObjectFileELF::PLTRelocationType() { 2410*0b57cec5SDimitry Andric // DT_PLTREL 2411*0b57cec5SDimitry Andric // This member specifies the type of relocation entry to which the 2412*0b57cec5SDimitry Andric // procedure linkage table refers. The d_val member holds DT_REL or 2413*0b57cec5SDimitry Andric // DT_RELA, as appropriate. All relocations in a procedure linkage table 2414*0b57cec5SDimitry Andric // must use the same relocation. 2415*0b57cec5SDimitry Andric const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL); 2416*0b57cec5SDimitry Andric 2417*0b57cec5SDimitry Andric if (symbol) 2418*0b57cec5SDimitry Andric return symbol->d_val; 2419*0b57cec5SDimitry Andric 2420*0b57cec5SDimitry Andric return 0; 2421*0b57cec5SDimitry Andric } 2422*0b57cec5SDimitry Andric 2423*0b57cec5SDimitry Andric // Returns the size of the normal plt entries and the offset of the first 2424*0b57cec5SDimitry Andric // normal plt entry. The 0th entry in the plt table is usually a resolution 2425*0b57cec5SDimitry Andric // entry which have different size in some architectures then the rest of the 2426*0b57cec5SDimitry Andric // plt entries. 2427*0b57cec5SDimitry Andric static std::pair<uint64_t, uint64_t> 2428*0b57cec5SDimitry Andric GetPltEntrySizeAndOffset(const ELFSectionHeader *rel_hdr, 2429*0b57cec5SDimitry Andric const ELFSectionHeader *plt_hdr) { 2430*0b57cec5SDimitry Andric const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize; 2431*0b57cec5SDimitry Andric 2432*0b57cec5SDimitry Andric // Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are 2433*0b57cec5SDimitry Andric // 16 bytes. So round the entsize up by the alignment if addralign is set. 2434*0b57cec5SDimitry Andric elf_xword plt_entsize = 2435*0b57cec5SDimitry Andric plt_hdr->sh_addralign 2436*0b57cec5SDimitry Andric ? llvm::alignTo(plt_hdr->sh_entsize, plt_hdr->sh_addralign) 2437*0b57cec5SDimitry Andric : plt_hdr->sh_entsize; 2438*0b57cec5SDimitry Andric 2439*0b57cec5SDimitry Andric // Some linkers e.g ld for arm, fill plt_hdr->sh_entsize field incorrectly. 2440*0b57cec5SDimitry Andric // PLT entries relocation code in general requires multiple instruction and 2441*0b57cec5SDimitry Andric // should be greater than 4 bytes in most cases. Try to guess correct size 2442*0b57cec5SDimitry Andric // just in case. 2443*0b57cec5SDimitry Andric if (plt_entsize <= 4) { 2444*0b57cec5SDimitry Andric // The linker haven't set the plt_hdr->sh_entsize field. Try to guess the 2445*0b57cec5SDimitry Andric // size of the plt entries based on the number of entries and the size of 2446*0b57cec5SDimitry Andric // the plt section with the assumption that the size of the 0th entry is at 2447*0b57cec5SDimitry Andric // least as big as the size of the normal entries and it isn't much bigger 2448*0b57cec5SDimitry Andric // then that. 2449*0b57cec5SDimitry Andric if (plt_hdr->sh_addralign) 2450*0b57cec5SDimitry Andric plt_entsize = plt_hdr->sh_size / plt_hdr->sh_addralign / 2451*0b57cec5SDimitry Andric (num_relocations + 1) * plt_hdr->sh_addralign; 2452*0b57cec5SDimitry Andric else 2453*0b57cec5SDimitry Andric plt_entsize = plt_hdr->sh_size / (num_relocations + 1); 2454*0b57cec5SDimitry Andric } 2455*0b57cec5SDimitry Andric 2456*0b57cec5SDimitry Andric elf_xword plt_offset = plt_hdr->sh_size - num_relocations * plt_entsize; 2457*0b57cec5SDimitry Andric 2458*0b57cec5SDimitry Andric return std::make_pair(plt_entsize, plt_offset); 2459*0b57cec5SDimitry Andric } 2460*0b57cec5SDimitry Andric 2461*0b57cec5SDimitry Andric static unsigned ParsePLTRelocations( 2462*0b57cec5SDimitry Andric Symtab *symbol_table, user_id_t start_id, unsigned rel_type, 2463*0b57cec5SDimitry Andric const ELFHeader *hdr, const ELFSectionHeader *rel_hdr, 2464*0b57cec5SDimitry Andric const ELFSectionHeader *plt_hdr, const ELFSectionHeader *sym_hdr, 2465*0b57cec5SDimitry Andric const lldb::SectionSP &plt_section_sp, DataExtractor &rel_data, 2466*0b57cec5SDimitry Andric DataExtractor &symtab_data, DataExtractor &strtab_data) { 2467*0b57cec5SDimitry Andric ELFRelocation rel(rel_type); 2468*0b57cec5SDimitry Andric ELFSymbol symbol; 2469*0b57cec5SDimitry Andric lldb::offset_t offset = 0; 2470*0b57cec5SDimitry Andric 2471*0b57cec5SDimitry Andric uint64_t plt_offset, plt_entsize; 2472*0b57cec5SDimitry Andric std::tie(plt_entsize, plt_offset) = 2473*0b57cec5SDimitry Andric GetPltEntrySizeAndOffset(rel_hdr, plt_hdr); 2474*0b57cec5SDimitry Andric const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize; 2475*0b57cec5SDimitry Andric 2476*0b57cec5SDimitry Andric typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel); 2477*0b57cec5SDimitry Andric reloc_info_fn reloc_type; 2478*0b57cec5SDimitry Andric reloc_info_fn reloc_symbol; 2479*0b57cec5SDimitry Andric 2480*0b57cec5SDimitry Andric if (hdr->Is32Bit()) { 2481*0b57cec5SDimitry Andric reloc_type = ELFRelocation::RelocType32; 2482*0b57cec5SDimitry Andric reloc_symbol = ELFRelocation::RelocSymbol32; 2483*0b57cec5SDimitry Andric } else { 2484*0b57cec5SDimitry Andric reloc_type = ELFRelocation::RelocType64; 2485*0b57cec5SDimitry Andric reloc_symbol = ELFRelocation::RelocSymbol64; 2486*0b57cec5SDimitry Andric } 2487*0b57cec5SDimitry Andric 2488*0b57cec5SDimitry Andric unsigned slot_type = hdr->GetRelocationJumpSlotType(); 2489*0b57cec5SDimitry Andric unsigned i; 2490*0b57cec5SDimitry Andric for (i = 0; i < num_relocations; ++i) { 2491*0b57cec5SDimitry Andric if (!rel.Parse(rel_data, &offset)) 2492*0b57cec5SDimitry Andric break; 2493*0b57cec5SDimitry Andric 2494*0b57cec5SDimitry Andric if (reloc_type(rel) != slot_type) 2495*0b57cec5SDimitry Andric continue; 2496*0b57cec5SDimitry Andric 2497*0b57cec5SDimitry Andric lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize; 2498*0b57cec5SDimitry Andric if (!symbol.Parse(symtab_data, &symbol_offset)) 2499*0b57cec5SDimitry Andric break; 2500*0b57cec5SDimitry Andric 2501*0b57cec5SDimitry Andric const char *symbol_name = strtab_data.PeekCStr(symbol.st_name); 2502*0b57cec5SDimitry Andric uint64_t plt_index = plt_offset + i * plt_entsize; 2503*0b57cec5SDimitry Andric 2504*0b57cec5SDimitry Andric Symbol jump_symbol( 2505*0b57cec5SDimitry Andric i + start_id, // Symbol table index 2506*0b57cec5SDimitry Andric symbol_name, // symbol name. 2507*0b57cec5SDimitry Andric eSymbolTypeTrampoline, // Type of this symbol 2508*0b57cec5SDimitry Andric false, // Is this globally visible? 2509*0b57cec5SDimitry Andric false, // Is this symbol debug info? 2510*0b57cec5SDimitry Andric true, // Is this symbol a trampoline? 2511*0b57cec5SDimitry Andric true, // Is this symbol artificial? 2512*0b57cec5SDimitry Andric plt_section_sp, // Section in which this symbol is defined or null. 2513*0b57cec5SDimitry Andric plt_index, // Offset in section or symbol value. 2514*0b57cec5SDimitry Andric plt_entsize, // Size in bytes of this symbol. 2515*0b57cec5SDimitry Andric true, // Size is valid 2516*0b57cec5SDimitry Andric false, // Contains linker annotations? 2517*0b57cec5SDimitry Andric 0); // Symbol flags. 2518*0b57cec5SDimitry Andric 2519*0b57cec5SDimitry Andric symbol_table->AddSymbol(jump_symbol); 2520*0b57cec5SDimitry Andric } 2521*0b57cec5SDimitry Andric 2522*0b57cec5SDimitry Andric return i; 2523*0b57cec5SDimitry Andric } 2524*0b57cec5SDimitry Andric 2525*0b57cec5SDimitry Andric unsigned 2526*0b57cec5SDimitry Andric ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id, 2527*0b57cec5SDimitry Andric const ELFSectionHeaderInfo *rel_hdr, 2528*0b57cec5SDimitry Andric user_id_t rel_id) { 2529*0b57cec5SDimitry Andric assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL); 2530*0b57cec5SDimitry Andric 2531*0b57cec5SDimitry Andric // The link field points to the associated symbol table. 2532*0b57cec5SDimitry Andric user_id_t symtab_id = rel_hdr->sh_link; 2533*0b57cec5SDimitry Andric 2534*0b57cec5SDimitry Andric // If the link field doesn't point to the appropriate symbol name table then 2535*0b57cec5SDimitry Andric // try to find it by name as some compiler don't fill in the link fields. 2536*0b57cec5SDimitry Andric if (!symtab_id) 2537*0b57cec5SDimitry Andric symtab_id = GetSectionIndexByName(".dynsym"); 2538*0b57cec5SDimitry Andric 2539*0b57cec5SDimitry Andric // Get PLT section. We cannot use rel_hdr->sh_info, since current linkers 2540*0b57cec5SDimitry Andric // point that to the .got.plt or .got section instead of .plt. 2541*0b57cec5SDimitry Andric user_id_t plt_id = GetSectionIndexByName(".plt"); 2542*0b57cec5SDimitry Andric 2543*0b57cec5SDimitry Andric if (!symtab_id || !plt_id) 2544*0b57cec5SDimitry Andric return 0; 2545*0b57cec5SDimitry Andric 2546*0b57cec5SDimitry Andric const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id); 2547*0b57cec5SDimitry Andric if (!plt_hdr) 2548*0b57cec5SDimitry Andric return 0; 2549*0b57cec5SDimitry Andric 2550*0b57cec5SDimitry Andric const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id); 2551*0b57cec5SDimitry Andric if (!sym_hdr) 2552*0b57cec5SDimitry Andric return 0; 2553*0b57cec5SDimitry Andric 2554*0b57cec5SDimitry Andric SectionList *section_list = m_sections_up.get(); 2555*0b57cec5SDimitry Andric if (!section_list) 2556*0b57cec5SDimitry Andric return 0; 2557*0b57cec5SDimitry Andric 2558*0b57cec5SDimitry Andric Section *rel_section = section_list->FindSectionByID(rel_id).get(); 2559*0b57cec5SDimitry Andric if (!rel_section) 2560*0b57cec5SDimitry Andric return 0; 2561*0b57cec5SDimitry Andric 2562*0b57cec5SDimitry Andric SectionSP plt_section_sp(section_list->FindSectionByID(plt_id)); 2563*0b57cec5SDimitry Andric if (!plt_section_sp) 2564*0b57cec5SDimitry Andric return 0; 2565*0b57cec5SDimitry Andric 2566*0b57cec5SDimitry Andric Section *symtab = section_list->FindSectionByID(symtab_id).get(); 2567*0b57cec5SDimitry Andric if (!symtab) 2568*0b57cec5SDimitry Andric return 0; 2569*0b57cec5SDimitry Andric 2570*0b57cec5SDimitry Andric // sh_link points to associated string table. 2571*0b57cec5SDimitry Andric Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link).get(); 2572*0b57cec5SDimitry Andric if (!strtab) 2573*0b57cec5SDimitry Andric return 0; 2574*0b57cec5SDimitry Andric 2575*0b57cec5SDimitry Andric DataExtractor rel_data; 2576*0b57cec5SDimitry Andric if (!ReadSectionData(rel_section, rel_data)) 2577*0b57cec5SDimitry Andric return 0; 2578*0b57cec5SDimitry Andric 2579*0b57cec5SDimitry Andric DataExtractor symtab_data; 2580*0b57cec5SDimitry Andric if (!ReadSectionData(symtab, symtab_data)) 2581*0b57cec5SDimitry Andric return 0; 2582*0b57cec5SDimitry Andric 2583*0b57cec5SDimitry Andric DataExtractor strtab_data; 2584*0b57cec5SDimitry Andric if (!ReadSectionData(strtab, strtab_data)) 2585*0b57cec5SDimitry Andric return 0; 2586*0b57cec5SDimitry Andric 2587*0b57cec5SDimitry Andric unsigned rel_type = PLTRelocationType(); 2588*0b57cec5SDimitry Andric if (!rel_type) 2589*0b57cec5SDimitry Andric return 0; 2590*0b57cec5SDimitry Andric 2591*0b57cec5SDimitry Andric return ParsePLTRelocations(symbol_table, start_id, rel_type, &m_header, 2592*0b57cec5SDimitry Andric rel_hdr, plt_hdr, sym_hdr, plt_section_sp, 2593*0b57cec5SDimitry Andric rel_data, symtab_data, strtab_data); 2594*0b57cec5SDimitry Andric } 2595*0b57cec5SDimitry Andric 2596*0b57cec5SDimitry Andric unsigned ObjectFileELF::ApplyRelocations( 2597*0b57cec5SDimitry Andric Symtab *symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr, 2598*0b57cec5SDimitry Andric const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr, 2599*0b57cec5SDimitry Andric DataExtractor &rel_data, DataExtractor &symtab_data, 2600*0b57cec5SDimitry Andric DataExtractor &debug_data, Section *rel_section) { 2601*0b57cec5SDimitry Andric ELFRelocation rel(rel_hdr->sh_type); 2602*0b57cec5SDimitry Andric lldb::addr_t offset = 0; 2603*0b57cec5SDimitry Andric const unsigned num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize; 2604*0b57cec5SDimitry Andric typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel); 2605*0b57cec5SDimitry Andric reloc_info_fn reloc_type; 2606*0b57cec5SDimitry Andric reloc_info_fn reloc_symbol; 2607*0b57cec5SDimitry Andric 2608*0b57cec5SDimitry Andric if (hdr->Is32Bit()) { 2609*0b57cec5SDimitry Andric reloc_type = ELFRelocation::RelocType32; 2610*0b57cec5SDimitry Andric reloc_symbol = ELFRelocation::RelocSymbol32; 2611*0b57cec5SDimitry Andric } else { 2612*0b57cec5SDimitry Andric reloc_type = ELFRelocation::RelocType64; 2613*0b57cec5SDimitry Andric reloc_symbol = ELFRelocation::RelocSymbol64; 2614*0b57cec5SDimitry Andric } 2615*0b57cec5SDimitry Andric 2616*0b57cec5SDimitry Andric for (unsigned i = 0; i < num_relocations; ++i) { 2617bdd1243dSDimitry Andric if (!rel.Parse(rel_data, &offset)) { 2618bdd1243dSDimitry Andric GetModule()->ReportError(".rel{0}[{1:d}] failed to parse relocation", 2619bdd1243dSDimitry Andric rel_section->GetName().AsCString(), i); 2620*0b57cec5SDimitry Andric break; 2621bdd1243dSDimitry Andric } 2622*0b57cec5SDimitry Andric Symbol *symbol = nullptr; 2623*0b57cec5SDimitry Andric 2624*0b57cec5SDimitry Andric if (hdr->Is32Bit()) { 2625*0b57cec5SDimitry Andric switch (reloc_type(rel)) { 2626*0b57cec5SDimitry Andric case R_386_32: 2627bdd1243dSDimitry Andric symbol = symtab->FindSymbolByID(reloc_symbol(rel)); 2628bdd1243dSDimitry Andric if (symbol) { 2629bdd1243dSDimitry Andric addr_t f_offset = 2630bdd1243dSDimitry Andric rel_section->GetFileOffset() + ELFRelocation::RelocOffset32(rel); 2631bdd1243dSDimitry Andric DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); 2632bdd1243dSDimitry Andric // ObjectFileELF creates a WritableDataBuffer in CreateInstance. 2633bdd1243dSDimitry Andric WritableDataBuffer *data_buffer = 2634bdd1243dSDimitry Andric llvm::cast<WritableDataBuffer>(data_buffer_sp.get()); 2635bdd1243dSDimitry Andric uint32_t *dst = reinterpret_cast<uint32_t *>( 2636bdd1243dSDimitry Andric data_buffer->GetBytes() + f_offset); 2637bdd1243dSDimitry Andric 2638bdd1243dSDimitry Andric addr_t value = symbol->GetAddressRef().GetFileAddress(); 2639bdd1243dSDimitry Andric if (rel.IsRela()) { 2640bdd1243dSDimitry Andric value += ELFRelocation::RelocAddend32(rel); 2641bdd1243dSDimitry Andric } else { 2642bdd1243dSDimitry Andric value += *dst; 2643bdd1243dSDimitry Andric } 2644bdd1243dSDimitry Andric *dst = value; 2645bdd1243dSDimitry Andric } else { 2646bdd1243dSDimitry Andric GetModule()->ReportError(".rel{0}[{1}] unknown symbol id: {2:d}", 2647bdd1243dSDimitry Andric rel_section->GetName().AsCString(), i, 2648bdd1243dSDimitry Andric reloc_symbol(rel)); 2649bdd1243dSDimitry Andric } 2650bdd1243dSDimitry Andric break; 2651*0b57cec5SDimitry Andric case R_386_PC32: 2652*0b57cec5SDimitry Andric default: 2653bdd1243dSDimitry Andric GetModule()->ReportError("unsupported 32-bit relocation:" 2654bdd1243dSDimitry Andric " .rel{0}[{1}], type {2}", 2655bdd1243dSDimitry Andric rel_section->GetName().AsCString(), i, 2656bdd1243dSDimitry Andric reloc_type(rel)); 2657*0b57cec5SDimitry Andric } 2658*0b57cec5SDimitry Andric } else { 2659*0b57cec5SDimitry Andric switch (reloc_type(rel)) { 2660*0b57cec5SDimitry Andric case R_AARCH64_ABS64: 2661*0b57cec5SDimitry Andric case R_X86_64_64: { 2662*0b57cec5SDimitry Andric symbol = symtab->FindSymbolByID(reloc_symbol(rel)); 2663*0b57cec5SDimitry Andric if (symbol) { 2664*0b57cec5SDimitry Andric addr_t value = symbol->GetAddressRef().GetFileAddress(); 2665*0b57cec5SDimitry Andric DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); 266681ad6265SDimitry Andric // ObjectFileELF creates a WritableDataBuffer in CreateInstance. 266781ad6265SDimitry Andric WritableDataBuffer *data_buffer = 266881ad6265SDimitry Andric llvm::cast<WritableDataBuffer>(data_buffer_sp.get()); 2669*0b57cec5SDimitry Andric uint64_t *dst = reinterpret_cast<uint64_t *>( 267081ad6265SDimitry Andric data_buffer->GetBytes() + rel_section->GetFileOffset() + 2671*0b57cec5SDimitry Andric ELFRelocation::RelocOffset64(rel)); 2672*0b57cec5SDimitry Andric uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel); 2673*0b57cec5SDimitry Andric memcpy(dst, &val_offset, sizeof(uint64_t)); 2674*0b57cec5SDimitry Andric } 2675*0b57cec5SDimitry Andric break; 2676*0b57cec5SDimitry Andric } 2677*0b57cec5SDimitry Andric case R_X86_64_32: 2678*0b57cec5SDimitry Andric case R_X86_64_32S: 2679*0b57cec5SDimitry Andric case R_AARCH64_ABS32: { 2680*0b57cec5SDimitry Andric symbol = symtab->FindSymbolByID(reloc_symbol(rel)); 2681*0b57cec5SDimitry Andric if (symbol) { 2682*0b57cec5SDimitry Andric addr_t value = symbol->GetAddressRef().GetFileAddress(); 2683*0b57cec5SDimitry Andric value += ELFRelocation::RelocAddend32(rel); 2684*0b57cec5SDimitry Andric if ((reloc_type(rel) == R_X86_64_32 && (value > UINT32_MAX)) || 2685*0b57cec5SDimitry Andric (reloc_type(rel) == R_X86_64_32S && 2686*0b57cec5SDimitry Andric ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN)) || 2687*0b57cec5SDimitry Andric (reloc_type(rel) == R_AARCH64_ABS32 && 2688*0b57cec5SDimitry Andric ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN))) { 268981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Modules); 26909dba64beSDimitry Andric LLDB_LOGF(log, "Failed to apply debug info relocations"); 2691*0b57cec5SDimitry Andric break; 2692*0b57cec5SDimitry Andric } 2693*0b57cec5SDimitry Andric uint32_t truncated_addr = (value & 0xFFFFFFFF); 2694*0b57cec5SDimitry Andric DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); 269581ad6265SDimitry Andric // ObjectFileELF creates a WritableDataBuffer in CreateInstance. 269681ad6265SDimitry Andric WritableDataBuffer *data_buffer = 269781ad6265SDimitry Andric llvm::cast<WritableDataBuffer>(data_buffer_sp.get()); 2698*0b57cec5SDimitry Andric uint32_t *dst = reinterpret_cast<uint32_t *>( 269981ad6265SDimitry Andric data_buffer->GetBytes() + rel_section->GetFileOffset() + 2700*0b57cec5SDimitry Andric ELFRelocation::RelocOffset32(rel)); 2701*0b57cec5SDimitry Andric memcpy(dst, &truncated_addr, sizeof(uint32_t)); 2702*0b57cec5SDimitry Andric } 2703*0b57cec5SDimitry Andric break; 2704*0b57cec5SDimitry Andric } 2705*0b57cec5SDimitry Andric case R_X86_64_PC32: 2706*0b57cec5SDimitry Andric default: 2707*0b57cec5SDimitry Andric assert(false && "unexpected relocation type"); 2708*0b57cec5SDimitry Andric } 2709*0b57cec5SDimitry Andric } 2710*0b57cec5SDimitry Andric } 2711*0b57cec5SDimitry Andric 2712*0b57cec5SDimitry Andric return 0; 2713*0b57cec5SDimitry Andric } 2714*0b57cec5SDimitry Andric 2715*0b57cec5SDimitry Andric unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr, 2716*0b57cec5SDimitry Andric user_id_t rel_id, 2717*0b57cec5SDimitry Andric lldb_private::Symtab *thetab) { 2718*0b57cec5SDimitry Andric assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL); 2719*0b57cec5SDimitry Andric 2720*0b57cec5SDimitry Andric // Parse in the section list if needed. 2721*0b57cec5SDimitry Andric SectionList *section_list = GetSectionList(); 2722*0b57cec5SDimitry Andric if (!section_list) 2723*0b57cec5SDimitry Andric return 0; 2724*0b57cec5SDimitry Andric 2725*0b57cec5SDimitry Andric user_id_t symtab_id = rel_hdr->sh_link; 2726*0b57cec5SDimitry Andric user_id_t debug_id = rel_hdr->sh_info; 2727*0b57cec5SDimitry Andric 2728*0b57cec5SDimitry Andric const ELFSectionHeader *symtab_hdr = GetSectionHeaderByIndex(symtab_id); 2729*0b57cec5SDimitry Andric if (!symtab_hdr) 2730*0b57cec5SDimitry Andric return 0; 2731*0b57cec5SDimitry Andric 2732*0b57cec5SDimitry Andric const ELFSectionHeader *debug_hdr = GetSectionHeaderByIndex(debug_id); 2733*0b57cec5SDimitry Andric if (!debug_hdr) 2734*0b57cec5SDimitry Andric return 0; 2735*0b57cec5SDimitry Andric 2736*0b57cec5SDimitry Andric Section *rel = section_list->FindSectionByID(rel_id).get(); 2737*0b57cec5SDimitry Andric if (!rel) 2738*0b57cec5SDimitry Andric return 0; 2739*0b57cec5SDimitry Andric 2740*0b57cec5SDimitry Andric Section *symtab = section_list->FindSectionByID(symtab_id).get(); 2741*0b57cec5SDimitry Andric if (!symtab) 2742*0b57cec5SDimitry Andric return 0; 2743*0b57cec5SDimitry Andric 2744*0b57cec5SDimitry Andric Section *debug = section_list->FindSectionByID(debug_id).get(); 2745*0b57cec5SDimitry Andric if (!debug) 2746*0b57cec5SDimitry Andric return 0; 2747*0b57cec5SDimitry Andric 2748*0b57cec5SDimitry Andric DataExtractor rel_data; 2749*0b57cec5SDimitry Andric DataExtractor symtab_data; 2750*0b57cec5SDimitry Andric DataExtractor debug_data; 2751*0b57cec5SDimitry Andric 2752*0b57cec5SDimitry Andric if (GetData(rel->GetFileOffset(), rel->GetFileSize(), rel_data) && 2753*0b57cec5SDimitry Andric GetData(symtab->GetFileOffset(), symtab->GetFileSize(), symtab_data) && 2754*0b57cec5SDimitry Andric GetData(debug->GetFileOffset(), debug->GetFileSize(), debug_data)) { 2755*0b57cec5SDimitry Andric ApplyRelocations(thetab, &m_header, rel_hdr, symtab_hdr, debug_hdr, 2756*0b57cec5SDimitry Andric rel_data, symtab_data, debug_data, debug); 2757*0b57cec5SDimitry Andric } 2758*0b57cec5SDimitry Andric 2759*0b57cec5SDimitry Andric return 0; 2760*0b57cec5SDimitry Andric } 2761*0b57cec5SDimitry Andric 27624824e7fdSDimitry Andric void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) { 2763*0b57cec5SDimitry Andric ModuleSP module_sp(GetModule()); 2764*0b57cec5SDimitry Andric if (!module_sp) 27654824e7fdSDimitry Andric return; 27664824e7fdSDimitry Andric 27674824e7fdSDimitry Andric Progress progress( 27684824e7fdSDimitry Andric llvm::formatv("Parsing symbol table for {0}", 27694824e7fdSDimitry Andric m_file.GetFilename().AsCString("<Unknown>"))); 27704824e7fdSDimitry Andric ElapsedTime elapsed(module_sp->GetSymtabParseTime()); 2771*0b57cec5SDimitry Andric 2772*0b57cec5SDimitry Andric // We always want to use the main object file so we (hopefully) only have one 2773*0b57cec5SDimitry Andric // cached copy of our symtab, dynamic sections, etc. 2774*0b57cec5SDimitry Andric ObjectFile *module_obj_file = module_sp->GetObjectFile(); 2775*0b57cec5SDimitry Andric if (module_obj_file && module_obj_file != this) 27764824e7fdSDimitry Andric return module_obj_file->ParseSymtab(lldb_symtab); 2777*0b57cec5SDimitry Andric 2778*0b57cec5SDimitry Andric SectionList *section_list = module_sp->GetSectionList(); 2779*0b57cec5SDimitry Andric if (!section_list) 27804824e7fdSDimitry Andric return; 2781*0b57cec5SDimitry Andric 2782*0b57cec5SDimitry Andric uint64_t symbol_id = 0; 2783*0b57cec5SDimitry Andric 2784*0b57cec5SDimitry Andric // Sharable objects and dynamic executables usually have 2 distinct symbol 2785*0b57cec5SDimitry Andric // tables, one named ".symtab", and the other ".dynsym". The dynsym is a 2786*0b57cec5SDimitry Andric // smaller version of the symtab that only contains global symbols. The 2787*0b57cec5SDimitry Andric // information found in the dynsym is therefore also found in the symtab, 2788*0b57cec5SDimitry Andric // while the reverse is not necessarily true. 2789*0b57cec5SDimitry Andric Section *symtab = 2790*0b57cec5SDimitry Andric section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get(); 27914824e7fdSDimitry Andric if (symtab) 27924824e7fdSDimitry Andric symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, symtab); 2793*0b57cec5SDimitry Andric 27949dba64beSDimitry Andric // The symtab section is non-allocable and can be stripped, while the 27959dba64beSDimitry Andric // .dynsym section which should always be always be there. To support the 27969dba64beSDimitry Andric // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo 27979dba64beSDimitry Andric // section, nomatter if .symtab was already parsed or not. This is because 27989dba64beSDimitry Andric // minidebuginfo normally removes the .symtab symbols which have their 27999dba64beSDimitry Andric // matching .dynsym counterparts. 28009dba64beSDimitry Andric if (!symtab || 28019dba64beSDimitry Andric GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) { 28029dba64beSDimitry Andric Section *dynsym = 28039dba64beSDimitry Andric section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true) 28049dba64beSDimitry Andric .get(); 28054824e7fdSDimitry Andric if (dynsym) 28064824e7fdSDimitry Andric symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, dynsym); 28079dba64beSDimitry Andric } 28089dba64beSDimitry Andric 2809*0b57cec5SDimitry Andric // DT_JMPREL 2810*0b57cec5SDimitry Andric // If present, this entry's d_ptr member holds the address of 2811*0b57cec5SDimitry Andric // relocation 2812*0b57cec5SDimitry Andric // entries associated solely with the procedure linkage table. 2813*0b57cec5SDimitry Andric // Separating 2814*0b57cec5SDimitry Andric // these relocation entries lets the dynamic linker ignore them during 2815*0b57cec5SDimitry Andric // process initialization, if lazy binding is enabled. If this entry is 2816*0b57cec5SDimitry Andric // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must 2817*0b57cec5SDimitry Andric // also be present. 2818*0b57cec5SDimitry Andric const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL); 2819*0b57cec5SDimitry Andric if (symbol) { 2820*0b57cec5SDimitry Andric // Synthesize trampoline symbols to help navigate the PLT. 2821*0b57cec5SDimitry Andric addr_t addr = symbol->d_ptr; 2822*0b57cec5SDimitry Andric Section *reloc_section = 2823*0b57cec5SDimitry Andric section_list->FindSectionContainingFileAddress(addr).get(); 2824*0b57cec5SDimitry Andric if (reloc_section) { 2825*0b57cec5SDimitry Andric user_id_t reloc_id = reloc_section->GetID(); 2826*0b57cec5SDimitry Andric const ELFSectionHeaderInfo *reloc_header = 2827*0b57cec5SDimitry Andric GetSectionHeaderByIndex(reloc_id); 28284824e7fdSDimitry Andric if (reloc_header) 28294824e7fdSDimitry Andric ParseTrampolineSymbols(&lldb_symtab, symbol_id, reloc_header, reloc_id); 2830*0b57cec5SDimitry Andric } 2831fe6060f1SDimitry Andric } 2832*0b57cec5SDimitry Andric 2833*0b57cec5SDimitry Andric if (DWARFCallFrameInfo *eh_frame = 2834*0b57cec5SDimitry Andric GetModule()->GetUnwindTable().GetEHFrameInfo()) { 28354824e7fdSDimitry Andric ParseUnwindSymbols(&lldb_symtab, eh_frame); 2836*0b57cec5SDimitry Andric } 2837*0b57cec5SDimitry Andric 28389dba64beSDimitry Andric // In the event that there's no symbol entry for the entry point we'll 28395ffd83dbSDimitry Andric // artificially create one. We delegate to the symtab object the figuring 28409dba64beSDimitry Andric // out of the proper size, this will usually make it span til the next 28419dba64beSDimitry Andric // symbol it finds in the section. This means that if there are missing 28429dba64beSDimitry Andric // symbols the entry point might span beyond its function definition. 28439dba64beSDimitry Andric // We're fine with this as it doesn't make it worse than not having a 28449dba64beSDimitry Andric // symbol entry at all. 28459dba64beSDimitry Andric if (CalculateType() == eTypeExecutable) { 28469dba64beSDimitry Andric ArchSpec arch = GetArchitecture(); 28479dba64beSDimitry Andric auto entry_point_addr = GetEntryPointAddress(); 28489dba64beSDimitry Andric bool is_valid_entry_point = 28499dba64beSDimitry Andric entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset(); 28509dba64beSDimitry Andric addr_t entry_point_file_addr = entry_point_addr.GetFileAddress(); 28514824e7fdSDimitry Andric if (is_valid_entry_point && !lldb_symtab.FindSymbolContainingFileAddress( 28529dba64beSDimitry Andric entry_point_file_addr)) { 28534824e7fdSDimitry Andric uint64_t symbol_id = lldb_symtab.GetNumSymbols(); 2854fe6060f1SDimitry Andric // Don't set the name for any synthetic symbols, the Symbol 2855fe6060f1SDimitry Andric // object will generate one if needed when the name is accessed 2856fe6060f1SDimitry Andric // via accessors. 2857fe6060f1SDimitry Andric SectionSP section_sp = entry_point_addr.GetSection(); 2858fe6060f1SDimitry Andric Symbol symbol( 2859fe6060f1SDimitry Andric /*symID=*/symbol_id, 2860fe6060f1SDimitry Andric /*name=*/llvm::StringRef(), // Name will be auto generated. 2861fe6060f1SDimitry Andric /*type=*/eSymbolTypeCode, 2862fe6060f1SDimitry Andric /*external=*/true, 2863fe6060f1SDimitry Andric /*is_debug=*/false, 2864fe6060f1SDimitry Andric /*is_trampoline=*/false, 2865fe6060f1SDimitry Andric /*is_artificial=*/true, 2866fe6060f1SDimitry Andric /*section_sp=*/section_sp, 2867fe6060f1SDimitry Andric /*offset=*/0, 2868fe6060f1SDimitry Andric /*size=*/0, // FDE can span multiple symbols so don't use its size. 2869fe6060f1SDimitry Andric /*size_is_valid=*/false, 2870fe6060f1SDimitry Andric /*contains_linker_annotations=*/false, 2871fe6060f1SDimitry Andric /*flags=*/0); 28729dba64beSDimitry Andric // When the entry point is arm thumb we need to explicitly set its 28739dba64beSDimitry Andric // class address to reflect that. This is important because expression 28749dba64beSDimitry Andric // evaluation relies on correctly setting a breakpoint at this 28759dba64beSDimitry Andric // address. 28769dba64beSDimitry Andric if (arch.GetMachine() == llvm::Triple::arm && 2877fe6060f1SDimitry Andric (entry_point_file_addr & 1)) { 2878fe6060f1SDimitry Andric symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1); 28799dba64beSDimitry Andric m_address_class_map[entry_point_file_addr ^ 1] = 28809dba64beSDimitry Andric AddressClass::eCodeAlternateISA; 2881fe6060f1SDimitry Andric } else { 28829dba64beSDimitry Andric m_address_class_map[entry_point_file_addr] = AddressClass::eCode; 28839dba64beSDimitry Andric } 28844824e7fdSDimitry Andric lldb_symtab.AddSymbol(symbol); 2885fe6060f1SDimitry Andric } 28869dba64beSDimitry Andric } 2887*0b57cec5SDimitry Andric } 2888*0b57cec5SDimitry Andric 2889*0b57cec5SDimitry Andric void ObjectFileELF::RelocateSection(lldb_private::Section *section) 2890*0b57cec5SDimitry Andric { 2891*0b57cec5SDimitry Andric static const char *debug_prefix = ".debug"; 2892*0b57cec5SDimitry Andric 2893*0b57cec5SDimitry Andric // Set relocated bit so we stop getting called, regardless of whether we 2894*0b57cec5SDimitry Andric // actually relocate. 2895*0b57cec5SDimitry Andric section->SetIsRelocated(true); 2896*0b57cec5SDimitry Andric 2897*0b57cec5SDimitry Andric // We only relocate in ELF relocatable files 2898*0b57cec5SDimitry Andric if (CalculateType() != eTypeObjectFile) 2899*0b57cec5SDimitry Andric return; 2900*0b57cec5SDimitry Andric 2901*0b57cec5SDimitry Andric const char *section_name = section->GetName().GetCString(); 2902*0b57cec5SDimitry Andric // Can't relocate that which can't be named 2903*0b57cec5SDimitry Andric if (section_name == nullptr) 2904*0b57cec5SDimitry Andric return; 2905*0b57cec5SDimitry Andric 2906*0b57cec5SDimitry Andric // We don't relocate non-debug sections at the moment 2907*0b57cec5SDimitry Andric if (strncmp(section_name, debug_prefix, strlen(debug_prefix))) 2908*0b57cec5SDimitry Andric return; 2909*0b57cec5SDimitry Andric 2910*0b57cec5SDimitry Andric // Relocation section names to look for 2911*0b57cec5SDimitry Andric std::string needle = std::string(".rel") + section_name; 2912*0b57cec5SDimitry Andric std::string needlea = std::string(".rela") + section_name; 2913*0b57cec5SDimitry Andric 2914*0b57cec5SDimitry Andric for (SectionHeaderCollIter I = m_section_headers.begin(); 2915*0b57cec5SDimitry Andric I != m_section_headers.end(); ++I) { 2916*0b57cec5SDimitry Andric if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL) { 2917*0b57cec5SDimitry Andric const char *hay_name = I->section_name.GetCString(); 2918*0b57cec5SDimitry Andric if (hay_name == nullptr) 2919*0b57cec5SDimitry Andric continue; 2920*0b57cec5SDimitry Andric if (needle == hay_name || needlea == hay_name) { 2921*0b57cec5SDimitry Andric const ELFSectionHeader &reloc_header = *I; 2922*0b57cec5SDimitry Andric user_id_t reloc_id = SectionIndex(I); 2923*0b57cec5SDimitry Andric RelocateDebugSections(&reloc_header, reloc_id, GetSymtab()); 2924*0b57cec5SDimitry Andric break; 2925*0b57cec5SDimitry Andric } 2926*0b57cec5SDimitry Andric } 2927*0b57cec5SDimitry Andric } 2928*0b57cec5SDimitry Andric } 2929*0b57cec5SDimitry Andric 2930*0b57cec5SDimitry Andric void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table, 2931*0b57cec5SDimitry Andric DWARFCallFrameInfo *eh_frame) { 2932*0b57cec5SDimitry Andric SectionList *section_list = GetSectionList(); 2933*0b57cec5SDimitry Andric if (!section_list) 2934*0b57cec5SDimitry Andric return; 2935*0b57cec5SDimitry Andric 2936*0b57cec5SDimitry Andric // First we save the new symbols into a separate list and add them to the 29375ffd83dbSDimitry Andric // symbol table after we collected all symbols we want to add. This is 2938*0b57cec5SDimitry Andric // neccessary because adding a new symbol invalidates the internal index of 2939*0b57cec5SDimitry Andric // the symtab what causing the next lookup to be slow because it have to 2940*0b57cec5SDimitry Andric // recalculate the index first. 2941*0b57cec5SDimitry Andric std::vector<Symbol> new_symbols; 2942*0b57cec5SDimitry Andric 2943fe6060f1SDimitry Andric size_t num_symbols = symbol_table->GetNumSymbols(); 2944fe6060f1SDimitry Andric uint64_t last_symbol_id = 2945fe6060f1SDimitry Andric num_symbols ? symbol_table->SymbolAtIndex(num_symbols - 1)->GetID() : 0; 2946fe6060f1SDimitry Andric eh_frame->ForEachFDEEntries([&](lldb::addr_t file_addr, uint32_t size, 2947fe6060f1SDimitry Andric dw_offset_t) { 2948*0b57cec5SDimitry Andric Symbol *symbol = symbol_table->FindSymbolAtFileAddress(file_addr); 2949*0b57cec5SDimitry Andric if (symbol) { 2950*0b57cec5SDimitry Andric if (!symbol->GetByteSizeIsValid()) { 2951*0b57cec5SDimitry Andric symbol->SetByteSize(size); 2952*0b57cec5SDimitry Andric symbol->SetSizeIsSynthesized(true); 2953*0b57cec5SDimitry Andric } 2954*0b57cec5SDimitry Andric } else { 2955*0b57cec5SDimitry Andric SectionSP section_sp = 2956*0b57cec5SDimitry Andric section_list->FindSectionContainingFileAddress(file_addr); 2957*0b57cec5SDimitry Andric if (section_sp) { 2958*0b57cec5SDimitry Andric addr_t offset = file_addr - section_sp->GetFileAddress(); 2959fe6060f1SDimitry Andric uint64_t symbol_id = ++last_symbol_id; 2960fe6060f1SDimitry Andric // Don't set the name for any synthetic symbols, the Symbol 2961fe6060f1SDimitry Andric // object will generate one if needed when the name is accessed 2962fe6060f1SDimitry Andric // via accessors. 2963*0b57cec5SDimitry Andric Symbol eh_symbol( 2964fe6060f1SDimitry Andric /*symID=*/symbol_id, 2965fe6060f1SDimitry Andric /*name=*/llvm::StringRef(), // Name will be auto generated. 2966fe6060f1SDimitry Andric /*type=*/eSymbolTypeCode, 2967fe6060f1SDimitry Andric /*external=*/true, 2968fe6060f1SDimitry Andric /*is_debug=*/false, 2969fe6060f1SDimitry Andric /*is_trampoline=*/false, 2970fe6060f1SDimitry Andric /*is_artificial=*/true, 2971fe6060f1SDimitry Andric /*section_sp=*/section_sp, 2972fe6060f1SDimitry Andric /*offset=*/offset, 2973fe6060f1SDimitry Andric /*size=*/0, // FDE can span multiple symbols so don't use its size. 2974fe6060f1SDimitry Andric /*size_is_valid=*/false, 2975fe6060f1SDimitry Andric /*contains_linker_annotations=*/false, 2976fe6060f1SDimitry Andric /*flags=*/0); 2977*0b57cec5SDimitry Andric new_symbols.push_back(eh_symbol); 2978*0b57cec5SDimitry Andric } 2979*0b57cec5SDimitry Andric } 2980*0b57cec5SDimitry Andric return true; 2981*0b57cec5SDimitry Andric }); 2982*0b57cec5SDimitry Andric 2983*0b57cec5SDimitry Andric for (const Symbol &s : new_symbols) 2984*0b57cec5SDimitry Andric symbol_table->AddSymbol(s); 2985*0b57cec5SDimitry Andric } 2986*0b57cec5SDimitry Andric 2987*0b57cec5SDimitry Andric bool ObjectFileELF::IsStripped() { 2988*0b57cec5SDimitry Andric // TODO: determine this for ELF 2989*0b57cec5SDimitry Andric return false; 2990*0b57cec5SDimitry Andric } 2991*0b57cec5SDimitry Andric 2992*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2993*0b57cec5SDimitry Andric // Dump 2994*0b57cec5SDimitry Andric // 2995*0b57cec5SDimitry Andric // Dump the specifics of the runtime file container (such as any headers 2996*0b57cec5SDimitry Andric // segments, sections, etc). 2997*0b57cec5SDimitry Andric void ObjectFileELF::Dump(Stream *s) { 2998*0b57cec5SDimitry Andric ModuleSP module_sp(GetModule()); 2999*0b57cec5SDimitry Andric if (!module_sp) { 3000*0b57cec5SDimitry Andric return; 3001*0b57cec5SDimitry Andric } 3002*0b57cec5SDimitry Andric 3003*0b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 3004*0b57cec5SDimitry Andric s->Printf("%p: ", static_cast<void *>(this)); 3005*0b57cec5SDimitry Andric s->Indent(); 3006*0b57cec5SDimitry Andric s->PutCString("ObjectFileELF"); 3007*0b57cec5SDimitry Andric 3008*0b57cec5SDimitry Andric ArchSpec header_arch = GetArchitecture(); 3009*0b57cec5SDimitry Andric 3010*0b57cec5SDimitry Andric *s << ", file = '" << m_file 3011*0b57cec5SDimitry Andric << "', arch = " << header_arch.GetArchitectureName() << "\n"; 3012*0b57cec5SDimitry Andric 3013*0b57cec5SDimitry Andric DumpELFHeader(s, m_header); 3014*0b57cec5SDimitry Andric s->EOL(); 3015*0b57cec5SDimitry Andric DumpELFProgramHeaders(s); 3016*0b57cec5SDimitry Andric s->EOL(); 3017*0b57cec5SDimitry Andric DumpELFSectionHeaders(s); 3018*0b57cec5SDimitry Andric s->EOL(); 3019*0b57cec5SDimitry Andric SectionList *section_list = GetSectionList(); 3020*0b57cec5SDimitry Andric if (section_list) 30215ffd83dbSDimitry Andric section_list->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true, 30225ffd83dbSDimitry Andric UINT32_MAX); 3023*0b57cec5SDimitry Andric Symtab *symtab = GetSymtab(); 3024*0b57cec5SDimitry Andric if (symtab) 3025*0b57cec5SDimitry Andric symtab->Dump(s, nullptr, eSortOrderNone); 3026*0b57cec5SDimitry Andric s->EOL(); 3027*0b57cec5SDimitry Andric DumpDependentModules(s); 3028*0b57cec5SDimitry Andric s->EOL(); 3029*0b57cec5SDimitry Andric } 3030*0b57cec5SDimitry Andric 3031*0b57cec5SDimitry Andric // DumpELFHeader 3032*0b57cec5SDimitry Andric // 3033*0b57cec5SDimitry Andric // Dump the ELF header to the specified output stream 3034*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) { 3035*0b57cec5SDimitry Andric s->PutCString("ELF Header\n"); 3036*0b57cec5SDimitry Andric s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]); 3037*0b57cec5SDimitry Andric s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG1], 3038*0b57cec5SDimitry Andric header.e_ident[EI_MAG1]); 3039*0b57cec5SDimitry Andric s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG2], 3040*0b57cec5SDimitry Andric header.e_ident[EI_MAG2]); 3041*0b57cec5SDimitry Andric s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG3], 3042*0b57cec5SDimitry Andric header.e_ident[EI_MAG3]); 3043*0b57cec5SDimitry Andric 3044*0b57cec5SDimitry Andric s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]); 3045*0b57cec5SDimitry Andric s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]); 3046*0b57cec5SDimitry Andric DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]); 3047*0b57cec5SDimitry Andric s->Printf("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]); 3048*0b57cec5SDimitry Andric s->Printf("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]); 3049*0b57cec5SDimitry Andric 3050*0b57cec5SDimitry Andric s->Printf("e_type = 0x%4.4x ", header.e_type); 3051*0b57cec5SDimitry Andric DumpELFHeader_e_type(s, header.e_type); 3052*0b57cec5SDimitry Andric s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine); 3053*0b57cec5SDimitry Andric s->Printf("e_version = 0x%8.8x\n", header.e_version); 3054*0b57cec5SDimitry Andric s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry); 3055*0b57cec5SDimitry Andric s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff); 3056*0b57cec5SDimitry Andric s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff); 3057*0b57cec5SDimitry Andric s->Printf("e_flags = 0x%8.8x\n", header.e_flags); 3058*0b57cec5SDimitry Andric s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize); 3059*0b57cec5SDimitry Andric s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize); 3060*0b57cec5SDimitry Andric s->Printf("e_phnum = 0x%8.8x\n", header.e_phnum); 3061*0b57cec5SDimitry Andric s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize); 3062*0b57cec5SDimitry Andric s->Printf("e_shnum = 0x%8.8x\n", header.e_shnum); 3063*0b57cec5SDimitry Andric s->Printf("e_shstrndx = 0x%8.8x\n", header.e_shstrndx); 3064*0b57cec5SDimitry Andric } 3065*0b57cec5SDimitry Andric 3066*0b57cec5SDimitry Andric // DumpELFHeader_e_type 3067*0b57cec5SDimitry Andric // 3068*0b57cec5SDimitry Andric // Dump an token value for the ELF header member e_type 3069*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type) { 3070*0b57cec5SDimitry Andric switch (e_type) { 3071*0b57cec5SDimitry Andric case ET_NONE: 3072*0b57cec5SDimitry Andric *s << "ET_NONE"; 3073*0b57cec5SDimitry Andric break; 3074*0b57cec5SDimitry Andric case ET_REL: 3075*0b57cec5SDimitry Andric *s << "ET_REL"; 3076*0b57cec5SDimitry Andric break; 3077*0b57cec5SDimitry Andric case ET_EXEC: 3078*0b57cec5SDimitry Andric *s << "ET_EXEC"; 3079*0b57cec5SDimitry Andric break; 3080*0b57cec5SDimitry Andric case ET_DYN: 3081*0b57cec5SDimitry Andric *s << "ET_DYN"; 3082*0b57cec5SDimitry Andric break; 3083*0b57cec5SDimitry Andric case ET_CORE: 3084*0b57cec5SDimitry Andric *s << "ET_CORE"; 3085*0b57cec5SDimitry Andric break; 3086*0b57cec5SDimitry Andric default: 3087*0b57cec5SDimitry Andric break; 3088*0b57cec5SDimitry Andric } 3089*0b57cec5SDimitry Andric } 3090*0b57cec5SDimitry Andric 3091*0b57cec5SDimitry Andric // DumpELFHeader_e_ident_EI_DATA 3092*0b57cec5SDimitry Andric // 3093*0b57cec5SDimitry Andric // Dump an token value for the ELF header member e_ident[EI_DATA] 3094*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, 3095*0b57cec5SDimitry Andric unsigned char ei_data) { 3096*0b57cec5SDimitry Andric switch (ei_data) { 3097*0b57cec5SDimitry Andric case ELFDATANONE: 3098*0b57cec5SDimitry Andric *s << "ELFDATANONE"; 3099*0b57cec5SDimitry Andric break; 3100*0b57cec5SDimitry Andric case ELFDATA2LSB: 3101*0b57cec5SDimitry Andric *s << "ELFDATA2LSB - Little Endian"; 3102*0b57cec5SDimitry Andric break; 3103*0b57cec5SDimitry Andric case ELFDATA2MSB: 3104*0b57cec5SDimitry Andric *s << "ELFDATA2MSB - Big Endian"; 3105*0b57cec5SDimitry Andric break; 3106*0b57cec5SDimitry Andric default: 3107*0b57cec5SDimitry Andric break; 3108*0b57cec5SDimitry Andric } 3109*0b57cec5SDimitry Andric } 3110*0b57cec5SDimitry Andric 3111*0b57cec5SDimitry Andric // DumpELFProgramHeader 3112*0b57cec5SDimitry Andric // 3113*0b57cec5SDimitry Andric // Dump a single ELF program header to the specified output stream 3114*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFProgramHeader(Stream *s, 3115*0b57cec5SDimitry Andric const ELFProgramHeader &ph) { 3116*0b57cec5SDimitry Andric DumpELFProgramHeader_p_type(s, ph.p_type); 3117*0b57cec5SDimitry Andric s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset, 3118*0b57cec5SDimitry Andric ph.p_vaddr, ph.p_paddr); 3119*0b57cec5SDimitry Andric s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8x (", ph.p_filesz, ph.p_memsz, 3120*0b57cec5SDimitry Andric ph.p_flags); 3121*0b57cec5SDimitry Andric 3122*0b57cec5SDimitry Andric DumpELFProgramHeader_p_flags(s, ph.p_flags); 3123*0b57cec5SDimitry Andric s->Printf(") %8.8" PRIx64, ph.p_align); 3124*0b57cec5SDimitry Andric } 3125*0b57cec5SDimitry Andric 3126*0b57cec5SDimitry Andric // DumpELFProgramHeader_p_type 3127*0b57cec5SDimitry Andric // 3128*0b57cec5SDimitry Andric // Dump an token value for the ELF program header member p_type which describes 3129*0b57cec5SDimitry Andric // the type of the program header 3130*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) { 3131*0b57cec5SDimitry Andric const int kStrWidth = 15; 3132*0b57cec5SDimitry Andric switch (p_type) { 3133*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_NULL, kStrWidth); 3134*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_LOAD, kStrWidth); 3135*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_DYNAMIC, kStrWidth); 3136*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_INTERP, kStrWidth); 3137*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_NOTE, kStrWidth); 3138*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_SHLIB, kStrWidth); 3139*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_PHDR, kStrWidth); 3140*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_TLS, kStrWidth); 3141*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_GNU_EH_FRAME, kStrWidth); 3142*0b57cec5SDimitry Andric default: 3143*0b57cec5SDimitry Andric s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, ""); 3144*0b57cec5SDimitry Andric break; 3145*0b57cec5SDimitry Andric } 3146*0b57cec5SDimitry Andric } 3147*0b57cec5SDimitry Andric 3148*0b57cec5SDimitry Andric // DumpELFProgramHeader_p_flags 3149*0b57cec5SDimitry Andric // 3150*0b57cec5SDimitry Andric // Dump an token value for the ELF program header member p_flags 3151*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) { 3152*0b57cec5SDimitry Andric *s << ((p_flags & PF_X) ? "PF_X" : " ") 3153*0b57cec5SDimitry Andric << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ') 3154*0b57cec5SDimitry Andric << ((p_flags & PF_W) ? "PF_W" : " ") 3155*0b57cec5SDimitry Andric << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ') 3156*0b57cec5SDimitry Andric << ((p_flags & PF_R) ? "PF_R" : " "); 3157*0b57cec5SDimitry Andric } 3158*0b57cec5SDimitry Andric 3159*0b57cec5SDimitry Andric // DumpELFProgramHeaders 3160*0b57cec5SDimitry Andric // 3161*0b57cec5SDimitry Andric // Dump all of the ELF program header to the specified output stream 3162*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFProgramHeaders(Stream *s) { 3163*0b57cec5SDimitry Andric if (!ParseProgramHeaders()) 3164*0b57cec5SDimitry Andric return; 3165*0b57cec5SDimitry Andric 3166*0b57cec5SDimitry Andric s->PutCString("Program Headers\n"); 3167*0b57cec5SDimitry Andric s->PutCString("IDX p_type p_offset p_vaddr p_paddr " 3168*0b57cec5SDimitry Andric "p_filesz p_memsz p_flags p_align\n"); 3169*0b57cec5SDimitry Andric s->PutCString("==== --------------- -------- -------- -------- " 3170*0b57cec5SDimitry Andric "-------- -------- ------------------------- --------\n"); 3171*0b57cec5SDimitry Andric 3172*0b57cec5SDimitry Andric for (const auto &H : llvm::enumerate(m_program_headers)) { 3173*0b57cec5SDimitry Andric s->Format("[{0,2}] ", H.index()); 3174*0b57cec5SDimitry Andric ObjectFileELF::DumpELFProgramHeader(s, H.value()); 3175*0b57cec5SDimitry Andric s->EOL(); 3176*0b57cec5SDimitry Andric } 3177*0b57cec5SDimitry Andric } 3178*0b57cec5SDimitry Andric 3179*0b57cec5SDimitry Andric // DumpELFSectionHeader 3180*0b57cec5SDimitry Andric // 3181*0b57cec5SDimitry Andric // Dump a single ELF section header to the specified output stream 3182*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFSectionHeader(Stream *s, 3183*0b57cec5SDimitry Andric const ELFSectionHeaderInfo &sh) { 3184*0b57cec5SDimitry Andric s->Printf("%8.8x ", sh.sh_name); 3185*0b57cec5SDimitry Andric DumpELFSectionHeader_sh_type(s, sh.sh_type); 3186*0b57cec5SDimitry Andric s->Printf(" %8.8" PRIx64 " (", sh.sh_flags); 3187*0b57cec5SDimitry Andric DumpELFSectionHeader_sh_flags(s, sh.sh_flags); 3188*0b57cec5SDimitry Andric s->Printf(") %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addr, 3189*0b57cec5SDimitry Andric sh.sh_offset, sh.sh_size); 3190*0b57cec5SDimitry Andric s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info); 3191*0b57cec5SDimitry Andric s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize); 3192*0b57cec5SDimitry Andric } 3193*0b57cec5SDimitry Andric 3194*0b57cec5SDimitry Andric // DumpELFSectionHeader_sh_type 3195*0b57cec5SDimitry Andric // 3196*0b57cec5SDimitry Andric // Dump an token value for the ELF section header member sh_type which 3197*0b57cec5SDimitry Andric // describes the type of the section 3198*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type) { 3199*0b57cec5SDimitry Andric const int kStrWidth = 12; 3200*0b57cec5SDimitry Andric switch (sh_type) { 3201*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_NULL, kStrWidth); 3202*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_PROGBITS, kStrWidth); 3203*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_SYMTAB, kStrWidth); 3204*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_STRTAB, kStrWidth); 3205*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_RELA, kStrWidth); 3206*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_HASH, kStrWidth); 3207*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_DYNAMIC, kStrWidth); 3208*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_NOTE, kStrWidth); 3209*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_NOBITS, kStrWidth); 3210*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_REL, kStrWidth); 3211*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_SHLIB, kStrWidth); 3212*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_DYNSYM, kStrWidth); 3213*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_LOPROC, kStrWidth); 3214*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_HIPROC, kStrWidth); 3215*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_LOUSER, kStrWidth); 3216*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_HIUSER, kStrWidth); 3217*0b57cec5SDimitry Andric default: 3218*0b57cec5SDimitry Andric s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, ""); 3219*0b57cec5SDimitry Andric break; 3220*0b57cec5SDimitry Andric } 3221*0b57cec5SDimitry Andric } 3222*0b57cec5SDimitry Andric 3223*0b57cec5SDimitry Andric // DumpELFSectionHeader_sh_flags 3224*0b57cec5SDimitry Andric // 3225*0b57cec5SDimitry Andric // Dump an token value for the ELF section header member sh_flags 3226*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, 3227*0b57cec5SDimitry Andric elf_xword sh_flags) { 3228*0b57cec5SDimitry Andric *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ") 3229*0b57cec5SDimitry Andric << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ') 3230*0b57cec5SDimitry Andric << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ") 3231*0b57cec5SDimitry Andric << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ') 3232*0b57cec5SDimitry Andric << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " "); 3233*0b57cec5SDimitry Andric } 3234*0b57cec5SDimitry Andric 3235*0b57cec5SDimitry Andric // DumpELFSectionHeaders 3236*0b57cec5SDimitry Andric // 3237*0b57cec5SDimitry Andric // Dump all of the ELF section header to the specified output stream 3238*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFSectionHeaders(Stream *s) { 3239*0b57cec5SDimitry Andric if (!ParseSectionHeaders()) 3240*0b57cec5SDimitry Andric return; 3241*0b57cec5SDimitry Andric 3242*0b57cec5SDimitry Andric s->PutCString("Section Headers\n"); 3243*0b57cec5SDimitry Andric s->PutCString("IDX name type flags " 3244*0b57cec5SDimitry Andric "addr offset size link info addralgn " 3245*0b57cec5SDimitry Andric "entsize Name\n"); 3246*0b57cec5SDimitry Andric s->PutCString("==== -------- ------------ -------------------------------- " 3247*0b57cec5SDimitry Andric "-------- -------- -------- -------- -------- -------- " 3248*0b57cec5SDimitry Andric "-------- ====================\n"); 3249*0b57cec5SDimitry Andric 3250*0b57cec5SDimitry Andric uint32_t idx = 0; 3251*0b57cec5SDimitry Andric for (SectionHeaderCollConstIter I = m_section_headers.begin(); 3252*0b57cec5SDimitry Andric I != m_section_headers.end(); ++I, ++idx) { 3253*0b57cec5SDimitry Andric s->Printf("[%2u] ", idx); 3254*0b57cec5SDimitry Andric ObjectFileELF::DumpELFSectionHeader(s, *I); 3255*0b57cec5SDimitry Andric const char *section_name = I->section_name.AsCString(""); 3256*0b57cec5SDimitry Andric if (section_name) 3257*0b57cec5SDimitry Andric *s << ' ' << section_name << "\n"; 3258*0b57cec5SDimitry Andric } 3259*0b57cec5SDimitry Andric } 3260*0b57cec5SDimitry Andric 3261*0b57cec5SDimitry Andric void ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) { 3262*0b57cec5SDimitry Andric size_t num_modules = ParseDependentModules(); 3263*0b57cec5SDimitry Andric 3264*0b57cec5SDimitry Andric if (num_modules > 0) { 3265*0b57cec5SDimitry Andric s->PutCString("Dependent Modules:\n"); 3266*0b57cec5SDimitry Andric for (unsigned i = 0; i < num_modules; ++i) { 3267*0b57cec5SDimitry Andric const FileSpec &spec = m_filespec_up->GetFileSpecAtIndex(i); 3268*0b57cec5SDimitry Andric s->Printf(" %s\n", spec.GetFilename().GetCString()); 3269*0b57cec5SDimitry Andric } 3270*0b57cec5SDimitry Andric } 3271*0b57cec5SDimitry Andric } 3272*0b57cec5SDimitry Andric 3273*0b57cec5SDimitry Andric ArchSpec ObjectFileELF::GetArchitecture() { 3274*0b57cec5SDimitry Andric if (!ParseHeader()) 3275*0b57cec5SDimitry Andric return ArchSpec(); 3276*0b57cec5SDimitry Andric 3277*0b57cec5SDimitry Andric if (m_section_headers.empty()) { 3278*0b57cec5SDimitry Andric // Allow elf notes to be parsed which may affect the detected architecture. 3279*0b57cec5SDimitry Andric ParseSectionHeaders(); 3280*0b57cec5SDimitry Andric } 3281*0b57cec5SDimitry Andric 3282*0b57cec5SDimitry Andric if (CalculateType() == eTypeCoreFile && 3283*0b57cec5SDimitry Andric !m_arch_spec.TripleOSWasSpecified()) { 3284*0b57cec5SDimitry Andric // Core files don't have section headers yet they have PT_NOTE program 3285*0b57cec5SDimitry Andric // headers that might shed more light on the architecture 3286*0b57cec5SDimitry Andric for (const elf::ELFProgramHeader &H : ProgramHeaders()) { 3287*0b57cec5SDimitry Andric if (H.p_type != PT_NOTE || H.p_offset == 0 || H.p_filesz == 0) 3288*0b57cec5SDimitry Andric continue; 3289*0b57cec5SDimitry Andric DataExtractor data; 3290*0b57cec5SDimitry Andric if (data.SetData(m_data, H.p_offset, H.p_filesz) == H.p_filesz) { 3291*0b57cec5SDimitry Andric UUID uuid; 3292*0b57cec5SDimitry Andric RefineModuleDetailsFromNote(data, m_arch_spec, uuid); 3293*0b57cec5SDimitry Andric } 3294*0b57cec5SDimitry Andric } 3295*0b57cec5SDimitry Andric } 3296*0b57cec5SDimitry Andric return m_arch_spec; 3297*0b57cec5SDimitry Andric } 3298*0b57cec5SDimitry Andric 3299*0b57cec5SDimitry Andric ObjectFile::Type ObjectFileELF::CalculateType() { 3300*0b57cec5SDimitry Andric switch (m_header.e_type) { 3301*0b57cec5SDimitry Andric case llvm::ELF::ET_NONE: 3302*0b57cec5SDimitry Andric // 0 - No file type 3303*0b57cec5SDimitry Andric return eTypeUnknown; 3304*0b57cec5SDimitry Andric 3305*0b57cec5SDimitry Andric case llvm::ELF::ET_REL: 3306*0b57cec5SDimitry Andric // 1 - Relocatable file 3307*0b57cec5SDimitry Andric return eTypeObjectFile; 3308*0b57cec5SDimitry Andric 3309*0b57cec5SDimitry Andric case llvm::ELF::ET_EXEC: 3310*0b57cec5SDimitry Andric // 2 - Executable file 3311*0b57cec5SDimitry Andric return eTypeExecutable; 3312*0b57cec5SDimitry Andric 3313*0b57cec5SDimitry Andric case llvm::ELF::ET_DYN: 3314*0b57cec5SDimitry Andric // 3 - Shared object file 3315*0b57cec5SDimitry Andric return eTypeSharedLibrary; 3316*0b57cec5SDimitry Andric 3317*0b57cec5SDimitry Andric case ET_CORE: 3318*0b57cec5SDimitry Andric // 4 - Core file 3319*0b57cec5SDimitry Andric return eTypeCoreFile; 3320*0b57cec5SDimitry Andric 3321*0b57cec5SDimitry Andric default: 3322*0b57cec5SDimitry Andric break; 3323*0b57cec5SDimitry Andric } 3324*0b57cec5SDimitry Andric return eTypeUnknown; 3325*0b57cec5SDimitry Andric } 3326*0b57cec5SDimitry Andric 3327*0b57cec5SDimitry Andric ObjectFile::Strata ObjectFileELF::CalculateStrata() { 3328*0b57cec5SDimitry Andric switch (m_header.e_type) { 3329*0b57cec5SDimitry Andric case llvm::ELF::ET_NONE: 3330*0b57cec5SDimitry Andric // 0 - No file type 3331*0b57cec5SDimitry Andric return eStrataUnknown; 3332*0b57cec5SDimitry Andric 3333*0b57cec5SDimitry Andric case llvm::ELF::ET_REL: 3334*0b57cec5SDimitry Andric // 1 - Relocatable file 3335*0b57cec5SDimitry Andric return eStrataUnknown; 3336*0b57cec5SDimitry Andric 3337*0b57cec5SDimitry Andric case llvm::ELF::ET_EXEC: 3338*0b57cec5SDimitry Andric // 2 - Executable file 3339*0b57cec5SDimitry Andric // TODO: is there any way to detect that an executable is a kernel 3340*0b57cec5SDimitry Andric // related executable by inspecting the program headers, section headers, 3341*0b57cec5SDimitry Andric // symbols, or any other flag bits??? 3342*0b57cec5SDimitry Andric return eStrataUser; 3343*0b57cec5SDimitry Andric 3344*0b57cec5SDimitry Andric case llvm::ELF::ET_DYN: 3345*0b57cec5SDimitry Andric // 3 - Shared object file 3346*0b57cec5SDimitry Andric // TODO: is there any way to detect that an shared library is a kernel 3347*0b57cec5SDimitry Andric // related executable by inspecting the program headers, section headers, 3348*0b57cec5SDimitry Andric // symbols, or any other flag bits??? 3349*0b57cec5SDimitry Andric return eStrataUnknown; 3350*0b57cec5SDimitry Andric 3351*0b57cec5SDimitry Andric case ET_CORE: 3352*0b57cec5SDimitry Andric // 4 - Core file 3353*0b57cec5SDimitry Andric // TODO: is there any way to detect that an core file is a kernel 3354*0b57cec5SDimitry Andric // related executable by inspecting the program headers, section headers, 3355*0b57cec5SDimitry Andric // symbols, or any other flag bits??? 3356*0b57cec5SDimitry Andric return eStrataUnknown; 3357*0b57cec5SDimitry Andric 3358*0b57cec5SDimitry Andric default: 3359*0b57cec5SDimitry Andric break; 3360*0b57cec5SDimitry Andric } 3361*0b57cec5SDimitry Andric return eStrataUnknown; 3362*0b57cec5SDimitry Andric } 3363*0b57cec5SDimitry Andric 3364*0b57cec5SDimitry Andric size_t ObjectFileELF::ReadSectionData(Section *section, 3365*0b57cec5SDimitry Andric lldb::offset_t section_offset, void *dst, 3366*0b57cec5SDimitry Andric size_t dst_len) { 3367*0b57cec5SDimitry Andric // If some other objectfile owns this data, pass this to them. 3368*0b57cec5SDimitry Andric if (section->GetObjectFile() != this) 3369*0b57cec5SDimitry Andric return section->GetObjectFile()->ReadSectionData(section, section_offset, 3370*0b57cec5SDimitry Andric dst, dst_len); 3371*0b57cec5SDimitry Andric 3372*0b57cec5SDimitry Andric if (!section->Test(SHF_COMPRESSED)) 3373*0b57cec5SDimitry Andric return ObjectFile::ReadSectionData(section, section_offset, dst, dst_len); 3374*0b57cec5SDimitry Andric 3375*0b57cec5SDimitry Andric // For compressed sections we need to read to full data to be able to 3376*0b57cec5SDimitry Andric // decompress. 3377*0b57cec5SDimitry Andric DataExtractor data; 3378*0b57cec5SDimitry Andric ReadSectionData(section, data); 3379*0b57cec5SDimitry Andric return data.CopyData(section_offset, dst_len, dst); 3380*0b57cec5SDimitry Andric } 3381*0b57cec5SDimitry Andric 3382*0b57cec5SDimitry Andric size_t ObjectFileELF::ReadSectionData(Section *section, 3383*0b57cec5SDimitry Andric DataExtractor §ion_data) { 3384*0b57cec5SDimitry Andric // If some other objectfile owns this data, pass this to them. 3385*0b57cec5SDimitry Andric if (section->GetObjectFile() != this) 3386*0b57cec5SDimitry Andric return section->GetObjectFile()->ReadSectionData(section, section_data); 3387*0b57cec5SDimitry Andric 3388*0b57cec5SDimitry Andric size_t result = ObjectFile::ReadSectionData(section, section_data); 3389fcaf7f86SDimitry Andric if (result == 0 || !(section->Get() & llvm::ELF::SHF_COMPRESSED)) 3390*0b57cec5SDimitry Andric return result; 3391*0b57cec5SDimitry Andric 3392*0b57cec5SDimitry Andric auto Decompressor = llvm::object::Decompressor::create( 3393*0b57cec5SDimitry Andric section->GetName().GetStringRef(), 3394*0b57cec5SDimitry Andric {reinterpret_cast<const char *>(section_data.GetDataStart()), 3395*0b57cec5SDimitry Andric size_t(section_data.GetByteSize())}, 3396*0b57cec5SDimitry Andric GetByteOrder() == eByteOrderLittle, GetAddressByteSize() == 8); 3397*0b57cec5SDimitry Andric if (!Decompressor) { 3398*0b57cec5SDimitry Andric GetModule()->ReportWarning( 3399bdd1243dSDimitry Andric "Unable to initialize decompressor for section '{0}': {1}", 3400*0b57cec5SDimitry Andric section->GetName().GetCString(), 3401*0b57cec5SDimitry Andric llvm::toString(Decompressor.takeError()).c_str()); 3402*0b57cec5SDimitry Andric section_data.Clear(); 3403*0b57cec5SDimitry Andric return 0; 3404*0b57cec5SDimitry Andric } 3405*0b57cec5SDimitry Andric 3406*0b57cec5SDimitry Andric auto buffer_sp = 3407*0b57cec5SDimitry Andric std::make_shared<DataBufferHeap>(Decompressor->getDecompressedSize(), 0); 3408*0b57cec5SDimitry Andric if (auto error = Decompressor->decompress( 3409753f127fSDimitry Andric {buffer_sp->GetBytes(), size_t(buffer_sp->GetByteSize())})) { 3410bdd1243dSDimitry Andric GetModule()->ReportWarning("Decompression of section '{0}' failed: {1}", 3411*0b57cec5SDimitry Andric section->GetName().GetCString(), 3412*0b57cec5SDimitry Andric llvm::toString(std::move(error)).c_str()); 3413*0b57cec5SDimitry Andric section_data.Clear(); 3414*0b57cec5SDimitry Andric return 0; 3415*0b57cec5SDimitry Andric } 3416*0b57cec5SDimitry Andric 3417*0b57cec5SDimitry Andric section_data.SetData(buffer_sp); 3418*0b57cec5SDimitry Andric return buffer_sp->GetByteSize(); 3419*0b57cec5SDimitry Andric } 3420*0b57cec5SDimitry Andric 3421*0b57cec5SDimitry Andric llvm::ArrayRef<ELFProgramHeader> ObjectFileELF::ProgramHeaders() { 3422*0b57cec5SDimitry Andric ParseProgramHeaders(); 3423*0b57cec5SDimitry Andric return m_program_headers; 3424*0b57cec5SDimitry Andric } 3425*0b57cec5SDimitry Andric 3426*0b57cec5SDimitry Andric DataExtractor ObjectFileELF::GetSegmentData(const ELFProgramHeader &H) { 3427*0b57cec5SDimitry Andric return DataExtractor(m_data, H.p_offset, H.p_filesz); 3428*0b57cec5SDimitry Andric } 3429*0b57cec5SDimitry Andric 3430*0b57cec5SDimitry Andric bool ObjectFileELF::AnySegmentHasPhysicalAddress() { 3431*0b57cec5SDimitry Andric for (const ELFProgramHeader &H : ProgramHeaders()) { 3432*0b57cec5SDimitry Andric if (H.p_paddr != 0) 3433*0b57cec5SDimitry Andric return true; 3434*0b57cec5SDimitry Andric } 3435*0b57cec5SDimitry Andric return false; 3436*0b57cec5SDimitry Andric } 3437*0b57cec5SDimitry Andric 3438*0b57cec5SDimitry Andric std::vector<ObjectFile::LoadableData> 3439*0b57cec5SDimitry Andric ObjectFileELF::GetLoadableData(Target &target) { 3440*0b57cec5SDimitry Andric // Create a list of loadable data from loadable segments, using physical 3441*0b57cec5SDimitry Andric // addresses if they aren't all null 3442*0b57cec5SDimitry Andric std::vector<LoadableData> loadables; 3443*0b57cec5SDimitry Andric bool should_use_paddr = AnySegmentHasPhysicalAddress(); 3444*0b57cec5SDimitry Andric for (const ELFProgramHeader &H : ProgramHeaders()) { 3445*0b57cec5SDimitry Andric LoadableData loadable; 3446*0b57cec5SDimitry Andric if (H.p_type != llvm::ELF::PT_LOAD) 3447*0b57cec5SDimitry Andric continue; 3448*0b57cec5SDimitry Andric loadable.Dest = should_use_paddr ? H.p_paddr : H.p_vaddr; 3449*0b57cec5SDimitry Andric if (loadable.Dest == LLDB_INVALID_ADDRESS) 3450*0b57cec5SDimitry Andric continue; 3451*0b57cec5SDimitry Andric if (H.p_filesz == 0) 3452*0b57cec5SDimitry Andric continue; 3453*0b57cec5SDimitry Andric auto segment_data = GetSegmentData(H); 3454*0b57cec5SDimitry Andric loadable.Contents = llvm::ArrayRef<uint8_t>(segment_data.GetDataStart(), 3455*0b57cec5SDimitry Andric segment_data.GetByteSize()); 3456*0b57cec5SDimitry Andric loadables.push_back(loadable); 3457*0b57cec5SDimitry Andric } 3458*0b57cec5SDimitry Andric return loadables; 3459*0b57cec5SDimitry Andric } 346081ad6265SDimitry Andric 346181ad6265SDimitry Andric lldb::WritableDataBufferSP 346281ad6265SDimitry Andric ObjectFileELF::MapFileDataWritable(const FileSpec &file, uint64_t Size, 346381ad6265SDimitry Andric uint64_t Offset) { 346481ad6265SDimitry Andric return FileSystem::Instance().CreateWritableDataBuffer(file.GetPath(), Size, 346581ad6265SDimitry Andric Offset); 346681ad6265SDimitry Andric } 3467