Skip to content

Commit

Permalink
[JITLoaderGDB] Read jit entry struct manually.
Browse files Browse the repository at this point in the history
Summary:
Though r264012 was fancy enough to make reading the jit entry struct
work with templates, the packing and alignment attributes do not work on
Windows. So, this change makes it plain and simple with manual reading
of the jit entry struct.

Reviewers: clayborg

Subscribers: lldb-commits

Differential Revision: http://reviews.llvm.org/D18379

llvm-svn: 264217
  • Loading branch information
Siva Chandra committed Mar 23, 2016
1 parent 9a95275 commit 02f593f
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 51 deletions.
112 changes: 62 additions & 50 deletions lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
Expand Up @@ -9,7 +9,10 @@

// C Includes

#include "llvm/Support/MathExtras.h"

#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
Expand All @@ -22,12 +25,41 @@
#include "lldb/Target/Process.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBAssert.h"

#include "JITLoaderGDB.h"

using namespace lldb;
using namespace lldb_private;

//------------------------------------------------------------------
// Debug Interface Structures
//------------------------------------------------------------------
typedef enum
{
JIT_NOACTION = 0,
JIT_REGISTER_FN,
JIT_UNREGISTER_FN
} jit_actions_t;

template <typename ptr_t>
struct jit_code_entry
{
ptr_t next_entry; // pointer
ptr_t prev_entry; // pointer
ptr_t symfile_addr; // pointer
uint64_t symfile_size;
};

template <typename ptr_t>
struct jit_descriptor
{
uint32_t version;
uint32_t action_flag; // Values are jit_action_t
ptr_t relevant_entry; // pointer
ptr_t first_entry; // pointer
};

namespace {

PropertyDefinition
Expand Down Expand Up @@ -78,44 +110,34 @@ namespace {
return g_settings_sp;
}

} // anonymous namespace end
template <typename ptr_t>
bool ReadJITEntry(const addr_t from_addr, Process *process, jit_code_entry<ptr_t> *entry)
{
lldbassert(from_addr % sizeof(ptr_t) == 0);

//------------------------------------------------------------------
// Debug Interface Structures
//------------------------------------------------------------------
typedef enum
{
JIT_NOACTION = 0,
JIT_REGISTER_FN,
JIT_UNREGISTER_FN
} jit_actions_t;
ArchSpec::Core core = process->GetTarget().GetArchitecture().GetCore();
bool i386_target = ArchSpec::kCore_x86_32_first <= core && core <= ArchSpec::kCore_x86_32_last;
uint8_t uint64_align_bytes = i386_target ? 4 : 8;
const size_t data_byte_size = llvm::alignTo(sizeof(ptr_t) * 3, uint64_align_bytes) + sizeof(uint64_t);

template <typename ptr_t, bool packed_size>
struct jit_code_entry
{
ptr_t next_entry; // pointer
ptr_t prev_entry; // pointer
ptr_t symfile_addr; // pointer
uint64_t symfile_size __attribute__ ((aligned (8)));
};
Error error;
DataBufferHeap data(data_byte_size, 0);
size_t bytes_read = process->ReadMemory(from_addr, data.GetBytes(), data.GetByteSize(), error);
if (bytes_read != data_byte_size || !error.Success())
return false;

template <typename ptr_t>
struct jit_code_entry<ptr_t, true>
{
ptr_t next_entry; // pointer
ptr_t prev_entry; // pointer
ptr_t symfile_addr; // pointer
uint64_t symfile_size __attribute__ ((packed));
};
DataExtractor extractor (data.GetBytes(), data.GetByteSize(), process->GetByteOrder(), sizeof(ptr_t));
lldb::offset_t offset = 0;
entry->next_entry = extractor.GetPointer(&offset);
entry->prev_entry = extractor.GetPointer(&offset);
entry->symfile_addr = extractor.GetPointer(&offset);
offset = llvm::alignTo(offset, uint64_align_bytes);
entry->symfile_size = extractor.GetU64(&offset);

template <typename ptr_t>
struct jit_descriptor
{
uint32_t version;
uint32_t action_flag; // Values are jit_action_t
ptr_t relevant_entry; // pointer
ptr_t first_entry; // pointer
};
return true;
}

} // anonymous namespace end

JITLoaderGDB::JITLoaderGDB (lldb_private::Process *process) :
JITLoader(process),
Expand Down Expand Up @@ -278,21 +300,13 @@ static void updateSectionLoadAddress(const SectionList &section_list,
bool
JITLoaderGDB::ReadJITDescriptor(bool all_entries)
{
Target &target = m_process->GetTarget();
const ArchSpec &arch_spec = target.GetArchitecture();
if (arch_spec.GetAddressByteSize() == 8)
return ReadJITDescriptorImpl<uint64_t, false>(all_entries);
if (m_process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
return ReadJITDescriptorImpl<uint64_t>(all_entries);
else
{
ArchSpec::Core core = arch_spec.GetCore();
if (ArchSpec::kCore_x86_32_first <= core && core <= ArchSpec::kCore_x86_32_last)
return ReadJITDescriptorImpl<uint32_t, true>(all_entries);
else
return ReadJITDescriptorImpl<uint32_t, false>(all_entries);
}
return ReadJITDescriptorImpl<uint32_t>(all_entries);
}

template <typename ptr_t, bool packed>
template <typename ptr_t>
bool
JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries)
{
Expand Down Expand Up @@ -326,10 +340,8 @@ JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries)

while (jit_relevant_entry != 0)
{
jit_code_entry<ptr_t, packed> jit_entry;
const size_t jit_entry_size = sizeof(jit_entry);
bytes_read = m_process->DoReadMemory(jit_relevant_entry, &jit_entry, jit_entry_size, error);
if (bytes_read != jit_entry_size || !error.Success())
jit_code_entry<ptr_t> jit_entry;
if (!ReadJITEntry(jit_relevant_entry, m_process, &jit_entry))
{
if (log)
log->Printf(
Expand Down
2 changes: 1 addition & 1 deletion lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h
Expand Up @@ -83,7 +83,7 @@ class JITLoaderGDB : public lldb_private::JITLoader
bool
ReadJITDescriptor(bool all_entries);

template <typename ptr_t, bool packed>
template <typename ptr_t>
bool
ReadJITDescriptorImpl(bool all_entries);

Expand Down

0 comments on commit 02f593f

Please sign in to comment.