1254721Semaste//===-- ObjectFile.cpp ------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/lldb-private.h"
11254721Semaste#include "lldb/lldb-private-log.h"
12254721Semaste#include "lldb/Core/DataBuffer.h"
13254721Semaste#include "lldb/Core/DataBufferHeap.h"
14254721Semaste#include "lldb/Core/Log.h"
15254721Semaste#include "lldb/Core/Module.h"
16254721Semaste#include "lldb/Core/ModuleSpec.h"
17254721Semaste#include "lldb/Core/PluginManager.h"
18254721Semaste#include "lldb/Core/RegularExpression.h"
19254721Semaste#include "lldb/Core/Section.h"
20254721Semaste#include "lldb/Core/Timer.h"
21254721Semaste#include "lldb/Symbol/ObjectFile.h"
22254721Semaste#include "lldb/Symbol/ObjectContainer.h"
23254721Semaste#include "lldb/Symbol/SymbolFile.h"
24254721Semaste#include "lldb/Target/Process.h"
25254721Semaste#include "Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h"
26254721Semaste
27254721Semasteusing namespace lldb;
28254721Semasteusing namespace lldb_private;
29254721Semaste
30254721SemasteObjectFileSP
31254721SemasteObjectFile::FindPlugin (const lldb::ModuleSP &module_sp,
32254721Semaste                        const FileSpec* file,
33254721Semaste                        lldb::offset_t file_offset,
34254721Semaste                        lldb::offset_t file_size,
35254721Semaste                        DataBufferSP &data_sp,
36254721Semaste                        lldb::offset_t &data_offset)
37254721Semaste{
38254721Semaste    ObjectFileSP object_file_sp;
39254721Semaste
40254721Semaste    if (module_sp)
41254721Semaste    {
42254721Semaste        Timer scoped_timer (__PRETTY_FUNCTION__,
43254721Semaste                            "ObjectFile::FindPlugin (module = %s, file = %p, file_offset = 0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
44254721Semaste                            module_sp->GetFileSpec().GetPath().c_str(),
45254721Semaste                            file, (uint64_t) file_offset, (uint64_t) file_size);
46254721Semaste        if (file)
47254721Semaste        {
48254721Semaste            FileSpec archive_file;
49254721Semaste            ObjectContainerCreateInstance create_object_container_callback;
50254721Semaste
51254721Semaste            const bool file_exists = file->Exists();
52254721Semaste            if (!data_sp)
53254721Semaste            {
54254721Semaste                // We have an object name which most likely means we have
55254721Semaste                // a .o file in a static archive (.a file). Try and see if
56254721Semaste                // we have a cached archive first without reading any data
57254721Semaste                // first
58254721Semaste                if (file_exists && module_sp->GetObjectName())
59254721Semaste                {
60254721Semaste                    for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
61254721Semaste                    {
62254721Semaste                        std::unique_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size));
63254721Semaste
64254721Semaste                        if (object_container_ap.get())
65254721Semaste                            object_file_sp = object_container_ap->GetObjectFile(file);
66254721Semaste
67254721Semaste                        if (object_file_sp.get())
68254721Semaste                            return object_file_sp;
69254721Semaste                    }
70254721Semaste                }
71254721Semaste                // Ok, we didn't find any containers that have a named object, now
72254721Semaste                // lets read the first 512 bytes from the file so the object file
73254721Semaste                // and object container plug-ins can use these bytes to see if they
74254721Semaste                // can parse this file.
75254721Semaste                if (file_size > 0)
76254721Semaste                {
77254721Semaste                    data_sp = file->ReadFileContents(file_offset, std::min<size_t>(512, file_size));
78254721Semaste                    data_offset = 0;
79254721Semaste                }
80254721Semaste            }
81254721Semaste
82254721Semaste            if (!data_sp || data_sp->GetByteSize() == 0)
83254721Semaste            {
84254721Semaste                // Check for archive file with format "/path/to/archive.a(object.o)"
85254721Semaste                char path_with_object[PATH_MAX*2];
86254721Semaste                module_sp->GetFileSpec().GetPath(path_with_object, sizeof(path_with_object));
87254721Semaste
88254721Semaste                ConstString archive_object;
89254721Semaste                const bool must_exist = true;
90254721Semaste                if (ObjectFile::SplitArchivePathWithObject (path_with_object, archive_file, archive_object, must_exist))
91254721Semaste                {
92254721Semaste                    file_size = archive_file.GetByteSize();
93254721Semaste                    if (file_size > 0)
94254721Semaste                    {
95254721Semaste                        file = &archive_file;
96254721Semaste                        module_sp->SetFileSpecAndObjectName (archive_file, archive_object);
97254721Semaste                        // Check if this is a object container by iterating through all object
98254721Semaste                        // container plugin instances and then trying to get an object file
99254721Semaste                        // from the container plugins since we had a name. Also, don't read
100254721Semaste                        // ANY data in case there is data cached in the container plug-ins
101254721Semaste                        // (like BSD archives caching the contained objects within an file).
102254721Semaste                        for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
103254721Semaste                        {
104254721Semaste                            std::unique_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size));
105254721Semaste
106254721Semaste                            if (object_container_ap.get())
107254721Semaste                                object_file_sp = object_container_ap->GetObjectFile(file);
108254721Semaste
109254721Semaste                            if (object_file_sp.get())
110254721Semaste                                return object_file_sp;
111254721Semaste                        }
112254721Semaste                        // We failed to find any cached object files in the container
113254721Semaste                        // plug-ins, so lets read the first 512 bytes and try again below...
114254721Semaste                        data_sp = archive_file.ReadFileContents(file_offset, 512);
115254721Semaste                    }
116254721Semaste                }
117254721Semaste            }
118254721Semaste
119254721Semaste            if (data_sp && data_sp->GetByteSize() > 0)
120254721Semaste            {
121254721Semaste                // Check if this is a normal object file by iterating through
122254721Semaste                // all object file plugin instances.
123254721Semaste                ObjectFileCreateInstance create_object_file_callback;
124254721Semaste                for (uint32_t idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx)
125254721Semaste                {
126254721Semaste                    object_file_sp.reset (create_object_file_callback(module_sp, data_sp, data_offset, file, file_offset, file_size));
127254721Semaste                    if (object_file_sp.get())
128254721Semaste                        return object_file_sp;
129254721Semaste                }
130254721Semaste
131254721Semaste                // Check if this is a object container by iterating through
132254721Semaste                // all object container plugin instances and then trying to get
133254721Semaste                // an object file from the container.
134254721Semaste                for (uint32_t idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
135254721Semaste                {
136254721Semaste                    std::unique_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module_sp, data_sp, data_offset, file, file_offset, file_size));
137254721Semaste
138254721Semaste                    if (object_container_ap.get())
139254721Semaste                        object_file_sp = object_container_ap->GetObjectFile(file);
140254721Semaste
141254721Semaste                    if (object_file_sp.get())
142254721Semaste                        return object_file_sp;
143254721Semaste                }
144254721Semaste            }
145254721Semaste        }
146254721Semaste    }
147254721Semaste    // We didn't find it, so clear our shared pointer in case it
148254721Semaste    // contains anything and return an empty shared pointer
149254721Semaste    object_file_sp.reset();
150254721Semaste    return object_file_sp;
151254721Semaste}
152254721Semaste
153254721SemasteObjectFileSP
154254721SemasteObjectFile::FindPlugin (const lldb::ModuleSP &module_sp,
155254721Semaste                        const ProcessSP &process_sp,
156254721Semaste                        lldb::addr_t header_addr,
157254721Semaste                        DataBufferSP &data_sp)
158254721Semaste{
159254721Semaste    ObjectFileSP object_file_sp;
160254721Semaste
161254721Semaste    if (module_sp)
162254721Semaste    {
163254721Semaste        Timer scoped_timer (__PRETTY_FUNCTION__,
164254721Semaste                            "ObjectFile::FindPlugin (module = %s, process = %p, header_addr = 0x%" PRIx64 ")",
165254721Semaste                            module_sp->GetFileSpec().GetPath().c_str(),
166254721Semaste                            process_sp.get(), header_addr);
167254721Semaste        uint32_t idx;
168254721Semaste
169254721Semaste        // Check if this is a normal object file by iterating through
170254721Semaste        // all object file plugin instances.
171254721Semaste        ObjectFileCreateMemoryInstance create_callback;
172254721Semaste        for (idx = 0; (create_callback = PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(idx)) != NULL; ++idx)
173254721Semaste        {
174254721Semaste            object_file_sp.reset (create_callback(module_sp, data_sp, process_sp, header_addr));
175254721Semaste            if (object_file_sp.get())
176254721Semaste                return object_file_sp;
177254721Semaste        }
178254721Semaste
179254721Semaste    }
180254721Semaste    // We didn't find it, so clear our shared pointer in case it
181254721Semaste    // contains anything and return an empty shared pointer
182254721Semaste    object_file_sp.reset();
183254721Semaste    return object_file_sp;
184254721Semaste}
185254721Semaste
186254721Semastesize_t
187254721SemasteObjectFile::GetModuleSpecifications (const FileSpec &file,
188254721Semaste                                     lldb::offset_t file_offset,
189254721Semaste                                     lldb::offset_t file_size,
190254721Semaste                                     ModuleSpecList &specs)
191254721Semaste{
192254721Semaste    DataBufferSP data_sp (file.ReadFileContents(file_offset, 512));
193254721Semaste    if (data_sp)
194254721Semaste    {
195254721Semaste        if (file_size == 0)
196254721Semaste        {
197254721Semaste            const lldb::offset_t actual_file_size = file.GetByteSize();
198254721Semaste            if (actual_file_size > file_offset)
199254721Semaste                file_size = actual_file_size - file_offset;
200254721Semaste        }
201254721Semaste        return ObjectFile::GetModuleSpecifications (file,       // file spec
202254721Semaste                                                    data_sp,    // data bytes
203254721Semaste                                                    0,          // data offset
204254721Semaste                                                    file_offset,// file offset
205254721Semaste                                                    file_size,  // file length
206254721Semaste                                                    specs);
207254721Semaste    }
208254721Semaste    return 0;
209254721Semaste}
210254721Semaste
211254721Semastesize_t
212254721SemasteObjectFile::GetModuleSpecifications (const lldb_private::FileSpec& file,
213254721Semaste                                     lldb::DataBufferSP& data_sp,
214254721Semaste                                     lldb::offset_t data_offset,
215254721Semaste                                     lldb::offset_t file_offset,
216254721Semaste                                     lldb::offset_t file_size,
217254721Semaste                                     lldb_private::ModuleSpecList &specs)
218254721Semaste{
219254721Semaste    const size_t initial_count = specs.GetSize();
220254721Semaste    ObjectFileGetModuleSpecifications callback;
221254721Semaste    uint32_t i;
222254721Semaste    // Try the ObjectFile plug-ins
223254721Semaste    for (i = 0; (callback = PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex(i)) != NULL; ++i)
224254721Semaste    {
225254721Semaste        if (callback (file, data_sp, data_offset, file_offset, file_size, specs) > 0)
226254721Semaste            return specs.GetSize() - initial_count;
227254721Semaste    }
228254721Semaste
229254721Semaste    // Try the ObjectContainer plug-ins
230254721Semaste    for (i = 0; (callback = PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex(i)) != NULL; ++i)
231254721Semaste    {
232254721Semaste        if (callback (file, data_sp, data_offset, file_offset, file_size, specs) > 0)
233254721Semaste            return specs.GetSize() - initial_count;
234254721Semaste    }
235254721Semaste    return 0;
236254721Semaste}
237254721Semaste
238254721SemasteObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
239254721Semaste                        const FileSpec *file_spec_ptr,
240254721Semaste                        lldb::offset_t file_offset,
241254721Semaste                        lldb::offset_t length,
242254721Semaste                        lldb::DataBufferSP& data_sp,
243254721Semaste                        lldb::offset_t data_offset
244254721Semaste) :
245254721Semaste    ModuleChild (module_sp),
246254721Semaste    m_file (),  // This file could be different from the original module's file
247254721Semaste    m_type (eTypeInvalid),
248254721Semaste    m_strata (eStrataInvalid),
249254721Semaste    m_file_offset (file_offset),
250254721Semaste    m_length (length),
251254721Semaste    m_data (),
252254721Semaste    m_unwind_table (*this),
253254721Semaste    m_process_wp(),
254254721Semaste    m_memory_addr (LLDB_INVALID_ADDRESS),
255254721Semaste    m_sections_ap(),
256254721Semaste    m_symtab_ap ()
257254721Semaste{
258254721Semaste    if (file_spec_ptr)
259254721Semaste        m_file = *file_spec_ptr;
260254721Semaste    if (data_sp)
261254721Semaste        m_data.SetData (data_sp, data_offset, length);
262254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
263254721Semaste    if (log)
264254721Semaste    {
265254721Semaste        if (m_file)
266254721Semaste        {
267254721Semaste            log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s), file = %s, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64,
268254721Semaste                         this,
269254721Semaste                         module_sp.get(),
270254721Semaste                         module_sp->GetSpecificationDescription().c_str(),
271254721Semaste                         m_file.GetPath().c_str(),
272254721Semaste                         m_file_offset,
273254721Semaste                         m_length);
274254721Semaste        }
275254721Semaste        else
276254721Semaste        {
277254721Semaste            log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s), file = <NULL>, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64,
278254721Semaste                         this,
279254721Semaste                         module_sp.get(),
280254721Semaste                         module_sp->GetSpecificationDescription().c_str(),
281254721Semaste                         m_file_offset,
282254721Semaste                         m_length);
283254721Semaste        }
284254721Semaste    }
285254721Semaste}
286254721Semaste
287254721Semaste
288254721SemasteObjectFile::ObjectFile (const lldb::ModuleSP &module_sp,
289254721Semaste                        const ProcessSP &process_sp,
290254721Semaste                        lldb::addr_t header_addr,
291254721Semaste                        DataBufferSP& header_data_sp) :
292254721Semaste    ModuleChild (module_sp),
293254721Semaste    m_file (),
294254721Semaste    m_type (eTypeInvalid),
295254721Semaste    m_strata (eStrataInvalid),
296254721Semaste    m_file_offset (0),
297254721Semaste    m_length (0),
298254721Semaste    m_data (),
299254721Semaste    m_unwind_table (*this),
300254721Semaste    m_process_wp (process_sp),
301254721Semaste    m_memory_addr (header_addr),
302254721Semaste    m_sections_ap(),
303254721Semaste    m_symtab_ap ()
304254721Semaste{
305254721Semaste    if (header_data_sp)
306254721Semaste        m_data.SetData (header_data_sp, 0, header_data_sp->GetByteSize());
307254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
308254721Semaste    if (log)
309254721Semaste    {
310254721Semaste        log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s), process = %p, header_addr = 0x%" PRIx64,
311254721Semaste                     this,
312254721Semaste                     module_sp.get(),
313254721Semaste                     module_sp->GetSpecificationDescription().c_str(),
314254721Semaste                     process_sp.get(),
315254721Semaste                     m_memory_addr);
316254721Semaste    }
317254721Semaste}
318254721Semaste
319254721Semaste
320254721SemasteObjectFile::~ObjectFile()
321254721Semaste{
322254721Semaste    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
323254721Semaste    if (log)
324254721Semaste        log->Printf ("%p ObjectFile::~ObjectFile ()\n", this);
325254721Semaste}
326254721Semaste
327254721Semastebool
328254721SemasteObjectFile::SetModulesArchitecture (const ArchSpec &new_arch)
329254721Semaste{
330254721Semaste    ModuleSP module_sp (GetModule());
331254721Semaste    if (module_sp)
332254721Semaste        return module_sp->SetArchitecture (new_arch);
333254721Semaste    return false;
334254721Semaste}
335254721Semaste
336254721SemasteAddressClass
337254721SemasteObjectFile::GetAddressClass (addr_t file_addr)
338254721Semaste{
339254721Semaste    Symtab *symtab = GetSymtab();
340254721Semaste    if (symtab)
341254721Semaste    {
342254721Semaste        Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
343254721Semaste        if (symbol)
344254721Semaste        {
345254721Semaste            if (symbol->ValueIsAddress())
346254721Semaste            {
347254721Semaste                const SectionSP section_sp (symbol->GetAddress().GetSection());
348254721Semaste                if (section_sp)
349254721Semaste                {
350254721Semaste                    const SectionType section_type = section_sp->GetType();
351254721Semaste                    switch (section_type)
352254721Semaste                    {
353254721Semaste                    case eSectionTypeInvalid:               return eAddressClassUnknown;
354254721Semaste                    case eSectionTypeCode:                  return eAddressClassCode;
355254721Semaste                    case eSectionTypeContainer:             return eAddressClassUnknown;
356254721Semaste                    case eSectionTypeData:
357254721Semaste                    case eSectionTypeDataCString:
358254721Semaste                    case eSectionTypeDataCStringPointers:
359254721Semaste                    case eSectionTypeDataSymbolAddress:
360254721Semaste                    case eSectionTypeData4:
361254721Semaste                    case eSectionTypeData8:
362254721Semaste                    case eSectionTypeData16:
363254721Semaste                    case eSectionTypeDataPointers:
364254721Semaste                    case eSectionTypeZeroFill:
365254721Semaste                    case eSectionTypeDataObjCMessageRefs:
366254721Semaste                    case eSectionTypeDataObjCCFStrings:
367254721Semaste                        return eAddressClassData;
368254721Semaste                    case eSectionTypeDebug:
369254721Semaste                    case eSectionTypeDWARFDebugAbbrev:
370254721Semaste                    case eSectionTypeDWARFDebugAranges:
371254721Semaste                    case eSectionTypeDWARFDebugFrame:
372254721Semaste                    case eSectionTypeDWARFDebugInfo:
373254721Semaste                    case eSectionTypeDWARFDebugLine:
374254721Semaste                    case eSectionTypeDWARFDebugLoc:
375254721Semaste                    case eSectionTypeDWARFDebugMacInfo:
376254721Semaste                    case eSectionTypeDWARFDebugPubNames:
377254721Semaste                    case eSectionTypeDWARFDebugPubTypes:
378254721Semaste                    case eSectionTypeDWARFDebugRanges:
379254721Semaste                    case eSectionTypeDWARFDebugStr:
380254721Semaste                    case eSectionTypeDWARFAppleNames:
381254721Semaste                    case eSectionTypeDWARFAppleTypes:
382254721Semaste                    case eSectionTypeDWARFAppleNamespaces:
383254721Semaste                    case eSectionTypeDWARFAppleObjC:
384254721Semaste                        return eAddressClassDebug;
385254721Semaste                    case eSectionTypeEHFrame:               return eAddressClassRuntime;
386254721Semaste                    case eSectionTypeELFSymbolTable:
387254721Semaste                    case eSectionTypeELFDynamicSymbols:
388254721Semaste                    case eSectionTypeELFRelocationEntries:
389254721Semaste                    case eSectionTypeELFDynamicLinkInfo:
390254721Semaste                    case eSectionTypeOther:                 return eAddressClassUnknown;
391254721Semaste                    }
392254721Semaste                }
393254721Semaste            }
394254721Semaste
395254721Semaste            const SymbolType symbol_type = symbol->GetType();
396254721Semaste            switch (symbol_type)
397254721Semaste            {
398254721Semaste            case eSymbolTypeAny:            return eAddressClassUnknown;
399254721Semaste            case eSymbolTypeAbsolute:       return eAddressClassUnknown;
400254721Semaste            case eSymbolTypeCode:           return eAddressClassCode;
401254721Semaste            case eSymbolTypeTrampoline:     return eAddressClassCode;
402254721Semaste            case eSymbolTypeResolver:       return eAddressClassCode;
403254721Semaste            case eSymbolTypeData:           return eAddressClassData;
404254721Semaste            case eSymbolTypeRuntime:        return eAddressClassRuntime;
405254721Semaste            case eSymbolTypeException:      return eAddressClassRuntime;
406254721Semaste            case eSymbolTypeSourceFile:     return eAddressClassDebug;
407254721Semaste            case eSymbolTypeHeaderFile:     return eAddressClassDebug;
408254721Semaste            case eSymbolTypeObjectFile:     return eAddressClassDebug;
409254721Semaste            case eSymbolTypeCommonBlock:    return eAddressClassDebug;
410254721Semaste            case eSymbolTypeBlock:          return eAddressClassDebug;
411254721Semaste            case eSymbolTypeLocal:          return eAddressClassData;
412254721Semaste            case eSymbolTypeParam:          return eAddressClassData;
413254721Semaste            case eSymbolTypeVariable:       return eAddressClassData;
414254721Semaste            case eSymbolTypeVariableType:   return eAddressClassDebug;
415254721Semaste            case eSymbolTypeLineEntry:      return eAddressClassDebug;
416254721Semaste            case eSymbolTypeLineHeader:     return eAddressClassDebug;
417254721Semaste            case eSymbolTypeScopeBegin:     return eAddressClassDebug;
418254721Semaste            case eSymbolTypeScopeEnd:       return eAddressClassDebug;
419254721Semaste            case eSymbolTypeAdditional:     return eAddressClassUnknown;
420254721Semaste            case eSymbolTypeCompiler:       return eAddressClassDebug;
421254721Semaste            case eSymbolTypeInstrumentation:return eAddressClassDebug;
422254721Semaste            case eSymbolTypeUndefined:      return eAddressClassUnknown;
423254721Semaste            case eSymbolTypeObjCClass:      return eAddressClassRuntime;
424254721Semaste            case eSymbolTypeObjCMetaClass:  return eAddressClassRuntime;
425254721Semaste            case eSymbolTypeObjCIVar:       return eAddressClassRuntime;
426263363Semaste            case eSymbolTypeReExported:     return eAddressClassRuntime;
427254721Semaste            }
428254721Semaste        }
429254721Semaste    }
430254721Semaste    return eAddressClassUnknown;
431254721Semaste}
432254721Semaste
433254721SemasteDataBufferSP
434254721SemasteObjectFile::ReadMemory (const ProcessSP &process_sp, lldb::addr_t addr, size_t byte_size)
435254721Semaste{
436254721Semaste    DataBufferSP data_sp;
437254721Semaste    if (process_sp)
438254721Semaste    {
439254721Semaste        std::unique_ptr<DataBufferHeap> data_ap (new DataBufferHeap (byte_size, 0));
440254721Semaste        Error error;
441254721Semaste        const size_t bytes_read = process_sp->ReadMemory (addr,
442254721Semaste                                                          data_ap->GetBytes(),
443254721Semaste                                                          data_ap->GetByteSize(),
444254721Semaste                                                          error);
445254721Semaste        if (bytes_read == byte_size)
446254721Semaste            data_sp.reset (data_ap.release());
447254721Semaste    }
448254721Semaste    return data_sp;
449254721Semaste}
450254721Semaste
451254721Semastesize_t
452254721SemasteObjectFile::GetData (off_t offset, size_t length, DataExtractor &data) const
453254721Semaste{
454254721Semaste    // The entire file has already been mmap'ed into m_data, so just copy from there
455254721Semaste    // as the back mmap buffer will be shared with shared pointers.
456254721Semaste    return data.SetData (m_data, offset, length);
457254721Semaste}
458254721Semaste
459254721Semastesize_t
460254721SemasteObjectFile::CopyData (off_t offset, size_t length, void *dst) const
461254721Semaste{
462254721Semaste    // The entire file has already been mmap'ed into m_data, so just copy from there
463263363Semaste    // Note that the data remains in target byte order.
464263363Semaste    return m_data.CopyData (offset, length, dst);
465254721Semaste}
466254721Semaste
467254721Semaste
468254721Semastesize_t
469254721SemasteObjectFile::ReadSectionData (const Section *section, off_t section_offset, void *dst, size_t dst_len) const
470254721Semaste{
471254721Semaste    // If some other objectfile owns this data, pass this to them.
472254721Semaste    if (section->GetObjectFile() != this)
473254721Semaste        return section->GetObjectFile()->ReadSectionData (section, section_offset, dst, dst_len);
474254721Semaste
475254721Semaste    if (IsInMemory())
476254721Semaste    {
477254721Semaste        ProcessSP process_sp (m_process_wp.lock());
478254721Semaste        if (process_sp)
479254721Semaste        {
480254721Semaste            Error error;
481254721Semaste            const addr_t base_load_addr = section->GetLoadBaseAddress (&process_sp->GetTarget());
482254721Semaste            if (base_load_addr != LLDB_INVALID_ADDRESS)
483254721Semaste                return process_sp->ReadMemory (base_load_addr + section_offset, dst, dst_len, error);
484254721Semaste        }
485254721Semaste    }
486254721Semaste    else
487254721Semaste    {
488254721Semaste        const uint64_t section_file_size = section->GetFileSize();
489254721Semaste        if (section_offset < section_file_size)
490254721Semaste        {
491254721Semaste            const uint64_t section_bytes_left = section_file_size - section_offset;
492254721Semaste            uint64_t section_dst_len = dst_len;
493254721Semaste            if (section_dst_len > section_bytes_left)
494254721Semaste                section_dst_len = section_bytes_left;
495254721Semaste            return CopyData (section->GetFileOffset() + section_offset, section_dst_len, dst);
496254721Semaste        }
497254721Semaste        else
498254721Semaste        {
499254721Semaste            if (section->GetType() == eSectionTypeZeroFill)
500254721Semaste            {
501254721Semaste                const uint64_t section_size = section->GetByteSize();
502254721Semaste                const uint64_t section_bytes_left = section_size - section_offset;
503254721Semaste                uint64_t section_dst_len = dst_len;
504254721Semaste                if (section_dst_len > section_bytes_left)
505254721Semaste                    section_dst_len = section_bytes_left;
506263363Semaste                memset(dst, 0, section_dst_len);
507254721Semaste                return section_dst_len;
508254721Semaste            }
509254721Semaste        }
510254721Semaste    }
511254721Semaste    return 0;
512254721Semaste}
513254721Semaste
514254721Semaste//----------------------------------------------------------------------
515254721Semaste// Get the section data the file on disk
516254721Semaste//----------------------------------------------------------------------
517254721Semastesize_t
518254721SemasteObjectFile::ReadSectionData (const Section *section, DataExtractor& section_data) const
519254721Semaste{
520254721Semaste    // If some other objectfile owns this data, pass this to them.
521254721Semaste    if (section->GetObjectFile() != this)
522254721Semaste        return section->GetObjectFile()->ReadSectionData (section, section_data);
523254721Semaste
524254721Semaste    if (IsInMemory())
525254721Semaste    {
526254721Semaste        ProcessSP process_sp (m_process_wp.lock());
527254721Semaste        if (process_sp)
528254721Semaste        {
529254721Semaste            const addr_t base_load_addr = section->GetLoadBaseAddress (&process_sp->GetTarget());
530254721Semaste            if (base_load_addr != LLDB_INVALID_ADDRESS)
531254721Semaste            {
532254721Semaste                DataBufferSP data_sp (ReadMemory (process_sp, base_load_addr, section->GetByteSize()));
533254721Semaste                if (data_sp)
534254721Semaste                {
535254721Semaste                    section_data.SetData (data_sp, 0, data_sp->GetByteSize());
536254721Semaste                    section_data.SetByteOrder (process_sp->GetByteOrder());
537254721Semaste                    section_data.SetAddressByteSize (process_sp->GetAddressByteSize());
538254721Semaste                    return section_data.GetByteSize();
539254721Semaste                }
540254721Semaste            }
541254721Semaste        }
542254721Semaste    }
543254721Semaste    else
544254721Semaste    {
545254721Semaste        // The object file now contains a full mmap'ed copy of the object file data, so just use this
546254721Semaste        return MemoryMapSectionData (section, section_data);
547254721Semaste    }
548254721Semaste    section_data.Clear();
549254721Semaste    return 0;
550254721Semaste}
551254721Semaste
552254721Semastesize_t
553254721SemasteObjectFile::MemoryMapSectionData (const Section *section, DataExtractor& section_data) const
554254721Semaste{
555254721Semaste    // If some other objectfile owns this data, pass this to them.
556254721Semaste    if (section->GetObjectFile() != this)
557254721Semaste        return section->GetObjectFile()->MemoryMapSectionData (section, section_data);
558254721Semaste
559254721Semaste    if (IsInMemory())
560254721Semaste    {
561254721Semaste        return ReadSectionData (section, section_data);
562254721Semaste    }
563254721Semaste    else
564254721Semaste    {
565254721Semaste        // The object file now contains a full mmap'ed copy of the object file data, so just use this
566254721Semaste        return GetData(section->GetFileOffset(), section->GetFileSize(), section_data);
567254721Semaste    }
568254721Semaste    section_data.Clear();
569254721Semaste    return 0;
570254721Semaste}
571254721Semaste
572254721Semaste
573254721Semastebool
574254721SemasteObjectFile::SplitArchivePathWithObject (const char *path_with_object, FileSpec &archive_file, ConstString &archive_object, bool must_exist)
575254721Semaste{
576254721Semaste    RegularExpression g_object_regex("(.*)\\(([^\\)]+)\\)$");
577254721Semaste    RegularExpression::Match regex_match(2);
578254721Semaste    if (g_object_regex.Execute (path_with_object, &regex_match))
579254721Semaste    {
580254721Semaste        std::string path;
581254721Semaste        std::string obj;
582254721Semaste        if (regex_match.GetMatchAtIndex (path_with_object, 1, path) &&
583254721Semaste            regex_match.GetMatchAtIndex (path_with_object, 2, obj))
584254721Semaste        {
585254721Semaste            archive_file.SetFile (path.c_str(), false);
586254721Semaste            archive_object.SetCString(obj.c_str());
587254721Semaste            if (must_exist && !archive_file.Exists())
588254721Semaste                return false;
589254721Semaste            return true;
590254721Semaste        }
591254721Semaste    }
592254721Semaste    return false;
593254721Semaste}
594254721Semaste
595254721Semastevoid
596254721SemasteObjectFile::ClearSymtab ()
597254721Semaste{
598254721Semaste    ModuleSP module_sp(GetModule());
599254721Semaste    if (module_sp)
600254721Semaste    {
601254721Semaste        lldb_private::Mutex::Locker locker(module_sp->GetMutex());
602254721Semaste        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
603254721Semaste        if (log)
604254721Semaste        {
605254721Semaste            log->Printf ("%p ObjectFile::ClearSymtab () symtab = %p",
606254721Semaste                         this,
607254721Semaste                         m_symtab_ap.get());
608254721Semaste        }
609254721Semaste        m_symtab_ap.reset();
610254721Semaste    }
611254721Semaste}
612254721Semaste
613254721SemasteSectionList *
614254721SemasteObjectFile::GetSectionList()
615254721Semaste{
616254721Semaste    if (m_sections_ap.get() == NULL)
617254721Semaste    {
618254721Semaste        ModuleSP module_sp(GetModule());
619254721Semaste        if (module_sp)
620254721Semaste            CreateSections(*module_sp->GetUnifiedSectionList());
621254721Semaste    }
622254721Semaste    return m_sections_ap.get();
623254721Semaste}
624