Esempio n. 1
0
status_t
DwarfType::ResolveLocation(DwarfTypeContext* typeContext,
	const LocationDescription* description, target_addr_t objectAddress,
	bool hasObjectAddress, ValueLocation& _location)
{
	status_t error = typeContext->File()->ResolveLocation(
		typeContext->GetCompilationUnit(), typeContext->AddressSize(),
		typeContext->SubprogramEntry(), description,
		typeContext->TargetInterface(), typeContext->InstructionPointer(),
		objectAddress, hasObjectAddress, typeContext->FramePointer(),
		typeContext->RelocationDelta(), _location);
	if (error != B_OK)
		return error;

	// translate the DWARF register indices and the bit offset/size semantics
	const Register* registers = typeContext->GetArchitecture()->Registers();
	bool bigEndian = typeContext->GetArchitecture()->IsBigEndian();
	int32 count = _location.CountPieces();
	for (int32 i = 0; i < count; i++) {
		ValuePieceLocation piece = _location.PieceAt(i);
		if (piece.type == VALUE_PIECE_LOCATION_REGISTER) {
			int32 reg = typeContext->FromDwarfRegisterMap()->MapRegisterIndex(
				piece.reg);
			if (reg >= 0) {
				piece.reg = reg;
				// The bit offset for registers is to the least
				// significant bit, while we want the offset to the most
				// significant bit.
				if (registers[reg].BitSize() > piece.bitSize) {
					piece.bitOffset = registers[reg].BitSize() - piece.bitSize
						- piece.bitOffset;
				}
			} else
				piece.SetToUnknown();
		} else if (piece.type == VALUE_PIECE_LOCATION_MEMORY) {
			// Whether the bit offset is to the least or most significant bit
			// is target architecture and source language specific.
			// TODO: Check whether this is correct!
			// TODO: Source language!
			if (!bigEndian && piece.size * 8 > piece.bitSize) {
				piece.bitOffset = piece.size * 8 - piece.bitSize
					- piece.bitOffset;
			}
		}

		piece.Normalize(bigEndian);
		_location.SetPieceAt(i, piece);
	}

	// If we only have one piece and that doesn't have a size, try to retrieve
	// the size of the type.
	if (count == 1) {
		ValuePieceLocation piece = _location.PieceAt(0);
		if (piece.IsValid() && piece.size == 0 && piece.bitSize == 0) {
			piece.SetSize(ByteSize());
				// TODO: Use bit size and bit offset, if specified!
			_location.SetPieceAt(0, piece);

			TRACE_LOCALS("  set single piece size to %" B_PRIu64 "\n",
				ByteSize());
		}
	}

	return B_OK;
}
Esempio n. 2
0
bool
ValueLocation::SetTo(const ValueLocation& other, uint64 bitOffset,
	uint64 bitSize)
{
	Clear();

	fBigEndian = other.fBigEndian;

	// compute the total bit size
	int32 count = other.CountPieces();
	uint64 totalBitSize = 0;
	for (int32 i = 0; i < count; i++) {
		const ValuePieceLocation &piece = other.PieceAt(i);
		totalBitSize += piece.bitSize;
	}

	// adjust requested bit offset/size to something reasonable, if necessary
	if (bitOffset + bitSize > totalBitSize) {
		if (bitOffset >= totalBitSize)
			return true;
		bitSize = totalBitSize - bitOffset;
	}

	if (fBigEndian) {
		// Big endian: Skip the superfluous most significant bits, copy the
		// pieces we need (cutting the first and the last one as needed) and
		// ignore the remaining pieces.

		// skip pieces for the most significant bits we don't need anymore
		uint64 bitsToSkip = bitOffset;
		int32 i;
		ValuePieceLocation piece;
		for (i = 0; i < count; i++) {
			const ValuePieceLocation& tempPiece = other.PieceAt(i);
			if (tempPiece.bitSize > bitsToSkip) {
				if (!piece.Copy(tempPiece))
					return false;
				break;
			}
			bitsToSkip -= tempPiece.bitSize;
		}

		// handle partial piece
		if (bitsToSkip > 0) {
			piece.bitOffset += bitsToSkip;
			piece.bitSize -= bitsToSkip;
			piece.Normalize(fBigEndian);
		}

		// handle remaining pieces
		while (bitSize > 0) {
			if (piece.bitSize > bitSize) {
				// the piece is bigger than the remaining size -- cut it
				piece.bitSize = bitSize;
				piece.Normalize(fBigEndian);
				bitSize = 0;
			} else
				bitSize -= piece.bitSize;

			if (!AddPiece(piece))
				return false;

			if (++i >= count)
				break;

			if (!piece.Copy(other.PieceAt(i)))
				return false;
		}
	} else {
		// Little endian: Skip the superfluous least significant bits, copy the
		// pieces we need (cutting the first and the last one as needed) and
		// ignore the remaining pieces.

		// skip pieces for the least significant bits we don't need anymore
		uint64 bitsToSkip = totalBitSize - bitOffset - bitSize;
		int32 i;
		ValuePieceLocation piece;
		for (i = 0; i < count; i++) {
			const ValuePieceLocation& tempPiece = other.PieceAt(i);
			if (tempPiece.bitSize > bitsToSkip) {
				if (!piece.Copy(tempPiece))
					return false;
				break;
			}
			bitsToSkip -= piece.bitSize;
		}

		// handle partial piece
		if (bitsToSkip > 0) {
			piece.bitSize -= bitsToSkip;
			piece.Normalize(fBigEndian);
		}

		// handle remaining pieces
		while (bitSize > 0) {
			if (piece.bitSize > bitSize) {
				// the piece is bigger than the remaining size -- cut it
				piece.bitOffset += piece.bitSize - bitSize;
				piece.bitSize = bitSize;
				piece.Normalize(fBigEndian);
				bitSize = 0;
			} else
				bitSize -= piece.bitSize;

			if (!AddPiece(piece))
				return false;

			if (++i >= count)
				break;

			if (!piece.Copy(other.PieceAt(i)))
				return false;
		}
	}

	return true;
}