blob: 40a35bd37006fcb8e61b6454427032f23d12adcf [file] [log] [blame]
sewardj2da47842006-10-17 01:23:07 +00001
2/*--------------------------------------------------------------------*/
3/*--- Startup: create initial process image on AIX5 ---*/
4/*--- initimg-aix5.c ---*/
5/*--------------------------------------------------------------------*/
6
7/*
8 This file is part of Valgrind, a dynamic binary instrumentation
9 framework.
10
sewardj9ebd6e02007-01-08 06:01:59 +000011 Copyright (C) 2006-2007 OpenWorks LLP
sewardj2da47842006-10-17 01:23:07 +000012 info@open-works.co.uk
13
14 This program is free software; you can redistribute it and/or
15 modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation; either version 2 of the
17 License, or (at your option) any later version.
18
19 This program is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 General Public License for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 02111-1307, USA.
28
29 The GNU General Public License is contained in the file COPYING.
sewardj38dba992007-04-29 09:06:40 +000030
31 Neither the names of the U.S. Department of Energy nor the
32 University of California nor the names of its contributors may be
33 used to endorse or promote products derived from this software
34 without prior written permission.
sewardj2da47842006-10-17 01:23:07 +000035*/
36
37#include "pub_core_basics.h"
38#include "pub_core_vki.h"
39#include "pub_core_vkiscnums.h"
40#include "pub_core_debuglog.h"
41#include "pub_core_libcbase.h"
42#include "pub_core_libcassert.h"
43#include "pub_core_libcfile.h"
44#include "pub_core_libcproc.h"
45#include "pub_core_libcprint.h"
sewardjc271ec82007-02-27 22:36:14 +000046#include "pub_core_xarray.h"
sewardj2da47842006-10-17 01:23:07 +000047#include "pub_core_clientstate.h"
48#include "pub_core_aspacemgr.h"
49#include "pub_core_mallocfree.h"
50#include "pub_core_machine.h"
51#include "pub_core_ume.h"
52#include "pub_core_options.h"
53#include "pub_core_threadstate.h" /* ThreadArchState */
54#include "pub_core_tooliface.h" /* VG_TRACK */
55#include "pub_core_trampoline.h" /* VG_(ppc32_aix5_do_preloads_then_start_client) */
56#include "pub_core_syscall.h" // VG_(do_syscall1)
57#include "pub_core_initimg.h" /* self */
58
59#include "simple_huffman.c"
60
61#if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5)
62#error "This should only be compiled on AIX"
63#endif
64
65
66static void diagnose_load_failure ( void );
67
68/* --- Create the client's initial memory image. --- */
69
sewardjf9d2f9b2006-11-17 20:00:57 +000070IIFinaliseImageInfo VG_(ii_create_image)( IICreateImageInfo iicii )
sewardj2da47842006-10-17 01:23:07 +000071{
sewardj2da47842006-10-17 01:23:07 +000072 /* Set up an AIX5PreloadPage structure with the names of
73
74 $VALGRIND_LIB/PLATFORM/vgpreload_core.so
75 $VALGRIND_LIB/PLATFORM/vgpreload_TOOL.so, if it exists
76 xxx in "LD_PRELOAD=xxx", if it exists
77
78 The client is started by running (on the simulator, of course)
79 VG_(ppc{32,64}_aix5_do_preloads_then_start_client), which uses
80 __loadx/_kload to load these .so's. When the preloading is
81 done, various guest registers are restored to what they are
82 really supposed to be at client startup, so these values too are
83 stored in the AIX5PreloadPage. Finally, we jump to the client's
84 entry point address.
85 */
86 const HChar* _so = ".so";
87 const HChar* vgpreload_ = "vgpreload_";
88 const HChar* vgpreload_core_so = "vgpreload_core.so";
89 const HChar* errmsg_str
90 = "valgrind: FATAL: core/tool/LD_PRELOAD= "
91 "preload failed.\n";
92 Int plcore_len, pltool_len, ld_pre_len, errmsg_len;
93 HChar *plcore_str, *pltool_str, *ld_pre_str;
94 Bool have_tool_so, have_ld_pre;
95
96 AIX5PreloadPage* pp;
97 UChar* pc;
98 Int szB, szPG;
99 SysRes sres;
100
sewardjf9d2f9b2006-11-17 20:00:57 +0000101 IIFinaliseImageInfo iifii;
102 VG_(memset)( &iifii, 0, sizeof(iifii) );
103
sewardj948a6fc2007-03-19 18:38:55 +0000104 /* this can happen, if m_main decides to NULL it out */
105 if (VG_(args_the_exename) == NULL)
106 VG_(err_missing_prog)();
107
sewardjf9d2f9b2006-11-17 20:00:57 +0000108 vg_assert( iicii.toolname );
sewardj2da47842006-10-17 01:23:07 +0000109 pltool_len = VG_(strlen)( VG_(libdir) )
110 + 1 /*slash*/
111 + VG_(strlen)(VG_PLATFORM)
112 + 1 /*slash*/
113 + VG_(strlen)( vgpreload_ )
sewardjf9d2f9b2006-11-17 20:00:57 +0000114 + VG_(strlen)( iicii.toolname )
sewardj2da47842006-10-17 01:23:07 +0000115 + VG_(strlen)( _so )
116 + 1 /*NUL*/;
117 vg_assert(pltool_len > 0);
118 pltool_str = VG_(malloc)( pltool_len );
119 pltool_str[0] = 0;
120 VG_(strcat)( pltool_str, VG_(libdir) );
121 VG_(strcat)( pltool_str, "/" );
122 VG_(strcat)( pltool_str, VG_PLATFORM );
123 VG_(strcat)( pltool_str, "/" );
124 VG_(strcat)( pltool_str, vgpreload_ );
sewardjf9d2f9b2006-11-17 20:00:57 +0000125 VG_(strcat)( pltool_str, iicii.toolname );
sewardj2da47842006-10-17 01:23:07 +0000126 VG_(strcat)( pltool_str, _so );
127 vg_assert( pltool_str[pltool_len-1] == 0);
128 vg_assert( VG_(strlen)(pltool_str) == pltool_len-1 );
129
130 plcore_len = VG_(strlen)( VG_(libdir) )
131 + 1 /*slash*/
132 + VG_(strlen)(VG_PLATFORM)
133 + 1 /*slash*/
134 + VG_(strlen)( vgpreload_core_so )
135 + 1 /*NUL*/;
136 vg_assert(plcore_len > 0);
137 plcore_str = VG_(malloc)( plcore_len );
138 plcore_str[0] = 0;
139 VG_(strcat)( plcore_str, VG_(libdir) );
140 VG_(strcat)( plcore_str, "/" );
141 VG_(strcat)( plcore_str, VG_PLATFORM );
142 VG_(strcat)( plcore_str, "/" );
143 VG_(strcat)( plcore_str, vgpreload_core_so );
144 vg_assert( plcore_str[plcore_len-1] == 0 );
145 vg_assert( VG_(strlen)(plcore_str) == plcore_len-1 );
146
147 errmsg_len = VG_(strlen)( errmsg_str )
148 + 1 /*NUL*/;
149
150 ld_pre_str = VG_(getenv)("LD_PRELOAD");
151 if (ld_pre_str && VG_(strlen)(ld_pre_str) > 0) {
152 have_ld_pre = True;
153 ld_pre_len = VG_(strlen)(ld_pre_str) + 1/*NUL*/;
154 ld_pre_str = VG_(malloc)( ld_pre_len );
155 ld_pre_str[0] = 0;
156 VG_(strcat)( ld_pre_str, VG_(getenv)("LD_PRELOAD") );
157 vg_assert( ld_pre_str[ld_pre_len-1] == 0);
158 vg_assert( VG_(strlen)( ld_pre_str ) == ld_pre_len - 1 );
159 } else {
160 have_ld_pre = False;
161 ld_pre_len = 0;
162 ld_pre_str = NULL;
163 }
164
165 VG_(debugLog)(1, "initimg", "plcore_str = '%s'\n", plcore_str );
166 VG_(debugLog)(1, "initimg", "pltool_str = '%s'\n", pltool_str );
167 VG_(debugLog)(1, "initimg", "ld_pre_str = '%s'\n", ld_pre_str );
168
169 if (0 != VG_(access)(plcore_str, True,False,True))
170 VG_(err_config_error)("Can't find core preload "
171 "(vgpreload_core.so)");
172
173 have_tool_so = 0 == VG_(access)(pltool_str, True,False,True);
174
175 /* Figure out how much space is needed for an AIX5PreloadInfo
176 followed by the three preload strings. */
177
178 vg_assert((sizeof(AIX5PreloadPage) % 4) == 0); /* paranoia */
179
180 szB = sizeof(AIX5PreloadPage) + plcore_len
181 + (have_tool_so ? pltool_len : 0)
182 + (have_ld_pre ? ld_pre_len : 0)
183 + errmsg_len;
184 szPG = VG_PGROUNDUP(szB+1) / VKI_PAGE_SIZE;
sewardjf9d2f9b2006-11-17 20:00:57 +0000185 VG_(debugLog)(2, "initimg",
186 "preload page size: %d bytes, %d pages\n", szB, szPG);
sewardj2da47842006-10-17 01:23:07 +0000187
188 vg_assert(szB > 0);
189 vg_assert(szB < szPG * VKI_PAGE_SIZE);
190
191 /* We'll need szPG pages of anonymous, rw-, client space (needs w
192 so we can write it here) */
193 sres = VG_(am_mmap_anon_float_client)
194 ( szPG * VKI_PAGE_SIZE, VKI_PROT_READ|VKI_PROT_WRITE);
195 if (sres.isError)
196 VG_(err_config_error)("Can't allocate client page(s) "
197 "for preload info");
198 pp = (AIX5PreloadPage*)sres.res;
199
200 VG_(debugLog)(2, "initimg", "preload page allocation succeeded at %p\n", pp);
201
202 /* Zero out the initial structure. */
203 VG_(memset)(pp, 0, sizeof(AIX5PreloadPage));
204
205 pc = (UChar*)pp;
206 pc += sizeof(AIX5PreloadPage);
207 VG_(memcpy)(pc, plcore_str, plcore_len);
208 pp->off_preloadcorename = pc - (UChar*)pp;
209 pc += plcore_len;
210 if (have_tool_so) {
211 VG_(memcpy)(pc, pltool_str, pltool_len);
212 pp->off_preloadtoolname = pc - (UChar*)pp;
213 pc += pltool_len;
214 }
215 if (have_ld_pre) {
216 VG_(memcpy)(pc, ld_pre_str, ld_pre_len);
217 pp->off_ld_preloadname = pc - (UChar*)pp;
218 pc += ld_pre_len;
219 }
220 VG_(memcpy)(pc, errmsg_str, errmsg_len);
221 pp->off_errmsg = pc - (UChar*)pp;
222 pp->len_errmsg = errmsg_len - 1; /* -1: skip terminating NUL */
223
224 vg_assert(pc <= ((UChar*)pp) - 1 + szPG * VKI_PAGE_SIZE);
225
226 VG_(free)(plcore_str);
227 VG_(free)(pltool_str);
228
229 /* Fill in all the other preload page fields that we can right
230 now. */
231# if defined(VGP_ppc32_aix5)
232 vg_assert(__NR_AIX5___loadx != __NR_AIX5_UNKNOWN);
233 pp->nr_load = __NR_AIX5___loadx;
234# else /* defined(VGP_ppc64_aix5) */
235 vg_assert(__NR_AIX5_kload != __NR_AIX5_UNKNOWN);
236 pp->nr_load = __NR_AIX5_kload;
237# endif
238
239 vg_assert(__NR_AIX5_kwrite != __NR_AIX5_UNKNOWN);
240 pp->nr_kwrite = __NR_AIX5_kwrite; /* kwrite */
241
242 vg_assert(__NR_AIX5__exit != __NR_AIX5_UNKNOWN);
243 pp->nr__exit = __NR_AIX5__exit; /* _exit */
244
245 pp->p_diagnose_load_failure = &diagnose_load_failure;
246
sewardjf9d2f9b2006-11-17 20:00:57 +0000247 iifii.preloadpage = pp;
248 iifii.intregs37 = iicii.intregs37;
249 iifii.initial_client_SP = iicii.intregs37[1]; /* r1 */
250 iifii.compressed_page = VG_PGROUNDDN((Addr)iicii.bootblock);
251 iifii.adler32_exp = iicii.adler32_exp;
252 iifii.clstack_max_size = 0; /* we don't know yet */
253 return iifii;
sewardj2da47842006-10-17 01:23:07 +0000254}
255
256
257/* --- Finalise the initial image and register state. --- */
258
259static UChar unz_page[VKI_PAGE_SIZE];
260
261static UInt compute_adler32 ( void* addr, UWord len )
262{
263 UInt s1 = 1;
264 UInt s2 = 0;
265 UChar* buf = (UChar*)addr;
266 while (len > 0) {
267 s1 += buf[0];
268 s2 += s1;
269 s1 %= 65521;
270 s2 %= 65521;
271 len--;
272 buf++;
273 }
274 return (s2 << 16) + s1;
275}
276
sewardjf9d2f9b2006-11-17 20:00:57 +0000277/* Just before starting the client, we may need to make final
278 adjustments to its initial image. Also we need to set up the VEX
279 guest state for thread 1 (the root thread) and copy in essential
280 starting values. This is handed the IIFinaliseImageInfo created by
281 VG_(ii_create_image).
282*/
283void VG_(ii_finalise_image)( IIFinaliseImageInfo iifii )
sewardj2da47842006-10-17 01:23:07 +0000284{
sewardjf9d2f9b2006-11-17 20:00:57 +0000285 UInt adler32_act;
sewardj2da47842006-10-17 01:23:07 +0000286 SysRes sres;
287 /* On AIX we get a block of 37 words telling us the initial state
288 for (GPR0 .. GPR31, PC, CR, LR, CTR, XER), and we start with all
289 the other registers zeroed. */
290
sewardjf9d2f9b2006-11-17 20:00:57 +0000291 ThreadArchState* arch = &VG_(threads)[1].arch;
292
sewardj2da47842006-10-17 01:23:07 +0000293# if defined(VGP_ppc32_aix5)
294
295 vg_assert(0 == sizeof(VexGuestPPC32State) % 8);
296
297 /* Zero out the initial state, and set up the simulated FPU in a
298 sane way. */
299 LibVEX_GuestPPC32_initialise(&arch->vex);
300
301 /* Zero out the shadow area. */
302 VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestPPC32State));
303
304# else /* defined(VGP_ppc64_aix5) */
305
306 vg_assert(0 == sizeof(VexGuestPPC64State) % 8);
307
308 /* Zero out the initial state, and set up the simulated FPU in a
309 sane way. */
310 LibVEX_GuestPPC64_initialise(&arch->vex);
311
312 /* Zero out the shadow area. */
313 VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestPPC64State));
314
315# endif
316
sewardjf9d2f9b2006-11-17 20:00:57 +0000317 /* iifii.intregs37 contains the integer register state as it needs
sewardj2da47842006-10-17 01:23:07 +0000318 to be at client startup. These values are supplied by the
319 launcher. The 37 regs are:initial values from launcher for:
320 GPR0 .. GPR31, PC, CR, LR, CTR, XER. */
321
322 /* Put essential stuff into the new state. */
sewardjf9d2f9b2006-11-17 20:00:57 +0000323 arch->vex.guest_GPR0 = (UWord)iifii.intregs37[0];
324 arch->vex.guest_GPR1 = (UWord)iifii.intregs37[1];
325 arch->vex.guest_GPR2 = (UWord)iifii.intregs37[2];
326 arch->vex.guest_GPR3 = (UWord)iifii.intregs37[3];
327 arch->vex.guest_GPR4 = (UWord)iifii.intregs37[4];
328 arch->vex.guest_GPR5 = (UWord)iifii.intregs37[5];
329 arch->vex.guest_GPR6 = (UWord)iifii.intregs37[6];
330 arch->vex.guest_GPR7 = (UWord)iifii.intregs37[7];
331 arch->vex.guest_GPR8 = (UWord)iifii.intregs37[8];
332 arch->vex.guest_GPR9 = (UWord)iifii.intregs37[9];
333 arch->vex.guest_GPR10 = (UWord)iifii.intregs37[10];
334 arch->vex.guest_GPR11 = (UWord)iifii.intregs37[11];
335 arch->vex.guest_GPR12 = (UWord)iifii.intregs37[12];
336 arch->vex.guest_GPR13 = (UWord)iifii.intregs37[13];
337 arch->vex.guest_GPR14 = (UWord)iifii.intregs37[14];
338 arch->vex.guest_GPR15 = (UWord)iifii.intregs37[15];
339 arch->vex.guest_GPR16 = (UWord)iifii.intregs37[16];
340 arch->vex.guest_GPR17 = (UWord)iifii.intregs37[17];
341 arch->vex.guest_GPR18 = (UWord)iifii.intregs37[18];
342 arch->vex.guest_GPR19 = (UWord)iifii.intregs37[19];
343 arch->vex.guest_GPR20 = (UWord)iifii.intregs37[20];
344 arch->vex.guest_GPR21 = (UWord)iifii.intregs37[21];
345 arch->vex.guest_GPR22 = (UWord)iifii.intregs37[22];
346 arch->vex.guest_GPR23 = (UWord)iifii.intregs37[23];
347 arch->vex.guest_GPR24 = (UWord)iifii.intregs37[24];
348 arch->vex.guest_GPR25 = (UWord)iifii.intregs37[25];
349 arch->vex.guest_GPR26 = (UWord)iifii.intregs37[26];
350 arch->vex.guest_GPR27 = (UWord)iifii.intregs37[27];
351 arch->vex.guest_GPR28 = (UWord)iifii.intregs37[28];
352 arch->vex.guest_GPR29 = (UWord)iifii.intregs37[29];
353 arch->vex.guest_GPR30 = (UWord)iifii.intregs37[30];
354 arch->vex.guest_GPR31 = (UWord)iifii.intregs37[31];
sewardj2da47842006-10-17 01:23:07 +0000355
sewardjf9d2f9b2006-11-17 20:00:57 +0000356 arch->vex.guest_CIA = (UWord)iifii.intregs37[32+0];
357 arch->vex.guest_LR = (UWord)iifii.intregs37[32+2];
358 arch->vex.guest_CTR = (UWord)iifii.intregs37[32+3];
sewardj2da47842006-10-17 01:23:07 +0000359
360# if defined(VGP_ppc32_aix5)
361
sewardjf9d2f9b2006-11-17 20:00:57 +0000362 LibVEX_GuestPPC32_put_CR( (UWord)iifii.intregs37[32+1], &arch->vex );
363 LibVEX_GuestPPC32_put_XER( (UWord)iifii.intregs37[32+4], &arch->vex );
sewardj2da47842006-10-17 01:23:07 +0000364
365 /* Set the cache line size (KLUDGE) */
366 VG_(machine_ppc32_set_clszB)( 128 );
367
368# else /* defined(VGP_ppc64_aix5) */
369
sewardjf9d2f9b2006-11-17 20:00:57 +0000370 LibVEX_GuestPPC64_put_CR( (UWord)iifii.intregs37[32+1], &arch->vex );
371 LibVEX_GuestPPC64_put_XER( (UWord)iifii.intregs37[32+4], &arch->vex );
sewardj2da47842006-10-17 01:23:07 +0000372
373 /* Set the cache line size (KLUDGE) */
374 VG_(machine_ppc64_set_clszB)( 128 );
375
376# endif
377
378 /* Fix up the client's command line. Its argc/v/envp is in r3/4/5
379 (32-bit AIX) or r14/15/16 (64-bit AIX). but that is for the
380 Valgrind invokation as a whole. Hence we need to decrement argc
381 and advance argv to step over the args for Valgrind, and the
382 name of the Valgrind tool exe bogusly inserted by the launcher
383 (hence the "+1"). */
384
385# if defined(VGP_ppc32_aix5)
386
sewardjc271ec82007-02-27 22:36:14 +0000387 { UWord n_vargs = VG_(sizeXA)( VG_(args_for_valgrind) );
388 vg_assert(arch->vex.guest_GPR3 >= 1 + n_vargs);
389 arch->vex.guest_GPR3 -= (1 + n_vargs);
390 arch->vex.guest_GPR4 += sizeof(UWord) * (1 + n_vargs);
391 }
sewardj2da47842006-10-17 01:23:07 +0000392
393# else /* defined(VGP_ppc64_aix5) */
394
sewardjc271ec82007-02-27 22:36:14 +0000395 { UWord n_vargs = VG_(sizeXA)( VG_(args_for_valgrind) );
396 vg_assert(arch->vex.guest_GPR14 >= 1 + n_vargs);
397 arch->vex.guest_GPR14 -= (1 + n_vargs);
398 arch->vex.guest_GPR15 += sizeof(UWord) * (1 + n_vargs);
399 }
sewardj2da47842006-10-17 01:23:07 +0000400
401# endif
402
403 /* At this point the guest register state is correct for client
404 startup. However, that's not where we want to start; in fact we
sewardjf9d2f9b2006-11-17 20:00:57 +0000405 want to start at VG_(ppc{32,64}_aix5_do_preloads_then_start_client),
406 passing it iifii.preloadpage in r3. This will load the core/tool
sewardj2da47842006-10-17 01:23:07 +0000407 preload .so's, then restore r2-r10 from what's stashed in the
408 preloadpage, and then start the client really. Hence: */
409
410 /* Save r2-r10 and the client start point in preloadpage */
sewardjf9d2f9b2006-11-17 20:00:57 +0000411 iifii.preloadpage->r2 = (ULong)arch->vex.guest_GPR2;
412 iifii.preloadpage->r3 = (ULong)arch->vex.guest_GPR3;
413 iifii.preloadpage->r4 = (ULong)arch->vex.guest_GPR4;
414 iifii.preloadpage->r5 = (ULong)arch->vex.guest_GPR5;
415 iifii.preloadpage->r6 = (ULong)arch->vex.guest_GPR6;
416 iifii.preloadpage->r7 = (ULong)arch->vex.guest_GPR7;
417 iifii.preloadpage->r8 = (ULong)arch->vex.guest_GPR8;
418 iifii.preloadpage->r9 = (ULong)arch->vex.guest_GPR9;
419 iifii.preloadpage->r10 = (ULong)arch->vex.guest_GPR10;
420 iifii.preloadpage->client_start = (ULong)arch->vex.guest_CIA;
sewardj2da47842006-10-17 01:23:07 +0000421
422
423# if defined(VGP_ppc32_aix5)
424
425 /* Set up to start at VG_(ppc32_aix5_do_preloads_then_start_client) */
426 arch->vex.guest_CIA = (UWord)&VG_(ppc32_aix5_do_preloads_then_start_client);
427
428# else /* defined(VGP_ppc64_aix5) */
429
430 /* Set up to start at VG_(ppc64_aix5_do_preloads_then_start_client) */
431 arch->vex.guest_CIA = (UWord)&VG_(ppc64_aix5_do_preloads_then_start_client);
432
433# endif
434
sewardjf9d2f9b2006-11-17 20:00:57 +0000435 arch->vex.guest_GPR3 = (UWord)iifii.preloadpage;
sewardj2da47842006-10-17 01:23:07 +0000436
437 /* The rest of the preloadpage fields will already have been filled
438 in by VG_(setup_client_initial_image). So we're done. */
439
440 /* Finally, decompress the page compressed by the launcher. We
441 can't do this any earlier, because the page is (effectively)
sewardjf9d2f9b2006-11-17 20:00:57 +0000442 decompressed in place, which trashes iifii.intregs37. So we have
443 to wait till this point, at which we're done with iifii.intregs37
sewardj2da47842006-10-17 01:23:07 +0000444 (to be precise, with what it points at). */
445 VG_(debugLog)(1, "initimg", "decompressing page at %p\n",
sewardjf9d2f9b2006-11-17 20:00:57 +0000446 (void*)iifii.compressed_page);
447 vg_assert(VG_IS_PAGE_ALIGNED(iifii.compressed_page));
sewardj2da47842006-10-17 01:23:07 +0000448
sewardjf9d2f9b2006-11-17 20:00:57 +0000449 Huffman_Uncompress( (void*)iifii.compressed_page, unz_page,
sewardj2da47842006-10-17 01:23:07 +0000450 VKI_PAGE_SIZE, VKI_PAGE_SIZE );
451 adler32_act = compute_adler32(unz_page, VKI_PAGE_SIZE);
452
453 VG_(debugLog)(1, "initimg",
454 "decompress done, adler32s: act 0x%x, exp 0x%x\n",
sewardjf9d2f9b2006-11-17 20:00:57 +0000455 adler32_act, iifii.adler32_exp );
sewardj2da47842006-10-17 01:23:07 +0000456
sewardjf9d2f9b2006-11-17 20:00:57 +0000457 VG_(memcpy)((void*)iifii.compressed_page, unz_page, VKI_PAGE_SIZE);
sewardj2da47842006-10-17 01:23:07 +0000458
459 VG_(debugLog)(1, "initimg", "copy back done\n");
460
461 /* Tell the tool that we just wrote to the registers. */
462 VG_TRACK( post_reg_write, Vg_CoreStartup, /*tid*/1, /*offset*/0,
463 sizeof(VexGuestArchState));
464
465 /* Determine the brk limit. */
466 VG_(debugLog)(1, "initimg", "establishing current brk ..\n");
467 vg_assert(__NR_AIX5_sbrk != __NR_AIX5_UNKNOWN);
468 sres = VG_(do_syscall1)(__NR_AIX5_sbrk, 0);
469 vg_assert(sres.err == 0); /* assert no error */
470 VG_(brk_base) = VG_(brk_limit) = sres.res;
471 VG_(debugLog)(1, "initimg", ".. brk = %p\n", (void*)VG_(brk_base));
472}
473
474
475/* --- Diagnose preload failures. --- */
476
477/* This is a nasty but effective kludge. The address of the following
478 function is put into the preload page. So, if a preload failure
479 happens, we call here to get helpful info printed out (the call
480 site is in m_trampoline.S). This is a dirty hack (1) because
481 diagnose_load_failure runs on the simulated CPU, not the real one
482 and (2) because it induces a libc dependency. Oh well. */
483
484/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
485#include <stdlib.h>
486#include <sys/ldr.h>
487/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
488
489static void diagnose_load_failure ( void )
490{
491# define NBUF 1024
492 UChar buf[NBUF];
493 VG_(debugLog)(0, "initimg", "Diagnosing load failure\n");
494 if (sizeof(void*) == 8) {
495 VG_(debugLog)(0, "initimg", "Can't safely do loadquery() "
496 "in 64-bit mode. Sorry.\n");
497 /* because this requires dynamic linking to be working (IIRC)
498 and it isn't; the tool file's dynamic linking was never done,
499 because it was loaded by the bootstrap stub, which simply did
500 sys_kload() but didn't make usla do the relevant
501 relocations. */
502 } else {
503 UChar** p;
504 Int r = loadquery(L_GETMESSAGES, buf, NBUF);
505 VG_(debugLog)(0, "initimg", "loadquery returned %d (0 = success)\n", r);
506 p = (UChar**)(&buf[0]);
507 for (; *p; p++)
508 VG_(debugLog)(0, "initimg", "\"%s\"\n", *p);
509 VG_(debugLog)(0, "initimg", "Use /usr/sbin/execerror to make "
510 "sense of above string(s)\n");
511 VG_(debugLog)(0, "initimg", "See also comments at the bottom of\n");
512 VG_(debugLog)(0, "initimg", "coregrind/m_initimg/"
513 "initimg-aix5.c (in Valgrind sources)\n");
514 }
515# undef NBUF
516}
517
518/* Take the strings that this prints out and feed them
519 to /usr/sbin/execerror. For example, it might print
520
521 (ld 3 1 __libc_freeres /foo/bar/ppc32-aix5/vgpreload_core.so
522
523 in which case
524
525 $ execerror xyzzy \
526 "(ld 3 1 __libc_freeres /foo/bar/ppc32-aix5/vgpreload_core.so"
527
528 gets you
529
530 Could not load program xyzzy:
531 rtld: 0712-001 Symbol __libc_freeres was referenced
532 from module /foo/bar/ppc32-aix5/vgpreload_core.so(),
533 but a runtime definition
534 of the symbol was not found.
535*/
536
537/*--------------------------------------------------------------------*/
538/*--- initimg-aix5.c ---*/
539/*--------------------------------------------------------------------*/