Path: blob/main/cddl/contrib/opensolaris/tools/ctf/cvt/ctfconvert.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* Given a file containing sections with stabs data, convert the stabs data to29* CTF data, and replace the stabs sections with a CTF section.30*/3132#include <stdio.h>33#include <stdlib.h>34#include <unistd.h>35#include <signal.h>36#include <string.h>37#include <fcntl.h>38#include <libgen.h>39#include <errno.h>40#include <assert.h>4142#include "ctftools.h"43#include "memory.h"4445const char *progname;46int debug_level = DEBUG_LEVEL;4748static char *infile = NULL;49static const char *outfile = NULL;50static int dynsym;5152static void53usage(void)54{55(void) fprintf(stderr,56"Usage: %s [-gis] -l label | -L labelenv [-o outfile] object_file\n"57"\n"58" Note: if -L labelenv is specified and labelenv is not set in\n"59" the environment, a default value is used.\n",60progname);61}6263static void64terminate_cleanup(void)65{66#if !defined(__FreeBSD__)67if (!outfile) {68fprintf(stderr, "Removing %s\n", infile);69unlink(infile);70}71#endif72}7374static void75handle_sig(int sig)76{77terminate("Caught signal %d - exiting\n", sig);78}7980static int81file_read(tdata_t *td, char *filename, int ignore_non_c)82{83typedef int (*reader_f)(tdata_t *, Elf *, char *);84static reader_f readers[] = {85dw_read,86NULL87};8889source_types_t source_types;90Elf *elf;91int i, rc, fd;9293if ((fd = open(filename, O_RDONLY)) < 0)94terminate("failed to open %s", filename);9596(void) elf_version(EV_CURRENT);9798if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL) {99close(fd);100terminate("failed to read %s: %s\n", filename,101elf_errmsg(-1));102}103104source_types = built_source_types(elf, filename);105106if ((source_types == SOURCE_NONE || (source_types & SOURCE_UNKNOWN)) &&107ignore_non_c) {108debug(1, "Ignoring file %s from unknown sources\n", filename);109exit(0);110}111112for (i = 0; readers[i] != NULL; i++) {113if ((rc = readers[i](td, elf, filename)) == 0)114break;115116assert(rc < 0 && errno == ENOENT);117}118119if (readers[i] == NULL) {120/*121* None of the readers found compatible type data.122*/123124if (findelfsecidx(elf, filename, ".debug") >= 0) {125terminate("%s: DWARF version 1 is not supported\n",126filename);127}128129if (!(source_types & SOURCE_C) && ignore_non_c) {130debug(1, "Ignoring file %s not built from C sources\n",131filename);132exit(0);133}134135rc = 0;136} else {137rc = 1;138}139140(void) elf_end(elf);141(void) close(fd);142143return (rc);144}145146int147main(int argc, char **argv)148{149tdata_t *filetd, *mstrtd;150const char *label = NULL;151int verbose = 0;152int ignore_non_c = 0;153int keep_stabs = 0;154int c;155156#ifdef illumos157sighold(SIGINT);158sighold(SIGQUIT);159sighold(SIGTERM);160#endif161162progname = basename(argv[0]);163164if (getenv("CTFCONVERT_DEBUG_LEVEL"))165debug_level = atoi(getenv("CTFCONVERT_DEBUG_LEVEL"));166167while ((c = getopt(argc, argv, ":l:L:o:givs")) != EOF) {168switch (c) {169case 'l':170label = optarg;171break;172case 'L':173if ((label = getenv(optarg)) == NULL)174label = CTF_DEFAULT_LABEL;175break;176case 'o':177outfile = optarg;178break;179case 's':180dynsym = CTF_USE_DYNSYM;181break;182case 'i':183ignore_non_c = 1;184break;185case 'g':186keep_stabs = CTF_KEEP_STABS;187break;188case 'v':189verbose = 1;190break;191default:192usage();193exit(2);194}195}196197if (getenv("STRIPSTABS_KEEP_STABS") != NULL)198keep_stabs = CTF_KEEP_STABS;199200if (argc - optind != 1 || label == NULL) {201usage();202exit(2);203}204205infile = argv[optind];206if (access(infile, R_OK) != 0)207terminate("Can't access %s", infile);208209/*210* Upon receipt of a signal, we want to clean up and exit. Our211* primary goal during cleanup is to restore the system to a state212* such that a subsequent make will eventually cause this command to213* be re-run. If we remove the input file (which we do if we get a214* signal and the user didn't specify a separate output file), make215* will need to rebuild the input file, and will then need to re-run216* ctfconvert, which is what we want.217*/218set_terminate_cleanup(terminate_cleanup);219220#ifdef illumos221sigset(SIGINT, handle_sig);222sigset(SIGQUIT, handle_sig);223sigset(SIGTERM, handle_sig);224#else225signal(SIGINT, handle_sig);226signal(SIGQUIT, handle_sig);227signal(SIGTERM, handle_sig);228#endif229230filetd = tdata_new();231232if (!file_read(filetd, infile, ignore_non_c))233terminate("%s doesn't have type data to convert\n", infile);234235if (verbose)236iidesc_stats(filetd->td_iihash);237238mstrtd = tdata_new();239merge_into_master(filetd, mstrtd, NULL, 1);240241tdata_label_add(mstrtd, label, CTF_LABEL_LASTIDX);242243/*244* If the user supplied an output file that is different from the245* input file, write directly to the output file. Otherwise, write246* to a temporary file, and replace the input file when we're done.247*/248if (outfile && strcmp(infile, outfile) != 0) {249write_ctf(mstrtd, infile, outfile, dynsym | keep_stabs);250} else {251char *tmpname = mktmpname(infile, ".ctf");252write_ctf(mstrtd, infile, tmpname, dynsym | keep_stabs);253if (rename(tmpname, infile) != 0)254terminate("Couldn't rename temp file %s", tmpname);255free(tmpname);256}257258return (0);259}260261262