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