Move ARM disassembler into a library.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9902 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
andrewfish 2010-02-01 18:25:18 +00:00
parent cb6cb44c1a
commit 097bd461c4
9 changed files with 180 additions and 48 deletions

View File

@ -36,7 +36,8 @@
SemihostLib|Include/Library/Semihosting.h
UncachedMemoryAllocationLib|Include/Library/UncachedMemoryAllocationLib.h
DefaultExceptioHandlerLib|Include/Library/DefaultExceptioHandlerLib.h
ArmDisassemblerLib|Include/Library/ArmDisassemblerLib.h
[Guids.common]
gArmTokenSpaceGuid = { 0xBB11ECFE, 0x820F, 0x4968, { 0xBB, 0xA6, 0xF7, 0x6A, 0xFE, 0x30, 0x25, 0x96 } }

View File

@ -52,6 +52,7 @@
ArmLib|ArmPkg/Library/ArmLib/ArmCortexA/ArmCortexArmLib.inf
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
[LibraryClasses.ARM]
NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf

View File

@ -0,0 +1,39 @@
/** @file
Copyright (c) 2008-2010 Apple Inc. All rights reserved.<BR>
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef __ARM_DISASSEBLER_LIB_H__
#define __ARM_DISASSEBLER_LIB_H__
/**
Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to
point to next instructin.
We cheat and only decode instructions that access
memory. If the instruction is not found we dump the instruction in hex.
@param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble.
@param Thumb TRUE for Thumb(2), FALSE for ARM instruction stream
@param Buf Buffer to sprintf disassembly into.
@param Size Size of Buf in bytes.
**/
VOID
DisassembleInstruction (
IN UINT8 **OpCodePtr,
IN BOOLEAN Thumb,
OUT CHAR8 *Buf,
OUT UINTN Size
);
#endif

View File

