xref: /freebsd/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- ObjectFile.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 "lldb/Symbol/ObjectFile.h"
10 #include "lldb/Core/Module.h"
11 #include "lldb/Core/ModuleSpec.h"
12 #include "lldb/Core/PluginManager.h"
13 #include "lldb/Core/Section.h"
14 #include "lldb/Symbol/CallFrameInfo.h"
15 #include "lldb/Symbol/ObjectContainer.h"
16 #include "lldb/Symbol/SymbolFile.h"
17 #include "lldb/Target/Process.h"
18 #include "lldb/Target/SectionLoadList.h"
19 #include "lldb/Target/Target.h"
20 #include "lldb/Utility/DataBuffer.h"
21 #include "lldb/Utility/DataBufferHeap.h"
22 #include "lldb/Utility/LLDBLog.h"
23 #include "lldb/Utility/Log.h"
24 #include "lldb/Utility/Timer.h"
25 #include "lldb/lldb-private.h"
26 
27 #include "llvm/Support/DJB.h"
28 
29 using namespace lldb;
30 using namespace lldb_private;
31 
32 char ObjectFile::ID;
33 size_t ObjectFile::g_initial_bytes_to_read = 512;
34 
35 static ObjectFileSP
CreateObjectFromContainer(const lldb::ModuleSP & module_sp,const FileSpec * file,lldb::offset_t file_offset,lldb::offset_t file_size,DataBufferSP data_sp,lldb::offset_t & data_offset)36 CreateObjectFromContainer(const lldb::ModuleSP &module_sp, const FileSpec *file,
37                           lldb::offset_t file_offset, lldb::offset_t file_size,
38                           DataBufferSP data_sp, lldb::offset_t &data_offset) {
39   ObjectContainerCreateInstance callback;
40   for (uint32_t idx = 0;
41        (callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(
42             idx)) != nullptr;
43        ++idx) {
44     std::unique_ptr<ObjectContainer> object_container_up(callback(
45         module_sp, data_sp, data_offset, file, file_offset, file_size));
46     if (object_container_up)
47       return object_container_up->GetObjectFile(file);
48   }
49   return {};
50 }
51 
52 ObjectFileSP
FindPlugin(const lldb::ModuleSP & module_sp,const FileSpec * file,lldb::offset_t file_offset,lldb::offset_t file_size,DataBufferSP & data_sp,lldb::offset_t & data_offset)53 ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
54                        lldb::offset_t file_offset, lldb::offset_t file_size,
55                        DataBufferSP &data_sp, lldb::offset_t &data_offset) {
56   LLDB_SCOPED_TIMERF(
57       "ObjectFile::FindPlugin (module = %s, file = %p, file_offset = "
58       "0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
59       module_sp->GetFileSpec().GetPath().c_str(),
60       static_cast<const void *>(file), static_cast<uint64_t>(file_offset),
61       static_cast<uint64_t>(file_size));
62 
63   if (!module_sp)
64     return {};
65 
66   if (!file)
67     return {};
68 
69   if (!data_sp) {
70     const bool file_exists = FileSystem::Instance().Exists(*file);
71     // We have an object name which most likely means we have a .o file in
72     // a static archive (.a file). Try and see if we have a cached archive
73     // first without reading any data first
74     if (file_exists && module_sp->GetObjectName()) {
75       ObjectFileSP object_file_sp = CreateObjectFromContainer(
76           module_sp, file, file_offset, file_size, data_sp, data_offset);
77       if (object_file_sp)
78         return object_file_sp;
79     }
80     // Ok, we didn't find any containers that have a named object, now lets
81     // read the first 512 bytes from the file so the object file and object
82     // container plug-ins can use these bytes to see if they can parse this
83     // file.
84     if (file_size > 0) {
85       data_sp = FileSystem::Instance().CreateDataBuffer(
86           file->GetPath(), g_initial_bytes_to_read, file_offset);
87       data_offset = 0;
88     }
89   }
90 
91   if (!data_sp || data_sp->GetByteSize() == 0) {
92     // Check for archive file with format "/path/to/archive.a(object.o)"
93     llvm::SmallString<256> path_with_object;
94     module_sp->GetFileSpec().GetPath(path_with_object);
95 
96     FileSpec archive_file;
97     ConstString archive_object;
98     const bool must_exist = true;
99     if (ObjectFile::SplitArchivePathWithObject(path_with_object, archive_file,
100                                                archive_object, must_exist)) {
101       file_size = FileSystem::Instance().GetByteSize(archive_file);
102       if (file_size > 0) {
103         file = &archive_file;
104         module_sp->SetFileSpecAndObjectName(archive_file, archive_object);
105         // Check if this is a object container by iterating through all
106         // object container plugin instances and then trying to get an
107         // object file from the container plugins since we had a name.
108         // Also, don't read
109         // ANY data in case there is data cached in the container plug-ins
110         // (like BSD archives caching the contained objects within an
111         // file).
112         ObjectFileSP object_file_sp = CreateObjectFromContainer(
113             module_sp, file, file_offset, file_size, data_sp, data_offset);
114         if (object_file_sp)
115           return object_file_sp;
116         // We failed to find any cached object files in the container plug-
117         // ins, so lets read the first 512 bytes and try again below...
118         data_sp = FileSystem::Instance().CreateDataBuffer(
119             archive_file.GetPath(), g_initial_bytes_to_read, file_offset);
120       }
121     }
122   }
123 
124   if (data_sp && data_sp->GetByteSize() > 0) {
125     // Check if this is a normal object file by iterating through all
126     // object file plugin instances.
127     ObjectFileCreateInstance callback;
128     for (uint32_t idx = 0;
129          (callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) !=
130          nullptr;
131          ++idx) {
132       ObjectFileSP object_file_sp(callback(module_sp, data_sp, data_offset,
133                                            file, file_offset, file_size));
134       if (object_file_sp.get())
135         return object_file_sp;
136     }
137 
138     // Check if this is a object container by iterating through all object
139     // container plugin instances and then trying to get an object file
140     // from the container.
141     ObjectFileSP object_file_sp = CreateObjectFromContainer(
142         module_sp, file, file_offset, file_size, data_sp, data_offset);
143     if (object_file_sp)
144       return object_file_sp;
145   }
146 
147   // We didn't find it, so clear our shared pointer in case it contains
148   // anything and return an empty shared pointer
149   return {};
150 }
151 
FindPlugin(const lldb::ModuleSP & module_sp,const ProcessSP & process_sp,lldb::addr_t header_addr,WritableDataBufferSP data_sp)152 ObjectFileSP ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp,
153                                     const ProcessSP &process_sp,
154                                     lldb::addr_t header_addr,
155                                     WritableDataBufferSP data_sp) {
156   ObjectFileSP object_file_sp;
157 
158   if (module_sp) {
159     LLDB_SCOPED_TIMERF("ObjectFile::FindPlugin (module = "
160                        "%s, process = %p, header_addr = "
161                        "0x%" PRIx64 ")",
162                        module_sp->GetFileSpec().GetPath().c_str(),
163                        static_cast<void *>(process_sp.get()), header_addr);
164     uint32_t idx;
165 
166     // Check if this is a normal object file by iterating through all object
167     // file plugin instances.
168     ObjectFileCreateMemoryInstance create_callback;
169     for (idx = 0;
170          (create_callback =
171               PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(idx)) !=
172          nullptr;
173          ++idx) {
174       object_file_sp.reset(
175           create_callback(module_sp, data_sp, process_sp, header_addr));
176       if (object_file_sp.get())
177         return object_file_sp;
178     }
179   }
180 
181   // We didn't find it, so clear our shared pointer in case it contains
182   // anything and return an empty shared pointer
183   object_file_sp.reset();
184   return object_file_sp;
185 }
186 
IsObjectFile(lldb_private::FileSpec file_spec)187 bool ObjectFile::IsObjectFile(lldb_private::FileSpec file_spec) {
188   DataBufferSP data_sp;
189   offset_t data_offset = 0;
190   ModuleSP module_sp = std::make_shared<Module>(file_spec);
191   return static_cast<bool>(ObjectFile::FindPlugin(
192       module_sp, &file_spec, 0, FileSystem::Instance().GetByteSize(file_spec),
193       data_sp, data_offset));
194 }
195 
GetModuleSpecifications(const FileSpec & file,lldb::offset_t file_offset,lldb::offset_t file_size,ModuleSpecList & specs,DataBufferSP data_sp)196 size_t ObjectFile::GetModuleSpecifications(const FileSpec &file,
197                                            lldb::offset_t file_offset,
198                                            lldb::offset_t file_size,
199                                            ModuleSpecList &specs,
200                                            DataBufferSP data_sp) {
201   if (!data_sp)
202     data_sp = FileSystem::Instance().CreateDataBuffer(
203         file.GetPath(), g_initial_bytes_to_read, file_offset);
204   if (data_sp) {
205     if (file_size == 0) {
206       const lldb::offset_t actual_file_size =
207           FileSystem::Instance().GetByteSize(file);
208       if (actual_file_size > file_offset)
209         file_size = actual_file_size - file_offset;
210     }
211     return ObjectFile::GetModuleSpecifications(file,        // file spec
212                                                data_sp,     // data bytes
213                                                0,           // data offset
214                                                file_offset, // file offset
215                                                file_size,   // file length
216                                                specs);
217   }
218   return 0;
219 }
220 
GetModuleSpecifications(const lldb_private::FileSpec & file,lldb::DataBufferSP & data_sp,lldb::offset_t data_offset,lldb::offset_t file_offset,lldb::offset_t file_size,lldb_private::ModuleSpecList & specs)221 size_t ObjectFile::GetModuleSpecifications(
222     const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
223     lldb::offset_t data_offset, lldb::offset_t file_offset,
224     lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
225   const size_t initial_count = specs.GetSize();
226   ObjectFileGetModuleSpecifications callback;
227   uint32_t i;
228   // Try the ObjectFile plug-ins
229   for (i = 0;
230        (callback =
231             PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
232                 i)) != nullptr;
233        ++i) {
234     if (callback(file, data_sp, data_offset, file_offset, file_size, specs) > 0)
235       return specs.GetSize() - initial_count;
236   }
237 
238   // Try the ObjectContainer plug-ins
239   for (i = 0;
240        (callback = PluginManager::
241             GetObjectContainerGetModuleSpecificationsCallbackAtIndex(i)) !=
242        nullptr;
243        ++i) {
244     if (callback(file, data_sp, data_offset, file_offset, file_size, specs) > 0)
245       return specs.GetSize() - initial_count;
246   }
247   return 0;
248 }
249 
ObjectFile(const lldb::ModuleSP & module_sp,const FileSpec * file_spec_ptr,lldb::offset_t file_offset,lldb::offset_t length,lldb::DataBufferSP data_sp,lldb::offset_t data_offset)250 ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp,
251                        const FileSpec *file_spec_ptr,
252                        lldb::offset_t file_offset, lldb::offset_t length,
253                        lldb::DataBufferSP data_sp, lldb::offset_t data_offset)
254     : ModuleChild(module_sp),
255       m_file(), // This file could be different from the original module's file
256       m_type(eTypeInvalid), m_strata(eStrataInvalid),
257       m_file_offset(file_offset), m_length(length), m_data(), m_process_wp(),
258       m_memory_addr(LLDB_INVALID_ADDRESS), m_sections_up(), m_symtab_up(),
259       m_symtab_once_up(new llvm::once_flag()) {
260   if (file_spec_ptr)
261     m_file = *file_spec_ptr;
262   if (data_sp)
263     m_data.SetData(data_sp, data_offset, length);
264   Log *log = GetLog(LLDBLog::Object);
265   LLDB_LOGF(log,
266             "%p ObjectFile::ObjectFile() module = %p (%s), file = %s, "
267             "file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64,
268             static_cast<void *>(this), static_cast<void *>(module_sp.get()),
269             module_sp->GetSpecificationDescription().c_str(),
270             m_file ? m_file.GetPath().c_str() : "<NULL>", m_file_offset,
271             m_length);
272 }
273 
ObjectFile(const lldb::ModuleSP & module_sp,const ProcessSP & process_sp,lldb::addr_t header_addr,DataBufferSP header_data_sp)274 ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp,
275                        const ProcessSP &process_sp, lldb::addr_t header_addr,
276                        DataBufferSP header_data_sp)
277     : ModuleChild(module_sp), m_file(), m_type(eTypeInvalid),
278       m_strata(eStrataInvalid), m_file_offset(0), m_length(0), m_data(),
279       m_process_wp(process_sp), m_memory_addr(header_addr), m_sections_up(),
280       m_symtab_up(), m_symtab_once_up(new llvm::once_flag()) {
281   if (header_data_sp)
282     m_data.SetData(header_data_sp, 0, header_data_sp->GetByteSize());
283   Log *log = GetLog(LLDBLog::Object);
284   LLDB_LOGF(log,
285             "%p ObjectFile::ObjectFile() module = %p (%s), process = %p, "
286             "header_addr = 0x%" PRIx64,
287             static_cast<void *>(this), static_cast<void *>(module_sp.get()),
288             module_sp->GetSpecificationDescription().c_str(),
289             static_cast<void *>(process_sp.get()), m_memory_addr);
290 }
291 
~ObjectFile()292 ObjectFile::~ObjectFile() {
293   Log *log = GetLog(LLDBLog::Object);
294   LLDB_LOGF(log, "%p ObjectFile::~ObjectFile ()\n", static_cast<void *>(this));
295 }
296 
SetModulesArchitecture(const ArchSpec & new_arch)297 bool ObjectFile::SetModulesArchitecture(const ArchSpec &new_arch) {
298   ModuleSP module_sp(GetModule());
299   if (module_sp)
300     return module_sp->SetArchitecture(new_arch);
301   return false;
302 }
303 
GetAddressClass(addr_t file_addr)304 AddressClass ObjectFile::GetAddressClass(addr_t file_addr) {
305   Symtab *symtab = GetSymtab();
306   if (symtab) {
307     Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
308     if (symbol) {
309       if (symbol->ValueIsAddress()) {
310         const SectionSP section_sp(symbol->GetAddressRef().GetSection());
311         if (section_sp) {
312           const SectionType section_type = section_sp->GetType();
313           switch (section_type) {
314           case eSectionTypeInvalid:
315             return AddressClass::eUnknown;
316           case eSectionTypeCode:
317             return AddressClass::eCode;
318           case eSectionTypeContainer:
319             return AddressClass::eUnknown;
320           case eSectionTypeData:
321           case eSectionTypeDataCString:
322           case eSectionTypeDataCStringPointers:
323           case eSectionTypeDataSymbolAddress:
324           case eSectionTypeData4:
325           case eSectionTypeData8:
326           case eSectionTypeData16:
327           case eSectionTypeDataPointers:
328           case eSectionTypeZeroFill:
329           case eSectionTypeDataObjCMessageRefs:
330           case eSectionTypeDataObjCCFStrings:
331           case eSectionTypeGoSymtab:
332             return AddressClass::eData;
333           case eSectionTypeDebug:
334           case eSectionTypeDWARFDebugAbbrev:
335           case eSectionTypeDWARFDebugAbbrevDwo:
336           case eSectionTypeDWARFDebugAddr:
337           case eSectionTypeDWARFDebugAranges:
338           case eSectionTypeDWARFDebugCuIndex:
339           case eSectionTypeDWARFDebugFrame:
340           case eSectionTypeDWARFDebugInfo:
341           case eSectionTypeDWARFDebugInfoDwo:
342           case eSectionTypeDWARFDebugLine:
343           case eSectionTypeDWARFDebugLineStr:
344           case eSectionTypeDWARFDebugLoc:
345           case eSectionTypeDWARFDebugLocDwo:
346           case eSectionTypeDWARFDebugLocLists:
347           case eSectionTypeDWARFDebugLocListsDwo:
348           case eSectionTypeDWARFDebugMacInfo:
349           case eSectionTypeDWARFDebugMacro:
350           case eSectionTypeDWARFDebugNames:
351           case eSectionTypeDWARFDebugPubNames:
352           case eSectionTypeDWARFDebugPubTypes:
353           case eSectionTypeDWARFDebugRanges:
354           case eSectionTypeDWARFDebugRngLists:
355           case eSectionTypeDWARFDebugRngListsDwo:
356           case eSectionTypeDWARFDebugStr:
357           case eSectionTypeDWARFDebugStrDwo:
358           case eSectionTypeDWARFDebugStrOffsets:
359           case eSectionTypeDWARFDebugStrOffsetsDwo:
360           case eSectionTypeDWARFDebugTuIndex:
361           case eSectionTypeDWARFDebugTypes:
362           case eSectionTypeDWARFDebugTypesDwo:
363           case eSectionTypeDWARFAppleNames:
364           case eSectionTypeDWARFAppleTypes:
365           case eSectionTypeDWARFAppleNamespaces:
366           case eSectionTypeDWARFAppleObjC:
367           case eSectionTypeDWARFGNUDebugAltLink:
368           case eSectionTypeCTF:
369           case eSectionTypeLLDBFormatters:
370           case eSectionTypeLLDBTypeSummaries:
371           case eSectionTypeSwiftModules:
372             return AddressClass::eDebug;
373           case eSectionTypeEHFrame:
374           case eSectionTypeARMexidx:
375           case eSectionTypeARMextab:
376           case eSectionTypeCompactUnwind:
377             return AddressClass::eRuntime;
378           case eSectionTypeELFSymbolTable:
379           case eSectionTypeELFDynamicSymbols:
380           case eSectionTypeELFRelocationEntries:
381           case eSectionTypeELFDynamicLinkInfo:
382           case eSectionTypeOther:
383             return AddressClass::eUnknown;
384           case eSectionTypeAbsoluteAddress:
385             // In case of absolute sections decide the address class based on
386             // the symbol type because the section type isn't specify if it is
387             // a code or a data section.
388             break;
389           }
390         }
391       }
392 
393       const SymbolType symbol_type = symbol->GetType();
394       switch (symbol_type) {
395       case eSymbolTypeAny:
396         return AddressClass::eUnknown;
397       case eSymbolTypeAbsolute:
398         return AddressClass::eUnknown;
399       case eSymbolTypeCode:
400         return AddressClass::eCode;
401       case eSymbolTypeTrampoline:
402         return AddressClass::eCode;
403       case eSymbolTypeResolver:
404         return AddressClass::eCode;
405       case eSymbolTypeData:
406         return AddressClass::eData;
407       case eSymbolTypeRuntime:
408         return AddressClass::eRuntime;
409       case eSymbolTypeException:
410         return AddressClass::eRuntime;
411       case eSymbolTypeSourceFile:
412         return AddressClass::eDebug;
413       case eSymbolTypeHeaderFile:
414         return AddressClass::eDebug;
415       case eSymbolTypeObjectFile:
416         return AddressClass::eDebug;
417       case eSymbolTypeCommonBlock:
418         return AddressClass::eDebug;
419       case eSymbolTypeBlock:
420         return AddressClass::eDebug;
421       case eSymbolTypeLocal:
422         return AddressClass::eData;
423       case eSymbolTypeParam:
424         return AddressClass::eData;
425       case eSymbolTypeVariable:
426         return AddressClass::eData;
427       case eSymbolTypeVariableType:
428         return AddressClass::eDebug;
429       case eSymbolTypeLineEntry:
430         return AddressClass::eDebug;
431       case eSymbolTypeLineHeader:
432         return AddressClass::eDebug;
433       case eSymbolTypeScopeBegin:
434         return AddressClass::eDebug;
435       case eSymbolTypeScopeEnd:
436         return AddressClass::eDebug;
437       case eSymbolTypeAdditional:
438         return AddressClass::eUnknown;
439       case eSymbolTypeCompiler:
440         return AddressClass::eDebug;
441       case eSymbolTypeInstrumentation:
442         return AddressClass::eDebug;
443       case eSymbolTypeUndefined:
444         return AddressClass::eUnknown;
445       case eSymbolTypeObjCClass:
446         return AddressClass::eRuntime;
447       case eSymbolTypeObjCMetaClass:
448         return AddressClass::eRuntime;
449       case eSymbolTypeObjCIVar:
450         return AddressClass::eRuntime;
451       case eSymbolTypeReExported:
452         return AddressClass::eRuntime;
453       }
454     }
455   }
456   return AddressClass::eUnknown;
457 }
458 
ReadMemory(const ProcessSP & process_sp,lldb::addr_t addr,size_t byte_size)459 WritableDataBufferSP ObjectFile::ReadMemory(const ProcessSP &process_sp,
460                                             lldb::addr_t addr,
461                                             size_t byte_size) {
462   WritableDataBufferSP data_sp;
463   if (process_sp) {
464     std::unique_ptr<DataBufferHeap> data_up(new DataBufferHeap(byte_size, 0));
465     Status error;
466     const size_t bytes_read = process_sp->ReadMemory(
467         addr, data_up->GetBytes(), data_up->GetByteSize(), error);
468     if (bytes_read == byte_size)
469       data_sp.reset(data_up.release());
470   }
471   return data_sp;
472 }
473 
GetData(lldb::offset_t offset,size_t length,DataExtractor & data) const474 size_t ObjectFile::GetData(lldb::offset_t offset, size_t length,
475                            DataExtractor &data) const {
476   // The entire file has already been mmap'ed into m_data, so just copy from
477   // there as the back mmap buffer will be shared with shared pointers.
478   return data.SetData(m_data, offset, length);
479 }
480 
CopyData(lldb::offset_t offset,size_t length,void * dst) const481 size_t ObjectFile::CopyData(lldb::offset_t offset, size_t length,
482                             void *dst) const {
483   // The entire file has already been mmap'ed into m_data, so just copy from
484   // there Note that the data remains in target byte order.
485   return m_data.CopyData(offset, length, dst);
486 }
487 
ReadSectionData(Section * section,lldb::offset_t section_offset,void * dst,size_t dst_len)488 size_t ObjectFile::ReadSectionData(Section *section,
489                                    lldb::offset_t section_offset, void *dst,
490                                    size_t dst_len) {
491   assert(section);
492   section_offset *= section->GetTargetByteSize();
493 
494   // If some other objectfile owns this data, pass this to them.
495   if (section->GetObjectFile() != this)
496     return section->GetObjectFile()->ReadSectionData(section, section_offset,
497                                                      dst, dst_len);
498 
499   if (!section->IsRelocated())
500     RelocateSection(section);
501 
502   if (IsInMemory()) {
503     ProcessSP process_sp(m_process_wp.lock());
504     if (process_sp) {
505       Status error;
506       const addr_t base_load_addr =
507           section->GetLoadBaseAddress(&process_sp->GetTarget());
508       if (base_load_addr != LLDB_INVALID_ADDRESS)
509         return process_sp->ReadMemory(base_load_addr + section_offset, dst,
510                                       dst_len, error);
511     }
512   } else {
513     const lldb::offset_t section_file_size = section->GetFileSize();
514     if (section_offset < section_file_size) {
515       const size_t section_bytes_left = section_file_size - section_offset;
516       size_t section_dst_len = dst_len;
517       if (section_dst_len > section_bytes_left)
518         section_dst_len = section_bytes_left;
519       return CopyData(section->GetFileOffset() + section_offset,
520                       section_dst_len, dst);
521     } else {
522       if (section->GetType() == eSectionTypeZeroFill) {
523         const uint64_t section_size = section->GetByteSize();
524         const uint64_t section_bytes_left = section_size - section_offset;
525         uint64_t section_dst_len = dst_len;
526         if (section_dst_len > section_bytes_left)
527           section_dst_len = section_bytes_left;
528         memset(dst, 0, section_dst_len);
529         return section_dst_len;
530       }
531     }
532   }
533   return 0;
534 }
535 
536 // Get the section data the file on disk
ReadSectionData(Section * section,DataExtractor & section_data)537 size_t ObjectFile::ReadSectionData(Section *section,
538                                    DataExtractor &section_data) {
539   // If some other objectfile owns this data, pass this to them.
540   if (section->GetObjectFile() != this)
541     return section->GetObjectFile()->ReadSectionData(section, section_data);
542 
543   if (!section->IsRelocated())
544     RelocateSection(section);
545 
546   if (IsInMemory()) {
547     ProcessSP process_sp(m_process_wp.lock());
548     if (process_sp) {
549       const addr_t base_load_addr =
550           section->GetLoadBaseAddress(&process_sp->GetTarget());
551       if (base_load_addr != LLDB_INVALID_ADDRESS) {
552         DataBufferSP data_sp(
553             ReadMemory(process_sp, base_load_addr, section->GetByteSize()));
554         if (data_sp) {
555           section_data.SetData(data_sp, 0, data_sp->GetByteSize());
556           section_data.SetByteOrder(process_sp->GetByteOrder());
557           section_data.SetAddressByteSize(process_sp->GetAddressByteSize());
558           return section_data.GetByteSize();
559         }
560       }
561     }
562   }
563 
564   // The object file now contains a full mmap'ed copy of the object file
565   // data, so just use this
566   return GetData(section->GetFileOffset(), GetSectionDataSize(section),
567                  section_data);
568 }
569 
SplitArchivePathWithObject(llvm::StringRef path_with_object,FileSpec & archive_file,ConstString & archive_object,bool must_exist)570 bool ObjectFile::SplitArchivePathWithObject(llvm::StringRef path_with_object,
571                                             FileSpec &archive_file,
572                                             ConstString &archive_object,
573                                             bool must_exist) {
574   size_t len = path_with_object.size();
575   if (len < 2 || path_with_object.back() != ')')
576     return false;
577   llvm::StringRef archive = path_with_object.substr(0, path_with_object.rfind('('));
578   if (archive.empty())
579     return false;
580   llvm::StringRef object = path_with_object.substr(archive.size() + 1).drop_back();
581   archive_file.SetFile(archive, FileSpec::Style::native);
582   if (must_exist && !FileSystem::Instance().Exists(archive_file))
583     return false;
584   archive_object.SetString(object);
585   return true;
586 }
587 
ClearSymtab()588 void ObjectFile::ClearSymtab() {
589   ModuleSP module_sp(GetModule());
590   if (module_sp) {
591     Log *log = GetLog(LLDBLog::Object);
592     LLDB_LOGF(log, "%p ObjectFile::ClearSymtab () symtab = %p",
593               static_cast<void *>(this),
594               static_cast<void *>(m_symtab_up.get()));
595     // Since we need to clear the symbol table, we need a new llvm::once_flag
596     // instance so we can safely create another symbol table
597     m_symtab_once_up.reset(new llvm::once_flag());
598     m_symtab_up.reset();
599   }
600 }
601 
GetSectionList(bool update_module_section_list)602 SectionList *ObjectFile::GetSectionList(bool update_module_section_list) {
603   if (m_sections_up == nullptr) {
604     if (update_module_section_list) {
605       ModuleSP module_sp(GetModule());
606       if (module_sp) {
607         std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
608         CreateSections(*module_sp->GetUnifiedSectionList());
609       }
610     } else {
611       SectionList unified_section_list;
612       CreateSections(unified_section_list);
613     }
614   }
615   return m_sections_up.get();
616 }
617 
618 lldb::SymbolType
GetSymbolTypeFromName(llvm::StringRef name,lldb::SymbolType symbol_type_hint)619 ObjectFile::GetSymbolTypeFromName(llvm::StringRef name,
620                                   lldb::SymbolType symbol_type_hint) {
621   if (!name.empty()) {
622     if (name.starts_with("_OBJC_")) {
623       // ObjC
624       if (name.starts_with("_OBJC_CLASS_$_"))
625         return lldb::eSymbolTypeObjCClass;
626       if (name.starts_with("_OBJC_METACLASS_$_"))
627         return lldb::eSymbolTypeObjCMetaClass;
628       if (name.starts_with("_OBJC_IVAR_$_"))
629         return lldb::eSymbolTypeObjCIVar;
630     } else if (name.starts_with(".objc_class_name_")) {
631       // ObjC v1
632       return lldb::eSymbolTypeObjCClass;
633     }
634   }
635   return symbol_type_hint;
636 }
637 
638 lldb::SectionType
GetDWARFSectionTypeFromName(llvm::StringRef name)639 ObjectFile::GetDWARFSectionTypeFromName(llvm::StringRef name) {
640   return llvm::StringSwitch<SectionType>(name)
641       .Case("abbrev", eSectionTypeDWARFDebugAbbrev)
642       .Case("abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo)
643       .Case("addr", eSectionTypeDWARFDebugAddr)
644       .Case("aranges", eSectionTypeDWARFDebugAranges)
645       .Case("cu_index", eSectionTypeDWARFDebugCuIndex)
646       .Case("frame", eSectionTypeDWARFDebugFrame)
647       .Case("info", eSectionTypeDWARFDebugInfo)
648       .Case("info.dwo", eSectionTypeDWARFDebugInfoDwo)
649       .Cases("line", "line.dwo", eSectionTypeDWARFDebugLine)
650       .Cases("line_str", "line_str.dwo", eSectionTypeDWARFDebugLineStr)
651       .Case("loc", eSectionTypeDWARFDebugLoc)
652       .Case("loc.dwo", eSectionTypeDWARFDebugLocDwo)
653       .Case("loclists", eSectionTypeDWARFDebugLocLists)
654       .Case("loclists.dwo", eSectionTypeDWARFDebugLocListsDwo)
655       .Case("macinfo", eSectionTypeDWARFDebugMacInfo)
656       .Cases("macro", "macro.dwo", eSectionTypeDWARFDebugMacro)
657       .Case("names", eSectionTypeDWARFDebugNames)
658       .Case("pubnames", eSectionTypeDWARFDebugPubNames)
659       .Case("pubtypes", eSectionTypeDWARFDebugPubTypes)
660       .Case("ranges", eSectionTypeDWARFDebugRanges)
661       .Case("rnglists", eSectionTypeDWARFDebugRngLists)
662       .Case("rnglists.dwo", eSectionTypeDWARFDebugRngListsDwo)
663       .Case("str", eSectionTypeDWARFDebugStr)
664       .Case("str.dwo", eSectionTypeDWARFDebugStrDwo)
665       .Case("str_offsets", eSectionTypeDWARFDebugStrOffsets)
666       .Case("str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo)
667       .Case("tu_index", eSectionTypeDWARFDebugTuIndex)
668       .Case("types", eSectionTypeDWARFDebugTypes)
669       .Case("types.dwo", eSectionTypeDWARFDebugTypesDwo)
670       .Default(eSectionTypeOther);
671 }
672 
673 std::vector<ObjectFile::LoadableData>
GetLoadableData(Target & target)674 ObjectFile::GetLoadableData(Target &target) {
675   std::vector<LoadableData> loadables;
676   SectionList *section_list = GetSectionList();
677   if (!section_list)
678     return loadables;
679   // Create a list of loadable data from loadable sections
680   size_t section_count = section_list->GetNumSections(0);
681   for (size_t i = 0; i < section_count; ++i) {
682     LoadableData loadable;
683     SectionSP section_sp = section_list->GetSectionAtIndex(i);
684     loadable.Dest = target.GetSectionLoadAddress(section_sp);
685     if (loadable.Dest == LLDB_INVALID_ADDRESS)
686       continue;
687     // We can skip sections like bss
688     if (section_sp->GetFileSize() == 0)
689       continue;
690     DataExtractor section_data;
691     section_sp->GetSectionData(section_data);
692     loadable.Contents = llvm::ArrayRef<uint8_t>(section_data.GetDataStart(),
693                                                 section_data.GetByteSize());
694     loadables.push_back(loadable);
695   }
696   return loadables;
697 }
698 
CreateCallFrameInfo()699 std::unique_ptr<CallFrameInfo> ObjectFile::CreateCallFrameInfo() {
700   return {};
701 }
702 
RelocateSection(lldb_private::Section * section)703 void ObjectFile::RelocateSection(lldb_private::Section *section)
704 {
705 }
706 
MapFileData(const FileSpec & file,uint64_t Size,uint64_t Offset)707 DataBufferSP ObjectFile::MapFileData(const FileSpec &file, uint64_t Size,
708                                      uint64_t Offset) {
709   return FileSystem::Instance().CreateDataBuffer(file.GetPath(), Size, Offset);
710 }
711 
format(const ObjectFile::Type & type,raw_ostream & OS,StringRef Style)712 void llvm::format_provider<ObjectFile::Type>::format(
713     const ObjectFile::Type &type, raw_ostream &OS, StringRef Style) {
714   switch (type) {
715   case ObjectFile::eTypeInvalid:
716     OS << "invalid";
717     break;
718   case ObjectFile::eTypeCoreFile:
719     OS << "core file";
720     break;
721   case ObjectFile::eTypeExecutable:
722     OS << "executable";
723     break;
724   case ObjectFile::eTypeDebugInfo:
725     OS << "debug info";
726     break;
727   case ObjectFile::eTypeDynamicLinker:
728     OS << "dynamic linker";
729     break;
730   case ObjectFile::eTypeObjectFile:
731     OS << "object file";
732     break;
733   case ObjectFile::eTypeSharedLibrary:
734     OS << "shared library";
735     break;
736   case ObjectFile::eTypeStubLibrary:
737     OS << "stub library";
738     break;
739   case ObjectFile::eTypeJIT:
740     OS << "jit";
741     break;
742   case ObjectFile::eTypeUnknown:
743     OS << "unknown";
744     break;
745   }
746 }
747 
format(const ObjectFile::Strata & strata,raw_ostream & OS,StringRef Style)748 void llvm::format_provider<ObjectFile::Strata>::format(
749     const ObjectFile::Strata &strata, raw_ostream &OS, StringRef Style) {
750   switch (strata) {
751   case ObjectFile::eStrataInvalid:
752     OS << "invalid";
753     break;
754   case ObjectFile::eStrataUnknown:
755     OS << "unknown";
756     break;
757   case ObjectFile::eStrataUser:
758     OS << "user";
759     break;
760   case ObjectFile::eStrataKernel:
761     OS << "kernel";
762     break;
763   case ObjectFile::eStrataRawImage:
764     OS << "raw image";
765     break;
766   case ObjectFile::eStrataJIT:
767     OS << "jit";
768     break;
769   }
770 }
771 
GetSymtab(bool can_create)772 Symtab *ObjectFile::GetSymtab(bool can_create) {
773   ModuleSP module_sp(GetModule());
774   if (module_sp && can_create) {
775     // We can't take the module lock in ObjectFile::GetSymtab() or we can
776     // deadlock in DWARF indexing when any file asks for the symbol table from
777     // an object file. This currently happens in the preloading of symbols in
778     // SymbolFileDWARF::PreloadSymbols() because the main thread will take the
779     // module lock, and then threads will be spun up to index the DWARF and
780     // any of those threads might end up trying to relocate items in the DWARF
781     // sections which causes ObjectFile::GetSectionData(...) to relocate section
782     // data which requires the symbol table.
783     //
784     // So to work around this, we create the symbol table one time using
785     // llvm::once_flag, lock it, and then set the unique pointer. Any other
786     // thread that gets ahold of the symbol table before parsing is done, will
787     // not be able to access the symbol table contents since all APIs in Symtab
788     // are protected by a mutex in the Symtab object itself.
789     llvm::call_once(*m_symtab_once_up, [&]() {
790       Symtab *symtab = new Symtab(this);
791       std::lock_guard<std::recursive_mutex> symtab_guard(symtab->GetMutex());
792       m_symtab_up.reset(symtab);
793       if (!m_symtab_up->LoadFromCache()) {
794         ElapsedTime elapsed(module_sp->GetSymtabParseTime());
795         ParseSymtab(*m_symtab_up);
796         m_symtab_up->Finalize();
797       }
798     });
799   }
800   return m_symtab_up.get();
801 }
802 
GetCacheHash()803 uint32_t ObjectFile::GetCacheHash() {
804   if (m_cache_hash)
805     return *m_cache_hash;
806   StreamString strm;
807   strm.Format("{0}-{1}-{2}", m_file, GetType(), GetStrata());
808   m_cache_hash = llvm::djbHash(strm.GetString());
809   return *m_cache_hash;
810 }
811 
GetObjectName() const812 std::string ObjectFile::GetObjectName() const {
813   if (ModuleSP module_sp = GetModule())
814     if (ConstString object_name = module_sp->GetObjectName())
815       return llvm::formatv("{0}({1})", GetFileSpec().GetFilename().GetString(),
816                            object_name.GetString())
817           .str();
818   return GetFileSpec().GetFilename().GetString();
819 }
820 
821 namespace llvm {
822 namespace json {
823 
fromJSON(const llvm::json::Value & value,lldb_private::ObjectFile::Type & type,llvm::json::Path path)824 bool fromJSON(const llvm::json::Value &value,
825               lldb_private::ObjectFile::Type &type, llvm::json::Path path) {
826   if (auto str = value.getAsString()) {
827     type = llvm::StringSwitch<ObjectFile::Type>(*str)
828                .Case("corefile", ObjectFile::eTypeCoreFile)
829                .Case("executable", ObjectFile::eTypeExecutable)
830                .Case("debuginfo", ObjectFile::eTypeDebugInfo)
831                .Case("dynamiclinker", ObjectFile::eTypeDynamicLinker)
832                .Case("objectfile", ObjectFile::eTypeObjectFile)
833                .Case("sharedlibrary", ObjectFile::eTypeSharedLibrary)
834                .Case("stublibrary", ObjectFile::eTypeStubLibrary)
835                .Case("jit", ObjectFile::eTypeJIT)
836                .Case("unknown", ObjectFile::eTypeUnknown)
837                .Default(ObjectFile::eTypeInvalid);
838 
839     if (type == ObjectFile::eTypeInvalid) {
840       path.report("invalid object type");
841       return false;
842     }
843 
844     return true;
845   }
846   path.report("expected string");
847   return false;
848 }
849 } // namespace json
850 } // namespace llvm
851