From 097bd461c4219edb62f4595ce7ccc6ec3bb34db9 Mon Sep 17 00:00:00 2001 From: andrewfish Date: Mon, 1 Feb 2010 18:25:18 +0000 Subject: [PATCH] Move ARM disassembler into a library. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9902 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPkg/ArmPkg.dec | 3 +- ArmPkg/ArmPkg.dsc | 1 + ArmPkg/Include/Library/ArmDisassemblerLib.h | 39 ++++++++ .../ArmDisassembler.c | 18 ++-- .../ArmDisassemblerLib/ArmDisassemblerLib.inf | 40 ++++++++ .../ThumbDisassembler.c | 91 ++++++++++++++++--- .../DefaultExceptionHandler.c | 30 ++---- .../DefaultExceptionHandlerLib.inf | 5 +- BeagleBoardPkg/BeagleBoardPkg.dsc | 1 + 9 files changed, 180 insertions(+), 48 deletions(-) create mode 100644 ArmPkg/Include/Library/ArmDisassemblerLib.h rename ArmPkg/Library/{DefaultExceptionHandlerLib => ArmDisassemblerLib}/ArmDisassembler.c (93%) create mode 100644 ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf rename ArmPkg/Library/{DefaultExceptionHandlerLib => ArmDisassemblerLib}/ThumbDisassembler.c (83%) diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec index 67c729d8e1..8f5d69635d 100644 --- a/ArmPkg/ArmPkg.dec +++ b/ArmPkg/ArmPkg.dec @@ -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 } } diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index 12dd519572..b0d2c8f227 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -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 diff --git a/ArmPkg/Include/Library/ArmDisassemblerLib.h b/ArmPkg/Include/Library/ArmDisassemblerLib.h new file mode 100644 index 0000000000..6ba270fea3 --- /dev/null +++ b/ArmPkg/Include/Library/ArmDisassemblerLib.h @@ -0,0 +1,39 @@ +/** @file + + Copyright (c) 2008-2010 Apple Inc. All rights reserved.
+ + 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 diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/ArmDisassembler.c b/ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c similarity index 93% rename from ArmPkg/Library/DefaultExceptionHandlerLib/ArmDisassembler.c rename to ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c index 034236b946..5b43f5542e 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/ArmDisassembler.c +++ b/ArmPkg/Library/ArmDisassemblerLib/ArmDisassembler.c @@ -15,9 +15,8 @@ #include #include -#include #include - +#include 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; } diff --git a/ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf b/ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf new file mode 100644 index 0000000000..4cbf461d17 --- /dev/null +++ b/ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf @@ -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 + + diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/ThumbDisassembler.c b/ArmPkg/Library/ArmDisassemblerLib/ThumbDisassembler.c similarity index 83% rename from ArmPkg/Library/DefaultExceptionHandlerLib/ThumbDisassembler.c rename to ArmPkg/Library/ArmDisassemblerLib/ThumbDisassembler.c index b021e7881c..d59d1030fc 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/ThumbDisassembler.c +++ b/ArmPkg/Library/ArmDisassemblerLib/ThumbDisassembler.c @@ -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 , [, #<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); + } +} diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandler.c b/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandler.c index 8180c42cab..b6fbb19f46 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandler.c +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandler.c @@ -18,27 +18,13 @@ #include #include #include +#include #include #include #include -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)); diff --git a/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf b/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf index a989895545..94009ed7c3 100644 --- a/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf +++ b/ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf @@ -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 diff --git a/BeagleBoardPkg/BeagleBoardPkg.dsc b/BeagleBoardPkg/BeagleBoardPkg.dsc index f9b1d2ef7b..cf49203c43 100644 --- a/BeagleBoardPkg/BeagleBoardPkg.dsc +++ b/BeagleBoardPkg/BeagleBoardPkg.dsc @@ -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] -- 2.39.2