130fdc8d8SChris Lattner //===-- ObjectFile.cpp ------------------------------------------*- C++ -*-===//
230fdc8d8SChris Lattner //
330fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
430fdc8d8SChris Lattner //
530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
630fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
730fdc8d8SChris Lattner //
830fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
930fdc8d8SChris Lattner 
1030fdc8d8SChris Lattner #include "lldb/lldb-private.h"
1130fdc8d8SChris Lattner #include "lldb/Core/Module.h"
1230fdc8d8SChris Lattner #include "lldb/Core/PluginManager.h"
1330fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h"
1430fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
1530fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h"
1630fdc8d8SChris Lattner #include "lldb/Symbol/ObjectContainer.h"
1730fdc8d8SChris Lattner #include "lldb/Symbol/SymbolFile.h"
1830fdc8d8SChris Lattner 
1930fdc8d8SChris Lattner using namespace lldb;
2030fdc8d8SChris Lattner using namespace lldb_private;
2130fdc8d8SChris Lattner 
2230fdc8d8SChris Lattner ObjectFile*
2330fdc8d8SChris Lattner ObjectFile::FindPlugin (Module* module, const FileSpec* file, lldb::addr_t file_offset, lldb::addr_t file_size)
2430fdc8d8SChris Lattner {
2530fdc8d8SChris Lattner     Timer scoped_timer (__PRETTY_FUNCTION__,
2630fdc8d8SChris Lattner                         "ObjectFile::FindPlugin (module = %s/%s, file = %p, file_offset = 0x%z8.8x, file_size = 0x%z8.8x)",
2730fdc8d8SChris Lattner                         module->GetFileSpec().GetDirectory().AsCString(),
2830fdc8d8SChris Lattner                         module->GetFileSpec().GetFilename().AsCString(),
2930fdc8d8SChris Lattner                         file, file_offset, file_size);
3030fdc8d8SChris Lattner     std::auto_ptr<ObjectFile> object_file_ap;
3130fdc8d8SChris Lattner 
3230fdc8d8SChris Lattner     if (module != NULL)
3330fdc8d8SChris Lattner     {
3430fdc8d8SChris Lattner         if (file)
3530fdc8d8SChris Lattner         {
3630fdc8d8SChris Lattner             if (file_size == 0)
3730fdc8d8SChris Lattner                 file_size = file->GetByteSize();
3830fdc8d8SChris Lattner 
3930fdc8d8SChris Lattner             if (file_size == 0)
4030fdc8d8SChris Lattner             {
4130fdc8d8SChris Lattner                 // Check for archive file with format "/path/to/archive.a(object.o)"
4230fdc8d8SChris Lattner                 char path_with_object[PATH_MAX*2];
4330fdc8d8SChris Lattner                 module->GetFileSpec().GetPath(path_with_object, sizeof(path_with_object));
4430fdc8d8SChris Lattner 
4530fdc8d8SChris Lattner                 RegularExpression g_object_regex("(.*)\\(([^\\)]+)\\)$");
4630fdc8d8SChris Lattner                 if (g_object_regex.Execute (path_with_object, 2))
4730fdc8d8SChris Lattner                 {
4830fdc8d8SChris Lattner                     FileSpec archive_file;
4930fdc8d8SChris Lattner                     std::string path;
5030fdc8d8SChris Lattner                     std::string object;
5130fdc8d8SChris Lattner                     if (g_object_regex.GetMatchAtIndex (path_with_object, 1, path) &&
5230fdc8d8SChris Lattner                         g_object_regex.GetMatchAtIndex (path_with_object, 2, object))
5330fdc8d8SChris Lattner                     {
54274060b6SGreg Clayton                         archive_file.SetFile (path.c_str(), false);
5530fdc8d8SChris Lattner                         file_size = archive_file.GetByteSize();
5630fdc8d8SChris Lattner                         if (file_size > 0)
5730fdc8d8SChris Lattner                             module->SetFileSpecAndObjectName (archive_file, ConstString(object.c_str()));
5830fdc8d8SChris Lattner                     }
5930fdc8d8SChris Lattner                 }
6030fdc8d8SChris Lattner             }
6130fdc8d8SChris Lattner 
6276c381b6SJohnny Chen             // No need to delegate further if (file_offset, file_size) exceeds the total file size.
6376c381b6SJohnny Chen             // This is the base case.
6476c381b6SJohnny Chen             if (file_offset + file_size > file->GetByteSize())
6576c381b6SJohnny Chen                 return NULL;
6676c381b6SJohnny Chen 
6730fdc8d8SChris Lattner             DataBufferSP file_header_data_sp(file->ReadFileContents(file_offset, 512));
6830fdc8d8SChris Lattner             uint32_t idx;
6930fdc8d8SChris Lattner 
7030fdc8d8SChris Lattner             // Check if this is a normal object file by iterating through
7130fdc8d8SChris Lattner             // all object file plugin instances.
7230fdc8d8SChris Lattner             ObjectFileCreateInstance create_object_file_callback;
7330fdc8d8SChris Lattner             for (idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx)
7430fdc8d8SChris Lattner             {
7530fdc8d8SChris Lattner                 object_file_ap.reset (create_object_file_callback(module, file_header_data_sp, file, file_offset, file_size));
7630fdc8d8SChris Lattner                 if (object_file_ap.get())
7730fdc8d8SChris Lattner                     return object_file_ap.release();
7830fdc8d8SChris Lattner             }
7930fdc8d8SChris Lattner 
8030fdc8d8SChris Lattner             // Check if this is a object container by iterating through
8130fdc8d8SChris Lattner             // all object container plugin instances and then trying to get
8230fdc8d8SChris Lattner             // an object file from the container.
8330fdc8d8SChris Lattner             ObjectContainerCreateInstance create_object_container_callback;
8430fdc8d8SChris Lattner             for (idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
8530fdc8d8SChris Lattner             {
8630fdc8d8SChris Lattner                 std::auto_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module, file_header_data_sp, file, file_offset, file_size));
8730fdc8d8SChris Lattner 
8830fdc8d8SChris Lattner                 if (object_container_ap.get())
8930fdc8d8SChris Lattner                     object_file_ap.reset (object_container_ap->GetObjectFile(file));
9030fdc8d8SChris Lattner 
9130fdc8d8SChris Lattner                 if (object_file_ap.get())
9230fdc8d8SChris Lattner                     return object_file_ap.release();
9330fdc8d8SChris Lattner             }
9430fdc8d8SChris Lattner         }
9530fdc8d8SChris Lattner     }
9630fdc8d8SChris Lattner     return NULL;
9730fdc8d8SChris Lattner }
985aee162fSJim Ingham 
995aee162fSJim Ingham bool
1005aee162fSJim Ingham ObjectFile::SetModulesArchitecture (const ArchSpec &new_arch)
1015aee162fSJim Ingham {
1025aee162fSJim Ingham     return m_module->SetArchitecture (new_arch);
1035aee162fSJim Ingham }
1045aee162fSJim Ingham 
105*ded470d3SGreg Clayton lldb::AddressClass
106*ded470d3SGreg Clayton ObjectFile::GetAddressClass (lldb::addr_t file_addr)
107*ded470d3SGreg Clayton {
108*ded470d3SGreg Clayton     Symtab *symtab = GetSymtab();
109*ded470d3SGreg Clayton     if (symtab)
110*ded470d3SGreg Clayton     {
111*ded470d3SGreg Clayton         Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
112*ded470d3SGreg Clayton         if (symbol)
113*ded470d3SGreg Clayton         {
114*ded470d3SGreg Clayton             const AddressRange *range_ptr = symbol->GetAddressRangePtr();
115*ded470d3SGreg Clayton             if (range_ptr)
116*ded470d3SGreg Clayton             {
117*ded470d3SGreg Clayton                 const Section *section = range_ptr->GetBaseAddress().GetSection();
118*ded470d3SGreg Clayton                 if (section)
119*ded470d3SGreg Clayton                 {
120*ded470d3SGreg Clayton                     const lldb::SectionType section_type = section->GetType();
121*ded470d3SGreg Clayton                     switch (section_type)
122*ded470d3SGreg Clayton                     {
123*ded470d3SGreg Clayton                     case eSectionTypeInvalid:               return eAddressClassUnknown;
124*ded470d3SGreg Clayton                     case eSectionTypeCode:                  return eAddressClassCode;
125*ded470d3SGreg Clayton                     case eSectionTypeContainer:             return eAddressClassUnknown;
126*ded470d3SGreg Clayton                     case eSectionTypeData:                  return eAddressClassData;
127*ded470d3SGreg Clayton                     case eSectionTypeDataCString:           return eAddressClassDataConst;
128*ded470d3SGreg Clayton                     case eSectionTypeDataCStringPointers:   return eAddressClassData;
129*ded470d3SGreg Clayton                     case eSectionTypeDataSymbolAddress:     return eAddressClassData;
130*ded470d3SGreg Clayton                     case eSectionTypeData4:                 return eAddressClassData;
131*ded470d3SGreg Clayton                     case eSectionTypeData8:                 return eAddressClassData;
132*ded470d3SGreg Clayton                     case eSectionTypeData16:                return eAddressClassData;
133*ded470d3SGreg Clayton                     case eSectionTypeDataPointers:          return eAddressClassData;
134*ded470d3SGreg Clayton                     case eSectionTypeZeroFill:              return eAddressClassData;
135*ded470d3SGreg Clayton                     case eSectionTypeDataObjCMessageRefs:   return eAddressClassDataConst;
136*ded470d3SGreg Clayton                     case eSectionTypeDataObjCCFStrings:     return eAddressClassDataConst;
137*ded470d3SGreg Clayton                     case eSectionTypeDebug:                 return eAddressClassDebug;
138*ded470d3SGreg Clayton                     case eSectionTypeDWARFDebugAbbrev:      return eAddressClassDebug;
139*ded470d3SGreg Clayton                     case eSectionTypeDWARFDebugAranges:     return eAddressClassDebug;
140*ded470d3SGreg Clayton                     case eSectionTypeDWARFDebugFrame:       return eAddressClassDebug;
141*ded470d3SGreg Clayton                     case eSectionTypeDWARFDebugInfo:        return eAddressClassDebug;
142*ded470d3SGreg Clayton                     case eSectionTypeDWARFDebugLine:        return eAddressClassDebug;
143*ded470d3SGreg Clayton                     case eSectionTypeDWARFDebugLoc:         return eAddressClassDebug;
144*ded470d3SGreg Clayton                     case eSectionTypeDWARFDebugMacInfo:     return eAddressClassDebug;
145*ded470d3SGreg Clayton                     case eSectionTypeDWARFDebugPubNames:    return eAddressClassDebug;
146*ded470d3SGreg Clayton                     case eSectionTypeDWARFDebugPubTypes:    return eAddressClassDebug;
147*ded470d3SGreg Clayton                     case eSectionTypeDWARFDebugRanges:      return eAddressClassDebug;
148*ded470d3SGreg Clayton                     case eSectionTypeDWARFDebugStr:         return eAddressClassDebug;
149*ded470d3SGreg Clayton                     case eSectionTypeEHFrame:               return eAddressClassRuntime;
150*ded470d3SGreg Clayton                     case eSectionTypeOther:                 return eAddressClassUnknown;
151*ded470d3SGreg Clayton                     }
152*ded470d3SGreg Clayton                 }
153*ded470d3SGreg Clayton             }
154*ded470d3SGreg Clayton 
155*ded470d3SGreg Clayton             const lldb::SymbolType symbol_type = symbol->GetType();
156*ded470d3SGreg Clayton             switch (symbol_type)
157*ded470d3SGreg Clayton             {
158*ded470d3SGreg Clayton             case eSymbolTypeAny:            return eAddressClassUnknown;
159*ded470d3SGreg Clayton             case eSymbolTypeAbsolute:       return eAddressClassUnknown;
160*ded470d3SGreg Clayton             case eSymbolTypeExtern:         return eAddressClassUnknown;
161*ded470d3SGreg Clayton             case eSymbolTypeCode:           return eAddressClassCode;
162*ded470d3SGreg Clayton             case eSymbolTypeTrampoline:     return eAddressClassCode;
163*ded470d3SGreg Clayton             case eSymbolTypeData:           return eAddressClassData;
164*ded470d3SGreg Clayton             case eSymbolTypeRuntime:        return eAddressClassRuntime;
165*ded470d3SGreg Clayton             case eSymbolTypeException:      return eAddressClassRuntime;
166*ded470d3SGreg Clayton             case eSymbolTypeSourceFile:     return eAddressClassDebug;
167*ded470d3SGreg Clayton             case eSymbolTypeHeaderFile:     return eAddressClassDebug;
168*ded470d3SGreg Clayton             case eSymbolTypeObjectFile:     return eAddressClassDebug;
169*ded470d3SGreg Clayton             case eSymbolTypeCommonBlock:    return eAddressClassDebug;
170*ded470d3SGreg Clayton             case eSymbolTypeBlock:          return eAddressClassDebug;
171*ded470d3SGreg Clayton             case eSymbolTypeLocal:          return eAddressClassData;
172*ded470d3SGreg Clayton             case eSymbolTypeParam:          return eAddressClassData;
173*ded470d3SGreg Clayton             case eSymbolTypeVariable:       return eAddressClassData;
174*ded470d3SGreg Clayton             case eSymbolTypeVariableType:   return eAddressClassDebug;
175*ded470d3SGreg Clayton             case eSymbolTypeLineEntry:      return eAddressClassDebug;
176*ded470d3SGreg Clayton             case eSymbolTypeLineHeader:     return eAddressClassDebug;
177*ded470d3SGreg Clayton             case eSymbolTypeScopeBegin:     return eAddressClassDebug;
178*ded470d3SGreg Clayton             case eSymbolTypeScopeEnd:       return eAddressClassDebug;
179*ded470d3SGreg Clayton             case eSymbolTypeAdditional:     return eAddressClassUnknown;
180*ded470d3SGreg Clayton             case eSymbolTypeCompiler:       return eAddressClassDebug;
181*ded470d3SGreg Clayton             case eSymbolTypeInstrumentation:return eAddressClassDebug;
182*ded470d3SGreg Clayton             case eSymbolTypeUndefined:      return eAddressClassUnknown;
183*ded470d3SGreg Clayton             }
184*ded470d3SGreg Clayton         }
185*ded470d3SGreg Clayton     }
186*ded470d3SGreg Clayton     return eAddressClassUnknown;
187*ded470d3SGreg Clayton }
188*ded470d3SGreg Clayton 
189*ded470d3SGreg Clayton 
190