ElfSegment* ElfFile::DataSegment() const { int32 count = fSegments.CountItems(); for (int32 i = 0; i < count; i++) { ElfSegment* segment = fSegments.ItemAt(i); if (segment->Type() == PT_LOAD && segment->IsWritable()) return segment; } return NULL; }
ElfSegment* CoreFile::_FindAreaSegment(uint64 address) const { int32 count = fElfFile.CountSegments(); for (int32 i = 0; i < count; i++) { ElfSegment* segment = fElfFile.SegmentAt(i); if (segment->Type() == PT_LOAD && segment->LoadAddress() == address) return segment; } return NULL; }
status_t CoreFile::_ReadNotes() { int32 count = fElfFile.CountSegments(); for (int32 i = 0; i < count; i++) { ElfSegment* segment = fElfFile.SegmentAt(i); if (segment->Type() == PT_NOTE) { status_t error = _ReadNotes<ElfClass>(segment); if (error != B_OK) return error; } } return B_OK; }
status_t CoreFile::CreateSymbolLookup(const CoreFileImageInfo* imageInfo, ElfSymbolLookup*& _lookup) { // get the needed data uint64 textDelta = imageInfo->TextDelta(); uint64 symbolTable = imageInfo->SymbolTable(); uint64 symbolHash = imageInfo->SymbolHash(); uint64 stringTable = imageInfo->StringTable(); CoreFileAreaInfo* textArea = imageInfo->TextArea(); ElfSegment* textSegment = textArea != NULL ? textArea->Segment() : NULL; if (symbolTable == 0 || symbolHash == 0 || stringTable == 0 || textSegment == NULL) { return B_UNSUPPORTED; } // create a data source for the text segment ElfSymbolLookupSource* source = fElfFile.CreateSymbolLookupSource( textSegment->FileOffset(), textSegment->FileSize(), textSegment->LoadAddress()); if (source == NULL) return B_NO_MEMORY; // get the symbol table entry size // TODO: This is not actually correct, since at least theoretically the // entry size may differ (cf. DT_SYMENT in the dynamic segment). size_t symbolTableEntrySize = fElfFile.Is64Bit() ? sizeof(ElfClass64::Sym) : sizeof(ElfClass32::Sym); // create the symbol lookup return ElfSymbolLookup::Create(source, symbolTable, symbolHash, stringTable, ElfSymbolLookup::kGetSymbolCountFromHash, symbolTableEntrySize, textDelta, fElfFile.Is64Bit(), fElfFile.IsByteOrderSwapped(), true, _lookup); }
bool ElfFile::load(ByteArray& data, bool sort) { fileData = data; memcpy(&fileHeader,&fileData[0],sizeof(Elf32_Ehdr)); symTab = NULL; strTab = NULL; // load segments for (int i = 0; i < fileHeader.e_phnum; i++) { int pos = fileHeader.e_phoff+i*fileHeader.e_phentsize; Elf32_Phdr sectionHeader; memcpy(§ionHeader,&fileData[pos],sizeof(Elf32_Phdr)); ByteArray segmentData = fileData.mid(sectionHeader.p_offset,sectionHeader.p_filesz); ElfSegment* segment = new ElfSegment(sectionHeader,segmentData); segments.push_back(segment); } // load sections and assign them to segments for (int i = 0; i < fileHeader.e_shnum; i++) { int pos = fileHeader.e_shoff+i*fileHeader.e_shentsize; Elf32_Shdr sectionHeader; memcpy(§ionHeader,&fileData[pos],sizeof(Elf32_Shdr)); ElfSection* section = new ElfSection(sectionHeader); sections.push_back(section); // check if the section belongs to a segment ElfSegment* owner = NULL; for (int k = 0; k < (int)segments.size(); k++) { if (segments[k]->isSectionPartOf(section)) { owner = segments[k]; break; } } if (owner != NULL) { owner->addSection(section); } else { if (section->getType() != SHT_NOBITS && section->getType() != SHT_NULL) { ByteArray data = fileData.mid(section->getOffset(),section->getSize()); section->setData(data); } switch (section->getType()) { case SHT_SYMTAB: symTab = section; break; case SHT_STRTAB: strTab = section; break; } segmentlessSections.push_back(section); } } determinePartOrder(); loadSectionNames(); if (sort) { std::sort(segmentlessSections.begin(),segmentlessSections.end(),compareSection); for (int i = 0; i < (int)segments.size(); i++) { segments[i]->sortSections(); } } return true; }