@ -15,9 +15,8 @@
#include <Base.h>
#include <Library/BaseLib.h>
#include <Library/UefiLib.h>
#include <Library/PrintLib.h>
#include <Library/ArmDisassemblerLib.h>
CHAR8 *gCondition[] = {
"EQ",
@ -146,20 +145,25 @@ RotateRight (
/**
DEBUG print the faulting instruction. We cheat and only decode instructions that access
Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to
point to next instructin.
We cheat and only decode instructions that access
memory. If the instruction is not found we dump the instruction in hex.
@param Insturction ARM instruction to disassemble.
@param OpCodePtr Pointer to pointer of ARM instruction to disassemble.
@param Buf Buffer to sprintf disassembly into.
@param Size Size of Buf in bytes.
**/
VOID
DisassembleArmInstruction (
IN UINT32 *OpCodePtr,
IN UINT32 **OpCodePtr,
OUT CHAR8 *Buf,
OUT UINTN Size
)
{
UINT32 OpCode = *OpCodePtr;
UINT32 OpCode = **OpCodePtr;
CHAR8 *Type, *Root;
BOOLEAN I, P, U, B, W, L, S, H;
UINT32 Rn, Rd, Rm;
@ -437,6 +441,8 @@ DisassembleArmInstruction (
}
AsciiSPrint (Buf, Size, "Faulting OpCode 0x%08x", OpCode);
*OpCodePtr += 1;
return;
}

View File

@ -0,0 +1,40 @@
#/** @file
# Semihosting serail port lib
#
# Copyright (c) 2008, Apple Inc.
#
# All rights reserved. This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#
#**/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = SemiHostingSerialPortLib
FILE_GUID = 7ACEC173-F15D-426C-8F2F-BD86B4183EF1
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = ArmDisassemblerLib
[Sources.common]
ArmDisassembler.c
ThumbDisassembler.c
[Packages]
MdePkg/MdePkg.dec
ArmPkg/ArmPkg.dec
[LibraryClasses]
UefiLib
BaseLib
PrintLib
DebugLib
PeCoffGetEntryPointLib

View File

@ -50,7 +50,7 @@ typedef struct {
UINT32 AddressMode;
} THUMB_INSTRUCTIONS;
THUMB_INSTRUCTIONS gOp[] = {
THUMB_INSTRUCTIONS gOpThumb[] = {
// Thumb 16-bit instrucitons
// Op Mask Format
{ "ADC" , 0x4140, 0xffc0, DATA_FORMAT5 },
@ -144,8 +144,10 @@ THUMB_INSTRUCTIONS gOp[] = {
{ "TST" , 0x4200, 0xffc0, DATA_FORMAT5 },
{ "UXTB", 0xb2c0, 0xffc0, DATA_FORMAT5 },
{ "UXTH", 0xb280, 0xffc0, DATA_FORMAT5 }
};
#if 0
THUMB_INSTRUCTIONS gOpThumb2[] = {
,
// 32-bit Thumb instructions op1 01
@ -193,9 +195,8 @@ THUMB_INSTRUCTIONS gOp[] = {
// 1111 1 011 0xxx xxxx xxxx xxxx xxxx xxxx Multiply
// 1111 1 011 1xxx xxxx xxxx xxxx xxxx xxxx Long Multiply
// 1111 1 1xx xxxx xxxx xxxx xxxx xxxx xxxx Coprocessor
#endif
};
#endif
CHAR8 mThumbMregListStr[4*15 + 1];
@ -253,20 +254,27 @@ SignExtend (
}
/**
DEBUG print the faulting instruction. We cheat and only decode instructions that access
Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to
point to next instructin.
We cheat and only decode instructions that access
memory. If the instruction is not found we dump the instruction in hex.
@param Insturction ARM instruction to disassemble.
@param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble.
@param Buf Buffer to sprintf disassembly into.
@param Size Size of Buf in bytes.
**/
VOID
DisassembleThumbInstruction (
IN UINT16 *OpCodePtr,
IN UINT16 **OpCodePtrPtr,
OUT CHAR8 *Buf,
OUT UINTN Size
)
{
UINT16 OpCode = *OpCodePtr;
UINT16 *OpCodePtr;
UINT16 OpCode;
UINT16 OpCode32;
UINT32 Index;
UINT32 Offset;
UINT16 Rd, Rn, Rm;
@ -274,6 +282,12 @@ DisassembleThumbInstruction (
BOOLEAN H1, H2, imod;
UINT32 PC;
OpCodePtr = *OpCodePtrPtr;
OpCode = **OpCodePtrPtr;
// Thumb2 is a stream of 16-bit instructions not a 32-bit instruction.
OpCode32 = (OpCode << 16) | *(OpCodePtr + 1);
// These register names match branch form, but not others
Rd = OpCode & 0x7;
Rn = (OpCode >> 3) & 0x7;
@ -283,10 +297,13 @@ DisassembleThumbInstruction (
imod = (OpCode & BIT4) != 0;
PC = (UINT32)(UINTN)*OpCodePtr;
for (Index = 0; Index < sizeof (gOp)/sizeof (THUMB_INSTRUCTIONS); Index++) {
if ((OpCode & gOp[Index].Mask) == gOp[Index].OpCode) {
Offset = AsciiSPrint (Buf, Size, "%a", gOp[Index].Start);
switch (gOp[Index].AddressMode) {
// Increment by the minimum instruction size, Thumb2 could be bigger
*OpCodePtrPtr += 1;
for (Index = 0; Index < sizeof (gOpThumb)/sizeof (THUMB_INSTRUCTIONS); Index++) {
if ((OpCode & gOpThumb[Index].Mask) == gOpThumb[Index].OpCode) {
Offset = AsciiSPrint (Buf, Size, "%a", gOpThumb[Index].Start);
switch (gOpThumb[Index].AddressMode) {
case LOAD_STORE_FORMAT1:
// A6.5.1 <Rd>, [<Rn>, #<5_bit_offset>]
AsciiSPrint (&Buf[Offset], Size - Offset, " r%d, [r%d #0x%x]", Rd, (OpCode >> 7) & 7, (OpCode >> 6) & 0x1f);
@ -392,8 +409,54 @@ DisassembleThumbInstruction (
}
}
}
#if 0
// Thumb2 are 32-bit instructions
*OpCodePtrPtr += 1;
for (Index = 0; Index < sizeof (gOpThumb2)/sizeof (THUMB_INSTRUCTIONS); Index++) {
if ((OpCode32 & gOpThumb2[Index].Mask) == gOpThumb2[Index].OpCode) {
}
}
#endif
// Unknown instruction is 16-bits
*OpCodePtrPtr -= 1;
AsciiSPrint (Buf, Size, "0x%04x", OpCode);
}
VOID
DisassembleArmInstruction (
IN UINT32 **OpCodePtr,
OUT CHAR8 *Buf,
OUT UINTN Size
);
/**
Place a dissasembly of of **OpCodePtr into buffer, and update OpCodePtr to
point to next instructin.
We cheat and only decode instructions that access
memory. If the instruction is not found we dump the instruction in hex.
@param OpCodePtrPtr Pointer to pointer of ARM Thumb instruction to disassemble.
@param Thumb TRUE for Thumb(2), FALSE for ARM instruction stream
@param Buf Buffer to sprintf disassembly into.
@param Size Size of Buf in bytes.
**/
VOID
DisassembleInstruction (
IN UINT8 **OpCodePtr,
IN BOOLEAN Thumb,
OUT CHAR8 *Buf,
OUT UINTN Size
)
{
if (Thumb) {
DisassembleThumbInstruction ((UINT16 **)OpCodePtr, Buf, Size);
} else {
DisassembleArmInstruction ((UINT32 **)OpCodePtr, Buf, Size);
}
}

View File

@ -18,27 +18,13 @@
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include <Library/ArmDisassemblerLib.h>
#include <Guid/DebugImageInfoTable.h>
#include <Protocol/DebugSupport.h>
#include <Protocol/LoadedImage.h>
VOID
DisassembleArmInstruction (
IN UINT32 *OpCodePtr,
OUT CHAR8 *Buf,
OUT UINTN Size
);
VOID
DisassembleThumbInstruction (
IN UINT16 *OpCodePtr,
OUT CHAR8 *Buf,
OUT UINTN Size
);
EFI_DEBUG_IMAGE_INFO_TABLE_HEADER *gDebugImageTableHeader = NULL;
@ -248,6 +234,7 @@ DefaultExceptionHandler (
UINT32 Offset;
CHAR8 CpsrStr[32]; // char per bit. Lower 5-bits are mode that is a 3 char string
CHAR8 Buffer[80];
UINT8 *DisAsm;
CpsrString (SystemContext.SystemContextArm->CPSR, CpsrStr);
DEBUG ((EFI_D_ERROR, "%a\n", CpsrStr));
@ -268,15 +255,10 @@ DefaultExceptionHandler (
DEBUG ((EFI_D_ERROR, "loaded at 0x%08x (PE/COFF offset) 0x%x (ELF or Mach-O offset) 0x%x", ImageBase, Offset, Offset - PeCoffSizeOfHeader));
// If we come from an image it is safe to show the instruction. We know it should not fault
if ((SystemContext.SystemContextArm->CPSR & 0x20) == 0) {
// ARM
DisassembleArmInstruction ((UINT32 *)(UINTN)SystemContext.SystemContextArm->PC, Buffer, sizeof (Buffer));
DEBUG ((EFI_D_ERROR, "\n%a", Buffer));
} else {
// Thumb
DisassembleThumbInstruction ((UINT16 *)(UINTN)SystemContext.SystemContextArm->PC, Buffer, sizeof (Buffer));
DEBUG ((EFI_D_ERROR, "\n%a", Buffer));
}
DisAsm = (UINT8 *)(UINTN)SystemContext.SystemContextArm->PC;
DisassembleInstruction (&DisAsm, (SystemContext.SystemContextArm->CPSR & BIT5) == BIT5, Buffer, sizeof (Buffer));
DEBUG ((EFI_D_ERROR, "\n%a", Buffer));
}
DEBUG_CODE_END ();
DEBUG ((EFI_D_ERROR, "\n R0 0x%08x R1 0x%08x R2 0x%08x R3 0x%08x\n", SystemContext.SystemContextArm->R0, SystemContext.SystemContextArm->R1, SystemContext.SystemContextArm->R2, SystemContext.SystemContextArm->R3));

View File

@ -15,7 +15,7 @@
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = SemiHostingSerialPortLib
BASE_NAME = DefaultExceptionHandlerLib
FILE_GUID = EACDB354-DF1A-4AF9-A171-499737ED818F
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
@ -25,8 +25,6 @@
[Sources.common]
DefaultExceptionHandler.c
ArmDisassembler.c
ThumbDisassembler.c
[Packages]
MdePkg/MdePkg.dec
@ -38,5 +36,6 @@
PrintLib
DebugLib
PeCoffGetEntryPointLib
ArmDisassemblerLib

View File

@ -110,6 +110,7 @@
EblNetworkLib|EmbeddedPkg/Library/EblNetworkLib/EblNetworkLib.inf
GdbSerialLib|Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.inf
ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
[LibraryClasses.common.SEC]