]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/coregrind/launcher-aix5.c
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / coregrind / launcher-aix5.c
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@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 /*--------------------------------------------------------------------*/