Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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);
}
Beispiel #5
0
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(&sectionHeader,&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(&sectionHeader,&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;
}