blob: 6a1b1998afcb6e589bdb966806bd7cdefc247734 [file] [log] [blame]
sewardje25abab2006-10-17 00:39:31 +00001
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
sewardj9eecbbb2010-05-03 21:37:12 +000010 Copyright (C) 2006-2010 OpenWorks LLP
sewardje25abab2006-10-17 00:39:31 +000011 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.
sewardj38dba992007-04-29 09:06:40 +000029
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.
sewardje25abab2006-10-17 00:39:31 +000034*/
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
83typedef
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. */
93static
94Bool 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. */
107static
108Bool 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. */
120static
121Bool 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. */
142static
143Bool 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 */
170static 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. */
201static 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
219static Bool file_exists ( char* fname )
220{
221 struct stat buf;
222 int r = stat(fname, &buf);
223 return r == 0;
224}
225
226static 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
234static 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
244static 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*/
259static 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*/
293static 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. */
326static
327Bool 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. */
368static
369Bool 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. */
377static
378Bool ptrace_put_r31 ( Child* child, ULong newr31 )
379{
380 return ptrace_WRITE_GPR( child, GPR31, newr31 );
381}
382
383
384/* ------ Instruction generators ------ */
385
386static 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}
396static 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}
410static 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}
433static 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}
449static 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
465static UInt gen_lis_r_N ( UInt r, UInt N ) {
466 return mkFormD(15, r, 0, N & 0xFFFF); /* lis r,r,N */
467}
468static UInt gen_ori_r_r_N ( UInt r, UInt N ) {
469 return mkFormD(24, r, r, N & 0xFFFF); /* ori r,r,N */
470}
471static 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}
sewardj13552642006-11-10 22:47:27 +0000475static 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}
sewardje25abab2006-10-17 00:39:31 +0000479static UInt gen_crorc_6_6_6 ( void ) {
480 return 0x4CC63342; /* crorc 6,6,6 */
481}
482static UInt gen_mr_rd_rs ( UInt rd, UInt rs ) {
483 return mkFormX(31, rs, rd, rs, 444, 0); /* or rd,rs,ts */
484}
485static UInt gen_bl_next ( void ) {
486 return 0x48000005; /* bl .+4 */
487}
488static UInt gen_mflr_r ( UInt r ) {
489 return mkFormXFX(r, 8, 339); /* mflr r */
490}
491static UInt gen_mtlr_r ( UInt r ) {
492 return mkFormXFX(r, 8, 467); /* mtlr r */
493}
494static UInt gen_blr ( void ) {
495 return 0x4E800020; /* blr */
496}
497__attribute__((unused))
498static UInt gen_blrl ( void ) {
499 return 0x4E800021; /* blrl */
500}
501static UInt gen_add_r_N ( UInt r, UInt N ) {
502 return mkFormD(14, r, r, N & 0xFFFF); /* addi r,r,N */
503}
504static UInt gen_cmpli_cr7_r_N ( UInt r, UInt N ) {
505 return mkFormD(10, 7<<2, r, N & 0xFFFF); /* cmpli cr7,r,N */
506}
507static UInt gen_bne_cr7_delta ( UInt delta ) {
508 return 0x409E0000 | (delta & 0x0000FFFC); /* bne- cr7,delta */
509}
510__attribute__((unused))
511static UInt gen_beq_cr7_delta ( UInt delta ) {
512 return 0x419E0000 | (delta & 0x0000FFFC); /* beq- cr7,delta */
513}
514static UInt gen_sc ( void ) {
515 return 0x44000002; /* sc */
516}
517static UInt gen_lwz_rd_off_ra ( UInt rd, UInt off, UInt ra ) {
518 return mkFormD(32, rd, ra, off); /* lwz rd, off(ra) */
519}
520static UInt gen_add_rd_rL_rR (UInt rd, UInt rsrcL, UInt rsrcR ) {
521 return mkFormXO(31, rd, rsrcL, rsrcR, 0, 266, 0);
522}
523static UInt gen_subf_rd_rL_rR (UInt rd, UInt rsrcL, UInt rsrcR ) {
524 return mkFormXO(31, rd, rsrcL, rsrcR, 0, 40, 0);
525}
526
527static Int emit_insn ( UInt* code, Int ix, UInt insn ) {
528 code[ix++] = insn;
529 return ix;
530}
531static Int emit_li32 ( UInt* code, Int ix, UInt rd, UInt imm32 ) {
532 code[ix++] = gen_lis_r_N(rd, imm32 >> 16);
sewardj13552642006-11-10 22:47:27 +0000533 if (imm32 & 0xFFFF)
534 code[ix++] = gen_ori_r_r_N(rd, imm32 & 0xFFFF);
sewardje25abab2006-10-17 00:39:31 +0000535 return ix;
536}
537static 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 */
550static 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}
573static 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
578static 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
665static 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
672static struct __ld_info32 ld_info32_array[N_LDINFOs];
673static struct __ld_info64 ld_info64_array[N_LDINFOs];
674
675
676static
677UChar* 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
687static 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:
sewardj13552642006-11-10 22:47:27 +0000849 addis 1, 1, -4
sewardje25abab2006-10-17 00:39:31 +0000850 imm 2, __NR__loadx
851 imm 3, VKI_DL_LOAD
sewardj13552642006-11-10 22:47:27 +0000852 mr 4, 1
853 imm 5, 3<<16
sewardje25abab2006-10-17 00:39:31 +0000854 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
sewardj13552642006-11-10 22:47:27 +0000860 addis 1, 1, 4
sewardje25abab2006-10-17 00:39:31 +0000861
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 */
sewardj13552642006-11-10 22:47:27 +00001000 ix = emit_insn( &block.code[0],ix,
1001 gen_addis_rd_rs_N(1,1,-4) );
sewardje25abab2006-10-17 00:39:31 +00001002 ix = emit_li32( &block.code[0],ix, 2, __nr___loadx );
1003 ix = emit_li32( &block.code[0],ix, 3, VKI_DL_LOAD );
sewardj13552642006-11-10 22:47:27 +00001004 ix = emit_insn( &block.code[0],ix, gen_mr_rd_rs(4,1) );
1005 ix = emit_li32( &block.code[0],ix, 5, 3<<16 );
sewardje25abab2006-10-17 00:39:31 +00001006 ix = emit_insn( &block.code[0],ix,
1007 gen_addi_rd_rs_N(6,31,offsetof(AIX5Bootblock,toolfile)));
sewardj13552642006-11-10 22:47:27 +00001008 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) );
sewardje25abab2006-10-17 00:39:31 +00001012 ix = emit_dosc( &block.code[0],ix );
sewardj13552642006-11-10 22:47:27 +00001013 ix = emit_insn( &block.code[0],ix,
1014 gen_addis_rd_rs_N(1,1,4) );
sewardje25abab2006-10-17 00:39:31 +00001015 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
1326static void barf ( int exitcode, char* argv0, char* msg )
1327{
1328 fprintf(stderr, "%s: %s\n", argv0, msg);
1329 exit(exitcode);
1330}
1331
1332int main ( int argc, char** argv, char** envp )
1333{
1334 Child child;
1335 Int i, loglevel;
1336 const char *toolname = NULL;
sewardj948a6fc2007-03-19 18:38:55 +00001337 char *clientname = NULL;
sewardje25abab2006-10-17 00:39:31 +00001338
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
sewardj948a6fc2007-03-19 18:38:55 +00001429 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
sewardje25abab2006-10-17 00:39:31 +00001467 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)
sewardj948a6fc2007-03-19 18:38:55 +00001474 clientname = (char*)find_client(clientname);
sewardje25abab2006-10-17 00:39:31 +00001475 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
sewardje25abab2006-10-17 00:39:31 +00001496 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 }
njn6bf365c2009-02-11 00:35:45 +00001506 sprintf(toolfile, "%s/%s-%s", valgrind_lib, toolname, platform);
sewardje25abab2006-10-17 00:39:31 +00001507
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
sewardj198f34f2007-07-09 23:13:07 +00001529 /* 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
sewardje25abab2006-10-17 00:39:31 +00001552 /* 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/*--------------------------------------------------------------------*/