if(FEATURE_EVENT_TRACE)
add_definitions(-DFEATURE_EVENT_TRACE=1)
endif(FEATURE_EVENT_TRACE)
+if(FEATURE_GDBJIT)
+ add_definitions(-DFEATURE_GDBJIT)
+endif()
+if(FEATURE_GDBJIT_FRAME)
+ add_definitions(-DFEATURE_GDBJIT_FRAME)
+endif(FEATURE_GDBJIT_FRAME)
if(CLR_CMAKE_PLATFORM_LINUX)
add_definitions(-DFEATURE_PERFTRACING)
endif(CLR_CMAKE_PLATFORM_LINUX)
//
RETAIL_CONFIG_DWORD_INFO(INTERNAL_PerformanceTracing, W("PerformanceTracing"), 0, "Enable/disable performance tracing. Non-zero values enable tracing.")
+#ifdef FEATURE_GDBJIT
+//
+// GDBJIT
+//
+CONFIG_STRING_INFO(INTERNAL_GDBJitElfDump, W("GDBJitElfDump"), "Dump ELF for specified method")
+#endif
+
//
// Unknown
//
set(VM_SOURCES_GDBJIT
gdbjit.cpp
)
- add_definitions(-DFEATURE_GDBJIT)
endif(FEATURE_GDBJIT)
-if(FEATURE_GDBJIT_FRAME)
- add_definitions(-DFEATURE_GDBJIT_FRAME)
-endif(FEATURE_GDBJIT_FRAME)
if(FEATURE_JIT_PITCHING)
add_definitions(-DFEATURE_JIT_PITCHING)
fTieredCompilation = false;
#endif
+#if defined(FEATURE_GDBJIT) && defined(_DEBUG)
+ pszGDBJitElfDump = NULL;
+#endif // FEATURE_GDBJIT && _DEBUG
+
// After initialization, register the code:#GetConfigValueCallback method with code:CLRConfig to let
// CLRConfig access config files. This is needed because CLRConfig lives outside the VM and can't
// statically link to EEConfig.
fTieredCompilation = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_TieredCompilation) != 0;
#endif
+#if defined(FEATURE_GDBJIT) && defined(_DEBUG)
+ {
+ LPWSTR pszGDBJitElfDumpW = NULL;
+ CLRConfig::GetConfigValue(CLRConfig::INTERNAL_GDBJitElfDump, &pszGDBJitElfDumpW);
+ pszGDBJitElfDump = NarrowWideChar(pszGDBJitElfDumpW);
+ }
+#endif // FEATURE_GDBJIT && _DEBUG
+
return hr;
}
bool TieredCompilation(void) const {LIMITED_METHOD_CONTRACT; return fTieredCompilation; }
#endif
+#if defined(FEATURE_GDBJIT) && defined(_DEBUG)
+ inline bool ShouldDumpElfOnMethod(LPCUTF8 methodName) const
+ {
+ CONTRACTL {
+ NOTHROW;
+ GC_NOTRIGGER;
+ PRECONDITION(CheckPointer(methodName, NULL_OK));
+ } CONTRACTL_END
+ return RegexOrExactMatch(pszGDBJitElfDump, methodName);
+ }
+#endif // FEATURE_GDBJIT && _DEBUG
+
BOOL PInvokeRestoreEsp(BOOL fDefault) const
{
LIMITED_METHOD_CONTRACT;
bool fTieredCompilation;
#endif
+#if defined(FEATURE_GDBJIT) && defined(_DEBUG)
+ LPCUTF8 pszGDBJitElfDump;
+#endif // FEATURE_GDBJIT && _DEBUG
+
public:
HRESULT GetConfiguration_DontUse_(__in_z LPCWSTR pKey, ConfigSearch direction, __deref_out_opt LPCWSTR* value);
__declspec(thread) bool tls_isSymReaderInProgress = false;
+#ifdef _DEBUG
+static void DumpElf(const char* methodName, const char *addr, size_t size)
+{
+ char dump[1024] = { 0, };
+
+ strcat(dump, methodName);
+ strcat(dump, ".o");
+
+ FILE *f = fopen(dump, "wb");
+ fwrite(addr, sizeof(char), size, f);
+ fclose(f);
+}
+#endif
+
TypeInfoBase*
GetTypeInfoFromTypeHandle(TypeHandle typeHandle,
NotifyGdb::PTK_TypeInfoMap pTypeMap,
void Finalize(void);
public:
- char *Export(UINT64 *len);
+ char *Export(size_t *len);
};
Elf_Builder::Elf_Builder()
m_Curr = nullptr;
}
-char *Elf_Builder::Export(UINT64 *pLen)
+char *Elf_Builder::Export(size_t *pLen)
{
unsigned int len = m_Buffer.GetPos();
const char *src = m_Buffer.GetPtr();
elfBuilder.Finalize();
+ char *symfile_addr = NULL;
+ size_t symfile_size = 0;
+
+ symfile_addr = elfBuilder.Export(&symfile_size);
+
+#ifdef _DEBUG
+ LPCUTF8 methodName = methodDescPtr->GetName();
+
+ if (g_pConfig->ShouldDumpElfOnMethod(methodName))
+ {
+ DumpElf(methodName, symfile_addr, symfile_size);
+ }
+#endif
+
/* Create GDB JIT structures */
NewHolder<jit_code_entry> jit_symbols = new jit_code_entry;
/* Fill the new entry */
jit_symbols->next_entry = jit_symbols->prev_entry = 0;
- jit_symbols->symfile_addr = elfBuilder.Export(&jit_symbols->symfile_size);
+ jit_symbols->symfile_addr = symfile_addr;
+ jit_symbols->symfile_size = symfile_size;
/* Link into list */
jit_code_entry *head = __jit_debug_descriptor.first_entry;
}
}
-#ifdef _DEBUG
-void NotifyGdb::DumpElf(const char* methodName, const MemBuf& elfFile)
-{
- char dump[1024];
- strcpy(dump, "./");
- strcat(dump, methodName);
- strcat(dump, ".o");
- FILE *f = fopen(dump, "wb");
- fwrite(elfFile.MemPtr, sizeof(char),elfFile.MemSize, f);
- fclose(f);
-}
-#endif
-
/* ELF 32bit header */
Elf32_Ehdr::Elf32_Ehdr()
{
static void SplitPathname(const char* path, const char*& pathName, const char*& fileName);
static bool CollectCalledMethods(CalledMethod* pCM, TADDR nativeCode, FunctionMemberPtrArrayHolder &method,
NewArrayHolder<Elf_Symbol> &symbolNames, int &symbolCount);
-#ifdef _DEBUG
- static void DumpElf(const char* methodName, const MemBuf& buf);
-#endif
};
class FunctionMember: public TypeMember