1*30fdc8d8SChris Lattner //===-- ObjectFile.cpp ------------------------------------------*- C++ -*-===//
2*30fdc8d8SChris Lattner //
3*30fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
4*30fdc8d8SChris Lattner //
5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
7*30fdc8d8SChris Lattner //
8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
9*30fdc8d8SChris Lattner 
10*30fdc8d8SChris Lattner #include "lldb/lldb-private.h"
11*30fdc8d8SChris Lattner #include "lldb/Core/Module.h"
12*30fdc8d8SChris Lattner #include "lldb/Core/PluginManager.h"
13*30fdc8d8SChris Lattner #include "lldb/Core/RegularExpression.h"
14*30fdc8d8SChris Lattner #include "lldb/Core/Timer.h"
15*30fdc8d8SChris Lattner #include "lldb/Symbol/ObjectFile.h"
16*30fdc8d8SChris Lattner #include "lldb/Symbol/ObjectContainer.h"
17*30fdc8d8SChris Lattner #include "lldb/Symbol/SymbolFile.h"
18*30fdc8d8SChris Lattner 
19*30fdc8d8SChris Lattner using namespace lldb;
20*30fdc8d8SChris Lattner using namespace lldb_private;
21*30fdc8d8SChris Lattner 
22*30fdc8d8SChris Lattner ObjectFile*
23*30fdc8d8SChris Lattner ObjectFile::FindPlugin (Module* module, const FileSpec* file, lldb::addr_t file_offset, lldb::addr_t file_size)
24*30fdc8d8SChris Lattner {
25*30fdc8d8SChris Lattner     Timer scoped_timer (__PRETTY_FUNCTION__,
26*30fdc8d8SChris Lattner                         "ObjectFile::FindPlugin (module = %s/%s, file = %p, file_offset = 0x%z8.8x, file_size = 0x%z8.8x)",
27*30fdc8d8SChris Lattner                         module->GetFileSpec().GetDirectory().AsCString(),
28*30fdc8d8SChris Lattner                         module->GetFileSpec().GetFilename().AsCString(),
29*30fdc8d8SChris Lattner                         file, file_offset, file_size);
30*30fdc8d8SChris Lattner     std::auto_ptr<ObjectFile> object_file_ap;
31*30fdc8d8SChris Lattner 
32*30fdc8d8SChris Lattner     if (module != NULL)
33*30fdc8d8SChris Lattner     {
34*30fdc8d8SChris Lattner         if (file)
35*30fdc8d8SChris Lattner         {
36*30fdc8d8SChris Lattner             if (file_size == 0)
37*30fdc8d8SChris Lattner                 file_size = file->GetByteSize();
38*30fdc8d8SChris Lattner 
39*30fdc8d8SChris Lattner             if (file_size == 0)
40*30fdc8d8SChris Lattner             {
41*30fdc8d8SChris Lattner                 // Check for archive file with format "/path/to/archive.a(object.o)"
42*30fdc8d8SChris Lattner                 char path_with_object[PATH_MAX*2];
43*30fdc8d8SChris Lattner                 module->GetFileSpec().GetPath(path_with_object, sizeof(path_with_object));
44*30fdc8d8SChris Lattner 
45*30fdc8d8SChris Lattner                 RegularExpression g_object_regex("(.*)\\(([^\\)]+)\\)$");
46*30fdc8d8SChris Lattner                 if (g_object_regex.Execute (path_with_object, 2))
47*30fdc8d8SChris Lattner                 {
48*30fdc8d8SChris Lattner                     FileSpec archive_file;
49*30fdc8d8SChris Lattner                     std::string path;
50*30fdc8d8SChris Lattner                     std::string object;
51*30fdc8d8SChris Lattner                     if (g_object_regex.GetMatchAtIndex (path_with_object, 1, path) &&
52*30fdc8d8SChris Lattner                         g_object_regex.GetMatchAtIndex (path_with_object, 2, object))
53*30fdc8d8SChris Lattner                     {
54*30fdc8d8SChris Lattner                         archive_file.SetFile (path.c_str());
55*30fdc8d8SChris Lattner                         file_size = archive_file.GetByteSize();
56*30fdc8d8SChris Lattner                         if (file_size > 0)
57*30fdc8d8SChris Lattner                             module->SetFileSpecAndObjectName (archive_file, ConstString(object.c_str()));
58*30fdc8d8SChris Lattner                     }
59*30fdc8d8SChris Lattner                 }
60*30fdc8d8SChris Lattner             }
61*30fdc8d8SChris Lattner 
62*30fdc8d8SChris Lattner             DataBufferSP file_header_data_sp(file->ReadFileContents(file_offset, 512));
63*30fdc8d8SChris Lattner             uint32_t idx;
64*30fdc8d8SChris Lattner 
65*30fdc8d8SChris Lattner             // Check if this is a normal object file by iterating through
66*30fdc8d8SChris Lattner             // all object file plugin instances.
67*30fdc8d8SChris Lattner             ObjectFileCreateInstance create_object_file_callback;
68*30fdc8d8SChris Lattner             for (idx = 0; (create_object_file_callback = PluginManager::GetObjectFileCreateCallbackAtIndex(idx)) != NULL; ++idx)
69*30fdc8d8SChris Lattner             {
70*30fdc8d8SChris Lattner                 object_file_ap.reset (create_object_file_callback(module, file_header_data_sp, file, file_offset, file_size));
71*30fdc8d8SChris Lattner                 if (object_file_ap.get())
72*30fdc8d8SChris Lattner                     return object_file_ap.release();
73*30fdc8d8SChris Lattner             }
74*30fdc8d8SChris Lattner 
75*30fdc8d8SChris Lattner             // Check if this is a object container by iterating through
76*30fdc8d8SChris Lattner             // all object container plugin instances and then trying to get
77*30fdc8d8SChris Lattner             // an object file from the container.
78*30fdc8d8SChris Lattner             ObjectContainerCreateInstance create_object_container_callback;
79*30fdc8d8SChris Lattner             for (idx = 0; (create_object_container_callback = PluginManager::GetObjectContainerCreateCallbackAtIndex(idx)) != NULL; ++idx)
80*30fdc8d8SChris Lattner             {
81*30fdc8d8SChris Lattner                 std::auto_ptr<ObjectContainer> object_container_ap(create_object_container_callback(module, file_header_data_sp, file, file_offset, file_size));
82*30fdc8d8SChris Lattner 
83*30fdc8d8SChris Lattner                 if (object_container_ap.get())
84*30fdc8d8SChris Lattner                     object_file_ap.reset (object_container_ap->GetObjectFile(file));
85*30fdc8d8SChris Lattner 
86*30fdc8d8SChris Lattner                 if (object_file_ap.get())
87*30fdc8d8SChris Lattner                     return object_file_ap.release();
88*30fdc8d8SChris Lattner             }
89*30fdc8d8SChris Lattner         }
90*30fdc8d8SChris Lattner     }
91*30fdc8d8SChris Lattner     return NULL;
92*30fdc8d8SChris Lattner }
93