Path: blob/main/cddl/contrib/opensolaris/tools/ctf/cvt/util.c
39586 views
/*1* CDDL HEADER START2*3* The contents of this file are subject to the terms of the4* Common Development and Distribution License (the "License").5* You may not use this file except in compliance with the License.6*7* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE8* or http://www.opensolaris.org/os/licensing.9* See the License for the specific language governing permissions10* and limitations under the License.11*12* When distributing Covered Code, include this CDDL HEADER in each13* file and include the License file at usr/src/OPENSOLARIS.LICENSE.14* If applicable, add the following below this CDDL HEADER, with the15* fields enclosed by brackets "[]" replaced with your own identifying16* information: Portions Copyright [yyyy] [name of copyright owner]17*18* CDDL HEADER END19*/20/*21* Copyright 2006 Sun Microsystems, Inc. All rights reserved.22* Use is subject to license terms.23*/2425#pragma ident "%Z%%M% %I% %E% SMI"2627/*28* Utility functions29*/3031#include <assert.h>32#include <stdio.h>33#include <stdlib.h>34#include <string.h>35#include <libelf.h>36#include <gelf.h>37#include <errno.h>38#include <stdarg.h>39#include <pthread.h>40#include <unistd.h>41#include <sys/param.h>4243#include "ctftools.h"44#include "memory.h"4546static void (*terminate_cleanup)(void) = NULL;4748/* returns 1 if s1 == s2, 0 otherwise */49int50streq(const char *s1, const char *s2)51{52if (s1 == NULL) {53if (s2 != NULL)54return (0);55} else if (s2 == NULL)56return (0);57else if (strcmp(s1, s2) != 0)58return (0);5960return (1);61}6263int64findelfsecidx(Elf *elf, const char *file, const char *tofind)65{66Elf_Scn *scn = NULL;67GElf_Ehdr ehdr;68GElf_Shdr shdr;6970if (gelf_getehdr(elf, &ehdr) == NULL)71elfterminate(file, "Couldn't read ehdr");7273while ((scn = elf_nextscn(elf, scn)) != NULL) {74char *name;7576if (gelf_getshdr(scn, &shdr) == NULL) {77elfterminate(file,78"Couldn't read header for section %d",79elf_ndxscn(scn));80}8182if ((name = elf_strptr(elf, ehdr.e_shstrndx,83(size_t)shdr.sh_name)) == NULL) {84elfterminate(file,85"Couldn't get name for section %d",86elf_ndxscn(scn));87}8889if (strcmp(name, tofind) == 0)90return (elf_ndxscn(scn));91}9293return (-1);94}9596size_t97elf_ptrsz(Elf *elf)98{99GElf_Ehdr ehdr;100101if (gelf_getehdr(elf, &ehdr) == NULL) {102terminate("failed to read ELF header: %s\n",103elf_errmsg(-1));104}105106if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)107return (4);108else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)109return (8);110else111terminate("unknown ELF class %d\n", ehdr.e_ident[EI_CLASS]);112113/*NOTREACHED*/114return (0);115}116117/*PRINTFLIKE2*/118static void119whine(const char *type, const char *format, va_list ap)120{121int error = errno;122123fprintf(stderr, "%s: %s: ", type, progname);124vfprintf(stderr, format, ap);125126if (format[strlen(format) - 1] != '\n')127fprintf(stderr, ": %s\n", strerror(error));128}129130void131set_terminate_cleanup(void (*cleanup)(void))132{133terminate_cleanup = cleanup;134}135136/*PRINTFLIKE1*/137void138terminate(const char *format, ...)139{140va_list ap;141142va_start(ap, format);143whine("ERROR", format, ap);144va_end(ap);145146if (terminate_cleanup)147terminate_cleanup();148149if (getenv("CTF_ABORT_ON_TERMINATE") != NULL)150abort();151#if defined(__FreeBSD__)152/*153* For the time being just output the termination message, but don't154* return an exit status that would cause the build to fail. We need155* to get as much stuff built as possible before going back and156* figuring out what is wrong with certain files.157*/158exit(0);159#else160exit(1);161#endif162}163164/*PRINTFLIKE1*/165void166aborterr(const char *format, ...)167{168va_list ap;169170va_start(ap, format);171whine("ERROR", format, ap);172va_end(ap);173174#ifdef illumos175abort();176#else177exit(0);178#endif179}180181/*PRINTFLIKE1*/182void183warning(const char *format, ...)184{185va_list ap;186187va_start(ap, format);188whine("WARNING", format, ap);189va_end(ap);190191if (debug_level >= 3)192terminate("Termination due to warning\n");193}194195/*PRINTFLIKE2*/196void197vadebug(int level, const char *format, va_list ap)198{199if (level > debug_level)200return;201202(void) fprintf(DEBUG_STREAM, "DEBUG: ");203(void) vfprintf(DEBUG_STREAM, format, ap);204fflush(DEBUG_STREAM);205}206207/*PRINTFLIKE2*/208void209debug(int level, const char *format, ...)210{211va_list ap;212213if (level > debug_level)214return;215216va_start(ap, format);217(void) vadebug(level, format, ap);218va_end(ap);219}220221char *222mktmpname(const char *origname, const char *suffix)223{224char *newname;225226newname = xmalloc(strlen(origname) + strlen(suffix) + 1);227(void) strcpy(newname, origname);228(void) strcat(newname, suffix);229return (newname);230}231232/*PRINTFLIKE2*/233void234elfterminate(const char *file, const char *fmt, ...)235{236static char msgbuf[BUFSIZ];237va_list ap;238239va_start(ap, fmt);240vsnprintf(msgbuf, sizeof (msgbuf), fmt, ap);241va_end(ap);242243terminate("%s: %s: %s\n", file, msgbuf, elf_errmsg(-1));244}245246const char *247tdesc_name(tdesc_t *tdp)248{249return (tdp->t_name == NULL ? "(anon)" : tdp->t_name);250}251252static char *watch_address = NULL;253static int watch_length = 0;254255void256watch_set(void *addr, int len)257{258watch_address = addr;259watch_length = len;260}261262void263watch_dump(int v)264{265char *p = watch_address;266int i;267268if (watch_address == NULL || watch_length == 0)269return;270271printf("%d: watch %p len %d\n",v,watch_address,watch_length);272for (i = 0; i < watch_length; i++) {273if (*p >= 0x20 && *p < 0x7f) {274printf(" %c",*p++ & 0xff);275} else {276printf(" %02x",*p++ & 0xff);277}278}279printf("\n");280281}282283284285286