diff options
| author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
|---|---|---|
| committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
| commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
| tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/amt | |
| download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz | |
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/amt')
| -rw-r--r-- | usr/src/cmd/amt/Makefile | 75 | ||||
| -rw-r--r-- | usr/src/cmd/amt/Makefile.com | 60 | ||||
| -rw-r--r-- | usr/src/cmd/amt/amd64/Makefile | 34 | ||||
| -rw-r--r-- | usr/src/cmd/amt/amt.c | 748 | ||||
| -rw-r--r-- | usr/src/cmd/amt/amt.sh | 44 | ||||
| -rw-r--r-- | usr/src/cmd/amt/i386/Makefile | 34 | ||||
| -rw-r--r-- | usr/src/cmd/amt/sparcv9/Makefile | 35 |
7 files changed, 1030 insertions, 0 deletions
diff --git a/usr/src/cmd/amt/Makefile b/usr/src/cmd/amt/Makefile new file mode 100644 index 0000000000..dfb4536724 --- /dev/null +++ b/usr/src/cmd/amt/Makefile @@ -0,0 +1,75 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +#ident "%Z%%M% %I% %E% SMI" +# +# Copyright 2003 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# cmd/amt/Makefile +# + +PROG= amt + +include ../Makefile.cmd + +TEXT_DOMAIN=SUNW_OST_OSCMD +POFILE=$(PROG).po + +$(64ONLY)SUBDIRS= $(MACH) +$(BUILD64)SUBDIRS += $(MACH64) +CLEANFILES += $(POFILE) + +SHFILERCS= $(PROG:%=%.sh) + +all := TARGET = all +install := TARGET = install +clean := TARGET = clean +clobber := TARGET = clobber +lint := TARGET = lint + +.KEEP_STATE: + +all: $(SUBDIRS) pofile $(PROG) + +clean clobber lint: $(SUBDIRS) + +install: $(SUBDIRS) $(ROOTPROG) + +pofile: $(POFILE) + +$(PROG): $(PROG).sh + $(RM) -f $(PROG) + $(CP) $(PROG).sh $(PROG) + $(CHMOD) 555 $(PROG) + +$(POFILE): $(SRCS) + $(RM) $(TEXT_DOMAIN).po + $(XGETTEXT) -s -d $(TEXT_DOMAIN) $< + $(MV) $(TEXT_DOMAIN).po $@ + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + +include ../Makefile.targ diff --git a/usr/src/cmd/amt/Makefile.com b/usr/src/cmd/amt/Makefile.com new file mode 100644 index 0000000000..d3519687af --- /dev/null +++ b/usr/src/cmd/amt/Makefile.com @@ -0,0 +1,60 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +#ident "%Z%%M% %I% %E% SMI" +# +# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# cmd/amt/Makefile.com +# + +PROG= amt +OBJS= amt.o +SRCS= $(OBJS:%.o=../%.c) + +include ../../Makefile.cmd + +LDLIBS += -lelf + +LINTFLAGS += -erroff=E_NAME_USED_NOT_DEF2 +LINTFLAGS64 += -erroff=E_NAME_USED_NOT_DEF2 + +CLEANFILES += $(PROG) $(OBJS) + +.KEEP_STATE: + +all: $(PROG) + +$(PROG): $(OBJS) + $(LINK.c) $(OBJS) -o $@ $(LDLIBS) + $(POST_PROCESS) + +lint: lint_SRCS + +%.o: ../%.c + $(COMPILE.c) $< + +clean: + $(RM) $(CLEANFILES) + +include ../../Makefile.targ diff --git a/usr/src/cmd/amt/amd64/Makefile b/usr/src/cmd/amt/amd64/Makefile new file mode 100644 index 0000000000..2a65ac9ed3 --- /dev/null +++ b/usr/src/cmd/amt/amd64/Makefile @@ -0,0 +1,34 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# ident "%Z%%M% %I% %E% SMI" +# + +.KEEP_STATE: + +include ../Makefile.com +include ../../Makefile.cmd.64 + +install: $(PROG) $(ROOTPROG64) diff --git a/usr/src/cmd/amt/amt.c b/usr/src/cmd/amt/amt.c new file mode 100644 index 0000000000..8c4cfdbe29 --- /dev/null +++ b/usr/src/cmd/amt/amt.c @@ -0,0 +1,748 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Abstract Machine Test; executes memory access tests to show + * compliance with Common Criteria object reuse and process address + * space separation requirements. + */ +#include <errno.h> +#include <fcntl.h> +#include <iso/stdlib_iso.h> +#include <libelf.h> +#include <libintl.h> +#include <locale.h> +#include <signal.h> +#include <stdio.h> +#include <string.h> +#include <sys/param.h> +#include <sys/resource.h> +#include <sys/sysmacros.h> +#include <sys/types.h> +#include <unistd.h> +#include <wait.h> + +#define NOT_SILENT 0 +#define SILENT_MODE 1 + +#define CHILD_SLEEP_PERIOD 2 +#define PARENT_SLEEP_PERIOD 1 +#define SIG_EVENT SIGUSR1 + +#define PASS 0 /* test passed, no SEGV */ +#define FAIL_ZERO 1 /* expected to read zero, didn't */ +#define FAIL_SEGV 2 /* expected good read or write, didn't */ +#define PASS_SEGV 3 /* expected SEGV, got it */ +#define FAIL_ABORT 4 /* test logic error */ + +#define PH_VALID 0 /* arg for probe_hole -- do valid memory */ + /* access */ +#define PH_INVALID 1 /* do illegal memory access */ + +#define WASTE_PAGES 8 /* a guess at where virgin stack space */ + /* is likely to exist */ +#define STACK_SLOP 256 /* a guess at how far below current end */ + /* of stack I'll find unused space */ + +#if !defined(TEXT_DOMAIN) +#define TEXT_DOMAIN "SYS_TEST" +#endif + +extern int _end; /* first address after the end of initialized data */ + +static int data_boundary_test(); +static void handler(int); +static int memory_not_shared_after_use(); +static int memory_allocation_not_shared(); +static int memory_type(const char *); +static void print_message(char *); +static void probe_data_area(void); +static void probe_hole(int); +static void probe_stack(void); +static void probe_text_area(void); +static void segv_action(int, siginfo_t *, void *); +static void set_handler(int); +static int test_stack_end_of_hole(); +static int text_area_not_writeable(); + +static int done_memory_grab = 0; +static int silent; +static int handler_exit_code; + +/* + * Main Routine + */ +int +main(int argc, char *argv[]) +{ + int fail_count = 0; + int status = 0; + int bitsize; + + /* Internationalization */ + (void) setlocale(LC_ALL, ""); + (void) textdomain(TEXT_DOMAIN); + + silent = NOT_SILENT; + + if (argc == 2) { + /* Pull out argument provided */ + /* -s silent mode, no status or error messages. */ + if (strncmp(argv[1], "-s", 4) == 0) + silent = SILENT_MODE; + else { + /* Wrong argument */ + (void) fprintf(stderr, gettext( + "Wrong argument, USAGE: amt [-s]\n")); + exit(EXIT_FAILURE); + } + } else if (argc != 1) { + /* Illegal number of arguments. */ + (void) fprintf(stderr, gettext( + "Wrong usage, USAGE: amt [-s]\n")); + exit(EXIT_FAILURE); + } + bitsize = memory_type(argv[0]); + + if (silent == NOT_SILENT) + (void) printf(gettext( + "\n\nAMT Test Program -- %d bit application\n" + "================\n"), bitsize); + /* + * test_stack_end_of_hole must be the first test, or the stack + * is of an unknown size. + */ + if ((status = test_stack_end_of_hole()) == EXIT_FAILURE) { + /* Normal fail */ + fail_count++; + print_message(gettext("TEST 1 FAILED\n")); + } else if (status == FAIL_ABORT) { + /* Test logic failure */ + fail_count++; + print_message(gettext("FAIL: Logic error in test\n")); + } else if (status == EXIT_SUCCESS) + print_message(gettext("TEST 1 PASSED\n")); + + /* Carry out test 2 */ + if (data_boundary_test() != EXIT_SUCCESS) { + fail_count++; + print_message(gettext("TEST 2 FAILED\n")); + } else + print_message(gettext("TEST 2 PASSED\n")); + + /* Carry out test 3 */ + if (text_area_not_writeable() != EXIT_SUCCESS) { + fail_count++; + print_message(gettext("TEST 3 FAILED\n")); + } else + print_message(gettext("TEST 3 PASSED\n")); + + /* Carry out test 4 */ + if (memory_not_shared_after_use() != EXIT_SUCCESS) { + fail_count++; + print_message(gettext("TEST 4 FAILED\n")); + } else + print_message(gettext("TEST 4 PASSED\n")); + + /* Carry out test 5 */ + if (memory_allocation_not_shared() != EXIT_SUCCESS) { + fail_count++; + print_message(gettext("TEST 5 FAILED\n")); + } else + print_message(gettext("TEST 5 PASSED\n")); + + if (silent == NOT_SILENT) { + if (fail_count > 0) + (void) printf(gettext("\n %d TESTS FAILED\n\n"), + fail_count); + else + (void) printf(gettext("\nTESTS SUCCEEDED\n\n")); + } + return (fail_count); +} + +/* + * Test the data boundaries. First test inside the data area at the boundary + * of the "hole" area. Second test inside the data area at the text area + * boundary. Both should pass. + */ +static int +data_boundary_test() +{ + int exit_status = EXIT_SUCCESS; + pid_t pid; + int status; + + print_message(gettext("\n\nTest 2- Data Side Boundary Test.\n")); + + if ((pid = fork()) == -1) { + print_message(gettext("Fork failed\n")); + return (EXIT_FAILURE); + } else if (pid == 0) { /* Am I my child? */ + set_handler(SIGSEGV); + + /* probe_data_area() does exit() */ + probe_data_area(); + } + /* still parent */ + (void) wait(&status); + status = WEXITSTATUS(status); + + if (status == PASS) + print_message(gettext( + "PASS: Successful read/write in data area.\n")); + else if (status == FAIL_SEGV) { + print_message(gettext( + "FAIL: Caught a segmentation fault while " + "attempting to write to the data area.\n")); + exit_status = EXIT_FAILURE; + } else { + (void) printf(gettext("Test program failure: %d\n"), + status); + exit_status = EXIT_FAILURE; + } + return (exit_status); +} + +static void +probe_data_area() +{ + int *p; + /* LINTED */ + volatile int p1; + void *address; + + /* set handler status */ + handler_exit_code = FAIL_SEGV; + + /* + * Get an address in the data area, near to the "hole". + * sbrk returns prior address value; rather than calculating + * the sbrk result, sbrk is called twice, so address points + * to the new end of data + */ + (void) sbrk(PAGESIZE); + address = sbrk(0); + /* + * Get to the inside edge of a page boundary + * two integer words short of a new page + */ + p = ((int *)P2ROUNDUP((uintptr_t)address, PAGESIZE)) - 2; + + /* Try writing to it, shouldn't cause a segmentation fault. */ + *p = 9999; + + /* Should be able to read back with no problems. */ + p1 = *p; + + /* + * Get an address near the text area boundary, but in the data + * area. _etext rounded up a page isn't correct since the + * initialized data area isn't writeable. + * + * Future versions should consider handling initialized data + * separately -- writing to initialized data should generate + * a fault. + */ + p = &_end; + + /* Try writing to it, should succeed. */ + *p = 9898; + + /* Should be able to read back with no problems. */ + p1 = *p; + + exit(EXIT_SUCCESS); +} + +/* + * Test that we cannot write to the text area. An attempt to write to + * the text area will result in a segmentation fault. So if we catch it, + * test has succeed, else it has failed. + */ +static int +text_area_not_writeable() +{ + int exit_status = EXIT_SUCCESS; + pid_t pid; + int status; + + print_message(gettext( + "\n\nTest 3- Text Area Not Writeable\n" + "Verify that a write to the text space does not cause " + "a write to the executable\n" + "file from which it came, or to another process which " + "shares that text.\n")); + + if ((pid = fork()) == -1) { + print_message(gettext("Fork failed\n")); + return (EXIT_FAILURE); + } else if (pid == 0) { /* Am I my child? */ + set_handler(SIGSEGV); + + /* probe_text_area() does exit() */ + probe_text_area(); + } + /* still parent */ + (void) wait(&status); + status = WEXITSTATUS(status); + + if (status == PASS) { + print_message(gettext( + "FAIL: We did not cause a segmentation fault.\n")); + exit_status = EXIT_FAILURE; + } else if (status == FAIL_SEGV) { + print_message(gettext( + "PASS: Caught the segmentation fault, " + "meaning we can't write to text area.\n")); + } else { + (void) printf(gettext( + "Test program failure: %d\n"), status); + exit_status = EXIT_FAILURE; + } + return (exit_status); +} + +/* + * write to text area, trigger a SEGV + */ +static void +probe_text_area() +{ + handler_exit_code = FAIL_SEGV; + *(caddr_t)probe_text_area = 0xff; + exit(EXIT_FAILURE); +} + +/* + * Test that when we set some values and fork a process, when the child + * writes to these inherited values, the parents copies are not changed. + */ +static int +memory_not_shared_after_use() +{ + pid_t pid; + int x = 1000; + int exit_status = EXIT_SUCCESS; + + print_message(gettext("\n\nTest 4- Memory Not Shared After Write\n" + "Verify that anonymous memory initially shared by two " + "processes (e.g. after a\n" + "fork) is not shared after either process writes " + "to it.\n")); + + if ((pid = fork()) == -1) { + print_message(gettext("Fork failed\n")); + return (EXIT_FAILURE); + } else if (pid == 0) { /* I am the child. */ + /* + * Change child value; this should not change + * parent value. + */ + x = 2000; + + /* Wait for parent to test value */ + (void) sleep(CHILD_SLEEP_PERIOD); + + exit(EXIT_SUCCESS); + } + /* Wait for child to do its stuff. */ + (void) sleep(PARENT_SLEEP_PERIOD); + + if (x == 1000) + exit_status = EXIT_SUCCESS; + else + exit_status = EXIT_FAILURE; + + return (exit_status); +} + +/* + * If we fork a process and then allocate some memory in that process, + * we should not see any memory changes in the parent. + */ +static int +memory_allocation_not_shared() +{ + pid_t pid; + pid_t parent_pid; + int exit_status = 0; + caddr_t address; + caddr_t hole_start; + caddr_t hole_after; + void (*old_handler) (); + + print_message(gettext( + "\n\nTest 5- Memory Allocation is Not Shared\n" + "Verify that newly allocated memory in one of two " + "processes created by forking\n" + "does not result in newly allocated memory in the other.\n")); + + /* Save Size of data area and 1st block address of "hole" */ + hole_start = (caddr_t)sbrk(0); + + if (silent == NOT_SILENT) + (void) printf(gettext( + "Parent address of hole before child change: %08X\n"), + hole_start); + + /* Set handler for signal SIG_EVENT (define at start) */ + old_handler = signal(SIG_EVENT, &handler); + if (old_handler == SIG_ERR) { + print_message(gettext( + "Can't establish signal handler, test failed\n")); + return (EXIT_FAILURE); + } + + if ((pid = fork()) == -1) { + print_message(gettext("Fork failed\n")); + return (EXIT_FAILURE); + } else if (pid == 0) { /* We are the child. */ + address = sbrk(0); + if (silent == NOT_SILENT) + (void) printf(gettext( + "Child end of hole before change: %08X\n"), + address); + + if (brk((address+PAGESIZE)) != 0) { + print_message(gettext( + "Can't change start of hole address.\n")); + exit(EXIT_FAILURE); + } + + address = sbrk(0); + if (silent == NOT_SILENT) + (void) printf(gettext( + "Child end of hole after change: %08X\n"), + address); + + /* Tell the parent we're done. */ + parent_pid = getppid(); + if (sigsend(P_PID, parent_pid, SIG_EVENT) != 0) { + print_message(gettext("Can't send signal to parent, " + "test failed\n")); + exit(EXIT_FAILURE); + } + + /* Sleep before exiting to allow parent to finish processing. */ + (void) sleep(CHILD_SLEEP_PERIOD); + exit(EXIT_SUCCESS); + } + /* Wait for child to do its work. */ + (void) sleep(PARENT_SLEEP_PERIOD); + + if (done_memory_grab != 1) { + print_message(gettext( + "Child failed to do memory alterations, " + "exiting\n")); + return (EXIT_FAILURE); + } + + hole_after = sbrk(0); + if (silent == NOT_SILENT) + (void) printf(gettext( + "Parent address of hole after child change: " + "%08X\n"), hole_after); + + /* Test size of hole and data region. */ + if (hole_start == hole_after) + print_message(gettext( + "PASS: Hole is same size in parent.\n")); + else { + print_message(gettext( + "FAIL: Hole is a different size.\n")); + exit_status = EXIT_FAILURE; + } + + /* Wait for child to finish. */ + (void) wait(0); + + if (signal(SIG_EVENT, old_handler) == SIG_ERR) { + print_message(gettext("Couldn't put back old signal handler, " + "test failed.\n")); + return (EXIT_FAILURE); + } + return (exit_status); +} + +static void +print_message(char *message) +{ + if (silent == NOT_SILENT) + (void) printf("%s", message); +} + +static int +test_stack_end_of_hole() +{ + pid_t pid; + int status; + int exit_status = EXIT_SUCCESS; + + print_message(gettext("\n\nTest 1- stack Side Boundary Test\n")); + + /* sub test 1: the space the stack grows into is zero */ + + if ((pid = fork()) == -1) { + print_message(gettext("Fork failed\n")); + return (EXIT_FAILURE); + } else if (pid == 0) { /* Am I my child? */ + set_handler(SIGSEGV); + + /* probe_stack() does exit */ + probe_stack(); + } + /* still parent */ + (void) wait(&status); + status = WEXITSTATUS(status); + + if (status == FAIL_ZERO) { + print_message(gettext("Fail with non-zero read.\n")); + exit_status = EXIT_FAILURE; + } else if (status != PASS) { + print_message(gettext("Test program failure\n")); + exit_status = EXIT_FAILURE; + } + /* sub test 2: the space in hole is not readable */ + + if ((pid = fork()) == -1) { + print_message(gettext("Fork failed\n")); + return (EXIT_FAILURE); + } else if (pid == 0) { /* Am I my child? */ + set_handler(SIGSEGV); + + /* probe_hole does exit */ + probe_hole(PH_INVALID); + } + /* still parent */ + (void) wait(&status); + status = WEXITSTATUS(status); + + if (status == FAIL_SEGV) { + print_message( + gettext("Fail (SEGV expected, not received).\n")); + exit_status = EXIT_FAILURE; + } else if (status != PASS_SEGV) { + print_message(gettext("Test program failure.\n")); + exit_status = EXIT_FAILURE; + } + + /* sub test 3: the space in new page below hole is zero */ + + if ((pid = fork()) == -1) { + print_message(gettext("Fork failed\n")); + return (EXIT_FAILURE); + } else if (pid == 0) { /* Am I my child? */ + set_handler(SIGSEGV); + + /* probe_hole does exit */ + probe_hole(PH_VALID); + } + /* still parent */ + (void) wait(&status); + status = WEXITSTATUS(status); + + if (status == FAIL_SEGV) { + print_message(gettext("Fail (got SEGV).\n")); + exit_status = EXIT_FAILURE; + } else if (status != PASS) { + print_message(gettext("Test program failure.\n")); + exit_status = EXIT_FAILURE; + } + return (exit_status); +} + + +/* + * set_handler + */ +static void +set_handler(int sig) +{ + struct sigaction act; + + act.sa_handler = NULL; + act.sa_flags = SA_SIGINFO; + act.sa_sigaction = segv_action; + (void) sigemptyset(&(act.sa_mask)); + + if (sigaction(sig, &act, NULL) < 0) { + if (silent == NOT_SILENT) { + (void) fprintf(stderr, gettext( + "sigaction() returned error: %s\n"), + strerror(errno)); + } + exit(EXIT_FAILURE); + } +} + + +/*ARGSUSED*/ +static void +segv_action(int which_sig, siginfo_t *t1, void *t2) +{ + exit(handler_exit_code); +} + +/* + * probe_stack + * + * Warning -- if you do a printf or fprintf prior to the actual + * reading from the stack, you've changed the stack to an unknown + * state. (stack memory isn't free'd automatically and this function + * needs to touch virgin stack space.) + */ +static void +probe_stack(void) +{ + unsigned char *end; /* end of stack */ + unsigned char probe; + long i; + int j; + unsigned char last_fail, *last_fail_address; + unsigned char mark = 0xAA; /* roughly the end of stack */ + handler_exit_code = FAIL_SEGV; + + end = &mark; + /* stack growth is negative */ + end -= (WASTE_PAGES * PAGESIZE) + STACK_SLOP; + + for (i = 0, j = 0; i < PAGESIZE; i++) { + if ((probe = *end) != 0) { + j++; + last_fail = probe; + last_fail_address = end; + } + end--; + } + + if (j != 0) { + if (silent == NOT_SILENT) + (void) fprintf(stderr, gettext( + "probe_stack failed. address=0x%08X; " + "probe=0x%02X; content = %d\n"), + (caddr_t)last_fail_address, last_fail, j); + + exit(FAIL_ZERO); /* test failed at least once */ + } + exit(EXIT_SUCCESS); +} + +static void +probe_hole(int test_type) +{ + long i; + /* LINTED */ + volatile unsigned char probe; + unsigned char *probe_adr; + void *address; + + address = sbrk(0); /* current end data + 1 */ + + if (address == (void *)-1) { + print_message(gettext("Test program logic error\n")); + exit(FAIL_ABORT); + } + if (test_type == PH_VALID) { + /* show that access works inside the hole */ + handler_exit_code = FAIL_SEGV; + + probe_adr = (unsigned char *)address - sizeof (char); + + for (i = 0; i < PAGESIZE; i++) + probe = *probe_adr--; + + exit(EXIT_SUCCESS); + } else { + /* show that a trap occurs in the hole */ + handler_exit_code = PASS_SEGV; + + address = (void *)P2ROUNDUP((uintptr_t)address, PAGESIZE); + probe_adr = (unsigned char *)address; + + probe = *probe_adr; + exit(FAIL_SEGV); /* expected SEGV, didn't get it */ + } +} + +/* + * Catch signal, child to parent + */ +/*ARGSUSED*/ +void +handler(int signal) +{ + done_memory_grab = 1; +} +/* + * memory_type: Determine whether a given executable file is compiled + * as 32 or 64 bit. + * + * The following code was stolen from isainfo (1) + */ + +static int +memory_type(const char *path) { + char *idarray; + Elf *elf; + int d; + int bits = 0; + + if ((d = open(path, O_RDONLY)) < 0) { + (void) fprintf(stderr, + "cannot open: %s -- %s\n", + path, strerror(errno)); + return (bits); + } + + if (elf_version(EV_CURRENT) == EV_NONE) { + (void) fprintf(stderr, + "internal error: ELF library out of date?\n"); + (void) close(d); + return (bits); + } + + elf = elf_begin(d, ELF_C_READ, (Elf *)0); + if (elf_kind(elf) != ELF_K_ELF) { + (void) elf_end(elf); + (void) close(d); + return (bits); + } + + idarray = elf_getident(elf, 0); + + if (idarray[EI_CLASS] == ELFCLASS32) { + bits = 32; + } else if (idarray[EI_CLASS] == ELFCLASS64) { + bits = 64; + } + + (void) elf_end(elf); + (void) close(d); + return (bits); +} diff --git a/usr/src/cmd/amt/amt.sh b/usr/src/cmd/amt/amt.sh new file mode 100644 index 0000000000..686738fa9e --- /dev/null +++ b/usr/src/cmd/amt/amt.sh @@ -0,0 +1,44 @@ +#! /usr/bin/sh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +#ident "%Z%%M% %I% %E% SMI" +# +# Copyright (c) 2000 by Sun Microsystems, Inc. +# All rights reserved. +# + +BIN=`dirname $0` +cmd=`basename $0` + +for d in `/usr/bin/isalist` +do + if [ -x $BIN/$d/$cmd ]; then + $BIN/$d/$cmd "$@" + res=$? + if [ $res != 0 ]; then + exit $res + fi + fi +done + +exit 0 diff --git a/usr/src/cmd/amt/i386/Makefile b/usr/src/cmd/amt/i386/Makefile new file mode 100644 index 0000000000..600bb4bea5 --- /dev/null +++ b/usr/src/cmd/amt/i386/Makefile @@ -0,0 +1,34 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +#ident "%Z%%M% %I% %E% SMI" +# +# Copyright (c) 2000 by Sun Microsystems, Inc. +# All rights reserved. +# +# cmd/amt/i386/Makefile + +.KEEP_STATE: + +include ../Makefile.com + +install: $(PROG) $(ROOTPROG32) diff --git a/usr/src/cmd/amt/sparcv9/Makefile b/usr/src/cmd/amt/sparcv9/Makefile new file mode 100644 index 0000000000..da3acb4713 --- /dev/null +++ b/usr/src/cmd/amt/sparcv9/Makefile @@ -0,0 +1,35 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +#ident "%Z%%M% %I% %E% SMI" +# +# Copyright (c) 2000 by Sun Microsystems, Inc. +# All rights reserved. +# +# cmd/amt/sparcv9/Makefile + +.KEEP_STATE: + +include ../Makefile.com +include ../../Makefile.cmd.64 + +install: $(PROG) $(ROOTPROG64) |
