b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam/*
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * CDDL HEADER START
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam *
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * The contents of this file are subject to the terms of the
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * Common Development and Distribution License (the "License").
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * You may not use this file except in compliance with the License.
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam *
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * or http://www.opensolaris.org/os/licensing.
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * See the License for the specific language governing permissions
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * and limitations under the License.
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam *
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * When distributing Covered Code, include this CDDL HEADER in each
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * If applicable, add the following below this CDDL HEADER, with the
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * fields enclosed by brackets "[]" replaced with your own identifying
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * information: Portions Copyright [yyyy] [name of copyright owner]
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam *
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * CDDL HEADER END
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam */
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam/*
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * Use is subject to license terms.
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam */
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam#include <stdio.h>
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam#include <sys/types.h>
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam#include <sys/param.h>
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam#include <fcntl.h>
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam#include <string.h>
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam#include <unistd.h>
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam#include <libgen.h>
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam#include <stdlib.h>
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam#include <errno.h>
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam#include <malloc.h>
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam#include <memory.h>
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam#include <libelf.h>
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam#include <gelf.h>
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam#include <utility.h>
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam/*
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * Tool to inspect a sun4u bootable module for a symbol table size
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * that will trigger a fatal error on older versions of OBP.
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam *
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * The failure mode when booting is recorded in CR 6828121
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * and appears as follows:
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam *
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * Executing last command: boot
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * Boot device: /pci@1f,0/pci@1/scsi@8/disk@0,0:a File and args: kmdb
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam *
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * Error in Fcode execution !!!
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * Evaluating: to load-base init-program
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * Out of memory
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * Warning: Fcode sequence resulted in a net stack depth change of 1
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam *
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * Error in Fcode execution !!!
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * Evaluating: to load-base init-program
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam *
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * Evaluating: to load-base init-program
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * The file just loaded does not appear to be executable.
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * ok
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam *
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * The OBP bug is CR 4777088, fixed in OBP versions 4.12.1 and forward.
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam *
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * The OBP memory allocator for the memory into which the module's
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * symbol table is read fails for a specific memory range on
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * each page, where the size &= 0x1fff is > 0x1fe1 && <= 0x1ff0.
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * Note the symbol table size is the size of both the SYMTAB
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * and the STRTAB ELF sections.
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam *
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * To prevent this problem on a given machine, update or patch the OBP.
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam *
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * If this tool reports that a module has a symbol table size in
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * the failing range, that build will not boot on any machine with
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * this OBP problem. The only known work-around is to make some
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * source change to add or remove symbols to adjust the symbol table
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * size outside the triggering range.
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam *
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * Each sun4u bootable module is in theory affected by this, including
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * cprboot, bootlst, and each unix module. Although the serengeti
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * (Sun-Fire) and opl (SPARC-Enterprise) OBP implementations never
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * included this bug. The bug only occurs for allocations
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * pagesize or greater, and the only such OBP allocation is for a
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * module's symbol table, for the sum of the SYMTAB and STRTAB
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * sections. The wanboot and inetboot binaries do not include
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * these sections and are therefore also unaffected.
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam */
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliamstatic char *whoami;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliamstatic int verbose = 0;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliamstatic int inject_err = 0;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliamstatic int no_err = 0;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliamstatic int exitcode = 0;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliamstatic uint_t pagemask = 0x1fff;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliamstatic char *sun4u_bootables[] = {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "platform/sun4u/kernel/sparcv9/unix",
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "platform/SUNW,Ultra-Enterprise-10000/kernel/sparcv9/unix",
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "platform/SUNW,Sun-Fire-15000/kernel/sparcv9/unix",
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "platform/sun4u/cprboot",
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "platform/sun4u/bootlst"
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam};
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliamstatic int nsun4ubootables = sizeof (sun4u_bootables) / sizeof (char *);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam/*
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * size check should be:
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * size &= 0x1fff, size > 0x1fe1 && size <= 0x1ff0
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam */
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliamstatic uint_t toxic_start = 0x1fe2;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliamstatic uint_t toxic_end = 0x1ff0;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam/*
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam * Tag each error message so it shows up in the build summary mail
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam */
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliamstatic char *detailed_error_msg =
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "ERROR: This binary will not boot on any machine with an older\n"
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "ERROR: version of OBP. See CR 4777088 and 6828121 for more details.\n"
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "ERROR: No work-around is possible other than making changes to\n"
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "ERROR: add/remove symbols from the module to move the symbol\n"
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "ERROR: table size outside the toxic range.\n";
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliamstatic int
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliamchk4ubin(char *root, char *binary)
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam{
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam int fd;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam Elf *elf;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam Elf_Scn *symscn;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam Elf_Scn *strscn;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam GElf_Shdr symhdr;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam GElf_Shdr strhdr;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam int64_t symtab_size;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam int64_t strtab_size;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam int64_t total;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam int found_symtab = 0;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam int found_strtab = 0;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam uint_t off;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam int rv = 1;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam char path[MAXPATHLEN];
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam if (root == NULL) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) snprintf(path, sizeof (path), "%s", binary);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam } else {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) snprintf(path, sizeof (path), "%s/%s", root, binary);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam }
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam if ((fd = open(path, O_RDONLY)) == -1) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) printf("%s: cannot open %s - %s\n",
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam whoami, path, strerror(errno));
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam return (1);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam }
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam elf_version(EV_CURRENT);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam elf = elf_begin(fd, ELF_C_READ, NULL);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam symscn = NULL;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam while ((symscn = elf_nextscn(elf, symscn)) != NULL) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam gelf_getshdr(symscn, &symhdr);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam switch (symhdr.sh_type) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam case SHT_SYMTAB:
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam found_symtab = 1;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam symtab_size = symhdr.sh_size;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam strscn = elf_getscn(elf, symhdr.sh_link);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam if (strscn != NULL) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam gelf_getshdr(strscn, &strhdr);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam strtab_size = strhdr.sh_size;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam found_strtab = 1;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam }
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam break;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam }
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam if (found_symtab && found_strtab)
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam break;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam }
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam elf_end(elf);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) close(fd);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam if (found_symtab && found_strtab) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam int err;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam total = symtab_size + strtab_size;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam off = total & pagemask;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam err = (off >= toxic_start && off <= toxic_end);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam if (inject_err || err) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) printf("%s: ERROR: %s\n", whoami, binary);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) printf("ERROR: symbol table size 0x%llx is "
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "in toxic range (0x%x - 0x%x)!\n",
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam total, toxic_start, toxic_end);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) printf("%s", detailed_error_msg);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam } else {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam rv = 0;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) printf("%s: %s ok\n", whoami, binary);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam if (verbose) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) printf("symbol table size 0x%llx "
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "not in toxic range (0x%x - 0x%x)\n",
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam total, toxic_start, toxic_end);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam }
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam }
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam if (verbose) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) printf(".symtab size: 0x%llx\n",
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam symtab_size);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) printf(".strtab size: 0x%llx\n",
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam strtab_size);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) printf("total: 0x%llx "
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "(0x%llx, 0x%llx)\n", total, (total & ~pagemask),
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (total & pagemask));
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam }
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam if (verbose || err || inject_err)
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) printf("\n");
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam } else {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam if (!found_symtab && !found_strtab) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) fprintf(stderr,
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "%s: %s - no symtab or strtab section found\n",
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam whoami, binary);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam } else if (!found_symtab) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) fprintf(stderr,
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "%s: %s - no symtab section found\n",
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam whoami, binary);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam } else if (!found_strtab) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) fprintf(stderr,
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "%s: %s - no strtab section found\n",
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam whoami, binary);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam }
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam }
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam return (rv);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam}
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliamstatic void
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliamusage()
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam{
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam int i;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) fprintf(stderr,
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "usage: %s [-n] [-v] [-r <root>] [<binary>] ...\n", whoami);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) fprintf(stderr,
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam " -n: exit with 0 even with an error detected to allow\n");
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) fprintf(stderr,
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam " a build to succeed even with a failing binary\n");
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) fprintf(stderr,
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam "The default list of binaries checked if none supplied is:\n");
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam for (i = 0; i < nsun4ubootables; i++) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam (void) fprintf(stderr, " %s\n", sun4u_bootables[i]);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam }
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam exit(0);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam}
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliamint
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliammain(int argc, char *argv[])
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam{
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam int i;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam char *root = NULL;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam whoami = basename(argv[0]);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam opterr = 0;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam while ((i = getopt(argc, argv, "enr:R:v")) != -1) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam switch (i) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam case 'v':
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam verbose = 1;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam break;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam case 'e':
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam inject_err = 1;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam break;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam case 'n':
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam no_err = 1;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam break;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam case 'r':
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam case 'R':
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam root = optarg;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam break;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam default:
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam usage();
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam break;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam }
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam }
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam if (optind < argc) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam for (i = optind; i < argc; i++) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam if (chk4ubin(root, argv[i]) != 0)
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam exitcode = 1;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam }
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam } else {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam for (i = 0; i < nsun4ubootables; i++) {
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam if (root == NULL)
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam root = "/";
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam if (chk4ubin(root, sun4u_bootables[i]) != 0)
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam exitcode = 1;
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam }
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam }
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam return (no_err ? 0 : exitcode);
b31b5de1357c915fe7dab4d9646d9d84f9fe69bcJerry Gilliam}