dis386 - a disassembler for ack
- it can disassemble object files (dis386o) and executables (dis386a) - only useful for as long as we still have ack
This commit is contained in:
parent
e2570d9b1b
commit
98ddbffe6e
|
@ -9,7 +9,7 @@ SUBDIR= aal add_route adduser advent arp ash at autil awk \
|
|||
chmod chown chroot ci cksum cleantmp clear cmp co \
|
||||
comm compress cp crc cron crontab cut date \
|
||||
dd de decomp16 DESCRIBE dev2name devsize df dhcpd \
|
||||
dhrystone diff dirname dis88 diskctl du dumpcore \
|
||||
dhrystone diff dirname dis386 dis88 diskctl du dumpcore \
|
||||
ed eject elle elvis env expand factor file \
|
||||
find finger fingerd fix fold format fortune fsck.mfs \
|
||||
fsck1 ftp101 ftpd200 gcov-pull getty grep gomoku head hexdump host \
|
||||
|
|
9
commands/dis386/Makefile
Normal file
9
commands/dis386/Makefile
Normal file
|
@ -0,0 +1,9 @@
|
|||
# Makefile for dis386
|
||||
|
||||
PROGS= dis386e dis386o
|
||||
SRCS.dis386e=dise.c misc.c unasm.c
|
||||
SRCS.dis386o=diso.c misc.c unasm.c
|
||||
MAN.dis386e=
|
||||
MAN.dis386o=
|
||||
|
||||
.include <bsd.prog.mk>
|
56
commands/dis386/const.h
Normal file
56
commands/dis386/const.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/* const.h - constants for db.
|
||||
*
|
||||
* $Id: const.h,v 1.0 1990/10/06 12:00:00 cwr Exp cwr $
|
||||
*/
|
||||
|
||||
/* general constants */
|
||||
#define FALSE 0
|
||||
#undef NULL
|
||||
#define NULL 0
|
||||
#define TRUE 1
|
||||
|
||||
/* C tricks */
|
||||
#define EXTERN extern
|
||||
#define FORWARD static
|
||||
#define PRIVATE static
|
||||
#define PUBLIC
|
||||
|
||||
/* ASCII codes */
|
||||
#define CAN 24
|
||||
#define CR 13
|
||||
#define EOF (-1)
|
||||
#define LF 10
|
||||
#define XOFF 19
|
||||
|
||||
/* hardware processor-specific for 8088 through 80386 */
|
||||
#ifndef HCLICK_SIZE
|
||||
#define HCLICK_SIZE 0x10
|
||||
#endif
|
||||
#define IF 0x0200 /* interrupt disable bit in flags */
|
||||
#define INT_BREAKPOINT 0xCC /* byte for breakpoint interrupt */
|
||||
#define LINEARADR(seg, off) \
|
||||
(HCLICK_SIZE * (physoff_t) (segment_t) (seg) + (off))
|
||||
#define TF 0x0100 /* trap bit in flags */
|
||||
|
||||
/* hardware processor-specific for 80386 and emulated for others */
|
||||
#define BS 0x4000 /* single-step bit in dr6 */
|
||||
|
||||
/* use hardware codes for segments for simplest decoding */
|
||||
#define CSEG 0x2E /* 8088 through 80386 */
|
||||
#define DSEG 0x3E
|
||||
#define ESEG 0x26
|
||||
#define FSEG 0x64
|
||||
#define GSEG 0x65 /* 80386 only */
|
||||
#define SSEG 0x36
|
||||
|
||||
/* software machine-specific for PC family */
|
||||
#define BIOS_DATA_SEG 0x40
|
||||
# define KB_FLAG 0x17 /* offset to 16-bits of keyboard shift flags */
|
||||
|
||||
/* switches to handle non-conforming compilers */
|
||||
#define UCHAR_BUG /* compiler converts unsigned chars wrong */
|
||||
|
||||
#ifdef UCHAR_BUG
|
||||
# define UCHAR(x) ((x) & 0xFF)
|
||||
#endif
|
||||
|
77
commands/dis386/dis386.doc
Normal file
77
commands/dis386/dis386.doc
Normal file
|
@ -0,0 +1,77 @@
|
|||
Dis36: a static disassembler for Minix 2.0. C W Rose, 20 Oct 97.
|
||||
|
||||
SUMMARY
|
||||
|
||||
This is the second release of dis386, a disassembler for Minix 2.0 At present
|
||||
it is comprised of two programs, dise which understands executable files, and
|
||||
diso which understands object files. The programs have been written using as
|
||||
much common code as possible, and in time they will be merged. Meantime, they
|
||||
are easier to debug separately.
|
||||
|
||||
The two programs are both front ends for Bruce Evan's x86 disassembler. The
|
||||
disassembler can handle both 16-bit and 32-bit code, but since the programs
|
||||
use large data tables (kept in memory for speedy access) they have been tested
|
||||
only on 32-bit Minix.
|
||||
|
||||
The changes between versions 1.0 and 1.1 are small, but add to the ease of
|
||||
use: addresses can now be entered in decimal or hexadecimal (leading 0x),
|
||||
and starting offset and program counter now have more intelligble values.
|
||||
|
||||
OPTIONS
|
||||
|
||||
Object, executable and core files have the following structures, where
|
||||
Name is the section name, and Option the option needed to display the section.
|
||||
|
||||
Object file Executable file Core file
|
||||
Name Option Name Option Name Option
|
||||
Header } h Header h Memory map m
|
||||
Section headers } Process table p
|
||||
Sections - Sections - Sections -
|
||||
text t text t text t
|
||||
rom m
|
||||
data d data d data d
|
||||
bss - stack k
|
||||
Relocation structures r
|
||||
Symbol table s Symbol table s
|
||||
Symbol names n
|
||||
|
||||
Other options are:
|
||||
-A str set executable file name
|
||||
-C str set core file name
|
||||
-O str set object file name
|
||||
-a display all sections
|
||||
-b dump in straight binary
|
||||
-f # set the first address to be displayed
|
||||
-l # set the last address to be displayed
|
||||
-x # set debugging level
|
||||
|
||||
Not all these options are functional at present; in particular, the file type
|
||||
override of -A/C/O isn't implemented (since the programs are single-purpose).
|
||||
|
||||
The default option is -h. The default input file is a.out for dise, and test.o
|
||||
for diso. Otherwise, input is taken from the first file option on the command
|
||||
line. Output is always written to standard output, and error messages to
|
||||
standard error.
|
||||
|
||||
BUGS AND FEATURES
|
||||
|
||||
The programs search the data area for possible local symbols; generally, these
|
||||
are the start of strings. At the moment this search is limited, and accepts
|
||||
even single printing characters as strings; it should probably accept only
|
||||
runs of three or more characters.
|
||||
|
||||
There is no search for local text symbols, as opposed to data symbols; this
|
||||
would need two full passes over the text with the disassembler, and doesn't
|
||||
seem worthwhile. Once the data symbols are out of the way, the disassembled
|
||||
text is fairly easy to read.
|
||||
|
||||
The programs do a fair amount of error checking to ensure that they are
|
||||
using eg. addresses that are within scope, but if they do fail they tend
|
||||
to abandon the task completely and bale out with a (supposedly informative)
|
||||
error message.
|
||||
|
||||
There are many apparent dead-ends in the code, left as hooks for later
|
||||
additions.
|
||||
|
||||
/* eof */
|
||||
|
46
commands/dis386/dis386.h
Normal file
46
commands/dis386/dis386.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* dis386.h: header file for dis386.c.
|
||||
*
|
||||
* $Id: dis386.h,v 1.1 1997/10/20 12:00:00 cwr Exp cwr $
|
||||
*
|
||||
* Written by C W Rose.
|
||||
*/
|
||||
|
||||
#ifndef EXTERN
|
||||
#define EXTERN extern
|
||||
#endif
|
||||
|
||||
/* Generally used variables */
|
||||
struct locname { /* local symbol table entry */
|
||||
char l_name[8]; /* symbol name */
|
||||
unsigned char l_sclass; /* storage class */
|
||||
long l_value; /* symbol value */
|
||||
struct locname *l_next; /* pointer to next entry */
|
||||
};
|
||||
EXTERN struct locname *locsym[MAXSECT]; /* local symbol tables */
|
||||
|
||||
EXTERN FILE *aoutfp; /* executable file pointer */
|
||||
EXTERN FILE *corefp; /* core file pointer */
|
||||
EXTERN FILE *disfp; /* disassembly file pointer */
|
||||
EXTERN FILE *objfp; /* object file pointer */
|
||||
EXTERN FILE *symfp; /* symbol file pointer */
|
||||
|
||||
/* executable file variables */
|
||||
EXTERN struct exec a_hdrbuf; /* executable header structure */
|
||||
EXTERN struct nlist *a_symtab; /* executable symbol table */
|
||||
|
||||
/* .o file variables */
|
||||
EXTERN struct outhead o_hdrbuf; /* object file header data */
|
||||
EXTERN struct outsect o_sectab[MAXSECT];/* object file section data */
|
||||
EXTERN char *o_secnam[MAXSECT]; /* object file section names */
|
||||
EXTERN struct outrelo *o_reltab; /* object file relocation table */
|
||||
EXTERN struct outname *o_symtab; /* object file symbol table */
|
||||
EXTERN char *o_strtab; /* object file symbol names */
|
||||
|
||||
/* Generally used functions */
|
||||
PUBLIC int dasm(unsigned long addr, unsigned long count); /* disassemble opcodes */
|
||||
|
||||
/*
|
||||
* EOF
|
||||
*/
|
||||
|
1036
commands/dis386/dise.c
Normal file
1036
commands/dis386/dise.c
Normal file
File diff suppressed because it is too large
Load diff
1322
commands/dis386/diso.c
Normal file
1322
commands/dis386/diso.c
Normal file
File diff suppressed because it is too large
Load diff
937
commands/dis386/misc.c
Normal file
937
commands/dis386/misc.c
Normal file
|
@ -0,0 +1,937 @@
|
|||
/*
|
||||
* misc.c: interface to Bruce Evan's dis86 package.
|
||||
*
|
||||
* $Id: misc.c,v 1.1 1997/10/20 12:00:00 cwr Exp cwr $
|
||||
*
|
||||
* Heavily modified by C W Rose.
|
||||
*/
|
||||
|
||||
/* Version settings */
|
||||
#define MINIX
|
||||
#undef OS2
|
||||
#undef TEST
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef MINIX
|
||||
#include <minix/config.h>
|
||||
#include <minix/const.h>
|
||||
#include <a.out.h>
|
||||
#endif
|
||||
#ifdef OS2
|
||||
typedef unsigned char u8_t;
|
||||
typedef unsigned int u16_t;
|
||||
typedef unsigned long u32_t;
|
||||
#include </local/minix/minix/config.h>
|
||||
#include </local/minix/minix/const.h>
|
||||
#include </local/minix/a.out.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "const.h"
|
||||
#include "type.h"
|
||||
#undef S_ABS /* clash with a.out.h */
|
||||
#include "out.h" /* ACK compiler output header */
|
||||
#include "var.h" /* db header */
|
||||
#include "dis386.h" /* dis386 package header */
|
||||
|
||||
/* Standard defines */
|
||||
#define FAILED -1
|
||||
#define MAYBE 0
|
||||
#define OK 1
|
||||
|
||||
/* Local defines */
|
||||
|
||||
#ifndef lint
|
||||
static char *Version = "@(#) misc.c $Revision: 1.1 $ $Date: 1997/10/20 12:00:00 $";
|
||||
#endif
|
||||
|
||||
/* Global variables */
|
||||
PRIVATE bool_t forceupper;
|
||||
PRIVATE bool_t someupper = TRUE;
|
||||
PRIVATE count_t stringcount = 0;
|
||||
PRIVATE char *string_ptr = (char *)0; /* stringptr ambiguous at 8th char */
|
||||
PRIVATE char *stringstart = (char *)0;
|
||||
|
||||
/* Externals */
|
||||
|
||||
/* Forward declarations */
|
||||
#if 0
|
||||
PUBLIC void closestring(void); /* */
|
||||
PUBLIC u8_pt get8(void); /* */
|
||||
PUBLIC u16_t get16(void); /* */
|
||||
PUBLIC u32_t get32(void); /* */
|
||||
PUBLIC void openstring(char *string, int len); /* */
|
||||
PUBLIC void outbyte(char_pt byte); /* */
|
||||
PUBLIC void outcolon(void); /* */
|
||||
PUBLIC void outcomma(void); /* */
|
||||
PUBLIC void outh4(u4_pt num); /* */
|
||||
PUBLIC void outh8(u8_pt num); /* */
|
||||
PUBLIC void outh16(u16_t num); /* */
|
||||
PUBLIC void outh32(u32_t num); /* */
|
||||
PUBLIC bool_pt outnl(void); /* */
|
||||
PUBLIC count_t outsegaddr(struct address_s *ap, offset_t addr); /* */
|
||||
PUBLIC count_t outsegreg(offset_t num); /* */
|
||||
PUBLIC void outspace(void); /* */
|
||||
PUBLIC void outstr(char *s); /* */
|
||||
PUBLIC void outtab(void); /* */
|
||||
PUBLIC void outustr(char *s); /* */
|
||||
PUBLIC count_t stringpos(void); /* */
|
||||
PUBLIC count_t stringtab(void); /* */
|
||||
PUBLIC void outrel(struct nlist *sp, offset_t off); /* */
|
||||
PUBLIC void outsym(struct nlist *sp, offset_t off); /* */
|
||||
PUBLIC struct nlist *findrval(offset_t value, int where);/* */
|
||||
PUBLIC struct nlist *findsval(offset_t value, int where);/* */
|
||||
PUBLIC int dasm(offset_t addr, offset_t count); /* */
|
||||
#endif
|
||||
|
||||
PRIVATE u8_pt peek8(struct address_s *ap); /* */
|
||||
PRIVATE u16_t peek16(struct address_s *ap); /* */
|
||||
PRIVATE u32_t peek32(struct address_s *ap); /* */
|
||||
PRIVATE struct nlist *find_arval(offset_t value, int where); /* */
|
||||
PRIVATE struct nlist *find_orval(offset_t value, int where); /* */
|
||||
PRIVATE struct nlist *find_asval(offset_t value, int where); /* */
|
||||
PRIVATE struct nlist *find_osval(offset_t value, int where); /* */
|
||||
PRIVATE int dis_one(void); /* */
|
||||
|
||||
|
||||
/*
|
||||
* Close string device.
|
||||
*/
|
||||
PUBLIC void closestring()
|
||||
{
|
||||
stringcount = 0;
|
||||
stringstart = string_ptr = (char *)0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get 8 bits from current instruction pointer and advance pointer.
|
||||
*/
|
||||
PUBLIC u8_pt get8()
|
||||
{
|
||||
u8_pt temp;
|
||||
|
||||
temp = peek8(&uptr);
|
||||
++uptr.off;
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get 16 bits from current instruction pointer and advance pointer.
|
||||
*/
|
||||
PUBLIC u16_pt get16()
|
||||
{
|
||||
u16_pt temp;
|
||||
|
||||
temp = peek16(&uptr);
|
||||
uptr.off += 2;
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get 32 bits from current instruction pointer and advance pointer.
|
||||
*/
|
||||
PUBLIC u32_t get32()
|
||||
{
|
||||
u32_t temp;
|
||||
|
||||
temp = peek32(&uptr);
|
||||
uptr.off += 4;
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Open string device.
|
||||
*/
|
||||
PUBLIC void openstring(string, len)
|
||||
char *string; int len;
|
||||
{
|
||||
while (--len >= 0)
|
||||
string[len] = '\0';
|
||||
stringcount = 0;
|
||||
stringstart = string_ptr = string;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print char to currently open output devices.
|
||||
*/
|
||||
PUBLIC void outbyte(char_pt byte)
|
||||
{
|
||||
/* convert to upper case if required */
|
||||
if (forceupper && byte >= 'a' && byte <= 'z')
|
||||
byte += 'A' - 'a';
|
||||
|
||||
/* increment the output line character count, allowing for tab stops */
|
||||
if (string_ptr != NULL) {
|
||||
if ((*string_ptr++ = byte) == '\t')
|
||||
stringcount = 8 * (stringcount / 8 + 1);
|
||||
else
|
||||
++stringcount;
|
||||
}
|
||||
else
|
||||
(void) fputc(byte, stdout);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print colon.
|
||||
*/
|
||||
PUBLIC void outcolon()
|
||||
{
|
||||
outbyte(':');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print comma.
|
||||
*/
|
||||
PUBLIC void outcomma()
|
||||
{
|
||||
outbyte(',');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print 4 bits hex.
|
||||
*/
|
||||
PUBLIC void outh4(u4_pt num)
|
||||
{
|
||||
static char hexdigits[] = "0123456789abcdef";
|
||||
|
||||
forceupper = someupper;
|
||||
outbyte(hexdigits[num % 16]);
|
||||
forceupper = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print 8 bits hex.
|
||||
*/
|
||||
PUBLIC void outh8(u8_pt num)
|
||||
{
|
||||
outh4(num / 16);
|
||||
outh4(num);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print 16 bits hex.
|
||||
*/
|
||||
PUBLIC void outh16(u16_pt num)
|
||||
{
|
||||
outh8(num / 256);
|
||||
outh8(num);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print 32 bits hex.
|
||||
*/
|
||||
PUBLIC void outh32(u32_t num)
|
||||
{
|
||||
outh16((u16_t) (num >> 16));
|
||||
outh16((u16_t) num);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print newline.
|
||||
*/
|
||||
PUBLIC bool_pt outnl()
|
||||
{
|
||||
/* bool_pt avoids change in type.h */
|
||||
outstr("\n");
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print segmented address.
|
||||
*/
|
||||
PUBLIC count_t outsegaddr(struct address_s *ap, offset_t addr)
|
||||
{
|
||||
count_t bytes_printed;
|
||||
|
||||
bytes_printed = 2;
|
||||
|
||||
if (ap->base == regs.csbase)
|
||||
outustr("cs");
|
||||
else if (ap->base == regs.dsbase)
|
||||
outustr("ds");
|
||||
else if (ap->base == regs.esbase)
|
||||
outustr("es");
|
||||
else if (processor >= 386 && ap->base == regs.fsbase)
|
||||
outustr("fs");
|
||||
else if (processor >= 386 && ap->base == regs.gsbase)
|
||||
outustr("gs");
|
||||
else if (ap->base == regs.ssbase)
|
||||
outustr("ss");
|
||||
else
|
||||
bytes_printed = outsegreg(ap->base);
|
||||
|
||||
if (bytes_printed > 4)
|
||||
outbyte('+');
|
||||
else
|
||||
outcolon();
|
||||
bytes_printed++;
|
||||
|
||||
if (ap->off >= 0x10000) {
|
||||
outh32(ap->off + addr);
|
||||
return bytes_printed + 8;
|
||||
}
|
||||
else {
|
||||
outh16((u16_pt) ap->off + addr);
|
||||
return bytes_printed + 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print segment register.
|
||||
*/
|
||||
PUBLIC count_t outsegreg(offset_t num)
|
||||
{
|
||||
if ((num % HCLICK_SIZE) != 0 || num >= 0x100000) {
|
||||
outh32(num);
|
||||
return 8;
|
||||
}
|
||||
outh16((u16_pt) (num / HCLICK_SIZE));
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print space.
|
||||
*/
|
||||
PUBLIC void outspace()
|
||||
{
|
||||
outbyte(' ');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print string.
|
||||
*/
|
||||
PUBLIC void outstr(char *s)
|
||||
{
|
||||
while (*s)
|
||||
outbyte(*s++);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print tab.
|
||||
*/
|
||||
PUBLIC void outtab()
|
||||
{
|
||||
outbyte('\t');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print string, perhaps converting case to upper.
|
||||
*/
|
||||
PUBLIC void outustr(char *s)
|
||||
{
|
||||
forceupper = someupper;
|
||||
while (*s)
|
||||
outbyte(*s++);
|
||||
forceupper = FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* p e e k 8
|
||||
*
|
||||
* Get a byte from the process.
|
||||
*
|
||||
* Returns: byte Success
|
||||
*
|
||||
* Note: aborts on read error.
|
||||
*/
|
||||
PRIVATE u8_pt peek8(struct address_s *ap)
|
||||
{
|
||||
unsigned int uj;
|
||||
|
||||
/* with luck buffering should make this fairly quick */
|
||||
if (fseek(disfp, (long)(ap->off), SEEK_CUR) != 0) {
|
||||
fprintf(stderr, "Cannot seek forward in object file\n");
|
||||
exit(1);
|
||||
}
|
||||
uj = fgetc(disfp) & 0377;
|
||||
if (fseek(disfp, -(long)(ap->off + 1), SEEK_CUR) != 0) {
|
||||
fprintf(stderr, "Cannot seek backward in object file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return uj;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* p e e k 1 6
|
||||
*
|
||||
* Get a 16-bit short from the process.
|
||||
*
|
||||
* Returns: 2 bytes Success
|
||||
*
|
||||
* Note: aborts on read error.
|
||||
*/
|
||||
PRIVATE u16_t peek16(struct address_s *ap)
|
||||
{
|
||||
unsigned int uj;
|
||||
|
||||
/* with luck buffering should make this fairly quick */
|
||||
if (fseek(disfp, (long)(ap->off), SEEK_CUR) != 0) {
|
||||
fprintf(stderr, "Cannot seek forward in object file\n");
|
||||
exit(1);
|
||||
}
|
||||
/* Intel has right to left byte ordering */
|
||||
#if 1
|
||||
uj = fgetc(disfp) & 0377;
|
||||
uj |= (fgetc(disfp) & 0377) << 8;
|
||||
#else
|
||||
uj = fgetc(disfp) & 0377;
|
||||
uj <<= 8;
|
||||
uj |= fgetc(disfp) & 0377;
|
||||
#endif
|
||||
if (fseek(disfp, -(long)(ap->off + 2), SEEK_CUR) != 0) {
|
||||
fprintf(stderr, "Cannot seek backward in object file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return uj;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* p e e k 3 2
|
||||
*
|
||||
* Get a 32-bit int from the process.
|
||||
*
|
||||
* Returns: 4 bytes Success
|
||||
*
|
||||
* Note: aborts on read error.
|
||||
*/
|
||||
PRIVATE u32_t peek32(struct address_s *ap)
|
||||
{
|
||||
unsigned int uj;
|
||||
|
||||
/* with luck buffering should make this fairly quick */
|
||||
if (fseek(disfp, (long)(ap->off), SEEK_CUR) != 0) {
|
||||
fprintf(stderr, "Cannot seek forward in object file\n");
|
||||
exit(1);
|
||||
}
|
||||
#if 1
|
||||
/* Intel has right to left byte ordering */
|
||||
uj = fgetc(disfp) & 0377;
|
||||
uj |= (fgetc(disfp) & 0377) << 8;
|
||||
uj |= (fgetc(disfp) & 0377) << 16;
|
||||
uj |= (fgetc(disfp) & 0377) << 24;
|
||||
#else
|
||||
uj = fgetc(disfp) & 0377;
|
||||
uj <<= 8;
|
||||
uj |= fgetc(disfp) & 0377;
|
||||
uj <<= 8;
|
||||
uj |= fgetc(disfp) & 0377;
|
||||
uj <<= 8;
|
||||
uj |= fgetc(disfp) & 0377;
|
||||
#endif
|
||||
if (fseek(disfp, -(long)(ap->off + 4), SEEK_CUR) != 0) {
|
||||
fprintf(stderr, "Cannot seek backward in object file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return uj;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return current offset of string device.
|
||||
*/
|
||||
PUBLIC count_t stringpos()
|
||||
{
|
||||
return string_ptr - stringstart;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return current "tab" spot of string device.
|
||||
*/
|
||||
PUBLIC count_t stringtab()
|
||||
{
|
||||
return stringcount;
|
||||
}
|
||||
|
||||
/******************** sym.c ***********************/
|
||||
|
||||
/*
|
||||
* f i n d r v a l
|
||||
*
|
||||
* Check if an address refers to a relocation structure,
|
||||
* and if so return the table entry.
|
||||
*
|
||||
* Returns: Pointer to struct nlist Success
|
||||
* Null pointer Failure
|
||||
*
|
||||
* Note that the nlist interface must be maintained for use by unasm().
|
||||
*/
|
||||
PUBLIC struct nlist *findrval(offset_t value, int where)
|
||||
{
|
||||
if (aoutfp != (FILE *)NULL)
|
||||
return (find_arval(value, where));
|
||||
else if (objfp != (FILE *)NULL)
|
||||
return (find_orval(value, where));
|
||||
else
|
||||
return (struct nlist *)NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* f i n d _ a r v a l
|
||||
*
|
||||
* Check if an address refers to an a.out file relocation structure,
|
||||
* and if so return the table entry.
|
||||
*
|
||||
* Returns: Pointer to struct nlist Success
|
||||
* Null pointer Failure
|
||||
*
|
||||
* Note that the nlist interface must be maintained for use by unasm().
|
||||
* ### Do any available ACK compilers have this feature?
|
||||
*/
|
||||
PRIVATE struct nlist *find_arval(offset_t value, int where)
|
||||
{
|
||||
return (struct nlist *)NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* f i n d _ o r v a l
|
||||
*
|
||||
* Check if an address refers to an object file relocation structure,
|
||||
* and if so return the table entry.
|
||||
*
|
||||
* Returns: Pointer to struct nlist Success
|
||||
* Null pointer Failure
|
||||
*
|
||||
* Note that the nlist interface must be maintained for use by unasm().
|
||||
* The table entry is stored in a static buffer which is overwritten
|
||||
* on successive calls.
|
||||
*/
|
||||
PRIVATE struct nlist *find_orval(offset_t value, int where)
|
||||
{
|
||||
char data[20];
|
||||
int j, k, status;
|
||||
long int lj;
|
||||
static struct nlist sym;
|
||||
|
||||
/* we need to have an object file */
|
||||
if (objfp == (FILE *)NULL) return (struct nlist *)NULL;
|
||||
|
||||
/* Sections in an object file usually have the order text, rom, data, bss.
|
||||
* The order is actually set out in the section data header. Assume that
|
||||
* the first user section is text, and all else is data.
|
||||
*/
|
||||
if (where != CSEG && where != DSEG)
|
||||
return(struct nlist *)NULL;
|
||||
|
||||
/* check for a relocation entry */
|
||||
status = FAILED;
|
||||
for (j = 0 ; j < o_hdrbuf.oh_nrelo ; j++) {
|
||||
if (value == o_reltab[j].or_addr) {
|
||||
/* abandon non-matching section entries */
|
||||
if (where == CSEG && (o_reltab[j].or_sect & S_TYP) != S_MIN)
|
||||
continue;
|
||||
if (where == DSEG && ((o_reltab[j].or_sect & S_TYP) <= S_MIN ||
|
||||
(o_reltab[j].or_sect & S_TYP) > (S_MIN + 3)))
|
||||
continue;
|
||||
/* the address is an offset from the symbol or section base */
|
||||
if (o_reltab[j].or_nami < o_hdrbuf.oh_nname) {
|
||||
lj = o_symtab[o_reltab[j].or_nami].on_foff -
|
||||
(long)OFF_CHAR(o_hdrbuf);
|
||||
/* check that addressing isn't messed up */
|
||||
assert(lj >= 0 && lj < o_hdrbuf.oh_nchar);
|
||||
/* name size is defined by SZ_NAME */
|
||||
sprintf(data, "%-13s", o_strtab + lj);
|
||||
/* convert from rel table to executable symbol table format */
|
||||
for (k = 0 ; k < sizeof(sym.n_name) ; k++) {
|
||||
sym.n_name[k] = data[k];/* 8 characters */
|
||||
}
|
||||
sym.n_value = o_symtab[o_reltab[j].or_nami].on_valu;
|
||||
/* long */
|
||||
#if 1
|
||||
sym.n_sclass = (where == CSEG) ? N_TEXT : N_DATA;
|
||||
#else
|
||||
sym.n_sclass = (o_symtab[o_reltab[j].or_nami].on_type &
|
||||
S_TYP) - S_MIN; /* unsigned char */
|
||||
#endif
|
||||
sym.n_numaux = 0; /* unsigned char */
|
||||
sym.n_type = 0; /* unsigned short */
|
||||
status = OK;
|
||||
break;
|
||||
}
|
||||
/* the address is an absolute number relative to the pc */
|
||||
else if (o_reltab[j].or_nami == o_hdrbuf.oh_nname) {
|
||||
strcpy(data, "Absolute");
|
||||
/* convert from relocation data to executable symbol table format */
|
||||
for (k = 0 ; k < sizeof(sym.n_name) ; k++) {
|
||||
sym.n_name[k] = data[k];
|
||||
}
|
||||
sym.n_value = 0;
|
||||
sym.n_sclass = (where == CSEG) ? N_TEXT : N_DATA;
|
||||
sym.n_numaux = 0;
|
||||
sym.n_type = 0;
|
||||
status = OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (status == OK ? &sym : (struct nlist *)NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* f i n d s v a l
|
||||
*
|
||||
* Check if an address refers to a symbol,
|
||||
* and if so return the table entry.
|
||||
*
|
||||
* Returns: Pointer to struct nlist Success
|
||||
* Null pointer Failure
|
||||
*
|
||||
* Note that the nlist interface must be maintained for use by unasm().
|
||||
*/
|
||||
PUBLIC struct nlist *findsval(offset_t value, int where)
|
||||
{
|
||||
if (aoutfp != (FILE *)NULL)
|
||||
return (find_asval(value, where));
|
||||
else if (objfp != (FILE *)NULL)
|
||||
return (find_osval(value, where));
|
||||
else
|
||||
return (struct nlist *)NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* f i n d _ a s v a l
|
||||
*
|
||||
* Check if an address refers to an a.out file symbol,
|
||||
* and if so return the table entry.
|
||||
*
|
||||
* Returns: Pointer to struct nlist Success
|
||||
* Null pointer Failure
|
||||
*
|
||||
* Note that the nlist interface must be maintained for use by unasm().
|
||||
* The table entry is stored in a static buffer which is overwritten
|
||||
* on successive calls.
|
||||
*/
|
||||
PRIVATE struct nlist *find_asval(offset_t value, int where)
|
||||
{
|
||||
int j, status;
|
||||
static struct nlist sym;
|
||||
|
||||
/* Sections in an a.out file have the order text, data, bss
|
||||
* but this function is called only with CSEG and DSEG.
|
||||
*/
|
||||
if (where != CSEG && where != DSEG)
|
||||
return(struct nlist *)NULL;
|
||||
|
||||
/* do a linear search for a symbol, as the symbol tables are unsorted */
|
||||
status = FAILED;
|
||||
for (j = 0 ; j < (a_hdrbuf.a_syms / sizeof(struct nlist)) ; j++) {
|
||||
if (value == a_symtab[j].n_value &&
|
||||
((where == CSEG && (a_symtab[j].n_sclass & N_SECT) == N_TEXT) ||
|
||||
(where == DSEG && ((a_symtab[j].n_sclass & N_SECT) == N_DATA ||
|
||||
(a_symtab[j].n_sclass & N_SECT) == N_BSS)))) {
|
||||
(void) memcpy(&sym, &a_symtab[j], sizeof(struct nlist));
|
||||
status = OK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (status == OK) ? &sym : (struct nlist *)NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* f i n d _ o s v a l
|
||||
*
|
||||
* Check if an address refers to an object file symbol,
|
||||
* and if so return the table entry.
|
||||
*
|
||||
* Returns: Pointer to struct nlist Success
|
||||
* Null pointer Failure
|
||||
*
|
||||
* Note that the nlist interface must be maintained for use by unasm().
|
||||
* The table entry is stored in a static buffer which is overwritten
|
||||
* on successive calls.
|
||||
*/
|
||||
PRIVATE struct nlist *find_osval(offset_t value, int where)
|
||||
{
|
||||
int j, k, sec, status;
|
||||
long int lj;
|
||||
struct locname *np;
|
||||
static struct nlist sym;
|
||||
|
||||
/* Sections in an object file usually have the order text, rom, data, bss.
|
||||
* The order is actually set out in the section data header. Assume that
|
||||
* the first user section is text, and all else is data.
|
||||
*/
|
||||
if (where != CSEG && where != DSEG)
|
||||
return(struct nlist *)NULL;
|
||||
|
||||
/* do a linear search for a local symbol, as the tables are unsorted */
|
||||
status = FAILED;
|
||||
if (where == DSEG) {
|
||||
/* nb. hardcoded assumption of section order */
|
||||
for (sec = 1 ; status == FAILED && sec < 4 ; sec++) {
|
||||
for (np = locsym[sec] ; status == FAILED && np !=
|
||||
(struct locname *)NULL ; np = np->l_next) {
|
||||
if (np->l_value == value) {
|
||||
for (k = 0 ; k < sizeof(sym.n_name) ; k++) {
|
||||
sym.n_name[k] = np->l_name[k];/* 8 characters */
|
||||
}
|
||||
sym.n_value = value; /* long */
|
||||
sym.n_sclass = N_DATA; /* unsigned char */
|
||||
sym.n_numaux = 0; /* unsigned char */
|
||||
sym.n_type = 0; /* unsigned short */
|
||||
status = OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* do a linear search for a symbol, as the symbol tables are unsorted */
|
||||
for (j = 0 ; status == FAILED && j < o_hdrbuf.oh_nname ; j++) {
|
||||
if (value == o_symtab[j].on_valu) {
|
||||
/* abandon non-matching section entries */
|
||||
if (where == CSEG && (o_symtab[j].on_type & S_TYP) != S_MIN)
|
||||
continue;
|
||||
if (where == DSEG && ((o_symtab[j].on_type & S_TYP) <= S_MIN ||
|
||||
(o_symtab[j].on_type & S_TYP) > (S_MIN + 3)))
|
||||
continue;
|
||||
#if 0
|
||||
((where == CSEG && sect == (o_symtab[j].on_type & S_TYP)) ||
|
||||
(where == DSEG && sect <= (o_symtab[j].on_type & S_TYP)))) {
|
||||
#endif
|
||||
/* find the name in the object file symbol table */
|
||||
lj = o_symtab[j].on_foff - (long)OFF_CHAR(o_hdrbuf);
|
||||
/* check that the offset addressing isn't messed up */
|
||||
assert(lj >= 0 && lj < o_hdrbuf.oh_nchar);
|
||||
/* convert from object to executable symbol table format */
|
||||
for (k = 0 ; k < sizeof(sym.n_name) ; k++) {
|
||||
sym.n_name[k] = *(o_strtab + lj + k);
|
||||
/* 8 characters */
|
||||
}
|
||||
sym.n_value = o_symtab[j].on_valu; /* long */
|
||||
sym.n_sclass = (where == CSEG) ? N_TEXT : N_DATA;
|
||||
/* unsigned char */
|
||||
sym.n_numaux = 0; /* unsigned char */
|
||||
sym.n_type = 0; /* unsigned short */
|
||||
status = OK;
|
||||
}
|
||||
}
|
||||
|
||||
return (status == OK ? &sym : (struct nlist *)NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* o u t r e l
|
||||
*
|
||||
* Output a symbol name from an nlist structure.
|
||||
*
|
||||
* Returns: Nothing Always
|
||||
*
|
||||
* Note that the nlist interface must be maintained for use by unasm().
|
||||
* The label may be a segment name, in which case the address is relative
|
||||
* to that segment and must be dereferenced further.
|
||||
*/
|
||||
PUBLIC void outrel(struct nlist *sp, offset_t off)
|
||||
{
|
||||
char data[20];
|
||||
int j, k;
|
||||
struct nlist *spnew;
|
||||
|
||||
/* get a local copy of the label */
|
||||
for (j = 0 ; j < 20 ; j++) {
|
||||
data[j] = sp->n_name[j];
|
||||
if (data[j] == ' ' || data[j] == '\0')
|
||||
break;
|
||||
}
|
||||
data[j] = '\0';
|
||||
data[8] = '\0';
|
||||
|
||||
/* see if we have a section name */
|
||||
for (k = 0 ; k < 4 ; k++) {
|
||||
if (strcmp(data, o_secnam[k]) == 0) {
|
||||
/* look up the name in the appropriate section */
|
||||
if ((spnew = findsval(off, (k ? DSEG : CSEG))) != (struct nlist *)NULL) {
|
||||
/* get a local copy of the label */
|
||||
for (j = 0 ; j < 20 ; j++) {
|
||||
data[j] = spnew->n_name[j];
|
||||
if (data[j] == '\0') break;
|
||||
}
|
||||
data[8] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* output the result */
|
||||
for (j = 0 ; data[j] != 0 ; j++)
|
||||
outbyte(data[j]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* o u t s y m
|
||||
*
|
||||
* Output a symbol name from an nlist structure.
|
||||
*
|
||||
* Returns: Nothing Always
|
||||
*
|
||||
* Note that the nlist interface must be maintained for use by unasm().
|
||||
*/
|
||||
PUBLIC void outsym(struct nlist *sp, offset_t off)
|
||||
{
|
||||
char *s;
|
||||
char *send;
|
||||
|
||||
/* output the symbol name */
|
||||
for (s = sp->n_name, send = s + sizeof sp->n_name; *s != 0 && s < send; ++s)
|
||||
outbyte(*s);
|
||||
|
||||
/* if the required address is offset from the name, output that too */
|
||||
if ((off -= sp->n_value) != 0) {
|
||||
outbyte('+');
|
||||
if (off >= 0x10000)
|
||||
outh32(off);
|
||||
else if (off >= 0x100)
|
||||
outh16((u16_pt) off);
|
||||
else
|
||||
outh8((u8_pt) off);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* d a s m
|
||||
*
|
||||
* Disassemble a stream of instructions.
|
||||
*
|
||||
* Returns: OK Success
|
||||
* FAILED Otherwise
|
||||
*/
|
||||
PUBLIC int dasm(offset_t addr, offset_t count)
|
||||
{
|
||||
#if (_WORD_SIZE == 4)
|
||||
bits32 = TRUE; /* set mode */
|
||||
#else
|
||||
bits32 = FALSE;
|
||||
#endif
|
||||
processor = bits32 ? 386 : 0;
|
||||
uptr.off = 0;
|
||||
uptr.base = 0;
|
||||
|
||||
while (uptr.off < count) {
|
||||
addrbase = addr;
|
||||
/* assume that the object file text segment is first */
|
||||
if (objfp != (FILE *)NULL && uptr.off >= o_sectab[0].os_flen)
|
||||
return FAILED;
|
||||
if (aoutfp != (FILE *)NULL && uptr.off >= (A_DATAPOS(a_hdrbuf) - 1))
|
||||
return FAILED;
|
||||
if (dis_one() == FAILED)
|
||||
return FAILED;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* d i s _ o n e
|
||||
*
|
||||
* Disassemble a single instruction.
|
||||
*
|
||||
* Returns: OK Always
|
||||
*
|
||||
* File read failures are handled at a low level by simply
|
||||
* baling out of the program; the startup checks on file
|
||||
* readability should make this a rare occurrence. Hence
|
||||
* there are no error returns from this routine.
|
||||
* The output is written into a static line buffer, which
|
||||
* is overwritten on successive calls.
|
||||
*/
|
||||
PRIVATE int dis_one()
|
||||
{
|
||||
int idone, column, maxcol;
|
||||
static char line[81];
|
||||
struct address_s newuptr;
|
||||
struct address_s olduptr;
|
||||
struct nlist *sp;
|
||||
|
||||
do {
|
||||
/* output a label */
|
||||
if ((sp = findsval(uptr.off + addrbase, CSEG)) != NULL
|
||||
&& sp->n_value == uptr.off + addrbase) {
|
||||
outsym(sp, uptr.off + addrbase);
|
||||
outbyte(':');
|
||||
(void) outnl();
|
||||
}
|
||||
|
||||
/* park the current address */
|
||||
olduptr = uptr;
|
||||
|
||||
/* initialise the string input */
|
||||
openstring(line, sizeof(line));
|
||||
|
||||
/* output an instruction */
|
||||
idone = puti();
|
||||
|
||||
/* terminate the line buffer */
|
||||
line[stringpos()] = 0;
|
||||
|
||||
/* deinitialise the string input */
|
||||
closestring();
|
||||
|
||||
/* park the new address, set by puti() */
|
||||
newuptr = uptr;
|
||||
|
||||
/* get back the current address */
|
||||
uptr = olduptr;
|
||||
|
||||
/* output the segment data */
|
||||
column = outsegaddr(&uptr, addrbase);
|
||||
outspace();
|
||||
outspace();
|
||||
column += 2;
|
||||
|
||||
/* output the raw bytes of the current instruction */
|
||||
while (uptr.off != newuptr.off) {
|
||||
outh8(get8());
|
||||
column += 2;
|
||||
}
|
||||
|
||||
/* format the disassembled output */
|
||||
maxcol = bits32 ? 24 : 16;
|
||||
while (column < maxcol) {
|
||||
outtab();
|
||||
column += 8;
|
||||
}
|
||||
outtab();
|
||||
|
||||
/* display the collected buffer */
|
||||
outstr(line);
|
||||
(void) outnl();
|
||||
} while (!idone); /* eat all prefixes */
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* EOF
|
||||
*/
|
||||
|
127
commands/dis386/out.h
Normal file
127
commands/dis386/out.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header: out.h,v 1.1 91/05/16 14:09:17 ceriel Exp $ */
|
||||
|
||||
#ifndef __OUT_H_INCLUDED
|
||||
#define __OUT_H_INCLUDED
|
||||
/*
|
||||
* output format for ACK assemblers
|
||||
*/
|
||||
#ifndef ushort
|
||||
#define ushort unsigned short
|
||||
#endif /* ushort */
|
||||
|
||||
struct outhead {
|
||||
ushort oh_magic; /* magic number */
|
||||
ushort oh_stamp; /* version stamp */
|
||||
ushort oh_flags; /* several format flags */
|
||||
ushort oh_nsect; /* number of outsect structures */
|
||||
ushort oh_nrelo; /* number of outrelo structures */
|
||||
ushort oh_nname; /* number of outname structures */
|
||||
long oh_nemit; /* sum of all os_flen */
|
||||
long oh_nchar; /* size of string area */
|
||||
};
|
||||
|
||||
#define O_MAGIC 0x0201 /* magic number of output file */
|
||||
#define O_STAMP 0 /* version stamp */
|
||||
#define MAXSECT 64 /* Maximum number of sections */
|
||||
|
||||
#define HF_LINK 0x0004 /* unresolved references left */
|
||||
#define HF_8086 0x0008 /* os_base specially encoded */
|
||||
|
||||
struct outsect {
|
||||
long os_base; /* startaddress in machine */
|
||||
long os_size; /* section size in machine */
|
||||
long os_foff; /* startaddress in file */
|
||||
long os_flen; /* section size in file */
|
||||
long os_lign; /* section alignment */
|
||||
};
|
||||
|
||||
struct outrelo {
|
||||
char or_type; /* type of reference */
|
||||
char or_sect; /* referencing section */
|
||||
ushort or_nami; /* referenced symbol index */
|
||||
long or_addr; /* referencing address */
|
||||
};
|
||||
|
||||
struct outname {
|
||||
union {
|
||||
char *on_ptr; /* symbol name (in core) */
|
||||
long on_off; /* symbol name (in file) */
|
||||
} on_u;
|
||||
#define on_mptr on_u.on_ptr
|
||||
#define on_foff on_u.on_off
|
||||
ushort on_type; /* symbol type */
|
||||
ushort on_desc; /* debug info */
|
||||
long on_valu; /* symbol value */
|
||||
};
|
||||
|
||||
/*
|
||||
* relocation type bits
|
||||
*/
|
||||
#define RELSZ 0x07 /* relocation length */
|
||||
#define RELO1 1 /* 1 byte */
|
||||
#define RELO2 2 /* 2 bytes */
|
||||
#define RELO4 4 /* 4 bytes */
|
||||
#define RELPC 0x08 /* pc relative */
|
||||
#define RELBR 0x10 /* High order byte lowest address. */
|
||||
#define RELWR 0x20 /* High order word lowest address. */
|
||||
|
||||
/*
|
||||
* section type bits and fields
|
||||
*/
|
||||
#define S_TYP 0x007F /* undefined, absolute or relative */
|
||||
#define S_EXT 0x0080 /* external flag */
|
||||
#define S_ETC 0x7F00 /* for symbolic debug, bypassing 'as' */
|
||||
|
||||
/*
|
||||
* S_TYP field values
|
||||
*/
|
||||
#define S_UND 0x0000 /* undefined item */
|
||||
#define S_ABS 0x0001 /* absolute item */
|
||||
#define S_MIN 0x0002 /* first user section */
|
||||
#define S_MAX (S_TYP-1) /* last user section */
|
||||
#define S_CRS S_TYP /* on_valu is symbol index which contains value */
|
||||
|
||||
/*
|
||||
* S_ETC field values
|
||||
*/
|
||||
#define S_SCT 0x0100 /* section names */
|
||||
#define S_LIN 0x0200 /* hll source line item */
|
||||
#define S_FIL 0x0300 /* hll source file item */
|
||||
#define S_MOD 0x0400 /* ass source file item */
|
||||
#define S_COM 0x1000 /* Common name. */
|
||||
#define S_STB 0xe000 /* entries with any of these bits set are
|
||||
reserved for debuggers
|
||||
*/
|
||||
|
||||
/*
|
||||
* structure format strings
|
||||
*/
|
||||
#define SF_HEAD "22222244"
|
||||
#define SF_SECT "44444"
|
||||
#define SF_RELO "1124"
|
||||
#define SF_NAME "4224"
|
||||
|
||||
/*
|
||||
* structure sizes (bytes in file; add digits in SF_*)
|
||||
*/
|
||||
#define SZ_HEAD 20
|
||||
#define SZ_SECT 20
|
||||
#define SZ_RELO 8
|
||||
#define SZ_NAME 12
|
||||
|
||||
/*
|
||||
* file access macros
|
||||
*/
|
||||
#define BADMAGIC(x) ((x).oh_magic!=O_MAGIC)
|
||||
#define OFF_SECT(x) SZ_HEAD
|
||||
#define OFF_EMIT(x) (OFF_SECT(x) + ((long)(x).oh_nsect * SZ_SECT))
|
||||
#define OFF_RELO(x) (OFF_EMIT(x) + (x).oh_nemit)
|
||||
#define OFF_NAME(x) (OFF_RELO(x) + ((long)(x).oh_nrelo * SZ_RELO))
|
||||
#define OFF_CHAR(x) (OFF_NAME(x) + ((long)(x).oh_nname * SZ_NAME))
|
||||
|
||||
#endif /* __OUT_H_INCLUDED */
|
||||
|
212
commands/dis386/type.h
Normal file
212
commands/dis386/type.h
Normal file
|
@ -0,0 +1,212 @@
|
|||
/* type.h - types for db.
|
||||
*
|
||||
* $Id: type.h,v 1.1 1997/10/20 12:00:00 cwr Exp cwr $
|
||||
*/
|
||||
|
||||
typedef unsigned long bigcount_t;
|
||||
typedef unsigned long flags_t;
|
||||
typedef int bool_pt;
|
||||
typedef char bool_t;
|
||||
typedef int char_pt;
|
||||
typedef int char16_t; /* ASCII character possibly with scan code */
|
||||
typedef unsigned count_t;
|
||||
typedef unsigned long offset_t;
|
||||
typedef unsigned opcode_pt; /* promote to unsigned and not int */
|
||||
typedef int (*pfi_t)();
|
||||
typedef void (*pfv_t)();
|
||||
typedef unsigned long physoff_t;
|
||||
typedef unsigned peekboff_t;
|
||||
typedef unsigned peekoff_t;
|
||||
typedef int peekseg_t;
|
||||
typedef unsigned port_t;
|
||||
typedef int reg_pt;
|
||||
typedef unsigned char reg_t;
|
||||
typedef unsigned segment_t;
|
||||
typedef long soffset_t;
|
||||
typedef int su8_pt;
|
||||
typedef int su16_t;
|
||||
typedef unsigned u4_pt; /* promote to unsigned and not int */
|
||||
typedef unsigned u8_pt;
|
||||
typedef unsigned u16_pt;
|
||||
|
||||
struct address_s
|
||||
{
|
||||
offset_t off;
|
||||
offset_t base;
|
||||
};
|
||||
|
||||
struct desctableptr_s {
|
||||
u16_t limit;
|
||||
u32_t base; /* really u24_t + pad for 286 */
|
||||
};
|
||||
|
||||
struct regs_s
|
||||
{
|
||||
offset_t ax;
|
||||
offset_t bx;
|
||||
offset_t cx;
|
||||
offset_t dx;
|
||||
offset_t si;
|
||||
offset_t di;
|
||||
offset_t bp;
|
||||
offset_t sp;
|
||||
offset_t dsbase;
|
||||
offset_t esbase;
|
||||
offset_t fsbase;
|
||||
offset_t gsbase;
|
||||
offset_t ssbase;
|
||||
offset_t csbase;
|
||||
offset_t ip;
|
||||
flags_t f;
|
||||
offset_t ds;
|
||||
offset_t es;
|
||||
offset_t fs;
|
||||
offset_t gs;
|
||||
offset_t ss;
|
||||
offset_t cs;
|
||||
};
|
||||
|
||||
struct specregs_s
|
||||
{
|
||||
u32_t cr0; /* control regs, cr0 is msw + pad for 286 */
|
||||
u32_t cr2;
|
||||
u32_t cr3;
|
||||
u32_t dr0; /* debug regs */
|
||||
u32_t dr1;
|
||||
u32_t dr2;
|
||||
u32_t dr3;
|
||||
u32_t dr6;
|
||||
u32_t dr7;
|
||||
u32_t tr6; /* test regs */
|
||||
u32_t tr7;
|
||||
u16_t gdtlimit;
|
||||
u32_t gdtbase; /* depend on 16-bit compiler so no long align */
|
||||
u16_t gdtpad;
|
||||
u16_t idtlimit;
|
||||
u32_t idtbase;
|
||||
u16_t idtpad;
|
||||
u16_t ldtlimit;
|
||||
u32_t ldtbase;
|
||||
u16_t ldt;
|
||||
u16_t tr; /* task register */
|
||||
u16_t trpad;
|
||||
};
|
||||
|
||||
/* prototypes */
|
||||
|
||||
#if __STDC__
|
||||
#define P(x) x
|
||||
#else
|
||||
#define P(x) ()
|
||||
#endif
|
||||
|
||||
/* library, very few! */
|
||||
void *memcpy P((void *dst, const void *src, unsigned size));
|
||||
void *memmove P((void *dst, const void *src, unsigned size));
|
||||
unsigned strlen P((const char *s));
|
||||
char *strncpy P((char *dst, const char *src, unsigned size));
|
||||
|
||||
/* db.c */
|
||||
void db_main P((void));
|
||||
void get_kbd_state P(());
|
||||
void get_scr_state P(());
|
||||
void info P((void));
|
||||
void reboot P((void));
|
||||
void reset_kbd_state P(());
|
||||
|
||||
/* getline.c */
|
||||
char *getline P((char *startline, unsigned maxlength, unsigned offset));
|
||||
|
||||
/* ihexload.c */
|
||||
void ihexload P((void));
|
||||
|
||||
/* io.c */
|
||||
void can_itty P((void));
|
||||
void can_keyboard P((void));
|
||||
void can_otty P((void));
|
||||
void can_screen P((void));
|
||||
void closeio P((void));
|
||||
void closestring P((void));
|
||||
void enab_itty P((void));
|
||||
void enab_keyboard P((void));
|
||||
void enab_otty P((void));
|
||||
void enab_screen P((void));
|
||||
void flipcase P((void));
|
||||
u8_pt get8 P((void));
|
||||
u16_pt get16 P((void));
|
||||
u32_t get32 P((void));
|
||||
char16_t inchar P((void));
|
||||
char_pt mytolower P((char_pt ch));
|
||||
void openio P((void));
|
||||
void openstring P((char *string, int length));
|
||||
void outbyte P((char_pt byte));
|
||||
void outcomma P((void));
|
||||
void outh4 P((u4_pt num));
|
||||
void outh8 P((u8_pt num));
|
||||
void outh16 P((u16_pt num));
|
||||
void outh32 P((u32_t num));
|
||||
bool_pt outnl P((void));
|
||||
count_t outsegaddr P((struct address_s *ap, offset_t addr));
|
||||
count_t outsegreg P((offset_t num));
|
||||
void outspace P((void));
|
||||
void outstr P((char *s));
|
||||
void outtab P((void));
|
||||
void outustr P((char *s));
|
||||
void set_tty P((void));
|
||||
void show_db_screen P((void));
|
||||
void show_user_screen P((void));
|
||||
count_t stringpos P((void));
|
||||
count_t stringtab P((void));
|
||||
char_pt testchar P((void));
|
||||
|
||||
/* lib88.s */
|
||||
int get_privilege P((void));
|
||||
unsigned get_processor P((void));
|
||||
unsigned in16portb P((port_t port));
|
||||
physoff_t linear2addr P((segment_t segment, u16_pt offset));
|
||||
void oportb P((port_t port, u8_pt value));
|
||||
u8_pt peek_byte P((physoff_t offset));
|
||||
u16_pt peek_word P((physoff_t offset));
|
||||
u32_t peek_dword P((physoff_t offset));
|
||||
void poke_byte P((physoff_t offset, u8_pt value));
|
||||
void poke_word P((physoff_t offset, u16_pt value));
|
||||
#ifdef N_TEXT
|
||||
void symswap P((struct nlist *left, struct nlist *right,
|
||||
segment_t tableseg, unsigned length));
|
||||
#endif
|
||||
|
||||
/* pcio.c */
|
||||
void kbdclose P((void));
|
||||
char_pt kbdin P((void));
|
||||
void kbdioctl P((int command));
|
||||
void kbdopen P((void));
|
||||
void kbdout P((int c));
|
||||
|
||||
/* screen.s */
|
||||
void scrclose P((void));
|
||||
void scrioctl P((int command));
|
||||
char_pt scrin P((void));
|
||||
void scropen P((void));
|
||||
void scrout P((char_pt c));
|
||||
|
||||
/* sym.c */
|
||||
#ifdef N_TEXT
|
||||
struct nlist *findsname P((char *name, int where, bool_pt allflag));
|
||||
struct nlist *findsval P((offset_t value, int where));
|
||||
struct nlist *findrval P((offset_t value, int where));
|
||||
void outsym P((struct nlist *sp, offset_t off));
|
||||
void outrel P((struct nlist *sp, offset_t off));
|
||||
#endif
|
||||
void setproc P((char_pt c, struct address_s *pdptr, struct address_s *pmptr));
|
||||
void syminit P((void));
|
||||
|
||||
/* tty.s */
|
||||
void ttyclose P((void));
|
||||
void ttyioctl P((int command));
|
||||
char_pt ttyin P((void));
|
||||
void ttyopen P((void));
|
||||
void ttyout P((char_pt c));
|
||||
|
||||
/* unasm.c */
|
||||
bool_pt puti P((void));
|
||||
|
1418
commands/dis386/unasm.c
Normal file
1418
commands/dis386/unasm.c
Normal file
File diff suppressed because it is too large
Load diff
14
commands/dis386/var.h
Normal file
14
commands/dis386/var.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
/* var.h - variables for db.
|
||||
*
|
||||
* $Id: var.h,v 1.1 1997/10/20 12:00:00 cwr Exp cwr $
|
||||
*/
|
||||
|
||||
EXTERN bool_t bits32;
|
||||
EXTERN unsigned processor;
|
||||
EXTERN char_pt prompt;
|
||||
EXTERN bool_t protected;
|
||||
EXTERN offset_t addrbase;
|
||||
EXTERN struct regs_s regs;
|
||||
EXTERN struct specregs_s specregs;
|
||||
EXTERN struct address_s uptr;
|
||||
|
Loading…
Reference in a new issue