diff --git a/include/clasp/core/debugger.h b/include/clasp/core/debugger.h index b7536988b8..a3942be195 100644 --- a/include/clasp/core/debugger.h +++ b/include/clasp/core/debugger.h @@ -81,10 +81,15 @@ struct OpenDynamicLibraryInfo { gctools::clasp_ptr_t _LibraryStart; gctools::clasp_ptr_t _TextStart; gctools::clasp_ptr_t _TextEnd; + bool _HasVtableSection; + gctools::clasp_ptr_t _VtableSectionStart; + gctools::clasp_ptr_t _VtableSectionEnd; OpenDynamicLibraryInfo(const std::string& f, void* h, const SymbolTable& symbol_table, gctools::clasp_ptr_t libstart, - gctools::clasp_ptr_t textStart, gctools::clasp_ptr_t textEnd) - : _Filename(f), _Handle(h), _SymbolTable(symbol_table), _LibraryStart(libstart), _TextStart(textStart), - _TextEnd(textEnd){ + gctools::clasp_ptr_t textStart, gctools::clasp_ptr_t textEnd, + bool hasVtableSection, + gctools::clasp_ptr_t vtableSectionStart, gctools::clasp_ptr_t vtableSectionEnd) + : _Filename(f), _Handle(h), _SymbolTable(symbol_table), _LibraryStart(libstart), _TextStart(textStart), _TextEnd(textEnd), + _HasVtableSection(hasVtableSection), _VtableSectionStart(vtableSectionStart), _VtableSectionEnd(vtableSectionEnd) { // printf("%s:%d:%s filename = %s\n", __FILE__, __LINE__, __FUNCTION__, f.c_str() ); }; virtual LoadableKind loadableKind() const { return Library; }; @@ -92,14 +97,10 @@ struct OpenDynamicLibraryInfo { }; struct ExecutableLibraryInfo : OpenDynamicLibraryInfo { - bool _HasVtableSection; - gctools::clasp_ptr_t _VtableSectionStart; - gctools::clasp_ptr_t _VtableSectionEnd; ExecutableLibraryInfo(const std::string& f, void* h, const SymbolTable& symbol_table, gctools::clasp_ptr_t libstart, - gctools::clasp_ptr_t textStart, gctools::clasp_ptr_t textEnd, bool hasVtableSection, - gctools::clasp_ptr_t vtableSectionStart, gctools::clasp_ptr_t vtableSectionEnd) - : OpenDynamicLibraryInfo(f, h, symbol_table, libstart, textStart, textEnd), _HasVtableSection(hasVtableSection), - _VtableSectionStart(vtableSectionStart), _VtableSectionEnd(vtableSectionEnd) { + gctools::clasp_ptr_t textStart, gctools::clasp_ptr_t textEnd, + bool hasVtableSection, gctools::clasp_ptr_t vtableSectionStart, gctools::clasp_ptr_t vtableSectionEnd) + : OpenDynamicLibraryInfo(f, h, symbol_table, libstart, textStart, textEnd, hasVtableSection, vtableSectionStart, vtableSectionEnd ) { #if 0 printf("%s:%d:%s filename = %s\n", __FILE__, __LINE__, __FUNCTION__, f.c_str() ); if (vtableSectionStart==NULL) { @@ -215,6 +216,6 @@ DebugInfo& debugInfo(); void executablePath(std::string& name); void executableTextSectionRange(gctools::clasp_ptr_t& start, gctools::clasp_ptr_t& end); -void executableVtableSectionRange(gctools::clasp_ptr_t& start, gctools::clasp_ptr_t& end); +void exclusiveVtableSectionRange(gctools::clasp_ptr_t& start, gctools::clasp_ptr_t& end); }; // namespace core diff --git a/src/core/debug_unixes.cc b/src/core/debug_unixes.cc index 7756ef842d..ec45a380cd 100644 --- a/src/core/debug_unixes.cc +++ b/src/core/debug_unixes.cc @@ -304,23 +304,21 @@ CL_DEFUN void core__walk_loaded_objects() { } int elf_startup_loaded_object_callback(struct dl_phdr_info* info, size_t size, void* data) { - // printf("%s:%d:%s Startup registering loaded object %s\n", __FILE__, __LINE__, __FUNCTION__, info->dlpi_name); +// printf("%s:%d:%s --------- Startup registering loaded object %s\n", __FILE__, __LINE__, __FUNCTION__, info->dlpi_name); core::General_O general; gctools::clasp_ptr_t vtablePtr = *(gctools::clasp_ptr_t*)&general; - // printf("%s:%d:%s one vtablePtr = %p\n", __FILE__, __LINE__, __FUNCTION__, vtablePtr ); +// printf("%s:%d:%s a KNOWN vtablePtr = %p\n", __FILE__, __LINE__, __FUNCTION__, vtablePtr ); ScanInfo* scan_callback_info = (ScanInfo*)data; bool is_executable = false; const char* libname; if (scan_callback_info->_Index == 0 && strlen(info->dlpi_name) == 0) { libname = getExecutablePath(); is_executable = true; - // printf("%s:%d:%s getExecutablePath() libname %s is_executable = %d\n", __FILE__, __LINE__, __FUNCTION__, libname, - // is_executable ); +// printf("%s:%d:%s getExecutablePath() libname %s is_executable = %d\n", __FILE__, __LINE__, __FUNCTION__, libname, is_executable ); } else { libname = info->dlpi_name; is_executable = false; - // printf("%s:%d:%s info->dlpi_name libname %s is_executable = %d\n", __FILE__, __LINE__, __FUNCTION__, libname, is_executable - // ); +// printf("%s:%d:%s info->dlpi_name libname %s is_executable = %d\n", __FILE__, __LINE__, __FUNCTION__, libname, is_executable ); } gctools::clasp_ptr_t text_start; gctools::clasp_ptr_t text_end; @@ -335,8 +333,7 @@ int elf_startup_loaded_object_callback(struct dl_phdr_info* info, size_t size, v if (p_type == PT_LOAD && (info->dlpi_phdr[j].p_flags & 0x1)) { // executable text_start = (gctools::clasp_ptr_t)(info->dlpi_addr + info->dlpi_phdr[j].p_vaddr); text_end = (gctools::clasp_ptr_t)(text_start + info->dlpi_phdr[j].p_memsz); - // printf("%s:%d:%s text_start = %p text_end = %p\n low = %p high = %p vtablePtr = %p\n", __FILE__, __LINE__, - // __FUNCTION__, (void*)text_start, (void*)text_end, low, high, vtablePtr ); +// printf("%s:%d:%s text_start = %p text_end = %p low = %p high = %p\n", __FILE__, __LINE__, __FUNCTION__, (void*)text_start, (void*)text_end, low, high ); } if (low <= vtablePtr && vtablePtr < high) { // @@ -354,9 +351,9 @@ int elf_startup_loaded_object_callback(struct dl_phdr_info* info, size_t size, v hasVtableSection = true; vtableSectionStart = low; vtableSectionEnd = high; - // printf("%s:%d:%s set vtableSection Start/End = %p/%p\n", __FILE__, __LINE__, __FUNCTION__, low, high ); +// printf("%s:%d:%s set vtableSection Start/End = %p/%p\n", __FILE__, __LINE__, __FUNCTION__, low, high ); } - // printf("%s:%d:%s Found vtableSection %p to %p\n", __FILE__, __LINE__, __FUNCTION__, vtableSectionStart, vtableSectionEnd ); +// printf("%s:%d:%s Found vtableSection %p to %p\n", __FILE__, __LINE__, __FUNCTION__, vtableSectionStart, vtableSectionEnd ); } } // printf("%s:%d:%s About to call add_dynamic_library_using_origin libname = %s is_executable = %d\n", __FILE__, __LINE__, @@ -377,8 +374,7 @@ void startup_register_loaded_objects(add_dynamic_library* callback) { otherwise it uses handle to look up the start of the library. */ void add_dynamic_library_impl(add_dynamic_library* callback, bool is_executable, const std::string& libraryName, bool use_origin, uintptr_t library_origin, void* handle, gctools::clasp_ptr_t text_start, - gctools::clasp_ptr_t text_end, bool hasVtableSection, gctools::clasp_ptr_t vtableSectionStart, - gctools::clasp_ptr_t vtableSectionEnd) { + gctools::clasp_ptr_t text_end, bool hasVtableSection, gctools::clasp_ptr_t vtableSectionStart, gctools::clasp_ptr_t vtableSectionEnd) { // printf("%s:%d:%s libraryName = %s is_executable = %d\n", __FILE__, __LINE__, __FUNCTION__, libraryName.c_str(), is_executable // ); BT_LOG(("Starting to load library: %s\n", libraryName.c_str())); @@ -421,7 +417,8 @@ void add_dynamic_library_impl(add_dynamic_library* callback, bool is_executable, } else { // printf("%s:%d:%s Creating an OpenDynamicLibraryInfo\n", __FILE__, __LINE__, __FUNCTION__ ); odli = - new OpenDynamicLibraryInfo(libraryName, handle, symbol_table, (gctools::clasp_ptr_t)library_origin, text_start, text_end); + new OpenDynamicLibraryInfo(libraryName, handle, symbol_table, (gctools::clasp_ptr_t)library_origin, text_start, text_end, + hasVtableSection, vtableSectionStart, vtableSectionEnd ); loadable = Library; } TrapProblem trap(is_executable, libraryName, odli->loadableKind()); diff --git a/src/core/debugger.cc b/src/core/debugger.cc index a45e447b60..7970d3049b 100644 --- a/src/core/debugger.cc +++ b/src/core/debugger.cc @@ -199,18 +199,42 @@ void executablePath(std::string& name) { } SIMPLE_ERROR("Could not find the executablePath"); } -void executableVtableSectionRange(gctools::clasp_ptr_t& start, gctools::clasp_ptr_t& end) { + +void exclusiveVtableSectionRange(gctools::clasp_ptr_t& start, gctools::clasp_ptr_t& end) { WITH_READ_LOCK(debugInfo()._OpenDynamicLibraryMutex); + size_t numberOfVtableRanges = 0; for (auto& entry : debugInfo()._OpenDynamicLibraryHandles) { - if (entry.second->loadableKind() == Executable) { - ExecutableLibraryInfo* eli = dynamic_cast(entry.second); - start = eli->_VtableSectionStart; - end = eli->_VtableSectionEnd; + if (entry.second->_HasVtableSection) { + // This assumes there is only one vtable section!!!!!!! + start = entry.second->_VtableSectionStart; + end = entry.second->_VtableSectionEnd; + numberOfVtableRanges++; +// printf("%s:%d:%s vtableRange# %lu library: %s vtable section start %p end %p\n", __FILE__, __LINE__, __FUNCTION__, numberOfVtableRanges, entry.first.c_str(), start, end ); + } + } + if (numberOfVtableRanges>1) { + printf("%s:%d:%s There can be only one vtable range in the executable or dynamic libraries - if there is more than one then we need to rearrange things and identify the vtable range that contains snapshot save/load-able objects\n", __FILE__, __LINE__, __FUNCTION__); + gctools::wait_for_user_signal("About to exit"); + } else if (numberOfVtableRanges==0) { + printf("%s:%d:%s Could not find any vtable sections\n", __FILE__, __LINE__, __FUNCTION__); + gctools::wait_for_user_signal("About to exit"); + } +} + +CL_DEFUN void core__openDynamicLibraries() { + WITH_READ_LOCK(debugInfo()._OpenDynamicLibraryMutex); + for (auto& entry : debugInfo()._OpenDynamicLibraryHandles) { + printf("%s:%d:%s lib: %s exec %d\n", __FILE__, __LINE__, __FUNCTION__, entry.first.c_str(), entry.second->loadableKind()==Executable ); + void* textstart = entry.second->_TextStart; + void* textend = entry.second->_TextEnd; + printf("%s:%d:%s textStart: %p textEnd: %p \n", __FILE__, __LINE__, __FUNCTION__, textstart, textend ); + if (entry.second->_HasVtableSection) { + void* start = entry.second->_VtableSectionStart; + void* end = entry.second->_VtableSectionEnd; + printf("%s:%d:%s vtableStart: %p vtableEnd: %p \n", __FILE__, __LINE__, __FUNCTION__, start, end ); // printf("%s:%d:%s start %p end %p\n", __FILE__, __LINE__, __FUNCTION__, start, end ); - return; } } - SIMPLE_ERROR("Could not find the executableVtableSectionRange"); } void executableTextSectionRange(gctools::clasp_ptr_t& start, gctools::clasp_ptr_t& end) { @@ -222,12 +246,14 @@ void executableTextSectionRange(gctools::clasp_ptr_t& start, gctools::clasp_ptr_ return; } } - SIMPLE_ERROR("Could not find the executableVtableSectionRange"); + SIMPLE_ERROR("Could not find the executableTextSectionRange"); } bool lookup_address_in_library(gctools::clasp_ptr_t address, gctools::clasp_ptr_t& start, gctools::clasp_ptr_t& end, std::string& libraryName, bool& executable, uintptr_t& vtableStart, uintptr_t& vtableEnd) { WITH_READ_LOCK(debugInfo()._OpenDynamicLibraryMutex); + vtableStart = 0; + vtableEnd = 0; for (auto entry : debugInfo()._OpenDynamicLibraryHandles) { // printf("%s:%d:%s Looking at entry: %s start: %p end: %p\n", __FILE__, __LINE__, __FUNCTION__, // entry.second._Filename.c_str(), entry.second._LibraryStart, entry.second._LibraryEnd ); @@ -238,17 +264,22 @@ bool lookup_address_in_library(gctools::clasp_ptr_t address, gctools::clasp_ptr_ start = eli->_TextStart; end = eli->_TextEnd; executable = true; - vtableStart = (uintptr_t)eli->_VtableSectionStart; - vtableEnd = (uintptr_t)eli->_VtableSectionEnd; + if (eli->_HasVtableSection) { + vtableStart = (uintptr_t)eli->_VtableSectionStart; + vtableEnd = (uintptr_t)eli->_VtableSectionEnd; + } return true; } - } else if (entry.second->_TextStart <= address && address < entry.second->_TextEnd) { + } else if ((entry.second->_TextStart <= address && address < entry.second->_TextEnd) + || (entry.second->_HasVtableSection && entry.second->_VtableSectionStart<=address && address_VtableSectionEnd) ) { libraryName = entry.second->_Filename; start = entry.second->_TextStart; end = entry.second->_TextEnd; executable = false; - vtableStart = 0; // libraries don't have vtables we care about - vtableEnd = 0; + if (entry.second->_HasVtableSection) { + vtableStart = (uintptr_t)entry.second->_VtableSectionStart; // libraries don't have vtables we care about + vtableEnd = (uintptr_t)entry.second->_VtableSectionEnd; + } return true; } } @@ -280,8 +311,8 @@ bool library_with_name(const std::string& name, bool isExecutable, std::string& libraryName = entry.second->_Filename; start = (uintptr_t)(entry.second->_TextStart); end = (uintptr_t)(entry.second->_TextEnd); - vtableStart = 0; // (uintptr_t)entry.second->_VtableSectionStart; - vtableEnd = 0; // (uintptr_t)entry.second->_VtableSectionEnd; + vtableStart = (uintptr_t)entry.second->_VtableSectionStart; + vtableEnd = (uintptr_t)entry.second->_VtableSectionEnd; // printf("%s:%d:%s isExecutable = %d name = %s libraryName = %s\n", __FILE__, __LINE__, __FUNCTION__, isExecutable, // name.c_str(), libraryName.c_str()); return true; diff --git a/src/gctools/gcFunctions.cc b/src/gctools/gcFunctions.cc index d45d4fddf8..79d31413d3 100644 --- a/src/gctools/gcFunctions.cc +++ b/src/gctools/gcFunctions.cc @@ -473,6 +473,18 @@ CL_DEFUN core::T_mv gctools__memory_profile_status() { core::make_fixnum(allocationSizeCounter), core::make_fixnum(allocationSizeThreshold)); } + +CL_DEFUN core::T_sp gctools__object_address(core::General_sp generalObject) { + void* address = (void*)&(*generalObject); + printf("%s:%d:%s address = %p\n", __FILE__, __LINE__, __FUNCTION__, address ); + return nil(); +} +CL_DEFUN core::T_sp gctools__vtable_address(core::General_sp generalObject) { + void* vtable_ptr = *(void**)&(*generalObject); + printf("%s:%d:%s vtable pointer = %p\n", __FILE__, __LINE__, __FUNCTION__, vtable_ptr ); + return nil(); +} + DOCGROUP(clasp); CL_DEFUN core::T_sp gctools__stack_depth() { int z = 0; diff --git a/src/gctools/snapshotSaveLoad.cc b/src/gctools/snapshotSaveLoad.cc index 1ef91609a3..ebe2d4bad6 100644 --- a/src/gctools/snapshotSaveLoad.cc +++ b/src/gctools/snapshotSaveLoad.cc @@ -39,6 +39,10 @@ #include #include +// Turn on debugging vtable pointer updates with libraries +//#define DEBUG_ISLLIBRARIES 1 + + #ifdef _TARGET_OS_LINUX #include #endif @@ -2586,9 +2590,10 @@ void* snapshot_save_impl(void* data) { { DBG_SL_STEP(11, "snapshot_save fixing up vtable pointers\n"); + core::lisp_write(fmt::format("Fixup vtable pointers\n")); gctools::clasp_ptr_t start; gctools::clasp_ptr_t end; - core::executableVtableSectionRange(start, end); + core::exclusiveVtableSectionRange(start, end); fixup_vtables_t fixup_vtables(&fixup, (uintptr_t)start, (uintptr_t)end, &islInfo); walk_snapshot_save_load_objects((ISLHeader_s*)snapshot._Memory->_BufferStart, fixup_vtables); } @@ -3097,8 +3102,10 @@ void snapshot_load(void* maybeStartOfSnapshot, void* maybeEndOfSnapshot, const s if (fout) fflush(fout); // flush fout if it's defined. --arguments option was passed updateRelocationTableAfterLoad(lib, lookup); + //printf("%s:%d:%s Done updateRelocationTableAfterLoad pushing library with name: %s\n", __FILE__, __LINE__, __FUNCTION__, lib._Name.c_str() ); #ifdef DEBUG_ISLLIBRARIES - printf("%s:%d:%s Done updateRelocationTableAfterLoad pushing library with name: %s\n", __FILE__, __LINE__, __FUNCTION__, lib._Name.c_str() ); + printf("%s:%d:%s push_back lib: %s start: %p end: %p vtableStart: %p vtableEnd: %p\n", + __FILE__, __LINE__, __FUNCTION__, lib._Name.c_str(), lib._TextStart, lib._TextEnd, (void*)lib._VtableStart, (void*)lib._VtableEnd); #endif fixup._ISLLibraries.push_back(lib); } @@ -3119,7 +3126,7 @@ void snapshot_load(void* maybeStartOfSnapshot, void* maybeEndOfSnapshot, const s DBG_SL("2 snapshot_load fixing up vtable pointers\n"); gctools::clasp_ptr_t start; gctools::clasp_ptr_t end; - core::executableVtableSectionRange(start, end); + core::exclusiveVtableSectionRange(start, end); if (start == NULL) { printf("%s:%d:%s vtable section range start is NULL\n", __FILE__, __LINE__, __FUNCTION__); } @@ -3194,9 +3201,11 @@ void snapshot_load(void* maybeStartOfSnapshot, void* maybeEndOfSnapshot, const s DBG_SL("6 Allocate objects\n"); { ISLHeader_s* start_header = reinterpret_cast(islbuffer); +#if 0 gctools::clasp_ptr_t startVtables; gctools::clasp_ptr_t end; - core::executableVtableSectionRange(startVtables, end); + core::exclusiveVtableSectionRange(startVtables, end); +#endif ISLHeader_s* next_header; ISLHeader_s* cur_header;