123f8c95aSGreg Clayton //===-- ObjectFileJIT.cpp ---------------------------------------*- C++ -*-===//
223f8c95aSGreg Clayton //
323f8c95aSGreg Clayton //                     The LLVM Compiler Infrastructure
423f8c95aSGreg Clayton //
523f8c95aSGreg Clayton // This file is distributed under the University of Illinois Open Source
623f8c95aSGreg Clayton // License. See LICENSE.TXT for details.
723f8c95aSGreg Clayton //
823f8c95aSGreg Clayton //===----------------------------------------------------------------------===//
923f8c95aSGreg Clayton 
1023f8c95aSGreg Clayton #include "llvm/ADT/StringRef.h"
1123f8c95aSGreg Clayton 
1223f8c95aSGreg Clayton #include "ObjectFileJIT.h"
1323f8c95aSGreg Clayton 
1423f8c95aSGreg Clayton #include "lldb/lldb-private-log.h"
1523f8c95aSGreg Clayton #include "lldb/Core/ArchSpec.h"
1623f8c95aSGreg Clayton #include "lldb/Core/DataBuffer.h"
1723f8c95aSGreg Clayton #include "lldb/Core/DataBufferHeap.h"
1823f8c95aSGreg Clayton #include "lldb/Core/Debugger.h"
1923f8c95aSGreg Clayton #include "lldb/Core/FileSpecList.h"
2023f8c95aSGreg Clayton #include "lldb/Core/Log.h"
2123f8c95aSGreg Clayton #include "lldb/Core/Module.h"
2223f8c95aSGreg Clayton #include "lldb/Core/ModuleSpec.h"
2323f8c95aSGreg Clayton #include "lldb/Core/PluginManager.h"
2423f8c95aSGreg Clayton #include "lldb/Core/RangeMap.h"
2523f8c95aSGreg Clayton #include "lldb/Core/Section.h"
2623f8c95aSGreg Clayton #include "lldb/Core/StreamFile.h"
2723f8c95aSGreg Clayton #include "lldb/Core/StreamString.h"
2823f8c95aSGreg Clayton #include "lldb/Core/Timer.h"
2923f8c95aSGreg Clayton #include "lldb/Core/UUID.h"
3023f8c95aSGreg Clayton #include "lldb/Host/Host.h"
3123f8c95aSGreg Clayton #include "lldb/Host/FileSpec.h"
3223f8c95aSGreg Clayton #include "lldb/Symbol/ObjectFile.h"
3323f8c95aSGreg Clayton #include "lldb/Target/Platform.h"
3423f8c95aSGreg Clayton #include "lldb/Target/Process.h"
3523f8c95aSGreg Clayton #include "lldb/Target/SectionLoadList.h"
3623f8c95aSGreg Clayton #include "lldb/Target/Target.h"
3723f8c95aSGreg Clayton 
3823f8c95aSGreg Clayton #ifndef __APPLE__
3923f8c95aSGreg Clayton #include "Utility/UuidCompatibility.h"
4023f8c95aSGreg Clayton #endif
4123f8c95aSGreg Clayton 
4223f8c95aSGreg Clayton using namespace lldb;
4323f8c95aSGreg Clayton using namespace lldb_private;
4423f8c95aSGreg Clayton 
4523f8c95aSGreg Clayton 
4623f8c95aSGreg Clayton void
4723f8c95aSGreg Clayton ObjectFileJIT::Initialize()
4823f8c95aSGreg Clayton {
4923f8c95aSGreg Clayton     PluginManager::RegisterPlugin (GetPluginNameStatic(),
5023f8c95aSGreg Clayton                                    GetPluginDescriptionStatic(),
5123f8c95aSGreg Clayton                                    CreateInstance,
5223f8c95aSGreg Clayton                                    CreateMemoryInstance,
5323f8c95aSGreg Clayton                                    GetModuleSpecifications);
5423f8c95aSGreg Clayton }
5523f8c95aSGreg Clayton 
5623f8c95aSGreg Clayton void
5723f8c95aSGreg Clayton ObjectFileJIT::Terminate()
5823f8c95aSGreg Clayton {
5923f8c95aSGreg Clayton     PluginManager::UnregisterPlugin (CreateInstance);
6023f8c95aSGreg Clayton }
6123f8c95aSGreg Clayton 
6223f8c95aSGreg Clayton 
6323f8c95aSGreg Clayton lldb_private::ConstString
6423f8c95aSGreg Clayton ObjectFileJIT::GetPluginNameStatic()
6523f8c95aSGreg Clayton {
6623f8c95aSGreg Clayton     static ConstString g_name("jit");
6723f8c95aSGreg Clayton     return g_name;
6823f8c95aSGreg Clayton }
6923f8c95aSGreg Clayton 
7023f8c95aSGreg Clayton const char *
7123f8c95aSGreg Clayton ObjectFileJIT::GetPluginDescriptionStatic()
7223f8c95aSGreg Clayton {
7323f8c95aSGreg Clayton     return "JIT code object file";
7423f8c95aSGreg Clayton }
7523f8c95aSGreg Clayton 
7623f8c95aSGreg Clayton ObjectFile *
7723f8c95aSGreg Clayton ObjectFileJIT::CreateInstance (const lldb::ModuleSP &module_sp,
7823f8c95aSGreg Clayton                                  DataBufferSP& data_sp,
7923f8c95aSGreg Clayton                                  lldb::offset_t data_offset,
8023f8c95aSGreg Clayton                                  const FileSpec* file,
8123f8c95aSGreg Clayton                                  lldb::offset_t file_offset,
8223f8c95aSGreg Clayton                                  lldb::offset_t length)
8323f8c95aSGreg Clayton {
8423f8c95aSGreg Clayton     // JIT'ed object file is backed by the ObjectFileJITDelegate, never
8523f8c95aSGreg Clayton     // read from a file
8623f8c95aSGreg Clayton     return NULL;
8723f8c95aSGreg Clayton }
8823f8c95aSGreg Clayton 
8923f8c95aSGreg Clayton ObjectFile *
9023f8c95aSGreg Clayton ObjectFileJIT::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
9123f8c95aSGreg Clayton                                      DataBufferSP& data_sp,
9223f8c95aSGreg Clayton                                      const ProcessSP &process_sp,
9323f8c95aSGreg Clayton                                      lldb::addr_t header_addr)
9423f8c95aSGreg Clayton {
9523f8c95aSGreg Clayton     // JIT'ed object file is backed by the ObjectFileJITDelegate, never
9623f8c95aSGreg Clayton     // read from memory
9723f8c95aSGreg Clayton     return NULL;
9823f8c95aSGreg Clayton }
9923f8c95aSGreg Clayton 
10023f8c95aSGreg Clayton size_t
10123f8c95aSGreg Clayton ObjectFileJIT::GetModuleSpecifications (const lldb_private::FileSpec& file,
10223f8c95aSGreg Clayton                                         lldb::DataBufferSP& data_sp,
10323f8c95aSGreg Clayton                                         lldb::offset_t data_offset,
10423f8c95aSGreg Clayton                                         lldb::offset_t file_offset,
10523f8c95aSGreg Clayton                                         lldb::offset_t length,
10623f8c95aSGreg Clayton                                         lldb_private::ModuleSpecList &specs)
10723f8c95aSGreg Clayton {
10823f8c95aSGreg Clayton     // JIT'ed object file can't be read from a file on disk
10923f8c95aSGreg Clayton     return 0;
11023f8c95aSGreg Clayton }
11123f8c95aSGreg Clayton 
11223f8c95aSGreg Clayton ObjectFileJIT::ObjectFileJIT (const lldb::ModuleSP &module_sp,
11323f8c95aSGreg Clayton                               const ObjectFileJITDelegateSP &delegate_sp) :
11423f8c95aSGreg Clayton     ObjectFile(module_sp, NULL, 0, 0, DataBufferSP(), 0),
11523f8c95aSGreg Clayton     m_delegate_wp ()
11623f8c95aSGreg Clayton {
11723f8c95aSGreg Clayton     if (delegate_sp)
11823f8c95aSGreg Clayton     {
11923f8c95aSGreg Clayton         m_delegate_wp = delegate_sp;
12023f8c95aSGreg Clayton         m_data.SetByteOrder(delegate_sp->GetByteOrder());
12123f8c95aSGreg Clayton         m_data.SetAddressByteSize(delegate_sp->GetAddressByteSize());
12223f8c95aSGreg Clayton     }
12323f8c95aSGreg Clayton }
12423f8c95aSGreg Clayton 
12523f8c95aSGreg Clayton ObjectFileJIT::~ObjectFileJIT()
12623f8c95aSGreg Clayton {
12723f8c95aSGreg Clayton }
12823f8c95aSGreg Clayton 
12923f8c95aSGreg Clayton 
13023f8c95aSGreg Clayton bool
13123f8c95aSGreg Clayton ObjectFileJIT::ParseHeader ()
13223f8c95aSGreg Clayton {
13323f8c95aSGreg Clayton     // JIT code is never in a file, nor is it required to have any header
13423f8c95aSGreg Clayton     return false;
13523f8c95aSGreg Clayton }
13623f8c95aSGreg Clayton 
13723f8c95aSGreg Clayton ByteOrder
13823f8c95aSGreg Clayton ObjectFileJIT::GetByteOrder () const
13923f8c95aSGreg Clayton {
14023f8c95aSGreg Clayton     return m_data.GetByteOrder();
14123f8c95aSGreg Clayton }
14223f8c95aSGreg Clayton 
14323f8c95aSGreg Clayton bool
14423f8c95aSGreg Clayton ObjectFileJIT::IsExecutable() const
14523f8c95aSGreg Clayton {
14623f8c95aSGreg Clayton     return false;
14723f8c95aSGreg Clayton }
14823f8c95aSGreg Clayton 
14923f8c95aSGreg Clayton uint32_t
15023f8c95aSGreg Clayton ObjectFileJIT::GetAddressByteSize () const
15123f8c95aSGreg Clayton {
15223f8c95aSGreg Clayton     return m_data.GetAddressByteSize();
15323f8c95aSGreg Clayton }
15423f8c95aSGreg Clayton 
15523f8c95aSGreg Clayton 
15623f8c95aSGreg Clayton Symtab *
15723f8c95aSGreg Clayton ObjectFileJIT::GetSymtab()
15823f8c95aSGreg Clayton {
15923f8c95aSGreg Clayton     ModuleSP module_sp(GetModule());
16023f8c95aSGreg Clayton     if (module_sp)
16123f8c95aSGreg Clayton     {
16223f8c95aSGreg Clayton         lldb_private::Mutex::Locker locker(module_sp->GetMutex());
16323f8c95aSGreg Clayton         if (m_symtab_ap.get() == NULL)
16423f8c95aSGreg Clayton         {
16523f8c95aSGreg Clayton             m_symtab_ap.reset(new Symtab(this));
16623f8c95aSGreg Clayton             Mutex::Locker symtab_locker (m_symtab_ap->GetMutex());
16723f8c95aSGreg Clayton             ObjectFileJITDelegateSP delegate_sp (m_delegate_wp.lock());
16823f8c95aSGreg Clayton             if (delegate_sp)
16923f8c95aSGreg Clayton                 delegate_sp->PopulateSymtab(this, *m_symtab_ap);
17023f8c95aSGreg Clayton             // TODO: get symbols from delegate
17123f8c95aSGreg Clayton             m_symtab_ap->Finalize ();
17223f8c95aSGreg Clayton         }
17323f8c95aSGreg Clayton     }
17423f8c95aSGreg Clayton     return m_symtab_ap.get();
17523f8c95aSGreg Clayton }
17623f8c95aSGreg Clayton 
17723f8c95aSGreg Clayton bool
17823f8c95aSGreg Clayton ObjectFileJIT::IsStripped ()
17923f8c95aSGreg Clayton {
18023f8c95aSGreg Clayton     return false; // JIT code that is in a module is never stripped
18123f8c95aSGreg Clayton }
18223f8c95aSGreg Clayton 
18323f8c95aSGreg Clayton void
18423f8c95aSGreg Clayton ObjectFileJIT::CreateSections (SectionList &unified_section_list)
18523f8c95aSGreg Clayton {
18623f8c95aSGreg Clayton     if (!m_sections_ap.get())
18723f8c95aSGreg Clayton     {
18823f8c95aSGreg Clayton         m_sections_ap.reset(new SectionList());
18923f8c95aSGreg Clayton         ObjectFileJITDelegateSP delegate_sp (m_delegate_wp.lock());
19023f8c95aSGreg Clayton         if (delegate_sp)
19123f8c95aSGreg Clayton         {
19223f8c95aSGreg Clayton             delegate_sp->PopulateSectionList(this, *m_sections_ap);
19323f8c95aSGreg Clayton             unified_section_list = *m_sections_ap;
19423f8c95aSGreg Clayton         }
19523f8c95aSGreg Clayton     }
19623f8c95aSGreg Clayton }
19723f8c95aSGreg Clayton 
19823f8c95aSGreg Clayton void
19923f8c95aSGreg Clayton ObjectFileJIT::Dump (Stream *s)
20023f8c95aSGreg Clayton {
20123f8c95aSGreg Clayton     ModuleSP module_sp(GetModule());
20223f8c95aSGreg Clayton     if (module_sp)
20323f8c95aSGreg Clayton     {
20423f8c95aSGreg Clayton         lldb_private::Mutex::Locker locker(module_sp->GetMutex());
205*324a1036SSaleem Abdulrasool         s->Printf("%p: ", static_cast<void*>(this));
20623f8c95aSGreg Clayton         s->Indent();
20723f8c95aSGreg Clayton         s->PutCString("ObjectFileJIT");
20823f8c95aSGreg Clayton 
20923f8c95aSGreg Clayton         ArchSpec arch;
21023f8c95aSGreg Clayton         if (GetArchitecture(arch))
21123f8c95aSGreg Clayton             *s << ", arch = " << arch.GetArchitectureName();
21223f8c95aSGreg Clayton 
21323f8c95aSGreg Clayton         s->EOL();
21423f8c95aSGreg Clayton 
21523f8c95aSGreg Clayton         SectionList *sections = GetSectionList();
21623f8c95aSGreg Clayton         if (sections)
21723f8c95aSGreg Clayton             sections->Dump(s, NULL, true, UINT32_MAX);
21823f8c95aSGreg Clayton 
21923f8c95aSGreg Clayton         if (m_symtab_ap.get())
22023f8c95aSGreg Clayton             m_symtab_ap->Dump(s, NULL, eSortOrderNone);
22123f8c95aSGreg Clayton     }
22223f8c95aSGreg Clayton }
22323f8c95aSGreg Clayton 
22423f8c95aSGreg Clayton bool
22523f8c95aSGreg Clayton ObjectFileJIT::GetUUID (lldb_private::UUID* uuid)
22623f8c95aSGreg Clayton {
22723f8c95aSGreg Clayton     // TODO: maybe get from delegate, not needed for first pass
22823f8c95aSGreg Clayton     return false;
22923f8c95aSGreg Clayton }
23023f8c95aSGreg Clayton 
23123f8c95aSGreg Clayton 
23223f8c95aSGreg Clayton uint32_t
23323f8c95aSGreg Clayton ObjectFileJIT::GetDependentModules (FileSpecList& files)
23423f8c95aSGreg Clayton {
23523f8c95aSGreg Clayton     // JIT modules don't have dependencies, but they could
23623f8c95aSGreg Clayton     // if external functions are called and we know where they are
23723f8c95aSGreg Clayton     files.Clear();
23823f8c95aSGreg Clayton     return 0;
23923f8c95aSGreg Clayton }
24023f8c95aSGreg Clayton 
24123f8c95aSGreg Clayton lldb_private::Address
24223f8c95aSGreg Clayton ObjectFileJIT::GetEntryPointAddress ()
24323f8c95aSGreg Clayton {
24423f8c95aSGreg Clayton     return Address();
24523f8c95aSGreg Clayton }
24623f8c95aSGreg Clayton 
24723f8c95aSGreg Clayton lldb_private::Address
24823f8c95aSGreg Clayton ObjectFileJIT::GetHeaderAddress ()
24923f8c95aSGreg Clayton {
25023f8c95aSGreg Clayton     return Address();
25123f8c95aSGreg Clayton }
25223f8c95aSGreg Clayton 
25323f8c95aSGreg Clayton 
25423f8c95aSGreg Clayton 
25523f8c95aSGreg Clayton ObjectFile::Type
25623f8c95aSGreg Clayton ObjectFileJIT::CalculateType()
25723f8c95aSGreg Clayton {
25823f8c95aSGreg Clayton     return eTypeJIT;
25923f8c95aSGreg Clayton }
26023f8c95aSGreg Clayton 
26123f8c95aSGreg Clayton ObjectFile::Strata
26223f8c95aSGreg Clayton ObjectFileJIT::CalculateStrata()
26323f8c95aSGreg Clayton {
26423f8c95aSGreg Clayton     return eStrataJIT;
26523f8c95aSGreg Clayton }
26623f8c95aSGreg Clayton 
26723f8c95aSGreg Clayton 
26823f8c95aSGreg Clayton bool
26923f8c95aSGreg Clayton ObjectFileJIT::GetArchitecture (ArchSpec &arch)
27023f8c95aSGreg Clayton {
27123f8c95aSGreg Clayton     ObjectFileJITDelegateSP delegate_sp (m_delegate_wp.lock());
27223f8c95aSGreg Clayton     if (delegate_sp)
27323f8c95aSGreg Clayton         return delegate_sp->GetArchitecture(arch);
27423f8c95aSGreg Clayton     return false;
27523f8c95aSGreg Clayton }
27623f8c95aSGreg Clayton 
27723f8c95aSGreg Clayton //------------------------------------------------------------------
27823f8c95aSGreg Clayton // PluginInterface protocol
27923f8c95aSGreg Clayton //------------------------------------------------------------------
28023f8c95aSGreg Clayton lldb_private::ConstString
28123f8c95aSGreg Clayton ObjectFileJIT::GetPluginName()
28223f8c95aSGreg Clayton {
28323f8c95aSGreg Clayton     return GetPluginNameStatic();
28423f8c95aSGreg Clayton }
28523f8c95aSGreg Clayton 
28623f8c95aSGreg Clayton uint32_t
28723f8c95aSGreg Clayton ObjectFileJIT::GetPluginVersion()
28823f8c95aSGreg Clayton {
28923f8c95aSGreg Clayton     return 1;
29023f8c95aSGreg Clayton }
29123f8c95aSGreg Clayton 
29223f8c95aSGreg Clayton 
29323f8c95aSGreg Clayton bool
29423f8c95aSGreg Clayton ObjectFileJIT::SetLoadAddress (Target &target,
29523f8c95aSGreg Clayton                                lldb::addr_t value,
29623f8c95aSGreg Clayton                                bool value_is_offset)
29723f8c95aSGreg Clayton {
29823f8c95aSGreg Clayton     bool changed = false;
29923f8c95aSGreg Clayton     size_t num_loaded_sections = 0;
30023f8c95aSGreg Clayton     SectionList *section_list = GetSectionList ();
30123f8c95aSGreg Clayton     if (section_list)
30223f8c95aSGreg Clayton     {
30323f8c95aSGreg Clayton         const size_t num_sections = section_list->GetSize();
30423f8c95aSGreg Clayton         // "value" is an offset to apply to each top level segment
30523f8c95aSGreg Clayton         for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
30623f8c95aSGreg Clayton         {
30723f8c95aSGreg Clayton             // Iterate through the object file sections to find all
30823f8c95aSGreg Clayton             // of the sections that size on disk (to avoid __PAGEZERO)
30923f8c95aSGreg Clayton             // and load them
31023f8c95aSGreg Clayton             SectionSP section_sp (section_list->GetSectionAtIndex (sect_idx));
31123f8c95aSGreg Clayton             if (section_sp &&
31223f8c95aSGreg Clayton                 section_sp->GetFileSize() > 0 &&
31323f8c95aSGreg Clayton                 section_sp->IsThreadSpecific() == false)
31423f8c95aSGreg Clayton             {
31523f8c95aSGreg Clayton                 if (target.GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress() + value))
31623f8c95aSGreg Clayton                     ++num_loaded_sections;
31723f8c95aSGreg Clayton             }
31823f8c95aSGreg Clayton         }
31923f8c95aSGreg Clayton     }
32023f8c95aSGreg Clayton     changed = num_loaded_sections > 0;
32123f8c95aSGreg Clayton     return num_loaded_sections > 0;
32223f8c95aSGreg Clayton }
32323f8c95aSGreg Clayton 
32423f8c95aSGreg Clayton 
32523f8c95aSGreg Clayton size_t
32623f8c95aSGreg Clayton ObjectFileJIT::ReadSectionData (const lldb_private::Section *section,
32723f8c95aSGreg Clayton                                 off_t section_offset,
32823f8c95aSGreg Clayton                                 void *dst,
32923f8c95aSGreg Clayton                                 size_t dst_len) const
33023f8c95aSGreg Clayton {
33123f8c95aSGreg Clayton     lldb::offset_t file_size = section->GetFileSize();
3323985c8c6SSaleem Abdulrasool     if (section_offset < static_cast<off_t>(file_size))
33323f8c95aSGreg Clayton     {
33423f8c95aSGreg Clayton         uint64_t src_len = file_size - section_offset;
33523f8c95aSGreg Clayton         if (src_len > dst_len)
33623f8c95aSGreg Clayton             src_len = dst_len;
33723f8c95aSGreg Clayton         const uint8_t *src = ((uint8_t *)(uintptr_t)section->GetFileOffset()) + section_offset;
33823f8c95aSGreg Clayton 
33923f8c95aSGreg Clayton         memcpy (dst, src, src_len);
34023f8c95aSGreg Clayton         return src_len;
34123f8c95aSGreg Clayton     }
34223f8c95aSGreg Clayton     return 0;
34323f8c95aSGreg Clayton }
34423f8c95aSGreg Clayton size_t
34523f8c95aSGreg Clayton ObjectFileJIT::ReadSectionData (const lldb_private::Section *section,
34623f8c95aSGreg Clayton                                 lldb_private::DataExtractor& section_data) const
34723f8c95aSGreg Clayton {
34823f8c95aSGreg Clayton     if (section->GetFileSize())
34923f8c95aSGreg Clayton     {
35023f8c95aSGreg Clayton         const void *src = (void *)(uintptr_t)section->GetFileOffset();
35123f8c95aSGreg Clayton 
35223f8c95aSGreg Clayton         DataBufferSP data_sp (new lldb_private::DataBufferHeap(src, section->GetFileSize()));
35323f8c95aSGreg Clayton         if (data_sp)
35423f8c95aSGreg Clayton         {
35523f8c95aSGreg Clayton             section_data.SetData (data_sp, 0, data_sp->GetByteSize());
35623f8c95aSGreg Clayton             section_data.SetByteOrder (GetByteOrder());
35723f8c95aSGreg Clayton             section_data.SetAddressByteSize (GetAddressByteSize());
35823f8c95aSGreg Clayton             return section_data.GetByteSize();
35923f8c95aSGreg Clayton         }
36023f8c95aSGreg Clayton     }
36123f8c95aSGreg Clayton     section_data.Clear();
36223f8c95aSGreg Clayton     return 0;
36323f8c95aSGreg Clayton }
36423f8c95aSGreg Clayton 
365