summaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>1997-10-05 15:05:09 +0200
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:40:02 +0200
commit48798bf2eb93ec3b99720ac2e16093441156653d (patch)
tree35e03d95df5f2677f05e32d70abb6d0583aa47ba /ld
parent9d97bc3cb3aecd3416fb7c4be3ca2f436665b696 (diff)
downloaddev86-48798bf2eb93ec3b99720ac2e16093441156653d.tar.gz
Import Dev86src-0.13.0.tar.gzv0.13.0
Diffstat (limited to 'ld')
-rw-r--r--ld/Makefile4
-rw-r--r--ld/README.199417
l---------ld/ar.h1
-rw-r--r--ld/catimage.c238
-rw-r--r--ld/ld.c10
-rw-r--r--ld/ld86r.c81
-rw-r--r--ld/syshead.h12
-rw-r--r--ld/typeconv.c.old536
-rw-r--r--ld/x86_aout.h2
9 files changed, 333 insertions, 568 deletions
diff --git a/ld/Makefile b/ld/Makefile
index 9e1f124..985008c 100644
--- a/ld/Makefile
+++ b/ld/Makefile
@@ -18,7 +18,7 @@ DEFS =-DREL_OUTPUT -DBUGCOMPAT
OBJS= dumps.o io.o ld.o readobj.o table.o typeconv.o linksyms.o \
writex86.o writebin.o writerel.o
-all: ld86 objchop
+all: ld86 objchop catimage
ld86: $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) -o $@
@@ -28,7 +28,7 @@ install: ld86
install -m 755 ld86 $(LIBDIR)
clean realclean:
- rm -f *.o ld86 objchop
+ rm -f *.o ld86 ld86r objchop catimage
$(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/README.1994 b/ld/README.1994
deleted file mode 100644
index 669c8a8..0000000
--- a/ld/README.1994
+++ /dev/null
@@ -1,17 +0,0 @@
-The `bcc' and `ld' parts of the bin86 distribution are now covered by the
-GNU GPL. The next release of the `as' part will be covered by the GPL.
-The `a.out.h' part is no longer used and should be deleted. The `bccfp'
-belongs in another package and may be deleted.
-
-`ld' is now correctly ported to linux. It now defaults to the target
-a.out format for output. However, it still requires its own special
-format for input. It is best used as a post-processor for `as' to
-produce objects in a.out format. Then the target ld can be used to
-link the objects. The post-processing step is:
-
- ld86 -r -o tmpfile.o file.o && mv tmpfile.o file.o
-
-This can be handled more simply by using the `bcc' compiler driver as
-the assembler and never calling as86 or ld86 directly:
-
- AS86="bcc -G -0 -c"
diff --git a/ld/ar.h b/ld/ar.h
deleted file mode 120000
index 774528d..0000000
--- a/ld/ar.h
+++ /dev/null
@@ -1 +0,0 @@
-../libc/include/ar.h \ No newline at end of file
diff --git a/ld/catimage.c b/ld/catimage.c
new file mode 100644
index 0000000..7d5c7a0
--- /dev/null
+++ b/ld/catimage.c
@@ -0,0 +1,238 @@
+/*
+ * This program concatenates memory images the executables specified
+ * on it's command line.
+ *
+ * The 'boot' image must have a symbol table any symbols that match
+ * the below patterns have their values patched.
+ *
+ * int __seg0_text; - Always zero
+ * int __seg0_data; - Segment offset of data of boot executable
+ *
+ * int __seg1_text; - Segment offset of text of first executable
+ * int __seg1_data; - Segment offset of data of first executable
+ * int __seg2_text; - Segment offset of text of second executable
+ * int __seg2_data; - Segment offset of data of second executable
+ *
+ * int __seg9_text; - Segment offset of text of executable nine
+ * int __seg9_data; - Segment offset of data of executable nine
+ *
+ * Any segment that's not an exact multiple of 16 bytes long is rounded up.
+ *
+ */
+
+#include <stdio.h>
+#include "x86_aout.h"
+
+#ifndef __OUT_OK
+#error "Compile error: struct exec invalid (long not 32 bit ?)"
+#endif
+
+unsigned long text_offt[10]; /* Locations to patch (0=don't) */
+unsigned long data_offt[10];
+
+char * input_file = "";
+FILE * ofd;
+FILE * ifd = 0;
+struct exec header;
+
+main(argc, argv)
+int argc;
+char ** argv;
+{
+ long image_offset, text_off;
+ int image_id;
+
+ if( argc < 3 || argc > 11 )
+ fatal("Usage: catimage mem.bin boot.out [a1.out] ... [a9.out]");
+
+ open_obj(argv[2]);
+
+ ofd = fopen(argv[1], "w");
+ if( ofd == 0 ) fatal("Cannot open output file");
+
+ read_symtable();
+
+ image_offset = 0;
+
+ for(image_id=0; image_id < argc-2; image_id++)
+ {
+ open_obj(argv[image_id+2]);
+
+ printf("File %-14s seg=0x%04lx text=0x%04lx data=0x%04lx\n",
+ input_file, (image_offset>>4),
+ (header.a_text>>4), (header.a_total>>4));
+
+ text_off = image_offset;
+ if( header.a_flags & A_SEP )
+ {
+ copy_segment(image_offset, A_TEXTPOS(header), header.a_text);
+ image_offset += header.a_text;
+ image_offset = ((image_offset+15L)&-16L);
+
+ copy_segment(image_offset, A_DATAPOS(header), header.a_data);
+ }
+ else
+ {
+ copy_segment(image_offset, A_TEXTPOS(header),
+ header.a_text+header.a_data);
+ }
+
+ patch_bin(text_offt[image_id], (unsigned)(text_off>>4));
+ patch_bin(data_offt[image_id], (unsigned)(image_offset>>4));
+
+ image_offset += header.a_total;
+ image_offset = ((image_offset+15L)&-16L);
+ }
+
+ if( fseek(ofd, image_offset-1, 0) < 0 )
+ fatal("Cannot seek to end of output");
+
+ fputc('\0', ofd);
+ fclose(ofd);
+
+ printf("Output file size %ldKb\n", ((image_offset+0x3FF)>>10));
+
+ if( ifd ) fclose(ifd);
+ exit(0);
+}
+
+open_obj(fname)
+char * fname;
+{
+ input_file = fname;
+
+ if( ifd ) fclose(ifd);
+
+ ifd = fopen(fname, "r");
+ if( ifd == 0 ) fatal("Cannot open input file");
+
+ if( fread(&header, A_MINHDR, 1, ifd) != 1 )
+ fatal("Incomplete executable header");
+
+ if( BADMAG(header) )
+ fatal("Input file has bad magic number");
+}
+
+copy_segment(out_offset, in_offset, length)
+long out_offset, in_offset, length;
+{
+ char buffer[1024];
+ int ssize;
+ long bsize = length;
+
+ if( fseek(ifd, in_offset, 0) < 0 )
+ fatal("Cannot seek to start of input segment");
+
+ if( fseek(ofd, out_offset, 0) < 0 )
+ fatal("Cannot seek to start of output segment");
+
+ while(bsize>0)
+ {
+ if( bsize > sizeof(buffer) ) ssize = sizeof(buffer);
+ else ssize = bsize;
+
+ if( (ssize=fread(buffer, 1, ssize, ifd)) <= 0 )
+ fatal("Error reading segment from executable");
+ if( fwrite(buffer, 1, ssize, ofd) != ssize )
+ fatal("Error writing output file");
+ bsize -= ssize;
+ }
+}
+
+patch_bin(file_off, value)
+long file_off;
+int value;
+{
+ char wbuf[4];
+ if( file_off <= 0 ) return;
+
+ printf("Patch at offset 0x%05lx = %04x\n", file_off, value);
+
+ wbuf[0] = value;
+ wbuf[0] = (value>>8);
+
+ if( fseek(ofd, file_off, 0) < 0 )
+ fatal("Cannot seek to patch binary");
+
+ if( fwrite(wbuf, 1, 2, ofd) != 2 )
+ fatal("Error patching output file");
+}
+
+read_symtable()
+{
+ struct nlist item;
+ int nitems;
+ long base_off = 0;
+
+ if( header.a_syms == 0 )
+ fatal("Input file has been stripped!");
+
+ if( fseek(ifd, A_SYMPOS(header), 0) < 0 )
+ fatal("Cannot seek to start of symbols");
+
+ nitems = header.a_syms;
+
+ /* Foreach symbol */
+ while( fread(&item, sizeof(struct nlist), 1, ifd) == 1 )
+ {
+ if( nitems-- <= 0 ) break;
+
+ /* Match the name */
+ if( memcmp(item.n_name, "__seg", 5) != 0 || item.n_name[6] != '_' )
+ continue;
+
+ /* Externals only */
+ if( (item.n_sclass & N_CLASS) != C_EXT )
+ continue;
+
+ /* Data seg only */
+ if( (item.n_sclass & N_SECT) != N_DATA &&
+ (item.n_sclass & N_SECT) != N_BSS &&
+ (item.n_sclass & N_SECT) != N_TEXT )
+ continue;
+
+ if( item.n_name[5] < '0' || item.n_name[5] > '9' )
+ continue;
+
+ if( (header.a_flags & A_SEP) && (item.n_sclass & N_SECT) != N_TEXT )
+ base_off = header.a_text;
+ else
+ base_off = 0;
+
+ switch( item.n_name[7] )
+ {
+ case 'd': data_offt[item.n_name[5]-'0'] = base_off+item.n_value; break;
+ case 't': text_offt[item.n_name[5]-'0'] = base_off+item.n_value; break;
+ }
+
+#ifdef DEBUG
+ printf("%-8.8s ", item.n_name);
+ printf("%08lx ", item.n_value);
+ switch(item.n_sclass & N_CLASS)
+ {
+ case C_NULL: printf("C_NULL "); break;
+ case C_EXT: printf("C_EXT "); break;
+ case C_STAT: printf("C_STAT "); break;
+ default: printf("%-6d ", (item.n_sclass & N_CLASS)); break;
+ }
+ switch(item.n_sclass & N_SECT)
+ {
+ case N_UNDF: printf("N_UNDF "); break;
+ case N_ABS : printf("N_ABS "); break;
+ case N_TEXT: printf("N_TEXT "); break;
+ case N_DATA: printf("N_DATA "); break;
+ case N_BSS : printf("N_BSS "); break;
+ case N_COMM: printf("N_COMM "); break;
+ }
+ printf("\n");
+#endif
+ }
+}
+
+fatal(str)
+char * str;
+{
+ fprintf(stderr, "catimage:%s: %s\n", input_file, str);
+ exit(2);
+}
+
diff --git a/ld/ld.c b/ld/ld.c
index 0a307e9..2a3999f 100644
--- a/ld/ld.c
+++ b/ld/ld.c
@@ -107,7 +107,6 @@ char **argv;
{
argv[0] = "ld86r";
execv("/usr/bin/ld86r", argv);
- execv("/usr/bin/ld86", argv);
}
#endif
usage();
@@ -190,7 +189,7 @@ char **argv;
infilename = tfn;
/* fatalerror(tfn); * XXX */
readsyms(infilename, flag['t']);
- icount++;
+ icount+=2;
break;
case 'o': /* output file name */
if (arg[2] != 0 || ++argn >= argc || outfilename != NUL_PTR)
@@ -205,20 +204,21 @@ char **argv;
#ifdef REL_OUTPUT
#ifndef MSDOS
-#ifndef BUGCOMPAT
+#ifdef BUGCOMPAT
+ if( icount>1 && ( flag['r'] && !flag['N'] ) )
+#else
if( flag['r'] && !flag['N'] )
+#endif
{
/* Ok, try for an alternate linker */
if( strcmp(argv[0], "ld86r") != 0 )
{
argv[0] = "ld86r";
execv("/usr/bin/ld86r", argv);
- execv("/usr/bin/ld86", argv);
}
}
#endif
#endif
-#endif
#ifdef MSDOS
/* MSDOS Native is special, we make a COM file */
diff --git a/ld/ld86r.c b/ld/ld86r.c
new file mode 100644
index 0000000..c8c0631
--- /dev/null
+++ b/ld/ld86r.c
@@ -0,0 +1,81 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <malloc.h>
+
+#define ARMAG "!<arch>\n"
+#define SARMAG 8
+#define ARFMAG "`\n"
+
+struct ar_hdr {
+ char ar_name[16],
+ ar_date[12],
+ ar_uid[6],
+ ar_gid[6],
+ ar_mode[8],
+ ar_size[10],
+ ar_fmag[2];
+} arbuf;
+
+void
+fatal(char * str) { fprintf(stderr, "%s\n", str); exit(2); }
+
+void
+main(int argc, char ** argv)
+{
+char buf[128];
+ FILE * fd, * ifd;
+ struct stat st;
+ int ar, libarg=0, need_o = 0, got_o = 0;
+
+ for(ar=1; ar<argc; ar++) if( argv[ar][0] == '-' )
+ {
+ if( argv[ar][1] == 'r' ) need_o = 1;
+ if( argv[ar][1] == 'o' ) { got_o++; libarg = 0; }
+ }
+ else
+ {
+ if( libarg == 0 ) libarg = ar;
+ }
+
+ if( libarg == 0 || got_o > 1 || need_o > got_o )
+ fatal("Err, what's the output gonna be called?");
+
+ if( (fd =fopen(argv[libarg], "wb")) == 0 ) fatal("Cannot open archive");
+ if( fwrite(ARMAG, 1, SARMAG, fd) != SARMAG) fatal("Cannot write magic");
+
+ for(ar=1; ar<argc; ar++) if( ar != libarg && argv[ar][0] != '-' )
+ {
+ char * ptr;
+ if( stat(argv[ar], &st) < 0 ) fatal("Cannot stat object");
+ if((ptr=strchr(argv[ar], '/'))) ptr++; else ptr=argv[ar];
+ memset(&arbuf, ' ', sizeof(arbuf));
+ strcpy(buf, ptr); strcat(buf, "/ ");
+ strncpy(arbuf.ar_name, buf, sizeof(arbuf.ar_name));
+
+ sprintf(arbuf.ar_date, "%-12ld", (long)st.st_mtime);
+ sprintf(arbuf.ar_uid, "%-6d", (int)(st.st_uid%1000000L));
+ sprintf(arbuf.ar_gid, "%-6d", (int)(st.st_gid%1000000L));
+ sprintf(arbuf.ar_mode, "%-8lo", (long)st.st_mode);
+ sprintf(arbuf.ar_size, "%-10ld", (long)st.st_size);
+ memcpy(arbuf.ar_fmag, ARFMAG, sizeof(arbuf.ar_fmag));
+
+ if( fwrite(&arbuf, 1, sizeof(arbuf), fd) != sizeof(arbuf) )
+ fatal("Cannot write header");
+
+ ptr = malloc(st.st_size+2);
+ if( ptr == 0 ) fatal("Out of memory");
+ ptr[st.st_size] = ' ';
+ if( (ifd = fopen(argv[ar], "rb")) == 0 ) fatal("Cannot open input");
+ if( fread(ptr, 1, st.st_size, ifd) != st.st_size )
+ fatal("Cannot read input file");
+ fclose(ifd);
+
+ if( st.st_size&1 ) st.st_size++;
+ if( fwrite(ptr, 1, st.st_size, fd) != st.st_size )
+ fatal("Cannot write output file");
+ }
+ fclose(fd);
+ exit(0);
+}
diff --git a/ld/syshead.h b/ld/syshead.h
index 7e110ab..5eeda82 100644
--- a/ld/syshead.h
+++ b/ld/syshead.h
@@ -1,10 +1,4 @@
-#ifndef STDC_HEADERS_MISSING
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#endif
-
#ifndef POSIX_HEADERS_MISSING
#include <sys/types.h>
#include <sys/stat.h>
@@ -12,6 +6,12 @@
#include <fcntl.h>
#endif
+#ifndef STDC_HEADERS_MISSING
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#endif
+
#ifdef MSDOS
#undef POSIX_HEADERS_MISSING
#include <sys/types.h>
diff --git a/ld/typeconv.c.old b/ld/typeconv.c.old
deleted file mode 100644
index 82dafdd..0000000
--- a/ld/typeconv.c.old
+++ /dev/null
@@ -1,536 +0,0 @@
-/* typeconv.c - convert between char arrays and unsigneds */
-
-/* Copyright (C) 1994 Bruce Evans */
-
-/*
- c2u2(): 2 byte array to 2 byte unsigned
- c4u4(): 4 byte array to 4 byte unsigned
- cnu2(): n byte array to 2 byte unsigned
- cnu4(): n byte array to 4 byte unsigned
- u2c2(): 2 byte unsigned to 2 byte array
- u2cn(): 2 byte unsigned to n byte array
- u4c4(): 4 byte unsigned to 4 byte array
- u4cn(): 4 byte unsigned to n byte array
- typeconv_init: (re)initialise for given byte order.
- Default is no swapping, but the initialisation should be done
- anyway to provide some validity checks (returns FALSE if error).
-
- Not provided:
- c2u4(), c4u2(), u2c4(), u4c2().
- Each of these is best done by truncating or extending a return value
- or argument to the appropiate fixed-count function.
- c4u2() has too many cases to do in-line conveniently, and the others
- are hardly more efficient when done in-line.
-
- 4 byte orderings for both char arrays and unsigneds are supported:
- 0123 - little-endian
- 3210 - big-endian
- 2301 - little-endian with long words big-endian (pdp11)
- 1032 - big-endian with long words little_endian (who knows?)
-
- The unsigned's byte order is that of the machine on which these
- routines are running.
- It is determined at run time initialisation since the compiler/
- preprocessor is too dumb to tell us at compile time.
-*/
-
-#include "const.h"
-#include "type.h"
-#include "globvar.h"
-
-FORWARD u2_pt c2u2_00 P((char *buf));
-FORWARD u4_pt c4u4_00 P((char *buf));
-FORWARD u2_pt c2u2_ss P((char *buf));
-FORWARD u4_pt c4u4_ss P((char *buf));
-FORWARD u4_pt c4u4_s0 P((char *buf));
-FORWARD u4_pt c4u4_0s P((char *buf));
-FORWARD void u2c2_00 P((char *buf, u2_pt offset));
-FORWARD void u4c4_00 P((char *buf, u4_t offset));
-FORWARD void u2c2_ss P((char *buf, u2_pt offset));
-FORWARD void u4c4_ss P((char *buf, u4_t offset));
-FORWARD void u4c4_s0 P((char *buf, u4_t offset));
-FORWARD void u4c4_0s P((char *buf, u4_t offset));
-
-PRIVATE u2_pt (*pc2u2) P((char *buf)) = c2u2_00;
-PRIVATE u4_pt (*pc4u4) P((char *buf)) = c4u4_00;
-PRIVATE void (*pu2c2) P((char *buf, u2_pt offset)) = u2c2_00;
-PRIVATE void (*pu4c4) P((char *buf, u4_t offset)) = u4c4_00;
-
-/* === char arrays to unsigneds === */
-
-/* no bytes swapped, longwinded to avoid alignment problems */
-
-PRIVATE u2_pt c2u2_00(buf)
-register char *buf;
-{
- u2_t offset;
-
- ((char *) &offset)[0] = buf[0];
- ((char *) &offset)[1] = buf[1];
- return offset;
-}
-
-PRIVATE u4_pt c4u4_00(buf)
-register char *buf;
-{
- u4_t offset;
-
- ((char *) &offset)[0] = buf[0];
- ((char *) &offset)[1] = buf[1];
- ((char *) &offset)[2] = buf[2];
- ((char *) &offset)[3] = buf[3];
- return offset;
-}
-
-/* straight swapping for little-endian to big-endian and vice versa */
-
-PRIVATE u2_pt c2u2_ss(buf)
-register char *buf;
-{
- u2_t offset;
-
- ((char *) &offset)[0] = buf[1];
- ((char *) &offset)[1] = buf[0];
- return offset;
-}
-
-PRIVATE u4_pt c4u4_ss(buf)
-register char *buf;
-{
- u4_t offset;
-
- ((char *) &offset)[0] = buf[3];
- ((char *) &offset)[1] = buf[2];
- ((char *) &offset)[2] = buf[1];
- ((char *) &offset)[3] = buf[0];
- return offset;
-}
-
-/* wierd swapping for different-endian u2's, same-endian u4's */
-
-PRIVATE u4_pt c4u4_s0(buf)
-register char *buf;
-{
- u4_t offset;
-
- ((char *) &offset)[0] = buf[1];
- ((char *) &offset)[1] = buf[0];
- ((char *) &offset)[2] = buf[3];
- ((char *) &offset)[3] = buf[2];
- return offset;
-}
-
-/* very wierd swapping for same-endian u2's, different-endian u4's */
-
-PRIVATE u4_pt c4u4_0s(buf)
-register char *buf;
-{
- u4_t offset;
-
- ((char *) &offset)[0] = buf[2];
- ((char *) &offset)[1] = buf[3];
- ((char *) &offset)[2] = buf[0];
- ((char *) &offset)[3] = buf[1];
- return offset;
-}
-
-/* === entry points === */
-
-PUBLIC u2_pt c2u2(buf)
-char *buf;
-{
- return (*pc2u2) (buf);
-}
-
-PUBLIC u4_t c4u4(buf)
-char *buf;
-{
- return (*pc4u4) (buf);
-}
-
-PUBLIC u2_pt cnu2(buf, count)
-char *buf;
-unsigned count;
-{
- switch (count)
- {
- case 1:
- return buf[0] & 0xFF;
- case 2:
- return (*pc2u2) (buf);
- case 4:
- return (u2_pt) (*pc4u4) (buf);
- default:
- return 0;
- }
-}
-
-PUBLIC u4_t cnu4(buf, count)
-char *buf;
-unsigned count;
-{
- switch (count)
- {
- case 1:
- return buf[0] & 0xFF;
- case 2:
- return (*pc2u2) (buf);
- case 4:
- return (*pc4u4) (buf);
- default:
- return 0;
- }
-}
-
-/* === unsigneds to char arrays === */
-
-/* no bytes swapped, longwinded to avoid alignment problems */
-
-PRIVATE void u2c2_00(buf, offset)
-register char *buf;
-u2_pt offset;
-{
-
- buf[0] = ((char *) &offset)[0];
- buf[1] = ((char *) &offset)[1];
-}
-
-PRIVATE void u4c4_00(buf, offset)
-register char *buf;
-u4_t offset;
-{
- buf[0] = ((char *) &offset)[0];
- buf[1] = ((char *) &offset)[1];
- buf[2] = ((char *) &offset)[2];
- buf[3] = ((char *) &offset)[3];
-}
-
-/* straight swapping for little-endian to big-endian and vice versa */
-
-PRIVATE void u2c2_ss(buf, offset)
-register char *buf;
-u2_pt offset;
-{
- u2_t offset2;
-
- offset2 = offset;
- buf[0] = ((char *) &offset2)[1];
- buf[1] = ((char *) &offset2)[0];
-}
-
-PRIVATE void u4c4_ss(buf, offset)
-register char *buf;
-u4_t offset;
-{
- buf[0] = ((char *) &offset)[3];
- buf[1] = ((char *) &offset)[2];
- buf[2] = ((char *) &offset)[1];
- buf[3] = ((char *) &offset)[0];
-}
-
-/* wierd swapping for different-endian u2's, same-endian u4's */
-
-PRIVATE void u4c4_s0(buf, offset)
-register char *buf;
-u4_t offset;
-{
- buf[0] = ((char *) &offset)[1];
- buf[1] = ((char *) &offset)[0];
- buf[2] = ((char *) &offset)[3];
- buf[3] = ((char *) &offset)[2];
-}
-
-/* very wierd swapping for same-endian u2's, different-endian u4's */
-
-PRIVATE void u4c4_0s(buf, offset)
-register char *buf;
-u4_t offset;
-{
- buf[0] = ((char *) &offset)[2];
- buf[1] = ((char *) &offset)[3];
- buf[2] = ((char *) &offset)[0];
- buf[3] = ((char *) &offset)[1];
-}
-
-/* === entry points === */
-
-PUBLIC void u2c2(buf, offset)
-register char *buf;
-u2_pt offset;
-{
- (*pu2c2) (buf, offset);
-}
-
-PUBLIC void u4c4(buf, offset)
-register char *buf;
-u4_t offset;
-{
- (*pu4c4) (buf, offset);
-}
-
-PUBLIC void u2cn(buf, offset, count)
-register char *buf;
-u2_pt offset;
-unsigned count;
-{
- switch (count)
- {
- case 1:
- buf[0] = (char) offset;
- return;
- case 2:
- (*pu2c2) (buf, offset);
- return;
- case 4:
- (*pu4c4) (buf, (u4_t) offset);
- return;
- }
-}
-
-PUBLIC void u4cn(buf, offset, count)
-register char *buf;
-u4_t offset;
-unsigned count;
-{
- switch (count)
- {
- case 1:
- buf[0] = (char) offset;
- return;
- case 2:
- (*pu2c2) (buf, (u2_pt) (u2_t) offset);
- return;
- case 4:
- (*pu4c4) (buf, offset);
- return;
- }
-}
-
-/* initialise type conversion, return FALSE if it cannot be handled */
-
-PUBLIC bool_pt typeconv_init(big_endian, long_big_endian)
-bool_pt big_endian;
-bool_pt long_big_endian;
-{
- u2_pt conv2;
- u4_pt conv4;
- char *conv2ptr;
- char *conv4ptr;
-
- if (sizeof(u2_t) != 2 || sizeof(u4_t) != 4)
- /* dumb preprocessor's don't accept sizeof in #if expressions */
- return FALSE;
-
- if (big_endian)
- {
- conv2ptr = (conv4ptr = "\1\2\3\4") + 2;
- if (!long_big_endian)
- conv4ptr = "\3\4\1\2";
- }
- else
- {
- conv2ptr = conv4ptr = "\4\3\2\1";
- if (long_big_endian)
- conv4ptr = "\2\1\4\3";
- }
- conv2 = c2u2_00(conv2ptr);
- conv4 = c4u4_00(conv4ptr);
- if (conv2 == 0x0304)
- {
- pc2u2 = c2u2_00;
- pc4u4 = c4u4_00;
- pu2c2 = u2c2_00;
- pu4c4 = u4c4_00;
- if (conv4 == 0x03040102L)
- {
- pc4u4 = c4u4_0s;
- pu4c4 = u4c4_0s;
- }
- else if (conv4 != 0x01020304L)
- return FALSE;
- }
- else if (conv2 == 0x0403)
- {
- pc2u2 = c2u2_ss;
- pc4u4 = c4u4_ss;
- pu2c2 = u2c2_ss;
- pu4c4 = u4c4_ss;
- if (conv4 == 0x02010403L)
- {
- pc4u4 = c4u4_s0;
- pu4c4 = u4c4_s0;
- }
- else if (conv4 != 0x04030201L)
- return FALSE;
- }
- else
- return FALSE;
- return TRUE;
-}
-
-#ifdef DEBUG_TYPECONV
-
-main()
-{
- char *source;
- char target[4];
- u2_t u2;
- u2_t u2a;
- u4_t u4;
- u4_t u4a;
-
- printf("%u\n", typeconv_init(FALSE, FALSE));
- printf("%u\n", typeconv_init(FALSE, TRUE));
- printf("%u\n", typeconv_init(TRUE, FALSE));
- printf("%u\n", typeconv_init(TRUE, TRUE));
-
- typeconv_init(FALSE, FALSE);
- source = "\4\3\2\1";
-
- target[0] = 0;
- target[1] = 0;
- u2 = cnu2(source, 2);
- u2cn(target, u2, 2);
- if (strncmp(source, target, 2))
- printf("oops9\n");
-
- target[0] = 0;
- target[1] = 0;
- u4a = cnu4(source, 2);
- u4cn(target, u4a, 2);
- if (strncmp(source, target, 2))
- printf("oops10\n");
-
- target[0] = 0;
- target[1] = 0;
- target[2] = 0;
- target[3] = 0;
- u2a = cnu2(source, 4);
- u2cn(target, u2a, 4);
- if (strncmp(target, "\4\3\0\0", 4))
- printf("oops11\n");
-
- target[0] = 0;
- target[1] = 0;
- target[2] = 0;
- target[3] = 0;
- u4 = cnu4(source, 4);
- u4cn(target, u4, 4);
- if (strncmp(source, target, 4))
- printf("oops12\n");
-
- printf("%04x %04x %08lx %08lx\n", u2, u2a, u4, u4a);
-
- typeconv_init(FALSE, TRUE);
- source = "\2\1\4\3";
-
- target[0] = 0;
- target[1] = 0;
- u2 = cnu2(source + 2, 2);
- u2cn(target, u2, 2);
- if (strncmp(source + 2, target, 2))
- printf("oops13\n");
-
- target[0] = 0;
- target[1] = 0;
- u4a = cnu4(source + 2, 2);
- u4cn(target, u4a, 2);
- if (strncmp(source + 2, target, 2))
- printf("oops14\n");
-
- target[0] = 0;
- target[1] = 0;
- target[2] = 0;
- target[3] = 0;
- u2a = cnu2(source, 4);
- u2cn(target, u2a, 4);
- if (strncmp(target, "\0\0\4\3", 4))
- printf("oops15\n");
-
- target[0] = 0;
- target[1] = 0;
- target[2] = 0;
- target[3] = 0;
- u4 = cnu4(source, 4);
- u4cn(target, u4, 4);
- if (strncmp(source, target, 4))
- printf("oops16\n");
-
- printf("%04x %04x %08lx %08lx\n", u2, u2a, u4, u4a);
-
- typeconv_init(TRUE, FALSE);
- source = "\3\4\1\2";
-
- target[0] = 0;
- target[1] = 0;
- u2 = cnu2(source, 2);
- u2cn(target, u2, 2);
- if (strncmp(source, target, 2))
- printf("oops5\n");
-
- target[0] = 0;
- target[1] = 0;
- u4a = cnu4(source, 2);
- u4cn(target, u4a, 2);
- if (strncmp(source, target, 2))
- printf("oops6\n");
-
- target[0] = 0;
- target[1] = 0;
- target[2] = 0;
- target[3] = 0;
- u2a = cnu2(source, 4);
- u2cn(target, u2a, 4);
- if (strncmp(target, "\3\4\0\0", 4))
- printf("oops7\n");
-
- target[0] = 0;
- target[1] = 0;
- target[2] = 0;
- target[3] = 0;
- u4 = cnu4(source, 4);
- u4cn(target, u4, 4);
- if (strncmp(source, target, 4))
- printf("oops8\n");
-
- printf("%04x %04x %08lx %08lx\n", u2, u2a, u4, u4a);
-
- typeconv_init(TRUE, TRUE);
- source = "\1\2\3\4";
-
- target[0] = 0;
- target[1] = 0;
- u2 = cnu2(source + 2, 2);
- u2cn(target, u2, 2);
- if (strncmp(source + 2, target, 2))
- printf("oops1\n");
-
- target[0] = 0;
- target[1] = 0;
- u4a = cnu4(source + 2, 2);
- u4cn(target, u4a, 2);
- if (strncmp(source + 2, target, 2))
- printf("oops2\n");
-
- target[0] = 0;
- target[1] = 0;
- target[2] = 0;
- target[3] = 0;
- u2a = cnu2(source, 4);
- u2cn(target, u2a, 4);
- if (strncmp(target, "\0\0\3\4", 4))
- printf("oops3\n");
-
- target[0] = 0;
- target[1] = 0;
- target[2] = 0;
- target[3] = 0;
- u4 = cnu4(source, 4);
- u4cn(target, u4, 4);
- if (strncmp(source, target, 4))
- printf("oops4\n");
-
- printf("%04x %04x %08lx %08lx\n", u2, u2a, u4, u4a);
-}
-
-#endif /* DEBUG_TYPECONV */
diff --git a/ld/x86_aout.h b/ld/x86_aout.h
index 777f281..580e977 100644
--- a/ld/x86_aout.h
+++ b/ld/x86_aout.h
@@ -118,7 +118,7 @@ struct nlist { /* symbol table entry */
/* High bits of storage class. */
#define N_CLASS 0370 /* storage class mask */
-#define C_NULL
+#define C_NULL 0
#define C_EXT 0020 /* external symbol */
#define C_STAT 0030 /* static */