1 /* $DragonFly: src/usr.bin/gprof/aout.c,v 1.3 2006/01/22 03:43:37 swildner Exp $ */
6 static void getstrtab(FILE *, const char *);
7 static void getsymtab(FILE *, const char *);
8 static void gettextspace(FILE *);
9 static bool funcsymbol(struct nlist
*);
11 static char *strtab
; /* string table in core */
12 static long ssiz
; /* size of the string table */
13 static struct exec xbuf
; /* exec header of a.out */
15 /* Things which get -E excluded by default. */
16 static char *excludes
[] = { "mcount", "__mcleanup", NULL
};
19 * Set up string and symbol tables from a.out.
20 * and optionally the text space.
21 * On return symbol table is sorted by value.
23 * Returns 0 on success, -1 on failure.
26 aout_getnfile(const char *filename
, char ***defaultEs
)
31 nfile
= fopen( filename
,"r");
36 fread(&xbuf
, 1, sizeof(xbuf
), nfile
);
41 getstrtab(nfile
, filename
);
42 getsymtab(nfile
, filename
);
43 gettextspace( nfile
);
46 if ( debug
& AOUTDEBUG
) {
49 for (j
= 0; j
< nname
; j
++){
50 printf("[getnfile] 0X%08x\t%s\n", nl
[j
].value
, nl
[j
].name
);
54 *defaultEs
= excludes
;
59 getstrtab(FILE *nfile
, const char *filename
)
62 fseek(nfile
, (long)(N_SYMOFF(xbuf
) + xbuf
.a_syms
), 0);
63 if (fread(&ssiz
, sizeof (ssiz
), 1, nfile
) == 0) {
64 warnx("%s: no string table (old format?)" , filename
);
67 strtab
= calloc(ssiz
, 1);
69 warnx("%s: no room for %d bytes of string table", filename
, ssiz
);
72 if (fread(strtab
+sizeof(ssiz
), ssiz
-sizeof(ssiz
), 1, nfile
) != 1) {
73 warnx("%s: error reading string table", filename
);
79 * Read in symbol table
82 getsymtab(FILE *nfile
, const char *filename
)
88 /* pass1 - count symbols */
89 fseek(nfile
, (long)N_SYMOFF(xbuf
), 0);
91 for (i
= xbuf
.a_syms
; i
> 0; i
-= sizeof(struct nlist
)) {
92 fread(&nbuf
, sizeof(nbuf
), 1, nfile
);
93 if ( ! funcsymbol( &nbuf
) ) {
99 warnx("%s: no symbols", filename
);
103 nl
= (nltype
*) calloc( askfor
, sizeof(nltype
) );
105 warnx("no room for %d bytes of symbol table", askfor
* sizeof(nltype
) );
109 /* pass2 - read symbols */
110 fseek(nfile
, (long)N_SYMOFF(xbuf
), 0);
113 for (i
= xbuf
.a_syms
; i
> 0; i
-= sizeof(struct nlist
)) {
114 fread(&nbuf
, sizeof(nbuf
), 1, nfile
);
115 if ( ! funcsymbol( &nbuf
) ) {
117 if ( debug
& AOUTDEBUG
) {
118 printf( "[getsymtab] rejecting: 0x%x %s\n" ,
119 nbuf
.n_type
, strtab
+ nbuf
.n_un
.n_strx
);
124 npe
->value
= nbuf
.n_value
;
125 npe
->name
= strtab
+nbuf
.n_un
.n_strx
;
127 if ( debug
& AOUTDEBUG
) {
128 printf( "[getsymtab] %d %s 0x%08x\n" ,
129 nname
, npe
-> name
, npe
-> value
);
139 * read in the text space of an a.out file
142 gettextspace(FILE *nfile
)
148 textspace
= (u_char
*) malloc( xbuf
.a_text
);
149 if ( textspace
== 0 ) {
150 warnx("ran out room for %d bytes of text space: can't do -c" ,
154 (void) fseek( nfile
, N_TXTOFF( xbuf
) , 0 );
155 if ( fread( textspace
, 1 , xbuf
.a_text
, nfile
) != xbuf
.a_text
) {
156 warnx("couldn't read text space: can't do -c");
164 funcsymbol(struct nlist
*nlistp
)
169 * must be a text symbol,
170 * and static text symbols don't qualify if aflag set.
172 if ( ! ( ( nlistp
-> n_type
== ( N_TEXT
| N_EXT
) )
173 || ( ( nlistp
-> n_type
== N_TEXT
) && ( aflag
== 0 ) ) ) ) {
177 * name must start with an underscore if uflag is set.
178 * can't have any `funny' characters in name,
179 * where `funny' means `.' (.o file names)
180 * need to make an exception for sparc .mul & co.
181 * perhaps we should just drop this code entirely...
183 name
= strtab
+ nlistp
-> n_un
.n_strx
;
184 if ( uflag
&& *name
!= '_' )
187 if ( *name
== '.' ) {
191 if ( strcmp ( p
, "mul" ) == 0 || strcmp ( p
, "div" ) == 0 ||
192 strcmp ( p
, "rem" ) == 0 )
196 while ( c
= *name
++ ) {