From c60453fd79d1f53488ffd9241129eb15c3a1c969 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 22 May 2016 17:21:25 +0200 Subject: [PATCH] Core dump: Add symbols for commpage to core file --- headers/os/kernel/elf.h | 9 ++ src/system/kernel/debug/core_dump.cpp | 138 +++++++++++++++++++++++++- 2 files changed, 146 insertions(+), 1 deletion(-) diff --git a/headers/os/kernel/elf.h b/headers/os/kernel/elf.h index 37aca69d9e..9445673dec 100644 --- a/headers/os/kernel/elf.h +++ b/headers/os/kernel/elf.h @@ -610,6 +610,7 @@ typedef struct { #define NT_AREAS 0x61726561 /* areas */ #define NT_IMAGES 0x696d6167 /* images */ #define NT_THREADS 0x74687264 /* threads */ +#define NT_SYMBOLS 0x73796d73 /* symbols */ /* NT_TEAM: uint32 entrySize; Elf32_Note_Team; char[] args */ typedef struct { @@ -731,6 +732,14 @@ typedef struct { uint64 nth_stack_end; /* thread stack end address */ } Elf64_Note_Thread_Entry; +/* NT_SYMBOLS: + * int32 imageId; + * uint32 symbolCount; + * uint32 entrySize; + * Elf{32,64}_Sym[count]; + * char[] strings + */ + /*** inline functions ***/ diff --git a/src/system/kernel/debug/core_dump.cpp b/src/system/kernel/debug/core_dump.cpp index 40c9209b21..088294ab1f 100644 --- a/src/system/kernel/debug/core_dump.cpp +++ b/src/system/kernel/debug/core_dump.cpp @@ -17,7 +17,9 @@ #include +#include #include +#include #include #include #include @@ -260,13 +262,20 @@ struct ImageInfo : DoublyLinkedListLinkImpl { fTextDelta(image->info.text_delta), fSymbolTable((addr_t)image->info.symbol_table), fSymbolHash((addr_t)image->info.symbol_hash), - fStringTable((addr_t)image->info.string_table) + fStringTable((addr_t)image->info.string_table), + fSymbolTableData(NULL), + fStringTableData(NULL), + fSymbolCount(0), + fStringTableSize(0) { + if (fName != NULL && strcmp(fName, "commpage") == 0) + _GetCommpageSymbols(); } ~ImageInfo() { free(fName); + _FreeSymbolData(); } static ImageInfo* Create(struct image* image) @@ -355,6 +364,72 @@ struct ImageInfo : DoublyLinkedListLinkImpl { return fStringTable; } + elf_sym* SymbolTableData() const + { + return fSymbolTableData; + } + + char* StringTableData() const + { + return fStringTableData; + } + + uint32 SymbolCount() const + { + return fSymbolCount; + } + + size_t StringTableSize() const + { + return fStringTableSize; + } + +private: + void _GetCommpageSymbols() + { + image_id commpageId = get_commpage_image(); + + // get the size of the tables + int32 symbolCount = 0; + size_t stringTableSize = 0; + status_t error = elf_read_kernel_image_symbols(commpageId, NULL, + &symbolCount, NULL, &stringTableSize, + NULL, true); + if (error != B_OK) + return; + if (symbolCount == 0 || stringTableSize == 0) + return; + + // allocate the tables + fSymbolTableData = (elf_sym*)malloc(sizeof(elf_sym) * symbolCount); + fStringTableData = (char*)malloc(stringTableSize); + if (fSymbolTableData == NULL || fStringTableData == NULL) { + _FreeSymbolData(); + return; + } + + fSymbolCount = symbolCount; + fStringTableSize = stringTableSize; + + // get the data + error = elf_read_kernel_image_symbols(commpageId, + fSymbolTableData, &symbolCount, fStringTableData, &stringTableSize, + NULL, true); + if (error != B_OK) + _FreeSymbolData(); + } + + void _FreeSymbolData() + { + free(fSymbolTableData); + free(fStringTableData); + + fSymbolTableData = NULL; + fStringTableData = NULL; + fSymbolCount = 0; + fStringTableSize = 0; + } + private: image_id fId; image_type fType; @@ -371,6 +446,11 @@ private: addr_t fSymbolTable; addr_t fSymbolHash; addr_t fStringTable; + // for commpage image + elf_sym* fSymbolTableData; + char* fStringTableData; + uint32 fSymbolCount; + size_t fStringTableSize; }; @@ -1146,6 +1226,10 @@ private: if (error != B_OK) return error; + error = _WriteImageSymbolsNotes(); + if (error != B_OK) + return error; + error = _WriteThreadsNote(); if (error != B_OK) return error; @@ -1342,6 +1426,58 @@ private: return fFile.Status(); } + status_t _WriteImageSymbolsNotes() + { + // write table + for (ImageInfoList::Iterator it = fImageInfos.GetIterator(); + ImageInfo* imageInfo = it.Next();) { + if (imageInfo->SymbolTableData() == NULL + || imageInfo->StringTableData() == NULL) { + continue; + } + + status_t error = _WriteImageSymbolsNote(imageInfo); + if (error != B_OK) + return error; + } + + return B_OK; + } + + template + void _WriteImageSymbolsNote(const ImageInfo* imageInfo, Writer& writer) + { + uint32 symbolCount = imageInfo->SymbolCount(); + uint32 symbolEntrySize = (uint32)sizeof(elf_sym); + + writer.Write((int32)imageInfo->Id()); + writer.Write(symbolCount); + writer.Write(symbolEntrySize); + writer.Write(imageInfo->SymbolTableData(), + symbolCount * symbolEntrySize); + writer.Write(imageInfo->StringTableData(), + imageInfo->StringTableSize()); + } + + status_t _WriteImageSymbolsNote(const ImageInfo* imageInfo) + { + // determine needed size for the note's data + DummyWriter dummyWriter; + _WriteImageSymbolsNote(imageInfo, dummyWriter); + size_t dataSize = dummyWriter.BytesWritten(); + + // write the note header + _WriteNoteHeader(kHaikuNote, NT_SYMBOLS, dataSize); + + // write the note data + _WriteImageSymbolsNote(imageInfo, fFile); + + // padding + _WriteNotePadding(dataSize); + + return fFile.Status(); + } + template void _WriteThreadsNote(Writer& writer) {