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