blob: 0a7b6b31783a348eb1c0fc50d450c0202c10b08a [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
sewardj4d474d02008-02-11 11:34:59 +000011 Copyright (C) 2006-2008 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
sewardj7cf4e6b2008-05-01 20:24:26 +0000301 /* Zero out the shadow areas. */
302 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestPPC32State));
303 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestPPC32State));
sewardj2da47842006-10-17 01:23:07 +0000304
305# else /* defined(VGP_ppc64_aix5) */
306
307 vg_assert(0 == sizeof(VexGuestPPC64State) % 8);
308
309 /* Zero out the initial state, and set up the simulated FPU in a
310 sane way. */
311 LibVEX_GuestPPC64_initialise(&arch->vex);
312
sewardj7cf4e6b2008-05-01 20:24:26 +0000313 /* Zero out the shadow areas. */
314 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestPPC64State));
315 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestPPC64State));
sewardj2da47842006-10-17 01:23:07 +0000316
317# endif
318
sewardjf9d2f9b2006-11-17 20:00:57 +0000319 /* iifii.intregs37 contains the integer register state as it needs
sewardj2da47842006-10-17 01:23:07 +0000320 to be at client startup. These values are supplied by the
321 launcher. The 37 regs are:initial values from launcher for:
322 GPR0 .. GPR31, PC, CR, LR, CTR, XER. */
323
324 /* Put essential stuff into the new state. */
sewardjf9d2f9b2006-11-17 20:00:57 +0000325 arch->vex.guest_GPR0 = (UWord)iifii.intregs37[0];
326 arch->vex.guest_GPR1 = (UWord)iifii.intregs37[1];
327 arch->vex.guest_GPR2 = (UWord)iifii.intregs37[2];
328 arch->vex.guest_GPR3 = (UWord)iifii.intregs37[3];
329 arch->vex.guest_GPR4 = (UWord)iifii.intregs37[4];
330 arch->vex.guest_GPR5 = (UWord)iifii.intregs37[5];
331 arch->vex.guest_GPR6 = (UWord)iifii.intregs37[6];
332 arch->vex.guest_GPR7 = (UWord)iifii.intregs37[7];
333 arch->vex.guest_GPR8 = (UWord)iifii.intregs37[8];
334 arch->vex.guest_GPR9 = (UWord)iifii.intregs37[9];
335 arch->vex.guest_GPR10 = (UWord)iifii.intregs37[10];
336 arch->vex.guest_GPR11 = (UWord)iifii.intregs37[11];
337 arch->vex.guest_GPR12 = (UWord)iifii.intregs37[12];
338 arch->vex.guest_GPR13 = (UWord)iifii.intregs37[13];
339 arch->vex.guest_GPR14 = (UWord)iifii.intregs37[14];
340 arch->vex.guest_GPR15 = (UWord)iifii.intregs37[15];
341 arch->vex.guest_GPR16 = (UWord)iifii.intregs37[16];
342 arch->vex.guest_GPR17 = (UWord)iifii.intregs37[17];
343 arch->vex.guest_GPR18 = (UWord)iifii.intregs37[18];
344 arch->vex.guest_GPR19 = (UWord)iifii.intregs37[19];
345 arch->vex.guest_GPR20 = (UWord)iifii.intregs37[20];
346 arch->vex.guest_GPR21 = (UWord)iifii.intregs37[21];
347 arch->vex.guest_GPR22 = (UWord)iifii.intregs37[22];
348 arch->vex.guest_GPR23 = (UWord)iifii.intregs37[23];
349 arch->vex.guest_GPR24 = (UWord)iifii.intregs37[24];
350 arch->vex.guest_GPR25 = (UWord)iifii.intregs37[25];
351 arch->vex.guest_GPR26 = (UWord)iifii.intregs37[26];
352 arch->vex.guest_GPR27 = (UWord)iifii.intregs37[27];
353 arch->vex.guest_GPR28 = (UWord)iifii.intregs37[28];
354 arch->vex.guest_GPR29 = (UWord)iifii.intregs37[29];
355 arch->vex.guest_GPR30 = (UWord)iifii.intregs37[30];
356 arch->vex.guest_GPR31 = (UWord)iifii.intregs37[31];
sewardj2da47842006-10-17 01:23:07 +0000357
sewardjf9d2f9b2006-11-17 20:00:57 +0000358 arch->vex.guest_CIA = (UWord)iifii.intregs37[32+0];
359 arch->vex.guest_LR = (UWord)iifii.intregs37[32+2];
360 arch->vex.guest_CTR = (UWord)iifii.intregs37[32+3];
sewardj2da47842006-10-17 01:23:07 +0000361
362# if defined(VGP_ppc32_aix5)
363
sewardjf9d2f9b2006-11-17 20:00:57 +0000364 LibVEX_GuestPPC32_put_CR( (UWord)iifii.intregs37[32+1], &arch->vex );
365 LibVEX_GuestPPC32_put_XER( (UWord)iifii.intregs37[32+4], &arch->vex );
sewardj2da47842006-10-17 01:23:07 +0000366
367 /* Set the cache line size (KLUDGE) */
368 VG_(machine_ppc32_set_clszB)( 128 );
369
370# else /* defined(VGP_ppc64_aix5) */
371
sewardjf9d2f9b2006-11-17 20:00:57 +0000372 LibVEX_GuestPPC64_put_CR( (UWord)iifii.intregs37[32+1], &arch->vex );
373 LibVEX_GuestPPC64_put_XER( (UWord)iifii.intregs37[32+4], &arch->vex );
sewardj2da47842006-10-17 01:23:07 +0000374
375 /* Set the cache line size (KLUDGE) */
376 VG_(machine_ppc64_set_clszB)( 128 );
377
378# endif
379
380 /* Fix up the client's command line. Its argc/v/envp is in r3/4/5
381 (32-bit AIX) or r14/15/16 (64-bit AIX). but that is for the
382 Valgrind invokation as a whole. Hence we need to decrement argc
383 and advance argv to step over the args for Valgrind, and the
384 name of the Valgrind tool exe bogusly inserted by the launcher
385 (hence the "+1"). */
386
387# if defined(VGP_ppc32_aix5)
388
sewardjc271ec82007-02-27 22:36:14 +0000389 { UWord n_vargs = VG_(sizeXA)( VG_(args_for_valgrind) );
390 vg_assert(arch->vex.guest_GPR3 >= 1 + n_vargs);
391 arch->vex.guest_GPR3 -= (1 + n_vargs);
392 arch->vex.guest_GPR4 += sizeof(UWord) * (1 + n_vargs);
393 }
sewardj2da47842006-10-17 01:23:07 +0000394
395# else /* defined(VGP_ppc64_aix5) */
396
sewardjc271ec82007-02-27 22:36:14 +0000397 { UWord n_vargs = VG_(sizeXA)( VG_(args_for_valgrind) );
398 vg_assert(arch->vex.guest_GPR14 >= 1 + n_vargs);
399 arch->vex.guest_GPR14 -= (1 + n_vargs);
400 arch->vex.guest_GPR15 += sizeof(UWord) * (1 + n_vargs);
401 }
sewardj2da47842006-10-17 01:23:07 +0000402
403# endif
404
405 /* At this point the guest register state is correct for client
406 startup. However, that's not where we want to start; in fact we
sewardjf9d2f9b2006-11-17 20:00:57 +0000407 want to start at VG_(ppc{32,64}_aix5_do_preloads_then_start_client),
408 passing it iifii.preloadpage in r3. This will load the core/tool
sewardj2da47842006-10-17 01:23:07 +0000409 preload .so's, then restore r2-r10 from what's stashed in the
410 preloadpage, and then start the client really. Hence: */
411
412 /* Save r2-r10 and the client start point in preloadpage */
sewardjf9d2f9b2006-11-17 20:00:57 +0000413 iifii.preloadpage->r2 = (ULong)arch->vex.guest_GPR2;
414 iifii.preloadpage->r3 = (ULong)arch->vex.guest_GPR3;
415 iifii.preloadpage->r4 = (ULong)arch->vex.guest_GPR4;
416 iifii.preloadpage->r5 = (ULong)arch->vex.guest_GPR5;
417 iifii.preloadpage->r6 = (ULong)arch->vex.guest_GPR6;
418 iifii.preloadpage->r7 = (ULong)arch->vex.guest_GPR7;
419 iifii.preloadpage->r8 = (ULong)arch->vex.guest_GPR8;
420 iifii.preloadpage->r9 = (ULong)arch->vex.guest_GPR9;
421 iifii.preloadpage->r10 = (ULong)arch->vex.guest_GPR10;
422 iifii.preloadpage->client_start = (ULong)arch->vex.guest_CIA;
sewardj2da47842006-10-17 01:23:07 +0000423
424
425# if defined(VGP_ppc32_aix5)
426
427 /* Set up to start at VG_(ppc32_aix5_do_preloads_then_start_client) */
428 arch->vex.guest_CIA = (UWord)&VG_(ppc32_aix5_do_preloads_then_start_client);
429
430# else /* defined(VGP_ppc64_aix5) */
431
432 /* Set up to start at VG_(ppc64_aix5_do_preloads_then_start_client) */
433 arch->vex.guest_CIA = (UWord)&VG_(ppc64_aix5_do_preloads_then_start_client);
434
435# endif
436
sewardjf9d2f9b2006-11-17 20:00:57 +0000437 arch->vex.guest_GPR3 = (UWord)iifii.preloadpage;
sewardj2da47842006-10-17 01:23:07 +0000438
439 /* The rest of the preloadpage fields will already have been filled
440 in by VG_(setup_client_initial_image). So we're done. */
441
442 /* Finally, decompress the page compressed by the launcher. We
443 can't do this any earlier, because the page is (effectively)
sewardjf9d2f9b2006-11-17 20:00:57 +0000444 decompressed in place, which trashes iifii.intregs37. So we have
445 to wait till this point, at which we're done with iifii.intregs37
sewardj2da47842006-10-17 01:23:07 +0000446 (to be precise, with what it points at). */
447 VG_(debugLog)(1, "initimg", "decompressing page at %p\n",
sewardjf9d2f9b2006-11-17 20:00:57 +0000448 (void*)iifii.compressed_page);
449 vg_assert(VG_IS_PAGE_ALIGNED(iifii.compressed_page));
sewardj2da47842006-10-17 01:23:07 +0000450
sewardjf9d2f9b2006-11-17 20:00:57 +0000451 Huffman_Uncompress( (void*)iifii.compressed_page, unz_page,
sewardj2da47842006-10-17 01:23:07 +0000452 VKI_PAGE_SIZE, VKI_PAGE_SIZE );
453 adler32_act = compute_adler32(unz_page, VKI_PAGE_SIZE);
454
455 VG_(debugLog)(1, "initimg",
456 "decompress done, adler32s: act 0x%x, exp 0x%x\n",
sewardjf9d2f9b2006-11-17 20:00:57 +0000457 adler32_act, iifii.adler32_exp );
sewardj2da47842006-10-17 01:23:07 +0000458
sewardjf9d2f9b2006-11-17 20:00:57 +0000459 VG_(memcpy)((void*)iifii.compressed_page, unz_page, VKI_PAGE_SIZE);
sewardj2da47842006-10-17 01:23:07 +0000460
461 VG_(debugLog)(1, "initimg", "copy back done\n");
462
463 /* Tell the tool that we just wrote to the registers. */
464 VG_TRACK( post_reg_write, Vg_CoreStartup, /*tid*/1, /*offset*/0,
465 sizeof(VexGuestArchState));
466
467 /* Determine the brk limit. */
468 VG_(debugLog)(1, "initimg", "establishing current brk ..\n");
469 vg_assert(__NR_AIX5_sbrk != __NR_AIX5_UNKNOWN);
470 sres = VG_(do_syscall1)(__NR_AIX5_sbrk, 0);
471 vg_assert(sres.err == 0); /* assert no error */
472 VG_(brk_base) = VG_(brk_limit) = sres.res;
473 VG_(debugLog)(1, "initimg", ".. brk = %p\n", (void*)VG_(brk_base));
474}
475
476
477/* --- Diagnose preload failures. --- */
478
479/* This is a nasty but effective kludge. The address of the following
480 function is put into the preload page. So, if a preload failure
481 happens, we call here to get helpful info printed out (the call
482 site is in m_trampoline.S). This is a dirty hack (1) because
483 diagnose_load_failure runs on the simulated CPU, not the real one
484 and (2) because it induces a libc dependency. Oh well. */
485
486/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
487#include <stdlib.h>
488#include <sys/ldr.h>
489/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
490
491static void diagnose_load_failure ( void )
492{
493# define NBUF 1024
494 UChar buf[NBUF];
495 VG_(debugLog)(0, "initimg", "Diagnosing load failure\n");
496 if (sizeof(void*) == 8) {
497 VG_(debugLog)(0, "initimg", "Can't safely do loadquery() "
498 "in 64-bit mode. Sorry.\n");
499 /* because this requires dynamic linking to be working (IIRC)
500 and it isn't; the tool file's dynamic linking was never done,
501 because it was loaded by the bootstrap stub, which simply did
502 sys_kload() but didn't make usla do the relevant
503 relocations. */
504 } else {
505 UChar** p;
506 Int r = loadquery(L_GETMESSAGES, buf, NBUF);
507 VG_(debugLog)(0, "initimg", "loadquery returned %d (0 = success)\n", r);
508 p = (UChar**)(&buf[0]);
509 for (; *p; p++)
510 VG_(debugLog)(0, "initimg", "\"%s\"\n", *p);
511 VG_(debugLog)(0, "initimg", "Use /usr/sbin/execerror to make "
512 "sense of above string(s)\n");
513 VG_(debugLog)(0, "initimg", "See also comments at the bottom of\n");
514 VG_(debugLog)(0, "initimg", "coregrind/m_initimg/"
515 "initimg-aix5.c (in Valgrind sources)\n");
516 }
517# undef NBUF
518}
519
520/* Take the strings that this prints out and feed them
521 to /usr/sbin/execerror. For example, it might print
522
523 (ld 3 1 __libc_freeres /foo/bar/ppc32-aix5/vgpreload_core.so
524
525 in which case
526
527 $ execerror xyzzy \
528 "(ld 3 1 __libc_freeres /foo/bar/ppc32-aix5/vgpreload_core.so"
529
530 gets you
531
532 Could not load program xyzzy:
533 rtld: 0712-001 Symbol __libc_freeres was referenced
534 from module /foo/bar/ppc32-aix5/vgpreload_core.so(),
535 but a runtime definition
536 of the symbol was not found.
537*/
538
539/*--------------------------------------------------------------------*/
540/*--- initimg-aix5.c ---*/
541/*--------------------------------------------------------------------*/