vfs: check userland buffers before reading them.
[haiku.git] / src / kits / debugger / elf / CoreFile.cpp
blobae06ed20767cf0e937c0404ee48f43a70f193a2b
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 if (segment == NULL) {
529 WARNING("No matching segment found for area %" B_PRIu64 " (ID %#"
530 B_PRIx32 " @ %#" B_PRIx64 ", name: '%s')", i, id, baseAddress,
531 name);
532 continue;
535 CoreFileAreaInfo* area = new(std::nothrow) CoreFileAreaInfo(segment, id,
536 baseAddress, size, ramSize, lock, protection, copiedName);
537 if (area == NULL || !fAreaInfos.AddItem(area)) {
538 delete area;
539 return B_NO_MEMORY;
543 return B_OK;
547 template<typename ElfClass>
548 status_t
549 CoreFile::_ReadImagesNote(const void* data, uint32 dataSize)
551 if (dataSize < 2 * sizeof(uint32)) {
552 WARNING("Images note too short\n");
553 return B_BAD_DATA;
555 uint32 imageCount = _ReadValue<uint32>(data, dataSize);
556 uint32 entrySize = _ReadValue<uint32>(data, dataSize);
558 typedef typename ElfClass::NoteImageEntry Entry;
560 if (imageCount == 0)
561 return B_OK;
563 // check entry size and image count
564 if (entrySize == 0 || dataSize == 0 || imageCount > dataSize
565 || dataSize - 1 < entrySize || imageCount * entrySize >= dataSize) {
566 WARNING("Images note: too short or invalid entry size (%" B_PRIu32
567 ")\n", entrySize);
568 return B_BAD_DATA;
571 // check, if strings are null-terminated
572 const char* strings = (const char*)data + imageCount * entrySize;
573 size_t stringsSize = dataSize - imageCount * entrySize;
574 if (stringsSize == 0 || strings[stringsSize - 1] != '\0') {
575 WARNING("Images note strings not terminated\n");
576 return B_BAD_DATA;
579 for (uint64 i = 0; i < imageCount; i++) {
580 // get entry values
581 Entry entry = {};
582 _ReadEntry(data, dataSize, entry, entrySize);
584 int32 id = Get(entry.ni_id);
585 int32 type = Get(entry.ni_type);
586 uint64 initRoutine = Get(entry.ni_init_routine);
587 uint64 termRoutine = Get(entry.ni_term_routine);
588 uint64 textBase = Get(entry.ni_text_base);
589 uint64 textSize = Get(entry.ni_text_size);
590 int64 textDelta = Get(entry.ni_text_delta);
591 uint64 dataBase = Get(entry.ni_data_base);
592 uint64 dataSize = Get(entry.ni_data_size);
593 int32 deviceId = Get(entry.ni_device);
594 int64 nodeId = Get(entry.ni_node);
595 uint64 symbolTable = Get(entry.ni_symbol_table);
596 uint64 symbolHash = Get(entry.ni_symbol_hash);
597 uint64 stringTable = Get(entry.ni_string_table);
599 // get name
600 if (stringsSize == 0) {
601 WARNING("Image %" B_PRIu64 " (ID %#" B_PRIx32 ") has no name\n",
602 i, id);
603 continue;
605 const char* name = strings;
606 size_t nameSize = strlen(name) + 1;
607 strings += nameSize;
608 stringsSize -= nameSize;
610 BString copiedName(name);
611 if (name[0] != '\0' && copiedName.Length() == 0)
612 return B_NO_MEMORY;
614 // create and add image
615 CoreFileAreaInfo* textArea = _FindArea(textBase);
616 CoreFileAreaInfo* dataArea = _FindArea(dataBase);
617 CoreFileImageInfo* image = new(std::nothrow) CoreFileImageInfo(id, type,
618 initRoutine, termRoutine, textBase, textSize, textDelta, dataBase,
619 dataSize, deviceId, nodeId, symbolTable, symbolHash, stringTable,
620 textArea, dataArea, copiedName);
621 if (image == NULL || !fImageInfos.AddItem(image)) {
622 delete image;
623 return B_NO_MEMORY;
627 return B_OK;
631 template<typename ElfClass>
632 status_t
633 CoreFile::_ReadSymbolsNote(const void* data, uint32 dataSize)
635 if (dataSize < 3 * sizeof(uint32)) {
636 WARNING("Symbols note too short\n");
637 return B_BAD_DATA;
639 int32 imageId = _ReadValue<int32>(data, dataSize);
640 uint32 symbolCount = _ReadValue<uint32>(data, dataSize);
641 uint32 entrySize = _ReadValue<uint32>(data, dataSize);
643 typedef typename ElfClass::Sym Sym;
645 if (symbolCount == 0)
646 return B_OK;
648 // get the corresponding image
649 CoreFileImageInfo* imageInfo = _ImageInfoForId(imageId);
650 if (imageInfo == NULL) {
651 WARNING("Symbols note: image (ID %" B_PRId32 ") not found\n",
652 entrySize);
653 return B_BAD_DATA;
656 // check entry size and symbol count
657 if (entrySize < sizeof(Sym) || symbolCount > dataSize
658 || dataSize - 1 < entrySize
659 || symbolCount * entrySize >= dataSize - 1) {
660 WARNING("Symbols note: too short or invalid entry size (%" B_PRIu32
661 ")\n", entrySize);
662 return B_BAD_DATA;
665 uint32 symbolTableSize = symbolCount * entrySize;
666 uint32 stringTableSize = dataSize - symbolTableSize;
668 // check, if the string table is null-terminated
669 const char* stringTable = (const char*)data + symbolTableSize;
670 if (stringTableSize == 0 || stringTable[stringTableSize - 1] != '\0') {
671 WARNING("Symbols note string table not terminated\n");
672 return B_BAD_DATA;
675 CoreFileSymbolsInfo* symbolsInfo = new(std::nothrow) CoreFileSymbolsInfo;
676 if (symbolsInfo == NULL
677 || !symbolsInfo->Init(data, symbolCount, entrySize, stringTable,
678 stringTableSize)) {
679 delete symbolsInfo;
680 return B_NO_MEMORY;
683 imageInfo->SetSymbolsInfo(symbolsInfo);
685 return B_OK;
689 template<typename ElfClass>
690 status_t
691 CoreFile::_ReadThreadsNote(const void* data, uint32 dataSize)
693 if (dataSize < 3 * sizeof(uint32)) {
694 WARNING("Threads note too short\n");
695 return B_BAD_DATA;
697 uint32 threadCount = _ReadValue<uint32>(data, dataSize);
698 uint32 entrySize = _ReadValue<uint32>(data, dataSize);
699 uint32 cpuStateSize = _ReadValue<uint32>(data, dataSize);
701 if (cpuStateSize > 1024 * 1024) {
702 WARNING("Threads note: unreasonable CPU state size: %" B_PRIu32 "\n",
703 cpuStateSize);
704 return B_BAD_DATA;
707 typedef typename ElfClass::NoteThreadEntry Entry;
709 if (threadCount == 0)
710 return B_OK;
712 size_t totalEntrySize = entrySize + cpuStateSize;
714 // check entry size and thread count
715 if (entrySize == 0 || dataSize == 0 || threadCount > dataSize
716 || entrySize > dataSize || cpuStateSize > dataSize
717 || dataSize - 1 < totalEntrySize
718 || threadCount * totalEntrySize >= dataSize) {
719 WARNING("Threads note: too short or invalid entry size (%" B_PRIu32
720 ")\n", entrySize);
721 return B_BAD_DATA;
724 // check, if strings are null-terminated
725 const char* strings = (const char*)data + threadCount * totalEntrySize;
726 size_t stringsSize = dataSize - threadCount * totalEntrySize;
727 if (stringsSize == 0 || strings[stringsSize - 1] != '\0') {
728 WARNING("Threads note strings not terminated\n");
729 return B_BAD_DATA;
732 for (uint64 i = 0; i < threadCount; i++) {
733 // get entry values
734 Entry entry = {};
735 _ReadEntry(data, dataSize, entry, entrySize);
737 int32 id = Get(entry.nth_id);
738 int32 state = Get(entry.nth_state);
739 int32 priority = Get(entry.nth_priority);
740 uint64 stackBase = Get(entry.nth_stack_base);
741 uint64 stackEnd = Get(entry.nth_stack_end);
743 // get name
744 if (stringsSize == 0) {
745 WARNING("Thread %" B_PRIu64 " (ID %#" B_PRIx32 ") has no name\n",
746 i, id);
747 continue;
749 const char* name = strings;
750 size_t nameSize = strlen(name) + 1;
751 strings += nameSize;
752 stringsSize -= nameSize;
754 BString copiedName(name);
755 if (name[0] != '\0' && copiedName.Length() == 0)
756 return B_NO_MEMORY;
758 // create and add thread
759 CoreFileThreadInfo* thread = new(std::nothrow) CoreFileThreadInfo(id,
760 state, priority, stackBase, stackEnd, copiedName);
761 if (thread == NULL || !fThreadInfos.AddItem(thread)) {
762 delete thread;
763 return B_NO_MEMORY;
766 // get CPU state
767 if (!thread->SetCpuState(data, cpuStateSize))
768 return B_NO_MEMORY;
769 _Advance(data, dataSize, cpuStateSize);
772 return B_OK;
776 CoreFileAreaInfo*
777 CoreFile::_FindArea(uint64 address) const
779 int32 count = fAreaInfos.CountItems();
780 for (int32 i = 0; i < count; i++) {
781 CoreFileAreaInfo* area = fAreaInfos.ItemAt(i);
782 if (address >= area->BaseAddress()
783 && address < area->EndAddress()) {
784 return area;
788 return NULL;
792 ElfSegment*
793 CoreFile::_FindAreaSegment(uint64 address) const
795 int32 count = fElfFile.CountSegments();
796 for (int32 i = 0; i < count; i++) {
797 ElfSegment* segment = fElfFile.SegmentAt(i);
798 if (segment->Type() == PT_LOAD && segment->LoadAddress() == address)
799 return segment;
802 return NULL;
806 CoreFileImageInfo*
807 CoreFile::_ImageInfoForId(int32 id) const
809 int32 count = fImageInfos.CountItems();
810 for (int32 i = 0; i < count; i++) {
811 CoreFileImageInfo* info = fImageInfos.ItemAt(i);
812 if (info->Id() == id)
813 return info;
816 return NULL;
820 template<typename Type>
821 Type
822 CoreFile::_ReadValue(const void*& data, uint32& dataSize)
824 Type value = Get(*(const Type*)data);
825 _Advance(data, dataSize, sizeof(Type));
826 return value;
830 template<typename Entry>
831 void
832 CoreFile::_ReadEntry(const void*& data, uint32& dataSize, Entry& entry,
833 size_t entrySize)
835 memcpy(&entry, data, std::min(sizeof(entry), entrySize));
836 _Advance(data, dataSize, entrySize);
840 void
841 CoreFile::_Advance(const void*& data, uint32& dataSize, size_t by)
843 data = (const uint8*)data + by;
844 dataSize -= by;