[AIX] dbxで関数呼び出しの引数を確認する方法

-g無しでコンパイルされている前提です。
-g付きの場合は、printサブコマンドなどで表示してください。
### 事前準備
引数を確認したいサブルーチンの定義を確認します。
```
例)
# man 3 read
ssize_t read (FileDescriptor, Buffer, NBytes)
int FileDescriptor;
void * Buffer;
size_t NBytes;
```
### 引数の確認方法
#### アクティブデバッグの場合：

```# dbx /usr/bin/more
(dbx) stop in read
[1] stop in read

(dbx) run textfile

[1] stopped in read at 0xd01264e0
0xd01264e0 (read)    7c0802a6           mflr   r0
```
AIXの場合、第1引数はr3、第2引数はr4・・・となるため、レジスターを表示します。
```
(dbx) x
  $r0:0xd01264e0  $stkp:0x2ff21500   $toc:0xf0809480    $r3:0x00000003
  $r4:0x2ff21590    $r5:0x00001000    $r6:0x0000f032    $r7:0x00003bf8
```
ここで、r3、r5については整数型のため、そのまま確認できます。
r4については、ポインタ型のため、アドレスのみ分かります。

read()なので、読み込んだ値を見るためにはreturnで処理を進める必要があります。
```
(dbx) return
stopped in . at 0x1000439c
0x1000439c (???) 80410014            lwz   r2,0x14(r1)

(dbx) 0x2ff21590/X
0x2ff21590:  23204028
```
23204028と文字列と思われるデータが格納されているため、/sや/Ncなどで文字としてデータを確認することもできます。

