diff options
Diffstat (limited to 'coregrind/m_initimg/.svn/text-base/initimg-aix5.c.svn-base')
-rw-r--r-- | coregrind/m_initimg/.svn/text-base/initimg-aix5.c.svn-base | 545 |
1 files changed, 545 insertions, 0 deletions
diff --git a/coregrind/m_initimg/.svn/text-base/initimg-aix5.c.svn-base b/coregrind/m_initimg/.svn/text-base/initimg-aix5.c.svn-base new file mode 100644 index 0000000..24ca1bc --- /dev/null +++ b/coregrind/m_initimg/.svn/text-base/initimg-aix5.c.svn-base @@ -0,0 +1,545 @@ + +/*--------------------------------------------------------------------*/ +/*--- Startup: create initial process image on AIX5 ---*/ +/*--- initimg-aix5.c ---*/ +/*--------------------------------------------------------------------*/ + +/* + This file is part of Valgrind, a dynamic binary instrumentation + framework. + + Copyright (C) 2006-2009 OpenWorks LLP + info@open-works.co.uk + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307, USA. + + The GNU General Public License is contained in the file COPYING. + + Neither the names of the U.S. Department of Energy nor the + University of California nor the names of its contributors may be + used to endorse or promote products derived from this software + without prior written permission. +*/ + +#include "pub_core_basics.h" +#include "pub_core_vki.h" +#include "pub_core_vkiscnums.h" +#include "pub_core_debuglog.h" +#include "pub_core_libcbase.h" +#include "pub_core_libcassert.h" +#include "pub_core_libcfile.h" +#include "pub_core_libcproc.h" +#include "pub_core_libcprint.h" +#include "pub_core_xarray.h" +#include "pub_core_clientstate.h" +#include "pub_core_aspacemgr.h" +#include "pub_core_mallocfree.h" +#include "pub_core_machine.h" +#include "pub_core_ume.h" +#include "pub_core_options.h" +#include "pub_core_threadstate.h" /* ThreadArchState */ +#include "pub_core_tooliface.h" /* VG_TRACK */ +#include "pub_core_trampoline.h" /* VG_(ppc32_aix5_do_preloads_then_start_client) */ +#include "pub_core_syscall.h" // VG_(do_syscall1) +#include "pub_core_initimg.h" /* self */ + +#include "simple_huffman.c" + +#if !defined(VGP_ppc32_aix5) && !defined(VGP_ppc64_aix5) +#error "This should only be compiled on AIX" +#endif + + +static void diagnose_load_failure ( void ); + +/* --- Create the client's initial memory image. --- */ + +IIFinaliseImageInfo VG_(ii_create_image)( IICreateImageInfo iicii ) +{ + /* Set up an AIX5PreloadPage structure with the names of + + $VALGRIND_LIB/vgpreload_core_PLATFORM.so + $VALGRIND_LIB/vgpreload_TOOL_PLATFORM.so, if it exists + xxx in "LD_PRELOAD=xxx", if it exists + + The client is started by running (on the simulator, of course) + VG_(ppc{32,64}_aix5_do_preloads_then_start_client), which uses + __loadx/_kload to load these .so's. When the preloading is + done, various guest registers are restored to what they are + really supposed to be at client startup, so these values too are + stored in the AIX5PreloadPage. Finally, we jump to the client's + entry point address. + */ + const HChar* _so = ".so"; + const HChar* vgpreload_ = "vgpreload_"; + const HChar* core = "core"; + const HChar* errmsg_str + = "valgrind: FATAL: core/tool/LD_PRELOAD= " + "preload failed.\n"; + Int plcore_len, pltool_len, ld_pre_len, errmsg_len; + HChar *plcore_str, *pltool_str, *ld_pre_str; + Bool have_tool_so, have_ld_pre; + + AIX5PreloadPage* pp; + UChar* pc; + Int szB, szPG; + SysRes sres; + + IIFinaliseImageInfo iifii; + VG_(memset)( &iifii, 0, sizeof(iifii) ); + + /* this can happen, if m_main decides to NULL it out */ + if (VG_(args_the_exename) == NULL) + VG_(err_missing_prog)(); + + vg_assert( iicii.toolname ); + pltool_len = VG_(strlen)( VG_(libdir) ) + + 1 /*slash*/ + + VG_(strlen)( vgpreload_ ) + + VG_(strlen)( iicii.toolname ) + + 1 /*dash*/ + + VG_(strlen)(VG_PLATFORM) + + VG_(strlen)( _so ) + + 1 /*NUL*/; + vg_assert(pltool_len > 0); + pltool_str = VG_(malloc)( "initimg-aix5.ici.1", pltool_len ); + pltool_str[0] = 0; + VG_(strcat)( pltool_str, VG_(libdir) ); + VG_(strcat)( pltool_str, "/" ); + VG_(strcat)( pltool_str, vgpreload_ ); + VG_(strcat)( pltool_str, iicii.toolname ); + VG_(strcat)( pltool_str, "-" ); + VG_(strcat)( pltool_str, VG_PLATFORM ); + VG_(strcat)( pltool_str, _so ); + vg_assert( pltool_str[pltool_len-1] == 0); + vg_assert( VG_(strlen)(pltool_str) == pltool_len-1 ); + + plcore_len = VG_(strlen)( VG_(libdir) ) + + 1 /*slash*/ + + VG_(strlen)( vgpreload_ ) + + VG_(strlen)( core ) + + 1 /*dash*/ + + VG_(strlen)(VG_PLATFORM) + + VG_(strlen)(_so) + + 1 /*NUL*/; + vg_assert(plcore_len > 0); + plcore_str = VG_(malloc)( "initimg-aix5.ici.2", plcore_len ); + plcore_str[0] = 0; + VG_(strcat)( plcore_str, VG_(libdir) ); + VG_(strcat)( plcore_str, "/" ); + VG_(strcat)( plcore_str, vgpreload_ ); + VG_(strcat)( plcore_str, core ); + VG_(strcat)( plcore_str, "-" ); + VG_(strcat)( plcore_str, VG_PLATFORM ); + VG_(strcat)( plcore_str, _so ); + vg_assert( plcore_str[plcore_len-1] == 0 ); + vg_assert( VG_(strlen)(plcore_str) == plcore_len-1 ); + + errmsg_len = VG_(strlen)( errmsg_str ) + + 1 /*NUL*/; + + ld_pre_str = VG_(getenv)("LD_PRELOAD"); + if (ld_pre_str && VG_(strlen)(ld_pre_str) > 0) { + have_ld_pre = True; + ld_pre_len = VG_(strlen)(ld_pre_str) + 1/*NUL*/; + ld_pre_str = VG_(malloc)( "initimg-aix5.ici.3", ld_pre_len ); + ld_pre_str[0] = 0; + VG_(strcat)( ld_pre_str, VG_(getenv)("LD_PRELOAD") ); + vg_assert( ld_pre_str[ld_pre_len-1] == 0); + vg_assert( VG_(strlen)( ld_pre_str ) == ld_pre_len - 1 ); + } else { + have_ld_pre = False; + ld_pre_len = 0; + ld_pre_str = NULL; + } + + VG_(debugLog)(1, "initimg", "plcore_str = '%s'\n", plcore_str ); + VG_(debugLog)(1, "initimg", "pltool_str = '%s'\n", pltool_str ); + VG_(debugLog)(1, "initimg", "ld_pre_str = '%s'\n", ld_pre_str ); + + if (0 != VG_(access)(plcore_str, True,False,True)) + VG_(err_config_error)("Can't find core preload " + "(vgpreload_core-<platform>.so)"); + + have_tool_so = 0 == VG_(access)(pltool_str, True,False,True); + + /* Figure out how much space is needed for an AIX5PreloadInfo + followed by the three preload strings. */ + + vg_assert((sizeof(AIX5PreloadPage) % 4) == 0); /* paranoia */ + + szB = sizeof(AIX5PreloadPage) + plcore_len + + (have_tool_so ? pltool_len : 0) + + (have_ld_pre ? ld_pre_len : 0) + + errmsg_len; + szPG = VG_PGROUNDUP(szB+1) / VKI_PAGE_SIZE; + VG_(debugLog)(2, "initimg", + "preload page size: %d bytes, %d pages\n", szB, szPG); + + vg_assert(szB > 0); + vg_assert(szB < szPG * VKI_PAGE_SIZE); + + /* We'll need szPG pages of anonymous, rw-, client space (needs w + so we can write it here) */ + sres = VG_(am_mmap_anon_float_client) + ( szPG * VKI_PAGE_SIZE, VKI_PROT_READ|VKI_PROT_WRITE); + if (sres.isError) + VG_(err_config_error)("Can't allocate client page(s) " + "for preload info"); + pp = (AIX5PreloadPage*)sres.res; + + VG_(debugLog)(2, "initimg", "preload page allocation succeeded at %p\n", pp); + + /* Zero out the initial structure. */ + VG_(memset)(pp, 0, sizeof(AIX5PreloadPage)); + + pc = (UChar*)pp; + pc += sizeof(AIX5PreloadPage); + VG_(memcpy)(pc, plcore_str, plcore_len); + pp->off_preloadcorename = pc - (UChar*)pp; + pc += plcore_len; + if (have_tool_so) { + VG_(memcpy)(pc, pltool_str, pltool_len); + pp->off_preloadtoolname = pc - (UChar*)pp; + pc += pltool_len; + } + if (have_ld_pre) { + VG_(memcpy)(pc, ld_pre_str, ld_pre_len); + pp->off_ld_preloadname = pc - (UChar*)pp; + pc += ld_pre_len; + } + VG_(memcpy)(pc, errmsg_str, errmsg_len); + pp->off_errmsg = pc - (UChar*)pp; + pp->len_errmsg = errmsg_len - 1; /* -1: skip terminating NUL */ + + vg_assert(pc <= ((UChar*)pp) - 1 + szPG * VKI_PAGE_SIZE); + + VG_(free)(plcore_str); + VG_(free)(pltool_str); + + /* Fill in all the other preload page fields that we can right + now. */ +# if defined(VGP_ppc32_aix5) + vg_assert(__NR_AIX5___loadx != __NR_AIX5_UNKNOWN); + pp->nr_load = __NR_AIX5___loadx; +# else /* defined(VGP_ppc64_aix5) */ + vg_assert(__NR_AIX5_kload != __NR_AIX5_UNKNOWN); + pp->nr_load = __NR_AIX5_kload; +# endif + + vg_assert(__NR_AIX5_kwrite != __NR_AIX5_UNKNOWN); + pp->nr_kwrite = __NR_AIX5_kwrite; /* kwrite */ + + vg_assert(__NR_AIX5__exit != __NR_AIX5_UNKNOWN); + pp->nr__exit = __NR_AIX5__exit; /* _exit */ + + pp->p_diagnose_load_failure = &diagnose_load_failure; + + iifii.preloadpage = pp; + iifii.intregs37 = iicii.intregs37; + iifii.initial_client_SP = iicii.intregs37[1]; /* r1 */ + iifii.compressed_page = VG_PGROUNDDN((Addr)iicii.bootblock); + iifii.adler32_exp = iicii.adler32_exp; + iifii.clstack_max_size = 0; /* we don't know yet */ + return iifii; +} + + +/* --- Finalise the initial image and register state. --- */ + +static UChar unz_page[VKI_PAGE_SIZE]; + +static UInt compute_adler32 ( void* addr, UWord len ) +{ + UInt s1 = 1; + UInt s2 = 0; + UChar* buf = (UChar*)addr; + while (len > 0) { + s1 += buf[0]; + s2 += s1; + s1 %= 65521; + s2 %= 65521; + len--; + buf++; + } + return (s2 << 16) + s1; +} + +/* Just before starting the client, we may need to make final + adjustments to its initial image. Also we need to set up the VEX + guest state for thread 1 (the root thread) and copy in essential + starting values. This is handed the IIFinaliseImageInfo created by + VG_(ii_create_image). +*/ +void VG_(ii_finalise_image)( IIFinaliseImageInfo iifii ) +{ + UInt adler32_act; + SysRes sres; + /* On AIX we get a block of 37 words telling us the initial state + for (GPR0 .. GPR31, PC, CR, LR, CTR, XER), and we start with all + the other registers zeroed. */ + + ThreadArchState* arch = &VG_(threads)[1].arch; + +# if defined(VGP_ppc32_aix5) + + vg_assert(0 == sizeof(VexGuestPPC32State) % 16); + + /* Zero out the initial state, and set up the simulated FPU in a + sane way. */ + LibVEX_GuestPPC32_initialise(&arch->vex); + + /* Zero out the shadow areas. */ + VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestPPC32State)); + VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestPPC32State)); + +# else /* defined(VGP_ppc64_aix5) */ + + vg_assert(0 == sizeof(VexGuestPPC64State) % 16); + + /* Zero out the initial state, and set up the simulated FPU in a + sane way. */ + LibVEX_GuestPPC64_initialise(&arch->vex); + + /* Zero out the shadow areas. */ + VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestPPC64State)); + VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestPPC64State)); + +# endif + + /* iifii.intregs37 contains the integer register state as it needs + to be at client startup. These values are supplied by the + launcher. The 37 regs are:initial values from launcher for: + GPR0 .. GPR31, PC, CR, LR, CTR, XER. */ + + /* Put essential stuff into the new state. */ + arch->vex.guest_GPR0 = (UWord)iifii.intregs37[0]; + arch->vex.guest_GPR1 = (UWord)iifii.intregs37[1]; + arch->vex.guest_GPR2 = (UWord)iifii.intregs37[2]; + arch->vex.guest_GPR3 = (UWord)iifii.intregs37[3]; + arch->vex.guest_GPR4 = (UWord)iifii.intregs37[4]; + arch->vex.guest_GPR5 = (UWord)iifii.intregs37[5]; + arch->vex.guest_GPR6 = (UWord)iifii.intregs37[6]; + arch->vex.guest_GPR7 = (UWord)iifii.intregs37[7]; + arch->vex.guest_GPR8 = (UWord)iifii.intregs37[8]; + arch->vex.guest_GPR9 = (UWord)iifii.intregs37[9]; + arch->vex.guest_GPR10 = (UWord)iifii.intregs37[10]; + arch->vex.guest_GPR11 = (UWord)iifii.intregs37[11]; + arch->vex.guest_GPR12 = (UWord)iifii.intregs37[12]; + arch->vex.guest_GPR13 = (UWord)iifii.intregs37[13]; + arch->vex.guest_GPR14 = (UWord)iifii.intregs37[14]; + arch->vex.guest_GPR15 = (UWord)iifii.intregs37[15]; + arch->vex.guest_GPR16 = (UWord)iifii.intregs37[16]; + arch->vex.guest_GPR17 = (UWord)iifii.intregs37[17]; + arch->vex.guest_GPR18 = (UWord)iifii.intregs37[18]; + arch->vex.guest_GPR19 = (UWord)iifii.intregs37[19]; + arch->vex.guest_GPR20 = (UWord)iifii.intregs37[20]; + arch->vex.guest_GPR21 = (UWord)iifii.intregs37[21]; + arch->vex.guest_GPR22 = (UWord)iifii.intregs37[22]; + arch->vex.guest_GPR23 = (UWord)iifii.intregs37[23]; + arch->vex.guest_GPR24 = (UWord)iifii.intregs37[24]; + arch->vex.guest_GPR25 = (UWord)iifii.intregs37[25]; + arch->vex.guest_GPR26 = (UWord)iifii.intregs37[26]; + arch->vex.guest_GPR27 = (UWord)iifii.intregs37[27]; + arch->vex.guest_GPR28 = (UWord)iifii.intregs37[28]; + arch->vex.guest_GPR29 = (UWord)iifii.intregs37[29]; + arch->vex.guest_GPR30 = (UWord)iifii.intregs37[30]; + arch->vex.guest_GPR31 = (UWord)iifii.intregs37[31]; + + arch->vex.guest_CIA = (UWord)iifii.intregs37[32+0]; + arch->vex.guest_LR = (UWord)iifii.intregs37[32+2]; + arch->vex.guest_CTR = (UWord)iifii.intregs37[32+3]; + +# if defined(VGP_ppc32_aix5) + + LibVEX_GuestPPC32_put_CR( (UWord)iifii.intregs37[32+1], &arch->vex ); + LibVEX_GuestPPC32_put_XER( (UWord)iifii.intregs37[32+4], &arch->vex ); + + /* Set the cache line size (KLUDGE) */ + VG_(machine_ppc32_set_clszB)( 128 ); + +# else /* defined(VGP_ppc64_aix5) */ + + LibVEX_GuestPPC64_put_CR( (UWord)iifii.intregs37[32+1], &arch->vex ); + LibVEX_GuestPPC64_put_XER( (UWord)iifii.intregs37[32+4], &arch->vex ); + + /* Set the cache line size (KLUDGE) */ + VG_(machine_ppc64_set_clszB)( 128 ); + +# endif + + /* Fix up the client's command line. Its argc/v/envp is in r3/4/5 + (32-bit AIX) or r14/15/16 (64-bit AIX). but that is for the + Valgrind invokation as a whole. Hence we need to decrement argc + and advance argv to step over the args for Valgrind, and the + name of the Valgrind tool exe bogusly inserted by the launcher + (hence the "+1"). */ + +# if defined(VGP_ppc32_aix5) + + { UWord n_vargs = VG_(sizeXA)( VG_(args_for_valgrind) ); + vg_assert(arch->vex.guest_GPR3 >= 1 + n_vargs); + arch->vex.guest_GPR3 -= (1 + n_vargs); + arch->vex.guest_GPR4 += sizeof(UWord) * (1 + n_vargs); + } + +# else /* defined(VGP_ppc64_aix5) */ + + { UWord n_vargs = VG_(sizeXA)( VG_(args_for_valgrind) ); + vg_assert(arch->vex.guest_GPR14 >= 1 + n_vargs); + arch->vex.guest_GPR14 -= (1 + n_vargs); + arch->vex.guest_GPR15 += sizeof(UWord) * (1 + n_vargs); + } + +# endif + + /* At this point the guest register state is correct for client + startup. However, that's not where we want to start; in fact we + want to start at VG_(ppc{32,64}_aix5_do_preloads_then_start_client), + passing it iifii.preloadpage in r3. This will load the core/tool + preload .so's, then restore r2-r10 from what's stashed in the + preloadpage, and then start the client really. Hence: */ + + /* Save r2-r10 and the client start point in preloadpage */ + iifii.preloadpage->r2 = (ULong)arch->vex.guest_GPR2; + iifii.preloadpage->r3 = (ULong)arch->vex.guest_GPR3; + iifii.preloadpage->r4 = (ULong)arch->vex.guest_GPR4; + iifii.preloadpage->r5 = (ULong)arch->vex.guest_GPR5; + iifii.preloadpage->r6 = (ULong)arch->vex.guest_GPR6; + iifii.preloadpage->r7 = (ULong)arch->vex.guest_GPR7; + iifii.preloadpage->r8 = (ULong)arch->vex.guest_GPR8; + iifii.preloadpage->r9 = (ULong)arch->vex.guest_GPR9; + iifii.preloadpage->r10 = (ULong)arch->vex.guest_GPR10; + iifii.preloadpage->client_start = (ULong)arch->vex.guest_CIA; + + +# if defined(VGP_ppc32_aix5) + + /* Set up to start at VG_(ppc32_aix5_do_preloads_then_start_client) */ + arch->vex.guest_CIA = (UWord)&VG_(ppc32_aix5_do_preloads_then_start_client); + +# else /* defined(VGP_ppc64_aix5) */ + + /* Set up to start at VG_(ppc64_aix5_do_preloads_then_start_client) */ + arch->vex.guest_CIA = (UWord)&VG_(ppc64_aix5_do_preloads_then_start_client); + +# endif + + arch->vex.guest_GPR3 = (UWord)iifii.preloadpage; + + /* The rest of the preloadpage fields will already have been filled + in by VG_(setup_client_initial_image). So we're done. */ + + /* Finally, decompress the page compressed by the launcher. We + can't do this any earlier, because the page is (effectively) + decompressed in place, which trashes iifii.intregs37. So we have + to wait till this point, at which we're done with iifii.intregs37 + (to be precise, with what it points at). */ + VG_(debugLog)(1, "initimg", "decompressing page at %p\n", + (void*)iifii.compressed_page); + vg_assert(VG_IS_PAGE_ALIGNED(iifii.compressed_page)); + + Huffman_Uncompress( (void*)iifii.compressed_page, unz_page, + VKI_PAGE_SIZE, VKI_PAGE_SIZE ); + adler32_act = compute_adler32(unz_page, VKI_PAGE_SIZE); + + VG_(debugLog)(1, "initimg", + "decompress done, adler32s: act 0x%x, exp 0x%x\n", + adler32_act, iifii.adler32_exp ); + + VG_(memcpy)((void*)iifii.compressed_page, unz_page, VKI_PAGE_SIZE); + + VG_(debugLog)(1, "initimg", "copy back done\n"); + + /* Tell the tool that we just wrote to the registers. */ + VG_TRACK( post_reg_write, Vg_CoreStartup, /*tid*/1, /*offset*/0, + sizeof(VexGuestArchState)); + + /* Determine the brk limit. */ + VG_(debugLog)(1, "initimg", "establishing current brk ..\n"); + vg_assert(__NR_AIX5_sbrk != __NR_AIX5_UNKNOWN); + sres = VG_(do_syscall1)(__NR_AIX5_sbrk, 0); + vg_assert(sres.err == 0); /* assert no error */ + VG_(brk_base) = VG_(brk_limit) = sres.res; + VG_(debugLog)(1, "initimg", ".. brk = %p\n", (void*)VG_(brk_base)); +} + + +/* --- Diagnose preload failures. --- */ + +/* This is a nasty but effective kludge. The address of the following + function is put into the preload page. So, if a preload failure + happens, we call here to get helpful info printed out (the call + site is in m_trampoline.S). This is a dirty hack (1) because + diagnose_load_failure runs on the simulated CPU, not the real one + and (2) because it induces a libc dependency. Oh well. */ + +/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */ +#include <stdlib.h> +#include <sys/ldr.h> +/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */ + +static void diagnose_load_failure ( void ) +{ +# define NBUF 1024 + UChar buf[NBUF]; + VG_(debugLog)(0, "initimg", "Diagnosing load failure\n"); + if (sizeof(void*) == 8) { + VG_(debugLog)(0, "initimg", "Can't safely do loadquery() " + "in 64-bit mode. Sorry.\n"); + /* because this requires dynamic linking to be working (IIRC) + and it isn't; the tool file's dynamic linking was never done, + because it was loaded by the bootstrap stub, which simply did + sys_kload() but didn't make usla do the relevant + relocations. */ + } else { + UChar** p; + Int r = loadquery(L_GETMESSAGES, buf, NBUF); + VG_(debugLog)(0, "initimg", "loadquery returned %d (0 = success)\n", r); + p = (UChar**)(&buf[0]); + for (; *p; p++) + VG_(debugLog)(0, "initimg", "\"%s\"\n", *p); + VG_(debugLog)(0, "initimg", "Use /usr/sbin/execerror to make " + "sense of above string(s)\n"); + VG_(debugLog)(0, "initimg", "See also comments at the bottom of\n"); + VG_(debugLog)(0, "initimg", "coregrind/m_initimg/" + "initimg-aix5.c (in Valgrind sources)\n"); + } +# undef NBUF +} + +/* Take the strings that this prints out and feed them + to /usr/sbin/execerror. For example, it might print + + (ld 3 1 __libc_freeres /foo/bar/vgpreload_core-ppc32-aix5.so + + in which case + + $ execerror xyzzy \ + "(ld 3 1 __libc_freeres /foo/bar/vgpreload_core-ppc32-aix5.so" + + gets you + + Could not load program xyzzy: + rtld: 0712-001 Symbol __libc_freeres was referenced + from module /foo/bar/vgpreload_core-ppc32-aix5.so(), + but a runtime definition + of the symbol was not found. +*/ + +/*--------------------------------------------------------------------*/ +/*--- initimg-aix5.c ---*/ +/*--------------------------------------------------------------------*/ |