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:
parent
ac9a5829a2
commit
d3fc0eca1d
9 changed files with 149 additions and 555 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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__ */
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue