Esempio n. 1
0
void EHSection::loadFDE(BufReader& reader, uint64_t endPos, CIE* cie)
{
	FDE* fde = new FDE;
	
	fde->startAddress = reader.readDwarfPointer(cie->ptrEncoding);
	fde->length = reader.readDwarfPointer(cie->ptrEncoding); // if ptrEncoding is relative, then in context of length, it is still just a plain number
	
	if (*cie->augmentationString == 'z')
		fde->augmentationDataLength = reader.readLEB128();
	else
		fde->augmentationDataLength = 0;
	
	if (strchr(cie->augmentationString, 'L') && cie->lsdaEncoding != 0xff) // DW_EH_PE_omit
		fde->lsdaPointer = reader.readDwarfPointer(cie->lsdaEncoding);
	
	uint64_t instructionsLength = endPos - reader.pos();
	const uint8_t* data = reinterpret_cast<const uint8_t*>(reader.readBlock(instructionsLength));
	
	fde->instructions.assign(data, data+instructionsLength);
	
	cie->fdes.push_back(fde);
}
Esempio n. 2
0
void EHSection::loadCIE(BufReader& reader, uint64_t endPos, uintptr_t location)
{
	CIE* cie = new CIE;
	
	cie->start = reader.pos();
	cie->version = reader.read();
	cie->augmentationString = reader.readString();
	cie->codeAlign = reader.readLEB128();
	cie->dataAlign = reader.readLEB128();
	
	if (cie->codeAlign != 1)
	{
		std::stringstream ss;
		ss << "Invalid code alignment: " << int(cie->codeAlign) << std::endl;
		delete cie;
		throw std::runtime_error(ss.str());
	}
	
	if (cie->version == 1)
		cie->returnRegister = reader.read();
	else if (cie->version == 3)
		cie->returnRegister = reader.readLEB128();
	else
	{
		std::stringstream ss;
		ss << "Invalid CIE version: " << int(cie->version) << std::endl;
		delete cie;
		throw std::runtime_error(ss.str());
	}
	
	cie->augmentationDataPresent = false;
	
	uint64_t augmentationDataLength, augmentationDataEnd;
	
	cie->lsdaEncoding = cie->ptrEncoding = 0xff;
	
	for (const char* augP = cie->augmentationString; *augP; augP++)
	{
		switch (*augP)
		{
			case 'z':
				cie->augmentationDataPresent = true;
				augmentationDataLength = reader.readULEB128();
				augmentationDataEnd = reader.pos() + augmentationDataLength;
				break;
			case 'L':
				cie->lsdaEncoding = reader.read();
				break;
			case 'R':
				cie->ptrEncoding = reader.read();
				break;
			case 'P':
			{
				uint8_t persEncoding = reader.read();
				cie->personality = reader.readDwarfPointer(persEncoding);
				break;
			}
			case 'S':
				break;
			default:
			{
				std::stringstream ss;
				ss << "Unsupported character in CIE augmentation string: " << *augP;
				delete cie;
				
				throw std::runtime_error(ss.str());
			}
		}
	}
	
	reader.moveTo(augmentationDataEnd);
	
	uint64_t instructionsLength = endPos - reader.pos();
	const uint8_t* data = reinterpret_cast<const uint8_t*>(reader.readBlock(instructionsLength));
	
	cie->instructions.assign(data, data+instructionsLength);
	
	m_cies.push_back(cie);
	m_ciePositions[location] = cie;
	
	LOG << "Loaded a CIE at " << std::hex << location << std::dec << std::endl;
}