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 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 ObjectFile*
23 ObjectFile::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 
99 bool
100 ObjectFile::SetModulesArchitecture (const ArchSpec &new_arch)
101 {
102     return m_module->SetArchitecture (new_arch);
103 }
104 
105 AddressClass
106 ObjectFile::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 eSectionTypeEHFrame:               return eAddressClassRuntime;
150                     case eSectionTypeOther:                 return eAddressClassUnknown;
151                     }
152                 }
153             }
154 
155             const SymbolType symbol_type = symbol->GetType();
156             switch (symbol_type)
157             {
158             case eSymbolTypeAny:            return eAddressClassUnknown;
159             case eSymbolTypeAbsolute:       return eAddressClassUnknown;
160             case eSymbolTypeExtern:         return eAddressClassUnknown;
161             case eSymbolTypeCode:           return eAddressClassCode;
162             case eSymbolTypeTrampoline:     return eAddressClassCode;
163             case eSymbolTypeData:           return eAddressClassData;
164             case eSymbolTypeRuntime:        return eAddressClassRuntime;
165             case eSymbolTypeException:      return eAddressClassRuntime;
166             case eSymbolTypeSourceFile:     return eAddressClassDebug;
167             case eSymbolTypeHeaderFile:     return eAddressClassDebug;
168             case eSymbolTypeObjectFile:     return eAddressClassDebug;
169             case eSymbolTypeCommonBlock:    return eAddressClassDebug;
170             case eSymbolTypeBlock:          return eAddressClassDebug;
171             case eSymbolTypeLocal:          return eAddressClassData;
172             case eSymbolTypeParam:          return eAddressClassData;
173             case eSymbolTypeVariable:       return eAddressClassData;
174             case eSymbolTypeVariableType:   return eAddressClassDebug;
175             case eSymbolTypeLineEntry:      return eAddressClassDebug;
176             case eSymbolTypeLineHeader:     return eAddressClassDebug;
177             case eSymbolTypeScopeBegin:     return eAddressClassDebug;
178             case eSymbolTypeScopeEnd:       return eAddressClassDebug;
179             case eSymbolTypeAdditional:     return eAddressClassUnknown;
180             case eSymbolTypeCompiler:       return eAddressClassDebug;
181             case eSymbolTypeInstrumentation:return eAddressClassDebug;
182             case eSymbolTypeUndefined:      return eAddressClassUnknown;
183             }
184         }
185     }
186     return eAddressClassUnknown;
187 }
188 
189 
190