mdb(1) fixes:

- allow core file offsets with high bit set
- repair and enable gcc-compiled binary support
- fix bug leading to random command execution
- remove obsolete ptrace.2 manpage
This commit is contained in:
David van Moolenbroek 2009-12-29 21:38:26 +00:00
parent ac9a5829a2
commit d3fc0eca1d
9 changed files with 149 additions and 555 deletions

View file

@ -14,10 +14,9 @@ Dist This file
Makefile Makefile
MDB.TXT Cover file
README README file
a.out.h GNU a.out.h (copied to /usr/include/gnu)
core.c core file functions
decode.c Optional for syscalls support
gnu_load.c Optional for GNU EXEC support
gnu_sym.c Optional for GNU EXEC support
io.c I/O done here
ioctl.c Optional for syscalls support
kernel.c kernel functions
@ -28,9 +27,7 @@ mdb.1 man page
mdbdis86.c Disassembler
mdbexp.c Expression parsing
misc.c misc functions including help
gnu_sym.c Optional for GNU EXEC support
proto.h Prototypes
ptrace.2 man page
sample sample command file
sym.c Symbolic names read from exec file
syscalls.c Optional for syscalls support

View file

@ -25,8 +25,8 @@ SYSTEM =$(USR)/src
#
# i) For GNU_EXEC Support, uncomment:
#
#FOR_GNU =gnu_sym.o gnu_load.o
#DEF_GNU =-DGNU_SUPPORT
FOR_GNU =gnu_sym.o
DEF_GNU =-DGNU_SUPPORT
#
# ii) For tracing of syscalls, uncomment:
#
@ -101,11 +101,7 @@ syscalls.o: syscalls.c mdb.h $(SYSFILES) proto.h
decode.o: decode.c mdb.h $(INCLUDE)/minix/callnr.h $(SYSFILES) proto.h
ioctl.o: ioctl.c mdb.h $(SYSFILES) proto.h
gnu_sym.o: gnu_sym.c mdb.h $(INCLUDE)/gnu/a.out.h $(SYSFILES) proto.h
gnu_load.o: gnu_load.c $(INCLUDE)/gnu/a.out.h $(SYSFILES) proto.h
$(INCLUDE)/gnu/a.out.h: a.out.h
install -c -o bin a.out.h $(INCLUDE)/gnu
gnu_sym.o: gnu_sym.c mdb.h $(SYSFILES) proto.h
#
@ -115,9 +111,9 @@ $(INCLUDE)/gnu/a.out.h: a.out.h
install: mdb
install -cs -o bin mdb /usr/bin
install_man: mdb.1 ptrace.2
install_man: mdb.1
install -c -o bin mdb.1 /usr/man/man1
install -c -o bin ptrace.2 /usr/man/man2
clean:
rm -f *.o mdb

View file

