summaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>1998-02-01 11:26:21 +0100
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:40:14 +0200
commit48f0b3eb836162d41622cedc1eb5f5168168fb8e (patch)
treec53156383d4682a0a296f6611575dbc1d64d1881 /ld
parent48798bf2eb93ec3b99720ac2e16093441156653d (diff)
downloaddev86-48f0b3eb836162d41622cedc1eb5f5168168fb8e.tar.gz
Import Dev86src-0.13.5.tar.gzv0.13.5
Diffstat (limited to 'ld')
-rw-r--r--ld/Makefile6
-rw-r--r--ld/dumps.c24
-rw-r--r--ld/io.c48
-rw-r--r--ld/objchop.c2
-rw-r--r--ld/objdump86.c681
-rw-r--r--ld/syshead.h2
-rw-r--r--ld/type.h1
-rw-r--r--ld/writex86.c80
-rw-r--r--ld/x1
9 files changed, 827 insertions, 18 deletions
diff --git a/ld/Makefile b/ld/Makefile
index 985008c..6dad38a 100644
--- a/ld/Makefile
+++ b/ld/Makefile
@@ -13,12 +13,12 @@ DEFS =-DREL_OUTPUT -DBUGCOMPAT
# An alternative file for a non-standard a.out.h (eg i386 linux on an Alpha)
#
-# NATIVE= -DA_OUT_INCL='"a_out_local.h"'
+# NATIVE=-DA_OUT_INCL='"a_out_local.h"'
OBJS= dumps.o io.o ld.o readobj.o table.o typeconv.o linksyms.o \
writex86.o writebin.o writerel.o
-all: ld86 objchop catimage
+all: ld86 objchop catimage objdump86
ld86: $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) -o $@
@@ -28,7 +28,7 @@ install: ld86
install -m 755 ld86 $(LIBDIR)
clean realclean:
- rm -f *.o ld86 ld86r objchop catimage
+ rm -f *.o ld86 ld86r objchop catimage objdump86
$(OBJS): align.h ar.h bindef.h byteord.h config.h const.h globvar.h obj.h \
syshead.h type.h x86_aout.h
diff --git a/ld/dumps.c b/ld/dumps.c
index c9a40d4..a969123 100644
--- a/ld/dumps.c
+++ b/ld/dumps.c
@@ -12,11 +12,26 @@
PUBLIC void dumpmods()
{
struct modstruct *modptr;
+ char *s, *d;
+ int i;
for (modptr = modfirst; modptr != NUL_PTR; modptr = modptr->modnext)
{
- putstr(modptr->loadflag ? "L " : " ");
- putbstr(20, modptr->modname);
+ for(s=d=modptr->filename; *s ; s++)
+ if( *s == '/' ) d=s+1;
+ if( memcmp(d, "libc", 4) == 0 && !modptr->loadflag ) continue;
+
+ putstr(modptr->modname);
+ i = strlen(modptr->modname);
+ while(i<16) putbyte(' '),i++;
+ putbyte( modptr->loadflag ? '+':'-' );
+ putstr(d);
+ if( modptr->archentry )
+ {
+ putbyte('(');
+ putstr(modptr->archentry);
+ putbyte(')');
+ }
putbyte('\n');
}
}
@@ -55,7 +70,10 @@ PUBLIC void dumpsyms()
#else
put08x(symptr->value);
#endif
- putstr(flags & A_MASK ? " A" : " R");
+ if( flags & (E_MASK|C_MASK) )
+ putstr(flags & A_MASK ? " A" : " R");
+ else
+ putstr(flags & A_MASK ? " a" : " r");
if (uflag)
putstr(" U");
if (flags & C_MASK)
diff --git a/ld/io.c b/ld/io.c
index a21ecd3..e56a474 100644
--- a/ld/io.c
+++ b/ld/io.c
@@ -22,6 +22,7 @@ PRIVATE char *drelbuftop; /* data relocation output buffer top */
PRIVATE char *errbuf; /* error buffer (actually uses STDOUT) */
PRIVATE char *errbufptr; /* error buffer ptr */
PRIVATE char *errbuftop; /* error buffer top */
+PRIVATE int errfil = STDOUT_FILENO;
PRIVATE char *inbuf; /* input buffer */
PRIVATE char *inbufend; /* input buffer top */
PRIVATE char *inbufptr; /* end of input in input buffer */
@@ -56,6 +57,7 @@ FORWARD void outputerror P((char *message));
FORWARD void put04x P((unsigned num));
FORWARD void putstrn P((char *message));
FORWARD void refer P((void));
+FORWARD void stderr_out P((void));
PUBLIC void ioinit(progname)
char *progname;
@@ -65,6 +67,10 @@ char *progname;
refname = progname; /* name must be static (is argv[0]) */
else
refname = "link";
+ for(progname=refname; *progname; progname++)
+ if(*progname=='/')
+ refname=progname+1;
+
#ifdef REL_OUTPUT
drelbuf = malloc(DRELBUFSIZE);
drelbuftop = drelbuf + DRELBUFSIZE;
@@ -129,10 +135,20 @@ PUBLIC void executable()
PUBLIC void flusherr()
{
- write(STDOUT_FILENO, errbuf, (unsigned) (errbufptr - errbuf));
+ if( errbufptr != errbuf )
+ write(errfil, errbuf, (unsigned) (errbufptr - errbuf));
errbufptr = errbuf;
}
+PRIVATE void stderr_out()
+{
+ if( errfil != STDERR_FILENO )
+ {
+ flusherr();
+ errfil = STDERR_FILENO;
+ }
+}
+
PRIVATE void flushout()
{
unsigned nbytes;
@@ -287,7 +303,7 @@ char *message;
{
putstr(message);
putbyte('\n');
- flusherr();
+ flusherr(); errfil = STDOUT_FILENO;
}
PUBLIC int readchar()
@@ -525,11 +541,32 @@ char *defarchentry;
putstr(defarchentry);
putbyte(')');
}
- putbyte('\n');
+ putstrn("");
+}
+
+PUBLIC void interseg(fname, aname, name)
+char *fname, *aname, *name;
+{
+ ++errcount;
+ refer();
+ putstr("error in ");
+ putstr(fname);
+ if( aname )
+ {
+ putstr("(");
+ putstr(aname);
+ putstr(")");
+ }
+ putstr(" intersegment jump to ");
+ if( name ) putstr(name);
+ else putstr("same file");
+
+ putstrn("");
}
PRIVATE void refer()
{
+ stderr_out();
putstr(refname);
putstr(": ");
}
@@ -538,6 +575,7 @@ PUBLIC void reserved(name)
char *name;
{
++errcount;
+ stderr_out();
putstr("incorrect use of reserved symbol: ");
putstrn(name);
}
@@ -554,19 +592,21 @@ bin_off_t size;
outhexdigs(count);
putstr(", supposed to be ");
outhexdigs(size);
- errexit("\n");
+ errexit("");
}
PUBLIC void undefined(name)
char *name;
{
++errcount;
+ stderr_out();
putstr("undefined symbol: ");
putstrn(name);
}
PUBLIC void usage()
{
+ stderr_out();
putstr("usage: ");
putstr(refname);
#ifdef REL_OUTPUT
diff --git a/ld/objchop.c b/ld/objchop.c
index c5a81e4..8defc13 100644
--- a/ld/objchop.c
+++ b/ld/objchop.c
@@ -61,7 +61,7 @@ long bsize;
FILE * ofd;
ofd = fopen(fname, "w");
- if( ofd == 0 ) fatal("Cannout open output file");
+ if( ofd == 0 ) fatal("Cannot open output file");
while(bsize>0)
{
diff --git a/ld/objdump86.c b/ld/objdump86.c
new file mode 100644
index 0000000..a5dbf44
--- /dev/null
+++ b/ld/objdump86.c
@@ -0,0 +1,681 @@
+/*
+ * This is a combination of three tools for decoding information from
+ * Dev86/ELKS object files and executables.
+ *
+ * This executable can be given the names:
+ *
+ * objdump86: Dumps detailed information about a binary file.
+ * size86: Summary sizes of the data in a binary file.
+ * nm86: The symbol table of the binary file.
+ *
+ * None of these programs have any options, neither can they currently deal
+ * with archive files. This may be a minor problem with nm86.
+ */
+
+#include <stdio.h>
+#include <malloc.h>
+#include <string.h>
+
+FILE * ifd = stdin;
+char * ifname;
+
+#ifdef __STDC__
+#define _(x) x
+#else
+#define _(x) ()
+#endif
+
+long get_long _((void));
+long get_sized _((int sz));
+unsigned int get_word _((void));
+int main _((int argc, char**argv));
+void do_file _((char * fname));
+int error _((char * str));
+int read_objheader _((void));
+int read_sectheader _((void));
+int read_syms _((void));
+void read_databytes _((void));
+void hex_output _((int ch));
+void fetch_aout_hdr _((void));
+void dump_aout _((void));
+void size_aout _((void));
+void nm_aout _((void));
+
+int sections;
+long segsizes[16];
+long textoff, textlen;
+long str_off, str_len;
+
+char ** symnames;
+char * symtab;
+
+int display_mode = 0;
+int multiple_files = 0;
+int byte_order = 0;
+
+long size_text, size_data, size_bss;
+
+int
+main(argc, argv)
+int argc;
+char ** argv;
+{
+ int ar;
+ char * p;
+
+ p = strrchr(argv[0], '/');
+ if(p) p++; else p=argv[0];
+
+ if( p[0] == 's' ) display_mode = 1;
+ if( p[0] == 'n' ) display_mode = 2;
+
+ if( display_mode == 1 )
+ printf("text\tdata\tbss\tdec\thex\tfilename\n");
+
+ multiple_files = (argc>2);
+
+ for(ar=1; ar<argc; ar++)
+ do_file(argv[ar]);
+
+ return (argc<=1);
+}
+
+void
+do_file(fname)
+char * fname;
+{
+ int modno, i, ch;
+
+ size_text = size_data = size_bss = 0;
+ byte_order = 0;
+
+ if( !display_mode )
+ printf("OBJECTFILE '%s'\n", fname);
+
+ ifname = fname;
+ if( (ifd=fopen(fname, "rb")) == 0 )
+ {
+ error("Cannot open file");
+ return;
+ }
+
+ switch( read_objheader() )
+ {
+ case 0: /* as86 object file */
+
+ for(modno=1; modno<=sections; modno++)
+ {
+ if( modno != 1 && !display_mode )
+ printf("OBJECTSECTION %d\n", modno);
+ if( read_sectheader() < 0 ) break;
+
+ for(i=0; i<16; i++)
+ {
+ if( i<3 ) size_text += segsizes[i];
+ else size_data += segsizes[i];
+ }
+
+ if( read_syms() < 0 ) break;
+
+ if( display_mode == 0 )
+ printf("text\tdata\tbss\tdec\thex\tfilename\n");
+ if( display_mode != 2 )
+ printf("%ld\t%ld\t%ld\t%ld\t%lx\t%s\n",
+ size_text, size_data, size_bss,
+ size_text+ size_data+ size_bss,
+ size_text+ size_data+ size_bss,
+ ifname);
+
+ if( sections == 1 && display_mode != 0 )
+ break;
+
+ read_databytes();
+ }
+ if( !display_mode )
+ {
+ i=0;
+ while( (ch=getc(ifd)) != EOF )
+ {
+ if( i == 0 )
+ {
+ printf("TRAILER\n");
+ i=1;
+ }
+ hex_output(ch);
+ }
+ hex_output(EOF);
+ }
+ break;
+
+ case 1: /* ELKS executable */
+ fseek(ifd, 0L, 0);
+
+ switch(display_mode)
+ {
+ case 0: dump_aout(); break;
+ case 1: size_aout(); break;
+ case 2: nm_aout(); break;
+ }
+ break;
+ }
+ fclose(ifd);
+
+ if( symtab ) free(symtab);
+ if( symnames ) free(symnames);
+ symtab = 0;
+ symnames = 0;
+}
+
+int
+error(str)
+char * str;
+{
+ switch( display_mode )
+ {
+ case 1: fprintf(stderr, "size: %s: %s\n", ifname, str); break;
+ case 2: fprintf(stderr, "nm: %s: %s\n", ifname, str); break;
+ default:
+ printf("Error: %s\n", str);
+ break;
+ }
+ return -1;
+}
+
+int
+read_objheader()
+{
+ unsigned char buf[5];
+
+ if( fread(buf, 1, 5, ifd) != 5 )
+ return error("Cannot read object header");
+
+ if( buf[0] != 0xA3 || buf[1] != 0x86 )
+ {
+ if( buf[0] == 1 && buf[1] == 3 )
+ {
+ sections = 1;
+ return 1;
+ }
+ return error("Bad magic number");
+ }
+
+ if( (unsigned char)(buf[0] + buf[1] + buf[2] + buf[3]) != buf[4] )
+ return error("Bad header checksum");
+
+ sections= buf[2]+256*buf[3];
+
+ return 0;
+}
+
+int
+read_sectheader()
+{
+ long ssenc, cpos;
+ int i, ver;
+
+ textoff = get_long(); textlen = get_long();
+ str_len=get_word(); str_off=textoff-str_len;
+ ver = get_word();
+
+ symtab = malloc((unsigned int)str_len+1);
+ if( symtab == 0 ) return error("Out of memory");
+
+ cpos = ftell(ifd);
+ fseek(ifd, str_off, 0);
+ fread(symtab, 1, (int)str_len, ifd);
+ fseek(ifd, cpos, 0);
+
+ if( !display_mode )
+ {
+ printf("MODULE '%s'\n", symtab);
+ printf("BYTEPOS %08lx\n", textoff);
+ printf("BINLEN %08lx\n", textlen);
+ printf("STRINGS %04lx +%04lx\n", str_off, str_len);
+ printf("VERSION %d.%d\n", ver/256, ver%256);
+ }
+
+ (void)get_long(); /* Ignore fives */
+ ssenc=get_long();
+
+ for(i=0; i<16; i++)
+ {
+ int ss;
+ ss = (i^3);
+ ss = ((ssenc>>(2*(15-ss)))&3);
+ segsizes[i] = get_sized(ss);
+ if( segsizes[i] && !display_mode )
+ printf("SEG%x %08lx\n", i, segsizes[i]);
+ }
+ if( !display_mode )
+ printf("\n");
+
+ return 0;
+}
+
+int
+read_syms()
+{
+ int syms, i;
+
+ syms=get_word();
+
+ if( !display_mode ) printf("SYMS %u\n", syms);
+ if( syms < 0 ) return error("Bad symbol table");
+
+ symnames = malloc(syms*sizeof(char*)+1);
+ if( symnames == 0 ) return error("Out of memory");
+
+ if(display_mode == 2 && multiple_files)
+ printf("\n%s:\n", ifname);
+
+ for(i=0; i<syms; i++)
+ {
+ long offset=0;
+ unsigned int nameoff, symtype;
+
+ nameoff = get_word();
+ symtype = get_word();
+ offset = get_sized((symtype>>14)&3);
+ symtype &= 0x3FFF;
+ symnames[i] = symtab+nameoff;
+
+ if( !display_mode )
+ {
+ printf("SYM %-4d %08lx ", i, offset);
+
+ printf("%s", (symtype&0x2000)?"C":".");
+ printf("%s", (symtype&0x0100)?"N":".");
+ printf("%s", (symtype&0x0080)?"E":".");
+ printf("%s", (symtype&0x0040)?"I":".");
+ printf("%c", "T12D456789abcdeUAhijklmnopqrstuv"[symtype&0x1F]);
+ if( symtype &0x1E20 )
+ printf(" %04x", symtype);
+ printf(" %s\n", symnames[i]);
+ }
+ if( display_mode == 2 )
+ {
+ if( symtype == 0x004f || symtype == 0x0040 )
+ printf(" ");
+ else
+ printf("%08lx ", offset);
+ switch(symtype)
+ {
+ case 0x004F: putchar('U'); break;
+ case 0x0000: putchar('t'); break;
+ case 0x0003: putchar('d'); break;
+ case 0x2003: putchar('b'); break;
+ case 0x0043: putchar('C'); break;
+ case 0x0083: putchar('D'); break;
+ case 0x0080: putchar('T'); break;
+ case 0x0040: putchar('T'); break;
+ case 0x0180: putchar('N'); break;
+ case 0x0010: putchar('a'); break;
+ case 0x0090: putchar('A'); break;
+ default: putchar('?'); break;
+ }
+ printf(" %s\n", symnames[i]);
+ }
+
+ if( symtype == 0x43 || symtype == 0x2003 )
+ size_bss += offset;
+ }
+ if( !display_mode )
+ printf("\n");
+
+ return 0;
+}
+
+void
+read_databytes()
+{
+static char * relstr[] = {"ERR", "DB", "DW", "DD"};
+ long l;
+ int ch, i;
+ int curseg = 0;
+ int relsize = 0;
+ fseek(ifd, textoff, 0);
+
+ printf("\nBYTECODE\n");
+ for(;;)
+ {
+ if( (ch=getc(ifd)) == EOF ) break;
+
+ if( ch == 0 ) break;
+
+ switch( ch & 0xC0 )
+ {
+ case 0x00: switch(ch & 0xF0)
+ {
+ case 0x00: /* Relocator size */
+ printf("RELSZ %d\n", relsize= (ch&0xF));
+ if(relsize>3) relsize=3;
+ break;
+ case 0x10: /* Skip bytes */
+ printf("SKP %ld\n", get_sized(ch&0xF));
+ break;
+ case 0x20: /* Segment */
+ printf("SEG %x\n", curseg= (ch&0xF));
+ break;
+ default: printf("CODE %02x - unknown\n", ch);
+ return ;
+ }
+ break;
+ case 0x40: /* Raw bytes */
+ {
+ int abscnt = (ch&0x3F);
+ if( abscnt == 0 ) abscnt = 64;
+ for( i=0; i<abscnt; i++ )
+ {
+ if( (ch=getc(ifd)) == EOF ) break;
+ hex_output(ch);
+ }
+ hex_output(EOF);
+
+ if( ch == EOF ) return;
+ }
+ break;
+ case 0x80: /* Relocator - simple */
+ l = get_sized(relsize);
+ printf("%s SEG%x%s%s", relstr[relsize],
+ (ch&0xF),
+ (ch&0x20)?"-PC":"",
+ (ch&0x10)?"+?":"");
+ if(l)
+ printf("+0x%04lx", l);
+ putchar('\n');
+ break;
+ case 0xC0: /* Relocator - symbol relative */
+ if( ch & 0x18 )
+ {
+ printf("CODE %02x - unknown\n", ch);
+ return;
+ }
+ if( ch & 4 ) i = get_word();
+ else i = getc(ifd);
+ l = get_sized(ch&3);
+
+ printf("%s %s%s%s", relstr[relsize],
+ symnames[i],
+ (ch&0x20)?"-PC":"",
+ (ch&0x18)?"+?":"");
+ if(l)
+ printf("+0x%04lx", l);
+ putchar('\n');
+ break;
+ }
+ }
+ printf("\n");
+}
+
+long
+get_sized(sz)
+int sz;
+{
+ switch(sz)
+ {
+ case 0: return 0;
+ case 1: return getc(ifd);
+ case 2: return get_word();
+ case 3: return get_long();
+ }
+ return -1;
+}
+
+long
+get_long()
+{
+ long retv = 0;
+ int i;
+ for(i=0; i<32; i+=16)
+ {
+ unsigned int v = get_word();
+ if( byte_order & 2 )
+ retv += ((long)v<<(16-i));
+ else
+ retv += ((long)v<<i);
+ }
+ return retv;
+}
+
+unsigned int
+get_word()
+{
+ long retv = 0;
+ int i;
+ for(i=0; i<16; i+=8)
+ {
+ int v = getc(ifd);
+ if( v == EOF ) return -1;
+ if( byte_order & 1 )
+ retv += (v<<(8-i));
+ else
+ retv += (v<<i);
+ }
+ return retv;
+}
+
+void
+hex_output(ch)
+int ch;
+{
+static char linebuf[80];
+static char buf[20];
+static int pos = 0;
+
+ if( ch == EOF )
+ {
+ if(pos)
+ printf(": %.66s\n", linebuf);
+ pos = 0;
+ }
+ else
+ {
+ if(!pos)
+ memset(linebuf, ' ', sizeof(linebuf));
+ sprintf(buf, "%02x", ch&0xFF);
+ memcpy(linebuf+pos*3+(pos>7), buf, 2);
+ if( ch > ' ' && ch <= '~' ) linebuf[50+pos] = ch;
+ else linebuf[50+pos] = '.';
+ pos = ((pos+1) & 0xF);
+ if( pos == 0 )
+ {
+ printf(": %.66s\n", linebuf);
+ memset(linebuf, ' ', sizeof(linebuf));
+ }
+ }
+}
+
+/************************************************************************/
+/* ELKS a.out versions
+ */
+
+long header[12];
+int h_len, h_flgs, h_cpu;
+
+void
+fetch_aout_hdr()
+{
+ int i;
+
+ header[0] = get_long();
+ header[1] = get_long();
+ byte_order = ((header[0]>>24) & 3);
+
+ h_len = (header[1] & 0xFF);
+ h_flgs = ((header[0]>>16) & 0xFF);
+ h_cpu = ((header[0]>>24) & 0xFF);
+
+ for(i=2; i<8; i++)
+ {
+ if( i*4 <= h_len )
+ header[i] = get_long();
+ else
+ header[i] = 0;
+ }
+}
+
+void
+dump_aout()
+{
+static char * cpu[] = { "unknown", "8086", "m68k", "ns16k", "i386", "sparc" };
+static char * byteord[] = { "LITTLE_ENDIAN", "(2143)","(3412)","BIG_ENDIAN" };
+ int i;
+ long l;
+
+ if( display_mode == 0 ) fetch_aout_hdr();
+
+ if( h_cpu > 0x17 ) h_cpu &= 3;
+
+ printf("HLEN %d\n", h_len);
+ printf("CPU %s %s\n", cpu[h_cpu>>2], byteord[h_cpu&3]);
+
+ printf("FLAGS:");
+ if( h_flgs & 0x01 ) printf(" A_UZP");
+ if( h_flgs & 0x02 ) printf(" A_PAL");
+ if( h_flgs & 0x04 ) printf(" A_NSYM");
+ if( h_flgs & 0x08 ) printf(" FLG-08");
+ if( h_flgs & 0x10 ) printf(" A_EXEC");
+ if( h_flgs & 0x20 ) printf(" A_SEP");
+ if( h_flgs & 0x40 ) printf(" A_PURE");
+ if( h_flgs & 0x80 ) printf(" A_TOVLY");
+ printf("\n");
+
+ if( header[5] )
+ printf("a_entry = 0x%08lx\n", header[5]);
+ printf("a_total = 0x%08lx\n", header[6]);
+ if( header[7] )
+ printf("a_syms = 0x%08lx\n", header[7]);
+
+ if( h_len >= 36 )
+ printf("a_trsize = 0x%08lx\n", header[8]);
+ if( h_len >= 40 )
+ printf("a_drsize = 0x%08lx\n", header[9]);
+ if( h_len >= 44 )
+ printf("a_tbase = 0x%08lx\n", header[10]);
+ if( h_len >= 48 )
+ printf("a_dbase = 0x%08lx\n", header[11]);
+ printf("\n");
+
+ size_aout();
+ printf("\n");
+
+ if( header[7] )
+ {
+ printf("SYMBOLS\n");
+ nm_aout();
+ }
+ else
+ printf("NO SYMBOLS\n");
+ printf("\n");
+
+ printf("TEXTSEG\n");
+ fseek(ifd, (long)h_len, 0);
+ for(l=0; l<header[2]; l++)
+ {
+ if( (i=getc(ifd)) == EOF ) break;
+ hex_output(i);
+ }
+ hex_output(EOF);
+
+ printf("DATASEG\n");
+ fseek(ifd, (long)h_len+header[2], 0);
+ for(l=0; l<header[3]; l++)
+ {
+ if( (i=getc(ifd)) == EOF ) break;
+ hex_output(i);
+ }
+ hex_output(EOF);
+}
+
+void
+size_aout()
+{
+ if( display_mode == 1 ) fetch_aout_hdr();
+
+ if( display_mode == 0 )
+ printf("text\tdata\tbss\tdec\thex\tfilename\n");
+
+ printf("%ld\t%ld\t%ld\t%ld\t%lx\t%s\n",
+ header[2], header[3], header[4],
+ header[2]+ header[3]+ header[4],
+ header[2]+ header[3]+ header[4],
+ ifname);
+}
+
+void
+nm_aout()
+{
+ char n_name[10];
+ long n_value;
+ int n_sclass, n_numaux, n_type;
+ long bytes_left;
+
+ if( display_mode == 2 ) fetch_aout_hdr();
+
+ fseek(ifd, h_len+header[2]+header[3]+header[8]+header[9], 0);
+
+ if( h_flgs & 4 ) { error("Executable has new format symtab\n"); return; }
+
+ bytes_left = header[7];
+
+ if( bytes_left == 0 )
+ printf("No symbols in '%s'\n", ifname);
+ else if(multiple_files)
+ printf("\n%s:\n", ifname);
+
+ while(bytes_left > 16)
+ {
+ if( fread(n_name, 1, 8, ifd) != 8 ) return;
+ n_name[8] = 0;
+ n_value = get_long();
+ if( (n_sclass = getc(ifd)) == EOF ) return;
+ if( (n_numaux = getc(ifd)) == EOF ) return;
+ n_type = get_word();
+
+ printf("%08lx ", n_value);
+ switch(n_sclass)
+ {
+ case 0x01: printf("a "); break;
+ case 0x12: printf("T "); break;
+ case 0x13: printf("D "); break;
+ case 0x14: printf("C "); break;
+ case 0x1a: printf("t "); break;
+ case 0x1b: printf("d "); break;
+ case 0x1c: printf("b "); break;
+ default: if( display_mode )
+ {
+ printf("? "); break;
+ }
+
+ printf("n_sclass=");
+ switch(n_sclass>>3)
+ {
+ case 0: printf("C_NULL,"); break;
+ case 2: printf("C_EXT,"); break;
+ case 3: printf("C_STAT,"); break;
+ default: printf("%04o,", n_sclass&0xF8);
+ }
+ switch(n_sclass&7)
+ {
+ case 0: printf("N_UNDF "); break;
+ case 1: printf("N_ABS "); break;
+ case 2: printf("N_TEXT "); break;
+ case 3: printf("N_DATA "); break;
+ case 4: printf("N_BSS "); break;
+ case 5: printf("N_COMM "); break;
+ default: printf("%o ", n_sclass&7); break;
+ }
+ break;
+ }
+
+ if( display_mode == 0 )
+ {
+ if( n_numaux )
+ printf("n_numaux=%02x ", n_numaux);
+ if( n_type )
+ printf("n_type=%04x ", n_type);
+ }
+
+ printf("%s\n", n_name);
+ }
+}
diff --git a/ld/syshead.h b/ld/syshead.h
index 5eeda82..fa5c23a 100644
--- a/ld/syshead.h
+++ b/ld/syshead.h
@@ -24,6 +24,7 @@
#define mode_t unsigned short
#define SEEK_SET 0
#define STDOUT_FILENO 0
+#define STDERR_FILENO 0
#endif
/******************************************************************************/
@@ -54,6 +55,7 @@ void *memset P((void *s, int c, unsigned n));
int access P((const char *path, int amode));
#define SEEK_SET 0
#define STDOUT_FILENO 0
+#define STDERR_FILENO 2
#define mode_t unsigned short
#define off_t long
diff --git a/ld/type.h b/ld/type.h
index 217d6a9..a4c16aa 100644
--- a/ld/type.h
+++ b/ld/type.h
@@ -114,6 +114,7 @@ void outofmemory P((void));
void prematureeof P((void));
void redefined P((char *name, char *message, char *archentry,
char *deffilename, char *defarchentry));
+void interseg P((char *fname, char *aname, char *name));
void reserved P((char *name));
void size_error P((int seg, bin_off_t count, bin_off_t size));
void undefined P((char *name));
diff --git a/ld/writex86.c b/ld/writex86.c
index 5dd3e8d..b2bab23 100644
--- a/ld/writex86.c
+++ b/ld/writex86.c
@@ -13,10 +13,8 @@
#define bdataoffset (data_base_value)
#define page_size() ((bin_off_t)4096)
-#ifdef __ELF__
#ifndef ELF_SYMS
-#define ELF_SYMS 1
-#endif
+#define ELF_SYMS 0
#endif
# define FILEHEADERLENGTH (headerless?0:A_MINHDR)
@@ -130,13 +128,21 @@ bool_pt arguzp;
symres(segboundary); /* __segXCL */
segboundary[7] = 'H';
symres(segboundary); /* __segXCH */
+#ifndef DATASEGS
+ if( curseg > 3 )
+ {
+ segboundary[6] = 'S';
+ segboundary[7] = 'O';
+ symres(segboundary); /* __segXSO */
+ }
+#endif
}
curseg = 3;
symres("__edata");
symres("__end");
curseg = 0; /* text seg, s.b. variable */
symres("__etext");
- if( headerless ) symres("__segoff");
+ symres("__segoff");
/* calculate segment and common sizes (sum over loaded modules) */
/* use zero init of segsz[] */
@@ -186,8 +192,13 @@ bool_pt arguzp;
}
/* calculate seg positions now their sizes are known */
- /* temp use fixed order 0D 0C 1D 1C 2D 2C ... */
- /* assume seg 0 is text and rest are data */
+ /*
+#ifdef DATASEGS
+ * Assume seg 0 is text and rest are data
+#else
+ * Assume seg 1..3 are data, Seg 0 is real text, seg 4+ are far text
+#endif
+ */
segpos[0] = segbase[0] = spos = btextoffset;
combase[0] = segbase[0] + segsz[0];
segadj[1] = segadj[0] = -btextoffset;
@@ -201,9 +212,23 @@ bool_pt arguzp;
bdataoffset = etextpadoff;
segpos[1] = segbase[1] = edataoffset = bdataoffset;
combase[1] = segbase[1] + segsz[1];
+#ifndef DATASEGS
+ for (seg = 4; seg < NSEG; ++seg)
+ {
+ segpos[seg] = segbase[seg] = 0;
+ combase[seg] = segbase[seg] + segsz[seg];
+ segadj[seg] = etextpadoff;
+
+ etextpadoff += ld_roundup(segsz[seg] + comsz[seg], 0x10, bin_off_t);
+ segadj[1] += ld_roundup(segsz[seg] + comsz[seg], 0x10, bin_off_t);
+ }
+ for (seg = 2; seg < 4; ++seg)
+#else
for (seg = 2; seg < NSEG; ++seg)
+#endif
{
segpos[seg] = segbase[seg] = combase[seg - 1] + comsz[seg - 1];
+#ifdef MC6809
if (seg == DPSEG)
{
/* temporarily have fixed DP seg */
@@ -216,6 +241,7 @@ bool_pt arguzp;
segpos[seg] = segbase[seg] = (segbase[seg] + 0xFF)
& ~(bin_off_t) 0xFF;
}
+#endif
combase[seg] = segbase[seg] + segsz[seg];
segadj[seg] = segadj[seg - 1];
}
@@ -241,8 +267,12 @@ bool_pt arguzp;
/* adjust special symbols */
for (seg = 0; seg < NSEG; ++seg)
{
+#ifdef DATASEGS
if (segsz[seg] != 0)
/* only count data of nonzero length */
+#else
+ if (segsz[seg] != 0 && seg < 4)
+#endif
edataoffset = segbase[seg] + segsz[seg];
segboundary[5] = hexdigit[seg]; /* to __segX?H */
segboundary[6] = 'D';
@@ -256,11 +286,24 @@ bool_pt arguzp;
segboundary[7] = 'H';
setsym(segboundary, tempoffset + comsz[seg]);
/* __segXCH */
+#ifndef DATASEGS
+ if( seg > 3 )
+ {
+ segboundary[6] = 'S';
+ segboundary[7] = 'O';
+ setsym(segboundary, (bin_off_t)(segadj[seg]-segadj[0])/0x10);
+ /* __segXSO */
+ }
+#endif
}
setsym("__etext", etextoffset);
setsym("__edata", edataoffset);
+#ifdef DATASEGS
setsym("__end", endoffset = combase[NSEG - 1] + comsz[NSEG - 1]);
- if( headerless ) setsym("__segoff", (bin_off_t)(segadj[1]-segadj[0])/0x10);
+#else
+ setsym("__end", endoffset = combase[3] + comsz[3]);
+#endif
+ setsym("__segoff", (bin_off_t)(segadj[1]-segadj[0])/0x10);
if( !bits32 )
{
if( etextoffset > 65536L )
@@ -322,11 +365,20 @@ bool_pt arguzp;
flags & C_MASK)
switch (flags & (A_MASK | SEGM_MASK))
{
+#ifdef DATASEGS
case 0:
+#else
+ default:
+#endif
extsym.n_sclass |= N_TEXT;
case A_MASK:
break;
+#ifdef DATASEGS
default:
+#else
+ case 1: case 2: case 3:
+ case A_MASK|1: case A_MASK|2: case A_MASK|3:
+#endif
if (flags & (C_MASK | SA_MASK))
extsym.n_sclass |= N_BSS;
else
@@ -414,7 +466,14 @@ struct modstruct *modptr;
case CM_OFFSET_RELOC:
offset = readsize(relocsize);
if (modify & R_MASK)
+ {
+#ifndef DATASEGS
+ int m = (modify & SEGM_MASK);
+ if( curseg != m && m != SEGM_MASK )
+ interseg(modptr->filename, modptr->archentry, (char*)0);
+#endif
offset -= (spos + relocsize);
+ }
offtocn(buf, segbase[modify & SEGM_MASK] + offset, relocsize);
writeout(buf, relocsize);
spos += relocsize;
@@ -424,7 +483,14 @@ struct modstruct *modptr;
(modify & S_MASK ? 2 : 1))];
offset = readconvsize((unsigned) modify & OF_MASK);
if (modify & R_MASK)
+ {
+#ifndef DATASEGS
+ int m = (symptr->flags & SEGM_MASK);
+ if( curseg != m && m != SEGM_MASK )
+ interseg(modptr->filename, modptr->archentry, symptr->name);
+#endif
offset -= (spos + relocsize);
+ }
offset += symptr->value;
offtocn(buf, offset, relocsize);
writeout(buf, relocsize);
diff --git a/ld/x b/ld/x
new file mode 100644
index 0000000..90d943e
--- /dev/null
+++ b/ld/x
@@ -0,0 +1 @@
+PUBLIC void interseg(fname, aname, name)