summaryrefslogtreecommitdiff
path: root/utils/test
diff options
context:
space:
mode:
Diffstat (limited to 'utils/test')
-rw-r--r--utils/test/README-disasm406
-rw-r--r--utils/test/README-lldb-disasm94
-rw-r--r--utils/test/README-run-until-faulted18
-rwxr-xr-xutils/test/disasm.py198
-rwxr-xr-xutils/test/lldb-disasm.py243
-rwxr-xr-xutils/test/llvm-mc-shell.py100
-rw-r--r--utils/test/main.c14
-rwxr-xr-xutils/test/ras.py176
-rwxr-xr-xutils/test/run-dis.py125
-rwxr-xr-xutils/test/run-until-faulted.py111
10 files changed, 1485 insertions, 0 deletions
diff --git a/utils/test/README-disasm b/utils/test/README-disasm
new file mode 100644
index 000000000000..00e9ab681a24
--- /dev/null
+++ b/utils/test/README-disasm
@@ -0,0 +1,406 @@
+This README describes a sample invocation of disasm.py whose purpose is to test
+the low level ARM/Thumb disassembly functionality from llvm using the llvm-mc
+command line. We invoke gdb on an executable, try to disassemble a function,
+and then read the memory contents of the disassembled function.
+
+The byte contents are written into a file named disasm-input.txt and then we
+invoke llvm-mc -disassemble plus options (set with the -o/--options) on the
+byte contents.
+
+See the following for a sample session using this command:
+
+[16:26:57] johnny:/Volumes/data/Radar/9131529 $ /Volumes/data/lldb/svn/trunk/utils/test/disasm.py -C 'set shlib-path-substitutions /usr /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/usr /System /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System /Library /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/Library' -O '-arch armv7' -m /Volumes/data/lldb/llvm/Debug+Asserts/bin/llvm-mc -e /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/usr/lib/libSystem.B.dylib -f printf --options='-triple=thumb-apple-darwin -debug-only=arm-disassembler'
+gdb commands: ['set shlib-path-substitutions /usr /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/usr /System /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System /Library /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/Library']
+gdb options: -arch armv7
+executable: /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/usr/lib/libSystem.B.dylib
+function: printf
+llvm-mc: /Volumes/data/lldb/llvm/Debug+Asserts/bin/llvm-mc
+llvm-mc options: -triple=thumb-apple-darwin -debug-only=arm-disassembler
+GNU gdb 6.3.50-20050815 (Apple version gdb-1518) (Sat Feb 12 02:56:02 UTC 2011)
+Copyright 2004 Free Software Foundation, Inc.
+GDB is free software, covered by the GNU General Public License, and you are
+welcome to change it and/or distribute copies of it under certain conditions.
+Type "show copying" to see the conditions.
+There is absolutely no warranty for GDB. Type "show warranty" for details.
+This GDB was configured as "--host=x86_64-apple-darwin --target=arm-apple-darwin".
+<Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/Library
+<eloper/SDKs/iPhoneOS4.3.sdk/usr/lib/libSystem.B.dylib
+Reading symbols for shared libraries ................ done
+Reading symbols from /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/usr/lib/libSystem.B.dylib...done.
+(gdb) disassemble printf
+Dump of assembler code for function printf:
+0x0704cdd0 <printf+0>: push {r0, r1, r2, r3}
+0x0704cdd2 <printf+2>: push {r4, r5, r7, lr}
+0x0704cdd4 <printf+4>: add r7, sp, #8
+0x0704cdd6 <printf+6>: sub sp, #4
+0x0704cdd8 <printf+8>: add r3, sp, #20
+0x0704cdda <printf+10>: ldr.w r5, [r3], #4
+0x0704cdde <printf+14>: str r3, [sp, #0]
+0x0704cde0 <printf+16>: ldr r3, [pc, #52] (0x704ce18 <printf+72>)
+0x0704cde2 <printf+18>: add r3, pc
+0x0704cde4 <printf+20>: ldr r0, [r3, #0]
+0x0704cde6 <printf+22>: ldr r4, [r0, #0]
+0x0704cde8 <printf+24>: ldr r0, [pc, #48] (0x704ce1c <printf+76>)
+0x0704cdea <printf+26>: add r0, pc
+0x0704cdec <printf+28>: ldr r0, [r0, #0]
+0x0704cdee <printf+30>: ldr r0, [r0, #0]
+0x0704cdf0 <printf+32>: blx 0x707ba30 <pthread_getspecific>
+0x0704cdf4 <printf+36>: cbnz r0, 0x704cdfe <printf+46>
+0x0704cdf6 <printf+38>: ldr r1, [pc, #40] (0x704ce20 <printf+80>)
+0x0704cdf8 <printf+40>: add r1, pc
+0x0704cdfa <printf+42>: ldr r1, [r1, #0]
+0x0704cdfc <printf+44>: b.n 0x704ce00 <printf+48>
+0x0704cdfe <printf+46>: mov r1, r0
+0x0704ce00 <printf+48>: mov r0, r4
+0x0704ce02 <printf+50>: mov r2, r5
+0x0704ce04 <printf+52>: ldr r3, [sp, #0]
+0x0704ce06 <printf+54>: bl 0x704ad44 <vfprintf_l>
+0x0704ce0a <printf+58>: sub.w sp, r7, #8 ; 0x8
+0x0704ce0e <printf+62>: ldmia.w sp!, {r4, r5, r7, lr}
+0x0704ce12 <printf+66>: add sp, #16
+0x0704ce14 <printf+68>: bx lr
+0x0704ce16 <printf+70>: nop
+0x0704ce18 <printf+72>: movs r3, #142
+0x0704ce1a <printf+74>: lsls r5, r0, #0
+0x0704ce1c <printf+76>: adds r1, #122
+0x0704ce1e <printf+78>: lsls r5, r0, #0
+0x0704ce20 <printf+80>: adds r1, #104
+0x0704ce22 <printf+82>: lsls r5, r0, #0
+End of assembler dump.
+(gdb) x /2b 0x0704cdd0
+0x704cdd0 <printf>: 0x0f 0xb4
+(gdb) x /2b 0x0704cdd2
+0x704cdd2 <printf+2>: 0xb0 0xb5
+(gdb) x /2b 0x0704cdd4
+0x704cdd4 <printf+4>: 0x02 0xaf
+(gdb) x /2b 0x0704cdd6
+0x704cdd6 <printf+6>: 0x81 0xb0
+(gdb) x /2b 0x0704cdd8
+0x704cdd8 <printf+8>: 0x05 0xab
+(gdb) x /4b 0x0704cdda
+0x704cdda <printf+10>: 0x53 0xf8 0x04 0x5b
+(gdb) x /2b 0x0704cdde
+0x704cdde <printf+14>: 0x00 0x93
+(gdb) x /2b 0x0704cde0
+0x704cde0 <printf+16>: 0x0d 0x4b
+(gdb) x /2b 0x0704cde2
+0x704cde2 <printf+18>: 0x7b 0x44
+(gdb) x /2b 0x0704cde4
+0x704cde4 <printf+20>: 0x18 0x68
+(gdb) x /2b 0x0704cde6
+0x704cde6 <printf+22>: 0x04 0x68
+(gdb) x /2b 0x0704cde8
+0x704cde8 <printf+24>: 0x0c 0x48
+(gdb) x /2b 0x0704cdea
+0x704cdea <printf+26>: 0x78 0x44
+(gdb) x /2b 0x0704cdec
+0x704cdec <printf+28>: 0x00 0x68
+(gdb) x /2b 0x0704cdee
+0x704cdee <printf+30>: 0x00 0x68
+(gdb) x /4b 0x0704cdf0
+0x704cdf0 <printf+32>: 0x2e 0xf0 0x1e 0xee
+(gdb) x /2b 0x0704cdf4
+0x704cdf4 <printf+36>: 0x18 0xb9
+(gdb) x /2b 0x0704cdf6
+0x704cdf6 <printf+38>: 0x0a 0x49
+(gdb) x /2b 0x0704cdf8
+0x704cdf8 <printf+40>: 0x79 0x44
+(gdb) x /2b 0x0704cdfa
+0x704cdfa <printf+42>: 0x09 0x68
+(gdb) x /2b 0x0704cdfc
+0x704cdfc <printf+44>: 0x00 0xe0
+(gdb) x /2b 0x0704cdfe
+0x704cdfe <printf+46>: 0x01 0x46
+(gdb) x /2b 0x0704ce00
+0x704ce00 <printf+48>: 0x20 0x46
+(gdb) x /2b 0x0704ce02
+0x704ce02 <printf+50>: 0x2a 0x46
+(gdb) x /2b 0x0704ce04
+0x704ce04 <printf+52>: 0x00 0x9b
+(gdb) x /4b 0x0704ce06
+0x704ce06 <printf+54>: 0xfd 0xf7 0x9d 0xff
+(gdb) x /4b 0x0704ce0a
+0x704ce0a <printf+58>: 0xa7 0xf1 0x08 0x0d
+(gdb) x /4b 0x0704ce0e
+0x704ce0e <printf+62>: 0xbd 0xe8 0xb0 0x40
+(gdb) x /2b 0x0704ce12
+0x704ce12 <printf+66>: 0x04 0xb0
+(gdb) x /2b 0x0704ce14
+0x704ce14 <printf+68>: 0x70 0x47
+(gdb) x /2b 0x0704ce16
+0x704ce16 <printf+70>: 0x00 0xbf
+(gdb) x /2b 0x0704ce18
+0x704ce18 <printf+72>: 0x8e 0x23
+(gdb) x /2b 0x0704ce1a
+0x704ce1a <printf+74>: 0x05 0x00
+(gdb) x /2b 0x0704ce1c
+0x704ce1c <printf+76>: 0x7a 0x31
+(gdb) x /2b 0x0704ce1e
+0x704ce1e <printf+78>: 0x05 0x00
+(gdb) x /2b 0x0704ce20
+0x704ce20 <printf+80>: 0x68 0x31
+(gdb) x /2b 0x0704ce22
+0x704ce22 <printf+82>: 0x05 0x00
+(gdb) quit
+
+Executing command: /Volumes/data/lldb/llvm/Debug+Asserts/bin/llvm-mc -disassemble -triple=thumb-apple-darwin -debug-only=arm-disassembler disasm-input.txt
+Opcode=2305 Name=tPUSH Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 1: 0: 1: 1| 0: 1: 0: 0| 0: 0: 0: 0| 1: 1: 1: 1|
+-------------------------------------------------------------------------------------------------
+
+ push {r0, r1, r2, r3}
+Opcode=2305 Name=tPUSH Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 1: 0: 1: 1| 0: 1: 0: 1| 1: 0: 1: 1| 0: 0: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ push {r4, r5, r7, lr}
+Opcode=2228 Name=tADDrSPi Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 1: 0: 1: 0| 1: 1: 1: 1| 0: 0: 0: 0| 0: 0: 1: 0|
+-------------------------------------------------------------------------------------------------
+
+ add r7, sp, #8
+Opcode=2328 Name=tSUBspi Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 1: 0: 1: 1| 0: 0: 0: 0| 1: 0: 0: 0| 0: 0: 0: 1|
+-------------------------------------------------------------------------------------------------
+
+ sub sp, #4
+Opcode=2228 Name=tADDrSPi Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 1: 0: 1: 0| 1: 0: 1: 1| 0: 0: 0: 0| 0: 1: 0: 1|
+-------------------------------------------------------------------------------------------------
+
+ add r3, sp, #20
+Opcode=1963 Name=t2LDR_POST Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 1: 1: 1: 1| 1: 0: 0: 0| 0: 1: 0: 1| 0: 0: 1: 1| 0: 1: 0: 1| 1: 0: 1: 1| 0: 0: 0: 0| 0: 1: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ ldr r5, [r3], #4
+Opcode=2324 Name=tSTRspi Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 1: 0: 0: 1| 0: 0: 1: 1| 0: 0: 0: 0| 0: 0: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ str r3, [sp]
+Opcode=2275 Name=tLDRpci Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 0| 1: 0: 1: 1| 0: 0: 0: 0| 1: 1: 0: 1|
+-------------------------------------------------------------------------------------------------
+
+ ldr.n r3, #52
+Opcode=2223 Name=tADDhirr Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 0| 0: 1: 0: 0| 0: 1: 1: 1| 1: 0: 1: 1|
+-------------------------------------------------------------------------------------------------
+
+ add r3, pc
+Opcode=2274 Name=tLDRi Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 1: 0| 1: 0: 0: 0| 0: 0: 0: 1| 1: 0: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ ldr r0, [r3]
+Opcode=2274 Name=tLDRi Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 1: 0| 1: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ ldr r4, [r0]
+Opcode=2275 Name=tLDRpci Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 0| 1: 0: 0: 0| 0: 0: 0: 0| 1: 1: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ ldr.n r0, #48
+Opcode=2223 Name=tADDhirr Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 0| 0: 1: 0: 0| 0: 1: 1: 1| 1: 0: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ add r0, pc
+Opcode=2274 Name=tLDRi Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 1: 0| 1: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ ldr r0, [r0]
+Opcode=2274 Name=tLDRi Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 1: 0| 1: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ ldr r0, [r0]
+Opcode=2243 Name=tBLXi_r9 Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 1: 1: 1: 1| 0: 0: 0: 0| 0: 0: 1: 0| 1: 1: 1: 0| 1: 1: 1: 0| 1: 1: 1: 0| 0: 0: 0: 1| 1: 1: 1: 0|
+-------------------------------------------------------------------------------------------------
+
+ blx #191548
+Opcode=2255 Name=tCBNZ Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 1: 0: 1: 1| 1: 0: 0: 1| 0: 0: 0: 1| 1: 0: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ cbnz r0, #6
+Opcode=2275 Name=tLDRpci Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 0| 1: 0: 0: 1| 0: 0: 0: 0| 1: 0: 1: 0|
+-------------------------------------------------------------------------------------------------
+
+ ldr.n r1, #40
+Opcode=2223 Name=tADDhirr Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 0| 0: 1: 0: 0| 0: 1: 1: 1| 1: 0: 0: 1|
+-------------------------------------------------------------------------------------------------
+
+ add r1, pc
+Opcode=2274 Name=tLDRi Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 1: 0| 1: 0: 0: 0| 0: 0: 0: 0| 1: 0: 0: 1|
+-------------------------------------------------------------------------------------------------
+
+ ldr r1, [r1]
+Opcode=2238 Name=tB Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 1: 1: 1: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ b #0
+Opcode=2294 Name=tMOVr Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 0| 0: 1: 1: 0| 0: 0: 0: 0| 0: 0: 0: 1|
+-------------------------------------------------------------------------------------------------
+
+ mov r1, r0
+Opcode=2294 Name=tMOVr Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 0| 0: 1: 1: 0| 0: 0: 1: 0| 0: 0: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ mov r0, r4
+Opcode=2294 Name=tMOVr Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 0| 0: 1: 1: 0| 0: 0: 1: 0| 1: 0: 1: 0|
+-------------------------------------------------------------------------------------------------
+
+ mov r2, r5
+Opcode=2278 Name=tLDRspi Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 1: 0: 0: 1| 1: 0: 1: 1| 0: 0: 0: 0| 0: 0: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ ldr r3, [sp]
+Opcode=2246 Name=tBLr9 Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 1: 1: 1: 1| 0: 1: 1: 1| 1: 1: 1: 1| 1: 1: 0: 1| 1: 1: 1: 1| 1: 1: 1: 1| 1: 0: 0: 1| 1: 1: 0: 1|
+-------------------------------------------------------------------------------------------------
+
+ bl #-8390
+Opcode=2153 Name=t2SUBri Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 1: 1: 1: 1| 0: 0: 0: 1| 1: 0: 1: 0| 0: 1: 1: 1| 0: 0: 0: 0| 1: 1: 0: 1| 0: 0: 0: 0| 1: 0: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ sub.w sp, r7, #8
+Opcode=1926 Name=t2LDMIA_UPD Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 1: 1: 1: 0| 1: 0: 0: 0| 1: 0: 1: 1| 1: 1: 0: 1| 0: 1: 0: 0| 0: 0: 0: 0| 1: 0: 1: 1| 0: 0: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ pop.w {r4, r5, r7, lr}
+Opcode=2230 Name=tADDspi Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 1: 0: 1: 1| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ add sp, #16
+Opcode=2250 Name=tBX_RET Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 0| 0: 1: 1: 1| 0: 1: 1: 1| 0: 0: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ bx lr
+Opcode=2300 Name=tNOP Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 1: 0: 1: 1| 1: 1: 1: 1| 0: 0: 0: 0| 0: 0: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ nop
+Opcode=2293 Name=tMOVi8 Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 1: 0| 0: 0: 1: 1| 1: 0: 0: 0| 1: 1: 1: 0|
+-------------------------------------------------------------------------------------------------
+
+ movs r3, #142
+Opcode=2290 Name=tMOVSr Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 1|
+-------------------------------------------------------------------------------------------------
+
+ movs r5, r0
+Opcode=2225 Name=tADDi8 Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 1: 1| 0: 0: 0: 1| 0: 1: 1: 1| 1: 0: 1: 0|
+-------------------------------------------------------------------------------------------------
+
+ adds r1, #122
+Opcode=2290 Name=tMOVSr Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 1|
+-------------------------------------------------------------------------------------------------
+
+ movs r5, r0
+Opcode=2225 Name=tADDi8 Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 1: 1| 0: 0: 0: 1| 0: 1: 1: 0| 1: 0: 0: 0|
+-------------------------------------------------------------------------------------------------
+
+ adds r1, #104
+Opcode=2290 Name=tMOVSr Format=ARM_FORMAT_THUMBFRM(25)
+ 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
+-------------------------------------------------------------------------------------------------
+| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 0: 0: 0| 0: 1: 0: 1|
+-------------------------------------------------------------------------------------------------
+
+ movs r5, r0
+[16:28:00] johnny:/Volumes/data/Radar/9131529 $
diff --git a/utils/test/README-lldb-disasm b/utils/test/README-lldb-disasm
new file mode 100644
index 000000000000..328658c326b1
--- /dev/null
+++ b/utils/test/README-lldb-disasm
@@ -0,0 +1,94 @@
+This README describes a sample invocation of lldb-disasm.py whose purpose is to test
+the lldb 'disassemble' command.
+
+This is for the initial checkin of lldb-disasm.py which only reads an executable image and
+dumps the symbol table from the imgae and its dependent libraries. The output was cut off
+since it is too large.
+
+da0603a-dhcp191:9131529 johnny$ /Volumes/data/lldb/svn/trunk/utils/test/lldb-disasm.py -C 'platform create remote-ios' -e /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/usr/lib/libSystem.B.dylib
+lldb commands: ['platform create remote-ios']
+lldb options: None
+executable: /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/usr/lib/libSystem.B.dylib
+sys.path: ['/Volumes/data/lldb/svn/trunk/utils/test', '/Volumes/data/lldb/svn/trunk/build/Debug/LLDB.framework/Resources/Python', '/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python26.zip', '/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6', '/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-darwin', '/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac', '/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac/lib-scriptpackages', '/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python', '/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk', '/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-old', '/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-dynload', '/Library/Python/2.6/site-packages', '/AppleInternal/Library/Python/2.6/site-packages', '/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/PyObjC', '/System/Library/Frameworks/Python.framework/Versions/2.6/Extras/lib/python/wx-2.8-mac-unicode', '/Volumes/data/lldb/svn/trunk/utils/test/../../test/pexpect-2.4', '/Volumes/data/lldb/svn/trunk/test']
+/Volumes/data/lldb/svn/trunk/test/lldbutil.py:80: SyntaxWarning: import * only allowed at module level
+ def int_to_bytearray(val, bytesize):
+/Volumes/data/lldb/svn/trunk/test/lldbutil.py:105: SyntaxWarning: import * only allowed at module level
+ def bytearray_to_int(bytes, bytesize):
+run command: platform create remote-ios
+output: Platform: remote-ios
+Not connected to a remote platform.
+SDKROOT: "/Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.3 (8F190)"
+
+run command: file /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/usr/lib/libSystem.B.dylib
+output: Current executable set to '/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/usr/lib/libSystem.B.dylib' (armv7).
+
+run command: image dump symtab
+output: Dumping symbol table for 18 modules.
+Symtab, file = /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/usr/lib/libSystem.B.dylib, num_symbols = 851:
+ Debug symbol
+ |Synthetic symbol
+ ||Externally Visible
+ |||
+Index UserID DSX Type File Address/Value Load Address Size Flags Name
+------- ------ --- ------------ ------------------ ------------------ ------------------ ---------- ----------------------------------
+[ 0] 0 Code 0x0000000000001420 0x0000000000000000 0x000e0008 libSystem_initializer
+[ 1] 1 Code 0x00000000000014c4 0x0000000000000000 0x001e0008 __keymgr_initializer
+[ 2] 2 Code 0x00000000000014fc 0x0000000000000000 0x000e0008 dwarf2_unwind_dyld_add_image_hook
+[ 3] 3 Code 0x0000000000001564 0x0000000000000000 0x000e0008 get_or_create_key_element
+[ 4] 4 Code 0x0000000000001684 0x0000000000000000 0x000e0008 unlock_node
+[ 5] 5 Code 0x0000000000001930 0x0000000000000000 0x000e0000 RsqrtTable
+[ 6] 6 Code 0x0000000000001c30 0x0000000000000000 0x000e0000 acosf_crossover
+[ 7] 7 Code 0x0000000000001c34 0x0000000000000000 0x000e0000 acosf_mid_poly
+[ 8] 8 Code 0x0000000000001c48 0x0000000000000000 0x000e0000 Pi2_Q30
+[ 9] 9 Code 0x0000000000001c4c 0x0000000000000000 0x000e0000 Pi_Q30
+[ 10] 10 Code 0x0000000000001c78 0x0000000000000000 0x000e0000 acosf_approx
+[ 11] 11 Code 0x0000000000001cec 0x0000000000000000 0x000e0000 acosf_pos_tail_poly
+[ 12] 12 Code 0x0000000000001d00 0x0000000000000000 0x000e0000 acosf_tail
+[ 13] 13 Code 0x0000000000001dfc 0x0000000000000000 0x000e0000 acosf_normalize
+[ 14] 14 Code 0x0000000000001e10 0x0000000000000000 0x000e0000 acosf_round
+[ 15] 15 Code 0x0000000000001e28 0x0000000000000000 0x000e0000 acosf_encode
+[ 16] 16 Code 0x0000000000001e30 0x0000000000000000 0x000e0000 acosf_done
+[ 17] 17 Code 0x0000000000001e38 0x0000000000000000 0x000e0000 acosf_special
+[ 18] 18 Code 0x0000000000001e68 0x0000000000000000 0x000e0000 acosf_small
+[ 19] 19 Code 0x0000000000001e9c 0x0000000000000000 0x000e0000 acosf_very_small
+[ 20] 20 Code 0x0000000000001eb8 0x0000000000000000 0x000e0000 Pif
+[ 21] 21 Code 0x000000000000220c 0x0000000000000000 0x000e0000 RsqrtTable
+[ 22] 22 Code 0x000000000000250c 0x0000000000000000 0x000e0000 asinf_crossover
+[ 23] 23 Code 0x0000000000002510 0x0000000000000000 0x000e0000 asinf_mid_poly
+[ 24] 24 Code 0x0000000000002524 0x0000000000000000 0x000e0000 Pi2_Q30
+[ 25] 25 Code 0x0000000000002550 0x0000000000000000 0x000e0000 asinf_approx
+[ 26] 26 Code 0x00000000000025e4 0x0000000000000000 0x000e0000 asinf_tail_poly
+[ 27] 27 Code 0x0000000000002600 0x0000000000000000 0x000e0000 asinf_tail
+[ 28] 28 Code 0x00000000000026e0 0x0000000000000000 0x000e0000 asinf_normalize
+[ 29] 29 Code 0x00000000000026f4 0x0000000000000000 0x000e0000 asinf_round
+[ 30] 30 Code 0x000000000000270c 0x0000000000000000 0x000e0000 asinf_encode
+[ 31] 31 Code 0x0000000000002718 0x0000000000000000 0x000e0000 asinf_done
+[ 32] 32 Code 0x0000000000002720 0x0000000000000000 0x000e0000 asinf_special
+[ 33] 33 Code 0x0000000000002754 0x0000000000000000 0x000e0000 asinf_small
+[ 34] 34 Code 0x0000000000002784 0x0000000000000000 0x000e0000 Pi2f
+[ 35] 35 Code 0x0000000000005774 0x0000000000000000 0x000e0008 rem_pio2
+[ 36] 36 Code 0x00000000000076c4 0x0000000000000000 0x000e0008 __kernel_rem_pio2
+[ 37] 37 Code 0x0000000000008c90 0x0000000000000000 0x000e0008 __kernel_tan
+[ 38] 38 Code 0x0000000000008ef0 0x0000000000000000 0x000e0008 lgammaApprox
+[ 39] 39 Code 0x000000000000b3d4 0x0000000000000000 0x000e0000 powf_not_special
+[ 40] 40 Code 0x000000000000b3dc 0x0000000000000000 0x000e0000 powf_ylgx
+[ 41] 41 Code 0x000000000000b438 0x0000000000000000 0x000e0000 powf_done
+[ 42] 42 Code 0x000000000000b43c 0x0000000000000000 0x000e0000 powf_special_y
+[ 43] 43 Code 0x000000000000b4a8 0x0000000000000000 0x000e0000 powf_special_x
+[ 44] 44 Code 0x000000000000b4cc 0x0000000000000000 0x000e0000 powf_mzero_minf
+[ 45] 45 Code 0x000000000000b54c 0x0000000000000000 0x000e0000 powf_y_odd
+[ 46] 46 Code 0x000000000000b57c 0x0000000000000000 0x000e0000 powf_y_nonint
+[ 47] 47 Code 0x000000000000b588 0x0000000000000000 0x000e0000 powf_y_even
+[ 48] 48 Code 0x000000000000b7a8 0x0000000000000000 0x000e0000 powf_log2_reduction
+[ 49] 49 Code 0x000000000000b7a8 0x0000000000000000 0x000e0000 powf_log2
+[ 50] 50 Code 0x000000000000b814 0x0000000000000000 0x000e0000 powf_log2_approx
+[ 51] 51 Code 0x000000000000b88c 0x0000000000000000 0x000e0000 powf_log2_synthesis
+[ 52] 52 Code 0x000000000000b960 0x0000000000000000 0x000e0000 powf_log2_exactPowerOfTwo
+[ 53] 53 Code 0x000000000000b980 0x0000000000000000 0x000e0000 powf_log2_near1
+[ 54] 54 Code 0x000000000000b9ec 0x0000000000000000 0x000e0000 powf_log2_synthesis_near1
+[ 55] 55 Code 0x000000000000ba04 0x0000000000000000 0x000e0000 Q32_minimax
+[ 56] 56 Code 0x000000000000ba10 0x0000000000000000 0x000e0000 iexp2_lut
+[ 57] 57 Code 0x000000000000ba94 0x0000000000000000 0x000e0000 powf_exp2
+[ 58] 58 Code 0x000000000000bb18 0x0000000000000000 0x000e0000 powf_exp2_exact_int
+[ 59] 59 Code 0x000000000000bb24 0x0000000000000000 0x000e0000 powf_exp2_big
+[ 60] 60 Code 0x000000000000bb74 0x0000000000000000 0x000e0000 powf_exp2_overflow
diff --git a/utils/test/README-run-until-faulted b/utils/test/README-run-until-faulted
new file mode 100644
index 000000000000..f89f8636d627
--- /dev/null
+++ b/utils/test/README-run-until-faulted
@@ -0,0 +1,18 @@
+A example usage of the Python script run-until-faulted.py:
+
+[18:20:29] johnny:/Volumes/data/lldb/svn/trunk/utils/test $ ./run-until-faulted.py -l /Volumes/data/lldb/svn/trunk/build/Debug/lldb -e './a.out'
+lldb command: /Volumes/data/lldb/svn/trunk/build/Debug/lldb
+executable: ./a.out
+executable options:
+sending file command....
+sending process launch -- (iteration: 0)
+
+* thread #1: tid = 0x2d03, 0x0000000100000eef a.out`main + 39 at main.c:7, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
+ 4 {
+ 5 int *null_ptr = 0;
+ 6 printf("Hello, fault!\n");
+-> 7 printf("Now segfault %d\n", *null_ptr);
+ 8 }
+
+(lldb) q
+[18:20:40] johnny:/Volumes/data/lldb/svn/trunk/utils/test $
diff --git a/utils/test/disasm.py b/utils/test/disasm.py
new file mode 100755
index 000000000000..46660299f188
--- /dev/null
+++ b/utils/test/disasm.py
@@ -0,0 +1,198 @@
+#!/usr/bin/env python
+
+"""
+Run gdb to disassemble a function, feed the bytes to 'llvm-mc -disassemble' command,
+and display the disassembly result.
+
+"""
+
+import os
+import sys
+from optparse import OptionParser
+
+def is_exe(fpath):
+ """Check whether fpath is an executable."""
+ return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+
+def which(program):
+ """Find the full path to a program, or return None."""
+ fpath, fname = os.path.split(program)
+ if fpath:
+ if is_exe(program):
+ return program
+ else:
+ for path in os.environ["PATH"].split(os.pathsep):
+ exe_file = os.path.join(path, program)
+ if is_exe(exe_file):
+ return exe_file
+ return None
+
+def do_llvm_mc_disassembly(gdb_commands, gdb_options, exe, func, mc, mc_options):
+ from cStringIO import StringIO
+ import pexpect
+
+ gdb_prompt = "\r\n\(gdb\) "
+ gdb = pexpect.spawn(('gdb %s' % gdb_options) if gdb_options else 'gdb')
+ # Turn on logging for what gdb sends back.
+ gdb.logfile_read = sys.stdout
+ gdb.expect(gdb_prompt)
+
+ # See if there any extra command(s) to execute before we issue the file command.
+ for cmd in gdb_commands:
+ gdb.sendline(cmd)
+ gdb.expect(gdb_prompt)
+
+ # Now issue the file command.
+ gdb.sendline('file %s' % exe)
+ gdb.expect(gdb_prompt)
+
+ # Send the disassemble command.
+ gdb.sendline('disassemble %s' % func)
+ gdb.expect(gdb_prompt)
+
+ # Get the output from gdb.
+ gdb_output = gdb.before
+
+ # Use StringIO to record the memory dump as well as the gdb assembler code.
+ mc_input = StringIO()
+
+ # These keep track of the states of our simple gdb_output parser.
+ prev_line = None
+ prev_addr = None
+ curr_addr = None
+ addr_diff = 0
+ looking = False
+ for line in gdb_output.split(os.linesep):
+ if line.startswith('Dump of assembler code'):
+ looking = True
+ continue
+
+ if line.startswith('End of assembler dump.'):
+ looking = False
+ prev_addr = curr_addr
+ if mc_options and mc_options.find('arm') != -1:
+ addr_diff = 4
+ if mc_options and mc_options.find('thumb') != -1:
+ # It is obviously wrong to assume the last instruction of the
+ # function has two bytes.
+ # FIXME
+ addr_diff = 2
+
+ if looking and line.startswith('0x'):
+ # It's an assembler code dump.
+ prev_addr = curr_addr
+ curr_addr = line.split(None, 1)[0]
+ if prev_addr and curr_addr:
+ addr_diff = int(curr_addr, 16) - int(prev_addr, 16)
+
+ if prev_addr and addr_diff > 0:
+ # Feed the examining memory command to gdb.
+ gdb.sendline('x /%db %s' % (addr_diff, prev_addr))
+ gdb.expect(gdb_prompt)
+ x_output = gdb.before
+ # Get the last output line from the gdb examine memory command,
+ # split the string into a 3-tuple with separator '>:' to handle
+ # objc method names.
+ memory_dump = x_output.split(os.linesep)[-1].partition('>:')[2].strip()
+ #print "\nbytes:", memory_dump
+ disasm_str = prev_line.partition('>:')[2]
+ print >> mc_input, '%s # %s' % (memory_dump, disasm_str)
+
+ # We're done with the processing. Assign the current line to be prev_line.
+ prev_line = line
+
+ # Close the gdb session now that we are done with it.
+ gdb.sendline('quit')
+ gdb.expect(pexpect.EOF)
+ gdb.close()
+
+ # Write the memory dump into a file.
+ with open('disasm-input.txt', 'w') as f:
+ f.write(mc_input.getvalue())
+
+ mc_cmd = '%s -disassemble %s disasm-input.txt' % (mc, mc_options)
+ print "\nExecuting command:", mc_cmd
+ os.system(mc_cmd)
+
+ # And invoke llvm-mc with the just recorded file.
+ #mc = pexpect.spawn('%s -disassemble %s disasm-input.txt' % (mc, mc_options))
+ #mc.logfile_read = sys.stdout
+ #print "mc:", mc
+ #mc.close()
+
+
+def main():
+ # This is to set up the Python path to include the pexpect-2.4 dir.
+ # Remember to update this when/if things change.
+ scriptPath = sys.path[0]
+ sys.path.append(os.path.join(scriptPath, os.pardir, os.pardir, 'test', 'pexpect-2.4'))
+
+ parser = OptionParser(usage="""\
+Run gdb to disassemble a function, feed the bytes to 'llvm-mc -disassemble' command,
+and display the disassembly result.
+
+Usage: %prog [options]
+""")
+ parser.add_option('-C', '--gdb-command',
+ type='string', action='append', metavar='COMMAND',
+ default=[], dest='gdb_commands',
+ help='Command(s) gdb executes after starting up (can be empty)')
+ parser.add_option('-O', '--gdb-options',
+ type='string', action='store',
+ dest='gdb_options',
+ help="""The options passed to 'gdb' command if specified.""")
+ parser.add_option('-e', '--executable',
+ type='string', action='store',
+ dest='executable',
+ help="""The executable to do disassembly on.""")
+ parser.add_option('-f', '--function',
+ type='string', action='store',
+ dest='function',
+ help="""The function name (could be an address to gdb) for disassembly.""")
+ parser.add_option('-m', '--llvm-mc',
+ type='string', action='store',
+ dest='llvm_mc',
+ help="""The llvm-mc executable full path, if specified.
+ Otherwise, it must be present in your PATH environment.""")
+
+ parser.add_option('-o', '--options',
+ type='string', action='store',
+ dest='llvm_mc_options',
+ help="""The options passed to 'llvm-mc -disassemble' command if specified.""")
+
+ opts, args = parser.parse_args()
+
+ gdb_commands = opts.gdb_commands
+ gdb_options = opts.gdb_options
+
+ if not opts.executable:
+ parser.print_help()
+ sys.exit(1)
+ executable = opts.executable
+
+ if not opts.function:
+ parser.print_help()
+ sys.exit(1)
+ function = opts.function
+
+ llvm_mc = opts.llvm_mc if opts.llvm_mc else which('llvm-mc')
+ if not llvm_mc:
+ parser.print_help()
+ sys.exit(1)
+
+ # This is optional. For example:
+ # --options='-triple=arm-apple-darwin -debug-only=arm-disassembler'
+ llvm_mc_options = opts.llvm_mc_options
+
+ # We have parsed the options.
+ print "gdb commands:", gdb_commands
+ print "gdb options:", gdb_options
+ print "executable:", executable
+ print "function:", function
+ print "llvm-mc:", llvm_mc
+ print "llvm-mc options:", llvm_mc_options
+
+ do_llvm_mc_disassembly(gdb_commands, gdb_options, executable, function, llvm_mc, llvm_mc_options)
+
+if __name__ == '__main__':
+ main()
diff --git a/utils/test/lldb-disasm.py b/utils/test/lldb-disasm.py
new file mode 100755
index 000000000000..7987c6b01c37
--- /dev/null
+++ b/utils/test/lldb-disasm.py
@@ -0,0 +1,243 @@
+#!/usr/bin/env python
+
+"""
+Run lldb to disassemble all the available functions for an executable image.
+
+"""
+
+import os
+import re
+import sys
+from optparse import OptionParser
+
+def setupSysPath():
+ """
+ Add LLDB.framework/Resources/Python and the test dir to the sys.path.
+ """
+ # Get the directory containing the current script.
+ scriptPath = sys.path[0]
+ if not scriptPath.endswith(os.path.join('utils', 'test')):
+ print "This script expects to reside in lldb's utils/test directory."
+ sys.exit(-1)
+
+ # This is our base name component.
+ base = os.path.abspath(os.path.join(scriptPath, os.pardir, os.pardir))
+
+ # This is for the goodies in the test directory under base.
+ sys.path.append(os.path.join(base,'test'))
+
+ # These are for xcode build directories.
+ xcode3_build_dir = ['build']
+ xcode4_build_dir = ['build', 'lldb', 'Build', 'Products']
+ dbg = ['Debug']
+ rel = ['Release']
+ bai = ['BuildAndIntegration']
+ python_resource_dir = ['LLDB.framework', 'Resources', 'Python']
+
+ dbgPath = os.path.join(base, *(xcode3_build_dir + dbg + python_resource_dir))
+ dbgPath2 = os.path.join(base, *(xcode4_build_dir + dbg + python_resource_dir))
+ relPath = os.path.join(base, *(xcode3_build_dir + rel + python_resource_dir))
+ relPath2 = os.path.join(base, *(xcode4_build_dir + rel + python_resource_dir))
+ baiPath = os.path.join(base, *(xcode3_build_dir + bai + python_resource_dir))
+ baiPath2 = os.path.join(base, *(xcode4_build_dir + bai + python_resource_dir))
+
+ lldbPath = None
+ if os.path.isfile(os.path.join(dbgPath, 'lldb.py')):
+ lldbPath = dbgPath
+ elif os.path.isfile(os.path.join(dbgPath2, 'lldb.py')):
+ lldbPath = dbgPath2
+ elif os.path.isfile(os.path.join(relPath, 'lldb.py')):
+ lldbPath = relPath
+ elif os.path.isfile(os.path.join(relPath2, 'lldb.py')):
+ lldbPath = relPath2
+ elif os.path.isfile(os.path.join(baiPath, 'lldb.py')):
+ lldbPath = baiPath
+ elif os.path.isfile(os.path.join(baiPath2, 'lldb.py')):
+ lldbPath = baiPath2
+
+ if not lldbPath:
+ print 'This script requires lldb.py to be in either ' + dbgPath + ',',
+ print relPath + ', or ' + baiPath
+ sys.exit(-1)
+
+ # This is to locate the lldb.py module. Insert it right after sys.path[0].
+ sys.path[1:1] = [lldbPath]
+ #print "sys.path:", sys.path
+
+
+def run_command(ci, cmd, res, echo=True):
+ if echo:
+ print "run command:", cmd
+ ci.HandleCommand(cmd, res)
+ if res.Succeeded():
+ if echo:
+ print "run_command output:", res.GetOutput()
+ else:
+ if echo:
+ print "run command failed!"
+ print "run_command error:", res.GetError()
+
+def do_lldb_disassembly(lldb_commands, exe, disassemble_options, num_symbols,
+ symbols_to_disassemble,
+ re_symbol_pattern,
+ quiet_disassembly):
+ import lldb, atexit, re
+
+ # Create the debugger instance now.
+ dbg = lldb.SBDebugger.Create()
+ if not dbg:
+ raise Exception('Invalid debugger instance')
+
+ # Register an exit callback.
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+
+ # We want our debugger to be synchronous.
+ dbg.SetAsync(False)
+
+ # Get the command interpreter from the debugger.
+ ci = dbg.GetCommandInterpreter()
+ if not ci:
+ raise Exception('Could not get the command interpreter')
+
+ # And the associated result object.
+ res = lldb.SBCommandReturnObject()
+
+ # See if there any extra command(s) to execute before we issue the file command.
+ for cmd in lldb_commands:
+ run_command(ci, cmd, res, not quiet_disassembly)
+
+ # Now issue the file command.
+ run_command(ci, 'file %s' % exe, res, not quiet_disassembly)
+
+ # Create a target.
+ #target = dbg.CreateTarget(exe)
+ target = dbg.GetSelectedTarget()
+ stream = lldb.SBStream()
+
+ def IsCodeType(symbol):
+ """Check whether an SBSymbol represents code."""
+ return symbol.GetType() == lldb.eSymbolTypeCode
+
+ # Define a generator for the symbols to disassemble.
+ def symbol_iter(num, symbols, re_symbol_pattern, target, verbose):
+ # If we specify the symbols to disassemble, ignore symbol table dump.
+ if symbols:
+ for i in range(len(symbols)):
+ if verbose:
+ print "symbol:", symbols[i]
+ yield symbols[i]
+ else:
+ limited = True if num != -1 else False
+ if limited:
+ count = 0
+ if re_symbol_pattern:
+ pattern = re.compile(re_symbol_pattern)
+ stream = lldb.SBStream()
+ for m in target.module_iter():
+ if verbose:
+ print "module:", m
+ for s in m:
+ if limited and count >= num:
+ return
+ # If a regexp symbol pattern is supplied, consult it.
+ if re_symbol_pattern:
+ # If the pattern does not match, look for the next symbol.
+ if not pattern.match(s.GetName()):
+ continue
+
+ # If we come here, we're ready to disassemble the symbol.
+ if verbose:
+ print "symbol:", s.GetName()
+ if IsCodeType(s):
+ if limited:
+ count = count + 1
+ if verbose:
+ print "returning symbol:", s.GetName()
+ yield s.GetName()
+ if verbose:
+ print "start address:", s.GetStartAddress()
+ print "end address:", s.GetEndAddress()
+ s.GetDescription(stream)
+ print "symbol description:", stream.GetData()
+ stream.Clear()
+
+ # Disassembly time.
+ for symbol in symbol_iter(num_symbols, symbols_to_disassemble, re_symbol_pattern, target, not quiet_disassembly):
+ cmd = "disassemble %s '%s'" % (disassemble_options, symbol)
+ run_command(ci, cmd, res, not quiet_disassembly)
+
+
+def main():
+ # This is to set up the Python path to include the pexpect-2.4 dir.
+ # Remember to update this when/if things change.
+ scriptPath = sys.path[0]
+ sys.path.append(os.path.join(scriptPath, os.pardir, os.pardir, 'test', 'pexpect-2.4'))
+
+ parser = OptionParser(usage="""\
+Run lldb to disassemble all the available functions for an executable image.
+
+Usage: %prog [options]
+""")
+ parser.add_option('-C', '--lldb-command',
+ type='string', action='append', metavar='COMMAND',
+ default=[], dest='lldb_commands',
+ help='Command(s) lldb executes after starting up (can be empty)')
+ parser.add_option('-e', '--executable',
+ type='string', action='store',
+ dest='executable',
+ help="""Mandatory: the executable to do disassembly on.""")
+ parser.add_option('-o', '--options',
+ type='string', action='store',
+ dest='disassemble_options',
+ help="""Mandatory: the options passed to lldb's 'disassemble' command.""")
+ parser.add_option('-q', '--quiet-disassembly',
+ action='store_true', default=False,
+ dest='quiet_disassembly',
+ help="""The symbol(s) to invoke lldb's 'disassemble' command on, if specified.""")
+ parser.add_option('-n', '--num-symbols',
+ type='int', action='store', default=-1,
+ dest='num_symbols',
+ help="""The number of symbols to disassemble, if specified.""")
+ parser.add_option('-p', '--symbol_pattern',
+ type='string', action='store',
+ dest='re_symbol_pattern',
+ help="""The regular expression of symbols to invoke lldb's 'disassemble' command.""")
+ parser.add_option('-s', '--symbol',
+ type='string', action='append', metavar='SYMBOL', default=[],
+ dest='symbols_to_disassemble',
+ help="""The symbol(s) to invoke lldb's 'disassemble' command on, if specified.""")
+
+ opts, args = parser.parse_args()
+
+ lldb_commands = opts.lldb_commands
+
+ if not opts.executable or not opts.disassemble_options:
+ parser.print_help()
+ sys.exit(1)
+
+ executable = opts.executable
+ disassemble_options = opts.disassemble_options
+ quiet_disassembly = opts.quiet_disassembly
+ num_symbols = opts.num_symbols
+ symbols_to_disassemble = opts.symbols_to_disassemble
+ re_symbol_pattern = opts.re_symbol_pattern
+
+ # We have parsed the options.
+ if not quiet_disassembly:
+ print "lldb commands:", lldb_commands
+ print "executable:", executable
+ print "disassemble options:", disassemble_options
+ print "quiet disassembly output:", quiet_disassembly
+ print "num of symbols to disassemble:", num_symbols
+ print "symbols to disassemble:", symbols_to_disassemble
+ print "regular expression of symbols to disassemble:", re_symbol_pattern
+
+ setupSysPath()
+ do_lldb_disassembly(lldb_commands, executable, disassemble_options,
+ num_symbols,
+ symbols_to_disassemble,
+ re_symbol_pattern,
+ quiet_disassembly)
+
+if __name__ == '__main__':
+ main()
diff --git a/utils/test/llvm-mc-shell.py b/utils/test/llvm-mc-shell.py
new file mode 100755
index 000000000000..38c12992b914
--- /dev/null
+++ b/utils/test/llvm-mc-shell.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+
+"""
+Run llvm-mc interactively.
+
+"""
+
+import os
+import sys
+from optparse import OptionParser
+
+def is_exe(fpath):
+ """Check whether fpath is an executable."""
+ return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+
+def which(program):
+ """Find the full path to a program, or return None."""
+ fpath, fname = os.path.split(program)
+ if fpath:
+ if is_exe(program):
+ return program
+ else:
+ for path in os.environ["PATH"].split(os.pathsep):
+ exe_file = os.path.join(path, program)
+ if is_exe(exe_file):
+ return exe_file
+ return None
+
+def llvm_mc_loop(mc, mc_options):
+ contents = []
+ fname = 'mc-input.txt'
+ sys.stdout.write("Enter your input to llvm-mc. A line starting with 'END' terminates the current batch of input.\n")
+ sys.stdout.write("Enter 'quit' or Ctrl-D to quit the program.\n")
+ while True:
+ sys.stdout.write("> ")
+ next = sys.stdin.readline()
+ # EOF => terminate this llvm-mc shell
+ if not next or next.startswith('quit'):
+ sys.stdout.write('\n')
+ sys.exit(0)
+ # 'END' => send the current batch of input to llvm-mc
+ if next.startswith('END'):
+ # Write contents to our file and clear the contents.
+ with open(fname, 'w') as f:
+ f.writelines(contents)
+ # Clear the list: replace all items with an empty list.
+ contents[:] = []
+
+ # Invoke llvm-mc with our newly created file.
+ mc_cmd = '%s %s %s' % (mc, mc_options, fname)
+ sys.stdout.write("Executing command: %s\n" % mc_cmd)
+ os.system(mc_cmd)
+ else:
+ # Keep accumulating our input.
+ contents.append(next)
+
+def main():
+ # This is to set up the Python path to include the pexpect-2.4 dir.
+ # Remember to update this when/if things change.
+ scriptPath = sys.path[0]
+ sys.path.append(os.path.join(scriptPath, os.pardir, os.pardir, 'test', 'pexpect-2.4'))
+
+ parser = OptionParser(usage="""\
+Do llvm-mc interactively within a shell-like environment. A batch of input is
+submitted to llvm-mc to execute whenever you terminate the current batch by
+inputing a line which starts with 'END'. Quit the program by either 'quit' or
+Ctrl-D.
+
+Usage: %prog [options]
+""")
+ parser.add_option('-m', '--llvm-mc',
+ type='string', action='store',
+ dest='llvm_mc',
+ help="""The llvm-mc executable full path, if specified.
+ Otherwise, it must be present in your PATH environment.""")
+
+ parser.add_option('-o', '--options',
+ type='string', action='store',
+ dest='llvm_mc_options',
+ help="""The options passed to 'llvm-mc' command if specified.""")
+
+ opts, args = parser.parse_args()
+
+ llvm_mc = opts.llvm_mc if opts.llvm_mc else which('llvm-mc')
+ if not llvm_mc:
+ parser.print_help()
+ sys.exit(1)
+
+ # This is optional. For example:
+ # --options='-disassemble -triple=arm-apple-darwin -debug-only=arm-disassembler'
+ llvm_mc_options = opts.llvm_mc_options
+
+ # We have parsed the options.
+ print "llvm-mc:", llvm_mc
+ print "llvm-mc options:", llvm_mc_options
+
+ llvm_mc_loop(llvm_mc, llvm_mc_options)
+
+if __name__ == '__main__':
+ main()
diff --git a/utils/test/main.c b/utils/test/main.c
new file mode 100644
index 000000000000..c0fe2f25a488
--- /dev/null
+++ b/utils/test/main.c
@@ -0,0 +1,14 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+int main(int argc, const char* argv[])
+{
+ int *null_ptr = 0;
+ printf("Hello, fault!\n");
+ u_int32_t val = (arc4random() & 0x0f);
+ printf("val=%u\n", val);
+ if (val == 0x07) // Lucky 7 :-)
+ printf("Now segfault %d\n", *null_ptr);
+ else
+ printf("Better luck next time!\n");
+}
diff --git a/utils/test/ras.py b/utils/test/ras.py
new file mode 100755
index 000000000000..a89cbae8c88d
--- /dev/null
+++ b/utils/test/ras.py
@@ -0,0 +1,176 @@
+#!/usr/bin/env python
+
+"""
+Run the test suite and send the result as an email message.
+
+The code for sending of the directory is copied from
+http://docs.python.org/library/email-examples.html.
+"""
+
+import os
+import sys
+import shutil
+import smtplib
+# For guessing MIME type based on file name extension
+import mimetypes
+
+from optparse import OptionParser
+
+from email import encoders
+from email.message import Message
+from email.mime.audio import MIMEAudio
+from email.mime.base import MIMEBase
+from email.mime.image import MIMEImage
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+
+def runTestsuite(testDir, sessDir, envs = None):
+ """Run the testsuite and return a (summary, output) tuple."""
+ os.chdir(testDir)
+
+ for env in envs:
+ list = env.split('=')
+ var = list[0].strip()
+ val = list[1].strip()
+ print var + "=" + val
+ os.environ[var] = val
+
+ import shlex, subprocess
+
+ command_line = "./dotest.py -w -s %s" % sessDir
+ # Apply correct tokenization for subprocess.Popen().
+ args = shlex.split(command_line)
+
+ # Use subprocess module to spawn a new process.
+ process = subprocess.Popen(args,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ # Wait for subprocess to terminate.
+ stdout, stderr = process.communicate()
+
+ # This will be used as the subject line of our email about this test.
+ cmd = "%s %s" % (' '.join(envs) if envs else "", command_line)
+
+ return (cmd, stderr)
+
+
+COMMASPACE = ', '
+
+def main():
+ parser = OptionParser(usage="""\
+Run lldb test suite and send the results as a MIME message.
+
+Usage: %prog [options]
+
+Unless the -o option is given, the email is sent by forwarding to the specified
+SMTP server, which then does the normal delivery process.
+""")
+ parser.add_option('-d', '--directory',
+ type='string', action='store',
+ dest='testDir',
+ help="""The LLDB test directory directly under the top dir.
+ Otherwise use the current directory.""")
+ #
+ # This is similar to TestBase.getRunSpec(self) from lldbtest.py.
+ #
+ parser.add_option('-e', '--environment',
+ type='string', action='append', metavar='ENVIRONMENT',
+ default=[], dest='environments',
+ help="""The environment setting as prefix to the test driver.
+ Example: -e 'CC=clang' -e 'ARCH=x86_64'""")
+ parser.add_option('-m', '--mailserver',
+ type='string', action='store', metavar='MAILSERVER',
+ dest='mailserver',
+ help="""The outgoing SMTP server.""")
+ parser.add_option('-o', '--output',
+ type='string', action='store', metavar='FILE',
+ help="""Print the composed message to FILE instead of
+ sending the message to the SMTP server.""")
+ parser.add_option('-s', '--sender',
+ type='string', action='store', metavar='SENDER',
+ help='The value of the From: header (required)')
+ parser.add_option('-r', '--recipient',
+ type='string', action='append', metavar='RECIPIENT',
+ default=[], dest='recipients',
+ help='A To: header value (at least one required)')
+ opts, args = parser.parse_args()
+ if not opts.sender or not opts.recipients:
+ parser.print_help()
+ sys.exit(1)
+ testDir = opts.testDir
+ if not testDir:
+ testDir = '.'
+
+ sessDir = 'tmp-lldb-session'
+ if os.path.exists(sessDir):
+ shutil.rmtree(sessDir)
+ #print "environments:", opts.environments
+ summary, output = runTestsuite(testDir, sessDir, opts.environments)
+
+ # Create the enclosing (outer) message
+ outer = MIMEMultipart()
+ outer['Subject'] = summary
+ outer['To'] = COMMASPACE.join(opts.recipients)
+ outer['From'] = opts.sender
+ outer.preamble = 'You will not see this in a MIME-aware mail reader.\n'
+
+ # The sessDir contains all the session logs for failed/errored tests.
+ # Attach them all if it exists!
+
+ if not os.path.exists(sessDir):
+ outer.attach(MIMEText(output, 'plain'))
+ else:
+ outer.attach(MIMEText("%s\n%s\n\n" % (output,
+ "Session logs of test failures/errors:"),
+ 'plain'))
+
+ for filename in (os.listdir(sessDir) if os.path.exists(sessDir) else []):
+ path = os.path.join(sessDir, filename)
+ if not os.path.isfile(path):
+ continue
+ # Guess the content type based on the file's extension. Encoding
+ # will be ignored, although we should check for simple things like
+ # gzip'd or compressed files.
+ ctype, encoding = mimetypes.guess_type(path)
+ if ctype is None or encoding is not None:
+ # No guess could be made, or the file is encoded (compressed), so
+ # use a generic bag-of-bits type.
+ ctype = 'application/octet-stream'
+ maintype, subtype = ctype.split('/', 1)
+ if maintype == 'text':
+ fp = open(path)
+ # Note: we should handle calculating the charset
+ msg = MIMEText(fp.read(), _subtype=subtype)
+ fp.close()
+ elif maintype == 'image':
+ fp = open(path, 'rb')
+ msg = MIMEImage(fp.read(), _subtype=subtype)
+ fp.close()
+ elif maintype == 'audio':
+ fp = open(path, 'rb')
+ msg = MIMEAudio(fp.read(), _subtype=subtype)
+ fp.close()
+ else:
+ fp = open(path, 'rb')
+ msg = MIMEBase(maintype, subtype)
+ msg.set_payload(fp.read())
+ fp.close()
+ # Encode the payload using Base64
+ encoders.encode_base64(msg)
+ # Set the filename parameter
+ msg.add_header('Content-Disposition', 'attachment', filename=filename)
+ outer.attach(msg)
+
+ # Now send or store the message
+ composed = outer.as_string()
+ if opts.output:
+ fp = open(opts.output, 'w')
+ fp.write(composed)
+ fp.close()
+ else:
+ s = smtplib.SMTP(opts.mailserver)
+ s.sendmail(opts.sender, opts.recipients, composed)
+ s.quit()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/utils/test/run-dis.py b/utils/test/run-dis.py
new file mode 100755
index 000000000000..a2437948e47d
--- /dev/null
+++ b/utils/test/run-dis.py
@@ -0,0 +1,125 @@
+#!/usr/bin/env python
+
+"""
+Run lldb disassembler on all the binaries specified by a combination of root dir
+and path pattern.
+"""
+
+import os, sys, subprocess
+import re
+from optparse import OptionParser
+
+# The directory of this Python script as well as the lldb-disasm.py workhorse.
+scriptPath = None
+
+# The root directory for the SDK symbols.
+root_dir = None
+
+# The regular expression pattern to match the desired pathname to the binaries.
+path_pattern = None
+
+# And the re-compiled regular expression object.
+path_regexp = None
+
+# If specified, number of symbols to disassemble for each qualified binary.
+num_symbols = -1
+
+# Command template of the invocation of lldb disassembler.
+template = '%s/lldb-disasm.py -C "platform select remote-ios" -o "-n" -q -e %s -n %s'
+
+# Regular expression for detecting file output for Mach-o binary.
+mach_o = re.compile('\sMach-O.+binary')
+def isbinary(path):
+ file_output = subprocess.Popen(["file", path],
+ stdout=subprocess.PIPE).stdout.read()
+ return (mach_o.search(file_output) is not None)
+
+def walk_and_invoke(sdk_root, path_regexp, suffix, num_symbols):
+ """Look for matched file and invoke lldb disassembly on it."""
+ global scriptPath
+
+ for root, dirs, files in os.walk(sdk_root, topdown=False):
+ for name in files:
+ path = os.path.join(root, name)
+
+ # We're not interested in .h file.
+ if name.endswith(".h"):
+ continue
+ # Neither a symbolically linked file.
+ if os.path.islink(path):
+ continue
+
+ # We'll be pattern matching based on the path relative to the SDK root.
+ replaced_path = path.replace(root_dir, "", 1)
+ # Check regular expression match for the replaced path.
+ if not path_regexp.search(replaced_path):
+ continue
+ # If a suffix is specified, check it, too.
+ if suffix and not name.endswith(suffix):
+ continue
+ if not isbinary(path):
+ continue
+
+ command = template % (scriptPath, path, num_symbols if num_symbols > 0 else 1000)
+ print "Running %s" % (command)
+ os.system(command)
+
+def main():
+ """Read the root dir and the path spec, invoke lldb-disasm.py on the file."""
+ global scriptPath
+ global root_dir
+ global path_pattern
+ global path_regexp
+ global num_symbols
+
+ scriptPath = sys.path[0]
+
+ parser = OptionParser(usage="""\
+Run lldb disassembler on all the binaries specified by a combination of root dir
+and path pattern.
+""")
+ parser.add_option('-r', '--root-dir',
+ type='string', action='store',
+ dest='root_dir',
+ help='Mandatory: the root directory for the SDK symbols.')
+ parser.add_option('-p', '--path-pattern',
+ type='string', action='store',
+ dest='path_pattern',
+ help='Mandatory: regular expression pattern for the desired binaries.')
+ parser.add_option('-s', '--suffix',
+ type='string', action='store', default=None,
+ dest='suffix',
+ help='Specify the suffix of the binaries to look for.')
+ parser.add_option('-n', '--num-symbols',
+ type='int', action='store', default=-1,
+ dest='num_symbols',
+ help="""The number of symbols to disassemble, if specified.""")
+
+
+ opts, args = parser.parse_args()
+ if not opts.root_dir or not opts.path_pattern:
+ parser.print_help()
+ sys.exit(1)
+
+ # Sanity check the root directory.
+ root_dir = opts.root_dir
+ root_dir = os.path.abspath(root_dir)
+ if not os.path.isdir(root_dir):
+ parser.print_help()
+ sys.exit(1)
+
+ path_pattern = opts.path_pattern
+ path_regexp = re.compile(path_pattern)
+ suffix = opts.suffix
+ num_symbols = opts.num_symbols
+
+ print "Root directory for SDK symbols:", root_dir
+ print "Regular expression for the binaries:", path_pattern
+ print "Suffix of the binaries to look for:", suffix
+ print "num of symbols to disassemble:", num_symbols
+
+ walk_and_invoke(root_dir, path_regexp, suffix, num_symbols)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/utils/test/run-until-faulted.py b/utils/test/run-until-faulted.py
new file mode 100755
index 000000000000..d895f565a79e
--- /dev/null
+++ b/utils/test/run-until-faulted.py
@@ -0,0 +1,111 @@
+#!/usr/bin/env python
+
+"""
+Run a program via lldb until it fails.
+The lldb executable is located via your PATH env variable, if not specified.
+"""
+
+import os
+import sys
+from optparse import OptionParser
+
+def is_exe(fpath):
+ """Check whether fpath is an executable."""
+ return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
+
+def which(program):
+ """Find the full path to a program, or return None."""
+ fpath, fname = os.path.split(program)
+ if fpath:
+ if is_exe(program):
+ return program
+ else:
+ for path in os.environ["PATH"].split(os.pathsep):
+ exe_file = os.path.join(path, program)
+ if is_exe(exe_file):
+ return exe_file
+ return None
+
+def do_lldb_launch_loop(lldb_command, exe, exe_options):
+ from cStringIO import StringIO
+ import pexpect, time
+
+ prompt = "\(lldb\) "
+ lldb = pexpect.spawn(lldb_command)
+ # Turn on logging for what lldb sends back.
+ lldb.logfile_read = sys.stdout
+ lldb.expect(prompt)
+
+ # Now issue the file command.
+ #print "sending 'file %s' command..." % exe
+ lldb.sendline('file %s' % exe)
+ lldb.expect(prompt)
+
+ # Loop until it faults....
+ count = 0
+ #while True:
+ # count = count + 1
+ for i in range(100):
+ count = i
+ #print "sending 'process launch -- %s' command... (iteration: %d)" % (exe_options, count)
+ lldb.sendline('process launch -- %s' % exe_options)
+ index = lldb.expect(['Process .* exited with status',
+ 'Process .* stopped',
+ pexpect.TIMEOUT])
+ if index == 0:
+ # We'll try again later.
+ time.sleep(3)
+ elif index == 1:
+ # Perfect, our process had stopped; break out of the loop.
+ break;
+ elif index == 2:
+ # Something went wrong.
+ print "TIMEOUT occurred:", str(lldb)
+
+ # Give control of lldb shell to the user.
+ lldb.interact()
+
+def main():
+ # This is to set up the Python path to include the pexpect-2.4 dir.
+ # Remember to update this when/if things change.
+ scriptPath = sys.path[0]
+ sys.path.append(os.path.join(scriptPath, os.pardir, os.pardir, 'test', 'pexpect-2.4'))
+
+ parser = OptionParser(usage="""\
+%prog [options]
+Run a program via lldb until it fails.
+The lldb executable is located via your PATH env variable, if not specified.\
+""")
+ parser.add_option('-l', '--lldb-command',
+ type='string', action='store', metavar='LLDB_COMMAND',
+ default='lldb', dest='lldb_command',
+ help='Full path to your lldb command')
+ parser.add_option('-e', '--executable',
+ type='string', action='store',
+ dest='exe',
+ help="""(Mandatory) The executable to launch via lldb.""")
+ parser.add_option('-o', '--options',
+ type='string', action='store',
+ default = '', dest='exe_options',
+ help="""The args/options passed to the launched program, if specified.""")
+
+ opts, args = parser.parse_args()
+
+ lldb_command = which(opts.lldb_command)
+
+ if not opts.exe:
+ parser.print_help()
+ sys.exit(1)
+ exe = opts.exe
+
+ exe_options = opts.exe_options
+
+ # We have parsed the options.
+ print "lldb command:", lldb_command
+ print "executable:", exe
+ print "executable options:", exe_options
+
+ do_lldb_launch_loop(lldb_command, exe, exe_options)
+
+if __name__ == '__main__':
+ main()