ObjectFile.cpp revision c8cf5e234be554d4acb6ae644a8269c303c4f56e
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/lldb-private.h"
11#include "lldb/Core/Module.h"
12#include "lldb/Core/PluginManager.h"
13#include "lldb/Core/RegularExpression.h"
14#include "lldb/Core/Timer.h"
15#include "lldb/Symbol/ObjectFile.h"
16#include "lldb/Symbol/ObjectContainer.h"
17#include "lldb/Symbol/SymbolFile.h"
18
19using namespace lldb;
20using namespace lldb_private;
21
22ObjectFile*
23ObjectFile::FindPlugin (Module* module, const FileSpec* file, lldb::addr_t file_offset, lldb::addr_t file_size)
24{
25    Timer scoped_timer (__PRETTY_FUNCTION__,
26                        "ObjectFile::FindPlugin (module = %s/%s, file = %p, file_offset = 0x%z8.8x, file_size = 0x%z8.8x)",
27                        module->GetFileSpec().GetDirectory().AsCString(),
28                        module->GetFileSpec().GetFilename().AsCString(),
29                        file, file_offset, file_size);
30    std::auto_ptr<ObjectFile> object_file_ap;
31
32    if (module != NULL)
33    {
34        if (file)
35        {
36            if (file_size == 0)
37                file_size = file->GetByteSize();
38
39            if (file_size == 0)
40            {
41                // Check for archive file with format "/path/to/archive.a(object.o)"
42                char path_with_object[PATH_MAX*2];
43                module->GetFileSpec().GetPath(path_with_object, sizeof(path_with_object));
44
45                RegularExpression g_object_regex("(.*)\\(([^\\)]+)\\)$");
46                if (g_object_regex.Execute (path_with_object, 2))
47                {
48                    FileSpec archive_file;
49                    std::string path;
50                    std::string object;
51                    if (g_object_regex.GetMatchAtIndex (path_with_object, 1, path) &&
52                        g_object_regex.GetMatchAtIndex (path_with_object, 2, object))
53                    {
54                        archive_file.SetFile (path.c_str(), false);
55                        file_size = archive_file.GetByteSize();
56                        if (file_size > 0)
57                            module->SetFileSpecAndObjectName (archive_file, ConstString(object.c_str()));
58                    }
59                }
60            }
61
62            // No need to delegate further if (file_offset, file_size) exceeds the total file size.
63            // This is the base case.
64//            if (file_offset + file_size > file->GetByteSize())
65//                return NULL;
66
67            DataBufferSP file_header_data_sp(file->ReadFileContents(file_offset, 512));
68            uint32_t idx;
69
70            // Check if this is a normal object file by iterating through
71            // all object file plugin instances.
72            ObjectFileCreateInstance create_object_file_callback;
73            for (idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx)
74            {
75                object_file_ap.reset (create_object_file_callback(module, file_header_data_sp, file, file_offset, file_size));
76                if (object_file_ap.get())
77                    return object_file_ap.release();
78            }
79
80            // Check if this is a object container by iterating through
81            // all object container plugin instances and then trying to get
82            // an object file from the container.
83            ObjectContainerCreateInstance create_object_container_callback;
84            for (idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
85            {
86                std::auto_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module, file_header_data_sp, file, file_offset, file_size));
87
88                if (object_container_ap.get())
89                    object_file_ap.reset (object_container_ap->GetObjectFile(file));
90
91                if (object_file_ap.get())
92                    return object_file_ap.release();
93            }
94        }
95    }
96    return NULL;
97}
98
99bool
100ObjectFile::SetModulesArchitecture (const ArchSpec &new_arch)
101{
102    return m_module->SetArchitecture (new_arch);
103}
104
105AddressClass
106ObjectFile::GetAddressClass (lldb::addr_t file_addr)
107{
108    Symtab *symtab = GetSymtab();
109    if (symtab)
110    {
111        Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
112        if (symbol)
113        {
114            const AddressRange *range_ptr = symbol->GetAddressRangePtr();
115            if (range_ptr)
116            {
117                const Section *section = range_ptr->GetBaseAddress().GetSection();
118                if (section)
119                {
120                    const SectionType section_type = section->GetType();
121                    switch (section_type)
122                    {
123                    case eSectionTypeInvalid:               return eAddressClassUnknown;
124                    case eSectionTypeCode:                  return eAddressClassCode;
125                    case eSectionTypeContainer:             return eAddressClassUnknown;
126                    case eSectionTypeData:                  return eAddressClassData;
127                    case eSectionTypeDataCString:           return eAddressClassData;
128                    case eSectionTypeDataCStringPointers:   return eAddressClassData;
129                    case eSectionTypeDataSymbolAddress:     return eAddressClassData;
130                    case eSectionTypeData4:                 return eAddressClassData;
131                    case eSectionTypeData8:                 return eAddressClassData;
132                    case eSectionTypeData16:                return eAddressClassData;
133                    case eSectionTypeDataPointers:          return eAddressClassData;
134                    case eSectionTypeZeroFill:              return eAddressClassData;
135                    case eSectionTypeDataObjCMessageRefs:   return eAddressClassData;
136                    case eSectionTypeDataObjCCFStrings:     return eAddressClassData;
137                    case eSectionTypeDebug:                 return eAddressClassDebug;
138                    case eSectionTypeDWARFDebugAbbrev:      return eAddressClassDebug;
139                    case eSectionTypeDWARFDebugAranges:     return eAddressClassDebug;
140                    case eSectionTypeDWARFDebugFrame:       return eAddressClassDebug;
141                    case eSectionTypeDWARFDebugInfo:        return eAddressClassDebug;
142                    case eSectionTypeDWARFDebugLine:        return eAddressClassDebug;
143                    case eSectionTypeDWARFDebugLoc:         return eAddressClassDebug;
144                    case eSectionTypeDWARFDebugMacInfo:     return eAddressClassDebug;
145                    case eSectionTypeDWARFDebugPubNames:    return eAddressClassDebug;
146                    case eSectionTypeDWARFDebugPubTypes:    return eAddressClassDebug;
147                    case eSectionTypeDWARFDebugRanges:      return eAddressClassDebug;
148                    case eSectionTypeDWARFDebugStr:         return eAddressClassDebug;
149                    case eSectionTypeDWARFDebugNames:       return eAddressClassDebug;
150                    case eSectionTypeDWARFDebugTypes:       return eAddressClassDebug;
151                    case eSectionTypeEHFrame:               return eAddressClassRuntime;
152                    case eSectionTypeOther:                 return eAddressClassUnknown;
153                    }
154                }
155            }
156
157            const SymbolType symbol_type = symbol->GetType();
158            switch (symbol_type)
159            {
160            case eSymbolTypeAny:            return eAddressClassUnknown;
161            case eSymbolTypeAbsolute:       return eAddressClassUnknown;
162            case eSymbolTypeExtern:         return eAddressClassUnknown;
163            case eSymbolTypeCode:           return eAddressClassCode;
164            case eSymbolTypeTrampoline:     return eAddressClassCode;
165            case eSymbolTypeData:           return eAddressClassData;
166            case eSymbolTypeRuntime:        return eAddressClassRuntime;
167            case eSymbolTypeException:      return eAddressClassRuntime;
168            case eSymbolTypeSourceFile:     return eAddressClassDebug;
169            case eSymbolTypeHeaderFile:     return eAddressClassDebug;
170            case eSymbolTypeObjectFile:     return eAddressClassDebug;
171            case eSymbolTypeCommonBlock:    return eAddressClassDebug;
172            case eSymbolTypeBlock:          return eAddressClassDebug;
173            case eSymbolTypeLocal:          return eAddressClassData;
174            case eSymbolTypeParam:          return eAddressClassData;
175            case eSymbolTypeVariable:       return eAddressClassData;
176            case eSymbolTypeVariableType:   return eAddressClassDebug;
177            case eSymbolTypeLineEntry:      return eAddressClassDebug;
178            case eSymbolTypeLineHeader:     return eAddressClassDebug;
179            case eSymbolTypeScopeBegin:     return eAddressClassDebug;
180            case eSymbolTypeScopeEnd:       return eAddressClassDebug;
181            case eSymbolTypeAdditional:     return eAddressClassUnknown;
182            case eSymbolTypeCompiler:       return eAddressClassDebug;
183            case eSymbolTypeInstrumentation:return eAddressClassDebug;
184            case eSymbolTypeUndefined:      return eAddressClassUnknown;
185            }
186        }
187    }
188    return eAddressClassUnknown;
189}
190
191
192