23 static struct symtab_s symtab
;
24 static int type_of_exec
;
26 static int check_exec(struct exec
*hdr
);
27 static void sortsyms(struct nlist
*array
, struct nlist
*top
);
28 static int symeq(char *t
, struct nlist
*sp
);
29 static int symprefix(char *t
, struct nlist
*sp
);
30 static struct nlist
*findsname(char *name
, int is_text
, int allflag
);
31 static void outsym(struct nlist
*sp
, off_t off
);
32 static struct nlist
*findsval(off_t value
, int where
);
34 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 static 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",
117 #if defined(__i386__)
118 if (hdr
->a_cpu
!= A_I80386
)
121 Printf("mdb: invalid cpu in exec header - %04x\n",
128 if (hdr
->a_flags
& A_SEP
)
133 if (hdr
->a_flags
& A_NSYM
)
138 * A_EXEC is not being set by current cc
139 * It was set in Minix 1.5.0
142 /* Check flags - separate I & D or not */
143 if (hdr
->a_flags
& A_EXEC
)
146 Printf("mdb: object file not exec %04x\n",
151 return MINIX_SYMBOLS
;
155 long symbolvalue( name
, is_text
)
159 register struct nlist
*sp
;
162 if ( type_of_exec
== GNU_SYMBOLS
)
163 return gnu_symbolvalue( name
, is_text
);
167 sp
= findsname(name
, is_text
, 0);
174 static struct nlist
*findsname( name
, is_text
, allflag
)
180 unsigned char sclass
;
183 register struct nlist
*sp
;
184 register struct symtab_s
*tp
;
189 /* find and print all matching symbols */
190 for ( sp
= tp
->start
; sp
< tp
->end
; ++sp
)
192 if ( symprefix( name
, sp
) )
195 for ( s
= sp
->n_name
, send
= s
+ sizeof sp
->n_name
;
196 *s
!= 0 && s
< send
; ++s
)
198 for ( ; s
<= send
; ++s
)
200 switch( sp
->n_sclass
& N_SECT
)
202 case N_ABS
: schar
= 'a'; break;
203 case N_TEXT
: schar
= 't'; break;
204 case N_DATA
: schar
= 'd'; break;
205 case N_BSS
: schar
= 'b'; break;
206 default: schar
= '?'; break;
208 if ( (sp
->n_sclass
& N_CLASS
) == C_EXT
&& schar
!= '?' )
212 outh32( sp
->n_value
);
219 /* find symbol by dumb linear search */
220 for ( sp
= tp
->start
; sp
< tp
->end
; ++sp
)
222 sclass
= sp
->n_sclass
& N_SECT
;
223 if ( (is_text
&& sclass
== N_TEXT
||
224 !is_text
&& (sclass
== N_DATA
|| sclass
== N_BSS
)) &&
232 static struct nlist
*findsval( value
, where
)
239 unsigned char sclass
;
240 register struct nlist
*sp
;
241 register struct symtab_s
*tp
;
245 /* find last symbol with value <= desired one by binary search */
246 for ( left
= 0, right
= tp
->nsym
- 1; left
<= right
; )
248 middle
= (left
+ right
) / 2;
249 sp
= tp
->start
+ middle
;
250 if ( value
< sp
->n_value
)
256 /* otherwise tp->start + right may wrap around to > tp->start !! */
257 for ( sp
= tp
->start
+ right
; sp
>= tp
->start
; --sp
)
259 if ( (sp
->n_sclass
& N_CLASS
) != C_EXT
) continue;
260 sclass
= sp
->n_sclass
& N_SECT
;
261 if ( (where
== CSEG
&& sclass
== N_TEXT
||
262 where
!= CSEG
&& (sclass
== N_DATA
|| sclass
== N_BSS
)) )
281 static void outsym( sp
, off
)
288 for ( s
= sp
->n_name
, send
= s
+ sizeof sp
->n_name
; *s
!= 0 && s
< send
; ++s
)
290 if ( (off
-= sp
->n_value
) != 0 )
297 /* shell sort symbols on value */
299 static void sortsyms( array
, top
)
306 register struct nlist
*left
;
307 register struct nlist
*right
;
308 struct nlist swaptemp
;
312 /* choose gaps according to Knuth V3 p95 */
313 for ( gap
= 1, i
= 4; (j
= 3 * i
+ 1) < size
; gap
= i
, i
= j
)
317 for ( j
= gap
; j
< size
; ++j
)
318 for ( i
= j
- gap
; i
>= 0; i
-= gap
)
321 right
= array
+ (i
+ gap
);
322 if ( (off_t
) left
->n_value
<=
330 while ( (gap
/= 3) != 0 );
333 void symbolic( value
, separator
)
337 register struct nlist
*sp
;
341 if ( type_of_exec
== GNU_SYMBOLS
) {
342 gnu_symbolic( value
, separator
);
349 if (value
< st_addr
|| value
> end_addr
) {
356 if ( (sp
= findsval( value
, CSEG
)) != NULL
)
360 else if ( (sp
= findsval( value
, DSEG
)) != NULL
)
367 off
= value
- st_addr
;
374 outbyte( separator
);
378 static int symeq( t
, sp
)
382 return strncmp( t
, sp
->n_name
, sizeof sp
->n_name
) == 0;
385 static int symprefix( t
, sp
)
392 for ( ; *t
== '_'; ++t
)
394 for ( s
= sp
->n_name
, send
= s
+ sizeof sp
->n_name
;
395 s
< send
&& *s
== '_'; ++s
)
397 return strncmp( s
, t
, (size_t)(send
- s
) ) == 0;
402 /* list all symbols - test for selection criteria */
407 register struct symtab_s
*tp
;
408 register struct nlist
*sp
;
416 if( *cmd
== '\n' || *cmd
== ';' )
422 if ( type_of_exec
== GNU_SYMBOLS
) {
431 for ( sp
= tp
->start
; sp
< tp
->end
; ++sp
)
433 switch( sp
->n_sclass
& N_SECT
)
435 case N_ABS
: schar
= 'a'; break;
436 case N_TEXT
: schar
= 't'; break;
437 case N_DATA
: schar
= 'd'; break;
438 case N_BSS
: schar
= 'b'; break;
439 default: schar
= '?'; break;
442 if ( (sp
->n_sclass
& N_CLASS
) == C_EXT
&& schar
!= '?' )
445 /* check for selection */
446 if ( tchar
!= '*' && schar
!= tchar
)
449 /* print symbol type and value */
450 for ( s
= sp
->n_name
, send
= s
+ sizeof sp
->n_name
;
451 *s
!= 0 && s
< send
; ++s
) outbyte( *s
);
452 for ( ; s
<= send
; ++s
) outspace();
455 outh32( sp
->n_value
);
461 int text_symbol(value
)
467 if ( type_of_exec
== GNU_SYMBOLS
)
468 return gnu_text_symbol(value
);
471 if ((sp
= findsval(value
, CSEG
)) != NULL
&& sp
->n_value
== value
)
480 int finds_data(off
,data_seg
)
487 if ( type_of_exec
== GNU_SYMBOLS
)
488 return gnu_finds_data(off
,data_seg
);
491 if ((sp
= findsval(off
, data_seg
)) != NULL
)
506 if ( type_of_exec
== GNU_SYMBOLS
)
507 return gnu_finds_pc(pc
);
510 if ((sp
= findsval(pc
, CSEG
)) != NULL
)