11673e404SJohn Birrell /*
21673e404SJohn Birrell * CDDL HEADER START
31673e404SJohn Birrell *
41673e404SJohn Birrell * The contents of this file are subject to the terms of the
51673e404SJohn Birrell * Common Development and Distribution License (the "License").
61673e404SJohn Birrell * You may not use this file except in compliance with the License.
71673e404SJohn Birrell *
81673e404SJohn Birrell * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91673e404SJohn Birrell * or http://www.opensolaris.org/os/licensing.
101673e404SJohn Birrell * See the License for the specific language governing permissions
111673e404SJohn Birrell * and limitations under the License.
121673e404SJohn Birrell *
131673e404SJohn Birrell * When distributing Covered Code, include this CDDL HEADER in each
141673e404SJohn Birrell * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151673e404SJohn Birrell * If applicable, add the following below this CDDL HEADER, with the
161673e404SJohn Birrell * fields enclosed by brackets "[]" replaced with your own identifying
171673e404SJohn Birrell * information: Portions Copyright [yyyy] [name of copyright owner]
181673e404SJohn Birrell *
191673e404SJohn Birrell * CDDL HEADER END
201673e404SJohn Birrell */
211673e404SJohn Birrell /*
221673e404SJohn Birrell * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
231673e404SJohn Birrell * Use is subject to license terms.
241673e404SJohn Birrell */
251673e404SJohn Birrell
261673e404SJohn Birrell #pragma ident "%Z%%M% %I% %E% SMI"
271673e404SJohn Birrell
281673e404SJohn Birrell /*
291673e404SJohn Birrell * Utility functions
301673e404SJohn Birrell */
311673e404SJohn Birrell
32*9e5787d2SMatt Macy #include <assert.h>
331673e404SJohn Birrell #include <stdio.h>
341673e404SJohn Birrell #include <stdlib.h>
351673e404SJohn Birrell #include <string.h>
361673e404SJohn Birrell #include <libelf.h>
371673e404SJohn Birrell #include <gelf.h>
381673e404SJohn Birrell #include <errno.h>
391673e404SJohn Birrell #include <stdarg.h>
401673e404SJohn Birrell #include <pthread.h>
411673e404SJohn Birrell #include <unistd.h>
421673e404SJohn Birrell #include <sys/param.h>
431673e404SJohn Birrell
441673e404SJohn Birrell #include "ctftools.h"
451673e404SJohn Birrell #include "memory.h"
461673e404SJohn Birrell
47c01977edSJohn Birrell static void (*terminate_cleanup)(void) = NULL;
481673e404SJohn Birrell
491673e404SJohn Birrell /* returns 1 if s1 == s2, 0 otherwise */
501673e404SJohn Birrell int
streq(const char * s1,const char * s2)511673e404SJohn Birrell streq(const char *s1, const char *s2)
521673e404SJohn Birrell {
531673e404SJohn Birrell if (s1 == NULL) {
541673e404SJohn Birrell if (s2 != NULL)
551673e404SJohn Birrell return (0);
561673e404SJohn Birrell } else if (s2 == NULL)
571673e404SJohn Birrell return (0);
581673e404SJohn Birrell else if (strcmp(s1, s2) != 0)
591673e404SJohn Birrell return (0);
601673e404SJohn Birrell
611673e404SJohn Birrell return (1);
621673e404SJohn Birrell }
631673e404SJohn Birrell
641673e404SJohn Birrell int
findelfsecidx(Elf * elf,const char * file,const char * tofind)651673e404SJohn Birrell findelfsecidx(Elf *elf, const char *file, const char *tofind)
661673e404SJohn Birrell {
671673e404SJohn Birrell Elf_Scn *scn = NULL;
681673e404SJohn Birrell GElf_Ehdr ehdr;
691673e404SJohn Birrell GElf_Shdr shdr;
701673e404SJohn Birrell
711673e404SJohn Birrell if (gelf_getehdr(elf, &ehdr) == NULL)
721673e404SJohn Birrell elfterminate(file, "Couldn't read ehdr");
731673e404SJohn Birrell
741673e404SJohn Birrell while ((scn = elf_nextscn(elf, scn)) != NULL) {
751673e404SJohn Birrell char *name;
761673e404SJohn Birrell
771673e404SJohn Birrell if (gelf_getshdr(scn, &shdr) == NULL) {
781673e404SJohn Birrell elfterminate(file,
791673e404SJohn Birrell "Couldn't read header for section %d",
801673e404SJohn Birrell elf_ndxscn(scn));
811673e404SJohn Birrell }
821673e404SJohn Birrell
831673e404SJohn Birrell if ((name = elf_strptr(elf, ehdr.e_shstrndx,
841673e404SJohn Birrell (size_t)shdr.sh_name)) == NULL) {
851673e404SJohn Birrell elfterminate(file,
861673e404SJohn Birrell "Couldn't get name for section %d",
871673e404SJohn Birrell elf_ndxscn(scn));
881673e404SJohn Birrell }
891673e404SJohn Birrell
901673e404SJohn Birrell if (strcmp(name, tofind) == 0)
911673e404SJohn Birrell return (elf_ndxscn(scn));
921673e404SJohn Birrell }
931673e404SJohn Birrell
941673e404SJohn Birrell return (-1);
951673e404SJohn Birrell }
961673e404SJohn Birrell
971673e404SJohn Birrell size_t
elf_ptrsz(Elf * elf)981673e404SJohn Birrell elf_ptrsz(Elf *elf)
991673e404SJohn Birrell {
1001673e404SJohn Birrell GElf_Ehdr ehdr;
1011673e404SJohn Birrell
1021673e404SJohn Birrell if (gelf_getehdr(elf, &ehdr) == NULL) {
1031673e404SJohn Birrell terminate("failed to read ELF header: %s\n",
1041673e404SJohn Birrell elf_errmsg(-1));
1051673e404SJohn Birrell }
1061673e404SJohn Birrell
1071673e404SJohn Birrell if (ehdr.e_ident[EI_CLASS] == ELFCLASS32)
1081673e404SJohn Birrell return (4);
1091673e404SJohn Birrell else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64)
1101673e404SJohn Birrell return (8);
1111673e404SJohn Birrell else
1121673e404SJohn Birrell terminate("unknown ELF class %d\n", ehdr.e_ident[EI_CLASS]);
1131673e404SJohn Birrell
1141673e404SJohn Birrell /*NOTREACHED*/
1151673e404SJohn Birrell return (0);
1161673e404SJohn Birrell }
1171673e404SJohn Birrell
1181673e404SJohn Birrell /*PRINTFLIKE2*/
1191673e404SJohn Birrell static void
whine(const char * type,const char * format,va_list ap)120c01977edSJohn Birrell whine(const char *type, const char *format, va_list ap)
1211673e404SJohn Birrell {
1221673e404SJohn Birrell int error = errno;
1231673e404SJohn Birrell
1241673e404SJohn Birrell fprintf(stderr, "%s: %s: ", type, progname);
1251673e404SJohn Birrell vfprintf(stderr, format, ap);
1261673e404SJohn Birrell
1271673e404SJohn Birrell if (format[strlen(format) - 1] != '\n')
1281673e404SJohn Birrell fprintf(stderr, ": %s\n", strerror(error));
1291673e404SJohn Birrell }
1301673e404SJohn Birrell
1311673e404SJohn Birrell void
set_terminate_cleanup(void (* cleanup)(void))132c01977edSJohn Birrell set_terminate_cleanup(void (*cleanup)(void))
1331673e404SJohn Birrell {
1341673e404SJohn Birrell terminate_cleanup = cleanup;
1351673e404SJohn Birrell }
1361673e404SJohn Birrell
1371673e404SJohn Birrell /*PRINTFLIKE1*/
1381673e404SJohn Birrell void
terminate(const char * format,...)139c01977edSJohn Birrell terminate(const char *format, ...)
1401673e404SJohn Birrell {
1411673e404SJohn Birrell va_list ap;
1421673e404SJohn Birrell
1431673e404SJohn Birrell va_start(ap, format);
1441673e404SJohn Birrell whine("ERROR", format, ap);
1451673e404SJohn Birrell va_end(ap);
1461673e404SJohn Birrell
1471673e404SJohn Birrell if (terminate_cleanup)
1481673e404SJohn Birrell terminate_cleanup();
1491673e404SJohn Birrell
1501673e404SJohn Birrell if (getenv("CTF_ABORT_ON_TERMINATE") != NULL)
1511673e404SJohn Birrell abort();
15275a81308SBryan Drewery #if defined(__FreeBSD__)
15375a81308SBryan Drewery /*
15475a81308SBryan Drewery * For the time being just output the termination message, but don't
15575a81308SBryan Drewery * return an exit status that would cause the build to fail. We need
15675a81308SBryan Drewery * to get as much stuff built as possible before going back and
15775a81308SBryan Drewery * figuring out what is wrong with certain files.
15875a81308SBryan Drewery */
15975a81308SBryan Drewery exit(0);
16075a81308SBryan Drewery #else
1611673e404SJohn Birrell exit(1);
16275a81308SBryan Drewery #endif
1631673e404SJohn Birrell }
1641673e404SJohn Birrell
1651673e404SJohn Birrell /*PRINTFLIKE1*/
1661673e404SJohn Birrell void
aborterr(const char * format,...)167c01977edSJohn Birrell aborterr(const char *format, ...)
1681673e404SJohn Birrell {
1691673e404SJohn Birrell va_list ap;
1701673e404SJohn Birrell
1711673e404SJohn Birrell va_start(ap, format);
1721673e404SJohn Birrell whine("ERROR", format, ap);
1731673e404SJohn Birrell va_end(ap);
1741673e404SJohn Birrell
175bc96366cSSteven Hartland #ifdef illumos
1761673e404SJohn Birrell abort();
177c01977edSJohn Birrell #else
178c01977edSJohn Birrell exit(0);
179c01977edSJohn Birrell #endif
1801673e404SJohn Birrell }
1811673e404SJohn Birrell
1821673e404SJohn Birrell /*PRINTFLIKE1*/
1831673e404SJohn Birrell void
warning(const char * format,...)184c01977edSJohn Birrell warning(const char *format, ...)
1851673e404SJohn Birrell {
1861673e404SJohn Birrell va_list ap;
1871673e404SJohn Birrell
1881673e404SJohn Birrell va_start(ap, format);
1891673e404SJohn Birrell whine("WARNING", format, ap);
1901673e404SJohn Birrell va_end(ap);
1911673e404SJohn Birrell
1921673e404SJohn Birrell if (debug_level >= 3)
1931673e404SJohn Birrell terminate("Termination due to warning\n");
1941673e404SJohn Birrell }
1951673e404SJohn Birrell
1961673e404SJohn Birrell /*PRINTFLIKE2*/
1971673e404SJohn Birrell void
vadebug(int level,const char * format,va_list ap)198c01977edSJohn Birrell vadebug(int level, const char *format, va_list ap)
1991673e404SJohn Birrell {
2001673e404SJohn Birrell if (level > debug_level)
2011673e404SJohn Birrell return;
2021673e404SJohn Birrell
2031673e404SJohn Birrell (void) fprintf(DEBUG_STREAM, "DEBUG: ");
2041673e404SJohn Birrell (void) vfprintf(DEBUG_STREAM, format, ap);
2051673e404SJohn Birrell fflush(DEBUG_STREAM);
2061673e404SJohn Birrell }
2071673e404SJohn Birrell
2081673e404SJohn Birrell /*PRINTFLIKE2*/
2091673e404SJohn Birrell void
debug(int level,const char * format,...)210c01977edSJohn Birrell debug(int level, const char *format, ...)
2111673e404SJohn Birrell {
2121673e404SJohn Birrell va_list ap;
2131673e404SJohn Birrell
2141673e404SJohn Birrell if (level > debug_level)
2151673e404SJohn Birrell return;
2161673e404SJohn Birrell
2171673e404SJohn Birrell va_start(ap, format);
2181673e404SJohn Birrell (void) vadebug(level, format, ap);
2191673e404SJohn Birrell va_end(ap);
2201673e404SJohn Birrell }
2211673e404SJohn Birrell
2221673e404SJohn Birrell char *
mktmpname(const char * origname,const char * suffix)2231673e404SJohn Birrell mktmpname(const char *origname, const char *suffix)
2241673e404SJohn Birrell {
2251673e404SJohn Birrell char *newname;
2261673e404SJohn Birrell
2271673e404SJohn Birrell newname = xmalloc(strlen(origname) + strlen(suffix) + 1);
2281673e404SJohn Birrell (void) strcpy(newname, origname);
2291673e404SJohn Birrell (void) strcat(newname, suffix);
2301673e404SJohn Birrell return (newname);
2311673e404SJohn Birrell }
2321673e404SJohn Birrell
2331673e404SJohn Birrell /*PRINTFLIKE2*/
2341673e404SJohn Birrell void
elfterminate(const char * file,const char * fmt,...)2351673e404SJohn Birrell elfterminate(const char *file, const char *fmt, ...)
2361673e404SJohn Birrell {
2371673e404SJohn Birrell static char msgbuf[BUFSIZ];
2381673e404SJohn Birrell va_list ap;
2391673e404SJohn Birrell
2401673e404SJohn Birrell va_start(ap, fmt);
2411673e404SJohn Birrell vsnprintf(msgbuf, sizeof (msgbuf), fmt, ap);
2421673e404SJohn Birrell va_end(ap);
2431673e404SJohn Birrell
2441673e404SJohn Birrell terminate("%s: %s: %s\n", file, msgbuf, elf_errmsg(-1));
2451673e404SJohn Birrell }
2461673e404SJohn Birrell
2471673e404SJohn Birrell const char *
tdesc_name(tdesc_t * tdp)2481673e404SJohn Birrell tdesc_name(tdesc_t *tdp)
2491673e404SJohn Birrell {
2501673e404SJohn Birrell return (tdp->t_name == NULL ? "(anon)" : tdp->t_name);
2511673e404SJohn Birrell }
252c01977edSJohn Birrell
253c0794a84SEd Schouten static char *watch_address = NULL;
254c0794a84SEd Schouten static int watch_length = 0;
255c01977edSJohn Birrell
256c01977edSJohn Birrell void
watch_set(void * addr,int len)257c01977edSJohn Birrell watch_set(void *addr, int len)
258c01977edSJohn Birrell {
259c01977edSJohn Birrell watch_address = addr;
260c01977edSJohn Birrell watch_length = len;
261c01977edSJohn Birrell }
262c01977edSJohn Birrell
263c01977edSJohn Birrell void
watch_dump(int v)264c01977edSJohn Birrell watch_dump(int v)
265c01977edSJohn Birrell {
266c01977edSJohn Birrell char *p = watch_address;
267c01977edSJohn Birrell int i;
268c01977edSJohn Birrell
269c01977edSJohn Birrell if (watch_address == NULL || watch_length == 0)
270c01977edSJohn Birrell return;
271c01977edSJohn Birrell
272c01977edSJohn Birrell printf("%d: watch %p len %d\n",v,watch_address,watch_length);
273c01977edSJohn Birrell for (i = 0; i < watch_length; i++) {
274c01977edSJohn Birrell if (*p >= 0x20 && *p < 0x7f) {
275c01977edSJohn Birrell printf(" %c",*p++ & 0xff);
276c01977edSJohn Birrell } else {
277c01977edSJohn Birrell printf(" %02x",*p++ & 0xff);
278c01977edSJohn Birrell }
279c01977edSJohn Birrell }
280c01977edSJohn Birrell printf("\n");
281c01977edSJohn Birrell
282c01977edSJohn Birrell }
283c01977edSJohn Birrell
284c01977edSJohn Birrell
285