#### coreファイルの場合:
```
# more textfile
終了(coredump) <= Ctrl+\でQUITを送りcore出力

# dbx /usr/bin/more core

(dbx) t
purgeandsig(??) at 0x10004bb0
read(??, ??, ??) at 0xd01266ac
iread(??, ??, ??) at 0x10004398
getchr() at 0x10003dcc

(dbx) set $stack_details
```
まずは$stack_detailsをOnにし、各関数のレジスターを表示します。
```
(dbx) t
---------
  $r0:0xffffffff  $stkp:0x2ff22100   $toc:0xffffffff    $r3:0x00000000
  $r4:0xffffffff    $r5:0xffffffff    $r6:0xffffffff    $r7:0xffffffff
  $r8:0xffffffff    $r9:0xffffffff   $r10:0xffffffff   $r11:0xffffffff
 $r12:0xffffffff   $r13:0x50349800   $r14:0x2ff22180   $r15:0x00000002
 $r16:0x00000002   $r17:0x00000018   $r18:0x00000003   $r19:0x30007930
 $r20:0xdeadbeef   $r21:0x00000003   $r22:0xc0152c00   $r23:0x2ff47600
 $r24:0x00000000   $r25:0xd0098e00   $r26:0x03a10000   $r27:0x00000000
 $r28:0x15f29cc0   $r29:0x00000000   $r30:0x00000000   $r31:0x00000003
 $iar:0x10004bb0   $msr:0x0000d032    $cr:0x00243000  $link:0xd01266ac
 $ctr:0x00139f00   $xer:0xffffffff
          Condition status = 2:e 3:g 4:eo
        [ unset $noflregs で浮動小数点レジスターを表示します ]
        [unset $novregs で vector register を表示します]
        [unset $novsregs でベクトル・スカラー・レジスターを表示します]

0 purgeandsig(??) at 0x10004bb0
---------
  $r0:0xffffffff  $stkp:0x2ff22510   $toc:0xffffffff    $r3:0xffffffff
  $r4:0xffffffff    $r5:0xffffffff    $r6:0xffffffff    $r7:0xffffffff
  $r8:0xffffffff    $r9:0xffffffff   $r10:0xffffffff   $r11:0xffffffff
 $r12:0xffffffff   $r13:0xdeadbeef   $r14:0x00000002   $r15:0x2ff22c00
 $r16:0x2ff22c0c   $r17:0xdeadbeef   $r18:0xdeadbeef   $r19:0x30007930
 $r20:0xdeadbeef   $r21:0x30007954   $r22:0x30007960   $r23:0x30001890
 $r24:0x30008160   $r25:0x30003fec   $r26:0x30001930   $r27:0x30007930
 $r28:0x30004000   $r29:0x2ff22680   $r30:0x00000001   $r31:0x00000002
 $iar:0xd01266ac   $msr:0x0000d032    $cr:0x00242000  $link:0x1000439c
 $ctr:0x00139f00   $xer:0xffffffff
          Condition status = 2:e 3:g 4:e
        [ unset $noflregs で浮動小数点レジスターを表示します ]
        [unset $novregs で vector register を表示します]
        [unset $novsregs でベクトル・スカラー・レジスターを表示します]

1 read(??, ??, ??) at 0xd01266ac
---------
$stkp:0x2ff225f0   $r14:0x00000002   $r15:0x2ff22c00   $r16:0x2ff22c0c
 $r17:0xdeadbeef   $r18:0xdeadbeef   $r19:0x30007930   $r20:0xdeadbeef
 $r21:0x30007954   $r22:0x30007960   $r23:0x30001890   $r24:0x30008160
 $r25:0x30003fec   $r26:0x30001930   $r27:0x30007930   $r28:0x30004000
 $r29:0x300012fc   $r30:0x30003ae4   $r31:0x30003fe8
 $iar:0x10004398  $link:0x10003dd0
        [ unset $noflregs で浮動小数点レジスターを表示します ]
        [unset $novregs で vector register を表示します]
        [unset $novsregs でベクトル・スカラー・レジスターを表示します]

2 iread(??, ??, ??) at 0x10004398
```
サブルーチンのプロローグで引数が保存される場合があるため、まずは確認したいサブルーチン(今回はread())のインストラクションを確認します。
```
(dbx) &read/10i
0xd01264e0 (read)      7c0802a6           mflr   r0
0xd01264e4 (read+0x4)  93e1fffc            stw   r31,-4(r1)
0xd01264e8 (read+0x8)  607f0000            ori   r31,r3,0x0
0xd01264ec (read+0xc)  93c1fff8            stw   r30,-8(r1)
0xd01264f0 (read+0x10) 60be0000            ori   r30,r5,0x0
0xd01264f4 (read+0x14) 93a1fff4            stw   r29,-12(r1)
0xd01264f8 (read+0x18) 3c608000            lis   r3,0x8000
0xd01264fc (read+0x1c) 9381fff0            stw   r28,-16(r1)
0xd0126500 (read+0x20) 9361ffec            stw   r27,-20(r1)
0xd0126504 (read+0x24) 9341ffe8            stw   r26,-24(r1)
```
r3がr31に保存されているため、r31を見るとFileDescriptorが2であることが確認できます。
$r31:0x00000002

r4、r5については分からないため、呼び出し元関数(今回はiread())のブランチ直前のインストラクションを確認します。
```
(dbx) 0x10004398-0x10/6i
0x10004388 (???) 80610068            lwz   r3,0x68(r1)
0x1000438c (???) 8081006c            lwz   r4,0x6c(r1)
0x10004390 (???) 901f0000            stw   r0,0x0(r31)
0x10004394 (???) 80a10070            lwz   r5,0x70(r1)
0x10004398 (???) 480006bd             bl   0x10004a54 (???)
0x1000439c (???) 80410014            lwz   r2,0x14(r1)
```
スタックポインタからのオフセットを使用してr3からr5を設定していることが確認できるため、iread()の$stkpから計算します。(auto変数の場合は、このパターンで確認できることが多いです。)
```
(dbx) 0x2ff225f0+0x68/X
0x2ff22658:  00000002
(dbx) 0x2ff225f0+0x6c/X
0x2ff2265c:  2ff22680
(dbx) 0x2ff225f0+0x70/X
0x2ff22660:  00000001
```
上記からFileDescriptor:2に対して0x2ff22680のバッファーを使用して1バイトの読み込みを行っていたことが分かります。