@ -1,297 +0,0 @@
/*
* MINIX 1.7.x
* GNU version based on Linux 1.1.45 version
* if _MINIX_EXEC defined use old MINIX GNU format
*/
#ifndef __A_OUT_GNU_H__
#define __A_OUT_GNU_H__
#define __GNU_EXEC_MACROS__
#ifndef __STRUCT_EXEC_OVERRIDE__
struct exec
{
unsigned long a_info; /* Use macros N_MAGIC, etc for access */
unsigned a_text; /* length of text, in bytes */
unsigned a_data; /* length of data, in bytes */
unsigned a_bss; /* length of uninitialized data area for file, in bytes */
unsigned a_syms; /* length of symbol table data in file, in bytes */
unsigned a_entry; /* start address */
unsigned a_trsize; /* length of relocation info for text, in bytes */
unsigned a_drsize; /* length of relocation info for data, in bytes */
#ifdef _MINIX_EXEC
unsigned a_smagic; /* SMAGIC */
unsigned a_memsize; /* Dynamic Memory Size */
#endif
};
#ifdef _MINIX_EXEC
#define GNU_SMAGIC 0xdeadbabe
#define GNU_DYNMEM (64 * 1024)
#else
#define GNU_STACK 64 /* Default Stack */
#endif
#endif /* __STRUCT_EXEC_OVERRIDE__ */
/* these go in the N_MACHTYPE field */
enum machine_type {
#if defined (M_OLDSUN2)
M__OLDSUN2 = M_OLDSUN2,
#else
M_OLDSUN2 = 0,
#endif
#if defined (M_68010)
M__68010 = M_68010,
#else
M_68010 = 1,
#endif
#if defined (M_68020)
M__68020 = M_68020,
#else
M_68020 = 2,
#endif
#if defined (M_SPARC)
M__SPARC = M_SPARC,
#else
M_SPARC = 3,
#endif
/* skip a bunch so we don't run into any of sun's numbers */
M_386 = 100
};
#if !defined (N_MAGIC)
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
#endif
#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
#define N_SET_INFO(exec, magic, type, flags) \
((exec).a_info = ((magic) & 0xffff) \
| (((int)(type) & 0xff) << 16) \
| (((flags) & 0xff) << 24))
#define N_SET_MAGIC(exec, magic) \
((exec).a_info = (((exec).a_info & 0xffff0000) | ((magic) & 0xffff)))
#define N_SET_MACHTYPE(exec, machtype) \
((exec).a_info = \
((exec).a_info&0xff00ffff) | ((((int)(machtype))&0xff) << 16))
#define N_SET_FLAGS(exec, flags) \
((exec).a_info = \
((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
#ifdef _MINIX
#define N_SET_MEMORY(exec, mem) \
((exec).a_info = \
((exec).a_info & 0x0000FFFF) | (((mem) & 0xFFFF) << 16))
#define N_MEMORY(exec) (((exec).a_info >> 16) & 0xFFFF)
#endif
/* Code indicating object file or impure executable. */
#define OMAGIC 0407
/* Code indicating pure executable. */
#define NMAGIC 0410
/* Code indicating demand-paged executable. */
#define ZMAGIC 0413
/* This indicates a demand-paged executable with the header in the text.
The first page is unmapped to help trap NULL pointer references */
#define QMAGIC 0314
/* Code indicating core file. */
#define CMAGIC 0421
#if !defined (N_BADMAG)
#define N_BADMAG(x) (N_MAGIC(x) != OMAGIC \
&& N_MAGIC(x) != NMAGIC \
&& N_MAGIC(x) != ZMAGIC \
&& N_MAGIC(x) != QMAGIC)
#endif
#define _N_HDROFF(x) (1024 - sizeof (struct exec))
#if !defined (N_TXTOFF)
#define N_TXTOFF(x) \
(N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : \
(N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
#endif
#if !defined (N_DATOFF)
#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
#endif
#if !defined (N_TRELOFF)
#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
#endif
#if !defined (N_DRELOFF)
#define N_DRELOFF(x) (N_TRELOFF(x) + (x).a_trsize)
#endif
#if !defined (N_SYMOFF)
#define N_SYMOFF(x) (N_DRELOFF(x) + (x).a_drsize)
#endif
#if !defined (N_STROFF)
#define N_STROFF(x) (N_SYMOFF(x) + (x).a_syms)
#endif
/* Address of text segment in memory after it is loaded. */
#if !defined (N_TXTADDR)
#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? PAGE_SIZE : 0)
#endif
/* Address of data segment in memory after it is loaded.
Note that it is up to you to define SEGMENT_SIZE
on machines not listed here. */
#if defined(vax) || defined(hp300) || defined(pyr)
#define SEGMENT_SIZE page_size
#endif
#ifdef sony
#define SEGMENT_SIZE 0x2000
#endif /* Sony. */
#ifdef is68k
#define SEGMENT_SIZE 0x20000
#endif
#if defined(m68k) && defined(PORTAR)
#define PAGE_SIZE 0x400
#define SEGMENT_SIZE PAGE_SIZE
#endif
#ifndef PAGE_SIZE
#define PAGE_SIZE 1024
#endif
#ifndef SEGMENT_SIZE
#define SEGMENT_SIZE PAGE_SIZE
#endif
#define _N_SEGMENT_ROUND(x) (((x) + SEGMENT_SIZE - 1) & ~(SEGMENT_SIZE - 1))
#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
#ifndef N_DATADDR
#define N_DATADDR(x) \
(N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
: (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
#endif
/* Address of bss segment in memory after it is loaded. */
#if !defined (N_BSSADDR)
#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
#endif
#if !defined (N_NLIST_DECLARED)
struct nlist {
union {
char *n_name;
struct nlist *n_next;
long n_strx;
} n_un;
unsigned char n_type;
char n_other;
short n_desc;
unsigned long n_value;
};
#endif /* no N_NLIST_DECLARED. */
#if !defined (N_UNDF)
#define N_UNDF 0
#endif
#if !defined (N_ABS)
#define N_ABS 2
#endif
#if !defined (N_TEXT)
#define N_TEXT 4
#endif
#if !defined (N_DATA)
#define N_DATA 6
#endif
#if !defined (N_BSS)
#define N_BSS 8
#endif
#if !defined (N_FN)
#define N_FN 15
#endif
#if !defined (N_EXT)
#define N_EXT 1
#endif
#if !defined (N_TYPE)
#define N_TYPE 036
#endif
#if !defined (N_STAB)
#define N_STAB 0340
#endif
/* The following type indicates the definition of a symbol as being
an indirect reference to another symbol. The other symbol
appears as an undefined reference, immediately following this symbol.
Indirection is asymmetrical. The other symbol's value will be used
to satisfy requests for the indirect symbol, but not vice versa.
If the other symbol does not have a definition, libraries will
be searched to find a definition. */
#define N_INDR 0xa
/* The following symbols refer to set elements.
All the N_SET[ATDB] symbols with the same name form one set.
Space is allocated for the set in the text section, and each set
element's value is stored into one word of the space.
The first word of the space is the length of the set (number of elements).
The address of the set is made into an N_SETV symbol
whose name is the same as the name of the set.
This symbol acts like a N_DATA global symbol
in that it can satisfy undefined external references. */
/* These appear as input to LD, in a .o file. */
#define N_SETA 0x14 /* Absolute set element symbol */
#define N_SETT 0x16 /* Text set element symbol */
#define N_SETD 0x18 /* Data set element symbol */
#define N_SETB 0x1A /* Bss set element symbol */
/* This is output from LD. */
#define N_SETV 0x1C /* Pointer to set vector in data area. */
#if !defined (N_RELOCATION_INFO_DECLARED)
/* This structure describes a single relocation to be performed.
The text-relocation section of the file is a vector of these structures,
all of which apply to the text section.
Likewise, the data-relocation section applies to the data section. */
struct relocation_info
{
/* Address (within segment) to be relocated. */
int r_address;
/* The meaning of r_symbolnum depends on r_extern. */
unsigned int r_symbolnum:24;
/* Nonzero means value is a pc-relative offset
and it should be relocated for changes in its own address
as well as for changes in the symbol or section specified. */
unsigned int r_pcrel:1;
/* Length (as exponent of 2) of the field to be relocated.
Thus, a value of 2 indicates 1<<2 bytes. */
unsigned int r_length:2;
/* 1 => relocate with value of symbol.
r_symbolnum is the index of the symbol
in file's the symbol table.
0 => relocate with the address of a segment.
r_symbolnum is N_TEXT, N_DATA, N_BSS or N_ABS
(the N_EXT bit may be set also, but signifies nothing). */
unsigned int r_extern:1;
/* Four bits that aren't used, but when writing an object file
it is desirable to clear them. */
#ifdef NS32K
unsigned r_bsr:1;
unsigned r_disp:1;
unsigned r_pad:2;
#else
unsigned int r_pad:4;
#endif
};
#endif /* no N_RELOCATION_INFO_DECLARED. */
#endif /* __A_OUT_GNU_H__ */

View file

@ -31,9 +31,9 @@ PRIVATE struct file {
int fid;
char *name;
long cblock;
long tmap[3];
long dmap[3];
long smap[3];
unsigned long tmap[3];
unsigned long dmap[3];
unsigned long smap[3];
char buf[BSIZE + BSIZE];
} Core_File, *core_file;
@ -94,7 +94,7 @@ long h = (long) h_size;
end_addr = fp->e2;
fp->b1 = 0;
fp->e1 = -1;
fp->e1 = 0;
fp->f1 = 0;
}
#endif
@ -305,7 +305,7 @@ char *filename;
}
core_file->b1 = core_file->b2 = core_file->b3 = 0;
core_file->e1 = core_file->e2 = core_file->e3 = -1;
core_file->e1 = core_file->e2 = core_file->e3 = 0;
core_file->f1 = core_file->f2 = core_file->f3 = 0;
core_file->cblock = -1;
@ -334,7 +334,7 @@ char *filename;
}
core_file->b1 = core_file->b2 = core_file->b3 = 0;
core_file->e1 = core_file->e2 = core_file->e3 = -1;
core_file->e1 = core_file->e2 = core_file->e3 = 0;
core_file->f1 = core_file->f2 = core_file->f3 = 0;
core_file->cblock = -1;

View file

@ -1,76 +0,0 @@
/*
* gnu_load for mdb.c
*/
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <gnu/a.out.h>
_PROTOTYPE( unsigned int gnu_load, (char *filename, struct nlist **start) );
_PROTOTYPE( void do_error, (char *message) );
unsigned int gnu_load( filename, start)
char *filename;
struct nlist **start;
{
struct exec header;
unsigned int nsym, string_size;
char *names;
struct nlist *p;
int fd;
if ( (fd = open( filename, 0)) < 0 ||
read( fd, (char *) &header, sizeof header ) != sizeof header )
{
do_error( "gnu_load" );
if ( fd >= 0) close( fd );
return 0;
}
if ( lseek( fd, N_STROFF( header ), 0 ) != N_STROFF( header ) )
{
do_error( "gnu_load - reading header" );
close( fd );
return 0;
}
if ( read( fd, (char *) &string_size, sizeof string_size ) < 0 )
{
do_error( "gnu_load - reading header" );
close( fd );
return 0;
}
if ( (int) header.a_syms < 0 ||
(unsigned) header.a_syms != header.a_syms ||
(*start = (struct nlist *) malloc( (unsigned) header.a_syms +
string_size ))
== (struct nlist *) NULL &&
header.a_syms != 0 )
{
close( fd );
return 0;
}
lseek( fd, N_SYMOFF( header ), 0 );
if ( read( fd, (char *) *start, (int) header.a_syms + string_size ) < 0 )
{
do_error( "gnu_load - reading symbols" );
close( fd );
return 0;
}
close( fd );
nsym = (unsigned int) header.a_syms / sizeof (struct nlist);
names = (char *) *start + header.a_syms;
for ( p = *start; p < *start + nsym; p++)
if(p->n_un.n_strx)
p->n_un.n_name = names + p->n_un.n_strx;
return nsym;
}

View file

@ -12,41 +12,115 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#if GNU_SUPPORT
#include <gnu/a.out.h>
#endif
#include <fcntl.h>
#include <minix/a.out.h>
#include "proto.h"
#if GNU_SUPPORT
_PROTOTYPE( PUBLIC unsigned int gnu_load, (char *filename, struct nlist **start) );
#endif
#define NN_UNDF 0
#define NN_ABS 2
#define NN_TEXT 4
#define NN_DATA 6
#define NN_BSS 8
#define NN_FN 15
#define NN_EXT 1
#define NN_TYPE 036
struct newnlist {
union {
char *n_name;
struct newnlist *n_next;
long n_strx;
} n_un;
unsigned char n_type;
char n_other;
short n_desc;
unsigned long n_value;
};
struct symtab_s
{
struct nlist *start;
struct nlist *end;
struct newnlist *start;
struct newnlist *end;
unsigned int nsym;
};
PRIVATE struct symtab_s symtab;
FORWARD _PROTOTYPE( void gnu_sort , (struct nlist *array , struct nlist *top ));
FORWARD _PROTOTYPE( int gnu_symeq , (char *t , struct nlist *sp ));
FORWARD _PROTOTYPE( int gnu_symprefix , (char *t , struct nlist *sp ));
FORWARD _PROTOTYPE( struct nlist *gnu_sname, (char *name, int is_text, int allflag) );
FORWARD _PROTOTYPE( struct nlist *gnu_sval, (off_t value, int where) );
FORWARD _PROTOTYPE( void gnu_sym, (struct nlist *sp, off_t off) );
FORWARD _PROTOTYPE( void gnu_sort , (struct newnlist *array ,
struct newnlist *top ));
FORWARD _PROTOTYPE( int gnu_symeq , (char *t , struct newnlist *sp ));
FORWARD _PROTOTYPE( int gnu_symprefix , (char *t , struct newnlist *sp ));
FORWARD _PROTOTYPE( struct newnlist *gnu_sname, (char *name, int is_text,
int allflag) );
FORWARD _PROTOTYPE( struct newnlist *gnu_sval, (off_t value, int where) );
FORWARD _PROTOTYPE( void gnu_sym, (struct newnlist *sp, off_t off) );
PUBLIC void gnu_init( filename )
char *filename;
{
struct exec header;
unsigned int string_size;
char *names;
struct newnlist *p;
int fd;
register struct symtab_s *tp;
tp = &symtab;
if ( (fd = open( filename, O_RDONLY)) < 0 ||
read( fd, (char *) &header, sizeof header ) != sizeof header )
{
do_error( "gnu_load - reading header" );
if ( fd >= 0) close( fd );
return;
}
tp->nsym = gnu_load(filename, &tp->start);
if ( (string_size = lseek( fd, 0, SEEK_END ) ) == -1 )
{
do_error( "gnu_load - determining file size" );
close( fd );
return;
}
string_size -= A_SYMPOS( header );
if ( (int) header.a_syms < 0 ||
(unsigned) header.a_syms != header.a_syms ||
(tp->start = (struct newnlist *) malloc( string_size ))
== (struct newnlist *) NULL &&
header.a_syms != 0 )
{
do_error( "gnu_load - allocating memory" );
close( fd );
return;
}
if ( lseek( fd, A_SYMPOS( header ), SEEK_SET ) != A_SYMPOS( header ) )
{
do_error( "gnu_load - reading header" );
close( fd );
return;
}
if ( read( fd, (char *) tp->start, string_size ) < 0 )
{
do_error( "gnu_load - reading symbols" );
close( fd );
return;
}
close( fd );
tp->nsym = (unsigned int) header.a_syms / sizeof (struct newnlist);
tp->end = tp->start + tp->nsym;
names = (char *) tp->start + header.a_syms;
for ( p = tp->start; p < tp->end; p++)
if(p->n_un.n_strx)
p->n_un.n_name = names + p->n_un.n_strx;
else
p->n_un.n_name = "";
/* sort on value only, name search not used much and storage a problem */
Printf("Sorting %d GNU symbols ....", tp->nsym );
gnu_sort( tp->start, tp->end );
@ -54,12 +128,11 @@ char *filename;
}
PUBLIC long gnu_symbolvalue( name, is_text )
char *name;
int is_text;
{
register struct nlist *sp;
register struct newnlist *sp;
sp = gnu_sname(name,is_text,0);
if (sp != NULL)
return sp->n_value;
@ -68,7 +141,7 @@ int is_text;
}
PRIVATE struct nlist *gnu_sname( name, is_text, allflag )
PRIVATE struct newnlist *gnu_sname( name, is_text, allflag )
char *name;
int is_text;
int allflag;
@ -77,7 +150,7 @@ int allflag;
unsigned char sclass;
int schar;
char *send;
register struct nlist *sp;
register struct newnlist *sp;
register struct symtab_s *tp;
tp = &symtab;
@ -95,15 +168,15 @@ int allflag;
outbyte( *s );
for ( ; s <= send; ++s )
outspace();
switch( sp->n_type & N_TYPE )
switch( sp->n_type & NN_TYPE )
{
case N_ABS: schar = 'a'; break;
case N_TEXT: schar = 't'; break;
case N_DATA: schar = 'd'; break;
case N_BSS: schar = 'b'; break;
case NN_ABS: schar = 'a'; break;
case NN_TEXT: schar = 't'; break;
case NN_DATA: schar = 'd'; break;
case NN_BSS: schar = 'b'; break;
default: schar = '?'; break;
}
if ( (sp->n_type & N_EXT) && schar != '?' )
if ( (sp->n_type & NN_EXT) && schar != '?' )
schar += 'A' - 'a';
outbyte( schar );
outspace();
@ -117,9 +190,10 @@ int allflag;
/* find symbol by dumb linear search */
for ( sp = tp->start; sp < tp->end; ++sp )
{
sclass = sp->n_type & N_TYPE;
if ( (is_text && sclass == N_TEXT ||
!is_text && (sclass == N_DATA || sclass == N_BSS)) &&
sclass = sp->n_type & NN_TYPE;
if ( (is_text && sclass == NN_TEXT ||
!is_text && (sclass == NN_DATA ||
sclass == NN_BSS)) &&
gnu_symeq( name, sp ) )
return sp;
}
@ -127,7 +201,7 @@ int allflag;
return NULL;
}
PRIVATE struct nlist *gnu_sval( value, where )
PRIVATE struct newnlist *gnu_sval( value, where )
off_t value;
int where;
{
@ -135,7 +209,7 @@ int where;
int middle;
int right;
unsigned char sclass;
register struct nlist *sp;
register struct newnlist *sp;
register struct symtab_s *tp;
tp = &symtab;
@ -154,10 +228,11 @@ int where;
/* otherwise tp->start + right may wrap around to > tp->start !! */
for ( sp = tp->start + right; sp >= tp->start; --sp )
{
if ( !(sp->n_type & N_EXT) ) continue;
sclass = sp->n_type & N_TYPE;
if ( (where == CSEG && sclass == N_TEXT ||
where != CSEG && (sclass == N_DATA || sclass == N_BSS)) )
if ( !(sp->n_type & NN_EXT) ) continue;
sclass = sp->n_type & NN_TYPE;
if ( (where == CSEG && sclass == NN_TEXT) ||
(where != CSEG &&
(sclass == NN_DATA || sclass == NN_BSS)) )
return sp;
}
return NULL;
@ -165,7 +240,7 @@ int where;
PRIVATE void gnu_sym( sp, off )
struct nlist *sp;
struct newnlist *sp;
off_t off;
{
register char *s;
@ -183,15 +258,15 @@ off_t off;
/* shell sort symbols on value */
PRIVATE void gnu_sort( array, top )
struct nlist *array;
struct nlist *top;
struct newnlist *array;
struct newnlist *top;
{
int gap;
int i;
int j;
register struct nlist *left;
register struct nlist *right;
struct nlist swaptemp;
register struct newnlist *left;
register struct newnlist *right;
struct newnlist swaptemp;
int size;
size = top - array;
@ -220,7 +295,7 @@ PUBLIC void gnu_symbolic( value, separator )
off_t value;
int separator;
{
register struct nlist *sp;
register struct newnlist *sp;
long off;
if (value < st_addr || value > end_addr) {
@ -254,14 +329,14 @@ int separator;
PRIVATE int gnu_symeq( t, sp )
register char *t;
struct nlist *sp;
struct newnlist *sp;
{
return strncmp( t, sp->n_un.n_name, strlen(t) ) == 0;
}
PRIVATE int gnu_symprefix( t, sp )
register char *t;
struct nlist *sp;
struct newnlist *sp;
{
register char *s;
char *send;
@ -282,7 +357,7 @@ PUBLIC void gnu_listsym( tchar )
char tchar;
{
register struct symtab_s *tp;
register struct nlist *sp;
register struct newnlist *sp;
char *s;
char *send;
char schar;
@ -291,16 +366,16 @@ char tchar;
tp = &symtab;
for ( sp = tp->start; sp < tp->end; ++sp )
{
switch( sp->n_type & N_TYPE )
switch( sp->n_type & NN_TYPE )
{
case N_ABS: schar = 'a'; break;
case N_TEXT: schar = 't'; break;
case N_DATA: schar = 'd'; break;
case N_BSS: schar = 'b'; break;
case NN_ABS: schar = 'a'; break;
case NN_TEXT: schar = 't'; break;
case NN_DATA: schar = 'd'; break;
case NN_BSS: schar = 'b'; break;
default: schar = '?'; break;
}
if ( (sp->n_type & N_EXT) && schar != '?' )
if ( (sp->n_type & NN_EXT) && schar != '?' )
schar += 'A' - 'a';
/* check for selection */
@ -321,7 +396,7 @@ char tchar;
PUBLIC int gnu_text_symbol(value)
off_t value;
{
struct nlist *sp;
struct newnlist *sp;
if ((sp = gnu_sval(value, CSEG)) != NULL && sp->n_value == value)
{
@ -336,7 +411,7 @@ PUBLIC int gnu_finds_data(off,data_seg)
off_t off;
int data_seg;
{
struct nlist *sp;
struct newnlist *sp;
if ((sp = gnu_sval(off, data_seg)) != NULL)
{
@ -350,7 +425,7 @@ struct nlist *sp;
PUBLIC int gnu_finds_pc(pc)
off_t pc;
{
struct nlist *sp;
struct newnlist *sp;
if ((sp = gnu_sval(pc, CSEG)) != NULL)
{

View file

@ -689,7 +689,7 @@ PRIVATE void command()
case 'X': /* print instruction - X n [, n] */
lj = strtol(cmd, &cmd, 0);
lk = 0;
if (*cmd != '\0')
if (*cmd != '\n')
lk = strtol(++cmd, &cmd, 0);
if (curpid > 0)
dasm(exp + lk, lj ? lj : 1, 1);

View file

@ -1,87 +0,0 @@
.TH PTRACE 2
.SH NAME
ptrace \- ptrace system call.
.SH SYNOPSIS
.ft B
.nf
.sp
#include <sys/ptrace.h>
long ptrace( int req, pid_t pid, long addr, long data)
.fi
.ft P
.SH DESCRIPTION
.sp
Ptrace(2) is called with following arguments:
.sp
.br
req
request
.br
pid
process id
.br
addr
address
.br
data
data
.br
.SH REQUESTS
.sp
.I
T_STOP
stop the process.
.br
.I
T_OK
enable tracing by parent for this process.
.br
.I
T_GETINS
return value from instruction space
.br
.I
T_GETDATA
return value from data space.
.br
.I
T_GETUSER
return value from process table. See proc.h in kernel.
.br
.I
T_SETINS
set value from instruction space.
.br
.I
T_SETDATA
set value from data space.
.br
.I
T_SETUSER
set value in process table.
.br
.I
T_RESUME
resume execution.
.br
.I
T_EXIT
exit. Turn off tracing.
.br
.I
T_STEP
set trace bit to enable single step.
.SH "SEE ALSO"
.sp
mdb(1)
.SH DIAGNOSTICS
.sp
errno is set by ptrace().
.SH FILES
.sp
/usr/src/kernel/proc.h for process table info.

View file

@ -11,12 +11,6 @@
#include <a.out.h>
#include "proto.h"
#if GNU_SUPPORT
#define ZMAGIC 0413
#define NMAGIC 0410
#define QMAGIC 0314
#endif
struct symtab_s
{
struct nlist *start;
@ -113,20 +107,6 @@ long magic;
/* Check MAGIC number */
if (hdr->a_magic[0] != A_MAGIC0 || hdr->a_magic[1] != A_MAGIC1) {
#if GNU_SUPPORT
memcpy(&magic, hdr, sizeof(long));
/* Clear bits */
magic &= 0xFFFF;
if ( magic == ZMAGIC || magic == QMAGIC ) {
is_separate = FALSE;
return GNU_SYMBOLS;
}
if ( magic == NMAGIC ) {
is_separate = TRUE;
return GNU_SYMBOLS;
}
#endif
Printf("mdb: invalid magic number in exec header - %02x %02x\n",
hdr->a_magic[0],
hdr->a_magic[1]);
@ -155,6 +135,12 @@ long magic;
if (hdr->a_flags & A_SEP)
is_separate = TRUE;
#endif
#if GNU_SUPPORT
if (hdr->a_flags & A_NSYM)
return GNU_SYMBOLS;
#endif
/*
* A_EXEC is not being set by current cc
* It was set in Minix 1.5.0