Debugger: Add dedicated functions for global {un}init.
[haiku.git] / src / apps / debugger / elf / CoreFile.cpp
blobc4eb3ac5c80f5708b85bd2cab65d7656ab408a28
1 /*
2 * Copyright 2016, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "CoreFile.h"
9 #include <errno.h>
11 #include <algorithm>
13 #include <OS.h>
15 #include <AutoDeleter.h>
17 #include "ElfSymbolLookup.h"
18 #include "Tracing.h"
21 static const size_t kMaxNotesSize = 10 * 1024 * 1024;
24 // pragma mark - CoreFileTeamInfo
27 CoreFileTeamInfo::CoreFileTeamInfo()
29 fId(-1),
30 fUid(-1),
31 fGid(-1),
32 fArgs()
37 void
38 CoreFileTeamInfo::Init(int32 id, int32 uid, int32 gid, const BString& args)
40 fId = id;
41 fUid = uid;
42 fGid = gid;
43 fArgs = args;
47 // pragma mark - CoreFileAreaInfo
50 CoreFileAreaInfo::CoreFileAreaInfo(ElfSegment* segment, int32 id,
51 uint64 baseAddress, uint64 size, uint64 ramSize, uint32 locking,
52 uint32 protection, const BString& name)
54 fSegment(segment),
55 fBaseAddress(baseAddress),
56 fSize(size),
57 fRamSize(ramSize),
58 fLocking(locking),
59 fProtection(protection),
60 fId(-1)
65 // pragma mark - CoreFileImageInfo
68 CoreFileImageInfo::CoreFileImageInfo(int32 id, int32 type, uint64 initRoutine,
69 uint64 termRoutine, uint64 textBase, uint64 textSize, int64 textDelta,
70 uint64 dataBase, uint64 dataSize, int32 deviceId, int64 nodeId,
71 uint64 symbolTable, uint64 symbolHash, uint64 stringTable,
72 CoreFileAreaInfo* textArea, CoreFileAreaInfo* dataArea, const BString& name)
74 fId(id),
75 fType(type),
76 fInitRoutine(initRoutine),
77 fTermRoutine(termRoutine),
78 fTextBase(textBase),
79 fTextSize(textSize),
80 fTextDelta(textDelta),
81 fDataBase(dataBase),
82 fDataSize(dataSize),
83 fDeviceId(deviceId),
84 fNodeId(nodeId),
85 fSymbolTable(symbolTable),
86 fSymbolHash(symbolHash),
87 fStringTable(stringTable),
88 fTextArea(textArea),
89 fDataArea(dataArea),
90 fName(name),
91 fSymbolsInfo(NULL)
96 CoreFileImageInfo::~CoreFileImageInfo()
98 SetSymbolsInfo(NULL);
102 void
103 CoreFileImageInfo::SetSymbolsInfo(CoreFileSymbolsInfo* symbolsInfo)
105 if (fSymbolsInfo != NULL)
106 delete fSymbolsInfo;
108 fSymbolsInfo = symbolsInfo;
112 // pragma mark - CoreFileSymbolsInfo
114 CoreFileSymbolsInfo::CoreFileSymbolsInfo()
116 fSymbolTable(NULL),
117 fStringTable(NULL),
118 fSymbolCount(0),
119 fSymbolTableEntrySize(0),
120 fStringTableSize(0)
125 CoreFileSymbolsInfo::~CoreFileSymbolsInfo()
127 free(fSymbolTable);
128 free(fStringTable);
132 bool
133 CoreFileSymbolsInfo::Init(const void* symbolTable, uint32 symbolCount,
134 uint32 symbolTableEntrySize, const char* stringTable,
135 uint32 stringTableSize)
137 fSymbolTable = malloc(symbolCount * symbolTableEntrySize);
138 fStringTable = (char*)malloc(stringTableSize);
140 if (fSymbolTable == NULL || fStringTable == NULL)
141 return false;
143 memcpy(fSymbolTable, symbolTable, symbolCount * symbolTableEntrySize);
144 memcpy(fStringTable, stringTable, stringTableSize);
146 fSymbolCount = symbolCount;
147 fSymbolTableEntrySize = symbolTableEntrySize;
148 fStringTableSize = stringTableSize;
150 return true;
154 // pragma mark - CoreFileThreadInfo
157 CoreFileThreadInfo::CoreFileThreadInfo(int32 id, int32 state, int32 priority,
158 uint64 stackBase, uint64 stackEnd, const BString& name)
160 fId(id),
161 fState(state),
162 fPriority(priority),
163 fStackBase(stackBase),
164 fStackEnd(stackEnd),
165 fName(name),
166 fCpuState(NULL),
167 fCpuStateSize(0)
172 CoreFileThreadInfo::~CoreFileThreadInfo()
174 free(fCpuState);
178 bool
179 CoreFileThreadInfo::SetCpuState(const void* state, size_t size)
181 free(fCpuState);
182 fCpuState = NULL;
183 fCpuStateSize = 0;
185 if (state != NULL) {
186 fCpuState = malloc(size);
187 if (fCpuState == NULL)
188 return false;
189 memcpy(fCpuState, state, size);
190 fCpuStateSize = size;
193 return true;
197 // pragma mark - CoreFile
200 CoreFile::CoreFile()
202 fElfFile(),
203 fTeamInfo(),
204 fAreaInfos(32, true),
205 fImageInfos(32, true),
206 fThreadInfos(32, true)
211 CoreFile::~CoreFile()
216 status_t
217 CoreFile::Init(const char* fileName)
219 status_t error = fElfFile.Init(fileName);
220 if (error != B_OK)
221 return error;
223 if (fElfFile.Is64Bit())
224 return _Init<ElfClass64>();
225 return _Init<ElfClass32>();
229 const CoreFileThreadInfo*
230 CoreFile::ThreadInfoForId(int32 id) const
232 int32 count = fThreadInfos.CountItems();
233 for (int32 i = 0; i < count; i++) {
234 CoreFileThreadInfo* info = fThreadInfos.ItemAt(i);
235 if (info->Id() == id)
236 return info;
239 return NULL;
243 status_t
244 CoreFile::CreateSymbolLookup(const CoreFileImageInfo* imageInfo,
245 ElfSymbolLookup*& _lookup)
247 // get the needed data
248 uint64 textDelta = imageInfo->TextDelta();
249 uint64 symbolTable = imageInfo->SymbolTable();
250 uint64 symbolHash = imageInfo->SymbolHash();
251 uint64 stringTable = imageInfo->StringTable();
252 CoreFileAreaInfo* textArea = imageInfo->TextArea();
253 ElfSegment* textSegment = textArea != NULL ? textArea->Segment() : NULL;
255 if (symbolTable == 0 || symbolHash == 0 || stringTable == 0
256 || textSegment == NULL) {
257 return B_UNSUPPORTED;
260 // create a data source for the text segment
261 ElfSymbolLookupSource* source = fElfFile.CreateSymbolLookupSource(
262 textSegment->FileOffset(), textSegment->FileSize(),
263 textSegment->LoadAddress());
264 if (source == NULL)
265 return B_NO_MEMORY;
267 // get the symbol table entry size
268 // TODO: This is not actually correct, since at least theoretically the
269 // entry size may differ (cf. DT_SYMENT in the dynamic segment).
270 size_t symbolTableEntrySize = fElfFile.Is64Bit()
271 ? sizeof(ElfClass64::Sym) : sizeof(ElfClass32::Sym);
273 // create the symbol lookup
274 return ElfSymbolLookup::Create(source, symbolTable, symbolHash, stringTable,
275 ElfSymbolLookup::kGetSymbolCountFromHash, symbolTableEntrySize,
276 textDelta, fElfFile.Is64Bit(), fElfFile.IsByteOrderSwapped(), true,
277 _lookup);
281 template<typename ElfClass>
282 status_t
283 CoreFile::_Init()
285 status_t error = _ReadNotes<ElfClass>();
286 if (error != B_OK)
287 return error;
288 printf("CoreFile::_Init(): got %" B_PRId32 " areas, %" B_PRId32 " images, %"
289 B_PRId32 " threads\n", CountAreaInfos(), CountImageInfos(), CountThreadInfos());
290 // TODO: Verify that we actually read something!
291 return B_OK;
295 template<typename ElfClass>
296 status_t
297 CoreFile::_ReadNotes()
299 int32 count = fElfFile.CountSegments();
300 for (int32 i = 0; i < count; i++) {
301 ElfSegment* segment = fElfFile.SegmentAt(i);
302 if (segment->Type() == PT_NOTE) {
303 status_t error = _ReadNotes<ElfClass>(segment);
304 if (error != B_OK)
305 return error;
309 return B_OK;
313 template<typename ElfClass>
314 status_t
315 CoreFile::_ReadNotes(ElfSegment* segment)
317 // read the whole segment into memory
318 if ((uint64)segment->FileSize() > kMaxNotesSize) {
319 WARNING("Notes segment too large (%" B_PRIdOFF ")\n",
320 segment->FileSize());
321 return B_UNSUPPORTED;
324 size_t notesSize = (size_t)segment->FileSize();
325 uint8* notes = (uint8*)malloc(notesSize);
326 if (notes == NULL)
327 return B_NO_MEMORY;
328 MemoryDeleter notesDeleter(notes);
330 ssize_t bytesRead = pread(fElfFile.FD(), notes, notesSize,
331 (off_t)segment->FileOffset());
332 if (bytesRead < 0) {
333 WARNING("Failed to read notes segment: %s\n", strerror(errno));
334 return errno;
336 if ((size_t)bytesRead != notesSize) {
337 WARNING("Failed to read whole notes segment\n");
338 return B_IO_ERROR;
341 // iterate through notes
342 typedef typename ElfClass::Nhdr Nhdr;
343 while (notesSize > 0) {
344 if (notesSize < sizeof(Nhdr)) {
345 WARNING("Remaining bytes in notes segment too short for header\n");
346 return B_BAD_DATA;
349 const Nhdr* header = (const Nhdr*)notes;
350 uint32 nameSize = Get(header->n_namesz);
351 uint32 dataSize = Get(header->n_descsz);
352 uint32 type = Get(header->n_type);
354 notes += sizeof(Nhdr);
355 notesSize -= sizeof(Nhdr);
357 size_t alignedNameSize = (nameSize + 3) / 4 * 4;
358 if (alignedNameSize > notesSize) {
359 WARNING("Not enough bytes remaining in notes segment for note "
360 "name (%zu / %zu)\n", notesSize, alignedNameSize);
361 return B_BAD_DATA;
364 const char* name = (const char*)notes;
365 size_t nameLen = strnlen(name, nameSize);
366 if (nameLen == nameSize) {
367 WARNING("Unterminated note name\n");
368 return B_BAD_DATA;
371 notes += alignedNameSize;
372 notesSize -= alignedNameSize;
374 size_t alignedDataSize = (dataSize + 3) / 4 * 4;
375 if (alignedDataSize > notesSize) {
376 WARNING("Not enough bytes remaining in notes segment for note "
377 "data\n");
378 return B_BAD_DATA;
381 _ReadNote<ElfClass>(name, type, notes, dataSize);
383 notes += alignedDataSize;
384 notesSize -= alignedDataSize;
387 return B_OK;
391 template<typename ElfClass>
392 status_t
393 CoreFile::_ReadNote(const char* name, uint32 type, const void* data,
394 uint32 dataSize)
396 if (strcmp(name, ELF_NOTE_CORE) == 0) {
397 switch (type) {
398 case NT_FILE:
399 // not needed
400 return B_OK;
402 } else if (strcmp(name, ELF_NOTE_HAIKU) == 0) {
403 switch (type) {
404 case NT_TEAM:
405 return _ReadTeamNote<ElfClass>(data, dataSize);
406 case NT_AREAS:
407 return _ReadAreasNote<ElfClass>(data, dataSize);
408 case NT_IMAGES:
409 return _ReadImagesNote<ElfClass>(data, dataSize);
410 case NT_SYMBOLS:
411 return _ReadSymbolsNote<ElfClass>(data, dataSize);
412 case NT_THREADS:
413 return _ReadThreadsNote<ElfClass>(data, dataSize);
414 break;
418 WARNING("Unsupported note type %s/%#" B_PRIx32 "\n", name, type);
419 return B_OK;
423 template<typename ElfClass>
424 status_t
425 CoreFile::_ReadTeamNote(const void* data, uint32 dataSize)
427 typedef typename ElfClass::NoteTeam NoteTeam;
429 if (dataSize < sizeof(uint32)) {
430 WARNING("Team note too short\n");
431 return B_BAD_DATA;
433 uint32 entrySize = Get(*(const uint32*)data);
434 data = (const uint32*)data + 1;
435 dataSize -= sizeof(uint32);
437 if (entrySize == 0 || dataSize == 0 || dataSize - 1 < entrySize) {
438 WARNING("Team note: too short or invalid entry size (%" B_PRIu32 ")\n",
439 entrySize);
440 return B_BAD_DATA;
443 NoteTeam note = {};
444 _ReadEntry(data, dataSize, note, entrySize);
446 // check, if args are null-terminated
447 const char* args = (const char*)data;
448 size_t argsSize = dataSize;
449 if (args[argsSize - 1] != '\0') {
450 WARNING("Team note args not terminated\n");
451 return B_BAD_DATA;
454 int32 id = Get(note.nt_id);
455 int32 uid = Get(note.nt_uid);
456 int32 gid = Get(note.nt_gid);
458 BString copiedArgs(args);
459 if (args[0] != '\0' && copiedArgs.Length() == 0)
460 return B_NO_MEMORY;
462 fTeamInfo.Init(id, uid, gid, copiedArgs);
463 return B_OK;
467 template<typename ElfClass>
468 status_t
469 CoreFile::_ReadAreasNote(const void* data, uint32 dataSize)
471 if (dataSize < 2 * sizeof(uint32)) {
472 WARNING("Areas note too short\n");
473 return B_BAD_DATA;
475 uint32 areaCount = _ReadValue<uint32>(data, dataSize);
476 uint32 entrySize = _ReadValue<uint32>(data, dataSize);
478 typedef typename ElfClass::NoteAreaEntry Entry;
480 if (areaCount == 0)
481 return B_OK;
483 // check entry size and area count
484 if (entrySize == 0 || dataSize == 0 || areaCount > dataSize
485 || dataSize - 1 < entrySize || areaCount * entrySize >= dataSize) {
486 WARNING("Areas note: too short or invalid entry size (%" B_PRIu32 ")\n",
487 entrySize);
488 return B_BAD_DATA;
491 // check, if strings are null-terminated
492 const char* strings = (const char*)data + areaCount * entrySize;
493 size_t stringsSize = dataSize - areaCount * entrySize;
494 if (stringsSize == 0 || strings[stringsSize - 1] != '\0') {
495 WARNING("Areas note strings not terminated\n");
496 return B_BAD_DATA;
499 for (uint64 i = 0; i < areaCount; i++) {
500 // get entry values
501 Entry entry = {};
502 _ReadEntry(data, dataSize, entry, entrySize);
504 int32 id = Get(entry.na_id);
505 uint64 baseAddress = Get(entry.na_base);
506 uint64 size = Get(entry.na_size);
507 uint64 ramSize = Get(entry.na_ram_size);
508 uint32 lock = Get(entry.na_lock);
509 uint32 protection = Get(entry.na_protection);
511 // get name
512 if (stringsSize == 0) {
513 WARNING("Area %" B_PRIu64 " (ID %#" B_PRIx32 " @ %#" B_PRIx64
514 ") has no name\n", i, id, baseAddress);
515 continue;
517 const char* name = strings;
518 size_t nameSize = strlen(name) + 1;
519 strings += nameSize;
520 stringsSize -= nameSize;
522 BString copiedName(name);
523 if (name[0] != '\0' && copiedName.Length() == 0)
524 return B_NO_MEMORY;
526 // create and add area
527 ElfSegment* segment = _FindAreaSegment(baseAddress);
528 CoreFileAreaInfo* area = new(std::nothrow) CoreFileAreaInfo(segment, id,
529 baseAddress, size, ramSize, lock, protection, copiedName);
530 if (area == NULL || !fAreaInfos.AddItem(area)) {
531 delete area;
532 return B_NO_MEMORY;
536 return B_OK;
540 template<typename ElfClass>
541 status_t
542 CoreFile::_ReadImagesNote(const void* data, uint32 dataSize)
544 if (dataSize < 2 * sizeof(uint32)) {
545 WARNING("Images note too short\n");
546 return B_BAD_DATA;
548 uint32 imageCount = _ReadValue<uint32>(data, dataSize);
549 uint32 entrySize = _ReadValue<uint32>(data, dataSize);
551 typedef typename ElfClass::NoteImageEntry Entry;
553 if (imageCount == 0)
554 return B_OK;
556 // check entry size and image count
557 if (entrySize == 0 || dataSize == 0 || imageCount > dataSize
558 || dataSize - 1 < entrySize || imageCount * entrySize >= dataSize) {
559 WARNING("Images note: too short or invalid entry size (%" B_PRIu32
560 ")\n", entrySize);
561 return B_BAD_DATA;
564 // check, if strings are null-terminated
565 const char* strings = (const char*)data + imageCount * entrySize;
566 size_t stringsSize = dataSize - imageCount * entrySize;
567 if (stringsSize == 0 || strings[stringsSize - 1] != '\0') {
568 WARNING("Images note strings not terminated\n");
569 return B_BAD_DATA;
572 for (uint64 i = 0; i < imageCount; i++) {
573 // get entry values
574 Entry entry = {};
575 _ReadEntry(data, dataSize, entry, entrySize);
577 int32 id = Get(entry.ni_id);
578 int32 type = Get(entry.ni_type);
579 uint64 initRoutine = Get(entry.ni_init_routine);
580 uint64 termRoutine = Get(entry.ni_term_routine);
581 uint64 textBase = Get(entry.ni_text_base);
582 uint64 textSize = Get(entry.ni_text_size);
583 int64 textDelta = Get(entry.ni_text_delta);
584 uint64 dataBase = Get(entry.ni_data_base);
585 uint64 dataSize = Get(entry.ni_data_size);
586 int32 deviceId = Get(entry.ni_device);
587 int64 nodeId = Get(entry.ni_node);
588 uint64 symbolTable = Get(entry.ni_symbol_table);
589 uint64 symbolHash = Get(entry.ni_symbol_hash);
590 uint64 stringTable = Get(entry.ni_string_table);
592 // get name
593 if (stringsSize == 0) {
594 WARNING("Image %" B_PRIu64 " (ID %#" B_PRIx32 ") has no name\n",
595 i, id);
596 continue;
598 const char* name = strings;
599 size_t nameSize = strlen(name) + 1;
600 strings += nameSize;
601 stringsSize -= nameSize;
603 BString copiedName(name);
604 if (name[0] != '\0' && copiedName.Length() == 0)
605 return B_NO_MEMORY;
607 // create and add image
608 CoreFileAreaInfo* textArea = _FindArea(textBase);
609 CoreFileAreaInfo* dataArea = _FindArea(dataBase);
610 CoreFileImageInfo* image = new(std::nothrow) CoreFileImageInfo(id, type,
611 initRoutine, termRoutine, textBase, textSize, textDelta, dataBase,
612 dataSize, deviceId, nodeId, symbolTable, symbolHash, stringTable,
613 textArea, dataArea, copiedName);
614 if (image == NULL || !fImageInfos.AddItem(image)) {
615 delete image;
616 return B_NO_MEMORY;
620 return B_OK;
624 template<typename ElfClass>
625 status_t
626 CoreFile::_ReadSymbolsNote(const void* data, uint32 dataSize)
628 if (dataSize < 3 * sizeof(uint32)) {
629 WARNING("Symbols note too short\n");
630 return B_BAD_DATA;
632 int32 imageId = _ReadValue<int32>(data, dataSize);
633 uint32 symbolCount = _ReadValue<uint32>(data, dataSize);
634 uint32 entrySize = _ReadValue<uint32>(data, dataSize);
636 typedef typename ElfClass::Sym Sym;
638 if (symbolCount == 0)
639 return B_OK;
641 // get the corresponding image
642 CoreFileImageInfo* imageInfo = _ImageInfoForId(imageId);
643 if (imageInfo == NULL) {
644 WARNING("Symbols note: image (ID %" B_PRId32 ") not found\n",
645 entrySize);
646 return B_BAD_DATA;
649 // check entry size and symbol count
650 if (entrySize < sizeof(Sym) || symbolCount > dataSize
651 || dataSize - 1 < entrySize
652 || symbolCount * entrySize >= dataSize - 1) {
653 WARNING("Symbols note: too short or invalid entry size (%" B_PRIu32
654 ")\n", entrySize);
655 return B_BAD_DATA;
658 uint32 symbolTableSize = symbolCount * entrySize;
659 uint32 stringTableSize = dataSize - symbolTableSize;
661 // check, if the string table is null-terminated
662 const char* stringTable = (const char*)data + symbolTableSize;
663 if (stringTableSize == 0 || stringTable[stringTableSize - 1] != '\0') {
664 WARNING("Symbols note string table not terminated\n");
665 return B_BAD_DATA;
668 CoreFileSymbolsInfo* symbolsInfo = new(std::nothrow) CoreFileSymbolsInfo;
669 if (symbolsInfo == NULL
670 || !symbolsInfo->Init(data, symbolCount, entrySize, stringTable,
671 stringTableSize)) {
672 delete symbolsInfo;
673 return B_NO_MEMORY;
676 imageInfo->SetSymbolsInfo(symbolsInfo);
678 return B_OK;
682 template<typename ElfClass>
683 status_t
684 CoreFile::_ReadThreadsNote(const void* data, uint32 dataSize)
686 if (dataSize < 3 * sizeof(uint32)) {
687 WARNING("Threads note too short\n");
688 return B_BAD_DATA;
690 uint32 threadCount = _ReadValue<uint32>(data, dataSize);
691 uint32 entrySize = _ReadValue<uint32>(data, dataSize);
692 uint32 cpuStateSize = _ReadValue<uint32>(data, dataSize);
694 if (cpuStateSize > 1024 * 1024) {
695 WARNING("Threads note: unreasonable CPU state size: %" B_PRIu32 "\n",
696 cpuStateSize);
697 return B_BAD_DATA;
700 typedef typename ElfClass::NoteThreadEntry Entry;
702 if (threadCount == 0)
703 return B_OK;
705 size_t totalEntrySize = entrySize + cpuStateSize;
707 // check entry size and thread count
708 if (entrySize == 0 || dataSize == 0 || threadCount > dataSize
709 || entrySize > dataSize || cpuStateSize > dataSize
710 || dataSize - 1 < totalEntrySize
711 || threadCount * totalEntrySize >= dataSize) {
712 WARNING("Threads note: too short or invalid entry size (%" B_PRIu32
713 ")\n", entrySize);
714 return B_BAD_DATA;
717 // check, if strings are null-terminated
718 const char* strings = (const char*)data + threadCount * totalEntrySize;
719 size_t stringsSize = dataSize - threadCount * totalEntrySize;
720 if (stringsSize == 0 || strings[stringsSize - 1] != '\0') {
721 WARNING("Threads note strings not terminated\n");
722 return B_BAD_DATA;
725 for (uint64 i = 0; i < threadCount; i++) {
726 // get entry values
727 Entry entry = {};
728 _ReadEntry(data, dataSize, entry, entrySize);
730 int32 id = Get(entry.nth_id);
731 int32 state = Get(entry.nth_state);
732 int32 priority = Get(entry.nth_priority);
733 uint64 stackBase = Get(entry.nth_stack_base);
734 uint64 stackEnd = Get(entry.nth_stack_end);
736 // get name
737 if (stringsSize == 0) {
738 WARNING("Thread %" B_PRIu64 " (ID %#" B_PRIx32 ") has no name\n",
739 i, id);
740 continue;
742 const char* name = strings;
743 size_t nameSize = strlen(name) + 1;
744 strings += nameSize;
745 stringsSize -= nameSize;
747 BString copiedName(name);
748 if (name[0] != '\0' && copiedName.Length() == 0)
749 return B_NO_MEMORY;
751 // create and add thread
752 CoreFileThreadInfo* thread = new(std::nothrow) CoreFileThreadInfo(id,
753 state, priority, stackBase, stackEnd, copiedName);
754 if (thread == NULL || !fThreadInfos.AddItem(thread)) {
755 delete thread;
756 return B_NO_MEMORY;
759 // get CPU state
760 if (!thread->SetCpuState(data, cpuStateSize))
761 return B_NO_MEMORY;
762 _Advance(data, dataSize, cpuStateSize);
765 return B_OK;
769 CoreFileAreaInfo*
770 CoreFile::_FindArea(uint64 address) const
772 int32 count = fAreaInfos.CountItems();
773 for (int32 i = 0; i < count; i++) {
774 CoreFileAreaInfo* area = fAreaInfos.ItemAt(i);
775 if (address >= area->BaseAddress()
776 && address < area->EndAddress()) {
777 return area;
781 return NULL;
785 ElfSegment*
786 CoreFile::_FindAreaSegment(uint64 address) const
788 int32 count = fElfFile.CountSegments();
789 for (int32 i = 0; i < count; i++) {
790 ElfSegment* segment = fElfFile.SegmentAt(i);
791 if (segment->Type() == PT_LOAD && segment->LoadAddress() == address)
792 return segment;
795 return NULL;
799 CoreFileImageInfo*
800 CoreFile::_ImageInfoForId(int32 id) const
802 int32 count = fImageInfos.CountItems();
803 for (int32 i = 0; i < count; i++) {
804 CoreFileImageInfo* info = fImageInfos.ItemAt(i);
805 if (info->Id() == id)
806 return info;
809 return NULL;
813 template<typename Type>
814 Type
815 CoreFile::_ReadValue(const void*& data, uint32& dataSize)
817 Type value = Get(*(const Type*)data);
818 _Advance(data, dataSize, sizeof(Type));
819 return value;
823 template<typename Entry>
824 void
825 CoreFile::_ReadEntry(const void*& data, uint32& dataSize, Entry& entry,
826 size_t entrySize)
828 memcpy(&entry, data, std::min(sizeof(entry), entrySize));
829 _Advance(data, dataSize, entrySize);
833 void
834 CoreFile::_Advance(const void*& data, uint32& dataSize, size_t by)
836 data = (const uint8*)data + by;
837 dataSize -= by;