1 //===-- ObjectFile.cpp ------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lldb/Symbol/ObjectFile.h"
11 #include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h"
12 #include "lldb/Core/DataBuffer.h"
13 #include "lldb/Core/DataBufferHeap.h"
14 #include "lldb/Core/Log.h"
15 #include "lldb/Core/Module.h"
16 #include "lldb/Core/ModuleSpec.h"
17 #include "lldb/Core/PluginManager.h"
18 #include "lldb/Core/Section.h"
19 #include "lldb/Core/Timer.h"
20 #include "lldb/Symbol/ObjectContainer.h"
21 #include "lldb/Symbol/SymbolFile.h"
22 #include "lldb/Target/Process.h"
23 #include "lldb/Target/RegisterContext.h"
24 #include "lldb/Target/SectionLoadList.h"
25 #include "lldb/Target/Target.h"
26 #include "lldb/Utility/RegularExpression.h"
27 #include "lldb/lldb-private.h"
28 
29 using namespace lldb;
30 using namespace lldb_private;
31 
32 ObjectFileSP
33 ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file,
34                        lldb::offset_t file_offset, lldb::offset_t file_size,
35                        DataBufferSP &data_sp, lldb::offset_t &data_offset) {
36   ObjectFileSP object_file_sp;
37 
38   if (module_sp) {
39     Timer scoped_timer(
40         LLVM_PRETTY_FUNCTION,
41         "ObjectFile::FindPlugin (module = %s, file = %p, file_offset = "
42         "0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
43         module_sp->GetFileSpec().GetPath().c_str(),
44         static_cast<const void *>(file), static_cast<uint64_t>(file_offset),
45         static_cast<uint64_t>(file_size));
46     if (file) {
47       FileSpec archive_file;
48       ObjectContainerCreateInstance create_object_container_callback;
49 
50       const bool file_exists = file->Exists();
51       if (!data_sp) {
52         // We have an object name which most likely means we have
53         // a .o file in a static archive (.a file). Try and see if
54         // we have a cached archive first without reading any data
55         // first
56         if (file_exists && module_sp->GetObjectName()) {
57           for (uint32_t idx = 0;
58                (create_object_container_callback =
59                     PluginManager::GetObjectContainerCreateCallbackAtIndex(
60                         idx)) != nullptr;
61                ++idx) {
62             std::unique_ptr<ObjectContainer> object_container_ap(
63                 create_object_container_callback(module_sp, data_sp,
64                                                  data_offset, file, file_offset,
65                                                  file_size));
66 
67             if (object_container_ap.get())
68               object_file_sp = object_container_ap->GetObjectFile(file);
69 
70             if (object_file_sp.get())
71               return object_file_sp;
72           }
73         }
74         // Ok, we didn't find any containers that have a named object, now
75         // lets read the first 512 bytes from the file so the object file
76         // and object container plug-ins can use these bytes to see if they
77         // can parse this file.
78         if (file_size > 0) {
79           data_sp = file->ReadFileContents(file_offset,
80                                            std::min<size_t>(512, file_size));
81           data_offset = 0;
82         }
83       }
84 
85       if (!data_sp || data_sp->GetByteSize() == 0) {
86         // Check for archive file with format "/path/to/archive.a(object.o)"
87         char path_with_object[PATH_MAX * 2];
88         module_sp->GetFileSpec().GetPath(path_with_object,
89                                          sizeof(path_with_object));
90 
91         ConstString archive_object;
92         const bool must_exist = true;
93         if (ObjectFile::SplitArchivePathWithObject(
94                 path_with_object, archive_file, archive_object, must_exist)) {
95           file_size = archive_file.GetByteSize();
96           if (file_size > 0) {
97             file = &archive_file;
98             module_sp->SetFileSpecAndObjectName(archive_file, archive_object);
99             // Check if this is a object container by iterating through all
100             // object
101             // container plugin instances and then trying to get an object file
102             // from the container plugins since we had a name. Also, don't read
103             // ANY data in case there is data cached in the container plug-ins
104             // (like BSD archives caching the contained objects within an file).
105             for (uint32_t idx = 0;
106                  (create_object_container_callback =
107                       PluginManager::GetObjectContainerCreateCallbackAtIndex(
108                           idx)) != nullptr;
109                  ++idx) {
110               std::unique_ptr<ObjectContainer> object_container_ap(
111                   create_object_container_callback(module_sp, data_sp,
112                                                    data_offset, file,
113                                                    file_offset, file_size));
114 
115               if (object_container_ap.get())
116                 object_file_sp = object_container_ap->GetObjectFile(file);
117 
118               if (object_file_sp.get())
119                 return object_file_sp;
120             }
121             // We failed to find any cached object files in the container
122             // plug-ins, so lets read the first 512 bytes and try again below...
123             data_sp = archive_file.ReadFileContents(file_offset, 512);
124           }
125         }
126       }
127 
128       if (data_sp && data_sp->GetByteSize() > 0) {
129         // Check if this is a normal object file by iterating through
130         // all object file plugin instances.
131         ObjectFileCreateInstance create_object_file_callback;
132         for (uint32_t idx = 0;
133              (create_object_file_callback =
134                   PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) !=
135              nullptr;
136              ++idx) {
137           object_file_sp.reset(create_object_file_callback(
138               module_sp, data_sp, data_offset, file, file_offset, file_size));
139           if (object_file_sp.get())
140             return object_file_sp;
141         }
142 
143         // Check if this is a object container by iterating through
144         // all object container plugin instances and then trying to get
145         // an object file from the container.
146         for (uint32_t idx = 0;
147              (create_object_container_callback =
148                   PluginManager::GetObjectContainerCreateCallbackAtIndex(
149                       idx)) != nullptr;
150              ++idx) {
151           std::unique_ptr<ObjectContainer> object_container_ap(
152               create_object_container_callback(module_sp, data_sp, data_offset,
153                                                file, file_offset, file_size));
154 
155           if (object_container_ap.get())
156             object_file_sp = object_container_ap->GetObjectFile(file);
157 
158           if (object_file_sp.get())
159             return object_file_sp;
160         }
161       }
162     }
163   }
164   // We didn't find it, so clear our shared pointer in case it
165   // contains anything and return an empty shared pointer
166   object_file_sp.reset();
167   return object_file_sp;
168 }
169 
170 ObjectFileSP ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp,
171                                     const ProcessSP &process_sp,
172                                     lldb::addr_t header_addr,
173                                     DataBufferSP &data_sp) {
174   ObjectFileSP object_file_sp;
175 
176   if (module_sp) {
177     Timer scoped_timer(LLVM_PRETTY_FUNCTION, "ObjectFile::FindPlugin (module = "
178                                              "%s, process = %p, header_addr = "
179                                              "0x%" PRIx64 ")",
180                        module_sp->GetFileSpec().GetPath().c_str(),
181                        static_cast<void *>(process_sp.get()), header_addr);
182     uint32_t idx;
183 
184     // Check if this is a normal object file by iterating through
185     // all object file plugin instances.
186     ObjectFileCreateMemoryInstance create_callback;
187     for (idx = 0;
188          (create_callback =
189               PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(idx)) !=
190          nullptr;
191          ++idx) {
192       object_file_sp.reset(
193           create_callback(module_sp, data_sp, process_sp, header_addr));
194       if (object_file_sp.get())
195         return object_file_sp;
196     }
197   }
198 
199   // We didn't find it, so clear our shared pointer in case it
200   // contains anything and return an empty shared pointer
201   object_file_sp.reset();
202   return object_file_sp;
203 }
204 
205 size_t ObjectFile::GetModuleSpecifications(const FileSpec &file,
206                                            lldb::offset_t file_offset,
207                                            lldb::offset_t file_size,
208                                            ModuleSpecList &specs) {
209   DataBufferSP data_sp(file.ReadFileContents(file_offset, 512));
210   if (data_sp) {
211     if (file_size == 0) {
212       const lldb::offset_t actual_file_size = file.GetByteSize();
213       if (actual_file_size > file_offset)
214         file_size = actual_file_size - file_offset;
215     }
216     return ObjectFile::GetModuleSpecifications(file,        // file spec
217                                                data_sp,     // data bytes
218                                                0,           // data offset
219                                                file_offset, // file offset
220                                                file_size,   // file length
221                                                specs);
222   }
223   return 0;
224 }
225 
226 size_t ObjectFile::GetModuleSpecifications(
227     const lldb_private::FileSpec &file, lldb::DataBufferSP &data_sp,
228     lldb::offset_t data_offset, lldb::offset_t file_offset,
229     lldb::offset_t file_size, lldb_private::ModuleSpecList &specs) {
230   const size_t initial_count = specs.GetSize();
231   ObjectFileGetModuleSpecifications callback;
232   uint32_t i;
233   // Try the ObjectFile plug-ins
234   for (i = 0;
235        (callback =
236             PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(
237                 i)) != nullptr;
238        ++i) {
239     if (callback(file, data_sp, data_offset, file_offset, file_size, specs) > 0)
240       return specs.GetSize() - initial_count;
241   }
242 
243   // Try the ObjectContainer plug-ins
244   for (i = 0;
245        (callback = PluginManager::
246             GetObjectContainerGetModuleSpecificationsCallbackAtIndex(i)) !=
247        nullptr;
248        ++i) {
249     if (callback(file, data_sp, data_offset, file_offset, file_size, specs) > 0)
250       return specs.GetSize() - initial_count;
251   }
252   return 0;
253 }
254 
255 ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp,
256                        const FileSpec *file_spec_ptr,
257                        lldb::offset_t file_offset, lldb::offset_t length,
258                        const lldb::DataBufferSP &data_sp,
259                        lldb::offset_t data_offset)
260     : ModuleChild(module_sp),
261       m_file(), // This file could be different from the original module's file
262       m_type(eTypeInvalid), m_strata(eStrataInvalid),
263       m_file_offset(file_offset), m_length(length), m_data(),
264       m_unwind_table(*this), m_process_wp(),
265       m_memory_addr(LLDB_INVALID_ADDRESS), m_sections_ap(), m_symtab_ap(),
266       m_synthetic_symbol_idx(0) {
267   if (file_spec_ptr)
268     m_file = *file_spec_ptr;
269   if (data_sp)
270     m_data.SetData(data_sp, data_offset, length);
271   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
272   if (log)
273     log->Printf("%p ObjectFile::ObjectFile() module = %p (%s), file = %s, "
274                 "file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64,
275                 static_cast<void *>(this), static_cast<void *>(module_sp.get()),
276                 module_sp->GetSpecificationDescription().c_str(),
277                 m_file ? m_file.GetPath().c_str() : "<NULL>", m_file_offset,
278                 m_length);
279 }
280 
281 ObjectFile::ObjectFile(const lldb::ModuleSP &module_sp,
282                        const ProcessSP &process_sp, lldb::addr_t header_addr,
283                        DataBufferSP &header_data_sp)
284     : ModuleChild(module_sp), m_file(), m_type(eTypeInvalid),
285       m_strata(eStrataInvalid), m_file_offset(0), m_length(0), m_data(),
286       m_unwind_table(*this), m_process_wp(process_sp),
287       m_memory_addr(header_addr), m_sections_ap(), m_symtab_ap(),
288       m_synthetic_symbol_idx(0) {
289   if (header_data_sp)
290     m_data.SetData(header_data_sp, 0, header_data_sp->GetByteSize());
291   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
292   if (log)
293     log->Printf("%p ObjectFile::ObjectFile() module = %p (%s), process = %p, "
294                 "header_addr = 0x%" PRIx64,
295                 static_cast<void *>(this), static_cast<void *>(module_sp.get()),
296                 module_sp->GetSpecificationDescription().c_str(),
297                 static_cast<void *>(process_sp.get()), m_memory_addr);
298 }
299 
300 ObjectFile::~ObjectFile() {
301   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
302   if (log)
303     log->Printf("%p ObjectFile::~ObjectFile ()\n", static_cast<void *>(this));
304 }
305 
306 bool ObjectFile::SetModulesArchitecture(const ArchSpec &new_arch) {
307   ModuleSP module_sp(GetModule());
308   if (module_sp)
309     return module_sp->SetArchitecture(new_arch);
310   return false;
311 }
312 
313 AddressClass ObjectFile::GetAddressClass(addr_t file_addr) {
314   Symtab *symtab = GetSymtab();
315   if (symtab) {
316     Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
317     if (symbol) {
318       if (symbol->ValueIsAddress()) {
319         const SectionSP section_sp(symbol->GetAddressRef().GetSection());
320         if (section_sp) {
321           const SectionType section_type = section_sp->GetType();
322           switch (section_type) {
323           case eSectionTypeInvalid:
324             return eAddressClassUnknown;
325           case eSectionTypeCode:
326             return eAddressClassCode;
327           case eSectionTypeContainer:
328             return eAddressClassUnknown;
329           case eSectionTypeData:
330           case eSectionTypeDataCString:
331           case eSectionTypeDataCStringPointers:
332           case eSectionTypeDataSymbolAddress:
333           case eSectionTypeData4:
334           case eSectionTypeData8:
335           case eSectionTypeData16:
336           case eSectionTypeDataPointers:
337           case eSectionTypeZeroFill:
338           case eSectionTypeDataObjCMessageRefs:
339           case eSectionTypeDataObjCCFStrings:
340           case eSectionTypeGoSymtab:
341             return eAddressClassData;
342           case eSectionTypeDebug:
343           case eSectionTypeDWARFDebugAbbrev:
344           case eSectionTypeDWARFDebugAddr:
345           case eSectionTypeDWARFDebugAranges:
346           case eSectionTypeDWARFDebugFrame:
347           case eSectionTypeDWARFDebugInfo:
348           case eSectionTypeDWARFDebugLine:
349           case eSectionTypeDWARFDebugLoc:
350           case eSectionTypeDWARFDebugMacInfo:
351           case eSectionTypeDWARFDebugMacro:
352           case eSectionTypeDWARFDebugPubNames:
353           case eSectionTypeDWARFDebugPubTypes:
354           case eSectionTypeDWARFDebugRanges:
355           case eSectionTypeDWARFDebugStr:
356           case eSectionTypeDWARFDebugStrOffsets:
357           case eSectionTypeDWARFAppleNames:
358           case eSectionTypeDWARFAppleTypes:
359           case eSectionTypeDWARFAppleNamespaces:
360           case eSectionTypeDWARFAppleObjC:
361             return eAddressClassDebug;
362           case eSectionTypeEHFrame:
363           case eSectionTypeARMexidx:
364           case eSectionTypeARMextab:
365           case eSectionTypeCompactUnwind:
366             return eAddressClassRuntime;
367           case eSectionTypeELFSymbolTable:
368           case eSectionTypeELFDynamicSymbols:
369           case eSectionTypeELFRelocationEntries:
370           case eSectionTypeELFDynamicLinkInfo:
371           case eSectionTypeOther:
372             return eAddressClassUnknown;
373           case eSectionTypeAbsoluteAddress:
374             // In case of absolute sections decide the address class based on
375             // the symbol
376             // type because the section type isn't specify if it is a code or a
377             // data
378             // section.
379             break;
380           }
381         }
382       }
383 
384       const SymbolType symbol_type = symbol->GetType();
385       switch (symbol_type) {
386       case eSymbolTypeAny:
387         return eAddressClassUnknown;
388       case eSymbolTypeAbsolute:
389         return eAddressClassUnknown;
390       case eSymbolTypeCode:
391         return eAddressClassCode;
392       case eSymbolTypeTrampoline:
393         return eAddressClassCode;
394       case eSymbolTypeResolver:
395         return eAddressClassCode;
396       case eSymbolTypeData:
397         return eAddressClassData;
398       case eSymbolTypeRuntime:
399         return eAddressClassRuntime;
400       case eSymbolTypeException:
401         return eAddressClassRuntime;
402       case eSymbolTypeSourceFile:
403         return eAddressClassDebug;
404       case eSymbolTypeHeaderFile:
405         return eAddressClassDebug;
406       case eSymbolTypeObjectFile:
407         return eAddressClassDebug;
408       case eSymbolTypeCommonBlock:
409         return eAddressClassDebug;
410       case eSymbolTypeBlock:
411         return eAddressClassDebug;
412       case eSymbolTypeLocal:
413         return eAddressClassData;
414       case eSymbolTypeParam:
415         return eAddressClassData;
416       case eSymbolTypeVariable:
417         return eAddressClassData;
418       case eSymbolTypeVariableType:
419         return eAddressClassDebug;
420       case eSymbolTypeLineEntry:
421         return eAddressClassDebug;
422       case eSymbolTypeLineHeader:
423         return eAddressClassDebug;
424       case eSymbolTypeScopeBegin:
425         return eAddressClassDebug;
426       case eSymbolTypeScopeEnd:
427         return eAddressClassDebug;
428       case eSymbolTypeAdditional:
429         return eAddressClassUnknown;
430       case eSymbolTypeCompiler:
431         return eAddressClassDebug;
432       case eSymbolTypeInstrumentation:
433         return eAddressClassDebug;
434       case eSymbolTypeUndefined:
435         return eAddressClassUnknown;
436       case eSymbolTypeObjCClass:
437         return eAddressClassRuntime;
438       case eSymbolTypeObjCMetaClass:
439         return eAddressClassRuntime;
440       case eSymbolTypeObjCIVar:
441         return eAddressClassRuntime;
442       case eSymbolTypeReExported:
443         return eAddressClassRuntime;
444       }
445     }
446   }
447   return eAddressClassUnknown;
448 }
449 
450 DataBufferSP ObjectFile::ReadMemory(const ProcessSP &process_sp,
451                                     lldb::addr_t addr, size_t byte_size) {
452   DataBufferSP data_sp;
453   if (process_sp) {
454     std::unique_ptr<DataBufferHeap> data_ap(new DataBufferHeap(byte_size, 0));
455     Error error;
456     const size_t bytes_read = process_sp->ReadMemory(
457         addr, data_ap->GetBytes(), data_ap->GetByteSize(), error);
458     if (bytes_read == byte_size)
459       data_sp.reset(data_ap.release());
460   }
461   return data_sp;
462 }
463 
464 size_t ObjectFile::GetData(lldb::offset_t offset, size_t length,
465                            DataExtractor &data) const {
466   // The entire file has already been mmap'ed into m_data, so just copy from
467   // there
468   // as the back mmap buffer will be shared with shared pointers.
469   return data.SetData(m_data, offset, length);
470 }
471 
472 size_t ObjectFile::CopyData(lldb::offset_t offset, size_t length,
473                             void *dst) const {
474   // The entire file has already been mmap'ed into m_data, so just copy from
475   // there
476   // Note that the data remains in target byte order.
477   return m_data.CopyData(offset, length, dst);
478 }
479 
480 size_t ObjectFile::ReadSectionData(const Section *section,
481                                    lldb::offset_t section_offset, void *dst,
482                                    size_t dst_len) const {
483   assert(section);
484   section_offset *= section->GetTargetByteSize();
485 
486   // If some other objectfile owns this data, pass this to them.
487   if (section->GetObjectFile() != this)
488     return section->GetObjectFile()->ReadSectionData(section, section_offset,
489                                                      dst, dst_len);
490 
491   if (IsInMemory()) {
492     ProcessSP process_sp(m_process_wp.lock());
493     if (process_sp) {
494       Error error;
495       const addr_t base_load_addr =
496           section->GetLoadBaseAddress(&process_sp->GetTarget());
497       if (base_load_addr != LLDB_INVALID_ADDRESS)
498         return process_sp->ReadMemory(base_load_addr + section_offset, dst,
499                                       dst_len, error);
500     }
501   } else {
502     const lldb::offset_t section_file_size = section->GetFileSize();
503     if (section_offset < section_file_size) {
504       const size_t section_bytes_left = section_file_size - section_offset;
505       size_t section_dst_len = dst_len;
506       if (section_dst_len > section_bytes_left)
507         section_dst_len = section_bytes_left;
508       return CopyData(section->GetFileOffset() + section_offset,
509                       section_dst_len, dst);
510     } else {
511       if (section->GetType() == eSectionTypeZeroFill) {
512         const uint64_t section_size = section->GetByteSize();
513         const uint64_t section_bytes_left = section_size - section_offset;
514         uint64_t section_dst_len = dst_len;
515         if (section_dst_len > section_bytes_left)
516           section_dst_len = section_bytes_left;
517         memset(dst, 0, section_dst_len);
518         return section_dst_len;
519       }
520     }
521   }
522   return 0;
523 }
524 
525 //----------------------------------------------------------------------
526 // Get the section data the file on disk
527 //----------------------------------------------------------------------
528 size_t ObjectFile::ReadSectionData(const Section *section,
529                                    DataExtractor &section_data) const {
530   // If some other objectfile owns this data, pass this to them.
531   if (section->GetObjectFile() != this)
532     return section->GetObjectFile()->ReadSectionData(section, section_data);
533 
534   if (IsInMemory()) {
535     ProcessSP process_sp(m_process_wp.lock());
536     if (process_sp) {
537       const addr_t base_load_addr =
538           section->GetLoadBaseAddress(&process_sp->GetTarget());
539       if (base_load_addr != LLDB_INVALID_ADDRESS) {
540         DataBufferSP data_sp(
541             ReadMemory(process_sp, base_load_addr, section->GetByteSize()));
542         if (data_sp) {
543           section_data.SetData(data_sp, 0, data_sp->GetByteSize());
544           section_data.SetByteOrder(process_sp->GetByteOrder());
545           section_data.SetAddressByteSize(process_sp->GetAddressByteSize());
546           return section_data.GetByteSize();
547         }
548       }
549     }
550     return GetData(section->GetFileOffset(), section->GetFileSize(),
551                    section_data);
552   } else {
553     // The object file now contains a full mmap'ed copy of the object file data,
554     // so just use this
555     return MemoryMapSectionData(section, section_data);
556   }
557 }
558 
559 size_t ObjectFile::MemoryMapSectionData(const Section *section,
560                                         DataExtractor &section_data) const {
561   // If some other objectfile owns this data, pass this to them.
562   if (section->GetObjectFile() != this)
563     return section->GetObjectFile()->MemoryMapSectionData(section,
564                                                           section_data);
565 
566   if (IsInMemory()) {
567     return ReadSectionData(section, section_data);
568   } else {
569     // The object file now contains a full mmap'ed copy of the object file data,
570     // so just use this
571     return GetData(section->GetFileOffset(), section->GetFileSize(),
572                    section_data);
573   }
574 }
575 
576 bool ObjectFile::SplitArchivePathWithObject(const char *path_with_object,
577                                             FileSpec &archive_file,
578                                             ConstString &archive_object,
579                                             bool must_exist) {
580   RegularExpression g_object_regex(llvm::StringRef("(.*)\\(([^\\)]+)\\)$"));
581   RegularExpression::Match regex_match(2);
582   if (g_object_regex.Execute(llvm::StringRef::withNullAsEmpty(path_with_object),
583                              &regex_match)) {
584     std::string path;
585     std::string obj;
586     if (regex_match.GetMatchAtIndex(path_with_object, 1, path) &&
587         regex_match.GetMatchAtIndex(path_with_object, 2, obj)) {
588       archive_file.SetFile(path, false);
589       archive_object.SetCString(obj.c_str());
590       if (must_exist && !archive_file.Exists())
591         return false;
592       return true;
593     }
594   }
595   return false;
596 }
597 
598 void ObjectFile::ClearSymtab() {
599   ModuleSP module_sp(GetModule());
600   if (module_sp) {
601     std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
602     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT));
603     if (log)
604       log->Printf("%p ObjectFile::ClearSymtab () symtab = %p",
605                   static_cast<void *>(this),
606                   static_cast<void *>(m_symtab_ap.get()));
607     m_symtab_ap.reset();
608   }
609 }
610 
611 SectionList *ObjectFile::GetSectionList(bool update_module_section_list) {
612   if (m_sections_ap.get() == nullptr) {
613     if (update_module_section_list) {
614       ModuleSP module_sp(GetModule());
615       if (module_sp) {
616         std::lock_guard<std::recursive_mutex> guard(module_sp->GetMutex());
617         CreateSections(*module_sp->GetUnifiedSectionList());
618       }
619     } else {
620       SectionList unified_section_list;
621       CreateSections(unified_section_list);
622     }
623   }
624   return m_sections_ap.get();
625 }
626 
627 lldb::SymbolType
628 ObjectFile::GetSymbolTypeFromName(llvm::StringRef name,
629                                   lldb::SymbolType symbol_type_hint) {
630   if (!name.empty()) {
631     if (name.startswith("_OBJC_")) {
632       // ObjC
633       if (name.startswith("_OBJC_CLASS_$_"))
634         return lldb::eSymbolTypeObjCClass;
635       if (name.startswith("_OBJC_METACLASS_$_"))
636         return lldb::eSymbolTypeObjCMetaClass;
637       if (name.startswith("_OBJC_IVAR_$_"))
638         return lldb::eSymbolTypeObjCIVar;
639     } else if (name.startswith(".objc_class_name_")) {
640       // ObjC v1
641       return lldb::eSymbolTypeObjCClass;
642     }
643   }
644   return symbol_type_hint;
645 }
646 
647 ConstString ObjectFile::GetNextSyntheticSymbolName() {
648   StreamString ss;
649   ConstString file_name = GetModule()->GetFileSpec().GetFilename();
650   ss.Printf("___lldb_unnamed_symbol%u$$%s", ++m_synthetic_symbol_idx,
651             file_name.GetCString());
652   return ConstString(ss.GetString());
653 }
654 
655 Error ObjectFile::LoadInMemory(Target &target, bool set_pc) {
656   Error error;
657   ProcessSP process = target.CalculateProcess();
658   if (!process)
659     return Error("No Process");
660   if (set_pc && !GetEntryPointAddress().IsValid())
661     return Error("No entry address in object file");
662 
663   SectionList *section_list = GetSectionList();
664   if (!section_list)
665       return Error("No section in object file");
666   size_t section_count = section_list->GetNumSections(0);
667   for (size_t i = 0; i < section_count; ++i) {
668     SectionSP section_sp = section_list->GetSectionAtIndex(i);
669     addr_t addr = target.GetSectionLoadList().GetSectionLoadAddress(section_sp);
670     if (addr != LLDB_INVALID_ADDRESS) {
671       DataExtractor section_data;
672       // We can skip sections like bss
673       if (section_sp->GetFileSize() == 0)
674         continue;
675       section_sp->GetSectionData(section_data);
676       lldb::offset_t written = process->WriteMemory(
677           addr, section_data.GetDataStart(), section_data.GetByteSize(), error);
678       if (written != section_data.GetByteSize())
679         return error;
680     }
681   }
682   if (set_pc) {
683     ThreadList &thread_list = process->GetThreadList();
684     ThreadSP curr_thread(thread_list.GetSelectedThread());
685     RegisterContextSP reg_context(curr_thread->GetRegisterContext());
686     Address file_entry = GetEntryPointAddress();
687     reg_context->SetPC(file_entry.GetLoadAddress(&target));
688   }
689   return error;
690 }
691