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> 13*0b57cec5SDimitry Andric #include <unordered_map> 14*0b57cec5SDimitry Andric 15*0b57cec5SDimitry Andric #include "lldb/Core/FileSpecList.h" 16*0b57cec5SDimitry Andric #include "lldb/Core/Module.h" 17*0b57cec5SDimitry Andric #include "lldb/Core/ModuleSpec.h" 18*0b57cec5SDimitry Andric #include "lldb/Core/PluginManager.h" 19fe6060f1SDimitry Andric #include "lldb/Core/Progress.h" 20*0b57cec5SDimitry Andric #include "lldb/Core/Section.h" 21*0b57cec5SDimitry Andric #include "lldb/Host/FileSystem.h" 229dba64beSDimitry Andric #include "lldb/Host/LZMA.h" 23*0b57cec5SDimitry Andric #include "lldb/Symbol/DWARFCallFrameInfo.h" 24*0b57cec5SDimitry Andric #include "lldb/Symbol/SymbolContext.h" 25*0b57cec5SDimitry Andric #include "lldb/Target/SectionLoadList.h" 26*0b57cec5SDimitry Andric #include "lldb/Target/Target.h" 27*0b57cec5SDimitry Andric #include "lldb/Utility/ArchSpec.h" 28*0b57cec5SDimitry Andric #include "lldb/Utility/DataBufferHeap.h" 2981ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h" 30*0b57cec5SDimitry Andric #include "lldb/Utility/Log.h" 31*0b57cec5SDimitry Andric #include "lldb/Utility/RangeMap.h" 32*0b57cec5SDimitry Andric #include "lldb/Utility/Status.h" 33*0b57cec5SDimitry Andric #include "lldb/Utility/Stream.h" 34*0b57cec5SDimitry Andric #include "lldb/Utility/Timer.h" 35*0b57cec5SDimitry Andric #include "llvm/ADT/IntervalMap.h" 36*0b57cec5SDimitry Andric #include "llvm/ADT/PointerUnion.h" 37*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 389dba64beSDimitry Andric #include "llvm/BinaryFormat/ELF.h" 39*0b57cec5SDimitry Andric #include "llvm/Object/Decompressor.h" 40*0b57cec5SDimitry Andric #include "llvm/Support/ARMBuildAttributes.h" 419dba64beSDimitry Andric #include "llvm/Support/CRC.h" 42fe6060f1SDimitry Andric #include "llvm/Support/FormatVariadic.h" 43*0b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 44*0b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 45*0b57cec5SDimitry Andric #include "llvm/Support/MipsABIFlags.h" 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andric #define CASE_AND_STREAM(s, def, width) \ 48*0b57cec5SDimitry Andric case def: \ 49*0b57cec5SDimitry Andric s->Printf("%-*s", width, #def); \ 50*0b57cec5SDimitry Andric break; 51*0b57cec5SDimitry Andric 52*0b57cec5SDimitry Andric using namespace lldb; 53*0b57cec5SDimitry Andric using namespace lldb_private; 54*0b57cec5SDimitry Andric using namespace elf; 55*0b57cec5SDimitry Andric using namespace llvm::ELF; 56*0b57cec5SDimitry Andric 575ffd83dbSDimitry Andric LLDB_PLUGIN_DEFINE(ObjectFileELF) 585ffd83dbSDimitry Andric 59*0b57cec5SDimitry Andric // ELF note owner definitions 60349cc55cSDimitry Andric static const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD"; 61349cc55cSDimitry Andric static const char *const LLDB_NT_OWNER_GNU = "GNU"; 62349cc55cSDimitry Andric static const char *const LLDB_NT_OWNER_NETBSD = "NetBSD"; 63349cc55cSDimitry Andric static const char *const LLDB_NT_OWNER_NETBSDCORE = "NetBSD-CORE"; 64349cc55cSDimitry Andric static const char *const LLDB_NT_OWNER_OPENBSD = "OpenBSD"; 65349cc55cSDimitry Andric static const char *const LLDB_NT_OWNER_ANDROID = "Android"; 66349cc55cSDimitry Andric static const char *const LLDB_NT_OWNER_CORE = "CORE"; 67349cc55cSDimitry Andric static const char *const LLDB_NT_OWNER_LINUX = "LINUX"; 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric // ELF note type definitions 70349cc55cSDimitry Andric static const elf_word LLDB_NT_FREEBSD_ABI_TAG = 0x01; 71349cc55cSDimitry Andric static const elf_word LLDB_NT_FREEBSD_ABI_SIZE = 4; 72*0b57cec5SDimitry Andric 73349cc55cSDimitry Andric static const elf_word LLDB_NT_GNU_ABI_TAG = 0x01; 74349cc55cSDimitry Andric static const elf_word LLDB_NT_GNU_ABI_SIZE = 16; 75*0b57cec5SDimitry Andric 76349cc55cSDimitry Andric static const elf_word LLDB_NT_GNU_BUILD_ID_TAG = 0x03; 77*0b57cec5SDimitry Andric 78349cc55cSDimitry Andric static const elf_word LLDB_NT_NETBSD_IDENT_TAG = 1; 79349cc55cSDimitry Andric static const elf_word LLDB_NT_NETBSD_IDENT_DESCSZ = 4; 80349cc55cSDimitry Andric static const elf_word LLDB_NT_NETBSD_IDENT_NAMESZ = 7; 81349cc55cSDimitry Andric static const elf_word LLDB_NT_NETBSD_PROCINFO = 1; 82*0b57cec5SDimitry Andric 83*0b57cec5SDimitry Andric // GNU ABI note OS constants 84349cc55cSDimitry Andric static const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00; 85349cc55cSDimitry Andric static const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01; 86349cc55cSDimitry Andric static const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02; 87349cc55cSDimitry Andric 88349cc55cSDimitry Andric namespace { 89*0b57cec5SDimitry Andric 90*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 91*0b57cec5SDimitry Andric /// \class ELFRelocation 92*0b57cec5SDimitry Andric /// Generic wrapper for ELFRel and ELFRela. 93*0b57cec5SDimitry Andric /// 94*0b57cec5SDimitry Andric /// This helper class allows us to parse both ELFRel and ELFRela relocation 95*0b57cec5SDimitry Andric /// entries in a generic manner. 96*0b57cec5SDimitry Andric class ELFRelocation { 97*0b57cec5SDimitry Andric public: 98*0b57cec5SDimitry Andric /// Constructs an ELFRelocation entry with a personality as given by @p 99*0b57cec5SDimitry Andric /// type. 100*0b57cec5SDimitry Andric /// 101*0b57cec5SDimitry Andric /// \param type Either DT_REL or DT_RELA. Any other value is invalid. 102*0b57cec5SDimitry Andric ELFRelocation(unsigned type); 103*0b57cec5SDimitry Andric 104*0b57cec5SDimitry Andric ~ELFRelocation(); 105*0b57cec5SDimitry Andric 106*0b57cec5SDimitry Andric bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); 107*0b57cec5SDimitry Andric 108*0b57cec5SDimitry Andric static unsigned RelocType32(const ELFRelocation &rel); 109*0b57cec5SDimitry Andric 110*0b57cec5SDimitry Andric static unsigned RelocType64(const ELFRelocation &rel); 111*0b57cec5SDimitry Andric 112*0b57cec5SDimitry Andric static unsigned RelocSymbol32(const ELFRelocation &rel); 113*0b57cec5SDimitry Andric 114*0b57cec5SDimitry Andric static unsigned RelocSymbol64(const ELFRelocation &rel); 115*0b57cec5SDimitry Andric 116*0b57cec5SDimitry Andric static unsigned RelocOffset32(const ELFRelocation &rel); 117*0b57cec5SDimitry Andric 118*0b57cec5SDimitry Andric static unsigned RelocOffset64(const ELFRelocation &rel); 119*0b57cec5SDimitry Andric 120*0b57cec5SDimitry Andric static unsigned RelocAddend32(const ELFRelocation &rel); 121*0b57cec5SDimitry Andric 122*0b57cec5SDimitry Andric static unsigned RelocAddend64(const ELFRelocation &rel); 123*0b57cec5SDimitry Andric 124*0b57cec5SDimitry Andric private: 125*0b57cec5SDimitry Andric typedef llvm::PointerUnion<ELFRel *, ELFRela *> RelocUnion; 126*0b57cec5SDimitry Andric 127*0b57cec5SDimitry Andric RelocUnion reloc; 128*0b57cec5SDimitry Andric }; 129349cc55cSDimitry Andric } // end anonymous namespace 130*0b57cec5SDimitry Andric 131*0b57cec5SDimitry Andric ELFRelocation::ELFRelocation(unsigned type) { 132*0b57cec5SDimitry Andric if (type == DT_REL || type == SHT_REL) 133*0b57cec5SDimitry Andric reloc = new ELFRel(); 134*0b57cec5SDimitry Andric else if (type == DT_RELA || type == SHT_RELA) 135*0b57cec5SDimitry Andric reloc = new ELFRela(); 136*0b57cec5SDimitry Andric else { 137*0b57cec5SDimitry Andric assert(false && "unexpected relocation type"); 138*0b57cec5SDimitry Andric reloc = static_cast<ELFRel *>(nullptr); 139*0b57cec5SDimitry Andric } 140*0b57cec5SDimitry Andric } 141*0b57cec5SDimitry Andric 142*0b57cec5SDimitry Andric ELFRelocation::~ELFRelocation() { 143*0b57cec5SDimitry Andric if (reloc.is<ELFRel *>()) 144*0b57cec5SDimitry Andric delete reloc.get<ELFRel *>(); 145*0b57cec5SDimitry Andric else 146*0b57cec5SDimitry Andric delete reloc.get<ELFRela *>(); 147*0b57cec5SDimitry Andric } 148*0b57cec5SDimitry Andric 149*0b57cec5SDimitry Andric bool ELFRelocation::Parse(const lldb_private::DataExtractor &data, 150*0b57cec5SDimitry Andric lldb::offset_t *offset) { 151*0b57cec5SDimitry Andric if (reloc.is<ELFRel *>()) 152*0b57cec5SDimitry Andric return reloc.get<ELFRel *>()->Parse(data, offset); 153*0b57cec5SDimitry Andric else 154*0b57cec5SDimitry Andric return reloc.get<ELFRela *>()->Parse(data, offset); 155*0b57cec5SDimitry Andric } 156*0b57cec5SDimitry Andric 157*0b57cec5SDimitry Andric unsigned ELFRelocation::RelocType32(const ELFRelocation &rel) { 158*0b57cec5SDimitry Andric if (rel.reloc.is<ELFRel *>()) 159*0b57cec5SDimitry Andric return ELFRel::RelocType32(*rel.reloc.get<ELFRel *>()); 160*0b57cec5SDimitry Andric else 161*0b57cec5SDimitry Andric return ELFRela::RelocType32(*rel.reloc.get<ELFRela *>()); 162*0b57cec5SDimitry Andric } 163*0b57cec5SDimitry Andric 164*0b57cec5SDimitry Andric unsigned ELFRelocation::RelocType64(const ELFRelocation &rel) { 165*0b57cec5SDimitry Andric if (rel.reloc.is<ELFRel *>()) 166*0b57cec5SDimitry Andric return ELFRel::RelocType64(*rel.reloc.get<ELFRel *>()); 167*0b57cec5SDimitry Andric else 168*0b57cec5SDimitry Andric return ELFRela::RelocType64(*rel.reloc.get<ELFRela *>()); 169*0b57cec5SDimitry Andric } 170*0b57cec5SDimitry Andric 171*0b57cec5SDimitry Andric unsigned ELFRelocation::RelocSymbol32(const ELFRelocation &rel) { 172*0b57cec5SDimitry Andric if (rel.reloc.is<ELFRel *>()) 173*0b57cec5SDimitry Andric return ELFRel::RelocSymbol32(*rel.reloc.get<ELFRel *>()); 174*0b57cec5SDimitry Andric else 175*0b57cec5SDimitry Andric return ELFRela::RelocSymbol32(*rel.reloc.get<ELFRela *>()); 176*0b57cec5SDimitry Andric } 177*0b57cec5SDimitry Andric 178*0b57cec5SDimitry Andric unsigned ELFRelocation::RelocSymbol64(const ELFRelocation &rel) { 179*0b57cec5SDimitry Andric if (rel.reloc.is<ELFRel *>()) 180*0b57cec5SDimitry Andric return ELFRel::RelocSymbol64(*rel.reloc.get<ELFRel *>()); 181*0b57cec5SDimitry Andric else 182*0b57cec5SDimitry Andric return ELFRela::RelocSymbol64(*rel.reloc.get<ELFRela *>()); 183*0b57cec5SDimitry Andric } 184*0b57cec5SDimitry Andric 185*0b57cec5SDimitry Andric unsigned ELFRelocation::RelocOffset32(const ELFRelocation &rel) { 186*0b57cec5SDimitry Andric if (rel.reloc.is<ELFRel *>()) 187*0b57cec5SDimitry Andric return rel.reloc.get<ELFRel *>()->r_offset; 188*0b57cec5SDimitry Andric else 189*0b57cec5SDimitry Andric return rel.reloc.get<ELFRela *>()->r_offset; 190*0b57cec5SDimitry Andric } 191*0b57cec5SDimitry Andric 192*0b57cec5SDimitry Andric unsigned ELFRelocation::RelocOffset64(const ELFRelocation &rel) { 193*0b57cec5SDimitry Andric if (rel.reloc.is<ELFRel *>()) 194*0b57cec5SDimitry Andric return rel.reloc.get<ELFRel *>()->r_offset; 195*0b57cec5SDimitry Andric else 196*0b57cec5SDimitry Andric return rel.reloc.get<ELFRela *>()->r_offset; 197*0b57cec5SDimitry Andric } 198*0b57cec5SDimitry Andric 199*0b57cec5SDimitry Andric unsigned ELFRelocation::RelocAddend32(const ELFRelocation &rel) { 200*0b57cec5SDimitry Andric if (rel.reloc.is<ELFRel *>()) 201*0b57cec5SDimitry Andric return 0; 202*0b57cec5SDimitry Andric else 203*0b57cec5SDimitry Andric return rel.reloc.get<ELFRela *>()->r_addend; 204*0b57cec5SDimitry Andric } 205*0b57cec5SDimitry Andric 206*0b57cec5SDimitry Andric unsigned ELFRelocation::RelocAddend64(const ELFRelocation &rel) { 207*0b57cec5SDimitry Andric if (rel.reloc.is<ELFRel *>()) 208*0b57cec5SDimitry Andric return 0; 209*0b57cec5SDimitry Andric else 210*0b57cec5SDimitry Andric return rel.reloc.get<ELFRela *>()->r_addend; 211*0b57cec5SDimitry Andric } 212*0b57cec5SDimitry Andric 2135ffd83dbSDimitry Andric static user_id_t SegmentID(size_t PHdrIndex) { 2145ffd83dbSDimitry Andric return ~user_id_t(PHdrIndex); 2155ffd83dbSDimitry Andric } 216*0b57cec5SDimitry Andric 217*0b57cec5SDimitry Andric bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) { 218*0b57cec5SDimitry Andric // Read all fields. 219*0b57cec5SDimitry Andric if (data.GetU32(offset, &n_namesz, 3) == nullptr) 220*0b57cec5SDimitry Andric return false; 221*0b57cec5SDimitry Andric 222*0b57cec5SDimitry Andric // The name field is required to be nul-terminated, and n_namesz includes the 223*0b57cec5SDimitry Andric // terminating nul in observed implementations (contrary to the ELF-64 spec). 224*0b57cec5SDimitry Andric // A special case is needed for cores generated by some older Linux versions, 225*0b57cec5SDimitry Andric // which write a note named "CORE" without a nul terminator and n_namesz = 4. 226*0b57cec5SDimitry Andric if (n_namesz == 4) { 227*0b57cec5SDimitry Andric char buf[4]; 228*0b57cec5SDimitry Andric if (data.ExtractBytes(*offset, 4, data.GetByteOrder(), buf) != 4) 229*0b57cec5SDimitry Andric return false; 230*0b57cec5SDimitry Andric if (strncmp(buf, "CORE", 4) == 0) { 231*0b57cec5SDimitry Andric n_name = "CORE"; 232*0b57cec5SDimitry Andric *offset += 4; 233*0b57cec5SDimitry Andric return true; 234*0b57cec5SDimitry Andric } 235*0b57cec5SDimitry Andric } 236*0b57cec5SDimitry Andric 237*0b57cec5SDimitry Andric const char *cstr = data.GetCStr(offset, llvm::alignTo(n_namesz, 4)); 238*0b57cec5SDimitry Andric if (cstr == nullptr) { 23981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Symbols); 2409dba64beSDimitry Andric LLDB_LOGF(log, "Failed to parse note name lacking nul terminator"); 241*0b57cec5SDimitry Andric 242*0b57cec5SDimitry Andric return false; 243*0b57cec5SDimitry Andric } 244*0b57cec5SDimitry Andric n_name = cstr; 245*0b57cec5SDimitry Andric return true; 246*0b57cec5SDimitry Andric } 247*0b57cec5SDimitry Andric 248*0b57cec5SDimitry Andric static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) { 249*0b57cec5SDimitry Andric const uint32_t mips_arch = header.e_flags & llvm::ELF::EF_MIPS_ARCH; 250*0b57cec5SDimitry Andric uint32_t endian = header.e_ident[EI_DATA]; 251*0b57cec5SDimitry Andric uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown; 252*0b57cec5SDimitry Andric uint32_t fileclass = header.e_ident[EI_CLASS]; 253*0b57cec5SDimitry Andric 254*0b57cec5SDimitry Andric // If there aren't any elf flags available (e.g core elf file) then return 255*0b57cec5SDimitry Andric // default 256*0b57cec5SDimitry Andric // 32 or 64 bit arch (without any architecture revision) based on object file's class. 257*0b57cec5SDimitry Andric if (header.e_type == ET_CORE) { 258*0b57cec5SDimitry Andric switch (fileclass) { 259*0b57cec5SDimitry Andric case llvm::ELF::ELFCLASS32: 260*0b57cec5SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el 261*0b57cec5SDimitry Andric : ArchSpec::eMIPSSubType_mips32; 262*0b57cec5SDimitry Andric case llvm::ELF::ELFCLASS64: 263*0b57cec5SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el 264*0b57cec5SDimitry Andric : ArchSpec::eMIPSSubType_mips64; 265*0b57cec5SDimitry Andric default: 266*0b57cec5SDimitry Andric return arch_variant; 267*0b57cec5SDimitry Andric } 268*0b57cec5SDimitry Andric } 269*0b57cec5SDimitry Andric 270*0b57cec5SDimitry Andric switch (mips_arch) { 271*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_1: 272*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_2: 273*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_32: 274*0b57cec5SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el 275*0b57cec5SDimitry Andric : ArchSpec::eMIPSSubType_mips32; 276*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_32R2: 277*0b57cec5SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r2el 278*0b57cec5SDimitry Andric : ArchSpec::eMIPSSubType_mips32r2; 279*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_32R6: 280*0b57cec5SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r6el 281*0b57cec5SDimitry Andric : ArchSpec::eMIPSSubType_mips32r6; 282*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_3: 283*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_4: 284*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_5: 285*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_64: 286*0b57cec5SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el 287*0b57cec5SDimitry Andric : ArchSpec::eMIPSSubType_mips64; 288*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_64R2: 289*0b57cec5SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r2el 290*0b57cec5SDimitry Andric : ArchSpec::eMIPSSubType_mips64r2; 291*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_64R6: 292*0b57cec5SDimitry Andric return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r6el 293*0b57cec5SDimitry Andric : ArchSpec::eMIPSSubType_mips64r6; 294*0b57cec5SDimitry Andric default: 295*0b57cec5SDimitry Andric break; 296*0b57cec5SDimitry Andric } 297*0b57cec5SDimitry Andric 298*0b57cec5SDimitry Andric return arch_variant; 299*0b57cec5SDimitry Andric } 300*0b57cec5SDimitry Andric 301e8d8bef9SDimitry Andric static uint32_t riscvVariantFromElfFlags(const elf::ELFHeader &header) { 302e8d8bef9SDimitry Andric uint32_t fileclass = header.e_ident[EI_CLASS]; 303e8d8bef9SDimitry Andric switch (fileclass) { 304e8d8bef9SDimitry Andric case llvm::ELF::ELFCLASS32: 305e8d8bef9SDimitry Andric return ArchSpec::eRISCVSubType_riscv32; 306e8d8bef9SDimitry Andric case llvm::ELF::ELFCLASS64: 307e8d8bef9SDimitry Andric return ArchSpec::eRISCVSubType_riscv64; 308e8d8bef9SDimitry Andric default: 309e8d8bef9SDimitry Andric return ArchSpec::eRISCVSubType_unknown; 310e8d8bef9SDimitry Andric } 311e8d8bef9SDimitry Andric } 312e8d8bef9SDimitry Andric 31381ad6265SDimitry Andric static uint32_t ppc64VariantFromElfFlags(const elf::ELFHeader &header) { 31481ad6265SDimitry Andric uint32_t endian = header.e_ident[EI_DATA]; 31581ad6265SDimitry Andric if (endian == ELFDATA2LSB) 31681ad6265SDimitry Andric return ArchSpec::eCore_ppc64le_generic; 31781ad6265SDimitry Andric else 31881ad6265SDimitry Andric return ArchSpec::eCore_ppc64_generic; 31981ad6265SDimitry Andric } 32081ad6265SDimitry Andric 321*0b57cec5SDimitry Andric static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) { 322*0b57cec5SDimitry Andric if (header.e_machine == llvm::ELF::EM_MIPS) 323*0b57cec5SDimitry Andric return mipsVariantFromElfFlags(header); 32481ad6265SDimitry Andric else if (header.e_machine == llvm::ELF::EM_PPC64) 32581ad6265SDimitry Andric return ppc64VariantFromElfFlags(header); 326e8d8bef9SDimitry Andric else if (header.e_machine == llvm::ELF::EM_RISCV) 327e8d8bef9SDimitry Andric return riscvVariantFromElfFlags(header); 328*0b57cec5SDimitry Andric 329*0b57cec5SDimitry Andric return LLDB_INVALID_CPUTYPE; 330*0b57cec5SDimitry Andric } 331*0b57cec5SDimitry Andric 3329dba64beSDimitry Andric char ObjectFileELF::ID; 3339dba64beSDimitry Andric 334*0b57cec5SDimitry Andric // Arbitrary constant used as UUID prefix for core files. 335*0b57cec5SDimitry Andric const uint32_t ObjectFileELF::g_core_uuid_magic(0xE210C); 336*0b57cec5SDimitry Andric 337*0b57cec5SDimitry Andric // Static methods. 338*0b57cec5SDimitry Andric void ObjectFileELF::Initialize() { 339*0b57cec5SDimitry Andric PluginManager::RegisterPlugin(GetPluginNameStatic(), 340*0b57cec5SDimitry Andric GetPluginDescriptionStatic(), CreateInstance, 341*0b57cec5SDimitry Andric CreateMemoryInstance, GetModuleSpecifications); 342*0b57cec5SDimitry Andric } 343*0b57cec5SDimitry Andric 344*0b57cec5SDimitry Andric void ObjectFileELF::Terminate() { 345*0b57cec5SDimitry Andric PluginManager::UnregisterPlugin(CreateInstance); 346*0b57cec5SDimitry Andric } 347*0b57cec5SDimitry Andric 348*0b57cec5SDimitry Andric ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp, 34981ad6265SDimitry Andric DataBufferSP data_sp, 350*0b57cec5SDimitry Andric lldb::offset_t data_offset, 351*0b57cec5SDimitry Andric const lldb_private::FileSpec *file, 352*0b57cec5SDimitry Andric lldb::offset_t file_offset, 353*0b57cec5SDimitry Andric lldb::offset_t length) { 35481ad6265SDimitry Andric bool mapped_writable = false; 355*0b57cec5SDimitry Andric if (!data_sp) { 35681ad6265SDimitry Andric data_sp = MapFileDataWritable(*file, length, file_offset); 357*0b57cec5SDimitry Andric if (!data_sp) 358*0b57cec5SDimitry Andric return nullptr; 359*0b57cec5SDimitry Andric data_offset = 0; 36081ad6265SDimitry Andric mapped_writable = true; 361*0b57cec5SDimitry Andric } 362*0b57cec5SDimitry Andric 363*0b57cec5SDimitry Andric assert(data_sp); 364*0b57cec5SDimitry Andric 365*0b57cec5SDimitry Andric if (data_sp->GetByteSize() <= (llvm::ELF::EI_NIDENT + data_offset)) 366*0b57cec5SDimitry Andric return nullptr; 367*0b57cec5SDimitry Andric 368*0b57cec5SDimitry Andric const uint8_t *magic = data_sp->GetBytes() + data_offset; 369*0b57cec5SDimitry Andric if (!ELFHeader::MagicBytesMatch(magic)) 370*0b57cec5SDimitry Andric return nullptr; 371*0b57cec5SDimitry Andric 372*0b57cec5SDimitry Andric // Update the data to contain the entire file if it doesn't already 373*0b57cec5SDimitry Andric if (data_sp->GetByteSize() < length) { 37481ad6265SDimitry Andric data_sp = MapFileDataWritable(*file, length, file_offset); 375*0b57cec5SDimitry Andric if (!data_sp) 376*0b57cec5SDimitry Andric return nullptr; 377*0b57cec5SDimitry Andric data_offset = 0; 37881ad6265SDimitry Andric mapped_writable = true; 37981ad6265SDimitry Andric magic = data_sp->GetBytes(); 38081ad6265SDimitry Andric } 38181ad6265SDimitry Andric 38281ad6265SDimitry Andric // If we didn't map the data as writable take ownership of the buffer. 38381ad6265SDimitry Andric if (!mapped_writable) { 38481ad6265SDimitry Andric data_sp = std::make_shared<DataBufferHeap>(data_sp->GetBytes(), 38581ad6265SDimitry Andric data_sp->GetByteSize()); 38681ad6265SDimitry Andric data_offset = 0; 387*0b57cec5SDimitry Andric magic = data_sp->GetBytes(); 388*0b57cec5SDimitry Andric } 389*0b57cec5SDimitry Andric 390*0b57cec5SDimitry Andric unsigned address_size = ELFHeader::AddressSizeInBytes(magic); 391*0b57cec5SDimitry Andric if (address_size == 4 || address_size == 8) { 392*0b57cec5SDimitry Andric std::unique_ptr<ObjectFileELF> objfile_up(new ObjectFileELF( 393*0b57cec5SDimitry Andric module_sp, data_sp, data_offset, file, file_offset, length)); 394*0b57cec5SDimitry Andric ArchSpec spec = objfile_up->GetArchitecture(); 395*0b57cec5SDimitry Andric if (spec && objfile_up->SetModulesArchitecture(spec)) 396*0b57cec5SDimitry Andric return objfile_up.release(); 397*0b57cec5SDimitry Andric } 398*0b57cec5SDimitry Andric 399*0b57cec5SDimitry Andric return nullptr; 400*0b57cec5SDimitry Andric } 401*0b57cec5SDimitry Andric 402*0b57cec5SDimitry Andric ObjectFile *ObjectFileELF::CreateMemoryInstance( 40381ad6265SDimitry Andric const lldb::ModuleSP &module_sp, WritableDataBufferSP data_sp, 404*0b57cec5SDimitry Andric const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) { 405*0b57cec5SDimitry Andric if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT)) { 406*0b57cec5SDimitry Andric const uint8_t *magic = data_sp->GetBytes(); 407*0b57cec5SDimitry Andric if (ELFHeader::MagicBytesMatch(magic)) { 408*0b57cec5SDimitry Andric unsigned address_size = ELFHeader::AddressSizeInBytes(magic); 409*0b57cec5SDimitry Andric if (address_size == 4 || address_size == 8) { 410*0b57cec5SDimitry Andric std::unique_ptr<ObjectFileELF> objfile_up( 411*0b57cec5SDimitry Andric new ObjectFileELF(module_sp, data_sp, process_sp, header_addr)); 412*0b57cec5SDimitry Andric ArchSpec spec = objfile_up->GetArchitecture(); 413*0b57cec5SDimitry Andric if (spec && objfile_up->SetModulesArchitecture(spec)) 414*0b57cec5SDimitry Andric return objfile_up.release(); 415*0b57cec5SDimitry Andric } 416*0b57cec5SDimitry Andric } 417*0b57cec5SDimitry Andric } 418*0b57cec5SDimitry Andric return nullptr; 419*0b57cec5SDimitry Andric } 420*0b57cec5SDimitry Andric 421*0b57cec5SDimitry Andric bool ObjectFileELF::MagicBytesMatch(DataBufferSP &data_sp, 422*0b57cec5SDimitry Andric lldb::addr_t data_offset, 423*0b57cec5SDimitry Andric lldb::addr_t data_length) { 424*0b57cec5SDimitry Andric if (data_sp && 425*0b57cec5SDimitry Andric data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset)) { 426*0b57cec5SDimitry Andric const uint8_t *magic = data_sp->GetBytes() + data_offset; 427*0b57cec5SDimitry Andric return ELFHeader::MagicBytesMatch(magic); 428*0b57cec5SDimitry Andric } 429*0b57cec5SDimitry Andric return false; 430*0b57cec5SDimitry Andric } 431*0b57cec5SDimitry Andric 4329dba64beSDimitry Andric static uint32_t calc_crc32(uint32_t init, const DataExtractor &data) { 4339dba64beSDimitry Andric return llvm::crc32( 4349dba64beSDimitry Andric init, llvm::makeArrayRef(data.GetDataStart(), data.GetByteSize())); 435*0b57cec5SDimitry Andric } 436*0b57cec5SDimitry Andric 437*0b57cec5SDimitry Andric uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32( 438*0b57cec5SDimitry Andric const ProgramHeaderColl &program_headers, DataExtractor &object_data) { 439*0b57cec5SDimitry Andric 440*0b57cec5SDimitry Andric uint32_t core_notes_crc = 0; 441*0b57cec5SDimitry Andric 442*0b57cec5SDimitry Andric for (const ELFProgramHeader &H : program_headers) { 443*0b57cec5SDimitry Andric if (H.p_type == llvm::ELF::PT_NOTE) { 444*0b57cec5SDimitry Andric const elf_off ph_offset = H.p_offset; 445*0b57cec5SDimitry Andric const size_t ph_size = H.p_filesz; 446*0b57cec5SDimitry Andric 447*0b57cec5SDimitry Andric DataExtractor segment_data; 448*0b57cec5SDimitry Andric if (segment_data.SetData(object_data, ph_offset, ph_size) != ph_size) { 449*0b57cec5SDimitry Andric // The ELF program header contained incorrect data, probably corefile 450*0b57cec5SDimitry Andric // is incomplete or corrupted. 451*0b57cec5SDimitry Andric break; 452*0b57cec5SDimitry Andric } 453*0b57cec5SDimitry Andric 4549dba64beSDimitry Andric core_notes_crc = calc_crc32(core_notes_crc, segment_data); 455*0b57cec5SDimitry Andric } 456*0b57cec5SDimitry Andric } 457*0b57cec5SDimitry Andric 458*0b57cec5SDimitry Andric return core_notes_crc; 459*0b57cec5SDimitry Andric } 460*0b57cec5SDimitry Andric 461*0b57cec5SDimitry Andric static const char *OSABIAsCString(unsigned char osabi_byte) { 462*0b57cec5SDimitry Andric #define _MAKE_OSABI_CASE(x) \ 463*0b57cec5SDimitry Andric case x: \ 464*0b57cec5SDimitry Andric return #x 465*0b57cec5SDimitry Andric switch (osabi_byte) { 466*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_NONE); 467*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_HPUX); 468*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_NETBSD); 469*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_GNU); 470*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_HURD); 471*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_SOLARIS); 472*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_AIX); 473*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_IRIX); 474*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_FREEBSD); 475*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_TRU64); 476*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_MODESTO); 477*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_OPENBSD); 478*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_OPENVMS); 479*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_NSK); 480*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_AROS); 481*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_FENIXOS); 482*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_C6000_ELFABI); 483*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_C6000_LINUX); 484*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_ARM); 485*0b57cec5SDimitry Andric _MAKE_OSABI_CASE(ELFOSABI_STANDALONE); 486*0b57cec5SDimitry Andric default: 487*0b57cec5SDimitry Andric return "<unknown-osabi>"; 488*0b57cec5SDimitry Andric } 489*0b57cec5SDimitry Andric #undef _MAKE_OSABI_CASE 490*0b57cec5SDimitry Andric } 491*0b57cec5SDimitry Andric 492*0b57cec5SDimitry Andric // 493*0b57cec5SDimitry Andric // WARNING : This function is being deprecated 494*0b57cec5SDimitry Andric // It's functionality has moved to ArchSpec::SetArchitecture This function is 495*0b57cec5SDimitry Andric // only being kept to validate the move. 496*0b57cec5SDimitry Andric // 497*0b57cec5SDimitry Andric // TODO : Remove this function 498*0b57cec5SDimitry Andric static bool GetOsFromOSABI(unsigned char osabi_byte, 499*0b57cec5SDimitry Andric llvm::Triple::OSType &ostype) { 500*0b57cec5SDimitry Andric switch (osabi_byte) { 501*0b57cec5SDimitry Andric case ELFOSABI_AIX: 502*0b57cec5SDimitry Andric ostype = llvm::Triple::OSType::AIX; 503*0b57cec5SDimitry Andric break; 504*0b57cec5SDimitry Andric case ELFOSABI_FREEBSD: 505*0b57cec5SDimitry Andric ostype = llvm::Triple::OSType::FreeBSD; 506*0b57cec5SDimitry Andric break; 507*0b57cec5SDimitry Andric case ELFOSABI_GNU: 508*0b57cec5SDimitry Andric ostype = llvm::Triple::OSType::Linux; 509*0b57cec5SDimitry Andric break; 510*0b57cec5SDimitry Andric case ELFOSABI_NETBSD: 511*0b57cec5SDimitry Andric ostype = llvm::Triple::OSType::NetBSD; 512*0b57cec5SDimitry Andric break; 513*0b57cec5SDimitry Andric case ELFOSABI_OPENBSD: 514*0b57cec5SDimitry Andric ostype = llvm::Triple::OSType::OpenBSD; 515*0b57cec5SDimitry Andric break; 516*0b57cec5SDimitry Andric case ELFOSABI_SOLARIS: 517*0b57cec5SDimitry Andric ostype = llvm::Triple::OSType::Solaris; 518*0b57cec5SDimitry Andric break; 519*0b57cec5SDimitry Andric default: 520*0b57cec5SDimitry Andric ostype = llvm::Triple::OSType::UnknownOS; 521*0b57cec5SDimitry Andric } 522*0b57cec5SDimitry Andric return ostype != llvm::Triple::OSType::UnknownOS; 523*0b57cec5SDimitry Andric } 524*0b57cec5SDimitry Andric 525*0b57cec5SDimitry Andric size_t ObjectFileELF::GetModuleSpecifications( 526*0b57cec5SDimitry Andric const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp, 527*0b57cec5SDimitry Andric lldb::offset_t data_offset, lldb::offset_t file_offset, 528*0b57cec5SDimitry Andric lldb::offset_t length, lldb_private::ModuleSpecList &specs) { 52981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Modules); 530*0b57cec5SDimitry Andric 531*0b57cec5SDimitry Andric const size_t initial_count = specs.GetSize(); 532*0b57cec5SDimitry Andric 533*0b57cec5SDimitry Andric if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) { 534*0b57cec5SDimitry Andric DataExtractor data; 535*0b57cec5SDimitry Andric data.SetData(data_sp); 536*0b57cec5SDimitry Andric elf::ELFHeader header; 537*0b57cec5SDimitry Andric lldb::offset_t header_offset = data_offset; 538*0b57cec5SDimitry Andric if (header.Parse(data, &header_offset)) { 539*0b57cec5SDimitry Andric if (data_sp) { 540*0b57cec5SDimitry Andric ModuleSpec spec(file); 541*0b57cec5SDimitry Andric 542*0b57cec5SDimitry Andric const uint32_t sub_type = subTypeFromElfHeader(header); 543*0b57cec5SDimitry Andric spec.GetArchitecture().SetArchitecture( 544*0b57cec5SDimitry Andric eArchTypeELF, header.e_machine, sub_type, header.e_ident[EI_OSABI]); 545*0b57cec5SDimitry Andric 546*0b57cec5SDimitry Andric if (spec.GetArchitecture().IsValid()) { 547*0b57cec5SDimitry Andric llvm::Triple::OSType ostype; 548*0b57cec5SDimitry Andric llvm::Triple::VendorType vendor; 549*0b57cec5SDimitry Andric llvm::Triple::OSType spec_ostype = 550*0b57cec5SDimitry Andric spec.GetArchitecture().GetTriple().getOS(); 551*0b57cec5SDimitry Andric 5529dba64beSDimitry Andric LLDB_LOGF(log, "ObjectFileELF::%s file '%s' module OSABI: %s", 553*0b57cec5SDimitry Andric __FUNCTION__, file.GetPath().c_str(), 554*0b57cec5SDimitry Andric OSABIAsCString(header.e_ident[EI_OSABI])); 555*0b57cec5SDimitry Andric 556*0b57cec5SDimitry Andric // SetArchitecture should have set the vendor to unknown 557*0b57cec5SDimitry Andric vendor = spec.GetArchitecture().GetTriple().getVendor(); 558*0b57cec5SDimitry Andric assert(vendor == llvm::Triple::UnknownVendor); 559*0b57cec5SDimitry Andric UNUSED_IF_ASSERT_DISABLED(vendor); 560*0b57cec5SDimitry Andric 561*0b57cec5SDimitry Andric // 562*0b57cec5SDimitry Andric // Validate it is ok to remove GetOsFromOSABI 563*0b57cec5SDimitry Andric GetOsFromOSABI(header.e_ident[EI_OSABI], ostype); 564*0b57cec5SDimitry Andric assert(spec_ostype == ostype); 565*0b57cec5SDimitry Andric if (spec_ostype != llvm::Triple::OSType::UnknownOS) { 5669dba64beSDimitry Andric LLDB_LOGF(log, 5679dba64beSDimitry Andric "ObjectFileELF::%s file '%s' set ELF module OS type " 568*0b57cec5SDimitry Andric "from ELF header OSABI.", 569*0b57cec5SDimitry Andric __FUNCTION__, file.GetPath().c_str()); 570*0b57cec5SDimitry Andric } 571*0b57cec5SDimitry Andric 5725ffd83dbSDimitry Andric if (data_sp->GetByteSize() < length) 573*0b57cec5SDimitry Andric data_sp = MapFileData(file, -1, file_offset); 574*0b57cec5SDimitry Andric if (data_sp) 575*0b57cec5SDimitry Andric data.SetData(data_sp); 576*0b57cec5SDimitry Andric // In case there is header extension in the section #0, the header we 577*0b57cec5SDimitry Andric // parsed above could have sentinel values for e_phnum, e_shnum, and 578*0b57cec5SDimitry Andric // e_shstrndx. In this case we need to reparse the header with a 579*0b57cec5SDimitry Andric // bigger data source to get the actual values. 580*0b57cec5SDimitry Andric if (header.HasHeaderExtension()) { 581*0b57cec5SDimitry Andric lldb::offset_t header_offset = data_offset; 582*0b57cec5SDimitry Andric header.Parse(data, &header_offset); 583*0b57cec5SDimitry Andric } 584*0b57cec5SDimitry Andric 585*0b57cec5SDimitry Andric uint32_t gnu_debuglink_crc = 0; 586*0b57cec5SDimitry Andric std::string gnu_debuglink_file; 587*0b57cec5SDimitry Andric SectionHeaderColl section_headers; 588*0b57cec5SDimitry Andric lldb_private::UUID &uuid = spec.GetUUID(); 589*0b57cec5SDimitry Andric 590*0b57cec5SDimitry Andric GetSectionHeaderInfo(section_headers, data, header, uuid, 591*0b57cec5SDimitry Andric gnu_debuglink_file, gnu_debuglink_crc, 592*0b57cec5SDimitry Andric spec.GetArchitecture()); 593*0b57cec5SDimitry Andric 594*0b57cec5SDimitry Andric llvm::Triple &spec_triple = spec.GetArchitecture().GetTriple(); 595*0b57cec5SDimitry Andric 5969dba64beSDimitry Andric LLDB_LOGF(log, 5979dba64beSDimitry Andric "ObjectFileELF::%s file '%s' module set to triple: %s " 598*0b57cec5SDimitry Andric "(architecture %s)", 599*0b57cec5SDimitry Andric __FUNCTION__, file.GetPath().c_str(), 600*0b57cec5SDimitry Andric spec_triple.getTriple().c_str(), 601*0b57cec5SDimitry Andric spec.GetArchitecture().GetArchitectureName()); 602*0b57cec5SDimitry Andric 603*0b57cec5SDimitry Andric if (!uuid.IsValid()) { 604*0b57cec5SDimitry Andric uint32_t core_notes_crc = 0; 605*0b57cec5SDimitry Andric 606*0b57cec5SDimitry Andric if (!gnu_debuglink_crc) { 607e8d8bef9SDimitry Andric LLDB_SCOPED_TIMERF( 608*0b57cec5SDimitry Andric "Calculating module crc32 %s with size %" PRIu64 " KiB", 609*0b57cec5SDimitry Andric file.GetLastPathComponent().AsCString(), 6105ffd83dbSDimitry Andric (length - file_offset) / 1024); 611*0b57cec5SDimitry Andric 612*0b57cec5SDimitry Andric // For core files - which usually don't happen to have a 613*0b57cec5SDimitry Andric // gnu_debuglink, and are pretty bulky - calculating whole 614*0b57cec5SDimitry Andric // contents crc32 would be too much of luxury. Thus we will need 615*0b57cec5SDimitry Andric // to fallback to something simpler. 616*0b57cec5SDimitry Andric if (header.e_type == llvm::ELF::ET_CORE) { 617*0b57cec5SDimitry Andric ProgramHeaderColl program_headers; 618*0b57cec5SDimitry Andric GetProgramHeaderInfo(program_headers, data, header); 619*0b57cec5SDimitry Andric 620*0b57cec5SDimitry Andric core_notes_crc = 621*0b57cec5SDimitry Andric CalculateELFNotesSegmentsCRC32(program_headers, data); 622*0b57cec5SDimitry Andric } else { 6239dba64beSDimitry Andric gnu_debuglink_crc = calc_crc32(0, data); 624*0b57cec5SDimitry Andric } 625*0b57cec5SDimitry Andric } 626*0b57cec5SDimitry Andric using u32le = llvm::support::ulittle32_t; 627*0b57cec5SDimitry Andric if (gnu_debuglink_crc) { 628*0b57cec5SDimitry Andric // Use 4 bytes of crc from the .gnu_debuglink section. 629*0b57cec5SDimitry Andric u32le data(gnu_debuglink_crc); 630*0b57cec5SDimitry Andric uuid = UUID::fromData(&data, sizeof(data)); 631*0b57cec5SDimitry Andric } else if (core_notes_crc) { 632*0b57cec5SDimitry Andric // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make 633*0b57cec5SDimitry Andric // it look different form .gnu_debuglink crc followed by 4 bytes 634*0b57cec5SDimitry Andric // of note segments crc. 635*0b57cec5SDimitry Andric u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)}; 636*0b57cec5SDimitry Andric uuid = UUID::fromData(data, sizeof(data)); 637*0b57cec5SDimitry Andric } 638*0b57cec5SDimitry Andric } 639*0b57cec5SDimitry Andric 640*0b57cec5SDimitry Andric specs.Append(spec); 641*0b57cec5SDimitry Andric } 642*0b57cec5SDimitry Andric } 643*0b57cec5SDimitry Andric } 644*0b57cec5SDimitry Andric } 645*0b57cec5SDimitry Andric 646*0b57cec5SDimitry Andric return specs.GetSize() - initial_count; 647*0b57cec5SDimitry Andric } 648*0b57cec5SDimitry Andric 649*0b57cec5SDimitry Andric // ObjectFile protocol 650*0b57cec5SDimitry Andric 651*0b57cec5SDimitry Andric ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, 65281ad6265SDimitry Andric DataBufferSP data_sp, lldb::offset_t data_offset, 653*0b57cec5SDimitry Andric const FileSpec *file, lldb::offset_t file_offset, 654*0b57cec5SDimitry Andric lldb::offset_t length) 6559dba64beSDimitry Andric : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset) { 656*0b57cec5SDimitry Andric if (file) 657*0b57cec5SDimitry Andric m_file = *file; 658*0b57cec5SDimitry Andric } 659*0b57cec5SDimitry Andric 660*0b57cec5SDimitry Andric ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, 66181ad6265SDimitry Andric DataBufferSP header_data_sp, 662*0b57cec5SDimitry Andric const lldb::ProcessSP &process_sp, 663*0b57cec5SDimitry Andric addr_t header_addr) 6649dba64beSDimitry Andric : ObjectFile(module_sp, process_sp, header_addr, header_data_sp) {} 665*0b57cec5SDimitry Andric 666*0b57cec5SDimitry Andric bool ObjectFileELF::IsExecutable() const { 667*0b57cec5SDimitry Andric return ((m_header.e_type & ET_EXEC) != 0) || (m_header.e_entry != 0); 668*0b57cec5SDimitry Andric } 669*0b57cec5SDimitry Andric 670*0b57cec5SDimitry Andric bool ObjectFileELF::SetLoadAddress(Target &target, lldb::addr_t value, 671*0b57cec5SDimitry Andric bool value_is_offset) { 672*0b57cec5SDimitry Andric ModuleSP module_sp = GetModule(); 673*0b57cec5SDimitry Andric if (module_sp) { 674*0b57cec5SDimitry Andric size_t num_loaded_sections = 0; 675*0b57cec5SDimitry Andric SectionList *section_list = GetSectionList(); 676*0b57cec5SDimitry Andric if (section_list) { 677*0b57cec5SDimitry Andric if (!value_is_offset) { 678*0b57cec5SDimitry Andric addr_t base = GetBaseAddress().GetFileAddress(); 679*0b57cec5SDimitry Andric if (base == LLDB_INVALID_ADDRESS) 680*0b57cec5SDimitry Andric return false; 681*0b57cec5SDimitry Andric value -= base; 682*0b57cec5SDimitry Andric } 683*0b57cec5SDimitry Andric 684*0b57cec5SDimitry Andric const size_t num_sections = section_list->GetSize(); 685*0b57cec5SDimitry Andric size_t sect_idx = 0; 686*0b57cec5SDimitry Andric 687*0b57cec5SDimitry Andric for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) { 688*0b57cec5SDimitry Andric // Iterate through the object file sections to find all of the sections 689*0b57cec5SDimitry Andric // that have SHF_ALLOC in their flag bits. 690*0b57cec5SDimitry Andric SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx)); 691*0b57cec5SDimitry Andric if (section_sp->Test(SHF_ALLOC) || 692*0b57cec5SDimitry Andric section_sp->GetType() == eSectionTypeContainer) { 693*0b57cec5SDimitry Andric lldb::addr_t load_addr = section_sp->GetFileAddress(); 694*0b57cec5SDimitry Andric // We don't want to update the load address of a section with type 695*0b57cec5SDimitry Andric // eSectionTypeAbsoluteAddress as they already have the absolute load 696*0b57cec5SDimitry Andric // address already specified 697*0b57cec5SDimitry Andric if (section_sp->GetType() != eSectionTypeAbsoluteAddress) 698*0b57cec5SDimitry Andric load_addr += value; 699*0b57cec5SDimitry Andric 700*0b57cec5SDimitry Andric // On 32-bit systems the load address have to fit into 4 bytes. The 701*0b57cec5SDimitry Andric // rest of the bytes are the overflow from the addition. 702*0b57cec5SDimitry Andric if (GetAddressByteSize() == 4) 703*0b57cec5SDimitry Andric load_addr &= 0xFFFFFFFF; 704*0b57cec5SDimitry Andric 705*0b57cec5SDimitry Andric if (target.GetSectionLoadList().SetSectionLoadAddress(section_sp, 706*0b57cec5SDimitry Andric load_addr)) 707*0b57cec5SDimitry Andric ++num_loaded_sections; 708*0b57cec5SDimitry Andric } 709*0b57cec5SDimitry Andric } 710*0b57cec5SDimitry Andric return num_loaded_sections > 0; 711*0b57cec5SDimitry Andric } 712*0b57cec5SDimitry Andric } 713*0b57cec5SDimitry Andric return false; 714*0b57cec5SDimitry Andric } 715*0b57cec5SDimitry Andric 716*0b57cec5SDimitry Andric ByteOrder ObjectFileELF::GetByteOrder() const { 717*0b57cec5SDimitry Andric if (m_header.e_ident[EI_DATA] == ELFDATA2MSB) 718*0b57cec5SDimitry Andric return eByteOrderBig; 719*0b57cec5SDimitry Andric if (m_header.e_ident[EI_DATA] == ELFDATA2LSB) 720*0b57cec5SDimitry Andric return eByteOrderLittle; 721*0b57cec5SDimitry Andric return eByteOrderInvalid; 722*0b57cec5SDimitry Andric } 723*0b57cec5SDimitry Andric 724*0b57cec5SDimitry Andric uint32_t ObjectFileELF::GetAddressByteSize() const { 725*0b57cec5SDimitry Andric return m_data.GetAddressByteSize(); 726*0b57cec5SDimitry Andric } 727*0b57cec5SDimitry Andric 728*0b57cec5SDimitry Andric AddressClass ObjectFileELF::GetAddressClass(addr_t file_addr) { 729*0b57cec5SDimitry Andric Symtab *symtab = GetSymtab(); 730*0b57cec5SDimitry Andric if (!symtab) 731*0b57cec5SDimitry Andric return AddressClass::eUnknown; 732*0b57cec5SDimitry Andric 733*0b57cec5SDimitry Andric // The address class is determined based on the symtab. Ask it from the 734*0b57cec5SDimitry Andric // object file what contains the symtab information. 735*0b57cec5SDimitry Andric ObjectFile *symtab_objfile = symtab->GetObjectFile(); 736*0b57cec5SDimitry Andric if (symtab_objfile != nullptr && symtab_objfile != this) 737*0b57cec5SDimitry Andric return symtab_objfile->GetAddressClass(file_addr); 738*0b57cec5SDimitry Andric 739*0b57cec5SDimitry Andric auto res = ObjectFile::GetAddressClass(file_addr); 740*0b57cec5SDimitry Andric if (res != AddressClass::eCode) 741*0b57cec5SDimitry Andric return res; 742*0b57cec5SDimitry Andric 743*0b57cec5SDimitry Andric auto ub = m_address_class_map.upper_bound(file_addr); 744*0b57cec5SDimitry Andric if (ub == m_address_class_map.begin()) { 745*0b57cec5SDimitry Andric // No entry in the address class map before the address. Return default 746*0b57cec5SDimitry Andric // address class for an address in a code section. 747*0b57cec5SDimitry Andric return AddressClass::eCode; 748*0b57cec5SDimitry Andric } 749*0b57cec5SDimitry Andric 750*0b57cec5SDimitry Andric // Move iterator to the address class entry preceding address 751*0b57cec5SDimitry Andric --ub; 752*0b57cec5SDimitry Andric 753*0b57cec5SDimitry Andric return ub->second; 754*0b57cec5SDimitry Andric } 755*0b57cec5SDimitry Andric 756*0b57cec5SDimitry Andric size_t ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I) { 757*0b57cec5SDimitry Andric return std::distance(m_section_headers.begin(), I); 758*0b57cec5SDimitry Andric } 759*0b57cec5SDimitry Andric 760*0b57cec5SDimitry Andric size_t ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const { 761*0b57cec5SDimitry Andric return std::distance(m_section_headers.begin(), I); 762*0b57cec5SDimitry Andric } 763*0b57cec5SDimitry Andric 764*0b57cec5SDimitry Andric bool ObjectFileELF::ParseHeader() { 765*0b57cec5SDimitry Andric lldb::offset_t offset = 0; 766*0b57cec5SDimitry Andric return m_header.Parse(m_data, &offset); 767*0b57cec5SDimitry Andric } 768*0b57cec5SDimitry Andric 769*0b57cec5SDimitry Andric UUID ObjectFileELF::GetUUID() { 770*0b57cec5SDimitry Andric // Need to parse the section list to get the UUIDs, so make sure that's been 771*0b57cec5SDimitry Andric // done. 772*0b57cec5SDimitry Andric if (!ParseSectionHeaders() && GetType() != ObjectFile::eTypeCoreFile) 773*0b57cec5SDimitry Andric return UUID(); 774*0b57cec5SDimitry Andric 775*0b57cec5SDimitry Andric if (!m_uuid) { 776*0b57cec5SDimitry Andric using u32le = llvm::support::ulittle32_t; 777*0b57cec5SDimitry Andric if (GetType() == ObjectFile::eTypeCoreFile) { 778*0b57cec5SDimitry Andric uint32_t core_notes_crc = 0; 779*0b57cec5SDimitry Andric 780*0b57cec5SDimitry Andric if (!ParseProgramHeaders()) 781*0b57cec5SDimitry Andric return UUID(); 782*0b57cec5SDimitry Andric 783*0b57cec5SDimitry Andric core_notes_crc = 784*0b57cec5SDimitry Andric CalculateELFNotesSegmentsCRC32(m_program_headers, m_data); 785*0b57cec5SDimitry Andric 786*0b57cec5SDimitry Andric if (core_notes_crc) { 787*0b57cec5SDimitry Andric // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it 788*0b57cec5SDimitry Andric // look different form .gnu_debuglink crc - followed by 4 bytes of note 789*0b57cec5SDimitry Andric // segments crc. 790*0b57cec5SDimitry Andric u32le data[] = {u32le(g_core_uuid_magic), u32le(core_notes_crc)}; 791*0b57cec5SDimitry Andric m_uuid = UUID::fromData(data, sizeof(data)); 792*0b57cec5SDimitry Andric } 793*0b57cec5SDimitry Andric } else { 794*0b57cec5SDimitry Andric if (!m_gnu_debuglink_crc) 7959dba64beSDimitry Andric m_gnu_debuglink_crc = calc_crc32(0, m_data); 796*0b57cec5SDimitry Andric if (m_gnu_debuglink_crc) { 797*0b57cec5SDimitry Andric // Use 4 bytes of crc from the .gnu_debuglink section. 798*0b57cec5SDimitry Andric u32le data(m_gnu_debuglink_crc); 799*0b57cec5SDimitry Andric m_uuid = UUID::fromData(&data, sizeof(data)); 800*0b57cec5SDimitry Andric } 801*0b57cec5SDimitry Andric } 802*0b57cec5SDimitry Andric } 803*0b57cec5SDimitry Andric 804*0b57cec5SDimitry Andric return m_uuid; 805*0b57cec5SDimitry Andric } 806*0b57cec5SDimitry Andric 8079dba64beSDimitry Andric llvm::Optional<FileSpec> ObjectFileELF::GetDebugLink() { 8089dba64beSDimitry Andric if (m_gnu_debuglink_file.empty()) 8099dba64beSDimitry Andric return llvm::None; 8109dba64beSDimitry Andric return FileSpec(m_gnu_debuglink_file); 811*0b57cec5SDimitry Andric } 812*0b57cec5SDimitry Andric 813*0b57cec5SDimitry Andric uint32_t ObjectFileELF::GetDependentModules(FileSpecList &files) { 814*0b57cec5SDimitry Andric size_t num_modules = ParseDependentModules(); 815*0b57cec5SDimitry Andric uint32_t num_specs = 0; 816*0b57cec5SDimitry Andric 817*0b57cec5SDimitry Andric for (unsigned i = 0; i < num_modules; ++i) { 818*0b57cec5SDimitry Andric if (files.AppendIfUnique(m_filespec_up->GetFileSpecAtIndex(i))) 819*0b57cec5SDimitry Andric num_specs++; 820*0b57cec5SDimitry Andric } 821*0b57cec5SDimitry Andric 822*0b57cec5SDimitry Andric return num_specs; 823*0b57cec5SDimitry Andric } 824*0b57cec5SDimitry Andric 825*0b57cec5SDimitry Andric Address ObjectFileELF::GetImageInfoAddress(Target *target) { 826*0b57cec5SDimitry Andric if (!ParseDynamicSymbols()) 827*0b57cec5SDimitry Andric return Address(); 828*0b57cec5SDimitry Andric 829*0b57cec5SDimitry Andric SectionList *section_list = GetSectionList(); 830*0b57cec5SDimitry Andric if (!section_list) 831*0b57cec5SDimitry Andric return Address(); 832*0b57cec5SDimitry Andric 833*0b57cec5SDimitry Andric // Find the SHT_DYNAMIC (.dynamic) section. 834*0b57cec5SDimitry Andric SectionSP dynsym_section_sp( 835*0b57cec5SDimitry Andric section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true)); 836*0b57cec5SDimitry Andric if (!dynsym_section_sp) 837*0b57cec5SDimitry Andric return Address(); 838*0b57cec5SDimitry Andric assert(dynsym_section_sp->GetObjectFile() == this); 839*0b57cec5SDimitry Andric 840*0b57cec5SDimitry Andric user_id_t dynsym_id = dynsym_section_sp->GetID(); 841*0b57cec5SDimitry Andric const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id); 842*0b57cec5SDimitry Andric if (!dynsym_hdr) 843*0b57cec5SDimitry Andric return Address(); 844*0b57cec5SDimitry Andric 845*0b57cec5SDimitry Andric for (size_t i = 0; i < m_dynamic_symbols.size(); ++i) { 846*0b57cec5SDimitry Andric ELFDynamic &symbol = m_dynamic_symbols[i]; 847*0b57cec5SDimitry Andric 848*0b57cec5SDimitry Andric if (symbol.d_tag == DT_DEBUG) { 849*0b57cec5SDimitry Andric // Compute the offset as the number of previous entries plus the size of 850*0b57cec5SDimitry Andric // d_tag. 851*0b57cec5SDimitry Andric addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize(); 852*0b57cec5SDimitry Andric return Address(dynsym_section_sp, offset); 853*0b57cec5SDimitry Andric } 854*0b57cec5SDimitry Andric // MIPS executables uses DT_MIPS_RLD_MAP_REL to support PIE. DT_MIPS_RLD_MAP 855*0b57cec5SDimitry Andric // exists in non-PIE. 856*0b57cec5SDimitry Andric else if ((symbol.d_tag == DT_MIPS_RLD_MAP || 857*0b57cec5SDimitry Andric symbol.d_tag == DT_MIPS_RLD_MAP_REL) && 858*0b57cec5SDimitry Andric target) { 859*0b57cec5SDimitry Andric addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize(); 860*0b57cec5SDimitry Andric addr_t dyn_base = dynsym_section_sp->GetLoadBaseAddress(target); 861*0b57cec5SDimitry Andric if (dyn_base == LLDB_INVALID_ADDRESS) 862*0b57cec5SDimitry Andric return Address(); 863*0b57cec5SDimitry Andric 864*0b57cec5SDimitry Andric Status error; 865*0b57cec5SDimitry Andric if (symbol.d_tag == DT_MIPS_RLD_MAP) { 866*0b57cec5SDimitry Andric // DT_MIPS_RLD_MAP tag stores an absolute address of the debug pointer. 867*0b57cec5SDimitry Andric Address addr; 868fe6060f1SDimitry Andric if (target->ReadPointerFromMemory(dyn_base + offset, error, addr, true)) 869*0b57cec5SDimitry Andric return addr; 870*0b57cec5SDimitry Andric } 871*0b57cec5SDimitry Andric if (symbol.d_tag == DT_MIPS_RLD_MAP_REL) { 872*0b57cec5SDimitry Andric // DT_MIPS_RLD_MAP_REL tag stores the offset to the debug pointer, 873*0b57cec5SDimitry Andric // relative to the address of the tag. 874*0b57cec5SDimitry Andric uint64_t rel_offset; 875*0b57cec5SDimitry Andric rel_offset = target->ReadUnsignedIntegerFromMemory( 876fe6060f1SDimitry Andric dyn_base + offset, GetAddressByteSize(), UINT64_MAX, error, true); 877*0b57cec5SDimitry Andric if (error.Success() && rel_offset != UINT64_MAX) { 878*0b57cec5SDimitry Andric Address addr; 879*0b57cec5SDimitry Andric addr_t debug_ptr_address = 880*0b57cec5SDimitry Andric dyn_base + (offset - GetAddressByteSize()) + rel_offset; 881*0b57cec5SDimitry Andric addr.SetOffset(debug_ptr_address); 882*0b57cec5SDimitry Andric return addr; 883*0b57cec5SDimitry Andric } 884*0b57cec5SDimitry Andric } 885*0b57cec5SDimitry Andric } 886*0b57cec5SDimitry Andric } 887*0b57cec5SDimitry Andric 888*0b57cec5SDimitry Andric return Address(); 889*0b57cec5SDimitry Andric } 890*0b57cec5SDimitry Andric 891*0b57cec5SDimitry Andric lldb_private::Address ObjectFileELF::GetEntryPointAddress() { 892*0b57cec5SDimitry Andric if (m_entry_point_address.IsValid()) 893*0b57cec5SDimitry Andric return m_entry_point_address; 894*0b57cec5SDimitry Andric 895*0b57cec5SDimitry Andric if (!ParseHeader() || !IsExecutable()) 896*0b57cec5SDimitry Andric return m_entry_point_address; 897*0b57cec5SDimitry Andric 898*0b57cec5SDimitry Andric SectionList *section_list = GetSectionList(); 899*0b57cec5SDimitry Andric addr_t offset = m_header.e_entry; 900*0b57cec5SDimitry Andric 901*0b57cec5SDimitry Andric if (!section_list) 902*0b57cec5SDimitry Andric m_entry_point_address.SetOffset(offset); 903*0b57cec5SDimitry Andric else 904*0b57cec5SDimitry Andric m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list); 905*0b57cec5SDimitry Andric return m_entry_point_address; 906*0b57cec5SDimitry Andric } 907*0b57cec5SDimitry Andric 908*0b57cec5SDimitry Andric Address ObjectFileELF::GetBaseAddress() { 909*0b57cec5SDimitry Andric for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) { 910*0b57cec5SDimitry Andric const ELFProgramHeader &H = EnumPHdr.value(); 911*0b57cec5SDimitry Andric if (H.p_type != PT_LOAD) 912*0b57cec5SDimitry Andric continue; 913*0b57cec5SDimitry Andric 914*0b57cec5SDimitry Andric return Address( 915*0b57cec5SDimitry Andric GetSectionList()->FindSectionByID(SegmentID(EnumPHdr.index())), 0); 916*0b57cec5SDimitry Andric } 917*0b57cec5SDimitry Andric return LLDB_INVALID_ADDRESS; 918*0b57cec5SDimitry Andric } 919*0b57cec5SDimitry Andric 920*0b57cec5SDimitry Andric // ParseDependentModules 921*0b57cec5SDimitry Andric size_t ObjectFileELF::ParseDependentModules() { 922*0b57cec5SDimitry Andric if (m_filespec_up) 923*0b57cec5SDimitry Andric return m_filespec_up->GetSize(); 924*0b57cec5SDimitry Andric 9255ffd83dbSDimitry Andric m_filespec_up = std::make_unique<FileSpecList>(); 926*0b57cec5SDimitry Andric 927*0b57cec5SDimitry Andric if (!ParseSectionHeaders()) 928*0b57cec5SDimitry Andric return 0; 929*0b57cec5SDimitry Andric 930*0b57cec5SDimitry Andric SectionList *section_list = GetSectionList(); 931*0b57cec5SDimitry Andric if (!section_list) 932*0b57cec5SDimitry Andric return 0; 933*0b57cec5SDimitry Andric 934*0b57cec5SDimitry Andric // Find the SHT_DYNAMIC section. 935*0b57cec5SDimitry Andric Section *dynsym = 936*0b57cec5SDimitry Andric section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true) 937*0b57cec5SDimitry Andric .get(); 938*0b57cec5SDimitry Andric if (!dynsym) 939*0b57cec5SDimitry Andric return 0; 940*0b57cec5SDimitry Andric assert(dynsym->GetObjectFile() == this); 941*0b57cec5SDimitry Andric 942*0b57cec5SDimitry Andric const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex(dynsym->GetID()); 943*0b57cec5SDimitry Andric if (!header) 944*0b57cec5SDimitry Andric return 0; 945*0b57cec5SDimitry Andric // sh_link: section header index of string table used by entries in the 946*0b57cec5SDimitry Andric // section. 947*0b57cec5SDimitry Andric Section *dynstr = section_list->FindSectionByID(header->sh_link).get(); 948*0b57cec5SDimitry Andric if (!dynstr) 949*0b57cec5SDimitry Andric return 0; 950*0b57cec5SDimitry Andric 951*0b57cec5SDimitry Andric DataExtractor dynsym_data; 952*0b57cec5SDimitry Andric DataExtractor dynstr_data; 953*0b57cec5SDimitry Andric if (ReadSectionData(dynsym, dynsym_data) && 954*0b57cec5SDimitry Andric ReadSectionData(dynstr, dynstr_data)) { 955*0b57cec5SDimitry Andric ELFDynamic symbol; 956*0b57cec5SDimitry Andric const lldb::offset_t section_size = dynsym_data.GetByteSize(); 957*0b57cec5SDimitry Andric lldb::offset_t offset = 0; 958*0b57cec5SDimitry Andric 959*0b57cec5SDimitry Andric // The only type of entries we are concerned with are tagged DT_NEEDED, 960*0b57cec5SDimitry Andric // yielding the name of a required library. 961*0b57cec5SDimitry Andric while (offset < section_size) { 962*0b57cec5SDimitry Andric if (!symbol.Parse(dynsym_data, &offset)) 963*0b57cec5SDimitry Andric break; 964*0b57cec5SDimitry Andric 965*0b57cec5SDimitry Andric if (symbol.d_tag != DT_NEEDED) 966*0b57cec5SDimitry Andric continue; 967*0b57cec5SDimitry Andric 968*0b57cec5SDimitry Andric uint32_t str_index = static_cast<uint32_t>(symbol.d_val); 969*0b57cec5SDimitry Andric const char *lib_name = dynstr_data.PeekCStr(str_index); 970*0b57cec5SDimitry Andric FileSpec file_spec(lib_name); 971*0b57cec5SDimitry Andric FileSystem::Instance().Resolve(file_spec); 972*0b57cec5SDimitry Andric m_filespec_up->Append(file_spec); 973*0b57cec5SDimitry Andric } 974*0b57cec5SDimitry Andric } 975*0b57cec5SDimitry Andric 976*0b57cec5SDimitry Andric return m_filespec_up->GetSize(); 977*0b57cec5SDimitry Andric } 978*0b57cec5SDimitry Andric 979*0b57cec5SDimitry Andric // GetProgramHeaderInfo 980*0b57cec5SDimitry Andric size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers, 981*0b57cec5SDimitry Andric DataExtractor &object_data, 982*0b57cec5SDimitry Andric const ELFHeader &header) { 983*0b57cec5SDimitry Andric // We have already parsed the program headers 984*0b57cec5SDimitry Andric if (!program_headers.empty()) 985*0b57cec5SDimitry Andric return program_headers.size(); 986*0b57cec5SDimitry Andric 987*0b57cec5SDimitry Andric // If there are no program headers to read we are done. 988*0b57cec5SDimitry Andric if (header.e_phnum == 0) 989*0b57cec5SDimitry Andric return 0; 990*0b57cec5SDimitry Andric 991*0b57cec5SDimitry Andric program_headers.resize(header.e_phnum); 992*0b57cec5SDimitry Andric if (program_headers.size() != header.e_phnum) 993*0b57cec5SDimitry Andric return 0; 994*0b57cec5SDimitry Andric 995*0b57cec5SDimitry Andric const size_t ph_size = header.e_phnum * header.e_phentsize; 996*0b57cec5SDimitry Andric const elf_off ph_offset = header.e_phoff; 997*0b57cec5SDimitry Andric DataExtractor data; 998*0b57cec5SDimitry Andric if (data.SetData(object_data, ph_offset, ph_size) != ph_size) 999*0b57cec5SDimitry Andric return 0; 1000*0b57cec5SDimitry Andric 1001*0b57cec5SDimitry Andric uint32_t idx; 1002*0b57cec5SDimitry Andric lldb::offset_t offset; 1003*0b57cec5SDimitry Andric for (idx = 0, offset = 0; idx < header.e_phnum; ++idx) { 1004*0b57cec5SDimitry Andric if (!program_headers[idx].Parse(data, &offset)) 1005*0b57cec5SDimitry Andric break; 1006*0b57cec5SDimitry Andric } 1007*0b57cec5SDimitry Andric 1008*0b57cec5SDimitry Andric if (idx < program_headers.size()) 1009*0b57cec5SDimitry Andric program_headers.resize(idx); 1010*0b57cec5SDimitry Andric 1011*0b57cec5SDimitry Andric return program_headers.size(); 1012*0b57cec5SDimitry Andric } 1013*0b57cec5SDimitry Andric 1014*0b57cec5SDimitry Andric // ParseProgramHeaders 1015*0b57cec5SDimitry Andric bool ObjectFileELF::ParseProgramHeaders() { 1016*0b57cec5SDimitry Andric return GetProgramHeaderInfo(m_program_headers, m_data, m_header) != 0; 1017*0b57cec5SDimitry Andric } 1018*0b57cec5SDimitry Andric 1019*0b57cec5SDimitry Andric lldb_private::Status 1020*0b57cec5SDimitry Andric ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, 1021*0b57cec5SDimitry Andric lldb_private::ArchSpec &arch_spec, 1022*0b57cec5SDimitry Andric lldb_private::UUID &uuid) { 102381ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Modules); 1024*0b57cec5SDimitry Andric Status error; 1025*0b57cec5SDimitry Andric 1026*0b57cec5SDimitry Andric lldb::offset_t offset = 0; 1027*0b57cec5SDimitry Andric 1028*0b57cec5SDimitry Andric while (true) { 1029*0b57cec5SDimitry Andric // Parse the note header. If this fails, bail out. 1030*0b57cec5SDimitry Andric const lldb::offset_t note_offset = offset; 1031*0b57cec5SDimitry Andric ELFNote note = ELFNote(); 1032*0b57cec5SDimitry Andric if (!note.Parse(data, &offset)) { 1033*0b57cec5SDimitry Andric // We're done. 1034*0b57cec5SDimitry Andric return error; 1035*0b57cec5SDimitry Andric } 1036*0b57cec5SDimitry Andric 10379dba64beSDimitry Andric LLDB_LOGF(log, "ObjectFileELF::%s parsing note name='%s', type=%" PRIu32, 1038*0b57cec5SDimitry Andric __FUNCTION__, note.n_name.c_str(), note.n_type); 1039*0b57cec5SDimitry Andric 1040*0b57cec5SDimitry Andric // Process FreeBSD ELF notes. 1041*0b57cec5SDimitry Andric if ((note.n_name == LLDB_NT_OWNER_FREEBSD) && 1042*0b57cec5SDimitry Andric (note.n_type == LLDB_NT_FREEBSD_ABI_TAG) && 1043*0b57cec5SDimitry Andric (note.n_descsz == LLDB_NT_FREEBSD_ABI_SIZE)) { 1044*0b57cec5SDimitry Andric // Pull out the min version info. 1045*0b57cec5SDimitry Andric uint32_t version_info; 1046*0b57cec5SDimitry Andric if (data.GetU32(&offset, &version_info, 1) == nullptr) { 1047*0b57cec5SDimitry Andric error.SetErrorString("failed to read FreeBSD ABI note payload"); 1048*0b57cec5SDimitry Andric return error; 1049*0b57cec5SDimitry Andric } 1050*0b57cec5SDimitry Andric 1051*0b57cec5SDimitry Andric // Convert the version info into a major/minor number. 1052*0b57cec5SDimitry Andric const uint32_t version_major = version_info / 100000; 1053*0b57cec5SDimitry Andric const uint32_t version_minor = (version_info / 1000) % 100; 1054*0b57cec5SDimitry Andric 1055*0b57cec5SDimitry Andric char os_name[32]; 1056*0b57cec5SDimitry Andric snprintf(os_name, sizeof(os_name), "freebsd%" PRIu32 ".%" PRIu32, 1057*0b57cec5SDimitry Andric version_major, version_minor); 1058*0b57cec5SDimitry Andric 1059*0b57cec5SDimitry Andric // Set the elf OS version to FreeBSD. Also clear the vendor. 1060*0b57cec5SDimitry Andric arch_spec.GetTriple().setOSName(os_name); 1061*0b57cec5SDimitry Andric arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); 1062*0b57cec5SDimitry Andric 10639dba64beSDimitry Andric LLDB_LOGF(log, 10649dba64beSDimitry Andric "ObjectFileELF::%s detected FreeBSD %" PRIu32 ".%" PRIu32 1065*0b57cec5SDimitry Andric ".%" PRIu32, 1066*0b57cec5SDimitry Andric __FUNCTION__, version_major, version_minor, 1067*0b57cec5SDimitry Andric static_cast<uint32_t>(version_info % 1000)); 1068*0b57cec5SDimitry Andric } 1069*0b57cec5SDimitry Andric // Process GNU ELF notes. 1070*0b57cec5SDimitry Andric else if (note.n_name == LLDB_NT_OWNER_GNU) { 1071*0b57cec5SDimitry Andric switch (note.n_type) { 1072*0b57cec5SDimitry Andric case LLDB_NT_GNU_ABI_TAG: 1073*0b57cec5SDimitry Andric if (note.n_descsz == LLDB_NT_GNU_ABI_SIZE) { 1074*0b57cec5SDimitry Andric // Pull out the min OS version supporting the ABI. 1075*0b57cec5SDimitry Andric uint32_t version_info[4]; 1076*0b57cec5SDimitry Andric if (data.GetU32(&offset, &version_info[0], note.n_descsz / 4) == 1077*0b57cec5SDimitry Andric nullptr) { 1078*0b57cec5SDimitry Andric error.SetErrorString("failed to read GNU ABI note payload"); 1079*0b57cec5SDimitry Andric return error; 1080*0b57cec5SDimitry Andric } 1081*0b57cec5SDimitry Andric 1082*0b57cec5SDimitry Andric // Set the OS per the OS field. 1083*0b57cec5SDimitry Andric switch (version_info[0]) { 1084*0b57cec5SDimitry Andric case LLDB_NT_GNU_ABI_OS_LINUX: 1085*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); 1086*0b57cec5SDimitry Andric arch_spec.GetTriple().setVendor( 1087*0b57cec5SDimitry Andric llvm::Triple::VendorType::UnknownVendor); 10889dba64beSDimitry Andric LLDB_LOGF(log, 1089*0b57cec5SDimitry Andric "ObjectFileELF::%s detected Linux, min version %" PRIu32 1090*0b57cec5SDimitry Andric ".%" PRIu32 ".%" PRIu32, 1091*0b57cec5SDimitry Andric __FUNCTION__, version_info[1], version_info[2], 1092*0b57cec5SDimitry Andric version_info[3]); 1093*0b57cec5SDimitry Andric // FIXME we have the minimal version number, we could be propagating 1094*0b57cec5SDimitry Andric // that. version_info[1] = OS Major, version_info[2] = OS Minor, 1095*0b57cec5SDimitry Andric // version_info[3] = Revision. 1096*0b57cec5SDimitry Andric break; 1097*0b57cec5SDimitry Andric case LLDB_NT_GNU_ABI_OS_HURD: 1098*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS); 1099*0b57cec5SDimitry Andric arch_spec.GetTriple().setVendor( 1100*0b57cec5SDimitry Andric llvm::Triple::VendorType::UnknownVendor); 11019dba64beSDimitry Andric LLDB_LOGF(log, 11029dba64beSDimitry Andric "ObjectFileELF::%s detected Hurd (unsupported), min " 1103*0b57cec5SDimitry Andric "version %" PRIu32 ".%" PRIu32 ".%" PRIu32, 1104*0b57cec5SDimitry Andric __FUNCTION__, version_info[1], version_info[2], 1105*0b57cec5SDimitry Andric version_info[3]); 1106*0b57cec5SDimitry Andric break; 1107*0b57cec5SDimitry Andric case LLDB_NT_GNU_ABI_OS_SOLARIS: 1108*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Solaris); 1109*0b57cec5SDimitry Andric arch_spec.GetTriple().setVendor( 1110*0b57cec5SDimitry Andric llvm::Triple::VendorType::UnknownVendor); 11119dba64beSDimitry Andric LLDB_LOGF(log, 1112*0b57cec5SDimitry Andric "ObjectFileELF::%s detected Solaris, min version %" PRIu32 1113*0b57cec5SDimitry Andric ".%" PRIu32 ".%" PRIu32, 1114*0b57cec5SDimitry Andric __FUNCTION__, version_info[1], version_info[2], 1115*0b57cec5SDimitry Andric version_info[3]); 1116*0b57cec5SDimitry Andric break; 1117*0b57cec5SDimitry Andric default: 11189dba64beSDimitry Andric LLDB_LOGF(log, 1119*0b57cec5SDimitry Andric "ObjectFileELF::%s unrecognized OS in note, id %" PRIu32 1120*0b57cec5SDimitry Andric ", min version %" PRIu32 ".%" PRIu32 ".%" PRIu32, 1121*0b57cec5SDimitry Andric __FUNCTION__, version_info[0], version_info[1], 1122*0b57cec5SDimitry Andric version_info[2], version_info[3]); 1123*0b57cec5SDimitry Andric break; 1124*0b57cec5SDimitry Andric } 1125*0b57cec5SDimitry Andric } 1126*0b57cec5SDimitry Andric break; 1127*0b57cec5SDimitry Andric 1128*0b57cec5SDimitry Andric case LLDB_NT_GNU_BUILD_ID_TAG: 1129*0b57cec5SDimitry Andric // Only bother processing this if we don't already have the uuid set. 1130*0b57cec5SDimitry Andric if (!uuid.IsValid()) { 1131*0b57cec5SDimitry Andric // 16 bytes is UUID|MD5, 20 bytes is SHA1. Other linkers may produce a 1132*0b57cec5SDimitry Andric // build-id of a different length. Accept it as long as it's at least 1133*0b57cec5SDimitry Andric // 4 bytes as it will be better than our own crc32. 1134*0b57cec5SDimitry Andric if (note.n_descsz >= 4) { 1135*0b57cec5SDimitry Andric if (const uint8_t *buf = data.PeekData(offset, note.n_descsz)) { 1136*0b57cec5SDimitry Andric // Save the build id as the UUID for the module. 1137*0b57cec5SDimitry Andric uuid = UUID::fromData(buf, note.n_descsz); 1138*0b57cec5SDimitry Andric } else { 1139*0b57cec5SDimitry Andric error.SetErrorString("failed to read GNU_BUILD_ID note payload"); 1140*0b57cec5SDimitry Andric return error; 1141*0b57cec5SDimitry Andric } 1142*0b57cec5SDimitry Andric } 1143*0b57cec5SDimitry Andric } 1144*0b57cec5SDimitry Andric break; 1145*0b57cec5SDimitry Andric } 1146*0b57cec5SDimitry Andric if (arch_spec.IsMIPS() && 1147*0b57cec5SDimitry Andric arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) 1148*0b57cec5SDimitry Andric // The note.n_name == LLDB_NT_OWNER_GNU is valid for Linux platform 1149*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); 1150*0b57cec5SDimitry Andric } 1151*0b57cec5SDimitry Andric // Process NetBSD ELF executables and shared libraries 1152*0b57cec5SDimitry Andric else if ((note.n_name == LLDB_NT_OWNER_NETBSD) && 1153*0b57cec5SDimitry Andric (note.n_type == LLDB_NT_NETBSD_IDENT_TAG) && 1154*0b57cec5SDimitry Andric (note.n_descsz == LLDB_NT_NETBSD_IDENT_DESCSZ) && 1155*0b57cec5SDimitry Andric (note.n_namesz == LLDB_NT_NETBSD_IDENT_NAMESZ)) { 1156*0b57cec5SDimitry Andric // Pull out the version info. 1157*0b57cec5SDimitry Andric uint32_t version_info; 1158*0b57cec5SDimitry Andric if (data.GetU32(&offset, &version_info, 1) == nullptr) { 1159*0b57cec5SDimitry Andric error.SetErrorString("failed to read NetBSD ABI note payload"); 1160*0b57cec5SDimitry Andric return error; 1161*0b57cec5SDimitry Andric } 1162*0b57cec5SDimitry Andric // Convert the version info into a major/minor/patch number. 1163*0b57cec5SDimitry Andric // #define __NetBSD_Version__ MMmmrrpp00 1164*0b57cec5SDimitry Andric // 1165*0b57cec5SDimitry Andric // M = major version 1166*0b57cec5SDimitry Andric // m = minor version; a minor number of 99 indicates current. 1167*0b57cec5SDimitry Andric // r = 0 (since NetBSD 3.0 not used) 1168*0b57cec5SDimitry Andric // p = patchlevel 1169*0b57cec5SDimitry Andric const uint32_t version_major = version_info / 100000000; 1170*0b57cec5SDimitry Andric const uint32_t version_minor = (version_info % 100000000) / 1000000; 1171*0b57cec5SDimitry Andric const uint32_t version_patch = (version_info % 10000) / 100; 1172*0b57cec5SDimitry Andric // Set the elf OS version to NetBSD. Also clear the vendor. 1173*0b57cec5SDimitry Andric arch_spec.GetTriple().setOSName( 1174*0b57cec5SDimitry Andric llvm::formatv("netbsd{0}.{1}.{2}", version_major, version_minor, 1175*0b57cec5SDimitry Andric version_patch).str()); 1176*0b57cec5SDimitry Andric arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); 1177*0b57cec5SDimitry Andric } 1178*0b57cec5SDimitry Andric // Process NetBSD ELF core(5) notes 1179*0b57cec5SDimitry Andric else if ((note.n_name == LLDB_NT_OWNER_NETBSDCORE) && 1180*0b57cec5SDimitry Andric (note.n_type == LLDB_NT_NETBSD_PROCINFO)) { 1181*0b57cec5SDimitry Andric // Set the elf OS version to NetBSD. Also clear the vendor. 1182*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::NetBSD); 1183*0b57cec5SDimitry Andric arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); 1184*0b57cec5SDimitry Andric } 1185*0b57cec5SDimitry Andric // Process OpenBSD ELF notes. 1186*0b57cec5SDimitry Andric else if (note.n_name == LLDB_NT_OWNER_OPENBSD) { 1187*0b57cec5SDimitry Andric // Set the elf OS version to OpenBSD. Also clear the vendor. 1188*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::OpenBSD); 1189*0b57cec5SDimitry Andric arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); 1190*0b57cec5SDimitry Andric } else if (note.n_name == LLDB_NT_OWNER_ANDROID) { 1191*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); 1192*0b57cec5SDimitry Andric arch_spec.GetTriple().setEnvironment( 1193*0b57cec5SDimitry Andric llvm::Triple::EnvironmentType::Android); 1194*0b57cec5SDimitry Andric } else if (note.n_name == LLDB_NT_OWNER_LINUX) { 1195*0b57cec5SDimitry Andric // This is sometimes found in core files and usually contains extended 1196*0b57cec5SDimitry Andric // register info 1197*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); 1198*0b57cec5SDimitry Andric } else if (note.n_name == LLDB_NT_OWNER_CORE) { 119981ad6265SDimitry Andric // Parse the NT_FILE to look for stuff in paths to shared libraries 120081ad6265SDimitry Andric // The contents look like this in a 64 bit ELF core file: 120181ad6265SDimitry Andric // 120281ad6265SDimitry Andric // count = 0x000000000000000a (10) 120381ad6265SDimitry Andric // page_size = 0x0000000000001000 (4096) 120481ad6265SDimitry Andric // Index start end file_ofs path 120581ad6265SDimitry Andric // ===== ------------------ ------------------ ------------------ ------------------------------------- 120681ad6265SDimitry Andric // [ 0] 0x0000000000401000 0x0000000000000000 /tmp/a.out 120781ad6265SDimitry Andric // [ 1] 0x0000000000600000 0x0000000000601000 0x0000000000000000 /tmp/a.out 120881ad6265SDimitry Andric // [ 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 /tmp/a.out 120981ad6265SDimitry Andric // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000 /lib/x86_64-linux-gnu/libc-2.19.so 121081ad6265SDimitry Andric // [ 4] 0x00007fa79cba8000 0x00007fa79cda7000 0x00000000000001bb /lib/x86_64-linux-gnu/libc-2.19.so 121181ad6265SDimitry Andric // [ 5] 0x00007fa79cda7000 0x00007fa79cdab000 0x00000000000001ba /lib/x86_64-linux-gnu/libc-2.19.so 121281ad6265SDimitry Andric // [ 6] 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be /lib/x86_64-linux-gnu/libc-2.19.so 121381ad6265SDimitry Andric // [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000 0x0000000000000000 /lib/x86_64-linux-gnu/ld-2.19.so 121481ad6265SDimitry Andric // [ 8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 /lib/x86_64-linux-gnu/ld-2.19.so 121581ad6265SDimitry Andric // [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000 0x0000000000000023 /lib/x86_64-linux-gnu/ld-2.19.so 121681ad6265SDimitry Andric // 121781ad6265SDimitry Andric // In the 32 bit ELFs the count, page_size, start, end, file_ofs are 121881ad6265SDimitry Andric // uint32_t. 121981ad6265SDimitry Andric // 122081ad6265SDimitry Andric // For reference: see readelf source code (in binutils). 1221*0b57cec5SDimitry Andric if (note.n_type == NT_FILE) { 1222*0b57cec5SDimitry Andric uint64_t count = data.GetAddress(&offset); 1223*0b57cec5SDimitry Andric const char *cstr; 1224*0b57cec5SDimitry Andric data.GetAddress(&offset); // Skip page size 1225*0b57cec5SDimitry Andric offset += count * 3 * 1226*0b57cec5SDimitry Andric data.GetAddressByteSize(); // Skip all start/end/file_ofs 1227*0b57cec5SDimitry Andric for (size_t i = 0; i < count; ++i) { 1228*0b57cec5SDimitry Andric cstr = data.GetCStr(&offset); 1229*0b57cec5SDimitry Andric if (cstr == nullptr) { 1230*0b57cec5SDimitry Andric error.SetErrorStringWithFormat("ObjectFileELF::%s trying to read " 1231*0b57cec5SDimitry Andric "at an offset after the end " 1232*0b57cec5SDimitry Andric "(GetCStr returned nullptr)", 1233*0b57cec5SDimitry Andric __FUNCTION__); 1234*0b57cec5SDimitry Andric return error; 1235*0b57cec5SDimitry Andric } 1236*0b57cec5SDimitry Andric llvm::StringRef path(cstr); 1237*0b57cec5SDimitry Andric if (path.contains("/lib/x86_64-linux-gnu") || path.contains("/lib/i386-linux-gnu")) { 1238*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); 1239*0b57cec5SDimitry Andric break; 1240*0b57cec5SDimitry Andric } 1241*0b57cec5SDimitry Andric } 1242*0b57cec5SDimitry Andric if (arch_spec.IsMIPS() && 1243*0b57cec5SDimitry Andric arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) 1244*0b57cec5SDimitry Andric // In case of MIPSR6, the LLDB_NT_OWNER_GNU note is missing for some 1245*0b57cec5SDimitry Andric // cases (e.g. compile with -nostdlib) Hence set OS to Linux 1246*0b57cec5SDimitry Andric arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); 1247*0b57cec5SDimitry Andric } 1248*0b57cec5SDimitry Andric } 1249*0b57cec5SDimitry Andric 1250*0b57cec5SDimitry Andric // Calculate the offset of the next note just in case "offset" has been 1251*0b57cec5SDimitry Andric // used to poke at the contents of the note data 1252*0b57cec5SDimitry Andric offset = note_offset + note.GetByteSize(); 1253*0b57cec5SDimitry Andric } 1254*0b57cec5SDimitry Andric 1255*0b57cec5SDimitry Andric return error; 1256*0b57cec5SDimitry Andric } 1257*0b57cec5SDimitry Andric 1258*0b57cec5SDimitry Andric void ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length, 1259*0b57cec5SDimitry Andric ArchSpec &arch_spec) { 1260*0b57cec5SDimitry Andric lldb::offset_t Offset = 0; 1261*0b57cec5SDimitry Andric 1262*0b57cec5SDimitry Andric uint8_t FormatVersion = data.GetU8(&Offset); 12635ffd83dbSDimitry Andric if (FormatVersion != llvm::ELFAttrs::Format_Version) 1264*0b57cec5SDimitry Andric return; 1265*0b57cec5SDimitry Andric 1266*0b57cec5SDimitry Andric Offset = Offset + sizeof(uint32_t); // Section Length 1267*0b57cec5SDimitry Andric llvm::StringRef VendorName = data.GetCStr(&Offset); 1268*0b57cec5SDimitry Andric 1269*0b57cec5SDimitry Andric if (VendorName != "aeabi") 1270*0b57cec5SDimitry Andric return; 1271*0b57cec5SDimitry Andric 1272*0b57cec5SDimitry Andric if (arch_spec.GetTriple().getEnvironment() == 1273*0b57cec5SDimitry Andric llvm::Triple::UnknownEnvironment) 1274*0b57cec5SDimitry Andric arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI); 1275*0b57cec5SDimitry Andric 1276*0b57cec5SDimitry Andric while (Offset < length) { 1277*0b57cec5SDimitry Andric uint8_t Tag = data.GetU8(&Offset); 1278*0b57cec5SDimitry Andric uint32_t Size = data.GetU32(&Offset); 1279*0b57cec5SDimitry Andric 1280*0b57cec5SDimitry Andric if (Tag != llvm::ARMBuildAttrs::File || Size == 0) 1281*0b57cec5SDimitry Andric continue; 1282*0b57cec5SDimitry Andric 1283*0b57cec5SDimitry Andric while (Offset < length) { 1284*0b57cec5SDimitry Andric uint64_t Tag = data.GetULEB128(&Offset); 1285*0b57cec5SDimitry Andric switch (Tag) { 1286*0b57cec5SDimitry Andric default: 1287*0b57cec5SDimitry Andric if (Tag < 32) 1288*0b57cec5SDimitry Andric data.GetULEB128(&Offset); 1289*0b57cec5SDimitry Andric else if (Tag % 2 == 0) 1290*0b57cec5SDimitry Andric data.GetULEB128(&Offset); 1291*0b57cec5SDimitry Andric else 1292*0b57cec5SDimitry Andric data.GetCStr(&Offset); 1293*0b57cec5SDimitry Andric 1294*0b57cec5SDimitry Andric break; 1295*0b57cec5SDimitry Andric 1296*0b57cec5SDimitry Andric case llvm::ARMBuildAttrs::CPU_raw_name: 1297*0b57cec5SDimitry Andric case llvm::ARMBuildAttrs::CPU_name: 1298*0b57cec5SDimitry Andric data.GetCStr(&Offset); 1299*0b57cec5SDimitry Andric 1300*0b57cec5SDimitry Andric break; 1301*0b57cec5SDimitry Andric 1302*0b57cec5SDimitry Andric case llvm::ARMBuildAttrs::ABI_VFP_args: { 1303*0b57cec5SDimitry Andric uint64_t VFPArgs = data.GetULEB128(&Offset); 1304*0b57cec5SDimitry Andric 1305*0b57cec5SDimitry Andric if (VFPArgs == llvm::ARMBuildAttrs::BaseAAPCS) { 1306*0b57cec5SDimitry Andric if (arch_spec.GetTriple().getEnvironment() == 1307*0b57cec5SDimitry Andric llvm::Triple::UnknownEnvironment || 1308*0b57cec5SDimitry Andric arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABIHF) 1309*0b57cec5SDimitry Andric arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI); 1310*0b57cec5SDimitry Andric 1311*0b57cec5SDimitry Andric arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float); 1312*0b57cec5SDimitry Andric } else if (VFPArgs == llvm::ARMBuildAttrs::HardFPAAPCS) { 1313*0b57cec5SDimitry Andric if (arch_spec.GetTriple().getEnvironment() == 1314*0b57cec5SDimitry Andric llvm::Triple::UnknownEnvironment || 1315*0b57cec5SDimitry Andric arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABI) 1316*0b57cec5SDimitry Andric arch_spec.GetTriple().setEnvironment(llvm::Triple::EABIHF); 1317*0b57cec5SDimitry Andric 1318*0b57cec5SDimitry Andric arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float); 1319*0b57cec5SDimitry Andric } 1320*0b57cec5SDimitry Andric 1321*0b57cec5SDimitry Andric break; 1322*0b57cec5SDimitry Andric } 1323*0b57cec5SDimitry Andric } 1324*0b57cec5SDimitry Andric } 1325*0b57cec5SDimitry Andric } 1326*0b57cec5SDimitry Andric } 1327*0b57cec5SDimitry Andric 1328*0b57cec5SDimitry Andric // GetSectionHeaderInfo 1329*0b57cec5SDimitry Andric size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, 1330*0b57cec5SDimitry Andric DataExtractor &object_data, 1331*0b57cec5SDimitry Andric const elf::ELFHeader &header, 1332*0b57cec5SDimitry Andric lldb_private::UUID &uuid, 1333*0b57cec5SDimitry Andric std::string &gnu_debuglink_file, 1334*0b57cec5SDimitry Andric uint32_t &gnu_debuglink_crc, 1335*0b57cec5SDimitry Andric ArchSpec &arch_spec) { 1336*0b57cec5SDimitry Andric // Don't reparse the section headers if we already did that. 1337*0b57cec5SDimitry Andric if (!section_headers.empty()) 1338*0b57cec5SDimitry Andric return section_headers.size(); 1339*0b57cec5SDimitry Andric 1340*0b57cec5SDimitry Andric // Only initialize the arch_spec to okay defaults if they're not already set. 1341*0b57cec5SDimitry Andric // We'll refine this with note data as we parse the notes. 1342*0b57cec5SDimitry Andric if (arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) { 1343*0b57cec5SDimitry Andric llvm::Triple::OSType ostype; 1344*0b57cec5SDimitry Andric llvm::Triple::OSType spec_ostype; 1345*0b57cec5SDimitry Andric const uint32_t sub_type = subTypeFromElfHeader(header); 1346*0b57cec5SDimitry Andric arch_spec.SetArchitecture(eArchTypeELF, header.e_machine, sub_type, 1347*0b57cec5SDimitry Andric header.e_ident[EI_OSABI]); 1348*0b57cec5SDimitry Andric 1349*0b57cec5SDimitry Andric // Validate if it is ok to remove GetOsFromOSABI. Note, that now the OS is 1350*0b57cec5SDimitry Andric // determined based on EI_OSABI flag and the info extracted from ELF notes 1351*0b57cec5SDimitry Andric // (see RefineModuleDetailsFromNote). However in some cases that still 1352*0b57cec5SDimitry Andric // might be not enough: for example a shared library might not have any 1353*0b57cec5SDimitry Andric // notes at all and have EI_OSABI flag set to System V, as result the OS 1354*0b57cec5SDimitry Andric // will be set to UnknownOS. 1355*0b57cec5SDimitry Andric GetOsFromOSABI(header.e_ident[EI_OSABI], ostype); 1356*0b57cec5SDimitry Andric spec_ostype = arch_spec.GetTriple().getOS(); 1357*0b57cec5SDimitry Andric assert(spec_ostype == ostype); 1358*0b57cec5SDimitry Andric UNUSED_IF_ASSERT_DISABLED(spec_ostype); 1359*0b57cec5SDimitry Andric } 1360*0b57cec5SDimitry Andric 1361*0b57cec5SDimitry Andric if (arch_spec.GetMachine() == llvm::Triple::mips || 1362*0b57cec5SDimitry Andric arch_spec.GetMachine() == llvm::Triple::mipsel || 1363*0b57cec5SDimitry Andric arch_spec.GetMachine() == llvm::Triple::mips64 || 1364*0b57cec5SDimitry Andric arch_spec.GetMachine() == llvm::Triple::mips64el) { 1365*0b57cec5SDimitry Andric switch (header.e_flags & llvm::ELF::EF_MIPS_ARCH_ASE) { 1366*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_MICROMIPS: 1367*0b57cec5SDimitry Andric arch_spec.SetFlags(ArchSpec::eMIPSAse_micromips); 1368*0b57cec5SDimitry Andric break; 1369*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_ASE_M16: 1370*0b57cec5SDimitry Andric arch_spec.SetFlags(ArchSpec::eMIPSAse_mips16); 1371*0b57cec5SDimitry Andric break; 1372*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ARCH_ASE_MDMX: 1373*0b57cec5SDimitry Andric arch_spec.SetFlags(ArchSpec::eMIPSAse_mdmx); 1374*0b57cec5SDimitry Andric break; 1375*0b57cec5SDimitry Andric default: 1376*0b57cec5SDimitry Andric break; 1377*0b57cec5SDimitry Andric } 1378*0b57cec5SDimitry Andric } 1379*0b57cec5SDimitry Andric 1380*0b57cec5SDimitry Andric if (arch_spec.GetMachine() == llvm::Triple::arm || 1381*0b57cec5SDimitry Andric arch_spec.GetMachine() == llvm::Triple::thumb) { 1382*0b57cec5SDimitry Andric if (header.e_flags & llvm::ELF::EF_ARM_SOFT_FLOAT) 1383*0b57cec5SDimitry Andric arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float); 1384*0b57cec5SDimitry Andric else if (header.e_flags & llvm::ELF::EF_ARM_VFP_FLOAT) 1385*0b57cec5SDimitry Andric arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float); 1386*0b57cec5SDimitry Andric } 1387*0b57cec5SDimitry Andric 138881ad6265SDimitry Andric if (arch_spec.GetMachine() == llvm::Triple::riscv32 || 138981ad6265SDimitry Andric arch_spec.GetMachine() == llvm::Triple::riscv64) { 139081ad6265SDimitry Andric uint32_t flags = arch_spec.GetFlags(); 139181ad6265SDimitry Andric 139281ad6265SDimitry Andric if (header.e_flags & llvm::ELF::EF_RISCV_RVC) 139381ad6265SDimitry Andric flags |= ArchSpec::eRISCV_rvc; 139481ad6265SDimitry Andric if (header.e_flags & llvm::ELF::EF_RISCV_RVE) 139581ad6265SDimitry Andric flags |= ArchSpec::eRISCV_rve; 139681ad6265SDimitry Andric 139781ad6265SDimitry Andric if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE) == 139881ad6265SDimitry Andric llvm::ELF::EF_RISCV_FLOAT_ABI_SINGLE) 139981ad6265SDimitry Andric flags |= ArchSpec::eRISCV_float_abi_single; 140081ad6265SDimitry Andric else if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE) == 140181ad6265SDimitry Andric llvm::ELF::EF_RISCV_FLOAT_ABI_DOUBLE) 140281ad6265SDimitry Andric flags |= ArchSpec::eRISCV_float_abi_double; 140381ad6265SDimitry Andric else if ((header.e_flags & llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD) == 140481ad6265SDimitry Andric llvm::ELF::EF_RISCV_FLOAT_ABI_QUAD) 140581ad6265SDimitry Andric flags |= ArchSpec::eRISCV_float_abi_quad; 140681ad6265SDimitry Andric 140781ad6265SDimitry Andric arch_spec.SetFlags(flags); 140881ad6265SDimitry Andric } 140981ad6265SDimitry Andric 1410*0b57cec5SDimitry Andric // If there are no section headers we are done. 1411*0b57cec5SDimitry Andric if (header.e_shnum == 0) 1412*0b57cec5SDimitry Andric return 0; 1413*0b57cec5SDimitry Andric 141481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Modules); 1415*0b57cec5SDimitry Andric 1416*0b57cec5SDimitry Andric section_headers.resize(header.e_shnum); 1417*0b57cec5SDimitry Andric if (section_headers.size() != header.e_shnum) 1418*0b57cec5SDimitry Andric return 0; 1419*0b57cec5SDimitry Andric 1420*0b57cec5SDimitry Andric const size_t sh_size = header.e_shnum * header.e_shentsize; 1421*0b57cec5SDimitry Andric const elf_off sh_offset = header.e_shoff; 1422*0b57cec5SDimitry Andric DataExtractor sh_data; 1423*0b57cec5SDimitry Andric if (sh_data.SetData(object_data, sh_offset, sh_size) != sh_size) 1424*0b57cec5SDimitry Andric return 0; 1425*0b57cec5SDimitry Andric 1426*0b57cec5SDimitry Andric uint32_t idx; 1427*0b57cec5SDimitry Andric lldb::offset_t offset; 1428*0b57cec5SDimitry Andric for (idx = 0, offset = 0; idx < header.e_shnum; ++idx) { 1429*0b57cec5SDimitry Andric if (!section_headers[idx].Parse(sh_data, &offset)) 1430*0b57cec5SDimitry Andric break; 1431*0b57cec5SDimitry Andric } 1432*0b57cec5SDimitry Andric if (idx < section_headers.size()) 1433*0b57cec5SDimitry Andric section_headers.resize(idx); 1434*0b57cec5SDimitry Andric 1435*0b57cec5SDimitry Andric const unsigned strtab_idx = header.e_shstrndx; 1436*0b57cec5SDimitry Andric if (strtab_idx && strtab_idx < section_headers.size()) { 1437*0b57cec5SDimitry Andric const ELFSectionHeaderInfo &sheader = section_headers[strtab_idx]; 1438*0b57cec5SDimitry Andric const size_t byte_size = sheader.sh_size; 1439*0b57cec5SDimitry Andric const Elf64_Off offset = sheader.sh_offset; 1440*0b57cec5SDimitry Andric lldb_private::DataExtractor shstr_data; 1441*0b57cec5SDimitry Andric 1442*0b57cec5SDimitry Andric if (shstr_data.SetData(object_data, offset, byte_size) == byte_size) { 1443*0b57cec5SDimitry Andric for (SectionHeaderCollIter I = section_headers.begin(); 1444*0b57cec5SDimitry Andric I != section_headers.end(); ++I) { 1445*0b57cec5SDimitry Andric static ConstString g_sect_name_gnu_debuglink(".gnu_debuglink"); 1446*0b57cec5SDimitry Andric const ELFSectionHeaderInfo &sheader = *I; 1447*0b57cec5SDimitry Andric const uint64_t section_size = 1448*0b57cec5SDimitry Andric sheader.sh_type == SHT_NOBITS ? 0 : sheader.sh_size; 1449*0b57cec5SDimitry Andric ConstString name(shstr_data.PeekCStr(I->sh_name)); 1450*0b57cec5SDimitry Andric 1451*0b57cec5SDimitry Andric I->section_name = name; 1452*0b57cec5SDimitry Andric 1453*0b57cec5SDimitry Andric if (arch_spec.IsMIPS()) { 1454*0b57cec5SDimitry Andric uint32_t arch_flags = arch_spec.GetFlags(); 1455*0b57cec5SDimitry Andric DataExtractor data; 1456*0b57cec5SDimitry Andric if (sheader.sh_type == SHT_MIPS_ABIFLAGS) { 1457*0b57cec5SDimitry Andric 1458*0b57cec5SDimitry Andric if (section_size && (data.SetData(object_data, sheader.sh_offset, 1459*0b57cec5SDimitry Andric section_size) == section_size)) { 1460*0b57cec5SDimitry Andric // MIPS ASE Mask is at offset 12 in MIPS.abiflags section 1461*0b57cec5SDimitry Andric lldb::offset_t offset = 12; // MIPS ABI Flags Version: 0 1462*0b57cec5SDimitry Andric arch_flags |= data.GetU32(&offset); 1463*0b57cec5SDimitry Andric 1464*0b57cec5SDimitry Andric // The floating point ABI is at offset 7 1465*0b57cec5SDimitry Andric offset = 7; 1466*0b57cec5SDimitry Andric switch (data.GetU8(&offset)) { 1467*0b57cec5SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_ANY: 1468*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_ANY; 1469*0b57cec5SDimitry Andric break; 1470*0b57cec5SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_DOUBLE: 1471*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_DOUBLE; 1472*0b57cec5SDimitry Andric break; 1473*0b57cec5SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_SINGLE: 1474*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SINGLE; 1475*0b57cec5SDimitry Andric break; 1476*0b57cec5SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_SOFT: 1477*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT; 1478*0b57cec5SDimitry Andric break; 1479*0b57cec5SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_OLD_64: 1480*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_OLD_64; 1481*0b57cec5SDimitry Andric break; 1482*0b57cec5SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_XX: 1483*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_XX; 1484*0b57cec5SDimitry Andric break; 1485*0b57cec5SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_64: 1486*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64; 1487*0b57cec5SDimitry Andric break; 1488*0b57cec5SDimitry Andric case llvm::Mips::Val_GNU_MIPS_ABI_FP_64A: 1489*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64A; 1490*0b57cec5SDimitry Andric break; 1491*0b57cec5SDimitry Andric } 1492*0b57cec5SDimitry Andric } 1493*0b57cec5SDimitry Andric } 1494*0b57cec5SDimitry Andric // Settings appropriate ArchSpec ABI Flags 1495*0b57cec5SDimitry Andric switch (header.e_flags & llvm::ELF::EF_MIPS_ABI) { 1496*0b57cec5SDimitry Andric case llvm::ELF::EF_MIPS_ABI_O32: 1497*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_O32; 1498*0b57cec5SDimitry Andric break; 1499*0b57cec5SDimitry Andric case EF_MIPS_ABI_O64: 1500*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_O64; 1501*0b57cec5SDimitry Andric break; 1502*0b57cec5SDimitry Andric case EF_MIPS_ABI_EABI32: 1503*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI32; 1504*0b57cec5SDimitry Andric break; 1505*0b57cec5SDimitry Andric case EF_MIPS_ABI_EABI64: 1506*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI64; 1507*0b57cec5SDimitry Andric break; 1508*0b57cec5SDimitry Andric default: 1509*0b57cec5SDimitry Andric // ABI Mask doesn't cover N32 and N64 ABI. 1510*0b57cec5SDimitry Andric if (header.e_ident[EI_CLASS] == llvm::ELF::ELFCLASS64) 1511*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_N64; 1512*0b57cec5SDimitry Andric else if (header.e_flags & llvm::ELF::EF_MIPS_ABI2) 1513*0b57cec5SDimitry Andric arch_flags |= lldb_private::ArchSpec::eMIPSABI_N32; 1514*0b57cec5SDimitry Andric break; 1515*0b57cec5SDimitry Andric } 1516*0b57cec5SDimitry Andric arch_spec.SetFlags(arch_flags); 1517*0b57cec5SDimitry Andric } 1518*0b57cec5SDimitry Andric 1519*0b57cec5SDimitry Andric if (arch_spec.GetMachine() == llvm::Triple::arm || 1520*0b57cec5SDimitry Andric arch_spec.GetMachine() == llvm::Triple::thumb) { 1521*0b57cec5SDimitry Andric DataExtractor data; 1522*0b57cec5SDimitry Andric 1523*0b57cec5SDimitry Andric if (sheader.sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 && 1524*0b57cec5SDimitry Andric data.SetData(object_data, sheader.sh_offset, section_size) == section_size) 1525*0b57cec5SDimitry Andric ParseARMAttributes(data, section_size, arch_spec); 1526*0b57cec5SDimitry Andric } 1527*0b57cec5SDimitry Andric 1528*0b57cec5SDimitry Andric if (name == g_sect_name_gnu_debuglink) { 1529*0b57cec5SDimitry Andric DataExtractor data; 1530*0b57cec5SDimitry Andric if (section_size && (data.SetData(object_data, sheader.sh_offset, 1531*0b57cec5SDimitry Andric section_size) == section_size)) { 1532*0b57cec5SDimitry Andric lldb::offset_t gnu_debuglink_offset = 0; 1533*0b57cec5SDimitry Andric gnu_debuglink_file = data.GetCStr(&gnu_debuglink_offset); 1534*0b57cec5SDimitry Andric gnu_debuglink_offset = llvm::alignTo(gnu_debuglink_offset, 4); 1535*0b57cec5SDimitry Andric data.GetU32(&gnu_debuglink_offset, &gnu_debuglink_crc, 1); 1536*0b57cec5SDimitry Andric } 1537*0b57cec5SDimitry Andric } 1538*0b57cec5SDimitry Andric 1539*0b57cec5SDimitry Andric // Process ELF note section entries. 1540*0b57cec5SDimitry Andric bool is_note_header = (sheader.sh_type == SHT_NOTE); 1541*0b57cec5SDimitry Andric 1542*0b57cec5SDimitry Andric // The section header ".note.android.ident" is stored as a 1543*0b57cec5SDimitry Andric // PROGBITS type header but it is actually a note header. 1544*0b57cec5SDimitry Andric static ConstString g_sect_name_android_ident(".note.android.ident"); 1545*0b57cec5SDimitry Andric if (!is_note_header && name == g_sect_name_android_ident) 1546*0b57cec5SDimitry Andric is_note_header = true; 1547*0b57cec5SDimitry Andric 1548*0b57cec5SDimitry Andric if (is_note_header) { 1549*0b57cec5SDimitry Andric // Allow notes to refine module info. 1550*0b57cec5SDimitry Andric DataExtractor data; 1551*0b57cec5SDimitry Andric if (section_size && (data.SetData(object_data, sheader.sh_offset, 1552*0b57cec5SDimitry Andric section_size) == section_size)) { 1553*0b57cec5SDimitry Andric Status error = RefineModuleDetailsFromNote(data, arch_spec, uuid); 1554*0b57cec5SDimitry Andric if (error.Fail()) { 15559dba64beSDimitry Andric LLDB_LOGF(log, "ObjectFileELF::%s ELF note processing failed: %s", 1556*0b57cec5SDimitry Andric __FUNCTION__, error.AsCString()); 1557*0b57cec5SDimitry Andric } 1558*0b57cec5SDimitry Andric } 1559*0b57cec5SDimitry Andric } 1560*0b57cec5SDimitry Andric } 1561*0b57cec5SDimitry Andric 1562*0b57cec5SDimitry Andric // Make any unknown triple components to be unspecified unknowns. 1563*0b57cec5SDimitry Andric if (arch_spec.GetTriple().getVendor() == llvm::Triple::UnknownVendor) 1564*0b57cec5SDimitry Andric arch_spec.GetTriple().setVendorName(llvm::StringRef()); 1565*0b57cec5SDimitry Andric if (arch_spec.GetTriple().getOS() == llvm::Triple::UnknownOS) 1566*0b57cec5SDimitry Andric arch_spec.GetTriple().setOSName(llvm::StringRef()); 1567*0b57cec5SDimitry Andric 1568*0b57cec5SDimitry Andric return section_headers.size(); 1569*0b57cec5SDimitry Andric } 1570*0b57cec5SDimitry Andric } 1571*0b57cec5SDimitry Andric 1572*0b57cec5SDimitry Andric section_headers.clear(); 1573*0b57cec5SDimitry Andric return 0; 1574*0b57cec5SDimitry Andric } 1575*0b57cec5SDimitry Andric 1576*0b57cec5SDimitry Andric llvm::StringRef 1577*0b57cec5SDimitry Andric ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const { 1578*0b57cec5SDimitry Andric size_t pos = symbol_name.find('@'); 1579*0b57cec5SDimitry Andric return symbol_name.substr(0, pos); 1580*0b57cec5SDimitry Andric } 1581*0b57cec5SDimitry Andric 1582*0b57cec5SDimitry Andric // ParseSectionHeaders 1583*0b57cec5SDimitry Andric size_t ObjectFileELF::ParseSectionHeaders() { 1584*0b57cec5SDimitry Andric return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, 1585*0b57cec5SDimitry Andric m_gnu_debuglink_file, m_gnu_debuglink_crc, 1586*0b57cec5SDimitry Andric m_arch_spec); 1587*0b57cec5SDimitry Andric } 1588*0b57cec5SDimitry Andric 1589*0b57cec5SDimitry Andric const ObjectFileELF::ELFSectionHeaderInfo * 1590*0b57cec5SDimitry Andric ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) { 1591*0b57cec5SDimitry Andric if (!ParseSectionHeaders()) 1592*0b57cec5SDimitry Andric return nullptr; 1593*0b57cec5SDimitry Andric 1594*0b57cec5SDimitry Andric if (id < m_section_headers.size()) 1595*0b57cec5SDimitry Andric return &m_section_headers[id]; 1596*0b57cec5SDimitry Andric 1597*0b57cec5SDimitry Andric return nullptr; 1598*0b57cec5SDimitry Andric } 1599*0b57cec5SDimitry Andric 1600*0b57cec5SDimitry Andric lldb::user_id_t ObjectFileELF::GetSectionIndexByName(const char *name) { 1601*0b57cec5SDimitry Andric if (!name || !name[0] || !ParseSectionHeaders()) 1602*0b57cec5SDimitry Andric return 0; 1603*0b57cec5SDimitry Andric for (size_t i = 1; i < m_section_headers.size(); ++i) 1604*0b57cec5SDimitry Andric if (m_section_headers[i].section_name == ConstString(name)) 1605*0b57cec5SDimitry Andric return i; 1606*0b57cec5SDimitry Andric return 0; 1607*0b57cec5SDimitry Andric } 1608*0b57cec5SDimitry Andric 1609*0b57cec5SDimitry Andric static SectionType GetSectionTypeFromName(llvm::StringRef Name) { 1610fcaf7f86SDimitry Andric if (Name.consume_front(".debug_")) { 1611*0b57cec5SDimitry Andric return llvm::StringSwitch<SectionType>(Name) 1612*0b57cec5SDimitry Andric .Case("abbrev", eSectionTypeDWARFDebugAbbrev) 1613*0b57cec5SDimitry Andric .Case("abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo) 1614*0b57cec5SDimitry Andric .Case("addr", eSectionTypeDWARFDebugAddr) 1615*0b57cec5SDimitry Andric .Case("aranges", eSectionTypeDWARFDebugAranges) 1616*0b57cec5SDimitry Andric .Case("cu_index", eSectionTypeDWARFDebugCuIndex) 1617*0b57cec5SDimitry Andric .Case("frame", eSectionTypeDWARFDebugFrame) 1618*0b57cec5SDimitry Andric .Case("info", eSectionTypeDWARFDebugInfo) 1619*0b57cec5SDimitry Andric .Case("info.dwo", eSectionTypeDWARFDebugInfoDwo) 1620*0b57cec5SDimitry Andric .Cases("line", "line.dwo", eSectionTypeDWARFDebugLine) 1621*0b57cec5SDimitry Andric .Cases("line_str", "line_str.dwo", eSectionTypeDWARFDebugLineStr) 1622480093f4SDimitry Andric .Case("loc", eSectionTypeDWARFDebugLoc) 1623480093f4SDimitry Andric .Case("loc.dwo", eSectionTypeDWARFDebugLocDwo) 1624480093f4SDimitry Andric .Case("loclists", eSectionTypeDWARFDebugLocLists) 1625480093f4SDimitry Andric .Case("loclists.dwo", eSectionTypeDWARFDebugLocListsDwo) 1626*0b57cec5SDimitry Andric .Case("macinfo", eSectionTypeDWARFDebugMacInfo) 1627*0b57cec5SDimitry Andric .Cases("macro", "macro.dwo", eSectionTypeDWARFDebugMacro) 1628*0b57cec5SDimitry Andric .Case("names", eSectionTypeDWARFDebugNames) 1629*0b57cec5SDimitry Andric .Case("pubnames", eSectionTypeDWARFDebugPubNames) 1630*0b57cec5SDimitry Andric .Case("pubtypes", eSectionTypeDWARFDebugPubTypes) 1631*0b57cec5SDimitry Andric .Case("ranges", eSectionTypeDWARFDebugRanges) 1632*0b57cec5SDimitry Andric .Case("rnglists", eSectionTypeDWARFDebugRngLists) 1633480093f4SDimitry Andric .Case("rnglists.dwo", eSectionTypeDWARFDebugRngListsDwo) 1634*0b57cec5SDimitry Andric .Case("str", eSectionTypeDWARFDebugStr) 1635*0b57cec5SDimitry Andric .Case("str.dwo", eSectionTypeDWARFDebugStrDwo) 1636*0b57cec5SDimitry Andric .Case("str_offsets", eSectionTypeDWARFDebugStrOffsets) 1637*0b57cec5SDimitry Andric .Case("str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo) 16385ffd83dbSDimitry Andric .Case("tu_index", eSectionTypeDWARFDebugTuIndex) 1639*0b57cec5SDimitry Andric .Case("types", eSectionTypeDWARFDebugTypes) 1640*0b57cec5SDimitry Andric .Case("types.dwo", eSectionTypeDWARFDebugTypesDwo) 1641*0b57cec5SDimitry Andric .Default(eSectionTypeOther); 1642*0b57cec5SDimitry Andric } 1643*0b57cec5SDimitry Andric return llvm::StringSwitch<SectionType>(Name) 1644*0b57cec5SDimitry Andric .Case(".ARM.exidx", eSectionTypeARMexidx) 1645*0b57cec5SDimitry Andric .Case(".ARM.extab", eSectionTypeARMextab) 1646*0b57cec5SDimitry Andric .Cases(".bss", ".tbss", eSectionTypeZeroFill) 1647*0b57cec5SDimitry Andric .Cases(".data", ".tdata", eSectionTypeData) 1648*0b57cec5SDimitry Andric .Case(".eh_frame", eSectionTypeEHFrame) 1649*0b57cec5SDimitry Andric .Case(".gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink) 1650*0b57cec5SDimitry Andric .Case(".gosymtab", eSectionTypeGoSymtab) 1651*0b57cec5SDimitry Andric .Case(".text", eSectionTypeCode) 1652*0b57cec5SDimitry Andric .Default(eSectionTypeOther); 1653*0b57cec5SDimitry Andric } 1654*0b57cec5SDimitry Andric 1655*0b57cec5SDimitry Andric SectionType ObjectFileELF::GetSectionType(const ELFSectionHeaderInfo &H) const { 1656*0b57cec5SDimitry Andric switch (H.sh_type) { 1657*0b57cec5SDimitry Andric case SHT_PROGBITS: 1658*0b57cec5SDimitry Andric if (H.sh_flags & SHF_EXECINSTR) 1659*0b57cec5SDimitry Andric return eSectionTypeCode; 1660*0b57cec5SDimitry Andric break; 1661*0b57cec5SDimitry Andric case SHT_SYMTAB: 1662*0b57cec5SDimitry Andric return eSectionTypeELFSymbolTable; 1663*0b57cec5SDimitry Andric case SHT_DYNSYM: 1664*0b57cec5SDimitry Andric return eSectionTypeELFDynamicSymbols; 1665*0b57cec5SDimitry Andric case SHT_RELA: 1666*0b57cec5SDimitry Andric case SHT_REL: 1667*0b57cec5SDimitry Andric return eSectionTypeELFRelocationEntries; 1668*0b57cec5SDimitry Andric case SHT_DYNAMIC: 1669*0b57cec5SDimitry Andric return eSectionTypeELFDynamicLinkInfo; 1670*0b57cec5SDimitry Andric } 1671*0b57cec5SDimitry Andric return GetSectionTypeFromName(H.section_name.GetStringRef()); 1672*0b57cec5SDimitry Andric } 1673*0b57cec5SDimitry Andric 1674*0b57cec5SDimitry Andric static uint32_t GetTargetByteSize(SectionType Type, const ArchSpec &arch) { 1675*0b57cec5SDimitry Andric switch (Type) { 1676*0b57cec5SDimitry Andric case eSectionTypeData: 1677*0b57cec5SDimitry Andric case eSectionTypeZeroFill: 1678*0b57cec5SDimitry Andric return arch.GetDataByteSize(); 1679*0b57cec5SDimitry Andric case eSectionTypeCode: 1680*0b57cec5SDimitry Andric return arch.GetCodeByteSize(); 1681*0b57cec5SDimitry Andric default: 1682*0b57cec5SDimitry Andric return 1; 1683*0b57cec5SDimitry Andric } 1684*0b57cec5SDimitry Andric } 1685*0b57cec5SDimitry Andric 1686*0b57cec5SDimitry Andric static Permissions GetPermissions(const ELFSectionHeader &H) { 1687*0b57cec5SDimitry Andric Permissions Perm = Permissions(0); 1688*0b57cec5SDimitry Andric if (H.sh_flags & SHF_ALLOC) 1689*0b57cec5SDimitry Andric Perm |= ePermissionsReadable; 1690*0b57cec5SDimitry Andric if (H.sh_flags & SHF_WRITE) 1691*0b57cec5SDimitry Andric Perm |= ePermissionsWritable; 1692*0b57cec5SDimitry Andric if (H.sh_flags & SHF_EXECINSTR) 1693*0b57cec5SDimitry Andric Perm |= ePermissionsExecutable; 1694*0b57cec5SDimitry Andric return Perm; 1695*0b57cec5SDimitry Andric } 1696*0b57cec5SDimitry Andric 1697*0b57cec5SDimitry Andric static Permissions GetPermissions(const ELFProgramHeader &H) { 1698*0b57cec5SDimitry Andric Permissions Perm = Permissions(0); 1699*0b57cec5SDimitry Andric if (H.p_flags & PF_R) 1700*0b57cec5SDimitry Andric Perm |= ePermissionsReadable; 1701*0b57cec5SDimitry Andric if (H.p_flags & PF_W) 1702*0b57cec5SDimitry Andric Perm |= ePermissionsWritable; 1703*0b57cec5SDimitry Andric if (H.p_flags & PF_X) 1704*0b57cec5SDimitry Andric Perm |= ePermissionsExecutable; 1705*0b57cec5SDimitry Andric return Perm; 1706*0b57cec5SDimitry Andric } 1707*0b57cec5SDimitry Andric 1708*0b57cec5SDimitry Andric namespace { 1709*0b57cec5SDimitry Andric 1710*0b57cec5SDimitry Andric using VMRange = lldb_private::Range<addr_t, addr_t>; 1711*0b57cec5SDimitry Andric 1712*0b57cec5SDimitry Andric struct SectionAddressInfo { 1713*0b57cec5SDimitry Andric SectionSP Segment; 1714*0b57cec5SDimitry Andric VMRange Range; 1715*0b57cec5SDimitry Andric }; 1716*0b57cec5SDimitry Andric 1717*0b57cec5SDimitry Andric // (Unlinked) ELF object files usually have 0 for every section address, meaning 1718*0b57cec5SDimitry Andric // we need to compute synthetic addresses in order for "file addresses" from 1719*0b57cec5SDimitry Andric // different sections to not overlap. This class handles that logic. 1720*0b57cec5SDimitry Andric class VMAddressProvider { 1721*0b57cec5SDimitry Andric using VMMap = llvm::IntervalMap<addr_t, SectionSP, 4, 1722*0b57cec5SDimitry Andric llvm::IntervalMapHalfOpenInfo<addr_t>>; 1723*0b57cec5SDimitry Andric 1724*0b57cec5SDimitry Andric ObjectFile::Type ObjectType; 1725*0b57cec5SDimitry Andric addr_t NextVMAddress = 0; 1726*0b57cec5SDimitry Andric VMMap::Allocator Alloc; 172781ad6265SDimitry Andric VMMap Segments{Alloc}; 172881ad6265SDimitry Andric VMMap Sections{Alloc}; 172981ad6265SDimitry Andric lldb_private::Log *Log = GetLog(LLDBLog::Modules); 17309dba64beSDimitry Andric size_t SegmentCount = 0; 17319dba64beSDimitry Andric std::string SegmentName; 1732*0b57cec5SDimitry Andric 1733*0b57cec5SDimitry Andric VMRange GetVMRange(const ELFSectionHeader &H) { 1734*0b57cec5SDimitry Andric addr_t Address = H.sh_addr; 1735*0b57cec5SDimitry Andric addr_t Size = H.sh_flags & SHF_ALLOC ? H.sh_size : 0; 1736*0b57cec5SDimitry Andric if (ObjectType == ObjectFile::Type::eTypeObjectFile && Segments.empty() && (H.sh_flags & SHF_ALLOC)) { 1737*0b57cec5SDimitry Andric NextVMAddress = 1738*0b57cec5SDimitry Andric llvm::alignTo(NextVMAddress, std::max<addr_t>(H.sh_addralign, 1)); 1739*0b57cec5SDimitry Andric Address = NextVMAddress; 1740*0b57cec5SDimitry Andric NextVMAddress += Size; 1741*0b57cec5SDimitry Andric } 1742*0b57cec5SDimitry Andric return VMRange(Address, Size); 1743*0b57cec5SDimitry Andric } 1744*0b57cec5SDimitry Andric 1745*0b57cec5SDimitry Andric public: 17469dba64beSDimitry Andric VMAddressProvider(ObjectFile::Type Type, llvm::StringRef SegmentName) 17475ffd83dbSDimitry Andric : ObjectType(Type), SegmentName(std::string(SegmentName)) {} 17489dba64beSDimitry Andric 17499dba64beSDimitry Andric std::string GetNextSegmentName() const { 17509dba64beSDimitry Andric return llvm::formatv("{0}[{1}]", SegmentName, SegmentCount).str(); 17519dba64beSDimitry Andric } 1752*0b57cec5SDimitry Andric 1753*0b57cec5SDimitry Andric llvm::Optional<VMRange> GetAddressInfo(const ELFProgramHeader &H) { 1754*0b57cec5SDimitry Andric if (H.p_memsz == 0) { 17559dba64beSDimitry Andric LLDB_LOG(Log, "Ignoring zero-sized {0} segment. Corrupt object file?", 17569dba64beSDimitry Andric SegmentName); 1757*0b57cec5SDimitry Andric return llvm::None; 1758*0b57cec5SDimitry Andric } 1759*0b57cec5SDimitry Andric 1760*0b57cec5SDimitry Andric if (Segments.overlaps(H.p_vaddr, H.p_vaddr + H.p_memsz)) { 17619dba64beSDimitry Andric LLDB_LOG(Log, "Ignoring overlapping {0} segment. Corrupt object file?", 17629dba64beSDimitry Andric SegmentName); 1763*0b57cec5SDimitry Andric return llvm::None; 1764*0b57cec5SDimitry Andric } 1765*0b57cec5SDimitry Andric return VMRange(H.p_vaddr, H.p_memsz); 1766*0b57cec5SDimitry Andric } 1767*0b57cec5SDimitry Andric 1768*0b57cec5SDimitry Andric llvm::Optional<SectionAddressInfo> GetAddressInfo(const ELFSectionHeader &H) { 1769*0b57cec5SDimitry Andric VMRange Range = GetVMRange(H); 1770*0b57cec5SDimitry Andric SectionSP Segment; 1771*0b57cec5SDimitry Andric auto It = Segments.find(Range.GetRangeBase()); 1772*0b57cec5SDimitry Andric if ((H.sh_flags & SHF_ALLOC) && It.valid()) { 1773*0b57cec5SDimitry Andric addr_t MaxSize; 1774*0b57cec5SDimitry Andric if (It.start() <= Range.GetRangeBase()) { 1775*0b57cec5SDimitry Andric MaxSize = It.stop() - Range.GetRangeBase(); 1776*0b57cec5SDimitry Andric Segment = *It; 1777*0b57cec5SDimitry Andric } else 1778*0b57cec5SDimitry Andric MaxSize = It.start() - Range.GetRangeBase(); 1779*0b57cec5SDimitry Andric if (Range.GetByteSize() > MaxSize) { 1780*0b57cec5SDimitry Andric LLDB_LOG(Log, "Shortening section crossing segment boundaries. " 1781*0b57cec5SDimitry Andric "Corrupt object file?"); 1782*0b57cec5SDimitry Andric Range.SetByteSize(MaxSize); 1783*0b57cec5SDimitry Andric } 1784*0b57cec5SDimitry Andric } 1785*0b57cec5SDimitry Andric if (Range.GetByteSize() > 0 && 1786*0b57cec5SDimitry Andric Sections.overlaps(Range.GetRangeBase(), Range.GetRangeEnd())) { 1787*0b57cec5SDimitry Andric LLDB_LOG(Log, "Ignoring overlapping section. Corrupt object file?"); 1788*0b57cec5SDimitry Andric return llvm::None; 1789*0b57cec5SDimitry Andric } 1790*0b57cec5SDimitry Andric if (Segment) 1791*0b57cec5SDimitry Andric Range.Slide(-Segment->GetFileAddress()); 1792*0b57cec5SDimitry Andric return SectionAddressInfo{Segment, Range}; 1793*0b57cec5SDimitry Andric } 1794*0b57cec5SDimitry Andric 1795*0b57cec5SDimitry Andric void AddSegment(const VMRange &Range, SectionSP Seg) { 1796*0b57cec5SDimitry Andric Segments.insert(Range.GetRangeBase(), Range.GetRangeEnd(), std::move(Seg)); 17979dba64beSDimitry Andric ++SegmentCount; 1798*0b57cec5SDimitry Andric } 1799*0b57cec5SDimitry Andric 1800*0b57cec5SDimitry Andric void AddSection(SectionAddressInfo Info, SectionSP Sect) { 1801*0b57cec5SDimitry Andric if (Info.Range.GetByteSize() == 0) 1802*0b57cec5SDimitry Andric return; 1803*0b57cec5SDimitry Andric if (Info.Segment) 1804*0b57cec5SDimitry Andric Info.Range.Slide(Info.Segment->GetFileAddress()); 1805*0b57cec5SDimitry Andric Sections.insert(Info.Range.GetRangeBase(), Info.Range.GetRangeEnd(), 1806*0b57cec5SDimitry Andric std::move(Sect)); 1807*0b57cec5SDimitry Andric } 1808*0b57cec5SDimitry Andric }; 1809*0b57cec5SDimitry Andric } 1810*0b57cec5SDimitry Andric 1811*0b57cec5SDimitry Andric void ObjectFileELF::CreateSections(SectionList &unified_section_list) { 1812*0b57cec5SDimitry Andric if (m_sections_up) 1813*0b57cec5SDimitry Andric return; 1814*0b57cec5SDimitry Andric 18159dba64beSDimitry Andric m_sections_up = std::make_unique<SectionList>(); 18169dba64beSDimitry Andric VMAddressProvider regular_provider(GetType(), "PT_LOAD"); 18179dba64beSDimitry Andric VMAddressProvider tls_provider(GetType(), "PT_TLS"); 1818*0b57cec5SDimitry Andric 1819*0b57cec5SDimitry Andric for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) { 1820*0b57cec5SDimitry Andric const ELFProgramHeader &PHdr = EnumPHdr.value(); 18219dba64beSDimitry Andric if (PHdr.p_type != PT_LOAD && PHdr.p_type != PT_TLS) 1822*0b57cec5SDimitry Andric continue; 1823*0b57cec5SDimitry Andric 18249dba64beSDimitry Andric VMAddressProvider &provider = 18259dba64beSDimitry Andric PHdr.p_type == PT_TLS ? tls_provider : regular_provider; 18269dba64beSDimitry Andric auto InfoOr = provider.GetAddressInfo(PHdr); 1827*0b57cec5SDimitry Andric if (!InfoOr) 1828*0b57cec5SDimitry Andric continue; 1829*0b57cec5SDimitry Andric 1830*0b57cec5SDimitry Andric uint32_t Log2Align = llvm::Log2_64(std::max<elf_xword>(PHdr.p_align, 1)); 1831*0b57cec5SDimitry Andric SectionSP Segment = std::make_shared<Section>( 18329dba64beSDimitry Andric GetModule(), this, SegmentID(EnumPHdr.index()), 18339dba64beSDimitry Andric ConstString(provider.GetNextSegmentName()), eSectionTypeContainer, 18349dba64beSDimitry Andric InfoOr->GetRangeBase(), InfoOr->GetByteSize(), PHdr.p_offset, 18359dba64beSDimitry Andric PHdr.p_filesz, Log2Align, /*flags*/ 0); 1836*0b57cec5SDimitry Andric Segment->SetPermissions(GetPermissions(PHdr)); 18379dba64beSDimitry Andric Segment->SetIsThreadSpecific(PHdr.p_type == PT_TLS); 1838*0b57cec5SDimitry Andric m_sections_up->AddSection(Segment); 1839*0b57cec5SDimitry Andric 18409dba64beSDimitry Andric provider.AddSegment(*InfoOr, std::move(Segment)); 1841*0b57cec5SDimitry Andric } 1842*0b57cec5SDimitry Andric 1843*0b57cec5SDimitry Andric ParseSectionHeaders(); 1844*0b57cec5SDimitry Andric if (m_section_headers.empty()) 1845*0b57cec5SDimitry Andric return; 1846*0b57cec5SDimitry Andric 1847*0b57cec5SDimitry Andric for (SectionHeaderCollIter I = std::next(m_section_headers.begin()); 1848*0b57cec5SDimitry Andric I != m_section_headers.end(); ++I) { 1849*0b57cec5SDimitry Andric const ELFSectionHeaderInfo &header = *I; 1850*0b57cec5SDimitry Andric 1851*0b57cec5SDimitry Andric ConstString &name = I->section_name; 1852*0b57cec5SDimitry Andric const uint64_t file_size = 1853*0b57cec5SDimitry Andric header.sh_type == SHT_NOBITS ? 0 : header.sh_size; 1854*0b57cec5SDimitry Andric 18559dba64beSDimitry Andric VMAddressProvider &provider = 18569dba64beSDimitry Andric header.sh_flags & SHF_TLS ? tls_provider : regular_provider; 18579dba64beSDimitry Andric auto InfoOr = provider.GetAddressInfo(header); 1858*0b57cec5SDimitry Andric if (!InfoOr) 1859*0b57cec5SDimitry Andric continue; 1860*0b57cec5SDimitry Andric 1861*0b57cec5SDimitry Andric SectionType sect_type = GetSectionType(header); 1862*0b57cec5SDimitry Andric 1863*0b57cec5SDimitry Andric const uint32_t target_bytes_size = 1864*0b57cec5SDimitry Andric GetTargetByteSize(sect_type, m_arch_spec); 1865*0b57cec5SDimitry Andric 1866*0b57cec5SDimitry Andric elf::elf_xword log2align = 1867*0b57cec5SDimitry Andric (header.sh_addralign == 0) ? 0 : llvm::Log2_64(header.sh_addralign); 1868*0b57cec5SDimitry Andric 1869*0b57cec5SDimitry Andric SectionSP section_sp(new Section( 1870*0b57cec5SDimitry Andric InfoOr->Segment, GetModule(), // Module to which this section belongs. 1871*0b57cec5SDimitry Andric this, // ObjectFile to which this section belongs and should 1872*0b57cec5SDimitry Andric // read section data from. 1873*0b57cec5SDimitry Andric SectionIndex(I), // Section ID. 1874*0b57cec5SDimitry Andric name, // Section name. 1875*0b57cec5SDimitry Andric sect_type, // Section type. 1876*0b57cec5SDimitry Andric InfoOr->Range.GetRangeBase(), // VM address. 1877*0b57cec5SDimitry Andric InfoOr->Range.GetByteSize(), // VM size in bytes of this section. 1878*0b57cec5SDimitry Andric header.sh_offset, // Offset of this section in the file. 1879*0b57cec5SDimitry Andric file_size, // Size of the section as found in the file. 1880*0b57cec5SDimitry Andric log2align, // Alignment of the section 1881*0b57cec5SDimitry Andric header.sh_flags, // Flags for this section. 1882*0b57cec5SDimitry Andric target_bytes_size)); // Number of host bytes per target byte 1883*0b57cec5SDimitry Andric 1884*0b57cec5SDimitry Andric section_sp->SetPermissions(GetPermissions(header)); 1885*0b57cec5SDimitry Andric section_sp->SetIsThreadSpecific(header.sh_flags & SHF_TLS); 1886*0b57cec5SDimitry Andric (InfoOr->Segment ? InfoOr->Segment->GetChildren() : *m_sections_up) 1887*0b57cec5SDimitry Andric .AddSection(section_sp); 18889dba64beSDimitry Andric provider.AddSection(std::move(*InfoOr), std::move(section_sp)); 1889*0b57cec5SDimitry Andric } 1890*0b57cec5SDimitry Andric 1891*0b57cec5SDimitry Andric // For eTypeDebugInfo files, the Symbol Vendor will take care of updating the 1892*0b57cec5SDimitry Andric // unified section list. 1893*0b57cec5SDimitry Andric if (GetType() != eTypeDebugInfo) 1894*0b57cec5SDimitry Andric unified_section_list = *m_sections_up; 18959dba64beSDimitry Andric 18969dba64beSDimitry Andric // If there's a .gnu_debugdata section, we'll try to read the .symtab that's 18979dba64beSDimitry Andric // embedded in there and replace the one in the original object file (if any). 18989dba64beSDimitry Andric // If there's none in the orignal object file, we add it to it. 18999dba64beSDimitry Andric if (auto gdd_obj_file = GetGnuDebugDataObjectFile()) { 19009dba64beSDimitry Andric if (auto gdd_objfile_section_list = gdd_obj_file->GetSectionList()) { 19019dba64beSDimitry Andric if (SectionSP symtab_section_sp = 19029dba64beSDimitry Andric gdd_objfile_section_list->FindSectionByType( 19039dba64beSDimitry Andric eSectionTypeELFSymbolTable, true)) { 19049dba64beSDimitry Andric SectionSP module_section_sp = unified_section_list.FindSectionByType( 19059dba64beSDimitry Andric eSectionTypeELFSymbolTable, true); 19069dba64beSDimitry Andric if (module_section_sp) 19079dba64beSDimitry Andric unified_section_list.ReplaceSection(module_section_sp->GetID(), 19089dba64beSDimitry Andric symtab_section_sp); 19099dba64beSDimitry Andric else 19109dba64beSDimitry Andric unified_section_list.AddSection(symtab_section_sp); 19119dba64beSDimitry Andric } 19129dba64beSDimitry Andric } 19139dba64beSDimitry Andric } 19149dba64beSDimitry Andric } 19159dba64beSDimitry Andric 19169dba64beSDimitry Andric std::shared_ptr<ObjectFileELF> ObjectFileELF::GetGnuDebugDataObjectFile() { 19179dba64beSDimitry Andric if (m_gnu_debug_data_object_file != nullptr) 19189dba64beSDimitry Andric return m_gnu_debug_data_object_file; 19199dba64beSDimitry Andric 19209dba64beSDimitry Andric SectionSP section = 19219dba64beSDimitry Andric GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata")); 19229dba64beSDimitry Andric if (!section) 19239dba64beSDimitry Andric return nullptr; 19249dba64beSDimitry Andric 19259dba64beSDimitry Andric if (!lldb_private::lzma::isAvailable()) { 19269dba64beSDimitry Andric GetModule()->ReportWarning( 19279dba64beSDimitry Andric "No LZMA support found for reading .gnu_debugdata section"); 19289dba64beSDimitry Andric return nullptr; 19299dba64beSDimitry Andric } 19309dba64beSDimitry Andric 19319dba64beSDimitry Andric // Uncompress the data 19329dba64beSDimitry Andric DataExtractor data; 19339dba64beSDimitry Andric section->GetSectionData(data); 19349dba64beSDimitry Andric llvm::SmallVector<uint8_t, 0> uncompressedData; 19359dba64beSDimitry Andric auto err = lldb_private::lzma::uncompress(data.GetData(), uncompressedData); 19369dba64beSDimitry Andric if (err) { 19379dba64beSDimitry Andric GetModule()->ReportWarning( 19389dba64beSDimitry Andric "An error occurred while decompression the section %s: %s", 19399dba64beSDimitry Andric section->GetName().AsCString(), llvm::toString(std::move(err)).c_str()); 19409dba64beSDimitry Andric return nullptr; 19419dba64beSDimitry Andric } 19429dba64beSDimitry Andric 19439dba64beSDimitry Andric // Construct ObjectFileELF object from decompressed buffer 19449dba64beSDimitry Andric DataBufferSP gdd_data_buf( 19459dba64beSDimitry Andric new DataBufferHeap(uncompressedData.data(), uncompressedData.size())); 19469dba64beSDimitry Andric auto fspec = GetFileSpec().CopyByAppendingPathComponent( 19479dba64beSDimitry Andric llvm::StringRef("gnu_debugdata")); 19489dba64beSDimitry Andric m_gnu_debug_data_object_file.reset(new ObjectFileELF( 19499dba64beSDimitry Andric GetModule(), gdd_data_buf, 0, &fspec, 0, gdd_data_buf->GetByteSize())); 19509dba64beSDimitry Andric 19519dba64beSDimitry Andric // This line is essential; otherwise a breakpoint can be set but not hit. 19529dba64beSDimitry Andric m_gnu_debug_data_object_file->SetType(ObjectFile::eTypeDebugInfo); 19539dba64beSDimitry Andric 19549dba64beSDimitry Andric ArchSpec spec = m_gnu_debug_data_object_file->GetArchitecture(); 19559dba64beSDimitry Andric if (spec && m_gnu_debug_data_object_file->SetModulesArchitecture(spec)) 19569dba64beSDimitry Andric return m_gnu_debug_data_object_file; 19579dba64beSDimitry Andric 19589dba64beSDimitry Andric return nullptr; 1959*0b57cec5SDimitry Andric } 1960*0b57cec5SDimitry Andric 1961*0b57cec5SDimitry Andric // Find the arm/aarch64 mapping symbol character in the given symbol name. 1962*0b57cec5SDimitry Andric // Mapping symbols have the form of "$<char>[.<any>]*". Additionally we 1963*0b57cec5SDimitry Andric // recognize cases when the mapping symbol prefixed by an arbitrary string 1964*0b57cec5SDimitry Andric // because if a symbol prefix added to each symbol in the object file with 1965*0b57cec5SDimitry Andric // objcopy then the mapping symbols are also prefixed. 1966*0b57cec5SDimitry Andric static char FindArmAarch64MappingSymbol(const char *symbol_name) { 1967*0b57cec5SDimitry Andric if (!symbol_name) 1968*0b57cec5SDimitry Andric return '\0'; 1969*0b57cec5SDimitry Andric 1970*0b57cec5SDimitry Andric const char *dollar_pos = ::strchr(symbol_name, '$'); 1971*0b57cec5SDimitry Andric if (!dollar_pos || dollar_pos[1] == '\0') 1972*0b57cec5SDimitry Andric return '\0'; 1973*0b57cec5SDimitry Andric 1974*0b57cec5SDimitry Andric if (dollar_pos[2] == '\0' || dollar_pos[2] == '.') 1975*0b57cec5SDimitry Andric return dollar_pos[1]; 1976*0b57cec5SDimitry Andric return '\0'; 1977*0b57cec5SDimitry Andric } 1978*0b57cec5SDimitry Andric 1979*0b57cec5SDimitry Andric #define STO_MIPS_ISA (3 << 6) 1980*0b57cec5SDimitry Andric #define STO_MICROMIPS (2 << 6) 1981*0b57cec5SDimitry Andric #define IS_MICROMIPS(ST_OTHER) (((ST_OTHER)&STO_MIPS_ISA) == STO_MICROMIPS) 1982*0b57cec5SDimitry Andric 1983*0b57cec5SDimitry Andric // private 1984*0b57cec5SDimitry Andric unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, 1985*0b57cec5SDimitry Andric SectionList *section_list, 1986*0b57cec5SDimitry Andric const size_t num_symbols, 1987*0b57cec5SDimitry Andric const DataExtractor &symtab_data, 1988*0b57cec5SDimitry Andric const DataExtractor &strtab_data) { 1989*0b57cec5SDimitry Andric ELFSymbol symbol; 1990*0b57cec5SDimitry Andric lldb::offset_t offset = 0; 1991*0b57cec5SDimitry Andric 1992*0b57cec5SDimitry Andric static ConstString text_section_name(".text"); 1993*0b57cec5SDimitry Andric static ConstString init_section_name(".init"); 1994*0b57cec5SDimitry Andric static ConstString fini_section_name(".fini"); 1995*0b57cec5SDimitry Andric static ConstString ctors_section_name(".ctors"); 1996*0b57cec5SDimitry Andric static ConstString dtors_section_name(".dtors"); 1997*0b57cec5SDimitry Andric 1998*0b57cec5SDimitry Andric static ConstString data_section_name(".data"); 1999*0b57cec5SDimitry Andric static ConstString rodata_section_name(".rodata"); 2000*0b57cec5SDimitry Andric static ConstString rodata1_section_name(".rodata1"); 2001*0b57cec5SDimitry Andric static ConstString data2_section_name(".data1"); 2002*0b57cec5SDimitry Andric static ConstString bss_section_name(".bss"); 2003*0b57cec5SDimitry Andric static ConstString opd_section_name(".opd"); // For ppc64 2004*0b57cec5SDimitry Andric 2005*0b57cec5SDimitry Andric // On Android the oatdata and the oatexec symbols in the oat and odex files 2006*0b57cec5SDimitry Andric // covers the full .text section what causes issues with displaying unusable 2007*0b57cec5SDimitry Andric // symbol name to the user and very slow unwinding speed because the 2008*0b57cec5SDimitry Andric // instruction emulation based unwind plans try to emulate all instructions 2009*0b57cec5SDimitry Andric // in these symbols. Don't add these symbols to the symbol list as they have 2010*0b57cec5SDimitry Andric // no use for the debugger and they are causing a lot of trouble. Filtering 2011*0b57cec5SDimitry Andric // can't be restricted to Android because this special object file don't 2012*0b57cec5SDimitry Andric // contain the note section specifying the environment to Android but the 2013*0b57cec5SDimitry Andric // custom extension and file name makes it highly unlikely that this will 2014*0b57cec5SDimitry Andric // collide with anything else. 2015*0b57cec5SDimitry Andric ConstString file_extension = m_file.GetFileNameExtension(); 2016*0b57cec5SDimitry Andric bool skip_oatdata_oatexec = 2017*0b57cec5SDimitry Andric file_extension == ".oat" || file_extension == ".odex"; 2018*0b57cec5SDimitry Andric 2019*0b57cec5SDimitry Andric ArchSpec arch = GetArchitecture(); 2020*0b57cec5SDimitry Andric ModuleSP module_sp(GetModule()); 2021*0b57cec5SDimitry Andric SectionList *module_section_list = 2022*0b57cec5SDimitry Andric module_sp ? module_sp->GetSectionList() : nullptr; 2023*0b57cec5SDimitry Andric 2024*0b57cec5SDimitry Andric // Local cache to avoid doing a FindSectionByName for each symbol. The "const 2025*0b57cec5SDimitry Andric // char*" key must came from a ConstString object so they can be compared by 2026*0b57cec5SDimitry Andric // pointer 2027*0b57cec5SDimitry Andric std::unordered_map<const char *, lldb::SectionSP> section_name_to_section; 2028*0b57cec5SDimitry Andric 2029*0b57cec5SDimitry Andric unsigned i; 2030*0b57cec5SDimitry Andric for (i = 0; i < num_symbols; ++i) { 2031*0b57cec5SDimitry Andric if (!symbol.Parse(symtab_data, &offset)) 2032*0b57cec5SDimitry Andric break; 2033*0b57cec5SDimitry Andric 2034*0b57cec5SDimitry Andric const char *symbol_name = strtab_data.PeekCStr(symbol.st_name); 2035*0b57cec5SDimitry Andric if (!symbol_name) 2036*0b57cec5SDimitry Andric symbol_name = ""; 2037*0b57cec5SDimitry Andric 2038*0b57cec5SDimitry Andric // No need to add non-section symbols that have no names 2039*0b57cec5SDimitry Andric if (symbol.getType() != STT_SECTION && 2040*0b57cec5SDimitry Andric (symbol_name == nullptr || symbol_name[0] == '\0')) 2041*0b57cec5SDimitry Andric continue; 2042*0b57cec5SDimitry Andric 2043*0b57cec5SDimitry Andric // Skipping oatdata and oatexec sections if it is requested. See details 2044*0b57cec5SDimitry Andric // above the definition of skip_oatdata_oatexec for the reasons. 2045*0b57cec5SDimitry Andric if (skip_oatdata_oatexec && (::strcmp(symbol_name, "oatdata") == 0 || 2046*0b57cec5SDimitry Andric ::strcmp(symbol_name, "oatexec") == 0)) 2047*0b57cec5SDimitry Andric continue; 2048*0b57cec5SDimitry Andric 2049*0b57cec5SDimitry Andric SectionSP symbol_section_sp; 2050*0b57cec5SDimitry Andric SymbolType symbol_type = eSymbolTypeInvalid; 2051*0b57cec5SDimitry Andric Elf64_Half shndx = symbol.st_shndx; 2052*0b57cec5SDimitry Andric 2053*0b57cec5SDimitry Andric switch (shndx) { 2054*0b57cec5SDimitry Andric case SHN_ABS: 2055*0b57cec5SDimitry Andric symbol_type = eSymbolTypeAbsolute; 2056*0b57cec5SDimitry Andric break; 2057*0b57cec5SDimitry Andric case SHN_UNDEF: 2058*0b57cec5SDimitry Andric symbol_type = eSymbolTypeUndefined; 2059*0b57cec5SDimitry Andric break; 2060*0b57cec5SDimitry Andric default: 2061*0b57cec5SDimitry Andric symbol_section_sp = section_list->FindSectionByID(shndx); 2062*0b57cec5SDimitry Andric break; 2063*0b57cec5SDimitry Andric } 2064*0b57cec5SDimitry Andric 2065*0b57cec5SDimitry Andric // If a symbol is undefined do not process it further even if it has a STT 2066*0b57cec5SDimitry Andric // type 2067*0b57cec5SDimitry Andric if (symbol_type != eSymbolTypeUndefined) { 2068*0b57cec5SDimitry Andric switch (symbol.getType()) { 2069*0b57cec5SDimitry Andric default: 2070*0b57cec5SDimitry Andric case STT_NOTYPE: 2071*0b57cec5SDimitry Andric // The symbol's type is not specified. 2072*0b57cec5SDimitry Andric break; 2073*0b57cec5SDimitry Andric 2074*0b57cec5SDimitry Andric case STT_OBJECT: 2075*0b57cec5SDimitry Andric // The symbol is associated with a data object, such as a variable, an 2076*0b57cec5SDimitry Andric // array, etc. 2077*0b57cec5SDimitry Andric symbol_type = eSymbolTypeData; 2078*0b57cec5SDimitry Andric break; 2079*0b57cec5SDimitry Andric 2080*0b57cec5SDimitry Andric case STT_FUNC: 2081*0b57cec5SDimitry Andric // The symbol is associated with a function or other executable code. 2082*0b57cec5SDimitry Andric symbol_type = eSymbolTypeCode; 2083*0b57cec5SDimitry Andric break; 2084*0b57cec5SDimitry Andric 2085*0b57cec5SDimitry Andric case STT_SECTION: 2086*0b57cec5SDimitry Andric // The symbol is associated with a section. Symbol table entries of 2087*0b57cec5SDimitry Andric // this type exist primarily for relocation and normally have STB_LOCAL 2088*0b57cec5SDimitry Andric // binding. 2089*0b57cec5SDimitry Andric break; 2090*0b57cec5SDimitry Andric 2091*0b57cec5SDimitry Andric case STT_FILE: 2092*0b57cec5SDimitry Andric // Conventionally, the symbol's name gives the name of the source file 2093*0b57cec5SDimitry Andric // associated with the object file. A file symbol has STB_LOCAL 2094*0b57cec5SDimitry Andric // binding, its section index is SHN_ABS, and it precedes the other 2095*0b57cec5SDimitry Andric // STB_LOCAL symbols for the file, if it is present. 2096*0b57cec5SDimitry Andric symbol_type = eSymbolTypeSourceFile; 2097*0b57cec5SDimitry Andric break; 2098*0b57cec5SDimitry Andric 2099*0b57cec5SDimitry Andric case STT_GNU_IFUNC: 2100*0b57cec5SDimitry Andric // The symbol is associated with an indirect function. The actual 2101*0b57cec5SDimitry Andric // function will be resolved if it is referenced. 2102*0b57cec5SDimitry Andric symbol_type = eSymbolTypeResolver; 2103*0b57cec5SDimitry Andric break; 2104*0b57cec5SDimitry Andric } 2105*0b57cec5SDimitry Andric } 2106*0b57cec5SDimitry Andric 2107*0b57cec5SDimitry Andric if (symbol_type == eSymbolTypeInvalid && symbol.getType() != STT_SECTION) { 2108*0b57cec5SDimitry Andric if (symbol_section_sp) { 2109*0b57cec5SDimitry Andric ConstString sect_name = symbol_section_sp->GetName(); 2110*0b57cec5SDimitry Andric if (sect_name == text_section_name || sect_name == init_section_name || 2111*0b57cec5SDimitry Andric sect_name == fini_section_name || sect_name == ctors_section_name || 2112*0b57cec5SDimitry Andric sect_name == dtors_section_name) { 2113*0b57cec5SDimitry Andric symbol_type = eSymbolTypeCode; 2114*0b57cec5SDimitry Andric } else if (sect_name == data_section_name || 2115*0b57cec5SDimitry Andric sect_name == data2_section_name || 2116*0b57cec5SDimitry Andric sect_name == rodata_section_name || 2117*0b57cec5SDimitry Andric sect_name == rodata1_section_name || 2118*0b57cec5SDimitry Andric sect_name == bss_section_name) { 2119*0b57cec5SDimitry Andric symbol_type = eSymbolTypeData; 2120*0b57cec5SDimitry Andric } 2121*0b57cec5SDimitry Andric } 2122*0b57cec5SDimitry Andric } 2123*0b57cec5SDimitry Andric 2124*0b57cec5SDimitry Andric int64_t symbol_value_offset = 0; 2125*0b57cec5SDimitry Andric uint32_t additional_flags = 0; 2126*0b57cec5SDimitry Andric 2127*0b57cec5SDimitry Andric if (arch.IsValid()) { 2128*0b57cec5SDimitry Andric if (arch.GetMachine() == llvm::Triple::arm) { 2129*0b57cec5SDimitry Andric if (symbol.getBinding() == STB_LOCAL) { 2130*0b57cec5SDimitry Andric char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name); 2131*0b57cec5SDimitry Andric if (symbol_type == eSymbolTypeCode) { 2132*0b57cec5SDimitry Andric switch (mapping_symbol) { 2133*0b57cec5SDimitry Andric case 'a': 2134*0b57cec5SDimitry Andric // $a[.<any>]* - marks an ARM instruction sequence 2135*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCode; 2136*0b57cec5SDimitry Andric break; 2137*0b57cec5SDimitry Andric case 'b': 2138*0b57cec5SDimitry Andric case 't': 2139*0b57cec5SDimitry Andric // $b[.<any>]* - marks a THUMB BL instruction sequence 2140*0b57cec5SDimitry Andric // $t[.<any>]* - marks a THUMB instruction sequence 2141*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = 2142*0b57cec5SDimitry Andric AddressClass::eCodeAlternateISA; 2143*0b57cec5SDimitry Andric break; 2144*0b57cec5SDimitry Andric case 'd': 2145*0b57cec5SDimitry Andric // $d[.<any>]* - marks a data item sequence (e.g. lit pool) 2146*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eData; 2147*0b57cec5SDimitry Andric break; 2148*0b57cec5SDimitry Andric } 2149*0b57cec5SDimitry Andric } 2150*0b57cec5SDimitry Andric if (mapping_symbol) 2151*0b57cec5SDimitry Andric continue; 2152*0b57cec5SDimitry Andric } 2153*0b57cec5SDimitry Andric } else if (arch.GetMachine() == llvm::Triple::aarch64) { 2154*0b57cec5SDimitry Andric if (symbol.getBinding() == STB_LOCAL) { 2155*0b57cec5SDimitry Andric char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name); 2156*0b57cec5SDimitry Andric if (symbol_type == eSymbolTypeCode) { 2157*0b57cec5SDimitry Andric switch (mapping_symbol) { 2158*0b57cec5SDimitry Andric case 'x': 2159*0b57cec5SDimitry Andric // $x[.<any>]* - marks an A64 instruction sequence 2160*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCode; 2161*0b57cec5SDimitry Andric break; 2162*0b57cec5SDimitry Andric case 'd': 2163*0b57cec5SDimitry Andric // $d[.<any>]* - marks a data item sequence (e.g. lit pool) 2164*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eData; 2165*0b57cec5SDimitry Andric break; 2166*0b57cec5SDimitry Andric } 2167*0b57cec5SDimitry Andric } 2168*0b57cec5SDimitry Andric if (mapping_symbol) 2169*0b57cec5SDimitry Andric continue; 2170*0b57cec5SDimitry Andric } 2171*0b57cec5SDimitry Andric } 2172*0b57cec5SDimitry Andric 2173*0b57cec5SDimitry Andric if (arch.GetMachine() == llvm::Triple::arm) { 2174*0b57cec5SDimitry Andric if (symbol_type == eSymbolTypeCode) { 2175*0b57cec5SDimitry Andric if (symbol.st_value & 1) { 2176*0b57cec5SDimitry Andric // Subtracting 1 from the address effectively unsets the low order 2177*0b57cec5SDimitry Andric // bit, which results in the address actually pointing to the 2178*0b57cec5SDimitry Andric // beginning of the symbol. This delta will be used below in 2179*0b57cec5SDimitry Andric // conjunction with symbol.st_value to produce the final 2180*0b57cec5SDimitry Andric // symbol_value that we store in the symtab. 2181*0b57cec5SDimitry Andric symbol_value_offset = -1; 2182*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value ^ 1] = 2183*0b57cec5SDimitry Andric AddressClass::eCodeAlternateISA; 2184*0b57cec5SDimitry Andric } else { 2185*0b57cec5SDimitry Andric // This address is ARM 2186*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCode; 2187*0b57cec5SDimitry Andric } 2188*0b57cec5SDimitry Andric } 2189*0b57cec5SDimitry Andric } 2190*0b57cec5SDimitry Andric 2191*0b57cec5SDimitry Andric /* 2192*0b57cec5SDimitry Andric * MIPS: 2193*0b57cec5SDimitry Andric * The bit #0 of an address is used for ISA mode (1 for microMIPS, 0 for 2194*0b57cec5SDimitry Andric * MIPS). 2195*0b57cec5SDimitry Andric * This allows processor to switch between microMIPS and MIPS without any 2196*0b57cec5SDimitry Andric * need 2197*0b57cec5SDimitry Andric * for special mode-control register. However, apart from .debug_line, 2198*0b57cec5SDimitry Andric * none of 2199*0b57cec5SDimitry Andric * the ELF/DWARF sections set the ISA bit (for symbol or section). Use 2200*0b57cec5SDimitry Andric * st_other 2201*0b57cec5SDimitry Andric * flag to check whether the symbol is microMIPS and then set the address 2202*0b57cec5SDimitry Andric * class 2203*0b57cec5SDimitry Andric * accordingly. 2204*0b57cec5SDimitry Andric */ 2205*0b57cec5SDimitry Andric if (arch.IsMIPS()) { 2206*0b57cec5SDimitry Andric if (IS_MICROMIPS(symbol.st_other)) 2207*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA; 2208*0b57cec5SDimitry Andric else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode)) { 2209*0b57cec5SDimitry Andric symbol.st_value = symbol.st_value & (~1ull); 2210*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCodeAlternateISA; 2211*0b57cec5SDimitry Andric } else { 2212*0b57cec5SDimitry Andric if (symbol_type == eSymbolTypeCode) 2213*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eCode; 2214*0b57cec5SDimitry Andric else if (symbol_type == eSymbolTypeData) 2215*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eData; 2216*0b57cec5SDimitry Andric else 2217*0b57cec5SDimitry Andric m_address_class_map[symbol.st_value] = AddressClass::eUnknown; 2218*0b57cec5SDimitry Andric } 2219*0b57cec5SDimitry Andric } 2220*0b57cec5SDimitry Andric } 2221*0b57cec5SDimitry Andric 2222*0b57cec5SDimitry Andric // symbol_value_offset may contain 0 for ARM symbols or -1 for THUMB 2223*0b57cec5SDimitry Andric // symbols. See above for more details. 2224*0b57cec5SDimitry Andric uint64_t symbol_value = symbol.st_value + symbol_value_offset; 2225*0b57cec5SDimitry Andric 2226*0b57cec5SDimitry Andric if (symbol_section_sp == nullptr && shndx == SHN_ABS && 2227*0b57cec5SDimitry Andric symbol.st_size != 0) { 2228*0b57cec5SDimitry Andric // We don't have a section for a symbol with non-zero size. Create a new 2229*0b57cec5SDimitry Andric // section for it so the address range covered by the symbol is also 2230*0b57cec5SDimitry Andric // covered by the module (represented through the section list). It is 2231*0b57cec5SDimitry Andric // needed so module lookup for the addresses covered by this symbol will 2232*0b57cec5SDimitry Andric // be successfull. This case happens for absolute symbols. 2233*0b57cec5SDimitry Andric ConstString fake_section_name(std::string(".absolute.") + symbol_name); 2234*0b57cec5SDimitry Andric symbol_section_sp = 2235*0b57cec5SDimitry Andric std::make_shared<Section>(module_sp, this, SHN_ABS, fake_section_name, 2236*0b57cec5SDimitry Andric eSectionTypeAbsoluteAddress, symbol_value, 2237*0b57cec5SDimitry Andric symbol.st_size, 0, 0, 0, SHF_ALLOC); 2238*0b57cec5SDimitry Andric 2239*0b57cec5SDimitry Andric module_section_list->AddSection(symbol_section_sp); 2240*0b57cec5SDimitry Andric section_list->AddSection(symbol_section_sp); 2241*0b57cec5SDimitry Andric } 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) { 2617*0b57cec5SDimitry Andric if (!rel.Parse(rel_data, &offset)) 2618*0b57cec5SDimitry Andric break; 2619*0b57cec5SDimitry Andric 2620*0b57cec5SDimitry Andric Symbol *symbol = nullptr; 2621*0b57cec5SDimitry Andric 2622*0b57cec5SDimitry Andric if (hdr->Is32Bit()) { 2623*0b57cec5SDimitry Andric switch (reloc_type(rel)) { 2624*0b57cec5SDimitry Andric case R_386_32: 2625*0b57cec5SDimitry Andric case R_386_PC32: 2626*0b57cec5SDimitry Andric default: 2627*0b57cec5SDimitry Andric // FIXME: This asserts with this input: 2628*0b57cec5SDimitry Andric // 2629*0b57cec5SDimitry Andric // foo.cpp 2630*0b57cec5SDimitry Andric // int main(int argc, char **argv) { return 0; } 2631*0b57cec5SDimitry Andric // 2632*0b57cec5SDimitry Andric // clang++.exe --target=i686-unknown-linux-gnu -g -c foo.cpp -o foo.o 2633*0b57cec5SDimitry Andric // 2634*0b57cec5SDimitry Andric // and running this on the foo.o module. 2635*0b57cec5SDimitry Andric assert(false && "unexpected relocation type"); 2636*0b57cec5SDimitry Andric } 2637*0b57cec5SDimitry Andric } else { 2638*0b57cec5SDimitry Andric switch (reloc_type(rel)) { 2639*0b57cec5SDimitry Andric case R_AARCH64_ABS64: 2640*0b57cec5SDimitry Andric case R_X86_64_64: { 2641*0b57cec5SDimitry Andric symbol = symtab->FindSymbolByID(reloc_symbol(rel)); 2642*0b57cec5SDimitry Andric if (symbol) { 2643*0b57cec5SDimitry Andric addr_t value = symbol->GetAddressRef().GetFileAddress(); 2644*0b57cec5SDimitry Andric DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); 264581ad6265SDimitry Andric // ObjectFileELF creates a WritableDataBuffer in CreateInstance. 264681ad6265SDimitry Andric WritableDataBuffer *data_buffer = 264781ad6265SDimitry Andric llvm::cast<WritableDataBuffer>(data_buffer_sp.get()); 2648*0b57cec5SDimitry Andric uint64_t *dst = reinterpret_cast<uint64_t *>( 264981ad6265SDimitry Andric data_buffer->GetBytes() + rel_section->GetFileOffset() + 2650*0b57cec5SDimitry Andric ELFRelocation::RelocOffset64(rel)); 2651*0b57cec5SDimitry Andric uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel); 2652*0b57cec5SDimitry Andric memcpy(dst, &val_offset, sizeof(uint64_t)); 2653*0b57cec5SDimitry Andric } 2654*0b57cec5SDimitry Andric break; 2655*0b57cec5SDimitry Andric } 2656*0b57cec5SDimitry Andric case R_X86_64_32: 2657*0b57cec5SDimitry Andric case R_X86_64_32S: 2658*0b57cec5SDimitry Andric case R_AARCH64_ABS32: { 2659*0b57cec5SDimitry Andric symbol = symtab->FindSymbolByID(reloc_symbol(rel)); 2660*0b57cec5SDimitry Andric if (symbol) { 2661*0b57cec5SDimitry Andric addr_t value = symbol->GetAddressRef().GetFileAddress(); 2662*0b57cec5SDimitry Andric value += ELFRelocation::RelocAddend32(rel); 2663*0b57cec5SDimitry Andric if ((reloc_type(rel) == R_X86_64_32 && (value > UINT32_MAX)) || 2664*0b57cec5SDimitry Andric (reloc_type(rel) == R_X86_64_32S && 2665*0b57cec5SDimitry Andric ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN)) || 2666*0b57cec5SDimitry Andric (reloc_type(rel) == R_AARCH64_ABS32 && 2667*0b57cec5SDimitry Andric ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN))) { 266881ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Modules); 26699dba64beSDimitry Andric LLDB_LOGF(log, "Failed to apply debug info relocations"); 2670*0b57cec5SDimitry Andric break; 2671*0b57cec5SDimitry Andric } 2672*0b57cec5SDimitry Andric uint32_t truncated_addr = (value & 0xFFFFFFFF); 2673*0b57cec5SDimitry Andric DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); 267481ad6265SDimitry Andric // ObjectFileELF creates a WritableDataBuffer in CreateInstance. 267581ad6265SDimitry Andric WritableDataBuffer *data_buffer = 267681ad6265SDimitry Andric llvm::cast<WritableDataBuffer>(data_buffer_sp.get()); 2677*0b57cec5SDimitry Andric uint32_t *dst = reinterpret_cast<uint32_t *>( 267881ad6265SDimitry Andric data_buffer->GetBytes() + rel_section->GetFileOffset() + 2679*0b57cec5SDimitry Andric ELFRelocation::RelocOffset32(rel)); 2680*0b57cec5SDimitry Andric memcpy(dst, &truncated_addr, sizeof(uint32_t)); 2681*0b57cec5SDimitry Andric } 2682*0b57cec5SDimitry Andric break; 2683*0b57cec5SDimitry Andric } 2684*0b57cec5SDimitry Andric case R_X86_64_PC32: 2685*0b57cec5SDimitry Andric default: 2686*0b57cec5SDimitry Andric assert(false && "unexpected relocation type"); 2687*0b57cec5SDimitry Andric } 2688*0b57cec5SDimitry Andric } 2689*0b57cec5SDimitry Andric } 2690*0b57cec5SDimitry Andric 2691*0b57cec5SDimitry Andric return 0; 2692*0b57cec5SDimitry Andric } 2693*0b57cec5SDimitry Andric 2694*0b57cec5SDimitry Andric unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr, 2695*0b57cec5SDimitry Andric user_id_t rel_id, 2696*0b57cec5SDimitry Andric lldb_private::Symtab *thetab) { 2697*0b57cec5SDimitry Andric assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL); 2698*0b57cec5SDimitry Andric 2699*0b57cec5SDimitry Andric // Parse in the section list if needed. 2700*0b57cec5SDimitry Andric SectionList *section_list = GetSectionList(); 2701*0b57cec5SDimitry Andric if (!section_list) 2702*0b57cec5SDimitry Andric return 0; 2703*0b57cec5SDimitry Andric 2704*0b57cec5SDimitry Andric user_id_t symtab_id = rel_hdr->sh_link; 2705*0b57cec5SDimitry Andric user_id_t debug_id = rel_hdr->sh_info; 2706*0b57cec5SDimitry Andric 2707*0b57cec5SDimitry Andric const ELFSectionHeader *symtab_hdr = GetSectionHeaderByIndex(symtab_id); 2708*0b57cec5SDimitry Andric if (!symtab_hdr) 2709*0b57cec5SDimitry Andric return 0; 2710*0b57cec5SDimitry Andric 2711*0b57cec5SDimitry Andric const ELFSectionHeader *debug_hdr = GetSectionHeaderByIndex(debug_id); 2712*0b57cec5SDimitry Andric if (!debug_hdr) 2713*0b57cec5SDimitry Andric return 0; 2714*0b57cec5SDimitry Andric 2715*0b57cec5SDimitry Andric Section *rel = section_list->FindSectionByID(rel_id).get(); 2716*0b57cec5SDimitry Andric if (!rel) 2717*0b57cec5SDimitry Andric return 0; 2718*0b57cec5SDimitry Andric 2719*0b57cec5SDimitry Andric Section *symtab = section_list->FindSectionByID(symtab_id).get(); 2720*0b57cec5SDimitry Andric if (!symtab) 2721*0b57cec5SDimitry Andric return 0; 2722*0b57cec5SDimitry Andric 2723*0b57cec5SDimitry Andric Section *debug = section_list->FindSectionByID(debug_id).get(); 2724*0b57cec5SDimitry Andric if (!debug) 2725*0b57cec5SDimitry Andric return 0; 2726*0b57cec5SDimitry Andric 2727*0b57cec5SDimitry Andric DataExtractor rel_data; 2728*0b57cec5SDimitry Andric DataExtractor symtab_data; 2729*0b57cec5SDimitry Andric DataExtractor debug_data; 2730*0b57cec5SDimitry Andric 2731*0b57cec5SDimitry Andric if (GetData(rel->GetFileOffset(), rel->GetFileSize(), rel_data) && 2732*0b57cec5SDimitry Andric GetData(symtab->GetFileOffset(), symtab->GetFileSize(), symtab_data) && 2733*0b57cec5SDimitry Andric GetData(debug->GetFileOffset(), debug->GetFileSize(), debug_data)) { 2734*0b57cec5SDimitry Andric ApplyRelocations(thetab, &m_header, rel_hdr, symtab_hdr, debug_hdr, 2735*0b57cec5SDimitry Andric rel_data, symtab_data, debug_data, debug); 2736*0b57cec5SDimitry Andric } 2737*0b57cec5SDimitry Andric 2738*0b57cec5SDimitry Andric return 0; 2739*0b57cec5SDimitry Andric } 2740*0b57cec5SDimitry Andric 27414824e7fdSDimitry Andric void ObjectFileELF::ParseSymtab(Symtab &lldb_symtab) { 2742*0b57cec5SDimitry Andric ModuleSP module_sp(GetModule()); 2743*0b57cec5SDimitry Andric if (!module_sp) 27444824e7fdSDimitry Andric return; 27454824e7fdSDimitry Andric 27464824e7fdSDimitry Andric Progress progress( 27474824e7fdSDimitry Andric llvm::formatv("Parsing symbol table for {0}", 27484824e7fdSDimitry Andric m_file.GetFilename().AsCString("<Unknown>"))); 27494824e7fdSDimitry Andric ElapsedTime elapsed(module_sp->GetSymtabParseTime()); 2750*0b57cec5SDimitry Andric 2751*0b57cec5SDimitry Andric // We always want to use the main object file so we (hopefully) only have one 2752*0b57cec5SDimitry Andric // cached copy of our symtab, dynamic sections, etc. 2753*0b57cec5SDimitry Andric ObjectFile *module_obj_file = module_sp->GetObjectFile(); 2754*0b57cec5SDimitry Andric if (module_obj_file && module_obj_file != this) 27554824e7fdSDimitry Andric return module_obj_file->ParseSymtab(lldb_symtab); 2756*0b57cec5SDimitry Andric 2757*0b57cec5SDimitry Andric SectionList *section_list = module_sp->GetSectionList(); 2758*0b57cec5SDimitry Andric if (!section_list) 27594824e7fdSDimitry Andric return; 2760*0b57cec5SDimitry Andric 2761*0b57cec5SDimitry Andric uint64_t symbol_id = 0; 2762*0b57cec5SDimitry Andric 2763*0b57cec5SDimitry Andric // Sharable objects and dynamic executables usually have 2 distinct symbol 2764*0b57cec5SDimitry Andric // tables, one named ".symtab", and the other ".dynsym". The dynsym is a 2765*0b57cec5SDimitry Andric // smaller version of the symtab that only contains global symbols. The 2766*0b57cec5SDimitry Andric // information found in the dynsym is therefore also found in the symtab, 2767*0b57cec5SDimitry Andric // while the reverse is not necessarily true. 2768*0b57cec5SDimitry Andric Section *symtab = 2769*0b57cec5SDimitry Andric section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get(); 27704824e7fdSDimitry Andric if (symtab) 27714824e7fdSDimitry Andric symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, symtab); 2772*0b57cec5SDimitry Andric 27739dba64beSDimitry Andric // The symtab section is non-allocable and can be stripped, while the 27749dba64beSDimitry Andric // .dynsym section which should always be always be there. To support the 27759dba64beSDimitry Andric // minidebuginfo case we parse .dynsym when there's a .gnu_debuginfo 27769dba64beSDimitry Andric // section, nomatter if .symtab was already parsed or not. This is because 27779dba64beSDimitry Andric // minidebuginfo normally removes the .symtab symbols which have their 27789dba64beSDimitry Andric // matching .dynsym counterparts. 27799dba64beSDimitry Andric if (!symtab || 27809dba64beSDimitry Andric GetSectionList()->FindSectionByName(ConstString(".gnu_debugdata"))) { 27819dba64beSDimitry Andric Section *dynsym = 27829dba64beSDimitry Andric section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true) 27839dba64beSDimitry Andric .get(); 27844824e7fdSDimitry Andric if (dynsym) 27854824e7fdSDimitry Andric symbol_id += ParseSymbolTable(&lldb_symtab, symbol_id, dynsym); 27869dba64beSDimitry Andric } 27879dba64beSDimitry Andric 2788*0b57cec5SDimitry Andric // DT_JMPREL 2789*0b57cec5SDimitry Andric // If present, this entry's d_ptr member holds the address of 2790*0b57cec5SDimitry Andric // relocation 2791*0b57cec5SDimitry Andric // entries associated solely with the procedure linkage table. 2792*0b57cec5SDimitry Andric // Separating 2793*0b57cec5SDimitry Andric // these relocation entries lets the dynamic linker ignore them during 2794*0b57cec5SDimitry Andric // process initialization, if lazy binding is enabled. If this entry is 2795*0b57cec5SDimitry Andric // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must 2796*0b57cec5SDimitry Andric // also be present. 2797*0b57cec5SDimitry Andric const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL); 2798*0b57cec5SDimitry Andric if (symbol) { 2799*0b57cec5SDimitry Andric // Synthesize trampoline symbols to help navigate the PLT. 2800*0b57cec5SDimitry Andric addr_t addr = symbol->d_ptr; 2801*0b57cec5SDimitry Andric Section *reloc_section = 2802*0b57cec5SDimitry Andric section_list->FindSectionContainingFileAddress(addr).get(); 2803*0b57cec5SDimitry Andric if (reloc_section) { 2804*0b57cec5SDimitry Andric user_id_t reloc_id = reloc_section->GetID(); 2805*0b57cec5SDimitry Andric const ELFSectionHeaderInfo *reloc_header = 2806*0b57cec5SDimitry Andric GetSectionHeaderByIndex(reloc_id); 28074824e7fdSDimitry Andric if (reloc_header) 28084824e7fdSDimitry Andric ParseTrampolineSymbols(&lldb_symtab, symbol_id, reloc_header, reloc_id); 2809*0b57cec5SDimitry Andric } 2810fe6060f1SDimitry Andric } 2811*0b57cec5SDimitry Andric 2812*0b57cec5SDimitry Andric if (DWARFCallFrameInfo *eh_frame = 2813*0b57cec5SDimitry Andric GetModule()->GetUnwindTable().GetEHFrameInfo()) { 28144824e7fdSDimitry Andric ParseUnwindSymbols(&lldb_symtab, eh_frame); 2815*0b57cec5SDimitry Andric } 2816*0b57cec5SDimitry Andric 28179dba64beSDimitry Andric // In the event that there's no symbol entry for the entry point we'll 28185ffd83dbSDimitry Andric // artificially create one. We delegate to the symtab object the figuring 28199dba64beSDimitry Andric // out of the proper size, this will usually make it span til the next 28209dba64beSDimitry Andric // symbol it finds in the section. This means that if there are missing 28219dba64beSDimitry Andric // symbols the entry point might span beyond its function definition. 28229dba64beSDimitry Andric // We're fine with this as it doesn't make it worse than not having a 28239dba64beSDimitry Andric // symbol entry at all. 28249dba64beSDimitry Andric if (CalculateType() == eTypeExecutable) { 28259dba64beSDimitry Andric ArchSpec arch = GetArchitecture(); 28269dba64beSDimitry Andric auto entry_point_addr = GetEntryPointAddress(); 28279dba64beSDimitry Andric bool is_valid_entry_point = 28289dba64beSDimitry Andric entry_point_addr.IsValid() && entry_point_addr.IsSectionOffset(); 28299dba64beSDimitry Andric addr_t entry_point_file_addr = entry_point_addr.GetFileAddress(); 28304824e7fdSDimitry Andric if (is_valid_entry_point && !lldb_symtab.FindSymbolContainingFileAddress( 28319dba64beSDimitry Andric entry_point_file_addr)) { 28324824e7fdSDimitry Andric uint64_t symbol_id = lldb_symtab.GetNumSymbols(); 2833fe6060f1SDimitry Andric // Don't set the name for any synthetic symbols, the Symbol 2834fe6060f1SDimitry Andric // object will generate one if needed when the name is accessed 2835fe6060f1SDimitry Andric // via accessors. 2836fe6060f1SDimitry Andric SectionSP section_sp = entry_point_addr.GetSection(); 2837fe6060f1SDimitry Andric Symbol symbol( 2838fe6060f1SDimitry Andric /*symID=*/symbol_id, 2839fe6060f1SDimitry Andric /*name=*/llvm::StringRef(), // Name will be auto generated. 2840fe6060f1SDimitry Andric /*type=*/eSymbolTypeCode, 2841fe6060f1SDimitry Andric /*external=*/true, 2842fe6060f1SDimitry Andric /*is_debug=*/false, 2843fe6060f1SDimitry Andric /*is_trampoline=*/false, 2844fe6060f1SDimitry Andric /*is_artificial=*/true, 2845fe6060f1SDimitry Andric /*section_sp=*/section_sp, 2846fe6060f1SDimitry Andric /*offset=*/0, 2847fe6060f1SDimitry Andric /*size=*/0, // FDE can span multiple symbols so don't use its size. 2848fe6060f1SDimitry Andric /*size_is_valid=*/false, 2849fe6060f1SDimitry Andric /*contains_linker_annotations=*/false, 2850fe6060f1SDimitry Andric /*flags=*/0); 28519dba64beSDimitry Andric // When the entry point is arm thumb we need to explicitly set its 28529dba64beSDimitry Andric // class address to reflect that. This is important because expression 28539dba64beSDimitry Andric // evaluation relies on correctly setting a breakpoint at this 28549dba64beSDimitry Andric // address. 28559dba64beSDimitry Andric if (arch.GetMachine() == llvm::Triple::arm && 2856fe6060f1SDimitry Andric (entry_point_file_addr & 1)) { 2857fe6060f1SDimitry Andric symbol.GetAddressRef().SetOffset(entry_point_addr.GetOffset() ^ 1); 28589dba64beSDimitry Andric m_address_class_map[entry_point_file_addr ^ 1] = 28599dba64beSDimitry Andric AddressClass::eCodeAlternateISA; 2860fe6060f1SDimitry Andric } else { 28619dba64beSDimitry Andric m_address_class_map[entry_point_file_addr] = AddressClass::eCode; 28629dba64beSDimitry Andric } 28634824e7fdSDimitry Andric lldb_symtab.AddSymbol(symbol); 2864fe6060f1SDimitry Andric } 28659dba64beSDimitry Andric } 2866*0b57cec5SDimitry Andric } 2867*0b57cec5SDimitry Andric 2868*0b57cec5SDimitry Andric void ObjectFileELF::RelocateSection(lldb_private::Section *section) 2869*0b57cec5SDimitry Andric { 2870*0b57cec5SDimitry Andric static const char *debug_prefix = ".debug"; 2871*0b57cec5SDimitry Andric 2872*0b57cec5SDimitry Andric // Set relocated bit so we stop getting called, regardless of whether we 2873*0b57cec5SDimitry Andric // actually relocate. 2874*0b57cec5SDimitry Andric section->SetIsRelocated(true); 2875*0b57cec5SDimitry Andric 2876*0b57cec5SDimitry Andric // We only relocate in ELF relocatable files 2877*0b57cec5SDimitry Andric if (CalculateType() != eTypeObjectFile) 2878*0b57cec5SDimitry Andric return; 2879*0b57cec5SDimitry Andric 2880*0b57cec5SDimitry Andric const char *section_name = section->GetName().GetCString(); 2881*0b57cec5SDimitry Andric // Can't relocate that which can't be named 2882*0b57cec5SDimitry Andric if (section_name == nullptr) 2883*0b57cec5SDimitry Andric return; 2884*0b57cec5SDimitry Andric 2885*0b57cec5SDimitry Andric // We don't relocate non-debug sections at the moment 2886*0b57cec5SDimitry Andric if (strncmp(section_name, debug_prefix, strlen(debug_prefix))) 2887*0b57cec5SDimitry Andric return; 2888*0b57cec5SDimitry Andric 2889*0b57cec5SDimitry Andric // Relocation section names to look for 2890*0b57cec5SDimitry Andric std::string needle = std::string(".rel") + section_name; 2891*0b57cec5SDimitry Andric std::string needlea = std::string(".rela") + section_name; 2892*0b57cec5SDimitry Andric 2893*0b57cec5SDimitry Andric for (SectionHeaderCollIter I = m_section_headers.begin(); 2894*0b57cec5SDimitry Andric I != m_section_headers.end(); ++I) { 2895*0b57cec5SDimitry Andric if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL) { 2896*0b57cec5SDimitry Andric const char *hay_name = I->section_name.GetCString(); 2897*0b57cec5SDimitry Andric if (hay_name == nullptr) 2898*0b57cec5SDimitry Andric continue; 2899*0b57cec5SDimitry Andric if (needle == hay_name || needlea == hay_name) { 2900*0b57cec5SDimitry Andric const ELFSectionHeader &reloc_header = *I; 2901*0b57cec5SDimitry Andric user_id_t reloc_id = SectionIndex(I); 2902*0b57cec5SDimitry Andric RelocateDebugSections(&reloc_header, reloc_id, GetSymtab()); 2903*0b57cec5SDimitry Andric break; 2904*0b57cec5SDimitry Andric } 2905*0b57cec5SDimitry Andric } 2906*0b57cec5SDimitry Andric } 2907*0b57cec5SDimitry Andric } 2908*0b57cec5SDimitry Andric 2909*0b57cec5SDimitry Andric void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table, 2910*0b57cec5SDimitry Andric DWARFCallFrameInfo *eh_frame) { 2911*0b57cec5SDimitry Andric SectionList *section_list = GetSectionList(); 2912*0b57cec5SDimitry Andric if (!section_list) 2913*0b57cec5SDimitry Andric return; 2914*0b57cec5SDimitry Andric 2915*0b57cec5SDimitry Andric // First we save the new symbols into a separate list and add them to the 29165ffd83dbSDimitry Andric // symbol table after we collected all symbols we want to add. This is 2917*0b57cec5SDimitry Andric // neccessary because adding a new symbol invalidates the internal index of 2918*0b57cec5SDimitry Andric // the symtab what causing the next lookup to be slow because it have to 2919*0b57cec5SDimitry Andric // recalculate the index first. 2920*0b57cec5SDimitry Andric std::vector<Symbol> new_symbols; 2921*0b57cec5SDimitry Andric 2922fe6060f1SDimitry Andric size_t num_symbols = symbol_table->GetNumSymbols(); 2923fe6060f1SDimitry Andric uint64_t last_symbol_id = 2924fe6060f1SDimitry Andric num_symbols ? symbol_table->SymbolAtIndex(num_symbols - 1)->GetID() : 0; 2925fe6060f1SDimitry Andric eh_frame->ForEachFDEEntries([&](lldb::addr_t file_addr, uint32_t size, 2926fe6060f1SDimitry Andric dw_offset_t) { 2927*0b57cec5SDimitry Andric Symbol *symbol = symbol_table->FindSymbolAtFileAddress(file_addr); 2928*0b57cec5SDimitry Andric if (symbol) { 2929*0b57cec5SDimitry Andric if (!symbol->GetByteSizeIsValid()) { 2930*0b57cec5SDimitry Andric symbol->SetByteSize(size); 2931*0b57cec5SDimitry Andric symbol->SetSizeIsSynthesized(true); 2932*0b57cec5SDimitry Andric } 2933*0b57cec5SDimitry Andric } else { 2934*0b57cec5SDimitry Andric SectionSP section_sp = 2935*0b57cec5SDimitry Andric section_list->FindSectionContainingFileAddress(file_addr); 2936*0b57cec5SDimitry Andric if (section_sp) { 2937*0b57cec5SDimitry Andric addr_t offset = file_addr - section_sp->GetFileAddress(); 2938fe6060f1SDimitry Andric uint64_t symbol_id = ++last_symbol_id; 2939fe6060f1SDimitry Andric // Don't set the name for any synthetic symbols, the Symbol 2940fe6060f1SDimitry Andric // object will generate one if needed when the name is accessed 2941fe6060f1SDimitry Andric // via accessors. 2942*0b57cec5SDimitry Andric Symbol eh_symbol( 2943fe6060f1SDimitry Andric /*symID=*/symbol_id, 2944fe6060f1SDimitry Andric /*name=*/llvm::StringRef(), // Name will be auto generated. 2945fe6060f1SDimitry Andric /*type=*/eSymbolTypeCode, 2946fe6060f1SDimitry Andric /*external=*/true, 2947fe6060f1SDimitry Andric /*is_debug=*/false, 2948fe6060f1SDimitry Andric /*is_trampoline=*/false, 2949fe6060f1SDimitry Andric /*is_artificial=*/true, 2950fe6060f1SDimitry Andric /*section_sp=*/section_sp, 2951fe6060f1SDimitry Andric /*offset=*/offset, 2952fe6060f1SDimitry Andric /*size=*/0, // FDE can span multiple symbols so don't use its size. 2953fe6060f1SDimitry Andric /*size_is_valid=*/false, 2954fe6060f1SDimitry Andric /*contains_linker_annotations=*/false, 2955fe6060f1SDimitry Andric /*flags=*/0); 2956*0b57cec5SDimitry Andric new_symbols.push_back(eh_symbol); 2957*0b57cec5SDimitry Andric } 2958*0b57cec5SDimitry Andric } 2959*0b57cec5SDimitry Andric return true; 2960*0b57cec5SDimitry Andric }); 2961*0b57cec5SDimitry Andric 2962*0b57cec5SDimitry Andric for (const Symbol &s : new_symbols) 2963*0b57cec5SDimitry Andric symbol_table->AddSymbol(s); 2964*0b57cec5SDimitry Andric } 2965*0b57cec5SDimitry Andric 2966*0b57cec5SDimitry Andric bool ObjectFileELF::IsStripped() { 2967*0b57cec5SDimitry Andric // TODO: determine this for ELF 2968*0b57cec5SDimitry Andric return false; 2969*0b57cec5SDimitry Andric } 2970*0b57cec5SDimitry Andric 2971*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 2972*0b57cec5SDimitry Andric // Dump 2973*0b57cec5SDimitry Andric // 2974*0b57cec5SDimitry Andric // Dump the specifics of the runtime file container (such as any headers 2975*0b57cec5SDimitry Andric // segments, sections, etc). 2976*0b57cec5SDimitry Andric void ObjectFileELF::Dump(Stream *s) { 2977*0b57cec5SDimitry Andric ModuleSP module_sp(GetModule()); 2978*0b57cec5SDimitry Andric if (!module_sp) { 2979*0b57cec5SDimitry Andric return; 2980*0b57cec5SDimitry Andric } 2981*0b57cec5SDimitry Andric 2982*0b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); 2983*0b57cec5SDimitry Andric s->Printf("%p: ", static_cast<void *>(this)); 2984*0b57cec5SDimitry Andric s->Indent(); 2985*0b57cec5SDimitry Andric s->PutCString("ObjectFileELF"); 2986*0b57cec5SDimitry Andric 2987*0b57cec5SDimitry Andric ArchSpec header_arch = GetArchitecture(); 2988*0b57cec5SDimitry Andric 2989*0b57cec5SDimitry Andric *s << ", file = '" << m_file 2990*0b57cec5SDimitry Andric << "', arch = " << header_arch.GetArchitectureName() << "\n"; 2991*0b57cec5SDimitry Andric 2992*0b57cec5SDimitry Andric DumpELFHeader(s, m_header); 2993*0b57cec5SDimitry Andric s->EOL(); 2994*0b57cec5SDimitry Andric DumpELFProgramHeaders(s); 2995*0b57cec5SDimitry Andric s->EOL(); 2996*0b57cec5SDimitry Andric DumpELFSectionHeaders(s); 2997*0b57cec5SDimitry Andric s->EOL(); 2998*0b57cec5SDimitry Andric SectionList *section_list = GetSectionList(); 2999*0b57cec5SDimitry Andric if (section_list) 30005ffd83dbSDimitry Andric section_list->Dump(s->AsRawOstream(), s->GetIndentLevel(), nullptr, true, 30015ffd83dbSDimitry Andric UINT32_MAX); 3002*0b57cec5SDimitry Andric Symtab *symtab = GetSymtab(); 3003*0b57cec5SDimitry Andric if (symtab) 3004*0b57cec5SDimitry Andric symtab->Dump(s, nullptr, eSortOrderNone); 3005*0b57cec5SDimitry Andric s->EOL(); 3006*0b57cec5SDimitry Andric DumpDependentModules(s); 3007*0b57cec5SDimitry Andric s->EOL(); 3008*0b57cec5SDimitry Andric } 3009*0b57cec5SDimitry Andric 3010*0b57cec5SDimitry Andric // DumpELFHeader 3011*0b57cec5SDimitry Andric // 3012*0b57cec5SDimitry Andric // Dump the ELF header to the specified output stream 3013*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) { 3014*0b57cec5SDimitry Andric s->PutCString("ELF Header\n"); 3015*0b57cec5SDimitry Andric s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]); 3016*0b57cec5SDimitry Andric s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG1], 3017*0b57cec5SDimitry Andric header.e_ident[EI_MAG1]); 3018*0b57cec5SDimitry Andric s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG2], 3019*0b57cec5SDimitry Andric header.e_ident[EI_MAG2]); 3020*0b57cec5SDimitry Andric s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG3], 3021*0b57cec5SDimitry Andric header.e_ident[EI_MAG3]); 3022*0b57cec5SDimitry Andric 3023*0b57cec5SDimitry Andric s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]); 3024*0b57cec5SDimitry Andric s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]); 3025*0b57cec5SDimitry Andric DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]); 3026*0b57cec5SDimitry Andric s->Printf("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]); 3027*0b57cec5SDimitry Andric s->Printf("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]); 3028*0b57cec5SDimitry Andric 3029*0b57cec5SDimitry Andric s->Printf("e_type = 0x%4.4x ", header.e_type); 3030*0b57cec5SDimitry Andric DumpELFHeader_e_type(s, header.e_type); 3031*0b57cec5SDimitry Andric s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine); 3032*0b57cec5SDimitry Andric s->Printf("e_version = 0x%8.8x\n", header.e_version); 3033*0b57cec5SDimitry Andric s->Printf("e_entry = 0x%8.8" PRIx64 "\n", header.e_entry); 3034*0b57cec5SDimitry Andric s->Printf("e_phoff = 0x%8.8" PRIx64 "\n", header.e_phoff); 3035*0b57cec5SDimitry Andric s->Printf("e_shoff = 0x%8.8" PRIx64 "\n", header.e_shoff); 3036*0b57cec5SDimitry Andric s->Printf("e_flags = 0x%8.8x\n", header.e_flags); 3037*0b57cec5SDimitry Andric s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize); 3038*0b57cec5SDimitry Andric s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize); 3039*0b57cec5SDimitry Andric s->Printf("e_phnum = 0x%8.8x\n", header.e_phnum); 3040*0b57cec5SDimitry Andric s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize); 3041*0b57cec5SDimitry Andric s->Printf("e_shnum = 0x%8.8x\n", header.e_shnum); 3042*0b57cec5SDimitry Andric s->Printf("e_shstrndx = 0x%8.8x\n", header.e_shstrndx); 3043*0b57cec5SDimitry Andric } 3044*0b57cec5SDimitry Andric 3045*0b57cec5SDimitry Andric // DumpELFHeader_e_type 3046*0b57cec5SDimitry Andric // 3047*0b57cec5SDimitry Andric // Dump an token value for the ELF header member e_type 3048*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type) { 3049*0b57cec5SDimitry Andric switch (e_type) { 3050*0b57cec5SDimitry Andric case ET_NONE: 3051*0b57cec5SDimitry Andric *s << "ET_NONE"; 3052*0b57cec5SDimitry Andric break; 3053*0b57cec5SDimitry Andric case ET_REL: 3054*0b57cec5SDimitry Andric *s << "ET_REL"; 3055*0b57cec5SDimitry Andric break; 3056*0b57cec5SDimitry Andric case ET_EXEC: 3057*0b57cec5SDimitry Andric *s << "ET_EXEC"; 3058*0b57cec5SDimitry Andric break; 3059*0b57cec5SDimitry Andric case ET_DYN: 3060*0b57cec5SDimitry Andric *s << "ET_DYN"; 3061*0b57cec5SDimitry Andric break; 3062*0b57cec5SDimitry Andric case ET_CORE: 3063*0b57cec5SDimitry Andric *s << "ET_CORE"; 3064*0b57cec5SDimitry Andric break; 3065*0b57cec5SDimitry Andric default: 3066*0b57cec5SDimitry Andric break; 3067*0b57cec5SDimitry Andric } 3068*0b57cec5SDimitry Andric } 3069*0b57cec5SDimitry Andric 3070*0b57cec5SDimitry Andric // DumpELFHeader_e_ident_EI_DATA 3071*0b57cec5SDimitry Andric // 3072*0b57cec5SDimitry Andric // Dump an token value for the ELF header member e_ident[EI_DATA] 3073*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, 3074*0b57cec5SDimitry Andric unsigned char ei_data) { 3075*0b57cec5SDimitry Andric switch (ei_data) { 3076*0b57cec5SDimitry Andric case ELFDATANONE: 3077*0b57cec5SDimitry Andric *s << "ELFDATANONE"; 3078*0b57cec5SDimitry Andric break; 3079*0b57cec5SDimitry Andric case ELFDATA2LSB: 3080*0b57cec5SDimitry Andric *s << "ELFDATA2LSB - Little Endian"; 3081*0b57cec5SDimitry Andric break; 3082*0b57cec5SDimitry Andric case ELFDATA2MSB: 3083*0b57cec5SDimitry Andric *s << "ELFDATA2MSB - Big Endian"; 3084*0b57cec5SDimitry Andric break; 3085*0b57cec5SDimitry Andric default: 3086*0b57cec5SDimitry Andric break; 3087*0b57cec5SDimitry Andric } 3088*0b57cec5SDimitry Andric } 3089*0b57cec5SDimitry Andric 3090*0b57cec5SDimitry Andric // DumpELFProgramHeader 3091*0b57cec5SDimitry Andric // 3092*0b57cec5SDimitry Andric // Dump a single ELF program header to the specified output stream 3093*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFProgramHeader(Stream *s, 3094*0b57cec5SDimitry Andric const ELFProgramHeader &ph) { 3095*0b57cec5SDimitry Andric DumpELFProgramHeader_p_type(s, ph.p_type); 3096*0b57cec5SDimitry Andric s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, ph.p_offset, 3097*0b57cec5SDimitry Andric ph.p_vaddr, ph.p_paddr); 3098*0b57cec5SDimitry Andric s->Printf(" %8.8" PRIx64 " %8.8" PRIx64 " %8.8x (", ph.p_filesz, ph.p_memsz, 3099*0b57cec5SDimitry Andric ph.p_flags); 3100*0b57cec5SDimitry Andric 3101*0b57cec5SDimitry Andric DumpELFProgramHeader_p_flags(s, ph.p_flags); 3102*0b57cec5SDimitry Andric s->Printf(") %8.8" PRIx64, ph.p_align); 3103*0b57cec5SDimitry Andric } 3104*0b57cec5SDimitry Andric 3105*0b57cec5SDimitry Andric // DumpELFProgramHeader_p_type 3106*0b57cec5SDimitry Andric // 3107*0b57cec5SDimitry Andric // Dump an token value for the ELF program header member p_type which describes 3108*0b57cec5SDimitry Andric // the type of the program header 3109*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) { 3110*0b57cec5SDimitry Andric const int kStrWidth = 15; 3111*0b57cec5SDimitry Andric switch (p_type) { 3112*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_NULL, kStrWidth); 3113*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_LOAD, kStrWidth); 3114*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_DYNAMIC, kStrWidth); 3115*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_INTERP, kStrWidth); 3116*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_NOTE, kStrWidth); 3117*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_SHLIB, kStrWidth); 3118*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_PHDR, kStrWidth); 3119*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_TLS, kStrWidth); 3120*0b57cec5SDimitry Andric CASE_AND_STREAM(s, PT_GNU_EH_FRAME, kStrWidth); 3121*0b57cec5SDimitry Andric default: 3122*0b57cec5SDimitry Andric s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, ""); 3123*0b57cec5SDimitry Andric break; 3124*0b57cec5SDimitry Andric } 3125*0b57cec5SDimitry Andric } 3126*0b57cec5SDimitry Andric 3127*0b57cec5SDimitry Andric // DumpELFProgramHeader_p_flags 3128*0b57cec5SDimitry Andric // 3129*0b57cec5SDimitry Andric // Dump an token value for the ELF program header member p_flags 3130*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) { 3131*0b57cec5SDimitry Andric *s << ((p_flags & PF_X) ? "PF_X" : " ") 3132*0b57cec5SDimitry Andric << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ') 3133*0b57cec5SDimitry Andric << ((p_flags & PF_W) ? "PF_W" : " ") 3134*0b57cec5SDimitry Andric << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ') 3135*0b57cec5SDimitry Andric << ((p_flags & PF_R) ? "PF_R" : " "); 3136*0b57cec5SDimitry Andric } 3137*0b57cec5SDimitry Andric 3138*0b57cec5SDimitry Andric // DumpELFProgramHeaders 3139*0b57cec5SDimitry Andric // 3140*0b57cec5SDimitry Andric // Dump all of the ELF program header to the specified output stream 3141*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFProgramHeaders(Stream *s) { 3142*0b57cec5SDimitry Andric if (!ParseProgramHeaders()) 3143*0b57cec5SDimitry Andric return; 3144*0b57cec5SDimitry Andric 3145*0b57cec5SDimitry Andric s->PutCString("Program Headers\n"); 3146*0b57cec5SDimitry Andric s->PutCString("IDX p_type p_offset p_vaddr p_paddr " 3147*0b57cec5SDimitry Andric "p_filesz p_memsz p_flags p_align\n"); 3148*0b57cec5SDimitry Andric s->PutCString("==== --------------- -------- -------- -------- " 3149*0b57cec5SDimitry Andric "-------- -------- ------------------------- --------\n"); 3150*0b57cec5SDimitry Andric 3151*0b57cec5SDimitry Andric for (const auto &H : llvm::enumerate(m_program_headers)) { 3152*0b57cec5SDimitry Andric s->Format("[{0,2}] ", H.index()); 3153*0b57cec5SDimitry Andric ObjectFileELF::DumpELFProgramHeader(s, H.value()); 3154*0b57cec5SDimitry Andric s->EOL(); 3155*0b57cec5SDimitry Andric } 3156*0b57cec5SDimitry Andric } 3157*0b57cec5SDimitry Andric 3158*0b57cec5SDimitry Andric // DumpELFSectionHeader 3159*0b57cec5SDimitry Andric // 3160*0b57cec5SDimitry Andric // Dump a single ELF section header to the specified output stream 3161*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFSectionHeader(Stream *s, 3162*0b57cec5SDimitry Andric const ELFSectionHeaderInfo &sh) { 3163*0b57cec5SDimitry Andric s->Printf("%8.8x ", sh.sh_name); 3164*0b57cec5SDimitry Andric DumpELFSectionHeader_sh_type(s, sh.sh_type); 3165*0b57cec5SDimitry Andric s->Printf(" %8.8" PRIx64 " (", sh.sh_flags); 3166*0b57cec5SDimitry Andric DumpELFSectionHeader_sh_flags(s, sh.sh_flags); 3167*0b57cec5SDimitry Andric s->Printf(") %8.8" PRIx64 " %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addr, 3168*0b57cec5SDimitry Andric sh.sh_offset, sh.sh_size); 3169*0b57cec5SDimitry Andric s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info); 3170*0b57cec5SDimitry Andric s->Printf(" %8.8" PRIx64 " %8.8" PRIx64, sh.sh_addralign, sh.sh_entsize); 3171*0b57cec5SDimitry Andric } 3172*0b57cec5SDimitry Andric 3173*0b57cec5SDimitry Andric // DumpELFSectionHeader_sh_type 3174*0b57cec5SDimitry Andric // 3175*0b57cec5SDimitry Andric // Dump an token value for the ELF section header member sh_type which 3176*0b57cec5SDimitry Andric // describes the type of the section 3177*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type) { 3178*0b57cec5SDimitry Andric const int kStrWidth = 12; 3179*0b57cec5SDimitry Andric switch (sh_type) { 3180*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_NULL, kStrWidth); 3181*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_PROGBITS, kStrWidth); 3182*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_SYMTAB, kStrWidth); 3183*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_STRTAB, kStrWidth); 3184*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_RELA, kStrWidth); 3185*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_HASH, kStrWidth); 3186*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_DYNAMIC, kStrWidth); 3187*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_NOTE, kStrWidth); 3188*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_NOBITS, kStrWidth); 3189*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_REL, kStrWidth); 3190*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_SHLIB, kStrWidth); 3191*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_DYNSYM, kStrWidth); 3192*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_LOPROC, kStrWidth); 3193*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_HIPROC, kStrWidth); 3194*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_LOUSER, kStrWidth); 3195*0b57cec5SDimitry Andric CASE_AND_STREAM(s, SHT_HIUSER, kStrWidth); 3196*0b57cec5SDimitry Andric default: 3197*0b57cec5SDimitry Andric s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, ""); 3198*0b57cec5SDimitry Andric break; 3199*0b57cec5SDimitry Andric } 3200*0b57cec5SDimitry Andric } 3201*0b57cec5SDimitry Andric 3202*0b57cec5SDimitry Andric // DumpELFSectionHeader_sh_flags 3203*0b57cec5SDimitry Andric // 3204*0b57cec5SDimitry Andric // Dump an token value for the ELF section header member sh_flags 3205*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, 3206*0b57cec5SDimitry Andric elf_xword sh_flags) { 3207*0b57cec5SDimitry Andric *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ") 3208*0b57cec5SDimitry Andric << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ') 3209*0b57cec5SDimitry Andric << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ") 3210*0b57cec5SDimitry Andric << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ') 3211*0b57cec5SDimitry Andric << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " "); 3212*0b57cec5SDimitry Andric } 3213*0b57cec5SDimitry Andric 3214*0b57cec5SDimitry Andric // DumpELFSectionHeaders 3215*0b57cec5SDimitry Andric // 3216*0b57cec5SDimitry Andric // Dump all of the ELF section header to the specified output stream 3217*0b57cec5SDimitry Andric void ObjectFileELF::DumpELFSectionHeaders(Stream *s) { 3218*0b57cec5SDimitry Andric if (!ParseSectionHeaders()) 3219*0b57cec5SDimitry Andric return; 3220*0b57cec5SDimitry Andric 3221*0b57cec5SDimitry Andric s->PutCString("Section Headers\n"); 3222*0b57cec5SDimitry Andric s->PutCString("IDX name type flags " 3223*0b57cec5SDimitry Andric "addr offset size link info addralgn " 3224*0b57cec5SDimitry Andric "entsize Name\n"); 3225*0b57cec5SDimitry Andric s->PutCString("==== -------- ------------ -------------------------------- " 3226*0b57cec5SDimitry Andric "-------- -------- -------- -------- -------- -------- " 3227*0b57cec5SDimitry Andric "-------- ====================\n"); 3228*0b57cec5SDimitry Andric 3229*0b57cec5SDimitry Andric uint32_t idx = 0; 3230*0b57cec5SDimitry Andric for (SectionHeaderCollConstIter I = m_section_headers.begin(); 3231*0b57cec5SDimitry Andric I != m_section_headers.end(); ++I, ++idx) { 3232*0b57cec5SDimitry Andric s->Printf("[%2u] ", idx); 3233*0b57cec5SDimitry Andric ObjectFileELF::DumpELFSectionHeader(s, *I); 3234*0b57cec5SDimitry Andric const char *section_name = I->section_name.AsCString(""); 3235*0b57cec5SDimitry Andric if (section_name) 3236*0b57cec5SDimitry Andric *s << ' ' << section_name << "\n"; 3237*0b57cec5SDimitry Andric } 3238*0b57cec5SDimitry Andric } 3239*0b57cec5SDimitry Andric 3240*0b57cec5SDimitry Andric void ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) { 3241*0b57cec5SDimitry Andric size_t num_modules = ParseDependentModules(); 3242*0b57cec5SDimitry Andric 3243*0b57cec5SDimitry Andric if (num_modules > 0) { 3244*0b57cec5SDimitry Andric s->PutCString("Dependent Modules:\n"); 3245*0b57cec5SDimitry Andric for (unsigned i = 0; i < num_modules; ++i) { 3246*0b57cec5SDimitry Andric const FileSpec &spec = m_filespec_up->GetFileSpecAtIndex(i); 3247*0b57cec5SDimitry Andric s->Printf(" %s\n", spec.GetFilename().GetCString()); 3248*0b57cec5SDimitry Andric } 3249*0b57cec5SDimitry Andric } 3250*0b57cec5SDimitry Andric } 3251*0b57cec5SDimitry Andric 3252*0b57cec5SDimitry Andric ArchSpec ObjectFileELF::GetArchitecture() { 3253*0b57cec5SDimitry Andric if (!ParseHeader()) 3254*0b57cec5SDimitry Andric return ArchSpec(); 3255*0b57cec5SDimitry Andric 3256*0b57cec5SDimitry Andric if (m_section_headers.empty()) { 3257*0b57cec5SDimitry Andric // Allow elf notes to be parsed which may affect the detected architecture. 3258*0b57cec5SDimitry Andric ParseSectionHeaders(); 3259*0b57cec5SDimitry Andric } 3260*0b57cec5SDimitry Andric 3261*0b57cec5SDimitry Andric if (CalculateType() == eTypeCoreFile && 3262*0b57cec5SDimitry Andric !m_arch_spec.TripleOSWasSpecified()) { 3263*0b57cec5SDimitry Andric // Core files don't have section headers yet they have PT_NOTE program 3264*0b57cec5SDimitry Andric // headers that might shed more light on the architecture 3265*0b57cec5SDimitry Andric for (const elf::ELFProgramHeader &H : ProgramHeaders()) { 3266*0b57cec5SDimitry Andric if (H.p_type != PT_NOTE || H.p_offset == 0 || H.p_filesz == 0) 3267*0b57cec5SDimitry Andric continue; 3268*0b57cec5SDimitry Andric DataExtractor data; 3269*0b57cec5SDimitry Andric if (data.SetData(m_data, H.p_offset, H.p_filesz) == H.p_filesz) { 3270*0b57cec5SDimitry Andric UUID uuid; 3271*0b57cec5SDimitry Andric RefineModuleDetailsFromNote(data, m_arch_spec, uuid); 3272*0b57cec5SDimitry Andric } 3273*0b57cec5SDimitry Andric } 3274*0b57cec5SDimitry Andric } 3275*0b57cec5SDimitry Andric return m_arch_spec; 3276*0b57cec5SDimitry Andric } 3277*0b57cec5SDimitry Andric 3278*0b57cec5SDimitry Andric ObjectFile::Type ObjectFileELF::CalculateType() { 3279*0b57cec5SDimitry Andric switch (m_header.e_type) { 3280*0b57cec5SDimitry Andric case llvm::ELF::ET_NONE: 3281*0b57cec5SDimitry Andric // 0 - No file type 3282*0b57cec5SDimitry Andric return eTypeUnknown; 3283*0b57cec5SDimitry Andric 3284*0b57cec5SDimitry Andric case llvm::ELF::ET_REL: 3285*0b57cec5SDimitry Andric // 1 - Relocatable file 3286*0b57cec5SDimitry Andric return eTypeObjectFile; 3287*0b57cec5SDimitry Andric 3288*0b57cec5SDimitry Andric case llvm::ELF::ET_EXEC: 3289*0b57cec5SDimitry Andric // 2 - Executable file 3290*0b57cec5SDimitry Andric return eTypeExecutable; 3291*0b57cec5SDimitry Andric 3292*0b57cec5SDimitry Andric case llvm::ELF::ET_DYN: 3293*0b57cec5SDimitry Andric // 3 - Shared object file 3294*0b57cec5SDimitry Andric return eTypeSharedLibrary; 3295*0b57cec5SDimitry Andric 3296*0b57cec5SDimitry Andric case ET_CORE: 3297*0b57cec5SDimitry Andric // 4 - Core file 3298*0b57cec5SDimitry Andric return eTypeCoreFile; 3299*0b57cec5SDimitry Andric 3300*0b57cec5SDimitry Andric default: 3301*0b57cec5SDimitry Andric break; 3302*0b57cec5SDimitry Andric } 3303*0b57cec5SDimitry Andric return eTypeUnknown; 3304*0b57cec5SDimitry Andric } 3305*0b57cec5SDimitry Andric 3306*0b57cec5SDimitry Andric ObjectFile::Strata ObjectFileELF::CalculateStrata() { 3307*0b57cec5SDimitry Andric switch (m_header.e_type) { 3308*0b57cec5SDimitry Andric case llvm::ELF::ET_NONE: 3309*0b57cec5SDimitry Andric // 0 - No file type 3310*0b57cec5SDimitry Andric return eStrataUnknown; 3311*0b57cec5SDimitry Andric 3312*0b57cec5SDimitry Andric case llvm::ELF::ET_REL: 3313*0b57cec5SDimitry Andric // 1 - Relocatable file 3314*0b57cec5SDimitry Andric return eStrataUnknown; 3315*0b57cec5SDimitry Andric 3316*0b57cec5SDimitry Andric case llvm::ELF::ET_EXEC: 3317*0b57cec5SDimitry Andric // 2 - Executable file 3318*0b57cec5SDimitry Andric // TODO: is there any way to detect that an executable is a kernel 3319*0b57cec5SDimitry Andric // related executable by inspecting the program headers, section headers, 3320*0b57cec5SDimitry Andric // symbols, or any other flag bits??? 3321*0b57cec5SDimitry Andric return eStrataUser; 3322*0b57cec5SDimitry Andric 3323*0b57cec5SDimitry Andric case llvm::ELF::ET_DYN: 3324*0b57cec5SDimitry Andric // 3 - Shared object file 3325*0b57cec5SDimitry Andric // TODO: is there any way to detect that an shared library is a kernel 3326*0b57cec5SDimitry Andric // related executable by inspecting the program headers, section headers, 3327*0b57cec5SDimitry Andric // symbols, or any other flag bits??? 3328*0b57cec5SDimitry Andric return eStrataUnknown; 3329*0b57cec5SDimitry Andric 3330*0b57cec5SDimitry Andric case ET_CORE: 3331*0b57cec5SDimitry Andric // 4 - Core file 3332*0b57cec5SDimitry Andric // TODO: is there any way to detect that an core file is a kernel 3333*0b57cec5SDimitry Andric // related executable by inspecting the program headers, section headers, 3334*0b57cec5SDimitry Andric // symbols, or any other flag bits??? 3335*0b57cec5SDimitry Andric return eStrataUnknown; 3336*0b57cec5SDimitry Andric 3337*0b57cec5SDimitry Andric default: 3338*0b57cec5SDimitry Andric break; 3339*0b57cec5SDimitry Andric } 3340*0b57cec5SDimitry Andric return eStrataUnknown; 3341*0b57cec5SDimitry Andric } 3342*0b57cec5SDimitry Andric 3343*0b57cec5SDimitry Andric size_t ObjectFileELF::ReadSectionData(Section *section, 3344*0b57cec5SDimitry Andric lldb::offset_t section_offset, void *dst, 3345*0b57cec5SDimitry Andric size_t dst_len) { 3346*0b57cec5SDimitry Andric // If some other objectfile owns this data, pass this to them. 3347*0b57cec5SDimitry Andric if (section->GetObjectFile() != this) 3348*0b57cec5SDimitry Andric return section->GetObjectFile()->ReadSectionData(section, section_offset, 3349*0b57cec5SDimitry Andric dst, dst_len); 3350*0b57cec5SDimitry Andric 3351*0b57cec5SDimitry Andric if (!section->Test(SHF_COMPRESSED)) 3352*0b57cec5SDimitry Andric return ObjectFile::ReadSectionData(section, section_offset, dst, dst_len); 3353*0b57cec5SDimitry Andric 3354*0b57cec5SDimitry Andric // For compressed sections we need to read to full data to be able to 3355*0b57cec5SDimitry Andric // decompress. 3356*0b57cec5SDimitry Andric DataExtractor data; 3357*0b57cec5SDimitry Andric ReadSectionData(section, data); 3358*0b57cec5SDimitry Andric return data.CopyData(section_offset, dst_len, dst); 3359*0b57cec5SDimitry Andric } 3360*0b57cec5SDimitry Andric 3361*0b57cec5SDimitry Andric size_t ObjectFileELF::ReadSectionData(Section *section, 3362*0b57cec5SDimitry Andric DataExtractor §ion_data) { 3363*0b57cec5SDimitry Andric // If some other objectfile owns this data, pass this to them. 3364*0b57cec5SDimitry Andric if (section->GetObjectFile() != this) 3365*0b57cec5SDimitry Andric return section->GetObjectFile()->ReadSectionData(section, section_data); 3366*0b57cec5SDimitry Andric 3367*0b57cec5SDimitry Andric size_t result = ObjectFile::ReadSectionData(section, section_data); 3368fcaf7f86SDimitry Andric if (result == 0 || !(section->Get() & llvm::ELF::SHF_COMPRESSED)) 3369*0b57cec5SDimitry Andric return result; 3370*0b57cec5SDimitry Andric 3371*0b57cec5SDimitry Andric auto Decompressor = llvm::object::Decompressor::create( 3372*0b57cec5SDimitry Andric section->GetName().GetStringRef(), 3373*0b57cec5SDimitry Andric {reinterpret_cast<const char *>(section_data.GetDataStart()), 3374*0b57cec5SDimitry Andric size_t(section_data.GetByteSize())}, 3375*0b57cec5SDimitry Andric GetByteOrder() == eByteOrderLittle, GetAddressByteSize() == 8); 3376*0b57cec5SDimitry Andric if (!Decompressor) { 3377*0b57cec5SDimitry Andric GetModule()->ReportWarning( 3378*0b57cec5SDimitry Andric "Unable to initialize decompressor for section '%s': %s", 3379*0b57cec5SDimitry Andric section->GetName().GetCString(), 3380*0b57cec5SDimitry Andric llvm::toString(Decompressor.takeError()).c_str()); 3381*0b57cec5SDimitry Andric section_data.Clear(); 3382*0b57cec5SDimitry Andric return 0; 3383*0b57cec5SDimitry Andric } 3384*0b57cec5SDimitry Andric 3385*0b57cec5SDimitry Andric auto buffer_sp = 3386*0b57cec5SDimitry Andric std::make_shared<DataBufferHeap>(Decompressor->getDecompressedSize(), 0); 3387*0b57cec5SDimitry Andric if (auto error = Decompressor->decompress( 3388753f127fSDimitry Andric {buffer_sp->GetBytes(), size_t(buffer_sp->GetByteSize())})) { 3389*0b57cec5SDimitry Andric GetModule()->ReportWarning( 3390*0b57cec5SDimitry Andric "Decompression of section '%s' failed: %s", 3391*0b57cec5SDimitry Andric section->GetName().GetCString(), 3392*0b57cec5SDimitry Andric llvm::toString(std::move(error)).c_str()); 3393*0b57cec5SDimitry Andric section_data.Clear(); 3394*0b57cec5SDimitry Andric return 0; 3395*0b57cec5SDimitry Andric } 3396*0b57cec5SDimitry Andric 3397*0b57cec5SDimitry Andric section_data.SetData(buffer_sp); 3398*0b57cec5SDimitry Andric return buffer_sp->GetByteSize(); 3399*0b57cec5SDimitry Andric } 3400*0b57cec5SDimitry Andric 3401*0b57cec5SDimitry Andric llvm::ArrayRef<ELFProgramHeader> ObjectFileELF::ProgramHeaders() { 3402*0b57cec5SDimitry Andric ParseProgramHeaders(); 3403*0b57cec5SDimitry Andric return m_program_headers; 3404*0b57cec5SDimitry Andric } 3405*0b57cec5SDimitry Andric 3406*0b57cec5SDimitry Andric DataExtractor ObjectFileELF::GetSegmentData(const ELFProgramHeader &H) { 3407*0b57cec5SDimitry Andric return DataExtractor(m_data, H.p_offset, H.p_filesz); 3408*0b57cec5SDimitry Andric } 3409*0b57cec5SDimitry Andric 3410*0b57cec5SDimitry Andric bool ObjectFileELF::AnySegmentHasPhysicalAddress() { 3411*0b57cec5SDimitry Andric for (const ELFProgramHeader &H : ProgramHeaders()) { 3412*0b57cec5SDimitry Andric if (H.p_paddr != 0) 3413*0b57cec5SDimitry Andric return true; 3414*0b57cec5SDimitry Andric } 3415*0b57cec5SDimitry Andric return false; 3416*0b57cec5SDimitry Andric } 3417*0b57cec5SDimitry Andric 3418*0b57cec5SDimitry Andric std::vector<ObjectFile::LoadableData> 3419*0b57cec5SDimitry Andric ObjectFileELF::GetLoadableData(Target &target) { 3420*0b57cec5SDimitry Andric // Create a list of loadable data from loadable segments, using physical 3421*0b57cec5SDimitry Andric // addresses if they aren't all null 3422*0b57cec5SDimitry Andric std::vector<LoadableData> loadables; 3423*0b57cec5SDimitry Andric bool should_use_paddr = AnySegmentHasPhysicalAddress(); 3424*0b57cec5SDimitry Andric for (const ELFProgramHeader &H : ProgramHeaders()) { 3425*0b57cec5SDimitry Andric LoadableData loadable; 3426*0b57cec5SDimitry Andric if (H.p_type != llvm::ELF::PT_LOAD) 3427*0b57cec5SDimitry Andric continue; 3428*0b57cec5SDimitry Andric loadable.Dest = should_use_paddr ? H.p_paddr : H.p_vaddr; 3429*0b57cec5SDimitry Andric if (loadable.Dest == LLDB_INVALID_ADDRESS) 3430*0b57cec5SDimitry Andric continue; 3431*0b57cec5SDimitry Andric if (H.p_filesz == 0) 3432*0b57cec5SDimitry Andric continue; 3433*0b57cec5SDimitry Andric auto segment_data = GetSegmentData(H); 3434*0b57cec5SDimitry Andric loadable.Contents = llvm::ArrayRef<uint8_t>(segment_data.GetDataStart(), 3435*0b57cec5SDimitry Andric segment_data.GetByteSize()); 3436*0b57cec5SDimitry Andric loadables.push_back(loadable); 3437*0b57cec5SDimitry Andric } 3438*0b57cec5SDimitry Andric return loadables; 3439*0b57cec5SDimitry Andric } 344081ad6265SDimitry Andric 344181ad6265SDimitry Andric lldb::WritableDataBufferSP 344281ad6265SDimitry Andric ObjectFileELF::MapFileDataWritable(const FileSpec &file, uint64_t Size, 344381ad6265SDimitry Andric uint64_t Offset) { 344481ad6265SDimitry Andric return FileSystem::Instance().CreateWritableDataBuffer(file.GetPath(), Size, 344581ad6265SDimitry Andric Offset); 344681ad6265SDimitry Andric } 3447