File: | tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp |
Warning: | line 2318, column 7 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===-- ObjectFileELF.cpp ------------------------------------- -*- C++ -*-===// | |||
2 | // | |||
3 | // The LLVM Compiler Infrastructure | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | ||||
10 | #include "ObjectFileELF.h" | |||
11 | ||||
12 | #include <algorithm> | |||
13 | #include <cassert> | |||
14 | #include <unordered_map> | |||
15 | ||||
16 | #include "lldb/Core/FileSpecList.h" | |||
17 | #include "lldb/Core/Module.h" | |||
18 | #include "lldb/Core/ModuleSpec.h" | |||
19 | #include "lldb/Core/PluginManager.h" | |||
20 | #include "lldb/Core/Section.h" | |||
21 | #include "lldb/Symbol/DWARFCallFrameInfo.h" | |||
22 | #include "lldb/Symbol/SymbolContext.h" | |||
23 | #include "lldb/Target/SectionLoadList.h" | |||
24 | #include "lldb/Target/Target.h" | |||
25 | #include "lldb/Utility/ArchSpec.h" | |||
26 | #include "lldb/Utility/DataBufferHeap.h" | |||
27 | #include "lldb/Utility/Log.h" | |||
28 | #include "lldb/Utility/Status.h" | |||
29 | #include "lldb/Utility/Stream.h" | |||
30 | #include "lldb/Utility/Timer.h" | |||
31 | ||||
32 | #include "llvm/ADT/PointerUnion.h" | |||
33 | #include "llvm/ADT/StringRef.h" | |||
34 | #include "llvm/Object/Decompressor.h" | |||
35 | #include "llvm/Support/ARMBuildAttributes.h" | |||
36 | #include "llvm/Support/MathExtras.h" | |||
37 | #include "llvm/Support/MemoryBuffer.h" | |||
38 | #include "llvm/Support/MipsABIFlags.h" | |||
39 | ||||
40 | #define CASE_AND_STREAM(s, def, width)case def: s->Printf("%-*s", width, "def"); break; \ | |||
41 | case def: \ | |||
42 | s->Printf("%-*s", width, #def); \ | |||
43 | break; | |||
44 | ||||
45 | using namespace lldb; | |||
46 | using namespace lldb_private; | |||
47 | using namespace elf; | |||
48 | using namespace llvm::ELF; | |||
49 | ||||
50 | namespace { | |||
51 | ||||
52 | // ELF note owner definitions | |||
53 | const char *const LLDB_NT_OWNER_FREEBSD = "FreeBSD"; | |||
54 | const char *const LLDB_NT_OWNER_GNU = "GNU"; | |||
55 | const char *const LLDB_NT_OWNER_NETBSD = "NetBSD"; | |||
56 | const char *const LLDB_NT_OWNER_OPENBSD = "OpenBSD"; | |||
57 | const char *const LLDB_NT_OWNER_CSR = "csr"; | |||
58 | const char *const LLDB_NT_OWNER_ANDROID = "Android"; | |||
59 | const char *const LLDB_NT_OWNER_CORE = "CORE"; | |||
60 | const char *const LLDB_NT_OWNER_LINUX = "LINUX"; | |||
61 | ||||
62 | // ELF note type definitions | |||
63 | const elf_word LLDB_NT_FREEBSD_ABI_TAG = 0x01; | |||
64 | const elf_word LLDB_NT_FREEBSD_ABI_SIZE = 4; | |||
65 | ||||
66 | const elf_word LLDB_NT_GNU_ABI_TAG = 0x01; | |||
67 | const elf_word LLDB_NT_GNU_ABI_SIZE = 16; | |||
68 | ||||
69 | const elf_word LLDB_NT_GNU_BUILD_ID_TAG = 0x03; | |||
70 | ||||
71 | const elf_word LLDB_NT_NETBSD_ABI_TAG = 0x01; | |||
72 | const elf_word LLDB_NT_NETBSD_ABI_SIZE = 4; | |||
73 | ||||
74 | // GNU ABI note OS constants | |||
75 | const elf_word LLDB_NT_GNU_ABI_OS_LINUX = 0x00; | |||
76 | const elf_word LLDB_NT_GNU_ABI_OS_HURD = 0x01; | |||
77 | const elf_word LLDB_NT_GNU_ABI_OS_SOLARIS = 0x02; | |||
78 | ||||
79 | // LLDB_NT_OWNER_CORE and LLDB_NT_OWNER_LINUX note contants | |||
80 | #define NT_PRSTATUS1 1 | |||
81 | #define NT_PRFPREG2 2 | |||
82 | #define NT_PRPSINFO3 3 | |||
83 | #define NT_TASKSTRUCT4 4 | |||
84 | #define NT_AUXV6 6 | |||
85 | #define NT_SIGINFO0x53494749 0x53494749 | |||
86 | #define NT_FILE0x46494c45 0x46494c45 | |||
87 | #define NT_PRXFPREG0x46e62b7f 0x46e62b7f | |||
88 | #define NT_PPC_VMX0x100 0x100 | |||
89 | #define NT_PPC_SPE0x101 0x101 | |||
90 | #define NT_PPC_VSX0x102 0x102 | |||
91 | #define NT_386_TLS0x200 0x200 | |||
92 | #define NT_386_IOPERM0x201 0x201 | |||
93 | #define NT_X86_XSTATE0x202 0x202 | |||
94 | #define NT_S390_HIGH_GPRS0x300 0x300 | |||
95 | #define NT_S390_TIMER0x301 0x301 | |||
96 | #define NT_S390_TODCMP0x302 0x302 | |||
97 | #define NT_S390_TODPREG0x303 0x303 | |||
98 | #define NT_S390_CTRS0x304 0x304 | |||
99 | #define NT_S390_PREFIX0x305 0x305 | |||
100 | #define NT_S390_LAST_BREAK0x306 0x306 | |||
101 | #define NT_S390_SYSTEM_CALL0x307 0x307 | |||
102 | #define NT_S390_TDB0x308 0x308 | |||
103 | #define NT_S390_VXRS_LOW0x309 0x309 | |||
104 | #define NT_S390_VXRS_HIGH0x30a 0x30a | |||
105 | #define NT_ARM_VFP0x400 0x400 | |||
106 | #define NT_ARM_TLS0x401 0x401 | |||
107 | #define NT_ARM_HW_BREAK0x402 0x402 | |||
108 | #define NT_ARM_HW_WATCH0x403 0x403 | |||
109 | #define NT_ARM_SYSTEM_CALL0x404 0x404 | |||
110 | #define NT_METAG_CBUF0x500 0x500 | |||
111 | #define NT_METAG_RPIPE0x501 0x501 | |||
112 | #define NT_METAG_TLS0x502 0x502 | |||
113 | ||||
114 | //===----------------------------------------------------------------------===// | |||
115 | /// @class ELFRelocation | |||
116 | /// @brief Generic wrapper for ELFRel and ELFRela. | |||
117 | /// | |||
118 | /// This helper class allows us to parse both ELFRel and ELFRela relocation | |||
119 | /// entries in a generic manner. | |||
120 | class ELFRelocation { | |||
121 | public: | |||
122 | /// Constructs an ELFRelocation entry with a personality as given by @p | |||
123 | /// type. | |||
124 | /// | |||
125 | /// @param type Either DT_REL or DT_RELA. Any other value is invalid. | |||
126 | ELFRelocation(unsigned type); | |||
127 | ||||
128 | ~ELFRelocation(); | |||
129 | ||||
130 | bool Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset); | |||
131 | ||||
132 | static unsigned RelocType32(const ELFRelocation &rel); | |||
133 | ||||
134 | static unsigned RelocType64(const ELFRelocation &rel); | |||
135 | ||||
136 | static unsigned RelocSymbol32(const ELFRelocation &rel); | |||
137 | ||||
138 | static unsigned RelocSymbol64(const ELFRelocation &rel); | |||
139 | ||||
140 | static unsigned RelocOffset32(const ELFRelocation &rel); | |||
141 | ||||
142 | static unsigned RelocOffset64(const ELFRelocation &rel); | |||
143 | ||||
144 | static unsigned RelocAddend32(const ELFRelocation &rel); | |||
145 | ||||
146 | static unsigned RelocAddend64(const ELFRelocation &rel); | |||
147 | ||||
148 | private: | |||
149 | typedef llvm::PointerUnion<ELFRel *, ELFRela *> RelocUnion; | |||
150 | ||||
151 | RelocUnion reloc; | |||
152 | }; | |||
153 | ||||
154 | ELFRelocation::ELFRelocation(unsigned type) { | |||
155 | if (type == DT_REL || type == SHT_REL) | |||
156 | reloc = new ELFRel(); | |||
157 | else if (type == DT_RELA || type == SHT_RELA) | |||
158 | reloc = new ELFRela(); | |||
159 | else { | |||
160 | assert(false && "unexpected relocation type")(static_cast <bool> (false && "unexpected relocation type" ) ? void (0) : __assert_fail ("false && \"unexpected relocation type\"" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 160, __extension__ __PRETTY_FUNCTION__)); | |||
161 | reloc = static_cast<ELFRel *>(NULL__null); | |||
162 | } | |||
163 | } | |||
164 | ||||
165 | ELFRelocation::~ELFRelocation() { | |||
166 | if (reloc.is<ELFRel *>()) | |||
167 | delete reloc.get<ELFRel *>(); | |||
168 | else | |||
169 | delete reloc.get<ELFRela *>(); | |||
170 | } | |||
171 | ||||
172 | bool ELFRelocation::Parse(const lldb_private::DataExtractor &data, | |||
173 | lldb::offset_t *offset) { | |||
174 | if (reloc.is<ELFRel *>()) | |||
175 | return reloc.get<ELFRel *>()->Parse(data, offset); | |||
176 | else | |||
177 | return reloc.get<ELFRela *>()->Parse(data, offset); | |||
178 | } | |||
179 | ||||
180 | unsigned ELFRelocation::RelocType32(const ELFRelocation &rel) { | |||
181 | if (rel.reloc.is<ELFRel *>()) | |||
182 | return ELFRel::RelocType32(*rel.reloc.get<ELFRel *>()); | |||
183 | else | |||
184 | return ELFRela::RelocType32(*rel.reloc.get<ELFRela *>()); | |||
185 | } | |||
186 | ||||
187 | unsigned ELFRelocation::RelocType64(const ELFRelocation &rel) { | |||
188 | if (rel.reloc.is<ELFRel *>()) | |||
189 | return ELFRel::RelocType64(*rel.reloc.get<ELFRel *>()); | |||
190 | else | |||
191 | return ELFRela::RelocType64(*rel.reloc.get<ELFRela *>()); | |||
192 | } | |||
193 | ||||
194 | unsigned ELFRelocation::RelocSymbol32(const ELFRelocation &rel) { | |||
195 | if (rel.reloc.is<ELFRel *>()) | |||
196 | return ELFRel::RelocSymbol32(*rel.reloc.get<ELFRel *>()); | |||
197 | else | |||
198 | return ELFRela::RelocSymbol32(*rel.reloc.get<ELFRela *>()); | |||
199 | } | |||
200 | ||||
201 | unsigned ELFRelocation::RelocSymbol64(const ELFRelocation &rel) { | |||
202 | if (rel.reloc.is<ELFRel *>()) | |||
203 | return ELFRel::RelocSymbol64(*rel.reloc.get<ELFRel *>()); | |||
204 | else | |||
205 | return ELFRela::RelocSymbol64(*rel.reloc.get<ELFRela *>()); | |||
206 | } | |||
207 | ||||
208 | unsigned ELFRelocation::RelocOffset32(const ELFRelocation &rel) { | |||
209 | if (rel.reloc.is<ELFRel *>()) | |||
210 | return rel.reloc.get<ELFRel *>()->r_offset; | |||
211 | else | |||
212 | return rel.reloc.get<ELFRela *>()->r_offset; | |||
213 | } | |||
214 | ||||
215 | unsigned ELFRelocation::RelocOffset64(const ELFRelocation &rel) { | |||
216 | if (rel.reloc.is<ELFRel *>()) | |||
217 | return rel.reloc.get<ELFRel *>()->r_offset; | |||
218 | else | |||
219 | return rel.reloc.get<ELFRela *>()->r_offset; | |||
220 | } | |||
221 | ||||
222 | unsigned ELFRelocation::RelocAddend32(const ELFRelocation &rel) { | |||
223 | if (rel.reloc.is<ELFRel *>()) | |||
224 | return 0; | |||
225 | else | |||
226 | return rel.reloc.get<ELFRela *>()->r_addend; | |||
227 | } | |||
228 | ||||
229 | unsigned ELFRelocation::RelocAddend64(const ELFRelocation &rel) { | |||
230 | if (rel.reloc.is<ELFRel *>()) | |||
231 | return 0; | |||
232 | else | |||
233 | return rel.reloc.get<ELFRela *>()->r_addend; | |||
234 | } | |||
235 | ||||
236 | } // end anonymous namespace | |||
237 | ||||
238 | bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) { | |||
239 | // Read all fields. | |||
240 | if (data.GetU32(offset, &n_namesz, 3) == NULL__null) | |||
241 | return false; | |||
242 | ||||
243 | // The name field is required to be nul-terminated, and n_namesz | |||
244 | // includes the terminating nul in observed implementations (contrary | |||
245 | // to the ELF-64 spec). A special case is needed for cores generated | |||
246 | // by some older Linux versions, which write a note named "CORE" | |||
247 | // without a nul terminator and n_namesz = 4. | |||
248 | if (n_namesz == 4) { | |||
249 | char buf[4]; | |||
250 | if (data.ExtractBytes(*offset, 4, data.GetByteOrder(), buf) != 4) | |||
251 | return false; | |||
252 | if (strncmp(buf, "CORE", 4) == 0) { | |||
253 | n_name = "CORE"; | |||
254 | *offset += 4; | |||
255 | return true; | |||
256 | } | |||
257 | } | |||
258 | ||||
259 | const char *cstr = data.GetCStr(offset, llvm::alignTo(n_namesz, 4)); | |||
260 | if (cstr == NULL__null) { | |||
261 | Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS(1u << 20))); | |||
262 | if (log) | |||
263 | log->Printf("Failed to parse note name lacking nul terminator"); | |||
264 | ||||
265 | return false; | |||
266 | } | |||
267 | n_name = cstr; | |||
268 | return true; | |||
269 | } | |||
270 | ||||
271 | static uint32_t kalimbaVariantFromElfFlags(const elf::elf_word e_flags) { | |||
272 | const uint32_t dsp_rev = e_flags & 0xFF; | |||
273 | uint32_t kal_arch_variant = LLDB_INVALID_CPUTYPE(0xFFFFFFFEu); | |||
274 | switch (dsp_rev) { | |||
275 | // TODO(mg11) Support more variants | |||
276 | case 10: | |||
277 | kal_arch_variant = llvm::Triple::KalimbaSubArch_v3; | |||
278 | break; | |||
279 | case 14: | |||
280 | kal_arch_variant = llvm::Triple::KalimbaSubArch_v4; | |||
281 | break; | |||
282 | case 17: | |||
283 | case 20: | |||
284 | kal_arch_variant = llvm::Triple::KalimbaSubArch_v5; | |||
285 | break; | |||
286 | default: | |||
287 | break; | |||
288 | } | |||
289 | return kal_arch_variant; | |||
290 | } | |||
291 | ||||
292 | static uint32_t mipsVariantFromElfFlags (const elf::ELFHeader &header) { | |||
293 | const uint32_t mips_arch = header.e_flags & llvm::ELF::EF_MIPS_ARCH; | |||
294 | uint32_t endian = header.e_ident[EI_DATA]; | |||
295 | uint32_t arch_variant = ArchSpec::eMIPSSubType_unknown; | |||
296 | uint32_t fileclass = header.e_ident[EI_CLASS]; | |||
297 | ||||
298 | // If there aren't any elf flags available (e.g core elf file) then return default | |||
299 | // 32 or 64 bit arch (without any architecture revision) based on object file's class. | |||
300 | if (header.e_type == ET_CORE) { | |||
301 | switch (fileclass) { | |||
302 | case llvm::ELF::ELFCLASS32: | |||
303 | return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el | |||
304 | : ArchSpec::eMIPSSubType_mips32; | |||
305 | case llvm::ELF::ELFCLASS64: | |||
306 | return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el | |||
307 | : ArchSpec::eMIPSSubType_mips64; | |||
308 | default: | |||
309 | return arch_variant; | |||
310 | } | |||
311 | } | |||
312 | ||||
313 | switch (mips_arch) { | |||
314 | case llvm::ELF::EF_MIPS_ARCH_1: | |||
315 | case llvm::ELF::EF_MIPS_ARCH_2: | |||
316 | case llvm::ELF::EF_MIPS_ARCH_32: | |||
317 | return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32el | |||
318 | : ArchSpec::eMIPSSubType_mips32; | |||
319 | case llvm::ELF::EF_MIPS_ARCH_32R2: | |||
320 | return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r2el | |||
321 | : ArchSpec::eMIPSSubType_mips32r2; | |||
322 | case llvm::ELF::EF_MIPS_ARCH_32R6: | |||
323 | return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips32r6el | |||
324 | : ArchSpec::eMIPSSubType_mips32r6; | |||
325 | case llvm::ELF::EF_MIPS_ARCH_3: | |||
326 | case llvm::ELF::EF_MIPS_ARCH_4: | |||
327 | case llvm::ELF::EF_MIPS_ARCH_5: | |||
328 | case llvm::ELF::EF_MIPS_ARCH_64: | |||
329 | return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64el | |||
330 | : ArchSpec::eMIPSSubType_mips64; | |||
331 | case llvm::ELF::EF_MIPS_ARCH_64R2: | |||
332 | return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r2el | |||
333 | : ArchSpec::eMIPSSubType_mips64r2; | |||
334 | case llvm::ELF::EF_MIPS_ARCH_64R6: | |||
335 | return (endian == ELFDATA2LSB) ? ArchSpec::eMIPSSubType_mips64r6el | |||
336 | : ArchSpec::eMIPSSubType_mips64r6; | |||
337 | default: | |||
338 | break; | |||
339 | } | |||
340 | ||||
341 | return arch_variant; | |||
342 | } | |||
343 | ||||
344 | static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) { | |||
345 | if (header.e_machine == llvm::ELF::EM_MIPS) | |||
346 | return mipsVariantFromElfFlags(header); | |||
347 | ||||
348 | return llvm::ELF::EM_CSR_KALIMBA == header.e_machine | |||
349 | ? kalimbaVariantFromElfFlags(header.e_flags) | |||
350 | : LLDB_INVALID_CPUTYPE(0xFFFFFFFEu); | |||
351 | } | |||
352 | ||||
353 | //! The kalimba toolchain identifies a code section as being | |||
354 | //! one with the SHT_PROGBITS set in the section sh_type and the top | |||
355 | //! bit in the 32-bit address field set. | |||
356 | static lldb::SectionType | |||
357 | kalimbaSectionType(const elf::ELFHeader &header, | |||
358 | const elf::ELFSectionHeader §_hdr) { | |||
359 | if (llvm::ELF::EM_CSR_KALIMBA != header.e_machine) { | |||
360 | return eSectionTypeOther; | |||
361 | } | |||
362 | ||||
363 | if (llvm::ELF::SHT_NOBITS == sect_hdr.sh_type) { | |||
364 | return eSectionTypeZeroFill; | |||
365 | } | |||
366 | ||||
367 | if (llvm::ELF::SHT_PROGBITS == sect_hdr.sh_type) { | |||
368 | const lldb::addr_t KAL_CODE_BIT = 1 << 31; | |||
369 | return KAL_CODE_BIT & sect_hdr.sh_addr ? eSectionTypeCode | |||
370 | : eSectionTypeData; | |||
371 | } | |||
372 | ||||
373 | return eSectionTypeOther; | |||
374 | } | |||
375 | ||||
376 | // Arbitrary constant used as UUID prefix for core files. | |||
377 | const uint32_t ObjectFileELF::g_core_uuid_magic(0xE210C); | |||
378 | ||||
379 | //------------------------------------------------------------------ | |||
380 | // Static methods. | |||
381 | //------------------------------------------------------------------ | |||
382 | void ObjectFileELF::Initialize() { | |||
383 | PluginManager::RegisterPlugin(GetPluginNameStatic(), | |||
384 | GetPluginDescriptionStatic(), CreateInstance, | |||
385 | CreateMemoryInstance, GetModuleSpecifications); | |||
386 | } | |||
387 | ||||
388 | void ObjectFileELF::Terminate() { | |||
389 | PluginManager::UnregisterPlugin(CreateInstance); | |||
390 | } | |||
391 | ||||
392 | lldb_private::ConstString ObjectFileELF::GetPluginNameStatic() { | |||
393 | static ConstString g_name("elf"); | |||
394 | return g_name; | |||
395 | } | |||
396 | ||||
397 | const char *ObjectFileELF::GetPluginDescriptionStatic() { | |||
398 | return "ELF object file reader."; | |||
399 | } | |||
400 | ||||
401 | ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp, | |||
402 | DataBufferSP &data_sp, | |||
403 | lldb::offset_t data_offset, | |||
404 | const lldb_private::FileSpec *file, | |||
405 | lldb::offset_t file_offset, | |||
406 | lldb::offset_t length) { | |||
407 | if (!data_sp) { | |||
408 | data_sp = MapFileData(*file, length, file_offset); | |||
409 | if (!data_sp) | |||
410 | return nullptr; | |||
411 | data_offset = 0; | |||
412 | } | |||
413 | ||||
414 | assert(data_sp)(static_cast <bool> (data_sp) ? void (0) : __assert_fail ("data_sp", "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 414, __extension__ __PRETTY_FUNCTION__)); | |||
415 | ||||
416 | if (data_sp->GetByteSize() <= (llvm::ELF::EI_NIDENT + data_offset)) | |||
417 | return nullptr; | |||
418 | ||||
419 | const uint8_t *magic = data_sp->GetBytes() + data_offset; | |||
420 | if (!ELFHeader::MagicBytesMatch(magic)) | |||
421 | return nullptr; | |||
422 | ||||
423 | // Update the data to contain the entire file if it doesn't already | |||
424 | if (data_sp->GetByteSize() < length) { | |||
425 | data_sp = MapFileData(*file, length, file_offset); | |||
426 | if (!data_sp) | |||
427 | return nullptr; | |||
428 | data_offset = 0; | |||
429 | magic = data_sp->GetBytes(); | |||
430 | } | |||
431 | ||||
432 | unsigned address_size = ELFHeader::AddressSizeInBytes(magic); | |||
433 | if (address_size == 4 || address_size == 8) { | |||
434 | std::unique_ptr<ObjectFileELF> objfile_ap(new ObjectFileELF( | |||
435 | module_sp, data_sp, data_offset, file, file_offset, length)); | |||
436 | ArchSpec spec; | |||
437 | if (objfile_ap->GetArchitecture(spec) && | |||
438 | objfile_ap->SetModulesArchitecture(spec)) | |||
439 | return objfile_ap.release(); | |||
440 | } | |||
441 | ||||
442 | return NULL__null; | |||
443 | } | |||
444 | ||||
445 | ObjectFile *ObjectFileELF::CreateMemoryInstance( | |||
446 | const lldb::ModuleSP &module_sp, DataBufferSP &data_sp, | |||
447 | const lldb::ProcessSP &process_sp, lldb::addr_t header_addr) { | |||
448 | if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT)) { | |||
449 | const uint8_t *magic = data_sp->GetBytes(); | |||
450 | if (ELFHeader::MagicBytesMatch(magic)) { | |||
451 | unsigned address_size = ELFHeader::AddressSizeInBytes(magic); | |||
452 | if (address_size == 4 || address_size == 8) { | |||
453 | std::unique_ptr<ObjectFileELF> objfile_ap( | |||
454 | new ObjectFileELF(module_sp, data_sp, process_sp, header_addr)); | |||
455 | ArchSpec spec; | |||
456 | if (objfile_ap->GetArchitecture(spec) && | |||
457 | objfile_ap->SetModulesArchitecture(spec)) | |||
458 | return objfile_ap.release(); | |||
459 | } | |||
460 | } | |||
461 | } | |||
462 | return NULL__null; | |||
463 | } | |||
464 | ||||
465 | bool ObjectFileELF::MagicBytesMatch(DataBufferSP &data_sp, | |||
466 | lldb::addr_t data_offset, | |||
467 | lldb::addr_t data_length) { | |||
468 | if (data_sp && | |||
469 | data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset)) { | |||
470 | const uint8_t *magic = data_sp->GetBytes() + data_offset; | |||
471 | return ELFHeader::MagicBytesMatch(magic); | |||
472 | } | |||
473 | return false; | |||
474 | } | |||
475 | ||||
476 | /* | |||
477 | * crc function from http://svnweb.freebsd.org/base/head/sys/libkern/crc32.c | |||
478 | * | |||
479 | * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or | |||
480 | * code or tables extracted from it, as desired without restriction. | |||
481 | */ | |||
482 | static uint32_t calc_crc32(uint32_t crc, const void *buf, size_t size) { | |||
483 | static const uint32_t g_crc32_tab[] = { | |||
484 | 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, | |||
485 | 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, | |||
486 | 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, | |||
487 | 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, | |||
488 | 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, | |||
489 | 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, | |||
490 | 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, | |||
491 | 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, | |||
492 | 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, | |||
493 | 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, | |||
494 | 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, | |||
495 | 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, | |||
496 | 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, | |||
497 | 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, | |||
498 | 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, | |||
499 | 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, | |||
500 | 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, | |||
501 | 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, | |||
502 | 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, | |||
503 | 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, | |||
504 | 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, | |||
505 | 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, | |||
506 | 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, | |||
507 | 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, | |||
508 | 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, | |||
509 | 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, | |||
510 | 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, | |||
511 | 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, | |||
512 | 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, | |||
513 | 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, | |||
514 | 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, | |||
515 | 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, | |||
516 | 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, | |||
517 | 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, | |||
518 | 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, | |||
519 | 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, | |||
520 | 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, | |||
521 | 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, | |||
522 | 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, | |||
523 | 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, | |||
524 | 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, | |||
525 | 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, | |||
526 | 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; | |||
527 | const uint8_t *p = (const uint8_t *)buf; | |||
528 | ||||
529 | crc = crc ^ ~0U; | |||
530 | while (size--) | |||
531 | crc = g_crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8); | |||
532 | return crc ^ ~0U; | |||
533 | } | |||
534 | ||||
535 | static uint32_t calc_gnu_debuglink_crc32(const void *buf, size_t size) { | |||
536 | return calc_crc32(0U, buf, size); | |||
537 | } | |||
538 | ||||
539 | uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32( | |||
540 | const ProgramHeaderColl &program_headers, DataExtractor &object_data) { | |||
541 | typedef ProgramHeaderCollConstIter Iter; | |||
542 | ||||
543 | uint32_t core_notes_crc = 0; | |||
544 | ||||
545 | for (Iter I = program_headers.begin(); I != program_headers.end(); ++I) { | |||
546 | if (I->p_type == llvm::ELF::PT_NOTE) { | |||
547 | const elf_off ph_offset = I->p_offset; | |||
548 | const size_t ph_size = I->p_filesz; | |||
549 | ||||
550 | DataExtractor segment_data; | |||
551 | if (segment_data.SetData(object_data, ph_offset, ph_size) != ph_size) { | |||
552 | // The ELF program header contained incorrect data, | |||
553 | // probably corefile is incomplete or corrupted. | |||
554 | break; | |||
555 | } | |||
556 | ||||
557 | core_notes_crc = calc_crc32(core_notes_crc, segment_data.GetDataStart(), | |||
558 | segment_data.GetByteSize()); | |||
559 | } | |||
560 | } | |||
561 | ||||
562 | return core_notes_crc; | |||
563 | } | |||
564 | ||||
565 | static const char *OSABIAsCString(unsigned char osabi_byte) { | |||
566 | #define _MAKE_OSABI_CASE(x) \ | |||
567 | case x: \ | |||
568 | return #x | |||
569 | switch (osabi_byte) { | |||
570 | _MAKE_OSABI_CASE(ELFOSABI_NONE); | |||
571 | _MAKE_OSABI_CASE(ELFOSABI_HPUX); | |||
572 | _MAKE_OSABI_CASE(ELFOSABI_NETBSD); | |||
573 | _MAKE_OSABI_CASE(ELFOSABI_GNU); | |||
574 | _MAKE_OSABI_CASE(ELFOSABI_HURD); | |||
575 | _MAKE_OSABI_CASE(ELFOSABI_SOLARIS); | |||
576 | _MAKE_OSABI_CASE(ELFOSABI_AIX); | |||
577 | _MAKE_OSABI_CASE(ELFOSABI_IRIX); | |||
578 | _MAKE_OSABI_CASE(ELFOSABI_FREEBSD); | |||
579 | _MAKE_OSABI_CASE(ELFOSABI_TRU64); | |||
580 | _MAKE_OSABI_CASE(ELFOSABI_MODESTO); | |||
581 | _MAKE_OSABI_CASE(ELFOSABI_OPENBSD); | |||
582 | _MAKE_OSABI_CASE(ELFOSABI_OPENVMS); | |||
583 | _MAKE_OSABI_CASE(ELFOSABI_NSK); | |||
584 | _MAKE_OSABI_CASE(ELFOSABI_AROS); | |||
585 | _MAKE_OSABI_CASE(ELFOSABI_FENIXOS); | |||
586 | _MAKE_OSABI_CASE(ELFOSABI_C6000_ELFABI); | |||
587 | _MAKE_OSABI_CASE(ELFOSABI_C6000_LINUX); | |||
588 | _MAKE_OSABI_CASE(ELFOSABI_ARM); | |||
589 | _MAKE_OSABI_CASE(ELFOSABI_STANDALONE); | |||
590 | default: | |||
591 | return "<unknown-osabi>"; | |||
592 | } | |||
593 | #undef _MAKE_OSABI_CASE | |||
594 | } | |||
595 | ||||
596 | // | |||
597 | // WARNING : This function is being deprecated | |||
598 | // It's functionality has moved to ArchSpec::SetArchitecture | |||
599 | // This function is only being kept to validate the move. | |||
600 | // | |||
601 | // TODO : Remove this function | |||
602 | static bool GetOsFromOSABI(unsigned char osabi_byte, | |||
603 | llvm::Triple::OSType &ostype) { | |||
604 | switch (osabi_byte) { | |||
605 | case ELFOSABI_AIX: | |||
606 | ostype = llvm::Triple::OSType::AIX; | |||
607 | break; | |||
608 | case ELFOSABI_FREEBSD: | |||
609 | ostype = llvm::Triple::OSType::FreeBSD; | |||
610 | break; | |||
611 | case ELFOSABI_GNU: | |||
612 | ostype = llvm::Triple::OSType::Linux; | |||
613 | break; | |||
614 | case ELFOSABI_NETBSD: | |||
615 | ostype = llvm::Triple::OSType::NetBSD; | |||
616 | break; | |||
617 | case ELFOSABI_OPENBSD: | |||
618 | ostype = llvm::Triple::OSType::OpenBSD; | |||
619 | break; | |||
620 | case ELFOSABI_SOLARIS: | |||
621 | ostype = llvm::Triple::OSType::Solaris; | |||
622 | break; | |||
623 | default: | |||
624 | ostype = llvm::Triple::OSType::UnknownOS; | |||
625 | } | |||
626 | return ostype != llvm::Triple::OSType::UnknownOS; | |||
627 | } | |||
628 | ||||
629 | size_t ObjectFileELF::GetModuleSpecifications( | |||
630 | const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp, | |||
631 | lldb::offset_t data_offset, lldb::offset_t file_offset, | |||
632 | lldb::offset_t length, lldb_private::ModuleSpecList &specs) { | |||
633 | Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES(1u << 21))); | |||
634 | ||||
635 | const size_t initial_count = specs.GetSize(); | |||
636 | ||||
637 | if (ObjectFileELF::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) { | |||
638 | DataExtractor data; | |||
639 | data.SetData(data_sp); | |||
640 | elf::ELFHeader header; | |||
641 | lldb::offset_t header_offset = data_offset; | |||
642 | if (header.Parse(data, &header_offset)) { | |||
643 | if (data_sp) { | |||
644 | ModuleSpec spec(file); | |||
645 | ||||
646 | const uint32_t sub_type = subTypeFromElfHeader(header); | |||
647 | spec.GetArchitecture().SetArchitecture( | |||
648 | eArchTypeELF, header.e_machine, sub_type, header.e_ident[EI_OSABI]); | |||
649 | ||||
650 | if (spec.GetArchitecture().IsValid()) { | |||
651 | llvm::Triple::OSType ostype; | |||
652 | llvm::Triple::VendorType vendor; | |||
653 | llvm::Triple::OSType spec_ostype = | |||
654 | spec.GetArchitecture().GetTriple().getOS(); | |||
655 | ||||
656 | if (log) | |||
657 | log->Printf("ObjectFileELF::%s file '%s' module OSABI: %s", | |||
658 | __FUNCTION__, file.GetPath().c_str(), | |||
659 | OSABIAsCString(header.e_ident[EI_OSABI])); | |||
660 | ||||
661 | // SetArchitecture should have set the vendor to unknown | |||
662 | vendor = spec.GetArchitecture().GetTriple().getVendor(); | |||
663 | assert(vendor == llvm::Triple::UnknownVendor)(static_cast <bool> (vendor == llvm::Triple::UnknownVendor ) ? void (0) : __assert_fail ("vendor == llvm::Triple::UnknownVendor" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 663, __extension__ __PRETTY_FUNCTION__)); | |||
664 | UNUSED_IF_ASSERT_DISABLED(vendor)((void)(vendor)); | |||
665 | ||||
666 | // | |||
667 | // Validate it is ok to remove GetOsFromOSABI | |||
668 | GetOsFromOSABI(header.e_ident[EI_OSABI], ostype); | |||
669 | assert(spec_ostype == ostype)(static_cast <bool> (spec_ostype == ostype) ? void (0) : __assert_fail ("spec_ostype == ostype", "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 669, __extension__ __PRETTY_FUNCTION__)); | |||
670 | if (spec_ostype != llvm::Triple::OSType::UnknownOS) { | |||
671 | if (log) | |||
672 | log->Printf("ObjectFileELF::%s file '%s' set ELF module OS type " | |||
673 | "from ELF header OSABI.", | |||
674 | __FUNCTION__, file.GetPath().c_str()); | |||
675 | } | |||
676 | ||||
677 | data_sp = MapFileData(file, -1, file_offset); | |||
678 | if (data_sp) | |||
679 | data.SetData(data_sp); | |||
680 | // In case there is header extension in the section #0, the header | |||
681 | // we parsed above could have sentinel values for e_phnum, e_shnum, | |||
682 | // and e_shstrndx. In this case we need to reparse the header | |||
683 | // with a bigger data source to get the actual values. | |||
684 | if (header.HasHeaderExtension()) { | |||
685 | lldb::offset_t header_offset = data_offset; | |||
686 | header.Parse(data, &header_offset); | |||
687 | } | |||
688 | ||||
689 | uint32_t gnu_debuglink_crc = 0; | |||
690 | std::string gnu_debuglink_file; | |||
691 | SectionHeaderColl section_headers; | |||
692 | lldb_private::UUID &uuid = spec.GetUUID(); | |||
693 | ||||
694 | GetSectionHeaderInfo(section_headers, data, header, uuid, | |||
695 | gnu_debuglink_file, gnu_debuglink_crc, | |||
696 | spec.GetArchitecture()); | |||
697 | ||||
698 | llvm::Triple &spec_triple = spec.GetArchitecture().GetTriple(); | |||
699 | ||||
700 | if (log) | |||
701 | log->Printf("ObjectFileELF::%s file '%s' module set to triple: %s " | |||
702 | "(architecture %s)", | |||
703 | __FUNCTION__, file.GetPath().c_str(), | |||
704 | spec_triple.getTriple().c_str(), | |||
705 | spec.GetArchitecture().GetArchitectureName()); | |||
706 | ||||
707 | if (!uuid.IsValid()) { | |||
708 | uint32_t core_notes_crc = 0; | |||
709 | ||||
710 | if (!gnu_debuglink_crc) { | |||
711 | static Timer::Category func_cat(LLVM_PRETTY_FUNCTION__PRETTY_FUNCTION__); | |||
712 | lldb_private::Timer scoped_timer( | |||
713 | func_cat, | |||
714 | "Calculating module crc32 %s with size %" PRIu64"l" "u" " KiB", | |||
715 | file.GetLastPathComponent().AsCString(), | |||
716 | (file.GetByteSize() - file_offset) / 1024); | |||
717 | ||||
718 | // For core files - which usually don't happen to have a | |||
719 | // gnu_debuglink, and are pretty bulky - calculating whole | |||
720 | // contents crc32 would be too much of luxury. Thus we will need | |||
721 | // to fallback to something simpler. | |||
722 | if (header.e_type == llvm::ELF::ET_CORE) { | |||
723 | ProgramHeaderColl program_headers; | |||
724 | GetProgramHeaderInfo(program_headers, data, header); | |||
725 | ||||
726 | core_notes_crc = | |||
727 | CalculateELFNotesSegmentsCRC32(program_headers, data); | |||
728 | } else { | |||
729 | gnu_debuglink_crc = calc_gnu_debuglink_crc32( | |||
730 | data.GetDataStart(), data.GetByteSize()); | |||
731 | } | |||
732 | } | |||
733 | if (gnu_debuglink_crc) { | |||
734 | // Use 4 bytes of crc from the .gnu_debuglink section. | |||
735 | uint32_t uuidt[4] = {gnu_debuglink_crc, 0, 0, 0}; | |||
736 | uuid.SetBytes(uuidt, sizeof(uuidt)); | |||
737 | } else if (core_notes_crc) { | |||
738 | // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make | |||
739 | // it look different form | |||
740 | // .gnu_debuglink crc followed by 4 bytes of note segments crc. | |||
741 | uint32_t uuidt[4] = {g_core_uuid_magic, core_notes_crc, 0, 0}; | |||
742 | uuid.SetBytes(uuidt, sizeof(uuidt)); | |||
743 | } | |||
744 | } | |||
745 | ||||
746 | specs.Append(spec); | |||
747 | } | |||
748 | } | |||
749 | } | |||
750 | } | |||
751 | ||||
752 | return specs.GetSize() - initial_count; | |||
753 | } | |||
754 | ||||
755 | //------------------------------------------------------------------ | |||
756 | // PluginInterface protocol | |||
757 | //------------------------------------------------------------------ | |||
758 | lldb_private::ConstString ObjectFileELF::GetPluginName() { | |||
759 | return GetPluginNameStatic(); | |||
760 | } | |||
761 | ||||
762 | uint32_t ObjectFileELF::GetPluginVersion() { return m_plugin_version; } | |||
763 | //------------------------------------------------------------------ | |||
764 | // ObjectFile protocol | |||
765 | //------------------------------------------------------------------ | |||
766 | ||||
767 | ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, | |||
768 | DataBufferSP &data_sp, lldb::offset_t data_offset, | |||
769 | const FileSpec *file, lldb::offset_t file_offset, | |||
770 | lldb::offset_t length) | |||
771 | : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset), | |||
772 | m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0), | |||
773 | m_program_headers(), m_section_headers(), m_dynamic_symbols(), | |||
774 | m_filespec_ap(), m_entry_point_address(), m_arch_spec() { | |||
775 | if (file) | |||
776 | m_file = *file; | |||
777 | ::memset(&m_header, 0, sizeof(m_header)); | |||
778 | } | |||
779 | ||||
780 | ObjectFileELF::ObjectFileELF(const lldb::ModuleSP &module_sp, | |||
781 | DataBufferSP &header_data_sp, | |||
782 | const lldb::ProcessSP &process_sp, | |||
783 | addr_t header_addr) | |||
784 | : ObjectFile(module_sp, process_sp, header_addr, header_data_sp), | |||
785 | m_header(), m_uuid(), m_gnu_debuglink_file(), m_gnu_debuglink_crc(0), | |||
786 | m_program_headers(), m_section_headers(), m_dynamic_symbols(), | |||
787 | m_filespec_ap(), m_entry_point_address(), m_arch_spec() { | |||
788 | ::memset(&m_header, 0, sizeof(m_header)); | |||
789 | } | |||
790 | ||||
791 | ObjectFileELF::~ObjectFileELF() {} | |||
792 | ||||
793 | bool ObjectFileELF::IsExecutable() const { | |||
794 | return ((m_header.e_type & ET_EXEC) != 0) || (m_header.e_entry != 0); | |||
795 | } | |||
796 | ||||
797 | bool ObjectFileELF::SetLoadAddress(Target &target, lldb::addr_t value, | |||
798 | bool value_is_offset) { | |||
799 | ModuleSP module_sp = GetModule(); | |||
800 | if (module_sp) { | |||
801 | size_t num_loaded_sections = 0; | |||
802 | SectionList *section_list = GetSectionList(); | |||
803 | if (section_list) { | |||
804 | if (!value_is_offset) { | |||
805 | bool found_offset = false; | |||
806 | for (size_t i = 1, count = GetProgramHeaderCount(); i <= count; ++i) { | |||
807 | const elf::ELFProgramHeader *header = GetProgramHeaderByIndex(i); | |||
808 | if (header == nullptr) | |||
809 | continue; | |||
810 | ||||
811 | if (header->p_type != PT_LOAD || header->p_offset != 0) | |||
812 | continue; | |||
813 | ||||
814 | value = value - header->p_vaddr; | |||
815 | found_offset = true; | |||
816 | break; | |||
817 | } | |||
818 | if (!found_offset) | |||
819 | return false; | |||
820 | } | |||
821 | ||||
822 | const size_t num_sections = section_list->GetSize(); | |||
823 | size_t sect_idx = 0; | |||
824 | ||||
825 | for (sect_idx = 0; sect_idx < num_sections; ++sect_idx) { | |||
826 | // Iterate through the object file sections to find all | |||
827 | // of the sections that have SHF_ALLOC in their flag bits. | |||
828 | SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx)); | |||
829 | if (section_sp && section_sp->Test(SHF_ALLOC)) { | |||
830 | lldb::addr_t load_addr = section_sp->GetFileAddress(); | |||
831 | // We don't want to update the load address of a section with type | |||
832 | // eSectionTypeAbsoluteAddress as they already have the absolute load | |||
833 | // address | |||
834 | // already specified | |||
835 | if (section_sp->GetType() != eSectionTypeAbsoluteAddress) | |||
836 | load_addr += value; | |||
837 | ||||
838 | // On 32-bit systems the load address have to fit into 4 bytes. The | |||
839 | // rest of | |||
840 | // the bytes are the overflow from the addition. | |||
841 | if (GetAddressByteSize() == 4) | |||
842 | load_addr &= 0xFFFFFFFF; | |||
843 | ||||
844 | if (target.GetSectionLoadList().SetSectionLoadAddress(section_sp, | |||
845 | load_addr)) | |||
846 | ++num_loaded_sections; | |||
847 | } | |||
848 | } | |||
849 | return num_loaded_sections > 0; | |||
850 | } | |||
851 | } | |||
852 | return false; | |||
853 | } | |||
854 | ||||
855 | ByteOrder ObjectFileELF::GetByteOrder() const { | |||
856 | if (m_header.e_ident[EI_DATA] == ELFDATA2MSB) | |||
857 | return eByteOrderBig; | |||
858 | if (m_header.e_ident[EI_DATA] == ELFDATA2LSB) | |||
859 | return eByteOrderLittle; | |||
860 | return eByteOrderInvalid; | |||
861 | } | |||
862 | ||||
863 | uint32_t ObjectFileELF::GetAddressByteSize() const { | |||
864 | return m_data.GetAddressByteSize(); | |||
865 | } | |||
866 | ||||
867 | AddressClass ObjectFileELF::GetAddressClass(addr_t file_addr) { | |||
868 | Symtab *symtab = GetSymtab(); | |||
869 | if (!symtab) | |||
870 | return eAddressClassUnknown; | |||
871 | ||||
872 | // The address class is determined based on the symtab. Ask it from the object | |||
873 | // file what | |||
874 | // contains the symtab information. | |||
875 | ObjectFile *symtab_objfile = symtab->GetObjectFile(); | |||
876 | if (symtab_objfile != nullptr && symtab_objfile != this) | |||
877 | return symtab_objfile->GetAddressClass(file_addr); | |||
878 | ||||
879 | auto res = ObjectFile::GetAddressClass(file_addr); | |||
880 | if (res != eAddressClassCode) | |||
881 | return res; | |||
882 | ||||
883 | auto ub = m_address_class_map.upper_bound(file_addr); | |||
884 | if (ub == m_address_class_map.begin()) { | |||
885 | // No entry in the address class map before the address. Return | |||
886 | // default address class for an address in a code section. | |||
887 | return eAddressClassCode; | |||
888 | } | |||
889 | ||||
890 | // Move iterator to the address class entry preceding address | |||
891 | --ub; | |||
892 | ||||
893 | return ub->second; | |||
894 | } | |||
895 | ||||
896 | size_t ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I) { | |||
897 | return std::distance(m_section_headers.begin(), I) + 1u; | |||
898 | } | |||
899 | ||||
900 | size_t ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const { | |||
901 | return std::distance(m_section_headers.begin(), I) + 1u; | |||
902 | } | |||
903 | ||||
904 | bool ObjectFileELF::ParseHeader() { | |||
905 | lldb::offset_t offset = 0; | |||
906 | return m_header.Parse(m_data, &offset); | |||
907 | } | |||
908 | ||||
909 | bool ObjectFileELF::GetUUID(lldb_private::UUID *uuid) { | |||
910 | // Need to parse the section list to get the UUIDs, so make sure that's been | |||
911 | // done. | |||
912 | if (!ParseSectionHeaders() && GetType() != ObjectFile::eTypeCoreFile) | |||
913 | return false; | |||
914 | ||||
915 | if (m_uuid.IsValid()) { | |||
916 | // We have the full build id uuid. | |||
917 | *uuid = m_uuid; | |||
918 | return true; | |||
919 | } else if (GetType() == ObjectFile::eTypeCoreFile) { | |||
920 | uint32_t core_notes_crc = 0; | |||
921 | ||||
922 | if (!ParseProgramHeaders()) | |||
923 | return false; | |||
924 | ||||
925 | core_notes_crc = CalculateELFNotesSegmentsCRC32(m_program_headers, m_data); | |||
926 | ||||
927 | if (core_notes_crc) { | |||
928 | // Use 8 bytes - first 4 bytes for *magic* prefix, mainly to make it | |||
929 | // look different form .gnu_debuglink crc - followed by 4 bytes of note | |||
930 | // segments crc. | |||
931 | uint32_t uuidt[4] = {g_core_uuid_magic, core_notes_crc, 0, 0}; | |||
932 | m_uuid.SetBytes(uuidt, sizeof(uuidt)); | |||
933 | } | |||
934 | } else { | |||
935 | if (!m_gnu_debuglink_crc) | |||
936 | m_gnu_debuglink_crc = | |||
937 | calc_gnu_debuglink_crc32(m_data.GetDataStart(), m_data.GetByteSize()); | |||
938 | if (m_gnu_debuglink_crc) { | |||
939 | // Use 4 bytes of crc from the .gnu_debuglink section. | |||
940 | uint32_t uuidt[4] = {m_gnu_debuglink_crc, 0, 0, 0}; | |||
941 | m_uuid.SetBytes(uuidt, sizeof(uuidt)); | |||
942 | } | |||
943 | } | |||
944 | ||||
945 | if (m_uuid.IsValid()) { | |||
946 | *uuid = m_uuid; | |||
947 | return true; | |||
948 | } | |||
949 | ||||
950 | return false; | |||
951 | } | |||
952 | ||||
953 | lldb_private::FileSpecList ObjectFileELF::GetDebugSymbolFilePaths() { | |||
954 | FileSpecList file_spec_list; | |||
955 | ||||
956 | if (!m_gnu_debuglink_file.empty()) { | |||
957 | FileSpec file_spec(m_gnu_debuglink_file, false); | |||
958 | file_spec_list.Append(file_spec); | |||
959 | } | |||
960 | return file_spec_list; | |||
961 | } | |||
962 | ||||
963 | uint32_t ObjectFileELF::GetDependentModules(FileSpecList &files) { | |||
964 | size_t num_modules = ParseDependentModules(); | |||
965 | uint32_t num_specs = 0; | |||
966 | ||||
967 | for (unsigned i = 0; i < num_modules; ++i) { | |||
968 | if (files.AppendIfUnique(m_filespec_ap->GetFileSpecAtIndex(i))) | |||
969 | num_specs++; | |||
970 | } | |||
971 | ||||
972 | return num_specs; | |||
973 | } | |||
974 | ||||
975 | Address ObjectFileELF::GetImageInfoAddress(Target *target) { | |||
976 | if (!ParseDynamicSymbols()) | |||
977 | return Address(); | |||
978 | ||||
979 | SectionList *section_list = GetSectionList(); | |||
980 | if (!section_list) | |||
981 | return Address(); | |||
982 | ||||
983 | // Find the SHT_DYNAMIC (.dynamic) section. | |||
984 | SectionSP dynsym_section_sp( | |||
985 | section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true)); | |||
986 | if (!dynsym_section_sp) | |||
987 | return Address(); | |||
988 | assert(dynsym_section_sp->GetObjectFile() == this)(static_cast <bool> (dynsym_section_sp->GetObjectFile () == this) ? void (0) : __assert_fail ("dynsym_section_sp->GetObjectFile() == this" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 988, __extension__ __PRETTY_FUNCTION__)); | |||
989 | ||||
990 | user_id_t dynsym_id = dynsym_section_sp->GetID(); | |||
991 | const ELFSectionHeaderInfo *dynsym_hdr = GetSectionHeaderByIndex(dynsym_id); | |||
992 | if (!dynsym_hdr) | |||
993 | return Address(); | |||
994 | ||||
995 | for (size_t i = 0; i < m_dynamic_symbols.size(); ++i) { | |||
996 | ELFDynamic &symbol = m_dynamic_symbols[i]; | |||
997 | ||||
998 | if (symbol.d_tag == DT_DEBUG) { | |||
999 | // Compute the offset as the number of previous entries plus the | |||
1000 | // size of d_tag. | |||
1001 | addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize(); | |||
1002 | return Address(dynsym_section_sp, offset); | |||
1003 | } | |||
1004 | // MIPS executables uses DT_MIPS_RLD_MAP_REL to support PIE. DT_MIPS_RLD_MAP | |||
1005 | // exists in non-PIE. | |||
1006 | else if ((symbol.d_tag == DT_MIPS_RLD_MAP || | |||
1007 | symbol.d_tag == DT_MIPS_RLD_MAP_REL) && | |||
1008 | target) { | |||
1009 | addr_t offset = i * dynsym_hdr->sh_entsize + GetAddressByteSize(); | |||
1010 | addr_t dyn_base = dynsym_section_sp->GetLoadBaseAddress(target); | |||
1011 | if (dyn_base == LLDB_INVALID_ADDRESS(18446744073709551615UL)) | |||
1012 | return Address(); | |||
1013 | ||||
1014 | Status error; | |||
1015 | if (symbol.d_tag == DT_MIPS_RLD_MAP) { | |||
1016 | // DT_MIPS_RLD_MAP tag stores an absolute address of the debug pointer. | |||
1017 | Address addr; | |||
1018 | if (target->ReadPointerFromMemory(dyn_base + offset, false, error, | |||
1019 | addr)) | |||
1020 | return addr; | |||
1021 | } | |||
1022 | if (symbol.d_tag == DT_MIPS_RLD_MAP_REL) { | |||
1023 | // DT_MIPS_RLD_MAP_REL tag stores the offset to the debug pointer, | |||
1024 | // relative to the address of the tag. | |||
1025 | uint64_t rel_offset; | |||
1026 | rel_offset = target->ReadUnsignedIntegerFromMemory( | |||
1027 | dyn_base + offset, false, GetAddressByteSize(), UINT64_MAX(18446744073709551615UL), error); | |||
1028 | if (error.Success() && rel_offset != UINT64_MAX(18446744073709551615UL)) { | |||
1029 | Address addr; | |||
1030 | addr_t debug_ptr_address = | |||
1031 | dyn_base + (offset - GetAddressByteSize()) + rel_offset; | |||
1032 | addr.SetOffset(debug_ptr_address); | |||
1033 | return addr; | |||
1034 | } | |||
1035 | } | |||
1036 | } | |||
1037 | } | |||
1038 | ||||
1039 | return Address(); | |||
1040 | } | |||
1041 | ||||
1042 | lldb_private::Address ObjectFileELF::GetEntryPointAddress() { | |||
1043 | if (m_entry_point_address.IsValid()) | |||
1044 | return m_entry_point_address; | |||
1045 | ||||
1046 | if (!ParseHeader() || !IsExecutable()) | |||
1047 | return m_entry_point_address; | |||
1048 | ||||
1049 | SectionList *section_list = GetSectionList(); | |||
1050 | addr_t offset = m_header.e_entry; | |||
1051 | ||||
1052 | if (!section_list) | |||
1053 | m_entry_point_address.SetOffset(offset); | |||
1054 | else | |||
1055 | m_entry_point_address.ResolveAddressUsingFileSections(offset, section_list); | |||
1056 | return m_entry_point_address; | |||
1057 | } | |||
1058 | ||||
1059 | //---------------------------------------------------------------------- | |||
1060 | // ParseDependentModules | |||
1061 | //---------------------------------------------------------------------- | |||
1062 | size_t ObjectFileELF::ParseDependentModules() { | |||
1063 | if (m_filespec_ap.get()) | |||
1064 | return m_filespec_ap->GetSize(); | |||
1065 | ||||
1066 | m_filespec_ap.reset(new FileSpecList()); | |||
1067 | ||||
1068 | if (!ParseSectionHeaders()) | |||
1069 | return 0; | |||
1070 | ||||
1071 | SectionList *section_list = GetSectionList(); | |||
1072 | if (!section_list) | |||
1073 | return 0; | |||
1074 | ||||
1075 | // Find the SHT_DYNAMIC section. | |||
1076 | Section *dynsym = | |||
1077 | section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true) | |||
1078 | .get(); | |||
1079 | if (!dynsym) | |||
1080 | return 0; | |||
1081 | assert(dynsym->GetObjectFile() == this)(static_cast <bool> (dynsym->GetObjectFile() == this ) ? void (0) : __assert_fail ("dynsym->GetObjectFile() == this" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 1081, __extension__ __PRETTY_FUNCTION__)); | |||
1082 | ||||
1083 | const ELFSectionHeaderInfo *header = GetSectionHeaderByIndex(dynsym->GetID()); | |||
1084 | if (!header) | |||
1085 | return 0; | |||
1086 | // sh_link: section header index of string table used by entries in the | |||
1087 | // section. | |||
1088 | Section *dynstr = section_list->FindSectionByID(header->sh_link + 1).get(); | |||
1089 | if (!dynstr) | |||
1090 | return 0; | |||
1091 | ||||
1092 | DataExtractor dynsym_data; | |||
1093 | DataExtractor dynstr_data; | |||
1094 | if (ReadSectionData(dynsym, dynsym_data) && | |||
1095 | ReadSectionData(dynstr, dynstr_data)) { | |||
1096 | ELFDynamic symbol; | |||
1097 | const lldb::offset_t section_size = dynsym_data.GetByteSize(); | |||
1098 | lldb::offset_t offset = 0; | |||
1099 | ||||
1100 | // The only type of entries we are concerned with are tagged DT_NEEDED, | |||
1101 | // yielding the name of a required library. | |||
1102 | while (offset < section_size) { | |||
1103 | if (!symbol.Parse(dynsym_data, &offset)) | |||
1104 | break; | |||
1105 | ||||
1106 | if (symbol.d_tag != DT_NEEDED) | |||
1107 | continue; | |||
1108 | ||||
1109 | uint32_t str_index = static_cast<uint32_t>(symbol.d_val); | |||
1110 | const char *lib_name = dynstr_data.PeekCStr(str_index); | |||
1111 | m_filespec_ap->Append(FileSpec(lib_name, true)); | |||
1112 | } | |||
1113 | } | |||
1114 | ||||
1115 | return m_filespec_ap->GetSize(); | |||
1116 | } | |||
1117 | ||||
1118 | //---------------------------------------------------------------------- | |||
1119 | // GetProgramHeaderInfo | |||
1120 | //---------------------------------------------------------------------- | |||
1121 | size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers, | |||
1122 | DataExtractor &object_data, | |||
1123 | const ELFHeader &header) { | |||
1124 | // We have already parsed the program headers | |||
1125 | if (!program_headers.empty()) | |||
1126 | return program_headers.size(); | |||
1127 | ||||
1128 | // If there are no program headers to read we are done. | |||
1129 | if (header.e_phnum == 0) | |||
1130 | return 0; | |||
1131 | ||||
1132 | program_headers.resize(header.e_phnum); | |||
1133 | if (program_headers.size() != header.e_phnum) | |||
1134 | return 0; | |||
1135 | ||||
1136 | const size_t ph_size = header.e_phnum * header.e_phentsize; | |||
1137 | const elf_off ph_offset = header.e_phoff; | |||
1138 | DataExtractor data; | |||
1139 | if (data.SetData(object_data, ph_offset, ph_size) != ph_size) | |||
1140 | return 0; | |||
1141 | ||||
1142 | uint32_t idx; | |||
1143 | lldb::offset_t offset; | |||
1144 | for (idx = 0, offset = 0; idx < header.e_phnum; ++idx) { | |||
1145 | if (program_headers[idx].Parse(data, &offset) == false) | |||
1146 | break; | |||
1147 | } | |||
1148 | ||||
1149 | if (idx < program_headers.size()) | |||
1150 | program_headers.resize(idx); | |||
1151 | ||||
1152 | return program_headers.size(); | |||
1153 | } | |||
1154 | ||||
1155 | //---------------------------------------------------------------------- | |||
1156 | // ParseProgramHeaders | |||
1157 | //---------------------------------------------------------------------- | |||
1158 | size_t ObjectFileELF::ParseProgramHeaders() { | |||
1159 | return GetProgramHeaderInfo(m_program_headers, m_data, m_header); | |||
1160 | } | |||
1161 | ||||
1162 | lldb_private::Status | |||
1163 | ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, | |||
1164 | lldb_private::ArchSpec &arch_spec, | |||
1165 | lldb_private::UUID &uuid) { | |||
1166 | Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES(1u << 21))); | |||
1167 | Status error; | |||
1168 | ||||
1169 | lldb::offset_t offset = 0; | |||
1170 | ||||
1171 | while (true) { | |||
1172 | // Parse the note header. If this fails, bail out. | |||
1173 | const lldb::offset_t note_offset = offset; | |||
1174 | ELFNote note = ELFNote(); | |||
1175 | if (!note.Parse(data, &offset)) { | |||
1176 | // We're done. | |||
1177 | return error; | |||
1178 | } | |||
1179 | ||||
1180 | if (log) | |||
1181 | log->Printf("ObjectFileELF::%s parsing note name='%s', type=%" PRIu32"u", | |||
1182 | __FUNCTION__, note.n_name.c_str(), note.n_type); | |||
1183 | ||||
1184 | // Process FreeBSD ELF notes. | |||
1185 | if ((note.n_name == LLDB_NT_OWNER_FREEBSD) && | |||
1186 | (note.n_type == LLDB_NT_FREEBSD_ABI_TAG) && | |||
1187 | (note.n_descsz == LLDB_NT_FREEBSD_ABI_SIZE)) { | |||
1188 | // Pull out the min version info. | |||
1189 | uint32_t version_info; | |||
1190 | if (data.GetU32(&offset, &version_info, 1) == nullptr) { | |||
1191 | error.SetErrorString("failed to read FreeBSD ABI note payload"); | |||
1192 | return error; | |||
1193 | } | |||
1194 | ||||
1195 | // Convert the version info into a major/minor number. | |||
1196 | const uint32_t version_major = version_info / 100000; | |||
1197 | const uint32_t version_minor = (version_info / 1000) % 100; | |||
1198 | ||||
1199 | char os_name[32]; | |||
1200 | snprintf(os_name, sizeof(os_name), "freebsd%" PRIu32"u" ".%" PRIu32"u", | |||
1201 | version_major, version_minor); | |||
1202 | ||||
1203 | // Set the elf OS version to FreeBSD. Also clear the vendor. | |||
1204 | arch_spec.GetTriple().setOSName(os_name); | |||
1205 | arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); | |||
1206 | ||||
1207 | if (log) | |||
1208 | log->Printf("ObjectFileELF::%s detected FreeBSD %" PRIu32"u" ".%" PRIu32"u" | |||
1209 | ".%" PRIu32"u", | |||
1210 | __FUNCTION__, version_major, version_minor, | |||
1211 | static_cast<uint32_t>(version_info % 1000)); | |||
1212 | } | |||
1213 | // Process GNU ELF notes. | |||
1214 | else if (note.n_name == LLDB_NT_OWNER_GNU) { | |||
1215 | switch (note.n_type) { | |||
1216 | case LLDB_NT_GNU_ABI_TAG: | |||
1217 | if (note.n_descsz == LLDB_NT_GNU_ABI_SIZE) { | |||
1218 | // Pull out the min OS version supporting the ABI. | |||
1219 | uint32_t version_info[4]; | |||
1220 | if (data.GetU32(&offset, &version_info[0], note.n_descsz / 4) == | |||
1221 | nullptr) { | |||
1222 | error.SetErrorString("failed to read GNU ABI note payload"); | |||
1223 | return error; | |||
1224 | } | |||
1225 | ||||
1226 | // Set the OS per the OS field. | |||
1227 | switch (version_info[0]) { | |||
1228 | case LLDB_NT_GNU_ABI_OS_LINUX: | |||
1229 | arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); | |||
1230 | arch_spec.GetTriple().setVendor( | |||
1231 | llvm::Triple::VendorType::UnknownVendor); | |||
1232 | if (log) | |||
1233 | log->Printf( | |||
1234 | "ObjectFileELF::%s detected Linux, min version %" PRIu32"u" | |||
1235 | ".%" PRIu32"u" ".%" PRIu32"u", | |||
1236 | __FUNCTION__, version_info[1], version_info[2], | |||
1237 | version_info[3]); | |||
1238 | // FIXME we have the minimal version number, we could be propagating | |||
1239 | // that. version_info[1] = OS Major, version_info[2] = OS Minor, | |||
1240 | // version_info[3] = Revision. | |||
1241 | break; | |||
1242 | case LLDB_NT_GNU_ABI_OS_HURD: | |||
1243 | arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS); | |||
1244 | arch_spec.GetTriple().setVendor( | |||
1245 | llvm::Triple::VendorType::UnknownVendor); | |||
1246 | if (log) | |||
1247 | log->Printf("ObjectFileELF::%s detected Hurd (unsupported), min " | |||
1248 | "version %" PRIu32"u" ".%" PRIu32"u" ".%" PRIu32"u", | |||
1249 | __FUNCTION__, version_info[1], version_info[2], | |||
1250 | version_info[3]); | |||
1251 | break; | |||
1252 | case LLDB_NT_GNU_ABI_OS_SOLARIS: | |||
1253 | arch_spec.GetTriple().setOS(llvm::Triple::OSType::Solaris); | |||
1254 | arch_spec.GetTriple().setVendor( | |||
1255 | llvm::Triple::VendorType::UnknownVendor); | |||
1256 | if (log) | |||
1257 | log->Printf( | |||
1258 | "ObjectFileELF::%s detected Solaris, min version %" PRIu32"u" | |||
1259 | ".%" PRIu32"u" ".%" PRIu32"u", | |||
1260 | __FUNCTION__, version_info[1], version_info[2], | |||
1261 | version_info[3]); | |||
1262 | break; | |||
1263 | default: | |||
1264 | if (log) | |||
1265 | log->Printf( | |||
1266 | "ObjectFileELF::%s unrecognized OS in note, id %" PRIu32"u" | |||
1267 | ", min version %" PRIu32"u" ".%" PRIu32"u" ".%" PRIu32"u", | |||
1268 | __FUNCTION__, version_info[0], version_info[1], | |||
1269 | version_info[2], version_info[3]); | |||
1270 | break; | |||
1271 | } | |||
1272 | } | |||
1273 | break; | |||
1274 | ||||
1275 | case LLDB_NT_GNU_BUILD_ID_TAG: | |||
1276 | // Only bother processing this if we don't already have the uuid set. | |||
1277 | if (!uuid.IsValid()) { | |||
1278 | // 16 bytes is UUID|MD5, 20 bytes is SHA1. Other linkers may produce a | |||
1279 | // build-id of a different | |||
1280 | // length. Accept it as long as it's at least 4 bytes as it will be | |||
1281 | // better than our own crc32. | |||
1282 | if (note.n_descsz >= 4 && note.n_descsz <= 20) { | |||
1283 | uint8_t uuidbuf[20]; | |||
1284 | if (data.GetU8(&offset, &uuidbuf, note.n_descsz) == nullptr) { | |||
1285 | error.SetErrorString("failed to read GNU_BUILD_ID note payload"); | |||
1286 | return error; | |||
1287 | } | |||
1288 | ||||
1289 | // Save the build id as the UUID for the module. | |||
1290 | uuid.SetBytes(uuidbuf, note.n_descsz); | |||
1291 | } | |||
1292 | } | |||
1293 | break; | |||
1294 | } | |||
1295 | if (arch_spec.IsMIPS() && | |||
1296 | arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) | |||
1297 | // The note.n_name == LLDB_NT_OWNER_GNU is valid for Linux platform | |||
1298 | arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); | |||
1299 | } | |||
1300 | // Process NetBSD ELF notes. | |||
1301 | else if ((note.n_name == LLDB_NT_OWNER_NETBSD) && | |||
1302 | (note.n_type == LLDB_NT_NETBSD_ABI_TAG) && | |||
1303 | (note.n_descsz == LLDB_NT_NETBSD_ABI_SIZE)) { | |||
1304 | // Pull out the min version info. | |||
1305 | uint32_t version_info; | |||
1306 | if (data.GetU32(&offset, &version_info, 1) == nullptr) { | |||
1307 | error.SetErrorString("failed to read NetBSD ABI note payload"); | |||
1308 | return error; | |||
1309 | } | |||
1310 | ||||
1311 | // Set the elf OS version to NetBSD. Also clear the vendor. | |||
1312 | arch_spec.GetTriple().setOS(llvm::Triple::OSType::NetBSD); | |||
1313 | arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); | |||
1314 | ||||
1315 | if (log) | |||
1316 | log->Printf( | |||
1317 | "ObjectFileELF::%s detected NetBSD, min version constant %" PRIu32"u", | |||
1318 | __FUNCTION__, version_info); | |||
1319 | } | |||
1320 | // Process OpenBSD ELF notes. | |||
1321 | else if (note.n_name == LLDB_NT_OWNER_OPENBSD) { | |||
1322 | // Set the elf OS version to OpenBSD. Also clear the vendor. | |||
1323 | arch_spec.GetTriple().setOS(llvm::Triple::OSType::OpenBSD); | |||
1324 | arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::UnknownVendor); | |||
1325 | } | |||
1326 | // Process CSR kalimba notes | |||
1327 | else if ((note.n_type == LLDB_NT_GNU_ABI_TAG) && | |||
1328 | (note.n_name == LLDB_NT_OWNER_CSR)) { | |||
1329 | arch_spec.GetTriple().setOS(llvm::Triple::OSType::UnknownOS); | |||
1330 | arch_spec.GetTriple().setVendor(llvm::Triple::VendorType::CSR); | |||
1331 | ||||
1332 | // TODO At some point the description string could be processed. | |||
1333 | // It could provide a steer towards the kalimba variant which | |||
1334 | // this ELF targets. | |||
1335 | if (note.n_descsz) { | |||
1336 | const char *cstr = | |||
1337 | data.GetCStr(&offset, llvm::alignTo(note.n_descsz, 4)); | |||
1338 | (void)cstr; | |||
1339 | } | |||
1340 | } else if (note.n_name == LLDB_NT_OWNER_ANDROID) { | |||
1341 | arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); | |||
1342 | arch_spec.GetTriple().setEnvironment( | |||
1343 | llvm::Triple::EnvironmentType::Android); | |||
1344 | } else if (note.n_name == LLDB_NT_OWNER_LINUX) { | |||
1345 | // This is sometimes found in core files and usually contains extended | |||
1346 | // register info | |||
1347 | arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); | |||
1348 | } else if (note.n_name == LLDB_NT_OWNER_CORE) { | |||
1349 | // Parse the NT_FILE to look for stuff in paths to shared libraries | |||
1350 | // As the contents look like this in a 64 bit ELF core file: | |||
1351 | // count = 0x000000000000000a (10) | |||
1352 | // page_size = 0x0000000000001000 (4096) | |||
1353 | // Index start end file_ofs path | |||
1354 | // ===== ------------------ ------------------ ------------------ | |||
1355 | // ------------------------------------- | |||
1356 | // [ 0] 0x0000000000400000 0x0000000000401000 0x0000000000000000 | |||
1357 | // /tmp/a.out | |||
1358 | // [ 1] 0x0000000000600000 0x0000000000601000 0x0000000000000000 | |||
1359 | // /tmp/a.out | |||
1360 | // [ 2] 0x0000000000601000 0x0000000000602000 0x0000000000000001 | |||
1361 | // /tmp/a.out | |||
1362 | // [ 3] 0x00007fa79c9ed000 0x00007fa79cba8000 0x0000000000000000 | |||
1363 | // /lib/x86_64-linux-gnu/libc-2.19.so | |||
1364 | // [ 4] 0x00007fa79cba8000 0x00007fa79cda7000 0x00000000000001bb | |||
1365 | // /lib/x86_64-linux-gnu/libc-2.19.so | |||
1366 | // [ 5] 0x00007fa79cda7000 0x00007fa79cdab000 0x00000000000001ba | |||
1367 | // /lib/x86_64-linux-gnu/libc-2.19.so | |||
1368 | // [ 6] 0x00007fa79cdab000 0x00007fa79cdad000 0x00000000000001be | |||
1369 | // /lib/x86_64-linux-gnu/libc-2.19.so | |||
1370 | // [ 7] 0x00007fa79cdb2000 0x00007fa79cdd5000 0x0000000000000000 | |||
1371 | // /lib/x86_64-linux-gnu/ld-2.19.so | |||
1372 | // [ 8] 0x00007fa79cfd4000 0x00007fa79cfd5000 0x0000000000000022 | |||
1373 | // /lib/x86_64-linux-gnu/ld-2.19.so | |||
1374 | // [ 9] 0x00007fa79cfd5000 0x00007fa79cfd6000 0x0000000000000023 | |||
1375 | // /lib/x86_64-linux-gnu/ld-2.19.so | |||
1376 | // In the 32 bit ELFs the count, page_size, start, end, file_ofs are | |||
1377 | // uint32_t | |||
1378 | // For reference: see readelf source code (in binutils). | |||
1379 | if (note.n_type == NT_FILE0x46494c45) { | |||
1380 | uint64_t count = data.GetAddress(&offset); | |||
1381 | const char *cstr; | |||
1382 | data.GetAddress(&offset); // Skip page size | |||
1383 | offset += count * 3 * | |||
1384 | data.GetAddressByteSize(); // Skip all start/end/file_ofs | |||
1385 | for (size_t i = 0; i < count; ++i) { | |||
1386 | cstr = data.GetCStr(&offset); | |||
1387 | if (cstr == nullptr) { | |||
1388 | error.SetErrorStringWithFormat("ObjectFileELF::%s trying to read " | |||
1389 | "at an offset after the end " | |||
1390 | "(GetCStr returned nullptr)", | |||
1391 | __FUNCTION__); | |||
1392 | return error; | |||
1393 | } | |||
1394 | llvm::StringRef path(cstr); | |||
1395 | if (path.contains("/lib/x86_64-linux-gnu") || path.contains("/lib/i386-linux-gnu")) { | |||
1396 | arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); | |||
1397 | break; | |||
1398 | } | |||
1399 | } | |||
1400 | if (arch_spec.IsMIPS() && | |||
1401 | arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) | |||
1402 | // In case of MIPSR6, the LLDB_NT_OWNER_GNU note is missing | |||
1403 | // for some cases (e.g. compile with -nostdlib) | |||
1404 | // Hence set OS to Linux | |||
1405 | arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); | |||
1406 | } | |||
1407 | } | |||
1408 | ||||
1409 | // Calculate the offset of the next note just in case "offset" has been used | |||
1410 | // to poke at the contents of the note data | |||
1411 | offset = note_offset + note.GetByteSize(); | |||
1412 | } | |||
1413 | ||||
1414 | return error; | |||
1415 | } | |||
1416 | ||||
1417 | void ObjectFileELF::ParseARMAttributes(DataExtractor &data, uint64_t length, | |||
1418 | ArchSpec &arch_spec) { | |||
1419 | lldb::offset_t Offset = 0; | |||
1420 | ||||
1421 | uint8_t FormatVersion = data.GetU8(&Offset); | |||
1422 | if (FormatVersion != llvm::ARMBuildAttrs::Format_Version) | |||
1423 | return; | |||
1424 | ||||
1425 | Offset = Offset + sizeof(uint32_t); // Section Length | |||
1426 | llvm::StringRef VendorName = data.GetCStr(&Offset); | |||
1427 | ||||
1428 | if (VendorName != "aeabi") | |||
1429 | return; | |||
1430 | ||||
1431 | if (arch_spec.GetTriple().getEnvironment() == | |||
1432 | llvm::Triple::UnknownEnvironment) | |||
1433 | arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI); | |||
1434 | ||||
1435 | while (Offset < length) { | |||
1436 | uint8_t Tag = data.GetU8(&Offset); | |||
1437 | uint32_t Size = data.GetU32(&Offset); | |||
1438 | ||||
1439 | if (Tag != llvm::ARMBuildAttrs::File || Size == 0) | |||
1440 | continue; | |||
1441 | ||||
1442 | while (Offset < length) { | |||
1443 | uint64_t Tag = data.GetULEB128(&Offset); | |||
1444 | switch (Tag) { | |||
1445 | default: | |||
1446 | if (Tag < 32) | |||
1447 | data.GetULEB128(&Offset); | |||
1448 | else if (Tag % 2 == 0) | |||
1449 | data.GetULEB128(&Offset); | |||
1450 | else | |||
1451 | data.GetCStr(&Offset); | |||
1452 | ||||
1453 | break; | |||
1454 | ||||
1455 | case llvm::ARMBuildAttrs::CPU_raw_name: | |||
1456 | case llvm::ARMBuildAttrs::CPU_name: | |||
1457 | data.GetCStr(&Offset); | |||
1458 | ||||
1459 | break; | |||
1460 | ||||
1461 | case llvm::ARMBuildAttrs::ABI_VFP_args: { | |||
1462 | uint64_t VFPArgs = data.GetULEB128(&Offset); | |||
1463 | ||||
1464 | if (VFPArgs == llvm::ARMBuildAttrs::BaseAAPCS) { | |||
1465 | if (arch_spec.GetTriple().getEnvironment() == | |||
1466 | llvm::Triple::UnknownEnvironment || | |||
1467 | arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABIHF) | |||
1468 | arch_spec.GetTriple().setEnvironment(llvm::Triple::EABI); | |||
1469 | ||||
1470 | arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float); | |||
1471 | } else if (VFPArgs == llvm::ARMBuildAttrs::HardFPAAPCS) { | |||
1472 | if (arch_spec.GetTriple().getEnvironment() == | |||
1473 | llvm::Triple::UnknownEnvironment || | |||
1474 | arch_spec.GetTriple().getEnvironment() == llvm::Triple::EABI) | |||
1475 | arch_spec.GetTriple().setEnvironment(llvm::Triple::EABIHF); | |||
1476 | ||||
1477 | arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float); | |||
1478 | } | |||
1479 | ||||
1480 | break; | |||
1481 | } | |||
1482 | } | |||
1483 | } | |||
1484 | } | |||
1485 | } | |||
1486 | ||||
1487 | //---------------------------------------------------------------------- | |||
1488 | // GetSectionHeaderInfo | |||
1489 | //---------------------------------------------------------------------- | |||
1490 | size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, | |||
1491 | DataExtractor &object_data, | |||
1492 | const elf::ELFHeader &header, | |||
1493 | lldb_private::UUID &uuid, | |||
1494 | std::string &gnu_debuglink_file, | |||
1495 | uint32_t &gnu_debuglink_crc, | |||
1496 | ArchSpec &arch_spec) { | |||
1497 | // Don't reparse the section headers if we already did that. | |||
1498 | if (!section_headers.empty()) | |||
1499 | return section_headers.size(); | |||
1500 | ||||
1501 | // Only initialize the arch_spec to okay defaults if they're not already set. | |||
1502 | // We'll refine this with note data as we parse the notes. | |||
1503 | if (arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) { | |||
1504 | llvm::Triple::OSType ostype; | |||
1505 | llvm::Triple::OSType spec_ostype; | |||
1506 | const uint32_t sub_type = subTypeFromElfHeader(header); | |||
1507 | arch_spec.SetArchitecture(eArchTypeELF, header.e_machine, sub_type, | |||
1508 | header.e_ident[EI_OSABI]); | |||
1509 | ||||
1510 | // Validate if it is ok to remove GetOsFromOSABI. | |||
1511 | // Note, that now the OS is determined based on EI_OSABI flag and | |||
1512 | // the info extracted from ELF notes (see RefineModuleDetailsFromNote). | |||
1513 | // However in some cases that still might be not enough: for example | |||
1514 | // a shared library might not have any notes at all | |||
1515 | // and have EI_OSABI flag set to System V, | |||
1516 | // as result the OS will be set to UnknownOS. | |||
1517 | GetOsFromOSABI(header.e_ident[EI_OSABI], ostype); | |||
1518 | spec_ostype = arch_spec.GetTriple().getOS(); | |||
1519 | assert(spec_ostype == ostype)(static_cast <bool> (spec_ostype == ostype) ? void (0) : __assert_fail ("spec_ostype == ostype", "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 1519, __extension__ __PRETTY_FUNCTION__)); | |||
1520 | UNUSED_IF_ASSERT_DISABLED(spec_ostype)((void)(spec_ostype)); | |||
1521 | } | |||
1522 | ||||
1523 | if (arch_spec.GetMachine() == llvm::Triple::mips || | |||
1524 | arch_spec.GetMachine() == llvm::Triple::mipsel || | |||
1525 | arch_spec.GetMachine() == llvm::Triple::mips64 || | |||
1526 | arch_spec.GetMachine() == llvm::Triple::mips64el) { | |||
1527 | switch (header.e_flags & llvm::ELF::EF_MIPS_ARCH_ASE) { | |||
1528 | case llvm::ELF::EF_MIPS_MICROMIPS: | |||
1529 | arch_spec.SetFlags(ArchSpec::eMIPSAse_micromips); | |||
1530 | break; | |||
1531 | case llvm::ELF::EF_MIPS_ARCH_ASE_M16: | |||
1532 | arch_spec.SetFlags(ArchSpec::eMIPSAse_mips16); | |||
1533 | break; | |||
1534 | case llvm::ELF::EF_MIPS_ARCH_ASE_MDMX: | |||
1535 | arch_spec.SetFlags(ArchSpec::eMIPSAse_mdmx); | |||
1536 | break; | |||
1537 | default: | |||
1538 | break; | |||
1539 | } | |||
1540 | } | |||
1541 | ||||
1542 | if (arch_spec.GetMachine() == llvm::Triple::arm || | |||
1543 | arch_spec.GetMachine() == llvm::Triple::thumb) { | |||
1544 | if (header.e_flags & llvm::ELF::EF_ARM_SOFT_FLOAT) | |||
1545 | arch_spec.SetFlags(ArchSpec::eARM_abi_soft_float); | |||
1546 | else if (header.e_flags & llvm::ELF::EF_ARM_VFP_FLOAT) | |||
1547 | arch_spec.SetFlags(ArchSpec::eARM_abi_hard_float); | |||
1548 | } | |||
1549 | ||||
1550 | // If there are no section headers we are done. | |||
1551 | if (header.e_shnum == 0) | |||
1552 | return 0; | |||
1553 | ||||
1554 | Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES(1u << 21))); | |||
1555 | ||||
1556 | section_headers.resize(header.e_shnum); | |||
1557 | if (section_headers.size() != header.e_shnum) | |||
1558 | return 0; | |||
1559 | ||||
1560 | const size_t sh_size = header.e_shnum * header.e_shentsize; | |||
1561 | const elf_off sh_offset = header.e_shoff; | |||
1562 | DataExtractor sh_data; | |||
1563 | if (sh_data.SetData(object_data, sh_offset, sh_size) != sh_size) | |||
1564 | return 0; | |||
1565 | ||||
1566 | uint32_t idx; | |||
1567 | lldb::offset_t offset; | |||
1568 | for (idx = 0, offset = 0; idx < header.e_shnum; ++idx) { | |||
1569 | if (section_headers[idx].Parse(sh_data, &offset) == false) | |||
1570 | break; | |||
1571 | } | |||
1572 | if (idx < section_headers.size()) | |||
1573 | section_headers.resize(idx); | |||
1574 | ||||
1575 | const unsigned strtab_idx = header.e_shstrndx; | |||
1576 | if (strtab_idx && strtab_idx < section_headers.size()) { | |||
1577 | const ELFSectionHeaderInfo &sheader = section_headers[strtab_idx]; | |||
1578 | const size_t byte_size = sheader.sh_size; | |||
1579 | const Elf64_Off offset = sheader.sh_offset; | |||
1580 | lldb_private::DataExtractor shstr_data; | |||
1581 | ||||
1582 | if (shstr_data.SetData(object_data, offset, byte_size) == byte_size) { | |||
1583 | for (SectionHeaderCollIter I = section_headers.begin(); | |||
1584 | I != section_headers.end(); ++I) { | |||
1585 | static ConstString g_sect_name_gnu_debuglink(".gnu_debuglink"); | |||
1586 | const ELFSectionHeaderInfo &sheader = *I; | |||
1587 | const uint64_t section_size = | |||
1588 | sheader.sh_type == SHT_NOBITS ? 0 : sheader.sh_size; | |||
1589 | ConstString name(shstr_data.PeekCStr(I->sh_name)); | |||
1590 | ||||
1591 | I->section_name = name; | |||
1592 | ||||
1593 | if (arch_spec.IsMIPS()) { | |||
1594 | uint32_t arch_flags = arch_spec.GetFlags(); | |||
1595 | DataExtractor data; | |||
1596 | if (sheader.sh_type == SHT_MIPS_ABIFLAGS) { | |||
1597 | ||||
1598 | if (section_size && (data.SetData(object_data, sheader.sh_offset, | |||
1599 | section_size) == section_size)) { | |||
1600 | // MIPS ASE Mask is at offset 12 in MIPS.abiflags section | |||
1601 | lldb::offset_t offset = 12; // MIPS ABI Flags Version: 0 | |||
1602 | arch_flags |= data.GetU32(&offset); | |||
1603 | ||||
1604 | // The floating point ABI is at offset 7 | |||
1605 | offset = 7; | |||
1606 | switch (data.GetU8(&offset)) { | |||
1607 | case llvm::Mips::Val_GNU_MIPS_ABI_FP_ANY: | |||
1608 | arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_ANY; | |||
1609 | break; | |||
1610 | case llvm::Mips::Val_GNU_MIPS_ABI_FP_DOUBLE: | |||
1611 | arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_DOUBLE; | |||
1612 | break; | |||
1613 | case llvm::Mips::Val_GNU_MIPS_ABI_FP_SINGLE: | |||
1614 | arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SINGLE; | |||
1615 | break; | |||
1616 | case llvm::Mips::Val_GNU_MIPS_ABI_FP_SOFT: | |||
1617 | arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_SOFT; | |||
1618 | break; | |||
1619 | case llvm::Mips::Val_GNU_MIPS_ABI_FP_OLD_64: | |||
1620 | arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_OLD_64; | |||
1621 | break; | |||
1622 | case llvm::Mips::Val_GNU_MIPS_ABI_FP_XX: | |||
1623 | arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_XX; | |||
1624 | break; | |||
1625 | case llvm::Mips::Val_GNU_MIPS_ABI_FP_64: | |||
1626 | arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64; | |||
1627 | break; | |||
1628 | case llvm::Mips::Val_GNU_MIPS_ABI_FP_64A: | |||
1629 | arch_flags |= lldb_private::ArchSpec::eMIPS_ABI_FP_64A; | |||
1630 | break; | |||
1631 | } | |||
1632 | } | |||
1633 | } | |||
1634 | // Settings appropriate ArchSpec ABI Flags | |||
1635 | switch (header.e_flags & llvm::ELF::EF_MIPS_ABI) { | |||
1636 | case llvm::ELF::EF_MIPS_ABI_O32: | |||
1637 | arch_flags |= lldb_private::ArchSpec::eMIPSABI_O32; | |||
1638 | break; | |||
1639 | case EF_MIPS_ABI_O64: | |||
1640 | arch_flags |= lldb_private::ArchSpec::eMIPSABI_O64; | |||
1641 | break; | |||
1642 | case EF_MIPS_ABI_EABI32: | |||
1643 | arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI32; | |||
1644 | break; | |||
1645 | case EF_MIPS_ABI_EABI64: | |||
1646 | arch_flags |= lldb_private::ArchSpec::eMIPSABI_EABI64; | |||
1647 | break; | |||
1648 | default: | |||
1649 | // ABI Mask doesn't cover N32 and N64 ABI. | |||
1650 | if (header.e_ident[EI_CLASS] == llvm::ELF::ELFCLASS64) | |||
1651 | arch_flags |= lldb_private::ArchSpec::eMIPSABI_N64; | |||
1652 | else if (header.e_flags & llvm::ELF::EF_MIPS_ABI2) | |||
1653 | arch_flags |= lldb_private::ArchSpec::eMIPSABI_N32; | |||
1654 | break; | |||
1655 | } | |||
1656 | arch_spec.SetFlags(arch_flags); | |||
1657 | } | |||
1658 | ||||
1659 | if (arch_spec.GetMachine() == llvm::Triple::arm || | |||
1660 | arch_spec.GetMachine() == llvm::Triple::thumb) { | |||
1661 | DataExtractor data; | |||
1662 | ||||
1663 | if (sheader.sh_type == SHT_ARM_ATTRIBUTES && section_size != 0 && | |||
1664 | data.SetData(object_data, sheader.sh_offset, section_size) == section_size) | |||
1665 | ParseARMAttributes(data, section_size, arch_spec); | |||
1666 | } | |||
1667 | ||||
1668 | if (name == g_sect_name_gnu_debuglink) { | |||
1669 | DataExtractor data; | |||
1670 | if (section_size && (data.SetData(object_data, sheader.sh_offset, | |||
1671 | section_size) == section_size)) { | |||
1672 | lldb::offset_t gnu_debuglink_offset = 0; | |||
1673 | gnu_debuglink_file = data.GetCStr(&gnu_debuglink_offset); | |||
1674 | gnu_debuglink_offset = llvm::alignTo(gnu_debuglink_offset, 4); | |||
1675 | data.GetU32(&gnu_debuglink_offset, &gnu_debuglink_crc, 1); | |||
1676 | } | |||
1677 | } | |||
1678 | ||||
1679 | // Process ELF note section entries. | |||
1680 | bool is_note_header = (sheader.sh_type == SHT_NOTE); | |||
1681 | ||||
1682 | // The section header ".note.android.ident" is stored as a | |||
1683 | // PROGBITS type header but it is actually a note header. | |||
1684 | static ConstString g_sect_name_android_ident(".note.android.ident"); | |||
1685 | if (!is_note_header && name == g_sect_name_android_ident) | |||
1686 | is_note_header = true; | |||
1687 | ||||
1688 | if (is_note_header) { | |||
1689 | // Allow notes to refine module info. | |||
1690 | DataExtractor data; | |||
1691 | if (section_size && (data.SetData(object_data, sheader.sh_offset, | |||
1692 | section_size) == section_size)) { | |||
1693 | Status error = RefineModuleDetailsFromNote(data, arch_spec, uuid); | |||
1694 | if (error.Fail()) { | |||
1695 | if (log) | |||
1696 | log->Printf("ObjectFileELF::%s ELF note processing failed: %s", | |||
1697 | __FUNCTION__, error.AsCString()); | |||
1698 | } | |||
1699 | } | |||
1700 | } | |||
1701 | } | |||
1702 | ||||
1703 | // Make any unknown triple components to be unspecified unknowns. | |||
1704 | if (arch_spec.GetTriple().getVendor() == llvm::Triple::UnknownVendor) | |||
1705 | arch_spec.GetTriple().setVendorName(llvm::StringRef()); | |||
1706 | if (arch_spec.GetTriple().getOS() == llvm::Triple::UnknownOS) | |||
1707 | arch_spec.GetTriple().setOSName(llvm::StringRef()); | |||
1708 | ||||
1709 | return section_headers.size(); | |||
1710 | } | |||
1711 | } | |||
1712 | ||||
1713 | section_headers.clear(); | |||
1714 | return 0; | |||
1715 | } | |||
1716 | ||||
1717 | size_t ObjectFileELF::GetProgramHeaderCount() { return ParseProgramHeaders(); } | |||
1718 | ||||
1719 | const elf::ELFProgramHeader * | |||
1720 | ObjectFileELF::GetProgramHeaderByIndex(lldb::user_id_t id) { | |||
1721 | if (!id || !ParseProgramHeaders()) | |||
1722 | return NULL__null; | |||
1723 | ||||
1724 | if (--id < m_program_headers.size()) | |||
1725 | return &m_program_headers[id]; | |||
1726 | ||||
1727 | return NULL__null; | |||
1728 | } | |||
1729 | ||||
1730 | DataExtractor ObjectFileELF::GetSegmentDataByIndex(lldb::user_id_t id) { | |||
1731 | const elf::ELFProgramHeader *segment_header = GetProgramHeaderByIndex(id); | |||
1732 | if (segment_header == NULL__null) | |||
1733 | return DataExtractor(); | |||
1734 | return DataExtractor(m_data, segment_header->p_offset, | |||
1735 | segment_header->p_filesz); | |||
1736 | } | |||
1737 | ||||
1738 | llvm::StringRef | |||
1739 | ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const { | |||
1740 | size_t pos = symbol_name.find('@'); | |||
1741 | return symbol_name.substr(0, pos); | |||
1742 | } | |||
1743 | ||||
1744 | //---------------------------------------------------------------------- | |||
1745 | // ParseSectionHeaders | |||
1746 | //---------------------------------------------------------------------- | |||
1747 | size_t ObjectFileELF::ParseSectionHeaders() { | |||
1748 | return GetSectionHeaderInfo(m_section_headers, m_data, m_header, m_uuid, | |||
1749 | m_gnu_debuglink_file, m_gnu_debuglink_crc, | |||
1750 | m_arch_spec); | |||
1751 | } | |||
1752 | ||||
1753 | const ObjectFileELF::ELFSectionHeaderInfo * | |||
1754 | ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) { | |||
1755 | if (!id || !ParseSectionHeaders()) | |||
1756 | return NULL__null; | |||
1757 | ||||
1758 | if (--id < m_section_headers.size()) | |||
1759 | return &m_section_headers[id]; | |||
1760 | ||||
1761 | return NULL__null; | |||
1762 | } | |||
1763 | ||||
1764 | lldb::user_id_t ObjectFileELF::GetSectionIndexByName(const char *name) { | |||
1765 | if (!name || !name[0] || !ParseSectionHeaders()) | |||
1766 | return 0; | |||
1767 | for (size_t i = 1; i < m_section_headers.size(); ++i) | |||
1768 | if (m_section_headers[i].section_name == ConstString(name)) | |||
1769 | return i; | |||
1770 | return 0; | |||
1771 | } | |||
1772 | ||||
1773 | void ObjectFileELF::CreateSections(SectionList &unified_section_list) { | |||
1774 | if (!m_sections_ap.get() && ParseSectionHeaders()) { | |||
1775 | m_sections_ap.reset(new SectionList()); | |||
1776 | ||||
1777 | // Object files frequently have 0 for every section address, meaning we | |||
1778 | // need to compute synthetic addresses in order for "file addresses" from | |||
1779 | // different sections to not overlap | |||
1780 | bool synthaddrs = (CalculateType() == ObjectFile::Type::eTypeObjectFile); | |||
1781 | uint64_t nextaddr = 0; | |||
1782 | ||||
1783 | for (SectionHeaderCollIter I = m_section_headers.begin(); | |||
1784 | I != m_section_headers.end(); ++I) { | |||
1785 | const ELFSectionHeaderInfo &header = *I; | |||
1786 | ||||
1787 | ConstString &name = I->section_name; | |||
1788 | const uint64_t file_size = | |||
1789 | header.sh_type == SHT_NOBITS ? 0 : header.sh_size; | |||
1790 | const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0; | |||
1791 | ||||
1792 | static ConstString g_sect_name_text(".text"); | |||
1793 | static ConstString g_sect_name_data(".data"); | |||
1794 | static ConstString g_sect_name_bss(".bss"); | |||
1795 | static ConstString g_sect_name_tdata(".tdata"); | |||
1796 | static ConstString g_sect_name_tbss(".tbss"); | |||
1797 | static ConstString g_sect_name_dwarf_debug_abbrev(".debug_abbrev"); | |||
1798 | static ConstString g_sect_name_dwarf_debug_addr(".debug_addr"); | |||
1799 | static ConstString g_sect_name_dwarf_debug_aranges(".debug_aranges"); | |||
1800 | static ConstString g_sect_name_dwarf_debug_cu_index(".debug_cu_index"); | |||
1801 | static ConstString g_sect_name_dwarf_debug_frame(".debug_frame"); | |||
1802 | static ConstString g_sect_name_dwarf_debug_info(".debug_info"); | |||
1803 | static ConstString g_sect_name_dwarf_debug_line(".debug_line"); | |||
1804 | static ConstString g_sect_name_dwarf_debug_loc(".debug_loc"); | |||
1805 | static ConstString g_sect_name_dwarf_debug_macinfo(".debug_macinfo"); | |||
1806 | static ConstString g_sect_name_dwarf_debug_macro(".debug_macro"); | |||
1807 | static ConstString g_sect_name_dwarf_debug_pubnames(".debug_pubnames"); | |||
1808 | static ConstString g_sect_name_dwarf_debug_pubtypes(".debug_pubtypes"); | |||
1809 | static ConstString g_sect_name_dwarf_debug_ranges(".debug_ranges"); | |||
1810 | static ConstString g_sect_name_dwarf_debug_str(".debug_str"); | |||
1811 | static ConstString g_sect_name_dwarf_debug_str_offsets( | |||
1812 | ".debug_str_offsets"); | |||
1813 | static ConstString g_sect_name_dwarf_debug_abbrev_dwo( | |||
1814 | ".debug_abbrev.dwo"); | |||
1815 | static ConstString g_sect_name_dwarf_debug_info_dwo(".debug_info.dwo"); | |||
1816 | static ConstString g_sect_name_dwarf_debug_line_dwo(".debug_line.dwo"); | |||
1817 | static ConstString g_sect_name_dwarf_debug_macro_dwo(".debug_macro.dwo"); | |||
1818 | static ConstString g_sect_name_dwarf_debug_loc_dwo(".debug_loc.dwo"); | |||
1819 | static ConstString g_sect_name_dwarf_debug_str_dwo(".debug_str.dwo"); | |||
1820 | static ConstString g_sect_name_dwarf_debug_str_offsets_dwo( | |||
1821 | ".debug_str_offsets.dwo"); | |||
1822 | static ConstString g_sect_name_eh_frame(".eh_frame"); | |||
1823 | static ConstString g_sect_name_arm_exidx(".ARM.exidx"); | |||
1824 | static ConstString g_sect_name_arm_extab(".ARM.extab"); | |||
1825 | static ConstString g_sect_name_go_symtab(".gosymtab"); | |||
1826 | ||||
1827 | SectionType sect_type = eSectionTypeOther; | |||
1828 | ||||
1829 | bool is_thread_specific = false; | |||
1830 | ||||
1831 | if (name == g_sect_name_text) | |||
1832 | sect_type = eSectionTypeCode; | |||
1833 | else if (name == g_sect_name_data) | |||
1834 | sect_type = eSectionTypeData; | |||
1835 | else if (name == g_sect_name_bss) | |||
1836 | sect_type = eSectionTypeZeroFill; | |||
1837 | else if (name == g_sect_name_tdata) { | |||
1838 | sect_type = eSectionTypeData; | |||
1839 | is_thread_specific = true; | |||
1840 | } else if (name == g_sect_name_tbss) { | |||
1841 | sect_type = eSectionTypeZeroFill; | |||
1842 | is_thread_specific = true; | |||
1843 | } | |||
1844 | // .debug_abbrev – Abbreviations used in the .debug_info section | |||
1845 | // .debug_aranges – Lookup table for mapping addresses to compilation | |||
1846 | // units | |||
1847 | // .debug_frame – Call frame information | |||
1848 | // .debug_info – The core DWARF information section | |||
1849 | // .debug_line – Line number information | |||
1850 | // .debug_loc – Location lists used in DW_AT_location attributes | |||
1851 | // .debug_macinfo – Macro information | |||
1852 | // .debug_pubnames – Lookup table for mapping object and function names to | |||
1853 | // compilation units | |||
1854 | // .debug_pubtypes – Lookup table for mapping type names to compilation | |||
1855 | // units | |||
1856 | // .debug_ranges – Address ranges used in DW_AT_ranges attributes | |||
1857 | // .debug_str – String table used in .debug_info | |||
1858 | // MISSING? .gnu_debugdata - "mini debuginfo / MiniDebugInfo" section, | |||
1859 | // http://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html | |||
1860 | // MISSING? .debug-index - | |||
1861 | // http://src.chromium.org/viewvc/chrome/trunk/src/build/gdb-add-index?pathrev=144644 | |||
1862 | // MISSING? .debug_types - Type descriptions from DWARF 4? See | |||
1863 | // http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo | |||
1864 | else if (name == g_sect_name_dwarf_debug_abbrev) | |||
1865 | sect_type = eSectionTypeDWARFDebugAbbrev; | |||
1866 | else if (name == g_sect_name_dwarf_debug_addr) | |||
1867 | sect_type = eSectionTypeDWARFDebugAddr; | |||
1868 | else if (name == g_sect_name_dwarf_debug_aranges) | |||
1869 | sect_type = eSectionTypeDWARFDebugAranges; | |||
1870 | else if (name == g_sect_name_dwarf_debug_cu_index) | |||
1871 | sect_type = eSectionTypeDWARFDebugCuIndex; | |||
1872 | else if (name == g_sect_name_dwarf_debug_frame) | |||
1873 | sect_type = eSectionTypeDWARFDebugFrame; | |||
1874 | else if (name == g_sect_name_dwarf_debug_info) | |||
1875 | sect_type = eSectionTypeDWARFDebugInfo; | |||
1876 | else if (name == g_sect_name_dwarf_debug_line) | |||
1877 | sect_type = eSectionTypeDWARFDebugLine; | |||
1878 | else if (name == g_sect_name_dwarf_debug_loc) | |||
1879 | sect_type = eSectionTypeDWARFDebugLoc; | |||
1880 | else if (name == g_sect_name_dwarf_debug_macinfo) | |||
1881 | sect_type = eSectionTypeDWARFDebugMacInfo; | |||
1882 | else if (name == g_sect_name_dwarf_debug_macro) | |||
1883 | sect_type = eSectionTypeDWARFDebugMacro; | |||
1884 | else if (name == g_sect_name_dwarf_debug_pubnames) | |||
1885 | sect_type = eSectionTypeDWARFDebugPubNames; | |||
1886 | else if (name == g_sect_name_dwarf_debug_pubtypes) | |||
1887 | sect_type = eSectionTypeDWARFDebugPubTypes; | |||
1888 | else if (name == g_sect_name_dwarf_debug_ranges) | |||
1889 | sect_type = eSectionTypeDWARFDebugRanges; | |||
1890 | else if (name == g_sect_name_dwarf_debug_str) | |||
1891 | sect_type = eSectionTypeDWARFDebugStr; | |||
1892 | else if (name == g_sect_name_dwarf_debug_str_offsets) | |||
1893 | sect_type = eSectionTypeDWARFDebugStrOffsets; | |||
1894 | else if (name == g_sect_name_dwarf_debug_abbrev_dwo) | |||
1895 | sect_type = eSectionTypeDWARFDebugAbbrev; | |||
1896 | else if (name == g_sect_name_dwarf_debug_info_dwo) | |||
1897 | sect_type = eSectionTypeDWARFDebugInfo; | |||
1898 | else if (name == g_sect_name_dwarf_debug_line_dwo) | |||
1899 | sect_type = eSectionTypeDWARFDebugLine; | |||
1900 | else if (name == g_sect_name_dwarf_debug_macro_dwo) | |||
1901 | sect_type = eSectionTypeDWARFDebugMacro; | |||
1902 | else if (name == g_sect_name_dwarf_debug_loc_dwo) | |||
1903 | sect_type = eSectionTypeDWARFDebugLoc; | |||
1904 | else if (name == g_sect_name_dwarf_debug_str_dwo) | |||
1905 | sect_type = eSectionTypeDWARFDebugStr; | |||
1906 | else if (name == g_sect_name_dwarf_debug_str_offsets_dwo) | |||
1907 | sect_type = eSectionTypeDWARFDebugStrOffsets; | |||
1908 | else if (name == g_sect_name_eh_frame) | |||
1909 | sect_type = eSectionTypeEHFrame; | |||
1910 | else if (name == g_sect_name_arm_exidx) | |||
1911 | sect_type = eSectionTypeARMexidx; | |||
1912 | else if (name == g_sect_name_arm_extab) | |||
1913 | sect_type = eSectionTypeARMextab; | |||
1914 | else if (name == g_sect_name_go_symtab) | |||
1915 | sect_type = eSectionTypeGoSymtab; | |||
1916 | ||||
1917 | const uint32_t permissions = | |||
1918 | ((header.sh_flags & SHF_ALLOC) ? ePermissionsReadable : 0u) | | |||
1919 | ((header.sh_flags & SHF_WRITE) ? ePermissionsWritable : 0u) | | |||
1920 | ((header.sh_flags & SHF_EXECINSTR) ? ePermissionsExecutable : 0u); | |||
1921 | switch (header.sh_type) { | |||
1922 | case SHT_SYMTAB: | |||
1923 | assert(sect_type == eSectionTypeOther)(static_cast <bool> (sect_type == eSectionTypeOther) ? void (0) : __assert_fail ("sect_type == eSectionTypeOther", "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 1923, __extension__ __PRETTY_FUNCTION__)); | |||
1924 | sect_type = eSectionTypeELFSymbolTable; | |||
1925 | break; | |||
1926 | case SHT_DYNSYM: | |||
1927 | assert(sect_type == eSectionTypeOther)(static_cast <bool> (sect_type == eSectionTypeOther) ? void (0) : __assert_fail ("sect_type == eSectionTypeOther", "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 1927, __extension__ __PRETTY_FUNCTION__)); | |||
1928 | sect_type = eSectionTypeELFDynamicSymbols; | |||
1929 | break; | |||
1930 | case SHT_RELA: | |||
1931 | case SHT_REL: | |||
1932 | assert(sect_type == eSectionTypeOther)(static_cast <bool> (sect_type == eSectionTypeOther) ? void (0) : __assert_fail ("sect_type == eSectionTypeOther", "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 1932, __extension__ __PRETTY_FUNCTION__)); | |||
1933 | sect_type = eSectionTypeELFRelocationEntries; | |||
1934 | break; | |||
1935 | case SHT_DYNAMIC: | |||
1936 | assert(sect_type == eSectionTypeOther)(static_cast <bool> (sect_type == eSectionTypeOther) ? void (0) : __assert_fail ("sect_type == eSectionTypeOther", "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 1936, __extension__ __PRETTY_FUNCTION__)); | |||
1937 | sect_type = eSectionTypeELFDynamicLinkInfo; | |||
1938 | break; | |||
1939 | } | |||
1940 | ||||
1941 | if (eSectionTypeOther == sect_type) { | |||
1942 | // the kalimba toolchain assumes that ELF section names are free-form. | |||
1943 | // It does | |||
1944 | // support linkscripts which (can) give rise to various arbitrarily | |||
1945 | // named | |||
1946 | // sections being "Code" or "Data". | |||
1947 | sect_type = kalimbaSectionType(m_header, header); | |||
1948 | } | |||
1949 | ||||
1950 | const uint32_t target_bytes_size = | |||
1951 | (eSectionTypeData == sect_type || eSectionTypeZeroFill == sect_type) | |||
1952 | ? m_arch_spec.GetDataByteSize() | |||
1953 | : eSectionTypeCode == sect_type ? m_arch_spec.GetCodeByteSize() | |||
1954 | : 1; | |||
1955 | elf::elf_xword log2align = | |||
1956 | (header.sh_addralign == 0) ? 0 : llvm::Log2_64(header.sh_addralign); | |||
1957 | ||||
1958 | uint64_t addr = header.sh_addr; | |||
1959 | ||||
1960 | if ((header.sh_flags & SHF_ALLOC) && synthaddrs) { | |||
1961 | nextaddr = | |||
1962 | (nextaddr + header.sh_addralign - 1) & ~(header.sh_addralign - 1); | |||
1963 | addr = nextaddr; | |||
1964 | nextaddr += vm_size; | |||
1965 | } | |||
1966 | ||||
1967 | SectionSP section_sp(new Section( | |||
1968 | GetModule(), // Module to which this section belongs. | |||
1969 | this, // ObjectFile to which this section belongs and should read | |||
1970 | // section data from. | |||
1971 | SectionIndex(I), // Section ID. | |||
1972 | name, // Section name. | |||
1973 | sect_type, // Section type. | |||
1974 | addr, // VM address. | |||
1975 | vm_size, // VM size in bytes of this section. | |||
1976 | header.sh_offset, // Offset of this section in the file. | |||
1977 | file_size, // Size of the section as found in the file. | |||
1978 | log2align, // Alignment of the section | |||
1979 | header.sh_flags, // Flags for this section. | |||
1980 | target_bytes_size)); // Number of host bytes per target byte | |||
1981 | ||||
1982 | section_sp->SetPermissions(permissions); | |||
1983 | if (is_thread_specific) | |||
1984 | section_sp->SetIsThreadSpecific(is_thread_specific); | |||
1985 | m_sections_ap->AddSection(section_sp); | |||
1986 | } | |||
1987 | } | |||
1988 | ||||
1989 | if (m_sections_ap.get()) { | |||
1990 | if (GetType() == eTypeDebugInfo) { | |||
1991 | static const SectionType g_sections[] = { | |||
1992 | eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr, | |||
1993 | eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex, | |||
1994 | eSectionTypeDWARFDebugFrame, eSectionTypeDWARFDebugInfo, | |||
1995 | eSectionTypeDWARFDebugLine, eSectionTypeDWARFDebugLoc, | |||
1996 | eSectionTypeDWARFDebugMacInfo, eSectionTypeDWARFDebugPubNames, | |||
1997 | eSectionTypeDWARFDebugPubTypes, eSectionTypeDWARFDebugRanges, | |||
1998 | eSectionTypeDWARFDebugStr, eSectionTypeDWARFDebugStrOffsets, | |||
1999 | eSectionTypeELFSymbolTable, | |||
2000 | }; | |||
2001 | SectionList *elf_section_list = m_sections_ap.get(); | |||
2002 | for (size_t idx = 0; idx < sizeof(g_sections) / sizeof(g_sections[0]); | |||
2003 | ++idx) { | |||
2004 | SectionType section_type = g_sections[idx]; | |||
2005 | SectionSP section_sp( | |||
2006 | elf_section_list->FindSectionByType(section_type, true)); | |||
2007 | if (section_sp) { | |||
2008 | SectionSP module_section_sp( | |||
2009 | unified_section_list.FindSectionByType(section_type, true)); | |||
2010 | if (module_section_sp) | |||
2011 | unified_section_list.ReplaceSection(module_section_sp->GetID(), | |||
2012 | section_sp); | |||
2013 | else | |||
2014 | unified_section_list.AddSection(section_sp); | |||
2015 | } | |||
2016 | } | |||
2017 | } else { | |||
2018 | unified_section_list = *m_sections_ap; | |||
2019 | } | |||
2020 | } | |||
2021 | } | |||
2022 | ||||
2023 | // Find the arm/aarch64 mapping symbol character in the given symbol name. | |||
2024 | // Mapping symbols have the | |||
2025 | // form of "$<char>[.<any>]*". Additionally we recognize cases when the mapping | |||
2026 | // symbol prefixed by | |||
2027 | // an arbitrary string because if a symbol prefix added to each symbol in the | |||
2028 | // object file with | |||
2029 | // objcopy then the mapping symbols are also prefixed. | |||
2030 | static char FindArmAarch64MappingSymbol(const char *symbol_name) { | |||
2031 | if (!symbol_name) | |||
2032 | return '\0'; | |||
2033 | ||||
2034 | const char *dollar_pos = ::strchr(symbol_name, '$'); | |||
2035 | if (!dollar_pos || dollar_pos[1] == '\0') | |||
2036 | return '\0'; | |||
2037 | ||||
2038 | if (dollar_pos[2] == '\0' || dollar_pos[2] == '.') | |||
2039 | return dollar_pos[1]; | |||
2040 | return '\0'; | |||
2041 | } | |||
2042 | ||||
2043 | #define STO_MIPS_ISA(3 << 6) (3 << 6) | |||
2044 | #define STO_MICROMIPS(2 << 6) (2 << 6) | |||
2045 | #define IS_MICROMIPS(ST_OTHER)(((ST_OTHER)&(3 << 6)) == (2 << 6)) (((ST_OTHER)&STO_MIPS_ISA(3 << 6)) == STO_MICROMIPS(2 << 6)) | |||
2046 | ||||
2047 | // private | |||
2048 | unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, | |||
2049 | SectionList *section_list, | |||
2050 | const size_t num_symbols, | |||
2051 | const DataExtractor &symtab_data, | |||
2052 | const DataExtractor &strtab_data) { | |||
2053 | ELFSymbol symbol; | |||
2054 | lldb::offset_t offset = 0; | |||
2055 | ||||
2056 | static ConstString text_section_name(".text"); | |||
2057 | static ConstString init_section_name(".init"); | |||
2058 | static ConstString fini_section_name(".fini"); | |||
2059 | static ConstString ctors_section_name(".ctors"); | |||
2060 | static ConstString dtors_section_name(".dtors"); | |||
2061 | ||||
2062 | static ConstString data_section_name(".data"); | |||
2063 | static ConstString rodata_section_name(".rodata"); | |||
2064 | static ConstString rodata1_section_name(".rodata1"); | |||
2065 | static ConstString data2_section_name(".data1"); | |||
2066 | static ConstString bss_section_name(".bss"); | |||
2067 | static ConstString opd_section_name(".opd"); // For ppc64 | |||
2068 | ||||
2069 | // On Android the oatdata and the oatexec symbols in the oat and odex files | |||
2070 | // covers the full | |||
2071 | // .text section what causes issues with displaying unusable symbol name to | |||
2072 | // the user and very | |||
2073 | // slow unwinding speed because the instruction emulation based unwind plans | |||
2074 | // try to emulate all | |||
2075 | // instructions in these symbols. Don't add these symbols to the symbol list | |||
2076 | // as they have no | |||
2077 | // use for the debugger and they are causing a lot of trouble. | |||
2078 | // Filtering can't be restricted to Android because this special object file | |||
2079 | // don't contain the | |||
2080 | // note section specifying the environment to Android but the custom extension | |||
2081 | // and file name | |||
2082 | // makes it highly unlikely that this will collide with anything else. | |||
2083 | ConstString file_extension = m_file.GetFileNameExtension(); | |||
2084 | bool skip_oatdata_oatexec = file_extension == ConstString("oat") || | |||
2085 | file_extension == ConstString("odex"); | |||
2086 | ||||
2087 | ArchSpec arch; | |||
2088 | GetArchitecture(arch); | |||
2089 | ModuleSP module_sp(GetModule()); | |||
2090 | SectionList *module_section_list = | |||
2091 | module_sp ? module_sp->GetSectionList() : nullptr; | |||
| ||||
2092 | ||||
2093 | // Local cache to avoid doing a FindSectionByName for each symbol. The "const | |||
2094 | // char*" key must | |||
2095 | // came from a ConstString object so they can be compared by pointer | |||
2096 | std::unordered_map<const char *, lldb::SectionSP> section_name_to_section; | |||
2097 | ||||
2098 | unsigned i; | |||
2099 | for (i = 0; i < num_symbols; ++i) { | |||
2100 | if (symbol.Parse(symtab_data, &offset) == false) | |||
2101 | break; | |||
2102 | ||||
2103 | const char *symbol_name = strtab_data.PeekCStr(symbol.st_name); | |||
2104 | if (!symbol_name) | |||
2105 | symbol_name = ""; | |||
2106 | ||||
2107 | // No need to add non-section symbols that have no names | |||
2108 | if (symbol.getType() != STT_SECTION && | |||
2109 | (symbol_name == nullptr || symbol_name[0] == '\0')) | |||
2110 | continue; | |||
2111 | ||||
2112 | // Skipping oatdata and oatexec sections if it is requested. See details | |||
2113 | // above the | |||
2114 | // definition of skip_oatdata_oatexec for the reasons. | |||
2115 | if (skip_oatdata_oatexec && (::strcmp(symbol_name, "oatdata") == 0 || | |||
2116 | ::strcmp(symbol_name, "oatexec") == 0)) | |||
2117 | continue; | |||
2118 | ||||
2119 | SectionSP symbol_section_sp; | |||
2120 | SymbolType symbol_type = eSymbolTypeInvalid; | |||
2121 | Elf64_Half section_idx = symbol.st_shndx; | |||
2122 | ||||
2123 | switch (section_idx) { | |||
2124 | case SHN_ABS: | |||
2125 | symbol_type = eSymbolTypeAbsolute; | |||
2126 | break; | |||
2127 | case SHN_UNDEF: | |||
2128 | symbol_type = eSymbolTypeUndefined; | |||
2129 | break; | |||
2130 | default: | |||
2131 | symbol_section_sp = section_list->GetSectionAtIndex(section_idx); | |||
2132 | break; | |||
2133 | } | |||
2134 | ||||
2135 | // If a symbol is undefined do not process it further even if it has a STT | |||
2136 | // type | |||
2137 | if (symbol_type != eSymbolTypeUndefined) { | |||
2138 | switch (symbol.getType()) { | |||
2139 | default: | |||
2140 | case STT_NOTYPE: | |||
2141 | // The symbol's type is not specified. | |||
2142 | break; | |||
2143 | ||||
2144 | case STT_OBJECT: | |||
2145 | // The symbol is associated with a data object, such as a variable, | |||
2146 | // an array, etc. | |||
2147 | symbol_type = eSymbolTypeData; | |||
2148 | break; | |||
2149 | ||||
2150 | case STT_FUNC: | |||
2151 | // The symbol is associated with a function or other executable code. | |||
2152 | symbol_type = eSymbolTypeCode; | |||
2153 | break; | |||
2154 | ||||
2155 | case STT_SECTION: | |||
2156 | // The symbol is associated with a section. Symbol table entries of | |||
2157 | // this type exist primarily for relocation and normally have | |||
2158 | // STB_LOCAL binding. | |||
2159 | break; | |||
2160 | ||||
2161 | case STT_FILE: | |||
2162 | // Conventionally, the symbol's name gives the name of the source | |||
2163 | // file associated with the object file. A file symbol has STB_LOCAL | |||
2164 | // binding, its section index is SHN_ABS, and it precedes the other | |||
2165 | // STB_LOCAL symbols for the file, if it is present. | |||
2166 | symbol_type = eSymbolTypeSourceFile; | |||
2167 | break; | |||
2168 | ||||
2169 | case STT_GNU_IFUNC: | |||
2170 | // The symbol is associated with an indirect function. The actual | |||
2171 | // function will be resolved if it is referenced. | |||
2172 | symbol_type = eSymbolTypeResolver; | |||
2173 | break; | |||
2174 | } | |||
2175 | } | |||
2176 | ||||
2177 | if (symbol_type == eSymbolTypeInvalid && symbol.getType() != STT_SECTION) { | |||
2178 | if (symbol_section_sp) { | |||
2179 | const ConstString §_name = symbol_section_sp->GetName(); | |||
2180 | if (sect_name == text_section_name || sect_name == init_section_name || | |||
2181 | sect_name == fini_section_name || sect_name == ctors_section_name || | |||
2182 | sect_name == dtors_section_name) { | |||
2183 | symbol_type = eSymbolTypeCode; | |||
2184 | } else if (sect_name == data_section_name || | |||
2185 | sect_name == data2_section_name || | |||
2186 | sect_name == rodata_section_name || | |||
2187 | sect_name == rodata1_section_name || | |||
2188 | sect_name == bss_section_name) { | |||
2189 | symbol_type = eSymbolTypeData; | |||
2190 | } | |||
2191 | } | |||
2192 | } | |||
2193 | ||||
2194 | int64_t symbol_value_offset = 0; | |||
2195 | uint32_t additional_flags = 0; | |||
2196 | ||||
2197 | if (arch.IsValid()) { | |||
2198 | if (arch.GetMachine() == llvm::Triple::arm) { | |||
2199 | if (symbol.getBinding() == STB_LOCAL) { | |||
2200 | char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name); | |||
2201 | if (symbol_type == eSymbolTypeCode) { | |||
2202 | switch (mapping_symbol) { | |||
2203 | case 'a': | |||
2204 | // $a[.<any>]* - marks an ARM instruction sequence | |||
2205 | m_address_class_map[symbol.st_value] = eAddressClassCode; | |||
2206 | break; | |||
2207 | case 'b': | |||
2208 | case 't': | |||
2209 | // $b[.<any>]* - marks a THUMB BL instruction sequence | |||
2210 | // $t[.<any>]* - marks a THUMB instruction sequence | |||
2211 | m_address_class_map[symbol.st_value] = | |||
2212 | eAddressClassCodeAlternateISA; | |||
2213 | break; | |||
2214 | case 'd': | |||
2215 | // $d[.<any>]* - marks a data item sequence (e.g. lit pool) | |||
2216 | m_address_class_map[symbol.st_value] = eAddressClassData; | |||
2217 | break; | |||
2218 | } | |||
2219 | } | |||
2220 | if (mapping_symbol) | |||
2221 | continue; | |||
2222 | } | |||
2223 | } else if (arch.GetMachine() == llvm::Triple::aarch64) { | |||
2224 | if (symbol.getBinding() == STB_LOCAL) { | |||
2225 | char mapping_symbol = FindArmAarch64MappingSymbol(symbol_name); | |||
2226 | if (symbol_type == eSymbolTypeCode) { | |||
2227 | switch (mapping_symbol) { | |||
2228 | case 'x': | |||
2229 | // $x[.<any>]* - marks an A64 instruction sequence | |||
2230 | m_address_class_map[symbol.st_value] = eAddressClassCode; | |||
2231 | break; | |||
2232 | case 'd': | |||
2233 | // $d[.<any>]* - marks a data item sequence (e.g. lit pool) | |||
2234 | m_address_class_map[symbol.st_value] = eAddressClassData; | |||
2235 | break; | |||
2236 | } | |||
2237 | } | |||
2238 | if (mapping_symbol) | |||
2239 | continue; | |||
2240 | } | |||
2241 | } | |||
2242 | ||||
2243 | if (arch.GetMachine() == llvm::Triple::arm) { | |||
2244 | if (symbol_type == eSymbolTypeCode) { | |||
2245 | if (symbol.st_value & 1) { | |||
2246 | // Subtracting 1 from the address effectively unsets | |||
2247 | // the low order bit, which results in the address | |||
2248 | // actually pointing to the beginning of the symbol. | |||
2249 | // This delta will be used below in conjunction with | |||
2250 | // symbol.st_value to produce the final symbol_value | |||
2251 | // that we store in the symtab. | |||
2252 | symbol_value_offset = -1; | |||
2253 | m_address_class_map[symbol.st_value ^ 1] = | |||
2254 | eAddressClassCodeAlternateISA; | |||
2255 | } else { | |||
2256 | // This address is ARM | |||
2257 | m_address_class_map[symbol.st_value] = eAddressClassCode; | |||
2258 | } | |||
2259 | } | |||
2260 | } | |||
2261 | ||||
2262 | /* | |||
2263 | * MIPS: | |||
2264 | * The bit #0 of an address is used for ISA mode (1 for microMIPS, 0 for | |||
2265 | * MIPS). | |||
2266 | * This allows processor to switch between microMIPS and MIPS without any | |||
2267 | * need | |||
2268 | * for special mode-control register. However, apart from .debug_line, | |||
2269 | * none of | |||
2270 | * the ELF/DWARF sections set the ISA bit (for symbol or section). Use | |||
2271 | * st_other | |||
2272 | * flag to check whether the symbol is microMIPS and then set the address | |||
2273 | * class | |||
2274 | * accordingly. | |||
2275 | */ | |||
2276 | const llvm::Triple::ArchType llvm_arch = arch.GetMachine(); | |||
2277 | if (llvm_arch == llvm::Triple::mips || | |||
2278 | llvm_arch == llvm::Triple::mipsel || | |||
2279 | llvm_arch == llvm::Triple::mips64 || | |||
2280 | llvm_arch == llvm::Triple::mips64el) { | |||
2281 | if (IS_MICROMIPS(symbol.st_other)(((symbol.st_other)&(3 << 6)) == (2 << 6))) | |||
2282 | m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA; | |||
2283 | else if ((symbol.st_value & 1) && (symbol_type == eSymbolTypeCode)) { | |||
2284 | symbol.st_value = symbol.st_value & (~1ull); | |||
2285 | m_address_class_map[symbol.st_value] = eAddressClassCodeAlternateISA; | |||
2286 | } else { | |||
2287 | if (symbol_type == eSymbolTypeCode) | |||
2288 | m_address_class_map[symbol.st_value] = eAddressClassCode; | |||
2289 | else if (symbol_type == eSymbolTypeData) | |||
2290 | m_address_class_map[symbol.st_value] = eAddressClassData; | |||
2291 | else | |||
2292 | m_address_class_map[symbol.st_value] = eAddressClassUnknown; | |||
2293 | } | |||
2294 | } | |||
2295 | } | |||
2296 | ||||
2297 | // symbol_value_offset may contain 0 for ARM symbols or -1 for THUMB | |||
2298 | // symbols. See above for | |||
2299 | // more details. | |||
2300 | uint64_t symbol_value = symbol.st_value + symbol_value_offset; | |||
2301 | ||||
2302 | if (symbol_section_sp == nullptr && section_idx == SHN_ABS && | |||
2303 | symbol.st_size != 0) { | |||
2304 | // We don't have a section for a symbol with non-zero size. Create a new | |||
2305 | // section for it | |||
2306 | // so the address range covered by the symbol is also covered by the | |||
2307 | // module (represented | |||
2308 | // through the section list). It is needed so module lookup for the | |||
2309 | // addresses covered | |||
2310 | // by this symbol will be successfull. This case happens for absolute | |||
2311 | // symbols. | |||
2312 | ConstString fake_section_name(std::string(".absolute.") + symbol_name); | |||
2313 | symbol_section_sp = | |||
2314 | std::make_shared<Section>(module_sp, this, SHN_ABS, fake_section_name, | |||
2315 | eSectionTypeAbsoluteAddress, symbol_value, | |||
2316 | symbol.st_size, 0, 0, 0, SHF_ALLOC); | |||
2317 | ||||
2318 | module_section_list->AddSection(symbol_section_sp); | |||
| ||||
2319 | section_list->AddSection(symbol_section_sp); | |||
2320 | } | |||
2321 | ||||
2322 | if (symbol_section_sp && | |||
2323 | CalculateType() != ObjectFile::Type::eTypeObjectFile) | |||
2324 | symbol_value -= symbol_section_sp->GetFileAddress(); | |||
2325 | ||||
2326 | if (symbol_section_sp && module_section_list && | |||
2327 | module_section_list != section_list) { | |||
2328 | const ConstString §_name = symbol_section_sp->GetName(); | |||
2329 | auto section_it = section_name_to_section.find(sect_name.GetCString()); | |||
2330 | if (section_it == section_name_to_section.end()) | |||
2331 | section_it = | |||
2332 | section_name_to_section | |||
2333 | .emplace(sect_name.GetCString(), | |||
2334 | module_section_list->FindSectionByName(sect_name)) | |||
2335 | .first; | |||
2336 | if (section_it->second) | |||
2337 | symbol_section_sp = section_it->second; | |||
2338 | } | |||
2339 | ||||
2340 | bool is_global = symbol.getBinding() == STB_GLOBAL; | |||
2341 | uint32_t flags = symbol.st_other << 8 | symbol.st_info | additional_flags; | |||
2342 | bool is_mangled = (symbol_name[0] == '_' && symbol_name[1] == 'Z'); | |||
2343 | ||||
2344 | llvm::StringRef symbol_ref(symbol_name); | |||
2345 | ||||
2346 | // Symbol names may contain @VERSION suffixes. Find those and strip them | |||
2347 | // temporarily. | |||
2348 | size_t version_pos = symbol_ref.find('@'); | |||
2349 | bool has_suffix = version_pos != llvm::StringRef::npos; | |||
2350 | llvm::StringRef symbol_bare = symbol_ref.substr(0, version_pos); | |||
2351 | Mangled mangled(ConstString(symbol_bare), is_mangled); | |||
2352 | ||||
2353 | // Now append the suffix back to mangled and unmangled names. Only do it if | |||
2354 | // the | |||
2355 | // demangling was successful (string is not empty). | |||
2356 | if (has_suffix) { | |||
2357 | llvm::StringRef suffix = symbol_ref.substr(version_pos); | |||
2358 | ||||
2359 | llvm::StringRef mangled_name = mangled.GetMangledName().GetStringRef(); | |||
2360 | if (!mangled_name.empty()) | |||
2361 | mangled.SetMangledName(ConstString((mangled_name + suffix).str())); | |||
2362 | ||||
2363 | ConstString demangled = | |||
2364 | mangled.GetDemangledName(lldb::eLanguageTypeUnknown); | |||
2365 | llvm::StringRef demangled_name = demangled.GetStringRef(); | |||
2366 | if (!demangled_name.empty()) | |||
2367 | mangled.SetDemangledName(ConstString((demangled_name + suffix).str())); | |||
2368 | } | |||
2369 | ||||
2370 | // In ELF all symbol should have a valid size but it is not true for some | |||
2371 | // function symbols | |||
2372 | // coming from hand written assembly. As none of the function symbol should | |||
2373 | // have 0 size we | |||
2374 | // try to calculate the size for these symbols in the symtab with saying | |||
2375 | // that their original | |||
2376 | // size is not valid. | |||
2377 | bool symbol_size_valid = | |||
2378 | symbol.st_size != 0 || symbol.getType() != STT_FUNC; | |||
2379 | ||||
2380 | Symbol dc_symbol( | |||
2381 | i + start_id, // ID is the original symbol table index. | |||
2382 | mangled, | |||
2383 | symbol_type, // Type of this symbol | |||
2384 | is_global, // Is this globally visible? | |||
2385 | false, // Is this symbol debug info? | |||
2386 | false, // Is this symbol a trampoline? | |||
2387 | false, // Is this symbol artificial? | |||
2388 | AddressRange(symbol_section_sp, // Section in which this symbol is | |||
2389 | // defined or null. | |||
2390 | symbol_value, // Offset in section or symbol value. | |||
2391 | symbol.st_size), // Size in bytes of this symbol. | |||
2392 | symbol_size_valid, // Symbol size is valid | |||
2393 | has_suffix, // Contains linker annotations? | |||
2394 | flags); // Symbol flags. | |||
2395 | symtab->AddSymbol(dc_symbol); | |||
2396 | } | |||
2397 | return i; | |||
2398 | } | |||
2399 | ||||
2400 | unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, | |||
2401 | user_id_t start_id, | |||
2402 | lldb_private::Section *symtab) { | |||
2403 | if (symtab->GetObjectFile() != this) { | |||
2404 | // If the symbol table section is owned by a different object file, have it | |||
2405 | // do the | |||
2406 | // parsing. | |||
2407 | ObjectFileELF *obj_file_elf = | |||
2408 | static_cast<ObjectFileELF *>(symtab->GetObjectFile()); | |||
2409 | return obj_file_elf->ParseSymbolTable(symbol_table, start_id, symtab); | |||
2410 | } | |||
2411 | ||||
2412 | // Get section list for this object file. | |||
2413 | SectionList *section_list = m_sections_ap.get(); | |||
2414 | if (!section_list) | |||
2415 | return 0; | |||
2416 | ||||
2417 | user_id_t symtab_id = symtab->GetID(); | |||
2418 | const ELFSectionHeaderInfo *symtab_hdr = GetSectionHeaderByIndex(symtab_id); | |||
2419 | assert(symtab_hdr->sh_type == SHT_SYMTAB ||(static_cast <bool> (symtab_hdr->sh_type == SHT_SYMTAB || symtab_hdr->sh_type == SHT_DYNSYM) ? void (0) : __assert_fail ("symtab_hdr->sh_type == SHT_SYMTAB || symtab_hdr->sh_type == SHT_DYNSYM" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 2420, __extension__ __PRETTY_FUNCTION__)) | |||
2420 | symtab_hdr->sh_type == SHT_DYNSYM)(static_cast <bool> (symtab_hdr->sh_type == SHT_SYMTAB || symtab_hdr->sh_type == SHT_DYNSYM) ? void (0) : __assert_fail ("symtab_hdr->sh_type == SHT_SYMTAB || symtab_hdr->sh_type == SHT_DYNSYM" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 2420, __extension__ __PRETTY_FUNCTION__)); | |||
2421 | ||||
2422 | // sh_link: section header index of associated string table. | |||
2423 | // Section ID's are ones based. | |||
2424 | user_id_t strtab_id = symtab_hdr->sh_link + 1; | |||
2425 | Section *strtab = section_list->FindSectionByID(strtab_id).get(); | |||
2426 | ||||
2427 | if (symtab && strtab) { | |||
2428 | assert(symtab->GetObjectFile() == this)(static_cast <bool> (symtab->GetObjectFile() == this ) ? void (0) : __assert_fail ("symtab->GetObjectFile() == this" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 2428, __extension__ __PRETTY_FUNCTION__)); | |||
2429 | assert(strtab->GetObjectFile() == this)(static_cast <bool> (strtab->GetObjectFile() == this ) ? void (0) : __assert_fail ("strtab->GetObjectFile() == this" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 2429, __extension__ __PRETTY_FUNCTION__)); | |||
2430 | ||||
2431 | DataExtractor symtab_data; | |||
2432 | DataExtractor strtab_data; | |||
2433 | if (ReadSectionData(symtab, symtab_data) && | |||
2434 | ReadSectionData(strtab, strtab_data)) { | |||
2435 | size_t num_symbols = symtab_data.GetByteSize() / symtab_hdr->sh_entsize; | |||
2436 | ||||
2437 | return ParseSymbols(symbol_table, start_id, section_list, num_symbols, | |||
2438 | symtab_data, strtab_data); | |||
2439 | } | |||
2440 | } | |||
2441 | ||||
2442 | return 0; | |||
2443 | } | |||
2444 | ||||
2445 | size_t ObjectFileELF::ParseDynamicSymbols() { | |||
2446 | if (m_dynamic_symbols.size()) | |||
2447 | return m_dynamic_symbols.size(); | |||
2448 | ||||
2449 | SectionList *section_list = GetSectionList(); | |||
2450 | if (!section_list) | |||
2451 | return 0; | |||
2452 | ||||
2453 | // Find the SHT_DYNAMIC section. | |||
2454 | Section *dynsym = | |||
2455 | section_list->FindSectionByType(eSectionTypeELFDynamicLinkInfo, true) | |||
2456 | .get(); | |||
2457 | if (!dynsym) | |||
2458 | return 0; | |||
2459 | assert(dynsym->GetObjectFile() == this)(static_cast <bool> (dynsym->GetObjectFile() == this ) ? void (0) : __assert_fail ("dynsym->GetObjectFile() == this" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 2459, __extension__ __PRETTY_FUNCTION__)); | |||
2460 | ||||
2461 | ELFDynamic symbol; | |||
2462 | DataExtractor dynsym_data; | |||
2463 | if (ReadSectionData(dynsym, dynsym_data)) { | |||
2464 | const lldb::offset_t section_size = dynsym_data.GetByteSize(); | |||
2465 | lldb::offset_t cursor = 0; | |||
2466 | ||||
2467 | while (cursor < section_size) { | |||
2468 | if (!symbol.Parse(dynsym_data, &cursor)) | |||
2469 | break; | |||
2470 | ||||
2471 | m_dynamic_symbols.push_back(symbol); | |||
2472 | } | |||
2473 | } | |||
2474 | ||||
2475 | return m_dynamic_symbols.size(); | |||
2476 | } | |||
2477 | ||||
2478 | const ELFDynamic *ObjectFileELF::FindDynamicSymbol(unsigned tag) { | |||
2479 | if (!ParseDynamicSymbols()) | |||
2480 | return NULL__null; | |||
2481 | ||||
2482 | DynamicSymbolCollIter I = m_dynamic_symbols.begin(); | |||
2483 | DynamicSymbolCollIter E = m_dynamic_symbols.end(); | |||
2484 | for (; I != E; ++I) { | |||
2485 | ELFDynamic *symbol = &*I; | |||
2486 | ||||
2487 | if (symbol->d_tag == tag) | |||
2488 | return symbol; | |||
2489 | } | |||
2490 | ||||
2491 | return NULL__null; | |||
2492 | } | |||
2493 | ||||
2494 | unsigned ObjectFileELF::PLTRelocationType() { | |||
2495 | // DT_PLTREL | |||
2496 | // This member specifies the type of relocation entry to which the | |||
2497 | // procedure linkage table refers. The d_val member holds DT_REL or | |||
2498 | // DT_RELA, as appropriate. All relocations in a procedure linkage table | |||
2499 | // must use the same relocation. | |||
2500 | const ELFDynamic *symbol = FindDynamicSymbol(DT_PLTREL); | |||
2501 | ||||
2502 | if (symbol) | |||
2503 | return symbol->d_val; | |||
2504 | ||||
2505 | return 0; | |||
2506 | } | |||
2507 | ||||
2508 | // Returns the size of the normal plt entries and the offset of the first normal | |||
2509 | // plt entry. The | |||
2510 | // 0th entry in the plt table is usually a resolution entry which have different | |||
2511 | // size in some | |||
2512 | // architectures then the rest of the plt entries. | |||
2513 | static std::pair<uint64_t, uint64_t> | |||
2514 | GetPltEntrySizeAndOffset(const ELFSectionHeader *rel_hdr, | |||
2515 | const ELFSectionHeader *plt_hdr) { | |||
2516 | const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize; | |||
2517 | ||||
2518 | // Clang 3.3 sets entsize to 4 for 32-bit binaries, but the plt entries are 16 | |||
2519 | // bytes. | |||
2520 | // So round the entsize up by the alignment if addralign is set. | |||
2521 | elf_xword plt_entsize = | |||
2522 | plt_hdr->sh_addralign | |||
2523 | ? llvm::alignTo(plt_hdr->sh_entsize, plt_hdr->sh_addralign) | |||
2524 | : plt_hdr->sh_entsize; | |||
2525 | ||||
2526 | // Some linkers e.g ld for arm, fill plt_hdr->sh_entsize field incorrectly. | |||
2527 | // PLT entries relocation code in general requires multiple instruction and | |||
2528 | // should be greater than 4 bytes in most cases. Try to guess correct size | |||
2529 | // just in case. | |||
2530 | if (plt_entsize <= 4) { | |||
2531 | // The linker haven't set the plt_hdr->sh_entsize field. Try to guess the | |||
2532 | // size of the plt | |||
2533 | // entries based on the number of entries and the size of the plt section | |||
2534 | // with the | |||
2535 | // assumption that the size of the 0th entry is at least as big as the size | |||
2536 | // of the normal | |||
2537 | // entries and it isn't much bigger then that. | |||
2538 | if (plt_hdr->sh_addralign) | |||
2539 | plt_entsize = plt_hdr->sh_size / plt_hdr->sh_addralign / | |||
2540 | (num_relocations + 1) * plt_hdr->sh_addralign; | |||
2541 | else | |||
2542 | plt_entsize = plt_hdr->sh_size / (num_relocations + 1); | |||
2543 | } | |||
2544 | ||||
2545 | elf_xword plt_offset = plt_hdr->sh_size - num_relocations * plt_entsize; | |||
2546 | ||||
2547 | return std::make_pair(plt_entsize, plt_offset); | |||
2548 | } | |||
2549 | ||||
2550 | static unsigned ParsePLTRelocations( | |||
2551 | Symtab *symbol_table, user_id_t start_id, unsigned rel_type, | |||
2552 | const ELFHeader *hdr, const ELFSectionHeader *rel_hdr, | |||
2553 | const ELFSectionHeader *plt_hdr, const ELFSectionHeader *sym_hdr, | |||
2554 | const lldb::SectionSP &plt_section_sp, DataExtractor &rel_data, | |||
2555 | DataExtractor &symtab_data, DataExtractor &strtab_data) { | |||
2556 | ELFRelocation rel(rel_type); | |||
2557 | ELFSymbol symbol; | |||
2558 | lldb::offset_t offset = 0; | |||
2559 | ||||
2560 | uint64_t plt_offset, plt_entsize; | |||
2561 | std::tie(plt_entsize, plt_offset) = | |||
2562 | GetPltEntrySizeAndOffset(rel_hdr, plt_hdr); | |||
2563 | const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize; | |||
2564 | ||||
2565 | typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel); | |||
2566 | reloc_info_fn reloc_type; | |||
2567 | reloc_info_fn reloc_symbol; | |||
2568 | ||||
2569 | if (hdr->Is32Bit()) { | |||
2570 | reloc_type = ELFRelocation::RelocType32; | |||
2571 | reloc_symbol = ELFRelocation::RelocSymbol32; | |||
2572 | } else { | |||
2573 | reloc_type = ELFRelocation::RelocType64; | |||
2574 | reloc_symbol = ELFRelocation::RelocSymbol64; | |||
2575 | } | |||
2576 | ||||
2577 | unsigned slot_type = hdr->GetRelocationJumpSlotType(); | |||
2578 | unsigned i; | |||
2579 | for (i = 0; i < num_relocations; ++i) { | |||
2580 | if (rel.Parse(rel_data, &offset) == false) | |||
2581 | break; | |||
2582 | ||||
2583 | if (reloc_type(rel) != slot_type) | |||
2584 | continue; | |||
2585 | ||||
2586 | lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize; | |||
2587 | if (!symbol.Parse(symtab_data, &symbol_offset)) | |||
2588 | break; | |||
2589 | ||||
2590 | const char *symbol_name = strtab_data.PeekCStr(symbol.st_name); | |||
2591 | bool is_mangled = | |||
2592 | symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false; | |||
2593 | uint64_t plt_index = plt_offset + i * plt_entsize; | |||
2594 | ||||
2595 | Symbol jump_symbol( | |||
2596 | i + start_id, // Symbol table index | |||
2597 | symbol_name, // symbol name. | |||
2598 | is_mangled, // is the symbol name mangled? | |||
2599 | eSymbolTypeTrampoline, // Type of this symbol | |||
2600 | false, // Is this globally visible? | |||
2601 | false, // Is this symbol debug info? | |||
2602 | true, // Is this symbol a trampoline? | |||
2603 | true, // Is this symbol artificial? | |||
2604 | plt_section_sp, // Section in which this symbol is defined or null. | |||
2605 | plt_index, // Offset in section or symbol value. | |||
2606 | plt_entsize, // Size in bytes of this symbol. | |||
2607 | true, // Size is valid | |||
2608 | false, // Contains linker annotations? | |||
2609 | 0); // Symbol flags. | |||
2610 | ||||
2611 | symbol_table->AddSymbol(jump_symbol); | |||
2612 | } | |||
2613 | ||||
2614 | return i; | |||
2615 | } | |||
2616 | ||||
2617 | unsigned | |||
2618 | ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id, | |||
2619 | const ELFSectionHeaderInfo *rel_hdr, | |||
2620 | user_id_t rel_id) { | |||
2621 | assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL)(static_cast <bool> (rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL) ? void (0) : __assert_fail ( "rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 2621, __extension__ __PRETTY_FUNCTION__)); | |||
2622 | ||||
2623 | // The link field points to the associated symbol table. | |||
2624 | user_id_t symtab_id = rel_hdr->sh_link; | |||
2625 | ||||
2626 | // If the link field doesn't point to the appropriate symbol name table then | |||
2627 | // try to find it by name as some compiler don't fill in the link fields. | |||
2628 | if (!symtab_id) | |||
2629 | symtab_id = GetSectionIndexByName(".dynsym"); | |||
2630 | ||||
2631 | // Get PLT section. We cannot use rel_hdr->sh_info, since current linkers | |||
2632 | // point that to the .got.plt or .got section instead of .plt. | |||
2633 | user_id_t plt_id = GetSectionIndexByName(".plt"); | |||
2634 | ||||
2635 | if (!symtab_id || !plt_id) | |||
2636 | return 0; | |||
2637 | ||||
2638 | // Section ID's are ones based; | |||
2639 | symtab_id++; | |||
2640 | plt_id++; | |||
2641 | ||||
2642 | const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id); | |||
2643 | if (!plt_hdr) | |||
2644 | return 0; | |||
2645 | ||||
2646 | const ELFSectionHeaderInfo *sym_hdr = GetSectionHeaderByIndex(symtab_id); | |||
2647 | if (!sym_hdr) | |||
2648 | return 0; | |||
2649 | ||||
2650 | SectionList *section_list = m_sections_ap.get(); | |||
2651 | if (!section_list) | |||
2652 | return 0; | |||
2653 | ||||
2654 | Section *rel_section = section_list->FindSectionByID(rel_id).get(); | |||
2655 | if (!rel_section) | |||
2656 | return 0; | |||
2657 | ||||
2658 | SectionSP plt_section_sp(section_list->FindSectionByID(plt_id)); | |||
2659 | if (!plt_section_sp) | |||
2660 | return 0; | |||
2661 | ||||
2662 | Section *symtab = section_list->FindSectionByID(symtab_id).get(); | |||
2663 | if (!symtab) | |||
2664 | return 0; | |||
2665 | ||||
2666 | // sh_link points to associated string table. | |||
2667 | Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get(); | |||
2668 | if (!strtab) | |||
2669 | return 0; | |||
2670 | ||||
2671 | DataExtractor rel_data; | |||
2672 | if (!ReadSectionData(rel_section, rel_data)) | |||
2673 | return 0; | |||
2674 | ||||
2675 | DataExtractor symtab_data; | |||
2676 | if (!ReadSectionData(symtab, symtab_data)) | |||
2677 | return 0; | |||
2678 | ||||
2679 | DataExtractor strtab_data; | |||
2680 | if (!ReadSectionData(strtab, strtab_data)) | |||
2681 | return 0; | |||
2682 | ||||
2683 | unsigned rel_type = PLTRelocationType(); | |||
2684 | if (!rel_type) | |||
2685 | return 0; | |||
2686 | ||||
2687 | return ParsePLTRelocations(symbol_table, start_id, rel_type, &m_header, | |||
2688 | rel_hdr, plt_hdr, sym_hdr, plt_section_sp, | |||
2689 | rel_data, symtab_data, strtab_data); | |||
2690 | } | |||
2691 | ||||
2692 | unsigned ObjectFileELF::ApplyRelocations( | |||
2693 | Symtab *symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr, | |||
2694 | const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr, | |||
2695 | DataExtractor &rel_data, DataExtractor &symtab_data, | |||
2696 | DataExtractor &debug_data, Section *rel_section) { | |||
2697 | ELFRelocation rel(rel_hdr->sh_type); | |||
2698 | lldb::addr_t offset = 0; | |||
2699 | const unsigned num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize; | |||
2700 | typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel); | |||
2701 | reloc_info_fn reloc_type; | |||
2702 | reloc_info_fn reloc_symbol; | |||
2703 | ||||
2704 | if (hdr->Is32Bit()) { | |||
2705 | reloc_type = ELFRelocation::RelocType32; | |||
2706 | reloc_symbol = ELFRelocation::RelocSymbol32; | |||
2707 | } else { | |||
2708 | reloc_type = ELFRelocation::RelocType64; | |||
2709 | reloc_symbol = ELFRelocation::RelocSymbol64; | |||
2710 | } | |||
2711 | ||||
2712 | for (unsigned i = 0; i < num_relocations; ++i) { | |||
2713 | if (rel.Parse(rel_data, &offset) == false) | |||
2714 | break; | |||
2715 | ||||
2716 | Symbol *symbol = NULL__null; | |||
2717 | ||||
2718 | if (hdr->Is32Bit()) { | |||
2719 | switch (reloc_type(rel)) { | |||
2720 | case R_386_32: | |||
2721 | case R_386_PC32: | |||
2722 | default: | |||
2723 | // FIXME: This asserts with this input: | |||
2724 | // | |||
2725 | // foo.cpp | |||
2726 | // int main(int argc, char **argv) { return 0; } | |||
2727 | // | |||
2728 | // clang++.exe --target=i686-unknown-linux-gnu -g -c foo.cpp -o foo.o | |||
2729 | // | |||
2730 | // and running this on the foo.o module. | |||
2731 | assert(false && "unexpected relocation type")(static_cast <bool> (false && "unexpected relocation type" ) ? void (0) : __assert_fail ("false && \"unexpected relocation type\"" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 2731, __extension__ __PRETTY_FUNCTION__)); | |||
2732 | } | |||
2733 | } else { | |||
2734 | switch (reloc_type(rel)) { | |||
2735 | case R_X86_64_64: { | |||
2736 | symbol = symtab->FindSymbolByID(reloc_symbol(rel)); | |||
2737 | if (symbol) { | |||
2738 | addr_t value = symbol->GetAddressRef().GetFileAddress(); | |||
2739 | DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); | |||
2740 | uint64_t *dst = reinterpret_cast<uint64_t *>( | |||
2741 | data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + | |||
2742 | ELFRelocation::RelocOffset64(rel)); | |||
2743 | *dst = value + ELFRelocation::RelocAddend64(rel); | |||
2744 | } | |||
2745 | break; | |||
2746 | } | |||
2747 | case R_X86_64_32: | |||
2748 | case R_X86_64_32S: { | |||
2749 | symbol = symtab->FindSymbolByID(reloc_symbol(rel)); | |||
2750 | if (symbol) { | |||
2751 | addr_t value = symbol->GetAddressRef().GetFileAddress(); | |||
2752 | value += ELFRelocation::RelocAddend32(rel); | |||
2753 | assert((static_cast <bool> ((reloc_type(rel) == R_X86_64_32 && (value <= (4294967295U))) || (reloc_type(rel) == R_X86_64_32S && ((int64_t)value <= (2147483647) && (int64_t )value >= (-2147483647-1)))) ? void (0) : __assert_fail ("(reloc_type(rel) == R_X86_64_32 && (value <= UINT32_MAX)) || (reloc_type(rel) == R_X86_64_32S && ((int64_t)value <= INT32_MAX && (int64_t)value >= INT32_MIN))" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 2756, __extension__ __PRETTY_FUNCTION__)) | |||
2754 | (reloc_type(rel) == R_X86_64_32 && (value <= UINT32_MAX)) ||(static_cast <bool> ((reloc_type(rel) == R_X86_64_32 && (value <= (4294967295U))) || (reloc_type(rel) == R_X86_64_32S && ((int64_t)value <= (2147483647) && (int64_t )value >= (-2147483647-1)))) ? void (0) : __assert_fail ("(reloc_type(rel) == R_X86_64_32 && (value <= UINT32_MAX)) || (reloc_type(rel) == R_X86_64_32S && ((int64_t)value <= INT32_MAX && (int64_t)value >= INT32_MIN))" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 2756, __extension__ __PRETTY_FUNCTION__)) | |||
2755 | (reloc_type(rel) == R_X86_64_32S &&(static_cast <bool> ((reloc_type(rel) == R_X86_64_32 && (value <= (4294967295U))) || (reloc_type(rel) == R_X86_64_32S && ((int64_t)value <= (2147483647) && (int64_t )value >= (-2147483647-1)))) ? void (0) : __assert_fail ("(reloc_type(rel) == R_X86_64_32 && (value <= UINT32_MAX)) || (reloc_type(rel) == R_X86_64_32S && ((int64_t)value <= INT32_MAX && (int64_t)value >= INT32_MIN))" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 2756, __extension__ __PRETTY_FUNCTION__)) | |||
2756 | ((int64_t)value <= INT32_MAX && (int64_t)value >= INT32_MIN)))(static_cast <bool> ((reloc_type(rel) == R_X86_64_32 && (value <= (4294967295U))) || (reloc_type(rel) == R_X86_64_32S && ((int64_t)value <= (2147483647) && (int64_t )value >= (-2147483647-1)))) ? void (0) : __assert_fail ("(reloc_type(rel) == R_X86_64_32 && (value <= UINT32_MAX)) || (reloc_type(rel) == R_X86_64_32S && ((int64_t)value <= INT32_MAX && (int64_t)value >= INT32_MIN))" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 2756, __extension__ __PRETTY_FUNCTION__)); | |||
2757 | uint32_t truncated_addr = (value & 0xFFFFFFFF); | |||
2758 | DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); | |||
2759 | uint32_t *dst = reinterpret_cast<uint32_t *>( | |||
2760 | data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + | |||
2761 | ELFRelocation::RelocOffset32(rel)); | |||
2762 | *dst = truncated_addr; | |||
2763 | } | |||
2764 | break; | |||
2765 | } | |||
2766 | case R_X86_64_PC32: | |||
2767 | default: | |||
2768 | assert(false && "unexpected relocation type")(static_cast <bool> (false && "unexpected relocation type" ) ? void (0) : __assert_fail ("false && \"unexpected relocation type\"" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 2768, __extension__ __PRETTY_FUNCTION__)); | |||
2769 | } | |||
2770 | } | |||
2771 | } | |||
2772 | ||||
2773 | return 0; | |||
2774 | } | |||
2775 | ||||
2776 | unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr, | |||
2777 | user_id_t rel_id, | |||
2778 | lldb_private::Symtab *thetab) { | |||
2779 | assert(rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL)(static_cast <bool> (rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL) ? void (0) : __assert_fail ( "rel_hdr->sh_type == SHT_RELA || rel_hdr->sh_type == SHT_REL" , "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 2779, __extension__ __PRETTY_FUNCTION__)); | |||
2780 | ||||
2781 | // Parse in the section list if needed. | |||
2782 | SectionList *section_list = GetSectionList(); | |||
2783 | if (!section_list) | |||
2784 | return 0; | |||
2785 | ||||
2786 | // Section ID's are ones based. | |||
2787 | user_id_t symtab_id = rel_hdr->sh_link + 1; | |||
2788 | user_id_t debug_id = rel_hdr->sh_info + 1; | |||
2789 | ||||
2790 | const ELFSectionHeader *symtab_hdr = GetSectionHeaderByIndex(symtab_id); | |||
2791 | if (!symtab_hdr) | |||
2792 | return 0; | |||
2793 | ||||
2794 | const ELFSectionHeader *debug_hdr = GetSectionHeaderByIndex(debug_id); | |||
2795 | if (!debug_hdr) | |||
2796 | return 0; | |||
2797 | ||||
2798 | Section *rel = section_list->FindSectionByID(rel_id).get(); | |||
2799 | if (!rel) | |||
2800 | return 0; | |||
2801 | ||||
2802 | Section *symtab = section_list->FindSectionByID(symtab_id).get(); | |||
2803 | if (!symtab) | |||
2804 | return 0; | |||
2805 | ||||
2806 | Section *debug = section_list->FindSectionByID(debug_id).get(); | |||
2807 | if (!debug) | |||
2808 | return 0; | |||
2809 | ||||
2810 | DataExtractor rel_data; | |||
2811 | DataExtractor symtab_data; | |||
2812 | DataExtractor debug_data; | |||
2813 | ||||
2814 | if (GetData(rel->GetFileOffset(), rel->GetFileSize(), rel_data) && | |||
2815 | GetData(symtab->GetFileOffset(), symtab->GetFileSize(), symtab_data) && | |||
2816 | GetData(debug->GetFileOffset(), debug->GetFileSize(), debug_data)) { | |||
2817 | ApplyRelocations(thetab, &m_header, rel_hdr, symtab_hdr, debug_hdr, | |||
2818 | rel_data, symtab_data, debug_data, debug); | |||
2819 | } | |||
2820 | ||||
2821 | return 0; | |||
2822 | } | |||
2823 | ||||
2824 | Symtab *ObjectFileELF::GetSymtab() { | |||
2825 | ModuleSP module_sp(GetModule()); | |||
2826 | if (!module_sp) | |||
2827 | return NULL__null; | |||
2828 | ||||
2829 | // We always want to use the main object file so we (hopefully) only have one | |||
2830 | // cached copy | |||
2831 | // of our symtab, dynamic sections, etc. | |||
2832 | ObjectFile *module_obj_file = module_sp->GetObjectFile(); | |||
2833 | if (module_obj_file && module_obj_file != this) | |||
2834 | return module_obj_file->GetSymtab(); | |||
2835 | ||||
2836 | if (m_symtab_ap.get() == NULL__null) { | |||
2837 | SectionList *section_list = module_sp->GetSectionList(); | |||
2838 | if (!section_list) | |||
2839 | return NULL__null; | |||
2840 | ||||
2841 | uint64_t symbol_id = 0; | |||
2842 | std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); | |||
2843 | ||||
2844 | // Sharable objects and dynamic executables usually have 2 distinct symbol | |||
2845 | // tables, one named ".symtab", and the other ".dynsym". The dynsym is a | |||
2846 | // smaller | |||
2847 | // version of the symtab that only contains global symbols. The information | |||
2848 | // found | |||
2849 | // in the dynsym is therefore also found in the symtab, while the reverse is | |||
2850 | // not | |||
2851 | // necessarily true. | |||
2852 | Section *symtab = | |||
2853 | section_list->FindSectionByType(eSectionTypeELFSymbolTable, true).get(); | |||
2854 | if (!symtab) { | |||
2855 | // The symtab section is non-allocable and can be stripped, so if it | |||
2856 | // doesn't exist | |||
2857 | // then use the dynsym section which should always be there. | |||
2858 | symtab = | |||
2859 | section_list->FindSectionByType(eSectionTypeELFDynamicSymbols, true) | |||
2860 | .get(); | |||
2861 | } | |||
2862 | if (symtab) { | |||
2863 | m_symtab_ap.reset(new Symtab(symtab->GetObjectFile())); | |||
2864 | symbol_id += ParseSymbolTable(m_symtab_ap.get(), symbol_id, symtab); | |||
2865 | } | |||
2866 | ||||
2867 | // DT_JMPREL | |||
2868 | // If present, this entry's d_ptr member holds the address of | |||
2869 | // relocation | |||
2870 | // entries associated solely with the procedure linkage table. | |||
2871 | // Separating | |||
2872 | // these relocation entries lets the dynamic linker ignore them during | |||
2873 | // process initialization, if lazy binding is enabled. If this entry is | |||
2874 | // present, the related entries of types DT_PLTRELSZ and DT_PLTREL must | |||
2875 | // also be present. | |||
2876 | const ELFDynamic *symbol = FindDynamicSymbol(DT_JMPREL); | |||
2877 | if (symbol) { | |||
2878 | // Synthesize trampoline symbols to help navigate the PLT. | |||
2879 | addr_t addr = symbol->d_ptr; | |||
2880 | Section *reloc_section = | |||
2881 | section_list->FindSectionContainingFileAddress(addr).get(); | |||
2882 | if (reloc_section) { | |||
2883 | user_id_t reloc_id = reloc_section->GetID(); | |||
2884 | const ELFSectionHeaderInfo *reloc_header = | |||
2885 | GetSectionHeaderByIndex(reloc_id); | |||
2886 | assert(reloc_header)(static_cast <bool> (reloc_header) ? void (0) : __assert_fail ("reloc_header", "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , 2886, __extension__ __PRETTY_FUNCTION__)); | |||
2887 | ||||
2888 | if (m_symtab_ap == nullptr) | |||
2889 | m_symtab_ap.reset(new Symtab(reloc_section->GetObjectFile())); | |||
2890 | ||||
2891 | ParseTrampolineSymbols(m_symtab_ap.get(), symbol_id, reloc_header, | |||
2892 | reloc_id); | |||
2893 | } | |||
2894 | } | |||
2895 | ||||
2896 | DWARFCallFrameInfo *eh_frame = GetUnwindTable().GetEHFrameInfo(); | |||
2897 | if (eh_frame) { | |||
2898 | if (m_symtab_ap == nullptr) | |||
2899 | m_symtab_ap.reset(new Symtab(this)); | |||
2900 | ParseUnwindSymbols(m_symtab_ap.get(), eh_frame); | |||
2901 | } | |||
2902 | ||||
2903 | // If we still don't have any symtab then create an empty instance to avoid | |||
2904 | // do the section | |||
2905 | // lookup next time. | |||
2906 | if (m_symtab_ap == nullptr) | |||
2907 | m_symtab_ap.reset(new Symtab(this)); | |||
2908 | ||||
2909 | m_symtab_ap->CalculateSymbolSizes(); | |||
2910 | } | |||
2911 | ||||
2912 | return m_symtab_ap.get(); | |||
2913 | } | |||
2914 | ||||
2915 | void ObjectFileELF::RelocateSection(lldb_private::Section *section) | |||
2916 | { | |||
2917 | static const char *debug_prefix = ".debug"; | |||
2918 | ||||
2919 | // Set relocated bit so we stop getting called, regardless of | |||
2920 | // whether we actually relocate. | |||
2921 | section->SetIsRelocated(true); | |||
2922 | ||||
2923 | // We only relocate in ELF relocatable files | |||
2924 | if (CalculateType() != eTypeObjectFile) | |||
2925 | return; | |||
2926 | ||||
2927 | const char *section_name = section->GetName().GetCString(); | |||
2928 | // Can't relocate that which can't be named | |||
2929 | if (section_name == nullptr) | |||
2930 | return; | |||
2931 | ||||
2932 | // We don't relocate non-debug sections at the moment | |||
2933 | if (strncmp(section_name, debug_prefix, strlen(debug_prefix))) | |||
2934 | return; | |||
2935 | ||||
2936 | // Relocation section names to look for | |||
2937 | std::string needle = std::string(".rel") + section_name; | |||
2938 | std::string needlea = std::string(".rela") + section_name; | |||
2939 | ||||
2940 | for (SectionHeaderCollIter I = m_section_headers.begin(); | |||
2941 | I != m_section_headers.end(); ++I) { | |||
2942 | if (I->sh_type == SHT_RELA || I->sh_type == SHT_REL) { | |||
2943 | const char *hay_name = I->section_name.GetCString(); | |||
2944 | if (hay_name == nullptr) | |||
2945 | continue; | |||
2946 | if (needle == hay_name || needlea == hay_name) { | |||
2947 | const ELFSectionHeader &reloc_header = *I; | |||
2948 | user_id_t reloc_id = SectionIndex(I); | |||
2949 | RelocateDebugSections(&reloc_header, reloc_id, GetSymtab()); | |||
2950 | break; | |||
2951 | } | |||
2952 | } | |||
2953 | } | |||
2954 | } | |||
2955 | ||||
2956 | void ObjectFileELF::ParseUnwindSymbols(Symtab *symbol_table, | |||
2957 | DWARFCallFrameInfo *eh_frame) { | |||
2958 | SectionList *section_list = GetSectionList(); | |||
2959 | if (!section_list) | |||
2960 | return; | |||
2961 | ||||
2962 | // First we save the new symbols into a separate list and add them to the | |||
2963 | // symbol table after | |||
2964 | // we colleced all symbols we want to add. This is neccessary because adding a | |||
2965 | // new symbol | |||
2966 | // invalidates the internal index of the symtab what causing the next lookup | |||
2967 | // to be slow because | |||
2968 | // it have to recalculate the index first. | |||
2969 | std::vector<Symbol> new_symbols; | |||
2970 | ||||
2971 | eh_frame->ForEachFDEEntries([this, symbol_table, section_list, &new_symbols]( | |||
2972 | lldb::addr_t file_addr, uint32_t size, dw_offset_t) { | |||
2973 | Symbol *symbol = symbol_table->FindSymbolAtFileAddress(file_addr); | |||
2974 | if (symbol) { | |||
2975 | if (!symbol->GetByteSizeIsValid()) { | |||
2976 | symbol->SetByteSize(size); | |||
2977 | symbol->SetSizeIsSynthesized(true); | |||
2978 | } | |||
2979 | } else { | |||
2980 | SectionSP section_sp = | |||
2981 | section_list->FindSectionContainingFileAddress(file_addr); | |||
2982 | if (section_sp) { | |||
2983 | addr_t offset = file_addr - section_sp->GetFileAddress(); | |||
2984 | const char *symbol_name = GetNextSyntheticSymbolName().GetCString(); | |||
2985 | uint64_t symbol_id = symbol_table->GetNumSymbols(); | |||
2986 | Symbol eh_symbol( | |||
2987 | symbol_id, // Symbol table index. | |||
2988 | symbol_name, // Symbol name. | |||
2989 | false, // Is the symbol name mangled? | |||
2990 | eSymbolTypeCode, // Type of this symbol. | |||
2991 | true, // Is this globally visible? | |||
2992 | false, // Is this symbol debug info? | |||
2993 | false, // Is this symbol a trampoline? | |||
2994 | true, // Is this symbol artificial? | |||
2995 | section_sp, // Section in which this symbol is defined or null. | |||
2996 | offset, // Offset in section or symbol value. | |||
2997 | 0, // Size: Don't specify the size as an FDE can | |||
2998 | false, // Size is valid: cover multiple symbols. | |||
2999 | false, // Contains linker annotations? | |||
3000 | 0); // Symbol flags. | |||
3001 | new_symbols.push_back(eh_symbol); | |||
3002 | } | |||
3003 | } | |||
3004 | return true; | |||
3005 | }); | |||
3006 | ||||
3007 | for (const Symbol &s : new_symbols) | |||
3008 | symbol_table->AddSymbol(s); | |||
3009 | } | |||
3010 | ||||
3011 | bool ObjectFileELF::IsStripped() { | |||
3012 | // TODO: determine this for ELF | |||
3013 | return false; | |||
3014 | } | |||
3015 | ||||
3016 | //===----------------------------------------------------------------------===// | |||
3017 | // Dump | |||
3018 | // | |||
3019 | // Dump the specifics of the runtime file container (such as any headers | |||
3020 | // segments, sections, etc). | |||
3021 | //---------------------------------------------------------------------- | |||
3022 | void ObjectFileELF::Dump(Stream *s) { | |||
3023 | ModuleSP module_sp(GetModule()); | |||
3024 | if (!module_sp) { | |||
3025 | return; | |||
3026 | } | |||
3027 | ||||
3028 | std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex()); | |||
3029 | s->Printf("%p: ", static_cast<void *>(this)); | |||
3030 | s->Indent(); | |||
3031 | s->PutCString("ObjectFileELF"); | |||
3032 | ||||
3033 | ArchSpec header_arch; | |||
3034 | GetArchitecture(header_arch); | |||
3035 | ||||
3036 | *s << ", file = '" << m_file | |||
3037 | << "', arch = " << header_arch.GetArchitectureName() << "\n"; | |||
3038 | ||||
3039 | DumpELFHeader(s, m_header); | |||
3040 | s->EOL(); | |||
3041 | DumpELFProgramHeaders(s); | |||
3042 | s->EOL(); | |||
3043 | DumpELFSectionHeaders(s); | |||
3044 | s->EOL(); | |||
3045 | SectionList *section_list = GetSectionList(); | |||
3046 | if (section_list) | |||
3047 | section_list->Dump(s, NULL__null, true, UINT32_MAX(4294967295U)); | |||
3048 | Symtab *symtab = GetSymtab(); | |||
3049 | if (symtab) | |||
3050 | symtab->Dump(s, NULL__null, eSortOrderNone); | |||
3051 | s->EOL(); | |||
3052 | DumpDependentModules(s); | |||
3053 | s->EOL(); | |||
3054 | } | |||
3055 | ||||
3056 | //---------------------------------------------------------------------- | |||
3057 | // DumpELFHeader | |||
3058 | // | |||
3059 | // Dump the ELF header to the specified output stream | |||
3060 | //---------------------------------------------------------------------- | |||
3061 | void ObjectFileELF::DumpELFHeader(Stream *s, const ELFHeader &header) { | |||
3062 | s->PutCString("ELF Header\n"); | |||
3063 | s->Printf("e_ident[EI_MAG0 ] = 0x%2.2x\n", header.e_ident[EI_MAG0]); | |||
3064 | s->Printf("e_ident[EI_MAG1 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG1], | |||
3065 | header.e_ident[EI_MAG1]); | |||
3066 | s->Printf("e_ident[EI_MAG2 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG2], | |||
3067 | header.e_ident[EI_MAG2]); | |||
3068 | s->Printf("e_ident[EI_MAG3 ] = 0x%2.2x '%c'\n", header.e_ident[EI_MAG3], | |||
3069 | header.e_ident[EI_MAG3]); | |||
3070 | ||||
3071 | s->Printf("e_ident[EI_CLASS ] = 0x%2.2x\n", header.e_ident[EI_CLASS]); | |||
3072 | s->Printf("e_ident[EI_DATA ] = 0x%2.2x ", header.e_ident[EI_DATA]); | |||
3073 | DumpELFHeader_e_ident_EI_DATA(s, header.e_ident[EI_DATA]); | |||
3074 | s->Printf("\ne_ident[EI_VERSION] = 0x%2.2x\n", header.e_ident[EI_VERSION]); | |||
3075 | s->Printf("e_ident[EI_PAD ] = 0x%2.2x\n", header.e_ident[EI_PAD]); | |||
3076 | ||||
3077 | s->Printf("e_type = 0x%4.4x ", header.e_type); | |||
3078 | DumpELFHeader_e_type(s, header.e_type); | |||
3079 | s->Printf("\ne_machine = 0x%4.4x\n", header.e_machine); | |||
3080 | s->Printf("e_version = 0x%8.8x\n", header.e_version); | |||
3081 | s->Printf("e_entry = 0x%8.8" PRIx64"l" "x" "\n", header.e_entry); | |||
3082 | s->Printf("e_phoff = 0x%8.8" PRIx64"l" "x" "\n", header.e_phoff); | |||
3083 | s->Printf("e_shoff = 0x%8.8" PRIx64"l" "x" "\n", header.e_shoff); | |||
3084 | s->Printf("e_flags = 0x%8.8x\n", header.e_flags); | |||
3085 | s->Printf("e_ehsize = 0x%4.4x\n", header.e_ehsize); | |||
3086 | s->Printf("e_phentsize = 0x%4.4x\n", header.e_phentsize); | |||
3087 | s->Printf("e_phnum = 0x%8.8x\n", header.e_phnum); | |||
3088 | s->Printf("e_shentsize = 0x%4.4x\n", header.e_shentsize); | |||
3089 | s->Printf("e_shnum = 0x%8.8x\n", header.e_shnum); | |||
3090 | s->Printf("e_shstrndx = 0x%8.8x\n", header.e_shstrndx); | |||
3091 | } | |||
3092 | ||||
3093 | //---------------------------------------------------------------------- | |||
3094 | // DumpELFHeader_e_type | |||
3095 | // | |||
3096 | // Dump an token value for the ELF header member e_type | |||
3097 | //---------------------------------------------------------------------- | |||
3098 | void ObjectFileELF::DumpELFHeader_e_type(Stream *s, elf_half e_type) { | |||
3099 | switch (e_type) { | |||
3100 | case ET_NONE: | |||
3101 | *s << "ET_NONE"; | |||
3102 | break; | |||
3103 | case ET_REL: | |||
3104 | *s << "ET_REL"; | |||
3105 | break; | |||
3106 | case ET_EXEC: | |||
3107 | *s << "ET_EXEC"; | |||
3108 | break; | |||
3109 | case ET_DYN: | |||
3110 | *s << "ET_DYN"; | |||
3111 | break; | |||
3112 | case ET_CORE: | |||
3113 | *s << "ET_CORE"; | |||
3114 | break; | |||
3115 | default: | |||
3116 | break; | |||
3117 | } | |||
3118 | } | |||
3119 | ||||
3120 | //---------------------------------------------------------------------- | |||
3121 | // DumpELFHeader_e_ident_EI_DATA | |||
3122 | // | |||
3123 | // Dump an token value for the ELF header member e_ident[EI_DATA] | |||
3124 | //---------------------------------------------------------------------- | |||
3125 | void ObjectFileELF::DumpELFHeader_e_ident_EI_DATA(Stream *s, | |||
3126 | unsigned char ei_data) { | |||
3127 | switch (ei_data) { | |||
3128 | case ELFDATANONE: | |||
3129 | *s << "ELFDATANONE"; | |||
3130 | break; | |||
3131 | case ELFDATA2LSB: | |||
3132 | *s << "ELFDATA2LSB - Little Endian"; | |||
3133 | break; | |||
3134 | case ELFDATA2MSB: | |||
3135 | *s << "ELFDATA2MSB - Big Endian"; | |||
3136 | break; | |||
3137 | default: | |||
3138 | break; | |||
3139 | } | |||
3140 | } | |||
3141 | ||||
3142 | //---------------------------------------------------------------------- | |||
3143 | // DumpELFProgramHeader | |||
3144 | // | |||
3145 | // Dump a single ELF program header to the specified output stream | |||
3146 | //---------------------------------------------------------------------- | |||
3147 | void ObjectFileELF::DumpELFProgramHeader(Stream *s, | |||
3148 | const ELFProgramHeader &ph) { | |||
3149 | DumpELFProgramHeader_p_type(s, ph.p_type); | |||
3150 | s->Printf(" %8.8" PRIx64"l" "x" " %8.8" PRIx64"l" "x" " %8.8" PRIx64"l" "x", ph.p_offset, | |||
3151 | ph.p_vaddr, ph.p_paddr); | |||
3152 | s->Printf(" %8.8" PRIx64"l" "x" " %8.8" PRIx64"l" "x" " %8.8x (", ph.p_filesz, ph.p_memsz, | |||
3153 | ph.p_flags); | |||
3154 | ||||
3155 | DumpELFProgramHeader_p_flags(s, ph.p_flags); | |||
3156 | s->Printf(") %8.8" PRIx64"l" "x", ph.p_align); | |||
3157 | } | |||
3158 | ||||
3159 | //---------------------------------------------------------------------- | |||
3160 | // DumpELFProgramHeader_p_type | |||
3161 | // | |||
3162 | // Dump an token value for the ELF program header member p_type which | |||
3163 | // describes the type of the program header | |||
3164 | // ---------------------------------------------------------------------- | |||
3165 | void ObjectFileELF::DumpELFProgramHeader_p_type(Stream *s, elf_word p_type) { | |||
3166 | const int kStrWidth = 15; | |||
3167 | switch (p_type) { | |||
3168 | CASE_AND_STREAM(s, PT_NULL, kStrWidth)case PT_NULL: s->Printf("%-*s", kStrWidth, "PT_NULL"); break ;; | |||
3169 | CASE_AND_STREAM(s, PT_LOAD, kStrWidth)case PT_LOAD: s->Printf("%-*s", kStrWidth, "PT_LOAD"); break ;; | |||
3170 | CASE_AND_STREAM(s, PT_DYNAMIC, kStrWidth)case PT_DYNAMIC: s->Printf("%-*s", kStrWidth, "PT_DYNAMIC" ); break;; | |||
3171 | CASE_AND_STREAM(s, PT_INTERP, kStrWidth)case PT_INTERP: s->Printf("%-*s", kStrWidth, "PT_INTERP"); break;; | |||
3172 | CASE_AND_STREAM(s, PT_NOTE, kStrWidth)case PT_NOTE: s->Printf("%-*s", kStrWidth, "PT_NOTE"); break ;; | |||
3173 | CASE_AND_STREAM(s, PT_SHLIB, kStrWidth)case PT_SHLIB: s->Printf("%-*s", kStrWidth, "PT_SHLIB"); break ;; | |||
3174 | CASE_AND_STREAM(s, PT_PHDR, kStrWidth)case PT_PHDR: s->Printf("%-*s", kStrWidth, "PT_PHDR"); break ;; | |||
3175 | CASE_AND_STREAM(s, PT_TLS, kStrWidth)case PT_TLS: s->Printf("%-*s", kStrWidth, "PT_TLS"); break ;; | |||
3176 | CASE_AND_STREAM(s, PT_GNU_EH_FRAME, kStrWidth)case PT_GNU_EH_FRAME: s->Printf("%-*s", kStrWidth, "PT_GNU_EH_FRAME" ); break;; | |||
3177 | default: | |||
3178 | s->Printf("0x%8.8x%*s", p_type, kStrWidth - 10, ""); | |||
3179 | break; | |||
3180 | } | |||
3181 | } | |||
3182 | ||||
3183 | //---------------------------------------------------------------------- | |||
3184 | // DumpELFProgramHeader_p_flags | |||
3185 | // | |||
3186 | // Dump an token value for the ELF program header member p_flags | |||
3187 | //---------------------------------------------------------------------- | |||
3188 | void ObjectFileELF::DumpELFProgramHeader_p_flags(Stream *s, elf_word p_flags) { | |||
3189 | *s << ((p_flags & PF_X) ? "PF_X" : " ") | |||
3190 | << (((p_flags & PF_X) && (p_flags & PF_W)) ? '+' : ' ') | |||
3191 | << ((p_flags & PF_W) ? "PF_W" : " ") | |||
3192 | << (((p_flags & PF_W) && (p_flags & PF_R)) ? '+' : ' ') | |||
3193 | << ((p_flags & PF_R) ? "PF_R" : " "); | |||
3194 | } | |||
3195 | ||||
3196 | //---------------------------------------------------------------------- | |||
3197 | // DumpELFProgramHeaders | |||
3198 | // | |||
3199 | // Dump all of the ELF program header to the specified output stream | |||
3200 | //---------------------------------------------------------------------- | |||
3201 | void ObjectFileELF::DumpELFProgramHeaders(Stream *s) { | |||
3202 | if (!ParseProgramHeaders()) | |||
3203 | return; | |||
3204 | ||||
3205 | s->PutCString("Program Headers\n"); | |||
3206 | s->PutCString("IDX p_type p_offset p_vaddr p_paddr " | |||
3207 | "p_filesz p_memsz p_flags p_align\n"); | |||
3208 | s->PutCString("==== --------------- -------- -------- -------- " | |||
3209 | "-------- -------- ------------------------- --------\n"); | |||
3210 | ||||
3211 | uint32_t idx = 0; | |||
3212 | for (ProgramHeaderCollConstIter I = m_program_headers.begin(); | |||
3213 | I != m_program_headers.end(); ++I, ++idx) { | |||
3214 | s->Printf("[%2u] ", idx); | |||
3215 | ObjectFileELF::DumpELFProgramHeader(s, *I); | |||
3216 | s->EOL(); | |||
3217 | } | |||
3218 | } | |||
3219 | ||||
3220 | //---------------------------------------------------------------------- | |||
3221 | // DumpELFSectionHeader | |||
3222 | // | |||
3223 | // Dump a single ELF section header to the specified output stream | |||
3224 | //---------------------------------------------------------------------- | |||
3225 | void ObjectFileELF::DumpELFSectionHeader(Stream *s, | |||
3226 | const ELFSectionHeaderInfo &sh) { | |||
3227 | s->Printf("%8.8x ", sh.sh_name); | |||
3228 | DumpELFSectionHeader_sh_type(s, sh.sh_type); | |||
3229 | s->Printf(" %8.8" PRIx64"l" "x" " (", sh.sh_flags); | |||
3230 | DumpELFSectionHeader_sh_flags(s, sh.sh_flags); | |||
3231 | s->Printf(") %8.8" PRIx64"l" "x" " %8.8" PRIx64"l" "x" " %8.8" PRIx64"l" "x", sh.sh_addr, | |||
3232 | sh.sh_offset, sh.sh_size); | |||
3233 | s->Printf(" %8.8x %8.8x", sh.sh_link, sh.sh_info); | |||
3234 | s->Printf(" %8.8" PRIx64"l" "x" " %8.8" PRIx64"l" "x", sh.sh_addralign, sh.sh_entsize); | |||
3235 | } | |||
3236 | ||||
3237 | //---------------------------------------------------------------------- | |||
3238 | // DumpELFSectionHeader_sh_type | |||
3239 | // | |||
3240 | // Dump an token value for the ELF section header member sh_type which | |||
3241 | // describes the type of the section | |||
3242 | //---------------------------------------------------------------------- | |||
3243 | void ObjectFileELF::DumpELFSectionHeader_sh_type(Stream *s, elf_word sh_type) { | |||
3244 | const int kStrWidth = 12; | |||
3245 | switch (sh_type) { | |||
3246 | CASE_AND_STREAM(s, SHT_NULL, kStrWidth)case SHT_NULL: s->Printf("%-*s", kStrWidth, "SHT_NULL"); break ;; | |||
3247 | CASE_AND_STREAM(s, SHT_PROGBITS, kStrWidth)case SHT_PROGBITS: s->Printf("%-*s", kStrWidth, "SHT_PROGBITS" ); break;; | |||
3248 | CASE_AND_STREAM(s, SHT_SYMTAB, kStrWidth)case SHT_SYMTAB: s->Printf("%-*s", kStrWidth, "SHT_SYMTAB" ); break;; | |||
3249 | CASE_AND_STREAM(s, SHT_STRTAB, kStrWidth)case SHT_STRTAB: s->Printf("%-*s", kStrWidth, "SHT_STRTAB" ); break;; | |||
3250 | CASE_AND_STREAM(s, SHT_RELA, kStrWidth)case SHT_RELA: s->Printf("%-*s", kStrWidth, "SHT_RELA"); break ;; | |||
3251 | CASE_AND_STREAM(s, SHT_HASH, kStrWidth)case SHT_HASH: s->Printf("%-*s", kStrWidth, "SHT_HASH"); break ;; | |||
3252 | CASE_AND_STREAM(s, SHT_DYNAMIC, kStrWidth)case SHT_DYNAMIC: s->Printf("%-*s", kStrWidth, "SHT_DYNAMIC" ); break;; | |||
3253 | CASE_AND_STREAM(s, SHT_NOTE, kStrWidth)case SHT_NOTE: s->Printf("%-*s", kStrWidth, "SHT_NOTE"); break ;; | |||
3254 | CASE_AND_STREAM(s, SHT_NOBITS, kStrWidth)case SHT_NOBITS: s->Printf("%-*s", kStrWidth, "SHT_NOBITS" ); break;; | |||
3255 | CASE_AND_STREAM(s, SHT_REL, kStrWidth)case SHT_REL: s->Printf("%-*s", kStrWidth, "SHT_REL"); break ;; | |||
3256 | CASE_AND_STREAM(s, SHT_SHLIB, kStrWidth)case SHT_SHLIB: s->Printf("%-*s", kStrWidth, "SHT_SHLIB"); break;; | |||
3257 | CASE_AND_STREAM(s, SHT_DYNSYM, kStrWidth)case SHT_DYNSYM: s->Printf("%-*s", kStrWidth, "SHT_DYNSYM" ); break;; | |||
3258 | CASE_AND_STREAM(s, SHT_LOPROC, kStrWidth)case SHT_LOPROC: s->Printf("%-*s", kStrWidth, "SHT_LOPROC" ); break;; | |||
3259 | CASE_AND_STREAM(s, SHT_HIPROC, kStrWidth)case SHT_HIPROC: s->Printf("%-*s", kStrWidth, "SHT_HIPROC" ); break;; | |||
3260 | CASE_AND_STREAM(s, SHT_LOUSER, kStrWidth)case SHT_LOUSER: s->Printf("%-*s", kStrWidth, "SHT_LOUSER" ); break;; | |||
3261 | CASE_AND_STREAM(s, SHT_HIUSER, kStrWidth)case SHT_HIUSER: s->Printf("%-*s", kStrWidth, "SHT_HIUSER" ); break;; | |||
3262 | default: | |||
3263 | s->Printf("0x%8.8x%*s", sh_type, kStrWidth - 10, ""); | |||
3264 | break; | |||
3265 | } | |||
3266 | } | |||
3267 | ||||
3268 | //---------------------------------------------------------------------- | |||
3269 | // DumpELFSectionHeader_sh_flags | |||
3270 | // | |||
3271 | // Dump an token value for the ELF section header member sh_flags | |||
3272 | //---------------------------------------------------------------------- | |||
3273 | void ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, | |||
3274 | elf_xword sh_flags) { | |||
3275 | *s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ") | |||
3276 | << (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ') | |||
3277 | << ((sh_flags & SHF_ALLOC) ? "ALLOC" : " ") | |||
3278 | << (((sh_flags & SHF_ALLOC) && (sh_flags & SHF_EXECINSTR)) ? '+' : ' ') | |||
3279 | << ((sh_flags & SHF_EXECINSTR) ? "EXECINSTR" : " "); | |||
3280 | } | |||
3281 | ||||
3282 | //---------------------------------------------------------------------- | |||
3283 | // DumpELFSectionHeaders | |||
3284 | // | |||
3285 | // Dump all of the ELF section header to the specified output stream | |||
3286 | //---------------------------------------------------------------------- | |||
3287 | void ObjectFileELF::DumpELFSectionHeaders(Stream *s) { | |||
3288 | if (!ParseSectionHeaders()) | |||
3289 | return; | |||
3290 | ||||
3291 | s->PutCString("Section Headers\n"); | |||
3292 | s->PutCString("IDX name type flags " | |||
3293 | "addr offset size link info addralgn " | |||
3294 | "entsize Name\n"); | |||
3295 | s->PutCString("==== -------- ------------ -------------------------------- " | |||
3296 | "-------- -------- -------- -------- -------- -------- " | |||
3297 | "-------- ====================\n"); | |||
3298 | ||||
3299 | uint32_t idx = 0; | |||
3300 | for (SectionHeaderCollConstIter I = m_section_headers.begin(); | |||
3301 | I != m_section_headers.end(); ++I, ++idx) { | |||
3302 | s->Printf("[%2u] ", idx); | |||
3303 | ObjectFileELF::DumpELFSectionHeader(s, *I); | |||
3304 | const char *section_name = I->section_name.AsCString(""); | |||
3305 | if (section_name) | |||
3306 | *s << ' ' << section_name << "\n"; | |||
3307 | } | |||
3308 | } | |||
3309 | ||||
3310 | void ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) { | |||
3311 | size_t num_modules = ParseDependentModules(); | |||
3312 | ||||
3313 | if (num_modules > 0) { | |||
3314 | s->PutCString("Dependent Modules:\n"); | |||
3315 | for (unsigned i = 0; i < num_modules; ++i) { | |||
3316 | const FileSpec &spec = m_filespec_ap->GetFileSpecAtIndex(i); | |||
3317 | s->Printf(" %s\n", spec.GetFilename().GetCString()); | |||
3318 | } | |||
3319 | } | |||
3320 | } | |||
3321 | ||||
3322 | bool ObjectFileELF::GetArchitecture(ArchSpec &arch) { | |||
3323 | if (!ParseHeader()) | |||
3324 | return false; | |||
3325 | ||||
3326 | if (m_section_headers.empty()) { | |||
3327 | // Allow elf notes to be parsed which may affect the detected architecture. | |||
3328 | ParseSectionHeaders(); | |||
3329 | } | |||
3330 | ||||
3331 | if (CalculateType() == eTypeCoreFile && | |||
3332 | m_arch_spec.TripleOSIsUnspecifiedUnknown()) { | |||
3333 | // Core files don't have section headers yet they have PT_NOTE program | |||
3334 | // headers | |||
3335 | // that might shed more light on the architecture | |||
3336 | if (ParseProgramHeaders()) { | |||
3337 | for (size_t i = 1, count = GetProgramHeaderCount(); i <= count; ++i) { | |||
3338 | const elf::ELFProgramHeader *header = GetProgramHeaderByIndex(i); | |||
3339 | if (header && header->p_type == PT_NOTE && header->p_offset != 0 && | |||
3340 | header->p_filesz > 0) { | |||
3341 | DataExtractor data; | |||
3342 | if (data.SetData(m_data, header->p_offset, header->p_filesz) == | |||
3343 | header->p_filesz) { | |||
3344 | lldb_private::UUID uuid; | |||
3345 | RefineModuleDetailsFromNote(data, m_arch_spec, uuid); | |||
3346 | } | |||
3347 | } | |||
3348 | } | |||
3349 | } | |||
3350 | } | |||
3351 | arch = m_arch_spec; | |||
3352 | return true; | |||
3353 | } | |||
3354 | ||||
3355 | ObjectFile::Type ObjectFileELF::CalculateType() { | |||
3356 | switch (m_header.e_type) { | |||
3357 | case llvm::ELF::ET_NONE: | |||
3358 | // 0 - No file type | |||
3359 | return eTypeUnknown; | |||
3360 | ||||
3361 | case llvm::ELF::ET_REL: | |||
3362 | // 1 - Relocatable file | |||
3363 | return eTypeObjectFile; | |||
3364 | ||||
3365 | case llvm::ELF::ET_EXEC: | |||
3366 | // 2 - Executable file | |||
3367 | return eTypeExecutable; | |||
3368 | ||||
3369 | case llvm::ELF::ET_DYN: | |||
3370 | // 3 - Shared object file | |||
3371 | return eTypeSharedLibrary; | |||
3372 | ||||
3373 | case ET_CORE: | |||
3374 | // 4 - Core file | |||
3375 | return eTypeCoreFile; | |||
3376 | ||||
3377 | default: | |||
3378 | break; | |||
3379 | } | |||
3380 | return eTypeUnknown; | |||
3381 | } | |||
3382 | ||||
3383 | ObjectFile::Strata ObjectFileELF::CalculateStrata() { | |||
3384 | switch (m_header.e_type) { | |||
3385 | case llvm::ELF::ET_NONE: | |||
3386 | // 0 - No file type | |||
3387 | return eStrataUnknown; | |||
3388 | ||||
3389 | case llvm::ELF::ET_REL: | |||
3390 | // 1 - Relocatable file | |||
3391 | return eStrataUnknown; | |||
3392 | ||||
3393 | case llvm::ELF::ET_EXEC: | |||
3394 | // 2 - Executable file | |||
3395 | // TODO: is there any way to detect that an executable is a kernel | |||
3396 | // related executable by inspecting the program headers, section | |||
3397 | // headers, symbols, or any other flag bits??? | |||
3398 | return eStrataUser; | |||
3399 | ||||
3400 | case llvm::ELF::ET_DYN: | |||
3401 | // 3 - Shared object file | |||
3402 | // TODO: is there any way to detect that an shared library is a kernel | |||
3403 | // related executable by inspecting the program headers, section | |||
3404 | // headers, symbols, or any other flag bits??? | |||
3405 | return eStrataUnknown; | |||
3406 | ||||
3407 | case ET_CORE: | |||
3408 | // 4 - Core file | |||
3409 | // TODO: is there any way to detect that an core file is a kernel | |||
3410 | // related executable by inspecting the program headers, section | |||
3411 | // headers, symbols, or any other flag bits??? | |||
3412 | return eStrataUnknown; | |||
3413 | ||||
3414 | default: | |||
3415 | break; | |||
3416 | } | |||
3417 | return eStrataUnknown; | |||
3418 | } | |||
3419 | ||||
3420 | size_t ObjectFileELF::ReadSectionData(Section *section, | |||
3421 | lldb::offset_t section_offset, void *dst, | |||
3422 | size_t dst_len) { | |||
3423 | // If some other objectfile owns this data, pass this to them. | |||
3424 | if (section->GetObjectFile() != this) | |||
3425 | return section->GetObjectFile()->ReadSectionData(section, section_offset, | |||
3426 | dst, dst_len); | |||
3427 | ||||
3428 | if (!section->Test(SHF_COMPRESSED)) | |||
3429 | return ObjectFile::ReadSectionData(section, section_offset, dst, dst_len); | |||
3430 | ||||
3431 | // For compressed sections we need to read to full data to be able to | |||
3432 | // decompress. | |||
3433 | DataExtractor data; | |||
3434 | ReadSectionData(section, data); | |||
3435 | return data.CopyData(section_offset, dst_len, dst); | |||
3436 | } | |||
3437 | ||||
3438 | size_t ObjectFileELF::ReadSectionData(Section *section, | |||
3439 | DataExtractor §ion_data) { | |||
3440 | // If some other objectfile owns this data, pass this to them. | |||
3441 | if (section->GetObjectFile() != this) | |||
3442 | return section->GetObjectFile()->ReadSectionData(section, section_data); | |||
3443 | ||||
3444 | Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES(1u << 21)); | |||
3445 | ||||
3446 | size_t result = ObjectFile::ReadSectionData(section, section_data); | |||
3447 | if (result == 0 || !section->Test(SHF_COMPRESSED)) | |||
3448 | return result; | |||
3449 | ||||
3450 | auto Decompressor = llvm::object::Decompressor::create( | |||
3451 | section->GetName().GetStringRef(), | |||
3452 | {reinterpret_cast<const char *>(section_data.GetDataStart()), | |||
3453 | size_t(section_data.GetByteSize())}, | |||
3454 | GetByteOrder() == eByteOrderLittle, GetAddressByteSize() == 8); | |||
3455 | if (!Decompressor) { | |||
3456 | LLDB_LOG_ERROR(log, Decompressor.takeError(),do { ::lldb_private::Log *log_private = (log); ::llvm::Error error_private = (Decompressor.takeError()); if (log_private && error_private ) { log_private->FormatError(::std::move(error_private), "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , __func__, "Unable to initialize decompressor for section {0}" , section->GetName()); } else ::llvm::consumeError(::std:: move(error_private)); } while (0) | |||
3457 | "Unable to initialize decompressor for section {0}",do { ::lldb_private::Log *log_private = (log); ::llvm::Error error_private = (Decompressor.takeError()); if (log_private && error_private ) { log_private->FormatError(::std::move(error_private), "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , __func__, "Unable to initialize decompressor for section {0}" , section->GetName()); } else ::llvm::consumeError(::std:: move(error_private)); } while (0) | |||
3458 | section->GetName())do { ::lldb_private::Log *log_private = (log); ::llvm::Error error_private = (Decompressor.takeError()); if (log_private && error_private ) { log_private->FormatError(::std::move(error_private), "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , __func__, "Unable to initialize decompressor for section {0}" , section->GetName()); } else ::llvm::consumeError(::std:: move(error_private)); } while (0); | |||
3459 | return result; | |||
3460 | } | |||
3461 | auto buffer_sp = | |||
3462 | std::make_shared<DataBufferHeap>(Decompressor->getDecompressedSize(), 0); | |||
3463 | if (auto Error = Decompressor->decompress( | |||
3464 | {reinterpret_cast<char *>(buffer_sp->GetBytes()), | |||
3465 | size_t(buffer_sp->GetByteSize())})) { | |||
3466 | LLDB_LOG_ERROR(log, std::move(Error), "Decompression of section {0} failed",do { ::lldb_private::Log *log_private = (log); ::llvm::Error error_private = (std::move(Error)); if (log_private && error_private ) { log_private->FormatError(::std::move(error_private), "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , __func__, "Decompression of section {0} failed", section-> GetName()); } else ::llvm::consumeError(::std::move(error_private )); } while (0) | |||
3467 | section->GetName())do { ::lldb_private::Log *log_private = (log); ::llvm::Error error_private = (std::move(Error)); if (log_private && error_private ) { log_private->FormatError(::std::move(error_private), "/build/llvm-toolchain-snapshot-7~svn326246/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp" , __func__, "Decompression of section {0} failed", section-> GetName()); } else ::llvm::consumeError(::std::move(error_private )); } while (0); | |||
3468 | return result; | |||
3469 | } | |||
3470 | section_data.SetData(buffer_sp); | |||
3471 | return buffer_sp->GetByteSize(); | |||
3472 | } |