23 PRIVATE
struct symtab_s symtab
;
24 PRIVATE
int type_of_exec
;
26 FORWARD
_PROTOTYPE( int check_exec
, (struct exec
*hdr
) );
27 FORWARD
_PROTOTYPE( void sortsyms
, (struct nlist
*array
, struct nlist
*top
));
28 FORWARD
_PROTOTYPE( int symeq
, (char *t
, struct nlist
*sp
));
29 FORWARD
_PROTOTYPE( int symprefix
, (char *t
, struct nlist
*sp
));
30 FORWARD
_PROTOTYPE( struct nlist
*findsname
, (char *name
, int is_text
, int allflag
) );
31 FORWARD
_PROTOTYPE( void outsym
, (struct nlist
*sp
, off_t off
) );
32 FORWARD
_PROTOTYPE( struct nlist
*findsval
, (off_t value
, int where
) );
34 PUBLIC
void syminit( filename
)
39 register struct symtab_s
*tp
;
42 if ( (fd
= open( filename
, O_RDONLY
)) < 0) {
43 fprintf(stderr
, "Couldn't open %s.\n", filename
);
48 if( read( fd
, (char *) &header
, sizeof header
) != sizeof header
)
50 fprintf(stderr
, "Couldn't read %d bytes from %s.\n", sizeof(header
), filename
);
54 type_of_exec
= check_exec(&header
);
57 if ( type_of_exec
== GNU_SYMBOLS
) {
65 if ( lseek( fd
, A_SYMPOS( header
), 0 ) != A_SYMPOS( header
) )
67 do_error( "mdb - reading header" );
71 if ( (int) header
.a_syms
< 0 ||
72 (unsigned) header
.a_syms
!= header
.a_syms
||
73 (tp
->start
= (struct nlist
*) malloc( (unsigned) header
.a_syms
))
74 == (struct nlist
*) NULL
&&
77 Printf("mdb: no room for symbol table" );
81 if ( read( fd
, (char *) tp
->start
, (int) header
.a_syms
) < 0 )
83 do_error( "mdb - reading symbol table" );
88 tp
->nsym
= (unsigned) header
.a_syms
/ sizeof (struct nlist
);
89 tp
->end
= tp
->start
+ tp
->nsym
;
93 /* sort on value only, name search not used much and storage a problem */
94 Printf("Sorting %d MINIX symbols ....", tp
->nsym
);
95 sortsyms( tp
->start
, tp
->end
);
100 * return type of exec
103 PRIVATE
int check_exec(hdr
)
108 /* Check MAGIC number */
109 if (hdr
->a_magic
[0] != A_MAGIC0
|| hdr
->a_magic
[1] != A_MAGIC1
) {
110 Printf("mdb: invalid magic number in exec header - %02x %02x\n",
118 #if (_WORD_SIZE == 4)
119 if (hdr
->a_cpu
!= A_I80386
)
121 if (hdr
->a_cpu
!= A_I8086
)
125 if (hdr
->a_cpu
!= A_M68K
)
128 Printf("mdb: invalid cpu in exec header - %04x\n",
135 if (hdr
->a_flags
& A_SEP
)
140 if (hdr
->a_flags
& A_NSYM
)
145 * A_EXEC is not being set by current cc
146 * It was set in Minix 1.5.0
149 /* Check flags - separate I & D or not */
150 if (hdr
->a_flags
& A_EXEC
)
153 Printf("mdb: object file not exec %04x\n",
158 return MINIX_SYMBOLS
;
162 PUBLIC
long symbolvalue( name
, is_text
)
166 register struct nlist
*sp
;
169 if ( type_of_exec
== GNU_SYMBOLS
)
170 return gnu_symbolvalue( name
, is_text
);
174 sp
= findsname(name
, is_text
, 0);
181 PRIVATE
struct nlist
*findsname( name
, is_text
, allflag
)
187 unsigned char sclass
;
190 register struct nlist
*sp
;
191 register struct symtab_s
*tp
;
196 /* find and print all matching symbols */
197 for ( sp
= tp
->start
; sp
< tp
->end
; ++sp
)
199 if ( symprefix( name
, sp
) )
202 for ( s
= sp
->n_name
, send
= s
+ sizeof sp
->n_name
;
203 *s
!= 0 && s
< send
; ++s
)
205 for ( ; s
<= send
; ++s
)
207 switch( sp
->n_sclass
& N_SECT
)
209 case N_ABS
: schar
= 'a'; break;
210 case N_TEXT
: schar
= 't'; break;
211 case N_DATA
: schar
= 'd'; break;
212 case N_BSS
: schar
= 'b'; break;
213 default: schar
= '?'; break;
215 if ( (sp
->n_sclass
& N_CLASS
) == C_EXT
&& schar
!= '?' )
219 #if (_WORD_SIZE == 2)
220 outh16( (u16_t
) sp
->n_value
);
222 outh32( sp
->n_value
);
230 /* find symbol by dumb linear search */
231 for ( sp
= tp
->start
; sp
< tp
->end
; ++sp
)
233 sclass
= sp
->n_sclass
& N_SECT
;
234 if ( (is_text
&& sclass
== N_TEXT
||
235 !is_text
&& (sclass
== N_DATA
|| sclass
== N_BSS
)) &&
243 PRIVATE
struct nlist
*findsval( value
, where
)
250 unsigned char sclass
;
251 register struct nlist
*sp
;
252 register struct symtab_s
*tp
;
256 /* find last symbol with value <= desired one by binary search */
257 for ( left
= 0, right
= tp
->nsym
- 1; left
<= right
; )
259 middle
= (left
+ right
) / 2;
260 sp
= tp
->start
+ middle
;
261 if ( value
< sp
->n_value
)
267 /* otherwise tp->start + right may wrap around to > tp->start !! */
268 for ( sp
= tp
->start
+ right
; sp
>= tp
->start
; --sp
)
270 if ( (sp
->n_sclass
& N_CLASS
) != C_EXT
) continue;
271 sclass
= sp
->n_sclass
& N_SECT
;
272 if ( (where
== CSEG
&& sclass
== N_TEXT
||
273 where
!= CSEG
&& (sclass
== N_DATA
|| sclass
== N_BSS
)) )
280 PUBLIC
void printhex(v
)
292 PRIVATE
void outsym( sp
, off
)
299 for ( s
= sp
->n_name
, send
= s
+ sizeof sp
->n_name
; *s
!= 0 && s
< send
; ++s
)
301 if ( (off
-= sp
->n_value
) != 0 )
308 /* shell sort symbols on value */
310 PRIVATE
void sortsyms( array
, top
)
317 register struct nlist
*left
;
318 register struct nlist
*right
;
319 struct nlist swaptemp
;
323 /* choose gaps according to Knuth V3 p95 */
324 for ( gap
= 1, i
= 4; (j
= 3 * i
+ 1) < size
; gap
= i
, i
= j
)
328 for ( j
= gap
; j
< size
; ++j
)
329 for ( i
= j
- gap
; i
>= 0; i
-= gap
)
332 right
= array
+ (i
+ gap
);
333 if ( (off_t
) left
->n_value
<=
341 while ( (gap
/= 3) != 0 );
344 PUBLIC
void symbolic( value
, separator
)
348 register struct nlist
*sp
;
352 if ( type_of_exec
== GNU_SYMBOLS
) {
353 gnu_symbolic( value
, separator
);
360 if (value
< st_addr
|| value
> end_addr
) {
367 if ( (sp
= findsval( value
, CSEG
)) != NULL
)
371 else if ( (sp
= findsval( value
, DSEG
)) != NULL
)
378 off
= value
- st_addr
;
385 outbyte( separator
);
389 PRIVATE
int symeq( t
, sp
)
393 return strncmp( t
, sp
->n_name
, sizeof sp
->n_name
) == 0;
396 PRIVATE
int symprefix( t
, sp
)
403 for ( ; *t
== '_'; ++t
)
405 for ( s
= sp
->n_name
, send
= s
+ sizeof sp
->n_name
;
406 s
< send
&& *s
== '_'; ++s
)
408 return strncmp( s
, t
, (size_t)(send
- s
) ) == 0;
413 /* list all symbols - test for selection criteria */
415 PUBLIC
void listsym(cmd
)
418 register struct symtab_s
*tp
;
419 register struct nlist
*sp
;
427 if( *cmd
== '\n' || *cmd
== ';' )
433 if ( type_of_exec
== GNU_SYMBOLS
) {
442 for ( sp
= tp
->start
; sp
< tp
->end
; ++sp
)
444 switch( sp
->n_sclass
& N_SECT
)
446 case N_ABS
: schar
= 'a'; break;
447 case N_TEXT
: schar
= 't'; break;
448 case N_DATA
: schar
= 'd'; break;
449 case N_BSS
: schar
= 'b'; break;
450 default: schar
= '?'; break;
453 if ( (sp
->n_sclass
& N_CLASS
) == C_EXT
&& schar
!= '?' )
456 /* check for selection */
457 if ( tchar
!= '*' && schar
!= tchar
)
460 /* print symbol type and value */
461 for ( s
= sp
->n_name
, send
= s
+ sizeof sp
->n_name
;
462 *s
!= 0 && s
< send
; ++s
) outbyte( *s
);
463 for ( ; s
<= send
; ++s
) outspace();
466 #if (_WORD_SIZE == 2)
467 outh16( (u16_t
) sp
->n_value
);
469 outh32( sp
->n_value
);
476 PUBLIC
int text_symbol(value
)
482 if ( type_of_exec
== GNU_SYMBOLS
)
483 return gnu_text_symbol(value
);
486 if ((sp
= findsval(value
, CSEG
)) != NULL
&& sp
->n_value
== value
)
495 PUBLIC
int finds_data(off
,data_seg
)
502 if ( type_of_exec
== GNU_SYMBOLS
)
503 return gnu_finds_data(off
,data_seg
);
506 if ((sp
= findsval(off
, data_seg
)) != NULL
)
515 PUBLIC
int finds_pc(pc
)
521 if ( type_of_exec
== GNU_SYMBOLS
)
522 return gnu_finds_pc(pc
);
525 if ((sp
= findsval(pc
, CSEG
)) != NULL
)