Home | History | Annotate | Download | only in coregrind
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Launching Valgrind on AIX5.                  launcher-aix5.c ---*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2006-2010 OpenWorks LLP
     11       info (at) open-works.co.uk
     12 
     13    This program is free software; you can redistribute it and/or
     14    modify it under the terms of the GNU General Public License as
     15    published by the Free Software Foundation; either version 2 of the
     16    License, or (at your option) any later version.
     17 
     18    This program is distributed in the hope that it will be useful, but
     19    WITHOUT ANY WARRANTY; without even the implied warranty of
     20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     21    General Public License for more details.
     22 
     23    You should have received a copy of the GNU General Public License
     24    along with this program; if not, write to the Free Software
     25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     26    02111-1307, USA.
     27 
     28    The GNU General Public License is contained in the file COPYING.
     29 
     30    Neither the names of the U.S. Department of Energy nor the
     31    University of California nor the names of its contributors may be
     32    used to endorse or promote products derived from this software
     33    without prior written permission.
     34 */
     35 
     36 /* Cut-down version of the normal launcher, except it is completely
     37    different on AIX5.  Does not handle shell scripts, only real
     38    machine code XCOFF executables.
     39 
     40    Note: this is a "normal" program and not part of Valgrind proper,
     41    and so it doesn't have to conform to Valgrind's arcane rules on
     42    no-glibc-usage etc.
     43 */
     44 
     45 #include <stdio.h>
     46 #include <assert.h>
     47 #include <string.h>
     48 #include <stdlib.h>
     49 
     50 #include <sys/types.h>
     51 #include <sys/stat.h>
     52 #include <unistd.h>
     53 #include <sys/ptrace.h>
     54 #include <sys/wait.h>
     55 
     56 /* Get both struct __ld_info32 and struct __ld_info64. */
     57 #define __LDINFO_PTRACE32__ 1
     58 #define __LDINFO_PTRACE64__ 1
     59 #include <sys/ldr.h>
     60 
     61 #include <sys/reg.h>     /* GPR0 .. GPR31 */
     62 #include <sys/procfs.h>  /* prsysent_t */
     63 
     64 #include "pub_core_debuglog.h"
     65 #include "pub_core_vki.h"
     66 #include "pub_core_vkiscnums.h"
     67 #include "pub_core_libcproc.h"  // For VALGRIND_LIB, VALGRIND_LAUNCHER
     68 
     69 /* Get the definition for the AIX5Bootblock structure.  This is what
     70    we will generate and patch into the child's address space. */
     71 #include "launcher-aix5-bootblock.h"
     72 
     73 /* Simple routines for Huffman compression/decompression */
     74 #include "m_initimg/simple_huffman.c"
     75 
     76 
     77 /* -------------------------------------------------------------- */
     78 /* ---                                                        --- */
     79 /* --- A uniform interface to the ptrace facilities we need.  --- */
     80 /* ---                                                        --- */
     81 /* -------------------------------------------------------------- */
     82 
     83 typedef
     84    struct {
     85       pid_t pid;
     86       Bool  is64;
     87    }
     88    Child;
     89 
     90 
     91 /* Read len bytes from target's rsrc to local ldst.  Returns True if
     92    error. */
     93 static
     94 Bool ptrace_READ_BLOCK ( Child* ch, Int len, void* ldst, Addr64 rsrc )
     95 {
     96    Int r;
     97    assert(len >= 0 && len <= 1024);
     98    r = ptrace64( PT_READ_BLOCK, (ULong)ch->pid, rsrc, len, ldst );
     99    if (r == len)
    100       return False; /* success */
    101    return True; /* error */
    102 }
    103 
    104 
    105 /* Write len bytes to target's rdst from local lsrc.  Returns True if
    106    error. */
    107 static
    108 Bool ptrace_WRITE_BLOCK ( Child* child, Int len, Addr64 rdst, void* lsrc )
    109 {
    110    Int r;
    111    assert(len >= 0 && len <= 1024);
    112    r = ptrace64( PT_WRITE_BLOCK, (ULong)child->pid, rdst, len, lsrc );
    113    if (r == len)
    114       return False; /* success */
    115    return True; /* error */
    116 }
    117 
    118 
    119 /* Read a GPR from the target.  Returns True if error. */
    120 static
    121 Bool ptrace_READ_GPR ( Child* child, Int reg, ULong* ldst )
    122 {
    123    ULong w64;
    124    UInt  w32;
    125    errno = 0;
    126    if (child->is64) {
    127       (void)ptrace64( PT_READ_GPR,
    128                       (ULong)child->pid, (ULong)reg, 8, (Int*)(&w64) );
    129       if (errno != 0) return True; /* error */
    130    } else {
    131       w32 = ptrace64( PT_READ_GPR,
    132                       (ULong)child->pid, (ULong)reg, 0, 0 );
    133       if (errno != 0) return True; /* error */
    134       w64 = (ULong)w32;
    135    }
    136    *ldst = w64;
    137    return False; /* success */
    138 }
    139 
    140 
    141 /* Write a GPR to the target.  Returns True if error. */
    142 static
    143 Bool ptrace_WRITE_GPR ( Child* child, Int reg, ULong val )
    144 {
    145    ULong w64;
    146    UInt w32;
    147    errno = 0;
    148    if (child->is64) {
    149       w64 = val;
    150       (void)ptrace64( PT_WRITE_GPR,
    151                       (ULong)child->pid, (ULong)reg, 8, (Int*)&w64 );
    152       if (errno != 0) return True; /* error */
    153    } else {
    154       w32 = (UInt)val;
    155       (void)ptrace64( PT_WRITE_GPR,
    156                       (ULong)child->pid, (ULong)reg, w32, 0 );
    157       if (errno != 0) return True; /* error */
    158    }
    159    return False; /* success */
    160 }
    161 
    162 
    163 /* -------------------------------------------------------------- */
    164 /* ---                                                        --- */
    165 /* --- Helper functions                                       --- */
    166 /* ---                                                        --- */
    167 /* -------------------------------------------------------------- */
    168 
    169 /* Search the path for the client program */
    170 static const char* find_client ( const char* clientname )
    171 {
    172    static char fullname[PATH_MAX];
    173    const char *path = getenv("PATH");
    174    const char *colon;
    175 
    176    while (path)
    177    {
    178       if ((colon = strchr(path, ':')) == NULL)
    179       {
    180          strcpy(fullname, path);
    181          path = NULL;
    182       }
    183       else
    184       {
    185          memcpy(fullname, path, colon - path);
    186          fullname[colon - path] = '\0';
    187          path = colon + 1;
    188       }
    189       strcat(fullname, "/");
    190       strcat(fullname, clientname);
    191 
    192       if (access(fullname, R_OK|X_OK) == 0)
    193          return fullname;
    194     }
    195 
    196     return clientname;
    197 }
    198 
    199 /* Examine the given file.  If it looks like valid XCOFF32 return 32,
    200    if valid XCOFF64 return 64, else return 0. */
    201 static Int examine_client ( const char* clientname )
    202 {
    203    UChar buf[16];
    204    Int n;
    205    FILE* f = fopen( clientname, "r" );
    206    if (f == NULL)
    207       return 0;
    208    n = fread( buf, 1, 16, f );
    209    fclose(f);
    210    if (n != 16)
    211       return 0;
    212    if (buf[0] == 0x01 && buf[1] == 0xDF)
    213       return 32; /* XCOFF32 */
    214    if (buf[0] == 0x01 && buf[1] == 0xF7)
    215       return 64; /* XCOFF64 */
    216    return 0;
    217 }
    218 
    219 static Bool file_exists ( char* fname )
    220 {
    221    struct stat buf;
    222    int r = stat(fname, &buf);
    223    return r == 0;
    224 }
    225 
    226 static Addr64 ROUNDDN_PAGE ( Addr64 v )
    227 {
    228    ULong p = (ULong)v;
    229    ULong a = PAGE_SIZE;
    230    p &= ~(a-1);
    231    return (Addr64)p;
    232 }
    233 
    234 static Bool IS_PAGE_ALIGNED ( Addr64 v )
    235 {
    236    ULong p = (ULong)v;
    237    ULong a = PAGE_SIZE;
    238    if (p & (a-1))
    239       return False;
    240    else
    241       return True;
    242 }
    243 
    244 static Bool IS_8_ALIGNED ( Addr64 v )
    245 {
    246    ULong p = (ULong)v;
    247    ULong a = 8;
    248    if (p & (a-1))
    249       return False;
    250    else
    251       return True;
    252 }
    253 
    254 
    255 /* Read a 4096-byte page from CHILD's address space at location SRC,
    256    into local address space at DST.  Returns True if error, False
    257    otherwise.
    258 */
    259 static Bool ptrace_read_page ( Child* child, UChar* ldst, Addr64 rsrc )
    260 {
    261    Int  off;
    262    Bool err;
    263 
    264    assert(IS_PAGE_ALIGNED(rsrc));
    265 
    266    off = 0;
    267    err = ptrace_READ_BLOCK(child, 1024, ldst + off, rsrc + off);
    268    if (err) return err;
    269 
    270    off += 1024;
    271    err = ptrace_READ_BLOCK(child, 1024, ldst + off, rsrc + off);
    272    if (err) return err;
    273 
    274    off += 1024;
    275    err = ptrace_READ_BLOCK(child, 1024, ldst + off, rsrc + off);
    276    if (err) return err;
    277 
    278    off += 1024;
    279    err = ptrace_READ_BLOCK(child, 1024, ldst + off, rsrc + off);
    280    if (err) return err;
    281 
    282    off += 1024;
    283    assert(off == PAGE_SIZE);
    284 
    285    return False;
    286 }
    287 
    288 
    289 /* Write a 4096-byte page from local address space at SRC to CHILD's
    290    address space at location DST.  Returns True if error, False
    291    otherwise.
    292 */
    293 static Bool ptrace_write_page ( Child* child, Addr64 rdst, UChar* lsrc )
    294 {
    295    Int  off;
    296    Bool err;
    297 
    298    assert(IS_PAGE_ALIGNED(rdst));
    299 
    300    off = 0;
    301    err = ptrace_WRITE_BLOCK(child, 1024, rdst + off, lsrc + off);
    302    if (err) return err;
    303 
    304    off += 1024;
    305    err = ptrace_WRITE_BLOCK(child, 1024, rdst + off, lsrc + off);
    306    if (err) return err;
    307 
    308    off += 1024;
    309    err = ptrace_WRITE_BLOCK(child, 1024, rdst + off, lsrc + off);
    310    if (err) return err;
    311 
    312    off += 1024;
    313    err = ptrace_WRITE_BLOCK(child, 1024, rdst + off, lsrc + off);
    314    if (err) return err;
    315 
    316    off += 1024;
    317    assert(off == PAGE_SIZE);
    318 
    319    return False;
    320 }
    321 
    322 
    323 /* Get 37 integer registers (GPR0 .. GPR31, PC, CR, LR, CTR, XER) from
    324    CHILD into the given array.  Returns True if there is any kind of
    325    error. */
    326 static
    327 Bool ptrace_get_iregs_pc_cr_lr_ctr_xer (
    328         Child* child,
    329         /*OUT*/ULong* iregs_pc_cr_lr_ctr_xer
    330      )
    331 {
    332    Int  i, j;
    333    Bool err;
    334 
    335    for (i = GPR0; i <= GPR31; i++) {
    336       j = i - GPR0;
    337       assert(j >= 0 && j < 32);
    338       err = ptrace_READ_GPR( child, i, &iregs_pc_cr_lr_ctr_xer[j] );
    339       if (err) return err;
    340    }
    341 
    342    /* PC */
    343    err = ptrace_READ_GPR( child, IAR, &iregs_pc_cr_lr_ctr_xer[32+0] );
    344    if (err) return err;
    345 
    346    /* CR */
    347    err = ptrace_READ_GPR( child, CR, &iregs_pc_cr_lr_ctr_xer[32+1] );
    348    if (err) return err;
    349 
    350    /* LR */
    351    err = ptrace_READ_GPR( child, LR, &iregs_pc_cr_lr_ctr_xer[32+2] );
    352    if (err) return err;
    353 
    354    /* CTR */
    355    err = ptrace_READ_GPR( child, CTR, &iregs_pc_cr_lr_ctr_xer[32+3] );
    356    if (err) return err;
    357 
    358    /* XER */
    359    err = ptrace_READ_GPR( child, XER, &iregs_pc_cr_lr_ctr_xer[32+4] );
    360    if (err) return err;
    361 
    362    return False;
    363 }
    364 
    365 
    366 /* Set CHILD's program counter to the given value.  Returns True if
    367    there is any kind of error. */
    368 static
    369 Bool ptrace_put_pc ( Child* child, ULong newpc )
    370 {
    371    return ptrace_WRITE_GPR( child, IAR, newpc );
    372 }
    373 
    374 
    375 /* Set CHILD's R31 to the given value.  Returns True if there is any
    376    kind of error. */
    377 static
    378 Bool ptrace_put_r31 ( Child* child, ULong newr31 )
    379 {
    380    return ptrace_WRITE_GPR( child, GPR31, newr31 );
    381 }
    382 
    383 
    384 /* ------ Instruction generators ------ */
    385 
    386 static UInt mkFormD ( UInt opc1, UInt r1, UInt r2, UInt imm )
    387 {
    388    UInt theInstr;
    389    assert(opc1 < 0x40);
    390    assert(r1   < 0x20);
    391    assert(r2   < 0x20);
    392    imm = imm & 0xFFFF;
    393    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) | (imm));
    394    return theInstr;
    395 }
    396 static UInt mkFormX ( UInt opc1,
    397                       UInt r1, UInt r2, UInt r3, UInt opc2, UInt b0 )
    398 {
    399    UInt theInstr;
    400    assert(opc1 < 0x40);
    401    assert(r1   < 0x20);
    402    assert(r2   < 0x20);
    403    assert(r3   < 0x20);
    404    assert(opc2 < 0x400);
    405    assert(b0   < 0x2);
    406    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
    407                (r3<<11) | (opc2<<1) | (b0));
    408    return theInstr;
    409 }
    410 static UInt mkFormXFX ( UInt r1, UInt f2, UInt opc2 )
    411 {
    412    UInt theInstr;
    413    assert(r1   < 0x20);
    414    assert(f2   < 0x20);
    415    assert(opc2 < 0x400);
    416    switch (opc2) {
    417    case 144:  // mtcrf
    418       assert(f2 < 0x100);
    419       f2 = f2 << 1;
    420       break;
    421    case 339:  // mfspr
    422    case 371:  // mftb
    423    case 467:  // mtspr
    424       assert(f2 < 0x400);
    425       // re-arrange split field
    426       f2 = ((f2>>5) & 0x1F) | ((f2 & 0x1F)<<5);
    427       break;
    428    default: assert(0);
    429    }
    430    theInstr = ((31<<26) | (r1<<21) | (f2<<11) | (opc2<<1));
    431    return theInstr;
    432 }
    433 static UInt mkFormMD ( UInt opc1, UInt r1, UInt r2,
    434                        UInt imm1, UInt imm2, UInt opc2 )
    435 {
    436    UInt theInstr;
    437    assert(opc1 < 0x40);
    438    assert(r1   < 0x20);
    439    assert(r2   < 0x20);
    440    assert(imm1 < 0x40);
    441    assert(imm2 < 0x40);
    442    assert(opc2 < 0x08);
    443    imm2 = ((imm2 & 0x1F) << 1) | (imm2 >> 5);
    444    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
    445                ((imm1 & 0x1F)<<11) | (imm2<<5) |
    446                (opc2<<2) | ((imm1 >> 5)<<1));
    447    return theInstr;
    448 }
    449 static UInt mkFormXO ( UInt opc1, UInt r1, UInt r2,
    450                        UInt r3, UInt b10, UInt opc2, UInt b0 )
    451 {
    452    UInt theInstr;
    453    assert(opc1 < 0x40);
    454    assert(r1   < 0x20);
    455    assert(r2   < 0x20);
    456    assert(r3   < 0x20);
    457    assert(b10  < 0x2);
    458    assert(opc2 < 0x200);
    459    assert(b0   < 0x2);
    460    theInstr = ((opc1<<26) | (r1<<21) | (r2<<16) |
    461                (r3<<11) | (b10 << 10) | (opc2<<1) | (b0));
    462    return theInstr;
    463 }
    464 
    465 static UInt gen_lis_r_N ( UInt r, UInt N ) {
    466    return mkFormD(15, r, 0, N & 0xFFFF); /* lis r,r,N */
    467 }
    468 static UInt gen_ori_r_r_N ( UInt r, UInt N ) {
    469    return mkFormD(24, r, r, N & 0xFFFF); /* ori r,r,N */
    470 }
    471 static UInt gen_addi_rd_rs_N ( UInt rd, UInt rs, UInt N ) {
    472    assert(rs != 0);
    473    return mkFormD(14, rd, rs, N & 0xFFFF); /* addi rd,rs,N */
    474 }
    475 static UInt gen_addis_rd_rs_N ( UInt rd, UInt rs, UInt N ) {
    476    assert(rs != 0);
    477    return mkFormD(15, rd, rs, N & 0xFFFF); /* addis rd,rs,N */
    478 }
    479 static UInt gen_crorc_6_6_6 ( void ) {
    480    return 0x4CC63342; /* crorc 6,6,6 */
    481 }
    482 static UInt gen_mr_rd_rs ( UInt rd, UInt rs ) {
    483    return mkFormX(31, rs, rd, rs, 444, 0); /* or rd,rs,ts */
    484 }
    485 static UInt gen_bl_next ( void ) {
    486    return 0x48000005; /* bl .+4 */
    487 }
    488 static UInt gen_mflr_r ( UInt r ) {
    489    return mkFormXFX(r, 8, 339); /* mflr r */
    490 }
    491 static UInt gen_mtlr_r ( UInt r ) {
    492    return mkFormXFX(r, 8, 467); /* mtlr r */
    493 }
    494 static UInt gen_blr ( void ) {
    495    return 0x4E800020; /* blr */
    496 }
    497 __attribute__((unused))
    498 static UInt gen_blrl ( void ) {
    499    return 0x4E800021; /* blrl */
    500 }
    501 static UInt gen_add_r_N ( UInt r, UInt N ) {
    502    return mkFormD(14, r, r, N & 0xFFFF); /* addi r,r,N */
    503 }
    504 static UInt gen_cmpli_cr7_r_N ( UInt r, UInt N ) {
    505    return mkFormD(10, 7<<2, r, N & 0xFFFF); /* cmpli cr7,r,N */
    506 }
    507 static UInt gen_bne_cr7_delta ( UInt delta ) {
    508    return 0x409E0000 | (delta & 0x0000FFFC); /* bne- cr7,delta */
    509 }
    510 __attribute__((unused))
    511 static UInt gen_beq_cr7_delta ( UInt delta ) {
    512    return 0x419E0000 | (delta & 0x0000FFFC); /* beq- cr7,delta */
    513 }
    514 static UInt gen_sc ( void ) {
    515    return 0x44000002; /* sc */
    516 }
    517 static UInt gen_lwz_rd_off_ra ( UInt rd, UInt off, UInt ra ) {
    518    return mkFormD(32, rd, ra, off); /* lwz rd, off(ra) */
    519 }
    520 static UInt gen_add_rd_rL_rR (UInt rd, UInt rsrcL, UInt rsrcR ) {
    521    return mkFormXO(31, rd, rsrcL, rsrcR, 0, 266, 0);
    522 }
    523 static UInt gen_subf_rd_rL_rR (UInt rd, UInt rsrcL, UInt rsrcR ) {
    524    return mkFormXO(31, rd, rsrcL, rsrcR, 0, 40, 0);
    525 }
    526 
    527 static Int emit_insn ( UInt* code, Int ix, UInt insn ) {
    528    code[ix++] = insn;
    529    return ix;
    530 }
    531 static Int emit_li32 ( UInt* code, Int ix, UInt rd, UInt imm32 ) {
    532    code[ix++] = gen_lis_r_N(rd, imm32 >> 16);
    533    if (imm32 & 0xFFFF)
    534       code[ix++] = gen_ori_r_r_N(rd, imm32 & 0xFFFF);
    535    return ix;
    536 }
    537 static Int emit_dosc ( UInt* code, Int ix ) {
    538    /* Generate code to do a syscall and continue at the next insn.
    539       Note: trashes r29. */
    540    code[ix++] = gen_crorc_6_6_6();
    541    code[ix++] = gen_bl_next();
    542    code[ix++] = gen_mflr_r(29);
    543    code[ix++] = gen_add_r_N(29,16);
    544    code[ix++] = gen_mtlr_r(29);
    545    code[ix++] = gen_sc();
    546    return ix;
    547 }
    548 
    549 /* Generate 64-bit insns */
    550 static Int emit_li64 ( UInt* code, Int ix, UInt rd, ULong imm64 ) {
    551    if (imm64 >= 0xFFFFFFFF80000000ULL || imm64 < 0x80000000ULL) {
    552       // sign-extendable from 32 bits
    553       // addis rd,r0,(imm64>>16) => lis rd, (imm64>>16)
    554       code[ix++] = mkFormD(15, rd, 0, (imm64>>16) & 0xFFFF);
    555       // ori rd, rd, (imm64 & 0xFFFF)
    556       code[ix++] = mkFormD(24, rd, rd, imm64 & 0xFFFF);
    557    } else {
    558       // load high word
    559       // lis rd, (imm64>>48) & 0xFFFF
    560       code[ix++] = mkFormD(15, rd, 0, (imm64>>48) & 0xFFFF);
    561       // ori rd, rd, (imm64>>32) & 0xFFFF
    562       code[ix++] = mkFormD(24, rd, rd, (imm64>>32) & 0xFFFF);
    563       // shift rd low word to high word => rldicr
    564       code[ix++] = mkFormMD(30, rd, rd, 32, 31, 1);
    565       // load low word
    566       // oris rd, rd, (imm64>>16) & 0xFFFF
    567       code[ix++] = mkFormD(25, rd, rd, (imm64>>16) & 0xFFFF);
    568       // ori rd, rd, (imm64) & 0xFFFF
    569       code[ix++] = mkFormD(24, rd, rd, imm64 & 0xFFFF);
    570    }
    571    return ix;
    572 }
    573 static UInt gen_ld_rd_off_ra ( UInt rd, UInt off, UInt ra ) {
    574    assert((off & 3) == 0);
    575    return mkFormD(58, rd, ra, off); /* ld rd, off(ra) */
    576 }
    577 
    578 static UInt compute_adler32 ( void* addr, UWord len )
    579 {
    580    UInt   s1 = 1;
    581    UInt   s2 = 0;
    582    UChar* buf = (UChar*)addr;
    583    while (len > 0) {
    584       s1 += buf[0];
    585       s2 += s1;
    586       s1 %= 65521;
    587       s2 %= 65521;
    588       len--;
    589       buf++;
    590    }
    591    return (s2 << 16) + s1;
    592 }
    593 
    594 
    595 /* -------------------------------------------------------------- */
    596 /* ---                                                        --- */
    597 /* --- BEGIN write bootstrap loader into child process        --- */
    598 /* ---                                                        --- */
    599 /* -------------------------------------------------------------- */
    600 
    601 /* From using truss, __loadx is used to load a module into a running
    602    process in 32-bit mode, and kload in 64-bit mode.  __loadx is
    603    simple: it returns a pointer to a standard function descriptor to
    604    the entry point.
    605 
    606    kload isn't: it returns a pointer which, from examination of
    607    /proc/<pid>/maps, doesn't point into the loaded object image.  It
    608    does appear to point to some kind of struct, words [4] and [6] of
    609    which do point into the loaded object image.  From comparison with
    610    /proc/<pid>/maps, they are respectively the actual VMAs of the text
    611    and data sections of the loaded module.
    612 
    613    Knowing this it is possible to find the entry point descriptor:
    614    - figure out where the auxiliary header is.  We have a pointer to
    615      the start of the mapped text section, so just add the size of
    616      the XCOFF file header to that.
    617    - figure out the data bias.  We know the avma of the data section;
    618      and the svma of it is in the auxiliary header in field
    619      o_data_start.  The data bias is therefore the difference between
    620      them.
    621    - The auxiliary header also gives the svma of the entry point
    622      descriptor; (o_entry); therefore its avma is o_entry + the data
    623      bias.
    624 
    625    ULong* kr  = (result of kload)
    626    // r3 is this value
    627 
    628    AOUTHDR* aux = kr[4] (text_avma) + 24 (size of XCOFF file header);
    629    // ld 9,32(3)     kr[4]
    630    // addi 9,9,24    + 24
    631    // 9=aux
    632 
    633    ULong data_avma = kr[6];
    634    // ld 11,48(3)    kr[6]
    635    // 9=aux
    636    // 11=data_avma
    637 
    638    ULong data_svma = aux->o_data_start;
    639    // ld 0,16(9)     aux->o_data_start
    640    // 9=aux
    641    // 11=data_avma
    642    // 0=data_svma
    643 
    644    ULong data_bias = data_avma - data_svma;
    645    // subf 11,0,11
    646    // 9=aux
    647    // 11=data_bias
    648    // 0=data_svma
    649 
    650    ULong ent_svma = (ULong)aux->o_entry;
    651    // ld 9,80(9)   aux->o_entry
    652    // 9=ent_svma
    653    // 11=data_bias
    654    // 0=data_svma
    655 
    656    ULong ent_avma = ent_svma + data_bias;
    657    // add 10,9,11
    658    // 9=ent_svma
    659    // 11=data_bias
    660    // 0=data_svma
    661    // 10=ent_avma
    662 */
    663 
    664 #define LAUNCHER_SYSENT_SIZE 100000
    665 static char sysent_buf[LAUNCHER_SYSENT_SIZE];
    666 
    667 /* The executable loaded must have no more than N_LDINFOs direct
    668    shared-object dependencies.  Just increase this value and rebuild,
    669    if you ever run out.  We have two arrays, one for each kind of
    670    target process. */
    671 #define N_LDINFOs 1000
    672 static  struct __ld_info32  ld_info32_array[N_LDINFOs];
    673 static  struct __ld_info64  ld_info64_array[N_LDINFOs];
    674 
    675 
    676 static
    677 UChar* bootstrap_errmsg
    678          = "\nvalgrind: bootstrap loader failed.  Cannot continue.\n\n";
    679 
    680 
    681 /* Write the bootstrap loader and associated data (iow, an
    682    AIX5Bootblock structure) into CHILD, so that when
    683    ptrace-detached, it will continue by loading TOOLNAME and
    684    continuing with that.  Returns NULL on success or an error string
    685    on failure. */
    686 
    687 static char* write_bootstrap_loader_into_child
    688                 ( Child* child, char* toolfile )
    689 {
    690    /* ------ STEP 1: Fill in most parts of the bootblock. ------ */
    691 
    692    /* All parts except code[], off_zdata and len_zdata. */
    693 
    694    AIX5Bootblock block;
    695 
    696    VG_(debugLog)(1, "launcher", "parent: size of bootblock is %ld\n",
    697                     sizeof(AIX5Bootblock));
    698 
    699    assert(IS_8_ALIGNED( sizeof(AIX5Bootblock) ));
    700 
    701    memset(&block, 0, sizeof(block));
    702 
    703    /* --- OFFSETS--- */
    704 
    705    /* off_zdata not known yet */
    706    /* len_zdata not known yet */
    707 
    708    /* --- SYSCALL NUMBERS --- */
    709 
    710    /* Read some system call entries from the child's
    711       /proc/<pid>/sysent file. */
    712    char        sysent_name[50];
    713    FILE*       sysent_file;
    714    int         sysent_used = 0;
    715    prsysent_t* sysent_hdr;
    716    int         i;
    717 
    718    VG_(debugLog)(1, "launcher",
    719                     "parent: reading child's /proc/../sysent\n");
    720 
    721    sprintf(sysent_name, "/proc/%d/sysent", child->pid);
    722    sysent_file = fopen(sysent_name, "r");
    723    if (sysent_file == NULL)
    724       return "Can't open child's /proc/<pid>/sysent file";
    725 
    726    sysent_used = fread(sysent_buf, 1, LAUNCHER_SYSENT_SIZE, sysent_file);
    727    if (sysent_used == 0)
    728       return "Error reading child's /proc/<pid>/sysent file";
    729    if (sysent_used == LAUNCHER_SYSENT_SIZE)
    730       return "LAUNCHER_SYSENT_SIZE is too low; increase and recompile";
    731    assert(sysent_used > 0 && sysent_used < LAUNCHER_SYSENT_SIZE);
    732 
    733    fclose(sysent_file);
    734 
    735    sysent_hdr = (prsysent_t*)&sysent_buf[0];
    736 
    737    /* Find some syscall numbers for the child. */
    738    Int __nr__getpid = -1;
    739    Int __nr_kwrite  = -1;
    740    Int __nr___loadx = -1; /* 32-bit child only */
    741    Int __nr_kload   = -1; /* 64-bit child only */
    742    Int __nr__exit   = -1;
    743    Int __nr_open    = -1;
    744    Int __nr_kread   = -1;
    745    Int __nr_close   = -1;
    746 
    747    for (i = 0; i < sysent_hdr->pr_nsyscalls; i++) {
    748       char* name = &sysent_buf[ sysent_hdr->pr_syscall[i].pr_nameoff ];
    749       int   nmbr = sysent_hdr->pr_syscall[i].pr_number;
    750       if (0 == strcmp(name, "_getpid"))
    751          __nr__getpid = nmbr;
    752       if (0 == strcmp(name, "kwrite"))
    753           __nr_kwrite = nmbr;
    754       if (0 == strcmp(name, "__loadx"))
    755           __nr___loadx = nmbr;
    756       if (0 == strcmp(name, "kload"))
    757           __nr_kload = nmbr;
    758       if (0 == strcmp(name, "_exit"))
    759           __nr__exit = nmbr;
    760       if (0 == strcmp(name, "open"))
    761           __nr_open = nmbr;
    762       if (0 == strcmp(name, "kread"))
    763           __nr_kread = nmbr;
    764       if (0 == strcmp(name, "close"))
    765           __nr_close = nmbr;
    766    }
    767 
    768    if (__nr__getpid == -1
    769        || __nr_kwrite == -1
    770        || ((!child->is64) && __nr___loadx == -1)
    771        || ((child->is64) && __nr_kload == -1)
    772        || __nr__exit == -1
    773        || __nr_open == -1
    774        || __nr_kread == -1
    775        || __nr_close == -1)
    776       return "can't establish syscall #s needed for bootstrap";
    777 
    778    block.__NR_getpid = __nr__getpid;
    779    block.__NR_write  = __nr_kwrite;
    780    block.__NR_exit   = __nr__exit;
    781    block.__NR_open   = __nr_open;
    782    block.__NR_read   = __nr_kread;
    783    block.__NR_close  = __nr_close;
    784 
    785    /* --- REGS --- */
    786 
    787    /* Continue by copying out the child's current integer register
    788       state. */
    789    VG_(debugLog)(1, "launcher",
    790                     "parent: reading child's int registers\n");
    791 
    792    Bool err = ptrace_get_iregs_pc_cr_lr_ctr_xer
    793                  ( child, &block.iregs_pc_cr_lr_ctr_xer[0] );
    794    if (err)
    795       return "read of child's int registers failed";
    796 
    797    /* --- CODE --- */
    798 
    799    /* We'll leave that till last (is difficult). */
    800 
    801    /* --- ERRMSG --- */
    802 
    803    if (1 + strlen(bootstrap_errmsg) > N_BOOTBLOCK_ERRMSG)
    804       return "bootstrap error message won't fit in bootblock";
    805 
    806    for (i = 0; bootstrap_errmsg[i]; i++)
    807       block.errmsg[i] = bootstrap_errmsg[i];
    808    assert(i <= N_BOOTBLOCK_ERRMSG);
    809 
    810    /* --- TOOLFILE --- */
    811 
    812    if (1 + strlen(toolfile) > N_BOOTBLOCK_TOOLFILE)
    813       return "tool file path is too long, won't fit in bootblock";
    814 
    815    for (i = 0; toolfile[i]; i++)
    816       block.toolfile[i] = toolfile[i];
    817    assert(i <= N_BOOTBLOCK_TOOLFILE);
    818 
    819 
    820    /* ------ STEP 2: Generate the bootblock code. ------ */
    821 
    822    VG_(debugLog)(1, "launcher",
    823                     "parent: creating bootblock code ..\n");
    824 
    825    /* This is the tricky bit.  The resulting code has to be position
    826       independent since we don't yet know where it's going to be
    827       placed.  The code is entered with r31 pointing at the bootblock.
    828       r29-31 are callee-saved, so presumably they don't get trashed
    829       across syscalls.  r30 is used as scratch, and r29 is also used
    830       as scratch by 'emit_dosc'. */
    831 
    832    /* Preliminaries: to do a syscall, we have to do 'crorc 6,6,6' and
    833       put the continuation address in LR, which is a bit of a drag.
    834       Hence the following macro:
    835 
    836          SYSCALL_SEQUENCE = crorc 6,6,6
    837                             bl   .+4
    838                             mflr 29
    839                             addi 29,29,16
    840                             mtlr 29
    841                             sc
    842 
    843       Also: 'imm' is an imaginary instruction to get a 32-bit literal into
    844       a register.  It's really li followed by oris.
    845    */
    846 
    847    /* So, the code.  First, prepare for and do a _loadx syscall, to
    848       get the tool aboard:
    849          addis 1, 1, -4
    850          imm  2, __NR__loadx
    851          imm  3, VKI_DL_LOAD
    852          mr   4, 1
    853          imm  5, 3<<16
    854          addi 6, 31, offset_of_toolfile
    855          mr   7, 4
    856          mr   8, 4
    857          mr   9, 4
    858          mr   10,4
    859          SYSCALL_SEQUENCE
    860          addis 1, 1, 4
    861 
    862       If the syscall failed, r4 will be nonzero.  Branch elsewhere if so.
    863          cmpi 4, 0
    864          bne  error
    865    */
    866    int ix = 0;
    867 
    868 #  if 1
    869 #  define TRAP \
    870       do { \
    871          ix=emit_insn( &block.code[0],ix, 0x7fe00008 ); } \
    872       while (0)
    873 #  define SEGV \
    874       do { \
    875          if (child->is64) { \
    876             ix=emit_li64( &block.code[0],ix, 28,0); \
    877             ix=emit_insn( &block.code[0],ix, \
    878                           gen_ld_rd_off_ra(27,0xfffc,28)); \
    879          } else { \
    880             ix=emit_li32( &block.code[0],ix, 28,0); \
    881             ix=emit_insn( &block.code[0],ix, \
    882                           gen_lwz_rd_off_ra(27,0xffff,28)); \
    883 	 } \
    884       } while (0)
    885 #  define ILL \
    886       do { \
    887          ix=emit_insn( &block.code[0],ix, 0 ); } \
    888       while (0)
    889 #  endif
    890 
    891    if (child->is64) {
    892 
    893       /* 64-bit sequence */
    894       /* Set up for 'sys_kload(toolfile, 0, 0)'
    895          li64  2, __NR_kload
    896          addi  3, 31, offset_toolfile
    897          li64  4, 0
    898          mr    5, 4
    899          mr    6, 4
    900          mr    7, 4
    901          mr    8, 4
    902          mr    9, 4
    903          mr    10,4
    904          SYSCALL_SEQUENCE
    905 
    906          // if kload failed, r3 will hold zero
    907          cmpdi 3,0
    908          beq error
    909 
    910          // from result of kload, figure out entry point address
    911          // as described above
    912          ld   9,32(3)
    913          addi 9,9,24
    914          ld   11,48(3)
    915          ld   0,16(9)
    916          subf 11,0,11
    917          ld   9,80(9)
    918          add  10,9,11  // r10 is entry descriptor avma
    919 
    920          void(*fn)(void*) = (void(*)(void*))ent_avma;
    921          fn();
    922          ld   9,0(10)
    923          mtlr 9
    924          ld   2,8(10)
    925          ld   11,16(10)
    926          mr   3,31  // arg to pass
    927          blr
    928       */
    929       ix = emit_li64( &block.code[0],ix, 2, __nr_kload );
    930       ix = emit_insn( &block.code[0],ix,
    931                       gen_addi_rd_rs_N(3,31,offsetof(AIX5Bootblock,toolfile)));
    932       ix = emit_li64( &block.code[0],ix, 4, 0 );
    933       ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(5,4) );
    934       ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(6,4) );
    935       ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(7,4) );
    936       ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(8,4) );
    937       ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(9,4) );
    938       ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(10,4) );
    939       ix = emit_dosc( &block.code[0],ix );
    940 
    941       ix = emit_insn( &block.code[0],ix, gen_cmpli_cr7_r_N(3,0) );
    942       Int ix_beq = ix; /* Patch this later */
    943       ix = emit_insn( &block.code[0],ix, 0 );
    944 
    945       ix = emit_insn( &block.code[0],ix, gen_ld_rd_off_ra( 9, 32, 3 ) );
    946       ix = emit_insn( &block.code[0],ix, gen_addi_rd_rs_N( 9, 9, 24 ) );
    947       ix = emit_insn( &block.code[0],ix, gen_ld_rd_off_ra( 11, 48, 3 ) );
    948       ix = emit_insn( &block.code[0],ix, gen_ld_rd_off_ra( 0, 16, 9 ) );
    949       ix = emit_insn( &block.code[0],ix, gen_subf_rd_rL_rR( 11, 0, 11 ) );
    950       ix = emit_insn( &block.code[0],ix, gen_ld_rd_off_ra( 9, 80, 9 ) );
    951       ix = emit_insn( &block.code[0],ix, gen_add_rd_rL_rR( 10, 9, 11 ) );
    952 
    953       ix = emit_insn( &block.code[0],ix, gen_ld_rd_off_ra( 9, 0, 10 ) );
    954       ix = emit_insn( &block.code[0],ix, gen_mtlr_r( 9 ) );
    955       ix = emit_insn( &block.code[0],ix, gen_ld_rd_off_ra( 2, 8, 10 ) );
    956       ix = emit_insn( &block.code[0],ix, gen_ld_rd_off_ra( 11, 16, 10 ) );
    957       ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(3, 31) );
    958       ix = emit_insn( &block.code[0],ix, gen_blr() );
    959       TRAP;
    960       assert(ix <= N_BOOTBLOCK_INSNS);
    961 
    962       /* error:
    963          We get here if the kload syscall fails.  Write a terse message
    964          to stderr saying so, then exit, carrying the error code of the
    965          kload call.  The latter is saved in r30 across the write() call.
    966             mr   30,4 (4 contains the error result from kload)
    967             imm  2, __NR_write
    968             imm  3,2 (2=stderr)
    969             addi 4, 31, offset_of_errormsg
    970             imm  5, length(errormsg)
    971             SYSCALL_SEQUENCE
    972             imm  2, __NR_exit
    973             mr   3, 30
    974             SYSCALL_SEQUENCE
    975 
    976          Well, we shouldn't be alive here.  But just in case we do, put
    977          a zero word, which will generate SIGILL and definitely stop the
    978          party.
    979             .word 0
    980       */
    981       /* fill in the conditional jump */
    982       (void)emit_insn( &block.code[0],ix_beq,
    983                                       gen_beq_cr7_delta(4*(ix-ix_beq)));
    984       ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(30,4) );
    985       ix = emit_li64( &block.code[0],ix, 2, __nr_kwrite);
    986       ix = emit_li64( &block.code[0],ix, 3, 2);
    987       ix = emit_insn( &block.code[0],ix,
    988                       gen_addi_rd_rs_N(4,31,offsetof(AIX5Bootblock,errmsg)));
    989       ix = emit_li64( &block.code[0],ix, 5, strlen(bootstrap_errmsg));
    990       ix = emit_dosc( &block.code[0],ix );
    991       ix = emit_li64( &block.code[0],ix, 2, __nr__exit);
    992       ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(3,30) );
    993       ix = emit_dosc( &block.code[0],ix );
    994       ix = emit_insn( &block.code[0],ix, 0 );
    995       assert(ix <= N_BOOTBLOCK_INSNS);
    996 
    997    } else {
    998 
    999       /* 32-bit sequence */
   1000       ix = emit_insn( &block.code[0],ix,
   1001                       gen_addis_rd_rs_N(1,1,-4) );
   1002       ix = emit_li32( &block.code[0],ix, 2, __nr___loadx );
   1003       ix = emit_li32( &block.code[0],ix, 3, VKI_DL_LOAD );
   1004       ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(4,1) );
   1005       ix = emit_li32( &block.code[0],ix, 5, 3<<16 );
   1006       ix = emit_insn( &block.code[0],ix,
   1007                       gen_addi_rd_rs_N(6,31,offsetof(AIX5Bootblock,toolfile)));
   1008       ix = emit_li32( &block.code[0],ix, 7, 0);
   1009       ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(8,7) );
   1010       ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(9,7) );
   1011       ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(10,7) );
   1012       ix = emit_dosc( &block.code[0],ix );
   1013       ix = emit_insn( &block.code[0],ix,
   1014 		      gen_addis_rd_rs_N(1,1,4) );
   1015       ix = emit_insn( &block.code[0],ix, gen_cmpli_cr7_r_N(4,0) );
   1016       Int ix_bne = ix; /* Patch this later */
   1017       ix = emit_insn( &block.code[0],ix, 0 );
   1018       assert(ix <= N_BOOTBLOCK_INSNS);
   1019 
   1020       /* Looks like we're good.  r3 now points at a standard function
   1021          descriptor for the entry point of the module we just loaded.
   1022          Load r2/r11 from the descriptor, then put the address of the
   1023          bootstrap area in r3, and jump to the code address.  Not a
   1024          call -- we don't intend to return here.  Note, must use r30
   1025          as scratch here since r31 is live.
   1026             lwz  30, 0(3)
   1027             mtlr 30
   1028             lwz  2, 4(3)
   1029             lwz  11, 8(3)
   1030             mr   3, 31
   1031             blr
   1032       */
   1033       ix = emit_insn( &block.code[0],ix, gen_lwz_rd_off_ra(30, 0, 3));
   1034       ix = emit_insn( &block.code[0],ix, gen_mtlr_r(30) );
   1035       ix = emit_insn( &block.code[0],ix, gen_lwz_rd_off_ra( 2, 4, 3));
   1036       ix = emit_insn( &block.code[0],ix, gen_lwz_rd_off_ra(11, 8, 3));
   1037       ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(3,31));
   1038       ix = emit_insn( &block.code[0],ix, gen_blr() );
   1039       assert(ix <= N_BOOTBLOCK_INSNS);
   1040 
   1041       /* error:
   1042          We get here if the _loadx syscall fails.  Write a terse message
   1043          to stderr saying so, then exit, carrying the error code of the
   1044          _loadx call.  The latter is saved in r30 across the write() call.
   1045             mr   30,4 (4 contains the error result from __loadx)
   1046             imm  2, __NR_write
   1047             imm  3,2 (2=stderr)
   1048             addi 4, 31, offset_of_errormsg
   1049             imm  5, length(errormsg)
   1050             SYSCALL_SEQUENCE
   1051             imm  2, __NR_exit
   1052             mr   3, 30
   1053             SYSCALL_SEQUENCE
   1054 
   1055          Well, we shouldn't be alive here.  But just in case we do, put
   1056          a zero word, which will generate SIGILL and definitely stop the
   1057          party.
   1058             .word 0
   1059       */
   1060       /* fill in the conditional jump */
   1061       (void)emit_insn( &block.code[0],ix_bne,
   1062                                       gen_bne_cr7_delta(4*(ix-ix_bne)));
   1063       ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(30,4) );
   1064       ix = emit_li32( &block.code[0],ix, 2, __nr_kwrite);
   1065       ix = emit_li32( &block.code[0],ix, 3, 2);
   1066       ix = emit_insn( &block.code[0],ix,
   1067                       gen_addi_rd_rs_N(4,31,offsetof(AIX5Bootblock,errmsg)));
   1068       ix = emit_li32( &block.code[0],ix, 5, strlen(bootstrap_errmsg));
   1069       ix = emit_dosc( &block.code[0],ix );
   1070       ix = emit_li32( &block.code[0],ix, 2, __nr__exit);
   1071       ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(3,30) );
   1072       ix = emit_dosc( &block.code[0],ix );
   1073       ix = emit_insn( &block.code[0],ix, 0 );
   1074       assert(ix <= N_BOOTBLOCK_INSNS);
   1075 
   1076    }
   1077 
   1078    VG_(debugLog)(1, "launcher",
   1079                     "parent: .. %d instructions emitted\n", ix);
   1080 
   1081 #  if 0
   1082    for (i = 0; i < ix; i++) {
   1083       if (0) printf("code[%d] = 0x%08x\n", i, block.code[i]);
   1084       char buff[100];
   1085       sprintf(buff, "echo 0x%x | ./ascii2u32", block.code[i]);
   1086       system(buff);
   1087    }
   1088 #  endif
   1089 
   1090    /* ------ STEP 3: Find out where to place stuff in the child. ------ */
   1091 
   1092    /* We'll have to hijack some space in the data section of the main
   1093       executable.  First off, find the first and last pages of said
   1094       data section.  We can't use the text section, because the child
   1095       is unable to write to its own text section, to undo the
   1096       compression of the hijacked page.  We can't use the stack
   1097       because it appears, although stacks in AIX 5.3 appear to be
   1098       executable, the child gets SIGKILL'd after the ptrace detach if
   1099       its program counter is pointing into its stack.  The data
   1100       section of the main executable appears to be executable, though,
   1101       so use that.
   1102 
   1103       This requires wading though the list of loaded modules in the
   1104       child, to find the main executable. */
   1105 
   1106    long lr;
   1107    if (child->is64) {
   1108       lr = ptrace64(PT_LDINFO, (ULong)child->pid,
   1109                                (ULong)(UWord)&ld_info64_array,
   1110                                sizeof(ld_info64_array), 0/*ignored*/);
   1111    } else {
   1112       lr = ptrace64(PT_LDINFO, (ULong)child->pid,
   1113                                (ULong)(UWord)&ld_info32_array,
   1114                                sizeof(ld_info32_array), 0/*ignored*/);
   1115    }
   1116    VG_(debugLog)(1, "launcher", "parent: ptrace PT_LDINFO got %ld\n", lr);
   1117    if (lr == -1)
   1118       return "ptrace(PT_LDINFO, ...) failed";
   1119    else
   1120       assert(lr == 0);
   1121 
   1122    /* We have to iterate through the entire array to close the object
   1123       files that this has opened.  Duh. */
   1124    if (child->is64) {
   1125       char* p = (char*)&ld_info64_array;
   1126       while (1) {
   1127          struct __ld_info64* info = (struct __ld_info64*)p;
   1128 
   1129          VG_(debugLog)(1,
   1130             "launcher", "parent: text 0x%llx-0x%llx data 0x%llx-0x%llx\n",
   1131             (Addr64)info->ldinfo_textorg,
   1132             (Addr64)info->ldinfo_textorg + (Addr64)info->ldinfo_textsize,
   1133             (Addr64)info->ldinfo_dataorg,
   1134             (Addr64)info->ldinfo_dataorg + (Addr64)info->ldinfo_datasize
   1135          );
   1136 
   1137          Int ir = close(info->_file._ldinfo_fd);
   1138          assert(ir == 0);
   1139          /* The last entry in the array is marked by having a zero
   1140             offset-link field. */
   1141          if (info->ldinfo_next == 0)
   1142             break;
   1143          p += info->ldinfo_next;
   1144       }
   1145    } else {
   1146       char* p = (char*)&ld_info32_array;
   1147       while (1) {
   1148          struct __ld_info32* info = (struct __ld_info32*)p;
   1149 
   1150          VG_(debugLog)(1,
   1151             "launcher", "parent: text 0x%llx-0x%llx data 0x%llx-0x%llx\n",
   1152             (Addr64)(UWord)info->ldinfo_textorg,
   1153             (Addr64)(UWord)info->ldinfo_textorg + info->ldinfo_textsize,
   1154             (Addr64)(UWord)info->ldinfo_dataorg,
   1155             (Addr64)(UWord)info->ldinfo_dataorg + info->ldinfo_datasize
   1156          );
   1157 
   1158          Int ir = close(info->_file._ldinfo_fd);
   1159          assert(ir == 0);
   1160          /* The last entry in the array is marked by having a zero
   1161             offset-link field. */
   1162          if (info->ldinfo_next == 0)
   1163             break;
   1164          p += info->ldinfo_next;
   1165       }
   1166    }
   1167 
   1168    /* The first entry in that array -- and it is guaranteed to to have
   1169       at least one entry -- is that of the the main executable.  We
   1170       need to put our bootblock in one of the pages the main
   1171       executable's data segment.  The abovementioned AIX 'ptrace'
   1172       documentation says:
   1173 
   1174         To allow a debugger to generate code more easily (in order to
   1175         handle fast trap instructions, for example), memory from the
   1176         end of the main program up to the next segment boundary can be
   1177         modified. That memory is read-only to the process but can be
   1178         modified by the debugger.
   1179 
   1180       which would be great if it actually worked reliably; but not so.
   1181       On AIX 5.2 this is true, but on 5.3 it appears to be impossible
   1182       to read or write (via ptrace) anything beyond the last page of
   1183       the executable's text section.
   1184    */
   1185    Addr64 c_cand_text_first, c_cand_text_last;
   1186 
   1187    if (child->is64) {
   1188       c_cand_text_first
   1189          = (Addr64)ld_info64_array[0].ldinfo_dataorg;
   1190       c_cand_text_last
   1191          = c_cand_text_first
   1192            + ld_info64_array[0].ldinfo_datasize - 1;
   1193    } else {
   1194       c_cand_text_first
   1195          = (Addr64)(UWord)ld_info32_array[0].ldinfo_dataorg;
   1196       c_cand_text_last
   1197          = c_cand_text_first
   1198            + ld_info32_array[0].ldinfo_datasize - 1;
   1199    }
   1200 
   1201    VG_(debugLog)(1, "launcher",
   1202                     "parent: candidate first 0x%llx last 0x%llx\n",
   1203                     c_cand_text_first, c_cand_text_last);
   1204 
   1205    /* Page align the text section limits. */
   1206    Addr64 c_first_page = ROUNDDN_PAGE( c_cand_text_first );
   1207    Addr64 c_last_page  = ROUNDDN_PAGE( c_cand_text_last );
   1208 
   1209    /* It's safe to try out any page p satisfying
   1210          c_first_page <= p && p <= c_last_page
   1211    */
   1212 
   1213    /* CHOOSE A PAGE.  Do a test compression of available pages until
   1214       we find one for which compression yields enough free space to
   1215       put the bootblock in. */
   1216    Int    zsize;
   1217    Addr64 c_chosen_page = 0;
   1218    Addr64 c_page;
   1219    UChar  p_page_unzbuf[PAGE_SIZE];
   1220    UChar  p_page_unzbuf2[PAGE_SIZE];
   1221    UChar  p_page_zbuf[PAGE_SIZE + 384 + 8/*paranoia*/];
   1222 
   1223    for (c_page = c_first_page; c_page <= c_last_page; c_page += PAGE_SIZE) {
   1224       assert(IS_PAGE_ALIGNED(c_page));
   1225       err = ptrace_read_page( child, p_page_unzbuf, c_page );
   1226       if (err)
   1227          return "read of page from child failed(1)";
   1228       zsize = Huffman_Compress(p_page_unzbuf, p_page_zbuf, PAGE_SIZE);
   1229       assert(zsize >= 0 && zsize <= PAGE_SIZE + 384);
   1230 
   1231       /* Do a test decompression, to check the compress/decompress
   1232          cycle works properly */
   1233       Huffman_Uncompress( p_page_zbuf, p_page_unzbuf2,
   1234                           PAGE_SIZE + 384, PAGE_SIZE);
   1235       assert(0 == memcmp(p_page_unzbuf, p_page_unzbuf2, PAGE_SIZE));
   1236 
   1237       VG_(debugLog)(1, "launcher",
   1238                        "parent: page 0x%llx has %d usable bytes\n",
   1239                        c_page, PAGE_SIZE - zsize);
   1240 
   1241       if ( (Int)(PAGE_SIZE - zsize)
   1242            >= (Int)sizeof(AIX5Bootblock)+8/*paranoia*/) {
   1243          c_chosen_page = c_page;
   1244          break;
   1245       }
   1246    }
   1247 
   1248    if (c_chosen_page == NULL)
   1249       return "can't find a page with enough free space for bootblock";
   1250 
   1251    /* Compress the chosen page, leaving the compressed data at the
   1252       start of the page, and put the bootblock at the end of the
   1253       page. */
   1254 
   1255    VG_(debugLog)(1, "launcher",
   1256                     "parent: reading page at 0x%llx\n", c_chosen_page);
   1257 
   1258    err = ptrace_read_page( child, p_page_unzbuf, c_chosen_page );
   1259    if (err)
   1260       return "read of page from child failed(2)";
   1261 
   1262    block.adler32 = compute_adler32( p_page_unzbuf, PAGE_SIZE );
   1263    VG_(debugLog)(1, "launcher",
   1264                     "parent: adler32 of unz page is 0x%x\n", block.adler32);
   1265 
   1266    memset(p_page_zbuf, 0, sizeof(p_page_zbuf));
   1267    zsize = Huffman_Compress(p_page_unzbuf, p_page_zbuf, PAGE_SIZE);
   1268    assert(zsize >= 0 && zsize <= PAGE_SIZE + 384);
   1269 
   1270    assert(PAGE_SIZE - zsize >= sizeof(AIX5Bootblock)+8/*paranoia*/);
   1271 
   1272    UChar* p_dst = p_page_zbuf   + PAGE_SIZE - sizeof(AIX5Bootblock);
   1273    Addr64 c_dst = c_chosen_page + PAGE_SIZE - sizeof(AIX5Bootblock);
   1274    assert(IS_8_ALIGNED(c_dst));
   1275 
   1276    VG_(debugLog)(1, "launcher",
   1277                     "parent: free space starts at 0x%llx in child\n",
   1278                     c_chosen_page + zsize);
   1279    VG_(debugLog)(1, "launcher",
   1280                     "parent: bootblock will be at 0x%llx in child\n",
   1281                     c_dst);
   1282 
   1283    *(AIX5Bootblock*)p_dst = block;
   1284 
   1285    VG_(debugLog)(1, "launcher",
   1286                     "parent: writing page at 0x%llx\n", c_chosen_page);
   1287 
   1288    err = ptrace_write_page( child, c_chosen_page, p_page_zbuf );
   1289    if (err)
   1290       return "write of page to child failed";
   1291 
   1292    /* Do a test read back to ensure ptrace didn't screw up. */
   1293 
   1294    err = ptrace_read_page( child, p_page_unzbuf2, c_chosen_page );
   1295    if (err)
   1296       return "test read back of boot page failed (1)";
   1297    if (0 != memcmp(p_page_zbuf, p_page_unzbuf2, PAGE_SIZE))
   1298       return "test read back of boot page failed (2)";
   1299 
   1300    /* Finally .. set the program counter so that when we detach, our
   1301       magic stub is run, not the original program. */
   1302 
   1303    VG_(debugLog)(1, "launcher",
   1304                     "parent: set child's pc to 0x%llx\n",
   1305                     c_dst + offsetof(AIX5Bootblock,code) );
   1306    err = ptrace_put_pc ( child, c_dst + offsetof(AIX5Bootblock,code) );
   1307    if (err)
   1308       return "write of new initial pc into child failed";
   1309 
   1310    VG_(debugLog)(1, "launcher",
   1311                     "parent: set child's r31 to 0x%llx\n", c_dst);
   1312    err = ptrace_put_r31 ( child, c_dst );
   1313    if (err)
   1314       return "write of new r31 into child failed";
   1315 
   1316    return NULL; /* success */
   1317 }
   1318 
   1319 
   1320 /* -------------------------------------------------------------- */
   1321 /* ---                                                        --- */
   1322 /* --- END write bootstrap loader into child process          --- */
   1323 /* ---                                                        --- */
   1324 /* -------------------------------------------------------------- */
   1325 
   1326 static void barf ( int exitcode, char* argv0, char* msg )
   1327 {
   1328    fprintf(stderr, "%s: %s\n", argv0, msg);
   1329    exit(exitcode);
   1330 }
   1331 
   1332 int main ( int argc, char** argv, char** envp )
   1333 {
   1334    Child child;
   1335    Int i, loglevel;
   1336    const char *toolname = NULL;
   1337          char *clientname = NULL;
   1338 
   1339    /* First, look in our own /proc/<pid>/sysent file to find
   1340       the syscall numbers for kwrite and _getpid.  These are needed
   1341       to make the VG_(debugLog) usable.  We'll temporarily use
   1342       the sysent_buf used by write_bootstrap_loader_into_child for this
   1343       purpose. */
   1344 
   1345    char        sysent_name[50];
   1346    FILE*       sysent_file;
   1347    int         sysent_used = 0;
   1348    prsysent_t* sysent_hdr;
   1349 
   1350    child.pid  = 0;
   1351    child.is64 = False;
   1352 
   1353    sprintf(sysent_name, "/proc/%d/sysent", getpid());
   1354    sysent_file = fopen(sysent_name, "r");
   1355    if (sysent_file == NULL)
   1356       barf(1, argv[0], "Can't open my own /proc/<pid>/sysent file");
   1357 
   1358    sysent_used = fread(sysent_buf, 1, LAUNCHER_SYSENT_SIZE, sysent_file);
   1359    if (sysent_used == 0)
   1360       barf(1, argv[0], "Error reading my own /proc/<pid>/sysent file");
   1361    if (sysent_used == LAUNCHER_SYSENT_SIZE)
   1362       barf(1, argv[0], "LAUNCHER_SYSENT_SIZE is too low; increase and recompile");
   1363    assert(sysent_used > 0 && sysent_used < LAUNCHER_SYSENT_SIZE);
   1364 
   1365    fclose(sysent_file);
   1366 
   1367    sysent_hdr = (prsysent_t*)&sysent_buf[0];
   1368 
   1369    /* Find some syscall numbers for the child.  Note, we copy them
   1370       from our own /proc/../sysent file, which isn't really right. */
   1371    Word __nr__getpid = -1;
   1372    Word __nr_kwrite  = -1;
   1373    for (i = 0; i < sysent_hdr->pr_nsyscalls; i++) {
   1374       char* name = &sysent_buf[ sysent_hdr->pr_syscall[i].pr_nameoff ];
   1375       int   nmbr = sysent_hdr->pr_syscall[i].pr_number;
   1376       if (0 == strcmp(name, "_getpid"))
   1377          __nr__getpid = nmbr;
   1378       if (0 == strcmp(name, "kwrite"))
   1379           __nr_kwrite = nmbr;
   1380    }
   1381    if (__nr__getpid == -1 || __nr_kwrite == -1)
   1382       barf(1, argv[0], "can't establish syscall #s needed for startup");
   1383 
   1384    /* "Tell" m_vkiscnums about them */
   1385    __NR_getpid = __nr__getpid;
   1386    __NR_write = __nr_kwrite;
   1387 
   1388    /* Right, now we're safe to start the debug logging system. */
   1389    /* Start the debugging-log system ASAP.  First find out how many
   1390       "-d"s were specified.  This is a pre-scan of the command line.
   1391       At the same time, look for the tool name. */
   1392    loglevel = 0;
   1393    for (i = 1; i < argc; i++) {
   1394       if (argv[i][0] != '-') {
   1395          clientname = argv[i];
   1396          break;
   1397       }
   1398       if (0 == strcmp(argv[i], "--")) {
   1399          if (i+1 < argc)
   1400             clientname = argv[i+1];
   1401          break;
   1402       }
   1403       if (0 == strcmp(argv[i], "-d"))
   1404          loglevel++;
   1405       if (0 == strncmp(argv[i], "--tool=", 7))
   1406          toolname = argv[i] + 7;
   1407    }
   1408 
   1409    /* ... and start the debug logger.  Now we can safely emit logging
   1410       messages all through startup. */
   1411    VG_(debugLog_startup)(loglevel, "Stage 1");
   1412 
   1413    /* Make sure we know which tool we're using */
   1414    if (toolname) {
   1415       VG_(debugLog)(1, "launcher", "tool '%s' requested\n", toolname);
   1416    } else {
   1417       VG_(debugLog)(1, "launcher",
   1418                        "no tool requested, defaulting to 'memcheck'\n");
   1419       toolname = "memcheck";
   1420    }
   1421 
   1422    /* Do some preliminary sanity checks */
   1423    long pagesize = sysconf(_SC_PAGESIZE);
   1424    if (pagesize != 4096)
   1425       barf(1, argv[0], "config error: sysconf(_SC_PAGESIZE) is not 4096");
   1426 
   1427    assert(PAGE_SIZE == 4096); /* stay sane */
   1428 
   1429    const char* valgrind_lib = VG_LIBDIR;
   1430 
   1431    /* If there is no program to run, which will be the case if the
   1432       user just does "valgrind --help", etc, run a dummy do-nothing
   1433       program so at least the tool can get started and handle the
   1434       --help/--version etc.  It spots the fact that this is a dummy
   1435       program and acts like it was started with no program, hence
   1436       behaving the same as the Linux ports would have. */
   1437    if (clientname == NULL) {
   1438       Int j;
   1439       char** new_argv;
   1440       const char* noop_exe_name = "no_op_client_for_valgrind";
   1441       const char* up_n_bindir = "/../../bin";
   1442       clientname = malloc(strlen(valgrind_lib) + strlen(up_n_bindir)
   1443                           + 2 + strlen(noop_exe_name));
   1444       if (clientname == NULL) {
   1445          fprintf(stderr,"%s: malloc of clientname failed\n", argv[0]);
   1446          return 1;
   1447       }
   1448       sprintf(clientname, "%s%s/%s", valgrind_lib, up_n_bindir, noop_exe_name);
   1449       /* now we have to add it to the end of argv, which means making
   1450 	 that one word longer.  How tedious. */
   1451       for (j = 0; argv[j]; j++)
   1452 	;
   1453       j += 2;
   1454       new_argv = calloc(j, sizeof(char*));
   1455       if (new_argv == NULL) {
   1456          fprintf(stderr,"%s: malloc of new_argv failed\n", argv[0]);
   1457          return 1;
   1458       }
   1459       for (i = 0; i < j-2; i++)
   1460 	new_argv[i] = argv[i];
   1461       new_argv[j-2] = clientname;
   1462       assert(new_argv[j-1] == NULL);
   1463       argv = new_argv;
   1464       argc++;
   1465    }
   1466 
   1467    if (argc < 2 || toolname == NULL || clientname == NULL)
   1468       barf(1, argv[0], "usage: valgrind [args-for-valgrind] prog args");
   1469 
   1470    /* Find the client, and figure out if it's a 32- or 64-bit
   1471       executable. */
   1472    VG_(debugLog)(1, "launcher", "searching for client in $PATH\n");
   1473    if (strchr(clientname, '/') == NULL)
   1474       clientname = (char*)find_client(clientname);
   1475    VG_(debugLog)(1, "launcher", "found %s\n", clientname);
   1476 
   1477    Int client_exekind = examine_client ( clientname );
   1478    switch (client_exekind) {
   1479       case 32:
   1480          child.is64 = False;
   1481          break;
   1482       case 64:
   1483          child.is64 = True;
   1484          break;
   1485       default:
   1486          fprintf(stderr, "%s: requested executable %s\n",
   1487                          argv[0], clientname);
   1488          fprintf(stderr, "%s: not found, or is not a valid XCOFF32 "
   1489                          "or XCOFF64 executable.\n", argv[0]);
   1490          return 1;
   1491    }
   1492 
   1493    VG_(debugLog)(1, "launcher", "client is an XCOFF%d executable\n",
   1494                     client_exekind);
   1495 
   1496    const char* platform = child.is64 ? "ppc64-aix5" : "ppc32-aix5";
   1497 
   1498    VG_(debugLog)(1, "launcher", "looking for the tool file\n");
   1499 
   1500    char* toolfile = malloc(strlen(valgrind_lib)
   1501                     + strlen(toolname) + strlen(platform) + 3);
   1502    if (toolfile == NULL) {
   1503       fprintf(stderr,"%s: malloc of toolfile failed\n", argv[0]);
   1504       return 1;
   1505    }
   1506    sprintf(toolfile, "%s/%s-%s", valgrind_lib, toolname, platform);
   1507 
   1508    if (!file_exists(toolfile)) {
   1509       fprintf(stderr,"%s: can't stat %s\n", argv[0], toolfile);
   1510       return 1;
   1511    }
   1512 
   1513    /* Force the client to use a 1:1 threading model - this works
   1514       because the client inherits our environment. */
   1515    VG_(debugLog)(1, "launcher", "doing putenv(\"AIXTHREAD_SCOPE=S\")\n");
   1516    Int putenv_err = putenv("AIXTHREAD_SCOPE=S");
   1517    if (putenv_err) {
   1518       fprintf(stderr,"%s: putenv(\"AIXTHREAD_SCOPE=S\") failed\n", argv[0]);
   1519       return 1;
   1520    }
   1521 
   1522    VG_(debugLog)(1, "launcher", "doing putenv(\"MP_SHARED_MEMORY=no\")\n");
   1523    putenv_err = putenv("MP_SHARED_MEMORY=no");
   1524    if (putenv_err) {
   1525       fprintf(stderr,"%s: putenv(\"MP_SHARED_MEMORY=no\") failed\n", argv[0]);
   1526       return 1;
   1527    }
   1528 
   1529    /* Find out what the current working directory is, and stuff it into the
   1530       environment so that the child can find it. */
   1531    char wd_buf[4096];
   1532    memset(wd_buf, 0, sizeof(wd_buf));
   1533    if (getcwd(wd_buf, sizeof(wd_buf)-1) == NULL) {
   1534       fprintf(stderr,"%s: getcwd(..) failed\n", argv[0]);
   1535       return 1;
   1536    }
   1537    assert(wd_buf[ sizeof(wd_buf)-1 ] == 0);
   1538    char* set_cwd = calloc(1, 100+sizeof(wd_buf));
   1539    if (set_cwd == NULL) {
   1540       fprintf(stderr,"%s: calloc of set_cwd failed\n", argv[0]);
   1541       return 1;
   1542    }
   1543    sprintf(set_cwd, "VALGRIND_STARTUP_PWD_%d_XYZZY=%s", getpid(), wd_buf);
   1544    VG_(debugLog)(1, "launcher", "doing putenv(\"%s\")\n", set_cwd);
   1545    putenv_err = putenv(set_cwd);
   1546    if (putenv_err) {
   1547       fprintf(stderr,"%s: putenv(\"VALGRIND_STARTUP_PWD_...\") failed\n",
   1548                      argv[0]);
   1549       return 1;
   1550    }
   1551 
   1552    /* Also, cook up the fully qualified name of this executable.  The
   1553       following is a kludge, but I don't see how to really get the
   1554       fully qualified name on AIX. */
   1555    char* up_n_down = "/../../bin/valgrind";
   1556    char* launcher = malloc(strlen(valgrind_lib)
   1557                            + strlen(up_n_down) + 2);
   1558    if (launcher == NULL) {
   1559       fprintf(stderr,"%s: malloc of launcher failed\n", argv[0]);
   1560       return 1;
   1561    }
   1562    sprintf(launcher, "%s%s", valgrind_lib, up_n_down);
   1563 
   1564    if (!file_exists(launcher)) {
   1565       fprintf(stderr,"%s: can't stat %s\n", argv[0], launcher);
   1566       return 1;
   1567    }
   1568 
   1569    /* First, fork.
   1570 
   1571       In the child, ask for a ptrace, then exec argv[2 ..].  This
   1572       causes the kernel to complete the exec, hence loading the
   1573       child, but does not start it; instead the child remains frozen
   1574       so that the parent can mess with it via ptrace().
   1575    */
   1576    VG_(debugLog)(1, "launcher", "doing fork()\n");
   1577    child.pid = fork();
   1578    if (child.pid == -1) {
   1579       fprintf(stderr,"%s: fork() failed\n", argv[0]);
   1580       return 1;
   1581    }
   1582 
   1583    if (child.pid == 0) {
   1584       /* --- CHILD --- */
   1585       VG_(debugLog)(1, "launcher", "child: before ptrace\n");
   1586       long rl = ptrace64(PT_TRACE_ME, 0,0,0,0);
   1587       if (rl != 0) {
   1588          fprintf(stderr,"%s: child: ptrace(PT_TRACE_ME, ...) failed\n", argv[0]);
   1589          fprintf(stderr,"%s: ", argv[0]);
   1590          perror(NULL);
   1591          fflush(stderr);
   1592          _exit(1);
   1593       }
   1594       VG_(debugLog)(1, "launcher", "child: before execve\n");
   1595 
   1596       /* make VALGRIND_LAUNCHER point at something plausible. */
   1597       VG_(debugLog)(1, "launcher", "child: launcher = %s\n", launcher);
   1598       int r = setenv("VALGRIND_LAUNCHER", launcher, 1/*overwrite*/);
   1599       if (r) {
   1600          /* setenv failed. */
   1601          fprintf(stderr,"%s: child: setenv failed\n", argv[0]);
   1602          fprintf(stderr,"%s: ", argv[0]);
   1603          perror(NULL);
   1604          fflush(stderr);
   1605          _exit(1);
   1606          /* NOTREACHED */
   1607       }
   1608 
   1609       /* This is kind-of strange.  We're execvp-ing the client but
   1610          argv[0] is the toolname, which is irrelevant - m_main ignores
   1611          it.  However, setting it like this at least makes m_main's
   1612          view of the world (as far as the argv goes) look the same as
   1613          it does in Linux-land:
   1614             tool-exe-name [args for V] client-name [args for client]
   1615       */
   1616       argv[0] = toolfile;
   1617       int ri = execvp(clientname, &argv[0]);
   1618       /* WE ONLY GET HERE IF execve FAILED */
   1619       assert(ri == -1);
   1620       fprintf(stderr,"%s: exec failed: %s: ", argv[0], clientname);
   1621       perror("");
   1622       return 1;
   1623       /* NOTREACHED */
   1624    }
   1625 
   1626    /* --- PARENT --- */
   1627    VG_(debugLog)(1, "launcher", "parent: waitpid-ing for child\n");
   1628    int status;
   1629    /* Wait to hear back from the child. */
   1630    pid_t p2 = waitpid(child.pid, &status, 0);
   1631    /* We could hear back for two reasons.  (1) the exec was
   1632       successful, and because the child is being ptraced, it is now
   1633       waiting for the parent.  (2) the exec failed, and so the child
   1634       did _exit(). */
   1635    VG_(debugLog)(1, "launcher", "parent: waitpid got pid %d\n", (int)p2);
   1636    VG_(debugLog)(1, "launcher", "parent: waitpid got status 0x%x\n", status);
   1637    assert(p2 == child.pid); /* Huh?! We only have one child. */
   1638 
   1639    if (WIFEXITED(status)) {
   1640       /* Case (2) - exec failed. */
   1641       fprintf(stderr, "parent: child's exec failed.\n");
   1642       return 0;
   1643    }
   1644 
   1645    /* else case (1) must apply */
   1646    assert(WIFSTOPPED(status));
   1647 
   1648    /* ------ BEGIN write bootstrap pages into child ------ */
   1649 
   1650    /* In this section, if for any reason we can't continue to the
   1651       child-detach and so have to give up, we have to kill the child,
   1652       else it'll become a zombie.  That's what the code at
   1653       latched_error: does. */
   1654    char* badness
   1655             = write_bootstrap_loader_into_child ( &child, toolfile );
   1656    /* Returns NULL if no error, else points to a string of at least
   1657       some descriptiveness. */
   1658    if (badness)
   1659       goto latched_error;
   1660 
   1661    /* ------ END write bootstrap pages into child ------ */
   1662 
   1663    VG_(debugLog)(1, "launcher", "parent: detaching child\n");
   1664    long lr = ptrace64(PT_DETACH, (ULong)child.pid, 0, SIGCONT, 0);
   1665    VG_(debugLog)(1, "launcher", "parent: detach got %ld\n", lr);
   1666    assert(lr == 0);
   1667    VG_(debugLog)(1, "launcher", "parent: waiting for child to finish\n");
   1668 
   1669    p2 = waitpid(child.pid, &status, 0);
   1670    assert(p2 == child.pid);
   1671    if (0)
   1672       fprintf(stderr,"parent: child finished, status 0x%x 0x%x\n",
   1673                      status, WEXITSTATUS(status));
   1674 
   1675    if (WIFEXITED(status)) {
   1676       VG_(debugLog)(1, "launcher",
   1677                        "parent: child finished normally, exit code %d\n",
   1678                        WEXITSTATUS(status));
   1679       return WEXITSTATUS(status);
   1680    }
   1681    else if (WIFSIGNALED(status)) {
   1682       VG_(debugLog)(1, "launcher",
   1683                        "parent: child exited on signal %d\n",
   1684                        (int)WTERMSIG(status));
   1685       /* Since the child exited with a signal, we'd better
   1686          whack ourselves on the head with the same signal. */
   1687       kill( getpid(), (int)WTERMSIG(status) );
   1688       /* presumably NOTREACHED? */
   1689       return 0; /* This is completely bogus */
   1690    }
   1691    else {
   1692       /* erm.  Can we ever get here? */
   1693       assert(0);
   1694       return 0;
   1695    }
   1696 
   1697   latched_error:
   1698    /* We get here if there was some kind of problem messing with the
   1699       child whilst we still had it latched by ptrace.  In this case we
   1700       need to kill it before exiting, since otherwise it will become a
   1701       zombie. */
   1702    assert(badness);
   1703    fprintf(stderr, "%s: error while doing ptracery on '%s'\n",
   1704                    argv[0], clientname);
   1705    fprintf(stderr, "%s: error is: %s\n",
   1706                    argv[0], badness);
   1707    return 0; /*BOGUS*/
   1708 }
   1709 
   1710 /*--------------------------------------------------------------------*/
   1711 /*--- end                                          launcher-aix5.c ---*/
   1712 /*--------------------------------------------------------------------*/
   1713