2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License, Version 1.0 only 2N/A * (the "License"). You may not use this file except in compliance 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 2N/A * Use is subject to license terms. 2N/A#
pragma ident "%Z%%M% %I% %E% SMI" 2N/A * VERSION FOR MACHINES WITH STACKS GROWING DOWNWARD IN MEMORY 2N/A * On program entry, the top of the stack frame looks like this: 2N/A * hi: |-----------------------| 2N/A * |-----------------------|+ 2N/A * | arg and env strings | > no more than NCARGS bytes 2N/A * |-----------------------|+ 2N/A * |-----------------------| 2N/A * | null auxiliary vector | 2N/A * |-----------------------| 2N/A * | auxiliary vector | 2N/A * | (2-word entries) | 2N/A * |-----------------------| 2N/A * |-----------------------| 2N/A * | ptrs to env strings | 2N/A * |-----------------------| 2N/A * |-----------------------| 2N/A * | ptrs to arg strings | 2N/A * | (argc = # of ptrs) | 2N/A * |-----------------------| 2N/A * low: |-----------------------| 2N/A#
define RoundUp(v, t) (((v) +
sizeof (t) -
1) & ~(
sizeof (t) -
1))
2N/A * Bring the entire stack into memory first, size it 2N/A * as an LP64 user stack, then allocate and copy into 2N/A * the buffer(s) to be returned to the caller. 2N/A * Find the interesting sizes of a 32-bit stack. 2N/A auxc++;
/* terminating AT_NULL record */ 2N/A * Compute the sizes of the stuff we're going to allocate or copy. 2N/A * Walk up the 32-bit stack, filling in the 64-bit argv and envp 2N/A * auxiliary vector (skip it..) 2N/A * Copy the string pool, untranslated 2N/A * Relocate the pointers to point at the newly allocated space. 2N/A * Use the same algorithms as kvm_getcmd to handle naughty 2N/A * changes to the argv and envp arrays. 2N/A#
endif /* _LP64 || lint */ 2N/A * reconstruct an argv-like argument list from the target process 2N/A * Protect against proc structs found by kvm_nextproc() 2N/A * while the kernel was doing a fork(). Such a proc struct 2N/A * may have p_usrstack set but a still zeroed uarea. 2N/A * We wouldn't want to unecessarily allocate 4GB memory ... 2N/A * If this is a 32-bit process running on a 64-bit system, 2N/A * then the stack is laid out using ILP32 pointers, not LP64. 2N/A * To minimize potential confusion, we blow it up to "LP64 2N/A * shaped" right here. 2N/A * Space for the stack, from the argument vector. An additional 2N/A * word is added to guarantee a NULL word terminates the buffer. 2N/A * Space for the stack, from the environment vector. An additional 2N/A * word is added to guarantee a NULL word terminates the buffer. 2N/A /* read the whole initial stack */ 2N/A * Copy it to the malloc()d space for the envp array 2N/A /* read most of the initial stack (excluding argv) */ 2N/A * Relocate and sanity check the argv array. Entries which have 2N/A * been explicity nulled are left that way. Entries which have 2N/A * been replaced are pointed to a null string. Well behaved apps 2N/A * don't do any of this. 2N/A /* relocate the argv[] addresses */ 2N/A * Relocate and sanity check the envp array. A null entry indicates 2N/A * the end of the environment. Entries which point outside of the 2N/A * initial stack are replaced with what must have been the initial 2N/A * value based on the known ordering of the string table by the 2N/A * kernel. If stack corruption prevents the calculation of the 2N/A * location of an initial string value, a pointer to a null string 2N/A * is returned. To return a null pointer would prematurely terminate 2N/A * the list. Well behaved apps do set pointers outside of the 2N/A * initial stack via the putenv(3C) library routine. 2N/A * Determine the start of the environment strings as one 2N/A * past the last argument string. 2N/A * Relocate the envp[] addresses, while ensuring that we 2N/A * don't return bad addresses.