Core dump: Add symbols for commpage to core file

This commit is contained in:
Ingo Weinhold
2016-05-22 22:10:48 +02:00
parent 90f571868e
commit c60453fd79
2 changed files with 146 additions and 1 deletions
+9
View File
@@ -610,6 +610,7 @@ typedef struct {
#define NT_AREAS 0x61726561 /* areas */ #define NT_AREAS 0x61726561 /* areas */
#define NT_IMAGES 0x696d6167 /* images */ #define NT_IMAGES 0x696d6167 /* images */
#define NT_THREADS 0x74687264 /* threads */ #define NT_THREADS 0x74687264 /* threads */
#define NT_SYMBOLS 0x73796d73 /* symbols */
/* NT_TEAM: uint32 entrySize; Elf32_Note_Team; char[] args */ /* NT_TEAM: uint32 entrySize; Elf32_Note_Team; char[] args */
typedef struct { typedef struct {
@@ -731,6 +732,14 @@ typedef struct {
uint64 nth_stack_end; /* thread stack end address */ uint64 nth_stack_end; /* thread stack end address */
} Elf64_Note_Thread_Entry; } Elf64_Note_Thread_Entry;
/* NT_SYMBOLS:
* int32 imageId;
* uint32 symbolCount;
* uint32 entrySize;
* Elf{32,64}_Sym[count];
* char[] strings
*/
/*** inline functions ***/ /*** inline functions ***/
+137 -1
View File
@@ -17,7 +17,9 @@
#include <AutoDeleter.h> #include <AutoDeleter.h>
#include <commpage.h>
#include <condition_variable.h> #include <condition_variable.h>
#include <elf.h>
#include <kimage.h> #include <kimage.h>
#include <ksignal.h> #include <ksignal.h>
#include <team.h> #include <team.h>
@@ -260,13 +262,20 @@ struct ImageInfo : DoublyLinkedListLinkImpl<ImageInfo> {
fTextDelta(image->info.text_delta), fTextDelta(image->info.text_delta),
fSymbolTable((addr_t)image->info.symbol_table), fSymbolTable((addr_t)image->info.symbol_table),
fSymbolHash((addr_t)image->info.symbol_hash), 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() ~ImageInfo()
{ {
free(fName); free(fName);
_FreeSymbolData();
} }
static ImageInfo* Create(struct image* image) static ImageInfo* Create(struct image* image)
@@ -355,6 +364,72 @@ struct ImageInfo : DoublyLinkedListLinkImpl<ImageInfo> {
return fStringTable; 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: private:
image_id fId; image_id fId;
image_type fType; image_type fType;
@@ -371,6 +446,11 @@ private:
addr_t fSymbolTable; addr_t fSymbolTable;
addr_t fSymbolHash; addr_t fSymbolHash;
addr_t fStringTable; 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) if (error != B_OK)
return error; return error;
error = _WriteImageSymbolsNotes();
if (error != B_OK)
return error;
error = _WriteThreadsNote(); error = _WriteThreadsNote();
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -1342,6 +1426,58 @@ private:
return fFile.Status(); 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<typename Writer>
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<typename Writer> template<typename Writer>
void _WriteThreadsNote(Writer& writer) void _WriteThreadsNote(Writer& writer)
{ {