1
0
Files
irix-657m-src/eoe/cmd/profiler/prfld.c
2022-09-29 17:59:04 +03:00

162 lines
3.8 KiB
C

/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
/* #ident "@(#)profil-3b5:prfld.c 1.4" */
#ident "$Header: /proj/irix6.5.7m/isms/eoe/cmd/profiler/RCS/prfld.c,v 1.11 1997/08/21 02:52:44 leedom Exp $"
/*
* prfld - load profiler with sorted kernel text addresses
*/
#include <stdarg.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include "prf.h"
static int Dump = 0; /* if set then dump symbols used */
static char *namelist = "/unix"; /* namelist file */
static int symcnt; /* number of symbols */
static int symlistsize; /* sized of malloc'ed memory for list */
static symaddr_t *symlist; /* list of symbol address */
static symaddr_t *symnext; /* next free slot */
extern int rdsymtab(int, void (*)(char *, symaddr_t));
extern int rdelfsymtab(int, void (*)(char *, symaddr_t));
static int compar(const void *, const void *);
static void listinit(void);
static void listadd(char *, symaddr_t);
static void fatal(const char *s, ...);
int
main(int argc, char **argv)
{
int fd, prf;
int dwarfsyms;
setlinebuf(stdout);
setlinebuf(stderr);
if (argc > 1) {
if (argv[1][0] == '-') {
if (argv[1][1] == 'd')
Dump++;
else
fatal("usage: prfld [-d] [/unix]");
if (argc > 3)
fatal("usage: prfld [-d] [/unix]");
namelist = argv[2];
} else
namelist = argv[1];
}
if ((prf = open("/dev/prf", O_WRONLY)) < 0)
fatal("cannot open /dev/prf: %s", strerror(errno));
if ((fd = open(namelist, O_RDONLY)) < 0)
fatal("cannot open namelist file: %s", strerror(errno));
listinit();
dwarfsyms = rdsymtab(fd, listadd);
if (rdelfsymtab(fd, listadd) && dwarfsyms)
fatal("unable to load dwarf/mdebug or elf symbol table information");
qsort(symlist, symcnt, sizeof (symaddr_t), compar);
if (write(prf, symlist, symcnt*sizeof(symaddr_t)) !=
symcnt*sizeof(symaddr_t))
switch(errno) {
case ENOSPC:
fatal("insufficient space in system for addresses");
case E2BIG:
fatal("unaligned data or insufficient addresses");
case EBUSY:
fatal("profiler is enabled");
case EINVAL:
fatal("text addresses not sorted properly");
default:
fatal("cannot load profiler addresses");
}
exit(EXIT_SUCCESS);
/* NOTREACHED */
}
static void
fatal(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
fputs("prfld: ", stderr);
vfprintf(stderr, fmt, ap);
fputc('\n', stderr);
va_end(ap);
exit(EXIT_FAILURE);
/*NOTREACHED*/
}
#define LISTINCR 6000
static void
listinit(void)
{
symlist = (symaddr_t *)malloc(LISTINCR * sizeof (symaddr_t));
if (symlist == NULL)
fatal("cannot allocate memory");
symnext = symlist;
symlistsize = LISTINCR;
/*
* Provide addr=0 bucket for PC addresses less than first legal
* text address. rdelfsymtab() will provide a similar bucket
* initialized to the value of "_etext".
*/
*symnext++ = 0;
symcnt = 1;
}
/* ARGSUSED */
static void
listadd(char *name, symaddr_t addr)
{
if (Dump)
printf("%s 0x%lx\n", name, addr);
if (strcmp("tcp_saveti", name) == 0)
puts("Function symbol filter let data address through!");
if (symcnt >= symlistsize) {
symlistsize += LISTINCR;
symlist = (symaddr_t *)
realloc(symlist, symlistsize * sizeof(symaddr_t));
if (symlist == NULL)
fatal("cannot allocate memory");
symnext = &symlist[symcnt];
}
*symnext++ = addr;
symcnt++;
}
int
list_repeated(symaddr_t addr)
{
register symaddr_t *sp;
int i;
for (sp = symlist, i = 0 ; i < symcnt ; i++, sp++)
if( *sp == addr )
return 1;
return 0;
}
static int
compar(const void *x, const void *y)
{
if (*(symaddr_t *)x > *(symaddr_t *)y)
return(1);
else if (*(symaddr_t *)x == *(symaddr_t *)y)
return(0);
return(-1);
}