diff options
Diffstat (limited to 'packaging/0018-Support-FEATURE_GDBJIT_FRAME-including-NI-IL_Stub.patch')
-rw-r--r-- | packaging/0018-Support-FEATURE_GDBJIT_FRAME-including-NI-IL_Stub.patch | 1439 |
1 files changed, 1439 insertions, 0 deletions
diff --git a/packaging/0018-Support-FEATURE_GDBJIT_FRAME-including-NI-IL_Stub.patch b/packaging/0018-Support-FEATURE_GDBJIT_FRAME-including-NI-IL_Stub.patch new file mode 100644 index 0000000000..2b03965319 --- /dev/null +++ b/packaging/0018-Support-FEATURE_GDBJIT_FRAME-including-NI-IL_Stub.patch @@ -0,0 +1,1439 @@ +From d88953cc229dcbf5d93aa04711ee599b3d073094 Mon Sep 17 00:00:00 2001 +From: Jonghyun Park <parjong@gmail.com> +Date: Tue, 8 Aug 2017 01:27:16 +0900 +Subject: [PATCH 18/23] Support FEATURE_GDBJIT_FRAME (including NI & IL_Stub) + +--- + src/vm/CMakeLists.txt | 3 + + src/vm/gdbjit.cpp | 1108 ++++++++++++++++++++++++++++++++++--------------- + src/vm/gdbjit.h | 13 +- + src/vm/prestub.cpp | 29 +- + src/vm/util.cpp | 10 +- + 5 files changed, 813 insertions(+), 350 deletions(-) + +diff --git a/src/vm/CMakeLists.txt b/src/vm/CMakeLists.txt +index c610d3c..835e31c 100644 +--- a/src/vm/CMakeLists.txt ++++ b/src/vm/CMakeLists.txt +@@ -31,6 +31,9 @@ if(FEATURE_GDBJIT) + ) + add_definitions(-DFEATURE_GDBJIT) + endif(FEATURE_GDBJIT) ++if(FEATURE_GDBJIT_FRAME) ++ add_definitions(-DFEATURE_GDBJIT_FRAME) ++endif(FEATURE_GDBJIT_FRAME) + + set(VM_SOURCES_DAC_AND_WKS_COMMON + appdomain.cpp +diff --git a/src/vm/gdbjit.cpp b/src/vm/gdbjit.cpp +index ace6b76..5a3f074 100644 +--- a/src/vm/gdbjit.cpp ++++ b/src/vm/gdbjit.cpp +@@ -648,46 +648,6 @@ struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 }; + + // END of GDB JIT interface + +-/* Predefined section names */ +-const char* SectionNames[] = { +- "", +- ".text", +- ".shstrtab", +- ".debug_str", +- ".debug_abbrev", +- ".debug_info", +- ".debug_pubnames", +- ".debug_pubtypes", +- ".debug_line", +- ".symtab", +- ".strtab" +- /* After the last (.strtab) section zero or more .thunk_* sections are generated. +- +- Each .thunk_* section contains a single .thunk_#. +- These symbols are mapped to methods (or trampolines) called by currently compiled method. */ +-}; +- +-const int SectionNamesCount = sizeof(SectionNames) / sizeof(SectionNames[0]); // Does not include .thunk_* sections +- +-/* Static data for section headers */ +-struct SectionHeader { +- uint32_t m_type; +- uint64_t m_flags; +-} Sections[] = { +- {SHT_NULL, 0}, +- {SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR}, +- {SHT_STRTAB, 0}, +- {SHT_PROGBITS, SHF_MERGE | SHF_STRINGS }, +- {SHT_PROGBITS, 0}, +- {SHT_PROGBITS, 0}, +- {SHT_PROGBITS, 0}, +- {SHT_PROGBITS, 0}, +- {SHT_PROGBITS, 0}, +- {SHT_SYMTAB, 0}, +- {SHT_STRTAB, 0}, +- {SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR} +-}; +- + /* Static data for .debug_str section */ + const char* DebugStrings[] = { + "CoreCLR", "" /* module name */, "" /* module path */ +@@ -1748,8 +1708,661 @@ static int getNextPrologueIndex(int from, const SymbolsInfo *lines, int nlines) + return -1; + } + ++static inline bool isListedModule(const WCHAR *wszModuleFile) ++{ ++ static NewArrayHolder<WCHAR> wszModuleNames = nullptr; ++ static DWORD cBytesNeeded = 0; ++ ++ // Get names of interesting modules from environment ++ if (wszModuleNames == nullptr && cBytesNeeded == 0) ++ { ++ DWORD cCharsNeeded = GetEnvironmentVariableW(W("CORECLR_GDBJIT"), NULL, 0); ++ ++ if (cCharsNeeded == 0) ++ { ++ cBytesNeeded = 0xffffffff; ++ return false; ++ } ++ ++ WCHAR *wszModuleNamesBuf = new WCHAR[cCharsNeeded+1]; ++ ++ cCharsNeeded = GetEnvironmentVariableW(W("CORECLR_GDBJIT"), wszModuleNamesBuf, cCharsNeeded); ++ ++ if (cCharsNeeded == 0) ++ { ++ delete[] wszModuleNamesBuf; ++ cBytesNeeded = 0xffffffff; ++ return false; ++ } ++ ++ wszModuleNames = wszModuleNamesBuf; ++ cBytesNeeded = cCharsNeeded + 1; ++ } ++ else if (wszModuleNames == nullptr) ++ { ++ return false; ++ } ++ ++ _ASSERTE(wszModuleNames != nullptr && cBytesNeeded > 0); ++ ++ BOOL isUserDebug = FALSE; ++ ++ NewArrayHolder<WCHAR> wszModuleName = new WCHAR[cBytesNeeded]; ++ LPWSTR pComma = wcsstr(wszModuleNames, W(",")); ++ LPWSTR tmp = wszModuleNames; ++ ++ while (pComma != NULL) ++ { ++ wcsncpy(wszModuleName, tmp, pComma - tmp); ++ wszModuleName[pComma - tmp] = W('\0'); ++ ++ if (wcscmp(wszModuleName, wszModuleFile) == 0) ++ { ++ isUserDebug = TRUE; ++ break; ++ } ++ tmp = pComma + 1; ++ pComma = wcsstr(tmp, W(",")); ++ } ++ if (isUserDebug == FALSE) ++ { ++ wcsncpy(wszModuleName, tmp, wcslen(tmp)); ++ wszModuleName[wcslen(tmp)] = W('\0'); ++ if (wcscmp(wszModuleName, wszModuleFile) == 0) ++ { ++ isUserDebug = TRUE; ++ } ++ } ++ ++ return isUserDebug; ++} ++ + static NotifyGdb::AddrSet codeAddrs; + ++class Elf_SectionTracker ++{ ++ private: ++ unsigned int m_Flag; ++ ++ private: ++ NewArrayHolder<char> m_NamePtr; ++ unsigned int m_NameLen; ++ ++ private: ++ unsigned int m_Ind; ++ unsigned int m_Off; ++ unsigned int m_Len; ++ ++ private: ++ Elf_Shdr m_Hdr; ++ ++ private: ++ Elf_SectionTracker *m_Next; ++ ++ public: ++ Elf_SectionTracker(const char *name, unsigned ind, unsigned off, uint32_t type, uint64_t flags); ++ ~Elf_SectionTracker(); ++ ++ public: ++ bool NeedHeaderUpdate() const; ++ void DisableHeaderUpdate(); ++ ++ public: ++ unsigned int GetIndex() const { return m_Ind; } ++ unsigned int GetOffset() const { return m_Off; } ++ unsigned int GetSize() const { return m_Len; } ++ ++ public: ++ const char *GetName() const { return m_NamePtr; } ++ unsigned int GetNameLen() const { return m_NameLen; } ++ ++ public: ++ Elf_SectionTracker *GetNext(void); ++ void SetNext(Elf_SectionTracker *next); ++ ++ public: ++ void Forward(unsigned int len); ++ ++ public: ++ Elf_Shdr *Header(void); ++ const Elf_Shdr *Header(void) const; ++ ++}; ++ ++Elf_SectionTracker::Elf_SectionTracker(const char *name, ++ unsigned ind, unsigned off, ++ uint32_t type, uint64_t flags) ++ : m_Flag(0), ++ m_NamePtr(nullptr), ++ m_NameLen(0), ++ m_Ind(ind), ++ m_Off(off), ++ m_Len(0), ++ m_Next(nullptr) ++{ ++ if (name) ++ { ++ unsigned int len = strlen(name); ++ char *ptr = new char[len + 1]; ++ ++ strncpy(ptr, name, len + 1); ++ ++ m_NamePtr = ptr; ++ m_NameLen = len; ++ } ++ ++ m_Hdr.sh_type = type; ++ m_Hdr.sh_flags = flags; ++ m_Hdr.sh_name = 0; ++ m_Hdr.sh_addr = 0; ++ m_Hdr.sh_offset = 0; ++ m_Hdr.sh_size = 0; ++ m_Hdr.sh_link = SHN_UNDEF; ++ m_Hdr.sh_info = 0; ++ m_Hdr.sh_addralign = 1; ++ m_Hdr.sh_entsize = 0; ++} ++ ++Elf_SectionTracker::~Elf_SectionTracker() ++{ ++} ++ ++#define ESTF_NO_HEADER_UPDATE 0x00000001 ++ ++bool Elf_SectionTracker::NeedHeaderUpdate() const ++{ ++ return !(m_Flag & ESTF_NO_HEADER_UPDATE); ++} ++ ++void Elf_SectionTracker::DisableHeaderUpdate() ++{ ++ m_Flag |= ESTF_NO_HEADER_UPDATE; ++} ++ ++void Elf_SectionTracker::Forward(unsigned int len) ++{ ++ m_Len += len; ++} ++ ++void Elf_SectionTracker::SetNext(Elf_SectionTracker *next) ++{ ++ m_Next = next; ++} ++ ++Elf_SectionTracker *Elf_SectionTracker::GetNext(void) ++{ ++ return m_Next; ++} ++ ++Elf_Shdr *Elf_SectionTracker::Header(void) ++{ ++ return &m_Hdr; ++} ++ ++const Elf_Shdr *Elf_SectionTracker::Header(void) const ++{ ++ return &m_Hdr; ++} ++ ++class Elf_Buffer ++{ ++ private: ++ NewArrayHolder<char> m_Ptr; ++ unsigned int m_Len; ++ unsigned int m_Pos; ++ ++ public: ++ Elf_Buffer(unsigned int len); ++ ++ private: ++ char *Ensure(unsigned int len); ++ void Forward(unsigned int len); ++ ++ public: ++ unsigned int GetPos() const ++ { ++ return m_Pos; ++ } ++ ++ char *GetPtr(unsigned int off = 0) ++ { ++ return m_Ptr.GetValue() + off; ++ } ++ ++ public: ++ char *Reserve(unsigned int len); ++ template <typename T> T *ReserveT(unsigned int len = sizeof(T)) ++ { ++ _ASSERTE(len >= sizeof(T)); ++ return reinterpret_cast<T *>(Reserve(len)); ++ } ++ ++ public: ++ void Append(const char *src, unsigned int len); ++ template <typename T> void AppendT(T *src) ++ { ++ Append(reinterpret_cast<const char *>(src), sizeof(T)); ++ } ++}; ++ ++Elf_Buffer::Elf_Buffer(unsigned int len) ++ : m_Ptr(new char[len]) ++ , m_Len(len) ++ , m_Pos(0) ++{ ++} ++ ++char *Elf_Buffer::Ensure(unsigned int len) ++{ ++ bool bAdjusted = false; ++ ++ while (m_Pos + len > m_Len) ++ { ++ m_Len *= 2; ++ bAdjusted = true; ++ } ++ ++ if (bAdjusted) ++ { ++ char *ptr = new char [m_Len * 2]; ++ memcpy(ptr, m_Ptr.GetValue(), m_Pos); ++ m_Ptr = ptr; ++ } ++ ++ return GetPtr(m_Pos); ++} ++ ++void Elf_Buffer::Forward(unsigned int len) ++{ ++ m_Pos += len; ++} ++ ++char *Elf_Buffer::Reserve(unsigned int len) ++{ ++ char *ptr = Ensure(len); ++ Forward(len); ++ return ptr; ++} ++ ++void Elf_Buffer::Append(const char *src, unsigned int len) ++{ ++ char *dst = Reserve(len); ++ memcpy(dst, src, len); ++} ++ ++#define ELF_BUILDER_TEXT_SECTION_INDEX 1 ++ ++class Elf_Builder ++{ ++ private: ++ Elf_Buffer m_Buffer; ++ ++ private: ++ unsigned int m_SectionCount; ++ Elf_SectionTracker *m_First; ++ Elf_SectionTracker *m_Last; ++ Elf_SectionTracker *m_Curr; ++ ++ public: ++ Elf_Builder(); ++ ~Elf_Builder(); ++ ++ public: ++ unsigned int GetSectionCount(void) { return m_SectionCount; } ++ ++ public: ++ void Initialize(PCODE codePtr, TADDR codeLen); ++ ++ public: ++ Elf_SectionTracker *OpenSection(const char *name, uint32_t type, uint64_t flags); ++ void CloseSection(); ++ ++ public: ++ char *Reserve(unsigned int len); ++ template <typename T> T *ReserveT(unsigned int len = sizeof(T)) ++ { ++ _ASSERTE(len >= sizeof(T)); ++ return reinterpret_cast<T *>(Reserve(len)); ++ } ++ ++ public: ++ void Append(const char *src, unsigned int len); ++ template <typename T> void AppendT(T *src) ++ { ++ Append(reinterpret_cast<const char *>(src), sizeof(T)); ++ } ++ ++ public: ++ void Finalize(void); ++ ++ public: ++ char *Export(UINT64 *len); ++}; ++ ++Elf_Builder::Elf_Builder() ++ : m_Buffer(128), ++ m_SectionCount(0), ++ m_First(nullptr), ++ m_Last(nullptr), ++ m_Curr(nullptr) ++{ ++} ++ ++Elf_Builder::~Elf_Builder() ++{ ++ Elf_SectionTracker *curr = m_First; ++ ++ while (curr) ++ { ++ Elf_SectionTracker *next = curr->GetNext(); ++ delete curr; ++ curr = next; ++ } ++} ++ ++void Elf_Builder::Initialize(PCODE codePtr, TADDR codeLen) ++{ ++ // ++ // Reserve ELF Header ++ // ++ m_Buffer.Reserve(sizeof(Elf_Ehdr)); ++ ++ // ++ // Create NULL section ++ // ++ Elf_SectionTracker *null = OpenSection("", SHT_NULL, 0); ++ { ++ null->DisableHeaderUpdate(); ++ null->Header()->sh_addralign = 0; ++ } ++ CloseSection(); ++ ++ // ++ // Create '.text' section ++ // ++ Elf_SectionTracker *text = OpenSection(".text", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); ++ { ++ text->DisableHeaderUpdate(); ++ text->Header()->sh_addr = codePtr; ++ text->Header()->sh_size = codeLen; ++ ++ _ASSERTE(text->GetIndex() == ELF_BUILDER_TEXT_SECTION_INDEX); ++ } ++ CloseSection(); ++} ++ ++char *Elf_Builder::Reserve(unsigned int len) ++{ ++ _ASSERTE(m_Curr != nullptr && "Section should be opened before"); ++ char *ptr = m_Buffer.Reserve(len); ++ m_Curr->Forward(len); ++ return ptr; ++} ++ ++void Elf_Builder::Append(const char *src, unsigned int len) ++{ ++ _ASSERTE(m_Curr != nullptr && "Section should be opened before"); ++ char *dst = Reserve(len); ++ memcpy(dst, src, len); ++} ++ ++Elf_SectionTracker *Elf_Builder::OpenSection(const char *name, uint32_t type, uint64_t flags) ++{ ++ _ASSERTE(m_Curr == nullptr && "Section should be closed before"); ++ ++ Elf_SectionTracker *next = new Elf_SectionTracker(name, m_SectionCount, m_Buffer.GetPos(), type, flags); ++ ++ if (m_First == NULL) ++ { ++ m_First = next; ++ } ++ ++ if (m_Last != NULL) ++ { ++ m_Last->SetNext(next); ++ } ++ ++ m_SectionCount++; ++ ++ m_Last = next; ++ m_Curr = next; ++ ++ return next; ++} ++ ++void Elf_Builder::CloseSection() ++{ ++ _ASSERTE(m_Curr != nullptr && "Section should be opened before"); ++ m_Curr = nullptr; ++} ++ ++char *Elf_Builder::Export(UINT64 *pLen) ++{ ++ unsigned int len = m_Buffer.GetPos(); ++ const char *src = m_Buffer.GetPtr(); ++ char *dst = new char[len]; ++ ++ memcpy(dst, src, len); ++ ++ if (pLen) ++ { ++ *pLen = len; ++ } ++ ++ return dst; ++} ++ ++void Elf_Builder::Finalize() ++{ ++ // ++ // Create '.shstrtab' ++ // ++ Elf_SectionTracker *shstrtab = OpenSection(".shstrtab", SHT_STRTAB, 0); ++ { ++ Elf_SectionTracker *curr = m_First; ++ ++ while (curr) ++ { ++ unsigned int off = shstrtab->GetSize(); ++ unsigned int len = curr->GetNameLen(); ++ ++ char *dst = Reserve(len + 1); ++ memcpy(dst, curr->GetName(), len); ++ dst[len] = '\0'; ++ ++ curr->Header()->sh_name = off; ++ ++ curr = curr->GetNext(); ++ } ++ } ++ CloseSection(); ++ ++ // ++ // Create Section Header(s) Table ++ // ++ unsigned int shtOffset = m_Buffer.GetPos(); ++ { ++ Elf_SectionTracker *curr = m_First; ++ ++ while (curr) ++ { ++ if (curr->NeedHeaderUpdate()) ++ { ++ curr->Header()->sh_offset = curr->GetOffset(); ++ curr->Header()->sh_size = curr->GetSize(); ++ } ++ m_Buffer.AppendT(curr->Header()); ++ curr = curr->GetNext(); ++ } ++ } ++ ++ // ++ // Update ELF Header ++ // ++ Elf_Ehdr *elfHeader = new (m_Buffer.GetPtr()) Elf_Ehdr; ++ ++#ifdef _TARGET_ARM_ ++ elfHeader->e_flags = EF_ARM_EABI_VER5; ++#ifdef ARM_SOFTFP ++ elfHeader->e_flags |= EF_ARM_SOFT_FLOAT; ++#else ++ elfHeader->e_flags |= EF_ARM_VFP_FLOAT; ++#endif ++#endif ++ elfHeader->e_shoff = shtOffset; ++ elfHeader->e_shentsize = sizeof(Elf_Shdr); ++ elfHeader->e_shnum = m_SectionCount; ++ elfHeader->e_shstrndx = shstrtab->GetIndex(); ++} ++ ++#ifdef FEATURE_GDBJIT_FRAME ++struct __attribute__((packed)) Length ++{ ++ UINT32 value; ++ ++ Length &operator=(UINT32 n) ++ { ++ value = n; ++ return *this; ++ } ++ ++ Length() ++ { ++ value = 0; ++ } ++}; ++ ++struct __attribute__((packed)) CIE ++{ ++ Length length; ++ UINT32 id; ++ UINT8 version; ++ UINT8 augmentation; ++ UINT8 code_alignment_factor; ++ INT8 data_alignment_factor; ++ UINT8 return_address_register; ++ UINT8 instructions[0]; ++}; ++ ++struct __attribute__((packed)) FDE ++{ ++ Length length; ++ UINT32 cie; ++ PCODE initial_location; ++ TADDR address_range; ++ UINT8 instructions[0]; ++}; ++ ++static void BuildDebugFrame(Elf_Builder &elfBuilder, PCODE pCode, TADDR codeSize) ++{ ++#if defined(_TARGET_ARM_) ++ const unsigned int code_alignment_factor = 2; ++ const int data_alignment_factor = -4; ++ ++ UINT8 cieCode[] = { ++ // DW_CFA_def_cfa 13[sp], 0 ++ 0x0c, 0x0d, 0x00, ++ }; ++ ++ UINT8 fdeCode[] = { ++ // DW_CFA_advance_loc 1 ++ 0x02, 0x01, ++ // DW_CFA_def_cfa_offset 8 ++ 0x0e, 0x08, ++ // DW_CFA_offset 11(r11), -8(= -4 * 2) ++ (0x02 << 6) | 0x0b, 0x02, ++ // DW_CFA_offset 14(lr), -4(= -4 * 1) ++ (0x02 << 6) | 0x0e, 0x01, ++ // DW_CFA_def_cfa_register 11(r11) ++ 0x0d, 0x0b, ++ }; ++#elif defined(_TARGET_X86_) ++ const unsigned int code_alignment_factor = 1; ++ const int data_alignment_factor = -4; ++ ++ UINT8 cieCode[] = { ++ // DW_CFA_def_cfa 4(esp), 4 ++ 0x0c, 0x04, 0x04, ++ // DW_CFA_offset 8(eip), -4(= -4 * 1) ++ (0x02 << 6) | 0x08, 0x01, ++ }; ++ ++ UINT8 fdeCode[] = { ++ // DW_CFA_advance_loc 1 ++ 0x02, 0x01, ++ // DW_CFA_def_cfa_offset 8 ++ 0x0e, 0x08, ++ // DW_CFA_offset 5(ebp), -8(= -4 * 2) ++ (0x02 << 6) | 0x05, 0x02, ++ // DW_CFA_def_cfa_register 5(ebp) ++ 0x0d, 0x05, ++ }; ++#elif defined(_TARGET_AMD64_) ++ const unsigned int code_alignment_factor = 1; ++ const int data_alignment_factor = -8; ++ ++ UINT8 cieCode[] = { ++ // DW_CFA_def_cfa 7(rsp), 8 ++ 0x0c, 0x07, 0x08, ++ // DW_CFA_offset 16, -16 (= -8 * 2) ++ (0x02 << 6) | 0x10, 0x01, ++ }; ++ ++ UINT8 fdeCode[] = { ++ // DW_CFA_advance_loc(1) ++ 0x02, 0x01, ++ // DW_CFA_def_cfa_offset(16) ++ 0x0e, 0x10, ++ // DW_CFA_offset 6, -16 (= -8 * 2) ++ (0x02 << 6) | 0x06, 0x02, ++ // DW_CFA_def_cfa_register(6) ++ 0x0d, 0x06, ++ }; ++#else ++#error "Unsupported architecture" ++#endif ++ ++ elfBuilder.OpenSection(".debug_frame", SHT_PROGBITS, 0); ++ ++ // ++ // Common Information Entry ++ // ++ int cieLen = ALIGN_UP(sizeof(CIE) + sizeof(cieCode), ADDRESS_SIZE) + sizeof(Length); ++ ++ CIE *pCIE = elfBuilder.ReserveT<CIE>(cieLen); ++ ++ memset(pCIE, 0, cieLen); ++ ++ pCIE->length = cieLen - sizeof(Length); ++ pCIE->id = 0xffffffff; ++ pCIE->version = 3; ++ pCIE->augmentation = 0; ++ Leb128Encode(code_alignment_factor, reinterpret_cast<char *>(&pCIE->code_alignment_factor), 1); ++ Leb128Encode(data_alignment_factor, reinterpret_cast<char *>(&pCIE->data_alignment_factor), 1); ++ ++ pCIE->return_address_register = 0; ++ ++ memcpy(&pCIE->instructions, cieCode, sizeof(cieCode)); ++ ++ // ++ // Frame Description Entry ++ // ++ int fdeLen = ALIGN_UP((sizeof(FDE) + sizeof(fdeCode)), ADDRESS_SIZE) + sizeof(Length); ++ ++ FDE *pFDE = elfBuilder.ReserveT<FDE>(fdeLen); ++ ++ memset(pFDE, 0, fdeLen); ++ ++ pFDE->length = fdeLen - sizeof(Length); ++ pFDE->cie = 0; ++ pFDE->initial_location = pCode; ++ pFDE->address_range = codeSize; ++ memcpy(&pFDE->instructions, fdeCode, sizeof(fdeCode)); ++ ++ elfBuilder.CloseSection(); ++} ++#endif // FEATURE_GDBJIT_FRAME ++ + /* Create ELF/DWARF debug info for jitted method */ + void NotifyGdb::MethodCompiled(MethodDesc* methodDescPtr) + { +@@ -1765,19 +2378,21 @@ void NotifyGdb::MethodCompiled(MethodDesc* methodDescPtr) + + void NotifyGdb::OnMethodCompiled(MethodDesc* methodDescPtr) + { +- int symbolCount = 0; +- NewArrayHolder<Elf_Symbol> symbolNames; +- + PCODE pCode = methodDescPtr->GetNativeCode(); ++ + if (pCode == NULL) ++ { + return; +- unsigned int symInfoLen = 0; +- NewArrayHolder<SymbolsInfo> symInfo = nullptr; +- LocalsInfo locals; ++ } + + /* Get method name & size of jitted code */ +- LPCUTF8 methodName = methodDescPtr->GetName(); + EECodeInfo codeInfo(pCode); ++ ++ if (!codeInfo.IsValid()) ++ { ++ return; ++ } ++ + TADDR codeSize = codeInfo.GetCodeManager()->GetFunctionSize(codeInfo.GetGCInfoToken()); + + pCode = PCODEToPINSTR(pCode); +@@ -1800,59 +2415,76 @@ void NotifyGdb::OnMethodCompiled(MethodDesc* methodDescPtr) + if (length == 0) + return; + +- static NewArrayHolder<WCHAR> wszModuleNames = nullptr; +- DWORD cCharsNeeded = 0; ++ bool bNotify = false; + +- // Get names of interesting modules from environment +- if (wszModuleNames == nullptr) ++ Elf_Builder elfBuilder; ++ ++ elfBuilder.Initialize(pCode, codeSize); ++ ++#ifdef FEATURE_GDBJIT_FRAME + { +- cCharsNeeded = GetEnvironmentVariableW(W("CORECLR_GDBJIT"), NULL, 0); ++ bool bEmitted = EmitFrameInfo(elfBuilder, pCode, codeSize); ++ bNotify = bNotify || bEmitted; ++ } ++#endif + +- if(cCharsNeeded == 0) +- return; +- wszModuleNames = new WCHAR[cCharsNeeded+1]; +- cCharsNeeded = GetEnvironmentVariableW(W("CORECLR_GDBJIT"), wszModuleNames, cCharsNeeded); +- if(cCharsNeeded == 0) +- return; ++ if (isListedModule(wszModuleFile)) ++ { ++ bool bEmitted = EmitDebugInfo(elfBuilder, methodDescPtr, pCode, codeSize, szModuleFile); ++ bNotify = bNotify || bEmitted; + } +- else ++ ++ if (!bNotify) + { +- cCharsNeeded = wcslen(wszModuleNames); ++ return; + } + +- BOOL isUserDebug = FALSE; ++ elfBuilder.Finalize(); + +- NewArrayHolder<WCHAR> wszModuleName = new WCHAR[cCharsNeeded+1]; +- LPWSTR pComma = wcsstr(wszModuleNames, W(",")); +- LPWSTR tmp = wszModuleNames; ++ /* Create GDB JIT structures */ ++ NewHolder<jit_code_entry> jit_symbols = new jit_code_entry; + +- while (pComma != NULL) +- { +- wcsncpy(wszModuleName, tmp, pComma - tmp); +- wszModuleName[pComma - tmp] = W('\0'); ++ /* Fill the new entry */ ++ jit_symbols->next_entry = jit_symbols->prev_entry = 0; ++ jit_symbols->symfile_addr = elfBuilder.Export(&jit_symbols->symfile_size); + +- if (wcscmp(wszModuleName, wszModuleFile) == 0) +- { +- isUserDebug = TRUE; +- break; +- } +- tmp = pComma + 1; +- pComma = wcsstr(tmp, W(",")); +- } +- if (isUserDebug == FALSE) ++ /* Link into list */ ++ jit_code_entry *head = __jit_debug_descriptor.first_entry; ++ __jit_debug_descriptor.first_entry = jit_symbols; ++ if (head != 0) + { +- wcsncpy(wszModuleName, tmp, wcslen(tmp)); +- wszModuleName[wcslen(tmp)] = W('\0'); +- if (wcscmp(wszModuleName, wszModuleFile) == 0) +- { +- isUserDebug = TRUE; +- } ++ jit_symbols->next_entry = head; ++ head->prev_entry = jit_symbols; + } + +- if (isUserDebug == FALSE) +- { +- return; +- } ++ jit_symbols.SuppressRelease(); ++ ++ /* Notify the debugger */ ++ __jit_debug_descriptor.relevant_entry = jit_symbols; ++ __jit_debug_descriptor.action_flag = JIT_REGISTER_FN; ++ __jit_debug_register_code(); ++} ++ ++#ifdef FEATURE_GDBJIT_FRAME ++bool NotifyGdb::EmitFrameInfo(Elf_Builder &elfBuilder, PCODE pCode, TADDR codeSize) ++{ ++ BuildDebugFrame(elfBuilder, pCode, codeSize); ++ return true; ++} ++#endif // FEATURE_GDBJIT_FRAME ++ ++bool NotifyGdb::EmitDebugInfo(Elf_Builder &elfBuilder, MethodDesc* methodDescPtr, PCODE pCode, TADDR codeSize, const char *szModuleFile) ++{ ++ unsigned int thunkIndexBase = elfBuilder.GetSectionCount(); ++ ++ LPCUTF8 methodName = methodDescPtr->GetName(); ++ ++ int symbolCount = 0; ++ NewArrayHolder<Elf_Symbol> symbolNames; ++ ++ unsigned int symInfoLen = 0; ++ NewArrayHolder<SymbolsInfo> symInfo = nullptr; ++ LocalsInfo locals; + + NewHolder<TK_TypeInfoMap> pTypeMap = new TK_TypeInfoMap(); + +@@ -1860,7 +2492,7 @@ void NotifyGdb::OnMethodCompiled(MethodDesc* methodDescPtr) + HRESULT hr = GetDebugInfoFromPDB(methodDescPtr, symInfo, symInfoLen, locals); + if (FAILED(hr) || symInfoLen == 0) + { +- return; ++ return false; + } + + int method_count = countFuncs(symInfo, symInfoLen); +@@ -1871,7 +2503,7 @@ void NotifyGdb::OnMethodCompiled(MethodDesc* methodDescPtr) + /* Collect addresses of thunks called by method */ + if (!CollectCalledMethods(pCalledMethods, (TADDR)methodDescPtr->GetNativeCode(), method, symbolNames, symbolCount)) + { +- return; ++ return false; + } + pCH->SetCalledMethods(NULL); + +@@ -1887,7 +2519,7 @@ void NotifyGdb::OnMethodCompiled(MethodDesc* methodDescPtr) + + if (firstLineIndex >= symInfoLen) + { +- return; ++ return false; + } + + int start_index = getNextPrologueIndex(0, symInfo, symInfoLen); +@@ -1921,19 +2553,19 @@ void NotifyGdb::OnMethodCompiled(MethodDesc* methodDescPtr) + start_index = end_index; + } + +- MemBuf elfHeader, sectHeaders, sectStr, sectSymTab, sectStrTab, dbgInfo, dbgAbbrev, dbgPubname, dbgPubType, dbgLine, +- dbgStr, elfFile; ++ MemBuf sectSymTab, sectStrTab, dbgInfo, dbgAbbrev, dbgPubname, dbgPubType, dbgLine, ++ dbgStr; + + /* Build .debug_abbrev section */ + if (!BuildDebugAbbrev(dbgAbbrev)) + { +- return; ++ return false; + } + + /* Build .debug_line section */ + if (!BuildLineTable(dbgLine, pCode, codeSize, symInfo, symInfoLen)) + { +- return; ++ return false; + } + + DebugStrings[1] = szModuleFile; +@@ -1941,13 +2573,13 @@ void NotifyGdb::OnMethodCompiled(MethodDesc* methodDescPtr) + /* Build .debug_str section */ + if (!BuildDebugStrings(dbgStr, pTypeMap, method)) + { +- return; ++ return false; + } + + /* Build .debug_info section */ + if (!BuildDebugInfo(dbgInfo, pTypeMap, method)) + { +- return; ++ return false; + } + + for (int i = 0; i < method.GetCount(); ++i) +@@ -1959,13 +2591,13 @@ void NotifyGdb::OnMethodCompiled(MethodDesc* methodDescPtr) + /* Build .debug_pubname section */ + if (!BuildDebugPub(dbgPubname, methodName, dbgInfo.MemSize, 0x28)) + { +- return; ++ return false; + } + + /* Build debug_pubtype section */ + if (!BuildDebugPub(dbgPubType, "int", dbgInfo.MemSize, 0x1a)) + { +- return; ++ return false; + } + + /* Build .strtab section */ +@@ -1979,158 +2611,64 @@ void NotifyGdb::OnMethodCompiled(MethodDesc* methodDescPtr) + } + if (!BuildStringTableSection(sectStrTab, symbolNames, symbolCount)) + { +- return; ++ return false; + } + /* Build .symtab section */ +- if (!BuildSymbolTableSection(sectSymTab, pCode, codeSize, method, symbolNames, symbolCount)) ++ if (!BuildSymbolTableSection(sectSymTab, pCode, codeSize, method, symbolNames, symbolCount, thunkIndexBase)) + { +- return; ++ return false; + } + +- /* Build section headers table and section names table */ +- BuildSectionTables(sectHeaders, sectStr, method, symbolCount); +- +- /* Patch section offsets & sizes */ +- long offset = sizeof(Elf_Ehdr); +- Elf_Shdr* pShdr = reinterpret_cast<Elf_Shdr*>(sectHeaders.MemPtr.GetValue()); +- ++pShdr; // .text +- pShdr->sh_addr = pCode; +- pShdr->sh_size = codeSize; +- ++pShdr; // .shstrtab +- pShdr->sh_offset = offset; +- pShdr->sh_size = sectStr.MemSize; +- offset += sectStr.MemSize; +- ++pShdr; // .debug_str +- pShdr->sh_offset = offset; +- pShdr->sh_size = dbgStr.MemSize; +- offset += dbgStr.MemSize; +- ++pShdr; // .debug_abbrev +- pShdr->sh_offset = offset; +- pShdr->sh_size = dbgAbbrev.MemSize; +- offset += dbgAbbrev.MemSize; +- ++pShdr; // .debug_info +- pShdr->sh_offset = offset; +- pShdr->sh_size = dbgInfo.MemSize; +- offset += dbgInfo.MemSize; +- ++pShdr; // .debug_pubnames +- pShdr->sh_offset = offset; +- pShdr->sh_size = dbgPubname.MemSize; +- offset += dbgPubname.MemSize; +- ++pShdr; // .debug_pubtypes +- pShdr->sh_offset = offset; +- pShdr->sh_size = dbgPubType.MemSize; +- offset += dbgPubType.MemSize; +- ++pShdr; // .debug_line +- pShdr->sh_offset = offset; +- pShdr->sh_size = dbgLine.MemSize; +- offset += dbgLine.MemSize; +- ++pShdr; // .symtab +- pShdr->sh_offset = offset; +- pShdr->sh_size = sectSymTab.MemSize; +- pShdr->sh_link = GetSectionIndex(".strtab"); +- offset += sectSymTab.MemSize; +- ++pShdr; // .strtab +- pShdr->sh_offset = offset; +- pShdr->sh_size = sectStrTab.MemSize; +- offset += sectStrTab.MemSize; +- +- // .thunks + for (int i = 1 + method.GetCount(); i < symbolCount; i++) + { +- ++pShdr; +- pShdr->sh_addr = PCODEToPINSTR(symbolNames[i].m_value); +- pShdr->sh_size = 8; +- } ++ char name[256]; + +- /* Build ELF header */ +- if (!BuildELFHeader(elfHeader)) +- { +- return; ++ sprintf_s(name, _countof(name), ".thunk_%i", i); ++ ++ Elf_SectionTracker *thunk = elfBuilder.OpenSection(name, SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR); ++ thunk->DisableHeaderUpdate(); ++ elfBuilder.CloseSection(); + } +- Elf_Ehdr* header = reinterpret_cast<Elf_Ehdr*>(elfHeader.MemPtr.GetValue()); +-#ifdef _TARGET_ARM_ +- header->e_flags = EF_ARM_EABI_VER5; +-#ifdef ARM_SOFTFP +- header->e_flags |= EF_ARM_SOFT_FLOAT; +-#else +- header->e_flags |= EF_ARM_VFP_FLOAT; +-#endif +-#endif +- header->e_shoff = offset; +- header->e_shentsize = sizeof(Elf_Shdr); +- int thunks_count = symbolCount - method.GetCount() - 1; +- header->e_shnum = SectionNamesCount + thunks_count; +- header->e_shstrndx = GetSectionIndex(".shstrtab"); +- +- /* Build ELF image in memory */ +- elfFile.MemSize = elfHeader.MemSize + sectStr.MemSize + dbgStr.MemSize + dbgAbbrev.MemSize + dbgInfo.MemSize + +- dbgPubname.MemSize + dbgPubType.MemSize + dbgLine.MemSize + sectSymTab.MemSize + +- sectStrTab.MemSize + sectHeaders.MemSize; +- elfFile.MemPtr = new char[elfFile.MemSize]; +- +- /* Copy section data */ +- offset = 0; +- memcpy(elfFile.MemPtr, elfHeader.MemPtr, elfHeader.MemSize); +- offset += elfHeader.MemSize; +- memcpy(elfFile.MemPtr + offset, sectStr.MemPtr, sectStr.MemSize); +- offset += sectStr.MemSize; +- memcpy(elfFile.MemPtr + offset, dbgStr.MemPtr, dbgStr.MemSize); +- offset += dbgStr.MemSize; +- memcpy(elfFile.MemPtr + offset, dbgAbbrev.MemPtr, dbgAbbrev.MemSize); +- offset += dbgAbbrev.MemSize; +- memcpy(elfFile.MemPtr + offset, dbgInfo.MemPtr, dbgInfo.MemSize); +- offset += dbgInfo.MemSize; +- memcpy(elfFile.MemPtr + offset, dbgPubname.MemPtr, dbgPubname.MemSize); +- offset += dbgPubname.MemSize; +- memcpy(elfFile.MemPtr + offset, dbgPubType.MemPtr, dbgPubType.MemSize); +- offset += dbgPubType.MemSize; +- memcpy(elfFile.MemPtr + offset, dbgLine.MemPtr, dbgLine.MemSize); +- offset += dbgLine.MemSize; +- memcpy(elfFile.MemPtr + offset, sectSymTab.MemPtr, sectSymTab.MemSize); +- offset += sectSymTab.MemSize; +- memcpy(elfFile.MemPtr + offset, sectStrTab.MemPtr, sectStrTab.MemSize); +- offset += sectStrTab.MemSize; +- +- memcpy(elfFile.MemPtr + offset, sectHeaders.MemPtr, sectHeaders.MemSize); +- +- elfFile.MemPtr.SuppressRelease(); +- +-#ifdef GDBJIT_DUMPELF +- DumpElf(methodName, elfFile); +-#endif + +- /* Create GDB JIT structures */ +- NewHolder<jit_code_entry> jit_symbols = new jit_code_entry; ++ elfBuilder.OpenSection(".debug_str", SHT_PROGBITS, SHF_MERGE | SHF_STRINGS); ++ elfBuilder.Append(dbgStr.MemPtr, dbgStr.MemSize); ++ elfBuilder.CloseSection(); + +- /* Fill the new entry */ +- jit_symbols->next_entry = jit_symbols->prev_entry = 0; +- jit_symbols->symfile_addr = elfFile.MemPtr; +- jit_symbols->symfile_size = elfFile.MemSize; +- +- /* Link into list */ +- jit_code_entry *head = __jit_debug_descriptor.first_entry; +- __jit_debug_descriptor.first_entry = jit_symbols; +- if (head != 0) +- { +- jit_symbols->next_entry = head; +- head->prev_entry = jit_symbols; +- } +- +- jit_symbols.SuppressRelease(); ++ elfBuilder.OpenSection(".debug_abbrev", SHT_PROGBITS, 0); ++ elfBuilder.Append(dbgAbbrev.MemPtr, dbgAbbrev.MemSize); ++ elfBuilder.CloseSection(); + +- /* Notify the debugger */ +- __jit_debug_descriptor.relevant_entry = jit_symbols; +- __jit_debug_descriptor.action_flag = JIT_REGISTER_FN; +- __jit_debug_register_code(); ++ elfBuilder.OpenSection(".debug_info", SHT_PROGBITS, 0); ++ elfBuilder.Append(dbgInfo.MemPtr, dbgInfo.MemSize); ++ elfBuilder.CloseSection(); ++ ++ elfBuilder.OpenSection(".debug_pubnames", SHT_PROGBITS, 0); ++ elfBuilder.Append(dbgPubname.MemPtr, dbgPubname.MemSize); ++ elfBuilder.CloseSection(); ++ ++ elfBuilder.OpenSection(".debug_pubtypes", SHT_PROGBITS, 0); ++ elfBuilder.Append(dbgPubType.MemPtr, dbgPubType.MemSize); ++ elfBuilder.CloseSection(); ++ ++ elfBuilder.OpenSection(".debug_line", SHT_PROGBITS, 0); ++ elfBuilder.Append(dbgLine.MemPtr, dbgLine.MemSize); ++ elfBuilder.CloseSection(); ++ ++ Elf_SectionTracker *strtab = elfBuilder.OpenSection(".strtab", SHT_STRTAB, 0); ++ elfBuilder.Append(sectStrTab.MemPtr, sectStrTab.MemSize); ++ elfBuilder.CloseSection(); ++ ++ Elf_SectionTracker *symtab = elfBuilder.OpenSection(".symtab", SHT_SYMTAB, 0); ++ elfBuilder.Append(sectSymTab.MemPtr, sectSymTab.MemSize); ++ symtab->Header()->sh_link = strtab->GetIndex(); ++ symtab->Header()->sh_entsize = sizeof(Elf_Sym); ++ elfBuilder.CloseSection(); ++ ++ return true; + } + + void NotifyGdb::MethodDropped(MethodDesc* methodDescPtr) + { +- static const int textSectionIndex = GetSectionIndex(".text"); +- +- if (textSectionIndex < 0) +- return; +- + PCODE pCode = methodDescPtr->GetNativeCode(); + + if (pCode == NULL) +@@ -2144,7 +2682,7 @@ void NotifyGdb::MethodDropped(MethodDesc* methodDescPtr) + + const Elf_Ehdr* pEhdr = reinterpret_cast<const Elf_Ehdr*>(ptr); + const Elf_Shdr* pShdr = reinterpret_cast<const Elf_Shdr*>(ptr + pEhdr->e_shoff); +- pShdr += textSectionIndex; // bump to .text section ++ pShdr += ELF_BUILDER_TEXT_SECTION_INDEX; // bump to .text section + if (pShdr->sh_addr == pCode) + { + /* Notify the debugger */ +@@ -2637,10 +3175,9 @@ bool NotifyGdb::BuildStringTableSection(MemBuf& buf, NewArrayHolder<Elf_Symbol> + + /* Build ELF .symtab section */ + bool NotifyGdb::BuildSymbolTableSection(MemBuf& buf, PCODE addr, TADDR codeSize, FunctionMemberPtrArrayHolder &method, +- NewArrayHolder<Elf_Symbol> &symbolNames, int symbolCount) ++ NewArrayHolder<Elf_Symbol> &symbolNames, int symbolCount, ++ unsigned int thunkIndexBase) + { +- static const int textSectionIndex = GetSectionIndex(".text"); +- + buf.MemSize = symbolCount * sizeof(Elf_Sym); + buf.MemPtr = new char[buf.MemSize]; + +@@ -2659,7 +3196,7 @@ bool NotifyGdb::BuildSymbolTableSection(MemBuf& buf, PCODE addr, TADDR codeSize, + sym[i].setBindingAndType(STB_GLOBAL, STT_FUNC); + sym[i].st_other = 0; + sym[i].st_value = PINSTRToPCODE(symbolNames[i].m_value - addr); +- sym[i].st_shndx = textSectionIndex; ++ sym[i].st_shndx = ELF_BUILDER_TEXT_SECTION_INDEX; + sym[i].st_size = symbolNames[i].m_size; + } + +@@ -2668,7 +3205,7 @@ bool NotifyGdb::BuildSymbolTableSection(MemBuf& buf, PCODE addr, TADDR codeSize, + sym[i].st_name = symbolNames[i].m_off; + sym[i].setBindingAndType(STB_GLOBAL, STT_FUNC); + sym[i].st_other = 0; +- sym[i].st_shndx = SectionNamesCount + (i - (1 + method.GetCount())); // .thunks section index ++ sym[i].st_shndx = thunkIndexBase + (i - (1 + method.GetCount())); // .thunks section index + sym[i].st_size = 8; + #ifdef _TARGET_ARM_ + sym[i].st_value = 1; // for THUMB code +@@ -2679,97 +3216,6 @@ bool NotifyGdb::BuildSymbolTableSection(MemBuf& buf, PCODE addr, TADDR codeSize, + return true; + } + +-int NotifyGdb::GetSectionIndex(const char *sectName) +-{ +- for (int i = 0; i < SectionNamesCount; ++i) +- if (strcmp(SectionNames[i], sectName) == 0) +- return i; +- return -1; +-} +- +-/* Build the ELF section headers table and section names table */ +-void NotifyGdb::BuildSectionTables(MemBuf& sectBuf, MemBuf& strBuf, FunctionMemberPtrArrayHolder &method, +- int symbolCount) +-{ +- static const int symtabSectionIndex = GetSectionIndex(".symtab"); +- static const int nullSectionIndex = GetSectionIndex(""); +- +- const int thunks_count = symbolCount - 1 - method.GetCount(); +- +- // Approximate length of single section name. +- // Used only to reduce memory reallocations. +- static const int SECT_NAME_LENGTH = 11; +- +- strBuf.Resize(SECT_NAME_LENGTH * (SectionNamesCount + thunks_count)); +- +- Elf_Shdr* sectionHeaders = new Elf_Shdr[SectionNamesCount + thunks_count]; +- sectBuf.MemPtr = reinterpret_cast<char*>(sectionHeaders); +- sectBuf.MemSize = sizeof(Elf_Shdr) * (SectionNamesCount + thunks_count); +- +- Elf_Shdr* pSh = sectionHeaders; +- uint32_t sectNameOffset = 0; +- +- // Additional memory for remaining section names, +- // grows twice on each reallocation. +- int addSize = SECT_NAME_LENGTH; +- +- // Fill section headers and names +- for (int i = 0; i < SectionNamesCount + thunks_count; ++i, ++pSh) +- { +- char thunkSectNameBuf[256]; // temporary buffer for .thunk_# section name +- const char *sectName; +- +- bool isThunkSection = i >= SectionNamesCount; +- if (isThunkSection) +- { +- sprintf_s(thunkSectNameBuf, _countof(thunkSectNameBuf), ".thunk_%i", i); +- sectName = thunkSectNameBuf; +- } +- else +- { +- sectName = SectionNames[i]; +- } +- +- // Ensure that there is enough memory for section name, +- // reallocate if necessary. +- pSh->sh_name = sectNameOffset; +- sectNameOffset += strlen(sectName) + 1; +- if (sectNameOffset > strBuf.MemSize) +- { +- // Allocate more memory for remaining section names +- strBuf.Resize(sectNameOffset + addSize); +- addSize *= 2; +- } +- +- strcpy(strBuf.MemPtr + pSh->sh_name, sectName); +- +- // All .thunk_* sections have the same type and flags +- int index = isThunkSection ? SectionNamesCount : i; +- pSh->sh_type = Sections[index].m_type; +- pSh->sh_flags = Sections[index].m_flags; +- +- pSh->sh_addr = 0; +- pSh->sh_offset = 0; +- pSh->sh_size = 0; +- pSh->sh_link = SHN_UNDEF; +- pSh->sh_info = 0; +- pSh->sh_addralign = i == nullSectionIndex ? 0 : 1; +- pSh->sh_entsize = i == symtabSectionIndex ? sizeof(Elf_Sym) : 0; +- } +- +- // Set actual used size to avoid garbage in ELF section +- strBuf.MemSize = sectNameOffset; +-} +- +-/* Build the ELF header */ +-bool NotifyGdb::BuildELFHeader(MemBuf& buf) +-{ +- Elf_Ehdr* header = new Elf_Ehdr; +- buf.MemPtr = reinterpret_cast<char*>(header); +- buf.MemSize = sizeof(Elf_Ehdr); +- return true; +-} +- + /* Split full path name into directory & file names */ + void NotifyGdb::SplitPathname(const char* path, const char*& pathName, const char*& fileName) + { +diff --git a/src/vm/gdbjit.h b/src/vm/gdbjit.h +index 84b9109..ebd5a7a 100644 +--- a/src/vm/gdbjit.h ++++ b/src/vm/gdbjit.h +@@ -324,6 +324,7 @@ public: + }; + + struct Elf_Symbol; ++class Elf_Builder; + + class NotifyGdb + { +@@ -404,12 +405,14 @@ private: + + static void OnMethodCompiled(MethodDesc* methodDescPtr); + +- static int GetSectionIndex(const char *sectName); +- static bool BuildELFHeader(MemBuf& buf); +- static void BuildSectionTables(MemBuf& sectBuf, MemBuf& strBuf, FunctionMemberPtrArrayHolder &method, +- int symbolCount); ++#ifdef FEATURE_GDBJIT_FRAME ++ static bool EmitFrameInfo(Elf_Builder &, PCODE pCode, TADDR codeSzie); ++#endif // FEATURE_GDBJIT_FRAME ++ static bool EmitDebugInfo(Elf_Builder &, MethodDesc* methodDescPtr, PCODE pCode, TADDR codeSize, const char *szModuleFile); ++ + static bool BuildSymbolTableSection(MemBuf& buf, PCODE addr, TADDR codeSize, FunctionMemberPtrArrayHolder &method, +- NewArrayHolder<Elf_Symbol> &symbolNames, int symbolCount); ++ NewArrayHolder<Elf_Symbol> &symbolNames, int symbolCount, ++ unsigned int thunkIndexBase); + static bool BuildStringTableSection(MemBuf& strTab, NewArrayHolder<Elf_Symbol> &symbolNames, int symbolCount); + static bool BuildDebugStrings(MemBuf& buf, PTK_TypeInfoMap pTypeMap, FunctionMemberPtrArrayHolder &method); + static bool BuildDebugAbbrev(MemBuf& buf); +diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp +index fccec51..88bd9de 100644 +--- a/src/vm/prestub.cpp ++++ b/src/vm/prestub.cpp +@@ -52,7 +52,12 @@ + #include "callcounter.h" + #endif + +-#ifndef DACCESS_COMPILE ++#if defined(FEATURE_GDBJIT) ++#include "gdbjit.h" ++__declspec(thread) bool tls_isSymReaderInProgress = false; ++#endif ++ ++#ifndef DACCESS_COMPILE + + EXTERN_C void STDCALL ThePreStub(); + +@@ -231,17 +236,13 @@ void DACNotifyCompilationFinished(MethodDesc *methodDesc) + + _ASSERTE(modulePtr); + +-#ifndef FEATURE_GDBJIT + // Are we listed? + USHORT jnt = jn.Requested((TADDR) modulePtr, t); + if (jnt & CLRDATA_METHNOTIFY_GENERATED) + { + // If so, throw an exception! +-#endif + DACNotify::DoJITNotification(methodDesc); +-#ifndef FEATURE_GDBJIT + } +-#endif + } + } + +@@ -678,6 +679,15 @@ Done: + LOG((LF_CORDB, LL_EVERYTHING, "MethodDesc::MakeJitWorker finished. Stub is" FMT_ADDR "\n", + DBG_ADDR(pCode))); + ++#if defined(FEATURE_GDBJIT) && defined(FEATURE_PAL) && !defined(CROSSGEN_COMPILE) ++ if (!tls_isSymReaderInProgress) ++ { ++ tls_isSymReaderInProgress = true; ++ NotifyGdb::MethodCompiled(this); ++ tls_isSymReaderInProgress = false; ++ } ++#endif ++ + return pCode; + } + +@@ -1568,6 +1578,15 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT) + } + #endif // FEATURE_INTERPRETER + } // end if (pCode == NULL) ++#if defined(FEATURE_GDBJIT) && defined(FEATURE_PAL) && !defined(CROSSGEN_COMPILE) ++ else if (!tls_isSymReaderInProgress) ++ { ++ tls_isSymReaderInProgress = true; ++ NotifyGdb::MethodCompiled(this); ++ tls_isSymReaderInProgress = false; ++ } ++#endif ++ + } // end else if (IsIL() || IsNoMetadata()) + else if (IsNDirect()) + { +diff --git a/src/vm/util.cpp b/src/vm/util.cpp +index da7d18c..9d9800b 100644 +--- a/src/vm/util.cpp ++++ b/src/vm/util.cpp +@@ -3315,7 +3315,6 @@ void InitializeClrNotifications() + + #if defined(FEATURE_GDBJIT) + #include "gdbjit.h" +-__declspec(thread) bool tls_isSymReaderInProgress = false; + #endif // FEATURE_GDBJIT + + // called from the runtime +@@ -3329,14 +3328,7 @@ void DACNotify::DoJITNotification(MethodDesc *MethodDescPtr) + MODE_PREEMPTIVE; + } + CONTRACTL_END; +-#if defined(FEATURE_GDBJIT) && defined(FEATURE_PAL) && !defined(CROSSGEN_COMPILE) +- if(!tls_isSymReaderInProgress) +- { +- tls_isSymReaderInProgress = true; +- NotifyGdb::MethodCompiled(MethodDescPtr); +- tls_isSymReaderInProgress = false; +- } +-#endif ++ + TADDR Args[2] = { JIT_NOTIFICATION, (TADDR) MethodDescPtr }; + DACNotifyExceptionHelper(Args, 2); + } +-- +1.9.1 + |