summaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorRobert de Bath <rdebath@poboxes.com>1997-02-25 20:42:19 +0100
committerLubomir Rintel <lkundrak@v3.sk>2013-10-23 23:38:07 +0200
commit4c36e9a0c125ccfff37aa440dab2cf58c4152fff (patch)
treea5d9c84ba2661029ddb2223dacd50529a361c3d5 /ld
parentf8de35da65c5d93bb733073cf40da154bc1c0748 (diff)
parent9696d7b0e1f3a1b0f5fd4a0428eb75afe8ad4ed6 (diff)
downloaddev86-4c36e9a0c125ccfff37aa440dab2cf58c4152fff.tar.gz
Import Dev86src-0.0.11.tar.gzv0.0.11
Diffstat (limited to 'ld')
-rw-r--r--ld/Makefile19
-rw-r--r--ld/bugs3
-rw-r--r--ld/globvar.h1
-rw-r--r--ld/io.c39
-rw-r--r--ld/ld.c19
-rw-r--r--ld/syshead.h18
-rw-r--r--ld/writebin.c7
-rw-r--r--ld/writex86.c12
-rw-r--r--ld/x86_aout.h2
9 files changed, 77 insertions, 43 deletions
diff --git a/ld/Makefile b/ld/Makefile
index 6351f10..da7b268 100644
--- a/ld/Makefile
+++ b/ld/Makefile
@@ -1,15 +1,11 @@
-ifneq ($(TOPDIR),)
-include $(TOPDIR)/Make.defs
-CFLAGS =$(CCFLAGS) -DREL_OUTPUT
-else
-LDFLAGS =-s
LIBDIR =/usr/bin
-CFLAGS =-O -DREL_OUTPUT
-endif
+CFLAGS =-O
+LDFLAGS =-s
# May need some of these if the auto-sense fails.
# -DV7_A_OUT -DBSD_A_OUT -DSTANDARD_GNU_A_OUT
+DEFS =-DREL_OUTPUT
OBJS= dumps.o io.o ld.o readobj.o table.o typeconv.o linksyms.o \
writex86.o writebin.o
@@ -23,8 +19,15 @@ install: ld86
install -d $(LIBDIR)
install -m 755 ld86 $(LIBDIR)
-clean:
+clean realclean:
rm -f $(OBJS) ld86
$(OBJS): align.h ar.h bindef.h byteord.h config.h const.h globvar.h obj.h \
syshead.h type.h x86_aout.h
+
+ar.h:
+ ln -s ../libc/include/ar.h . || \
+ ln ../libc/include/ar.h .
+
+.c.o:
+ $(CC) $(CFLAGS) $(DEFS) -c $< -o $@
diff --git a/ld/bugs b/ld/bugs
index b671f30..9444281 100644
--- a/ld/bugs
+++ b/ld/bugs
@@ -12,6 +12,3 @@ TODO:
TODO:
do malloc stuff better, as in compiler
-
-2. Error message about "foo.a is not an object file" is confusing - should
- name archive member.
diff --git a/ld/globvar.h b/ld/globvar.h
index d257d5c..4a66e89 100644
--- a/ld/globvar.h
+++ b/ld/globvar.h
@@ -16,3 +16,4 @@ extern int headerless; /* Don't output header on exe */
extern bin_off_t text_base_value; /* Base address of text seg */
extern bin_off_t data_base_value; /* Base or alignment of data seg */
+extern bin_off_t heap_top_value; /* Minimum 'total' value in x86 header */
diff --git a/ld/io.c b/ld/io.c
index 7b88222..39fc6a0 100644
--- a/ld/io.c
+++ b/ld/io.c
@@ -42,6 +42,10 @@ PRIVATE int trelfd; /* text relocation output file descriptor */
#endif
PRIVATE unsigned warncount; /* count of warnings */
+#ifdef MSDOS
+#define off_t long /* NOT a typedef */
+#endif
+
FORWARD void errexit P((char *message));
FORWARD void flushout P((void));
#ifdef REL_OUTPUT
@@ -117,14 +121,8 @@ int level;
PUBLIC void executable()
{
- mode_t oldmask;
-
if (errcount == 0)
- {
- oldmask = umask(0);
- umask(oldmask);
- chmod(outputname, outputperms | (EXEC_PERMS & ~oldmask));
- }
+ chmod(outputname, outputperms);
}
PUBLIC void flusherr()
@@ -164,7 +162,11 @@ char *filename;
{
closein();
inputname = filename; /* this relies on filename being static */
+#ifdef O_BINARY
if ((infd = open(filename, O_BINARY|O_RDONLY)) < 0)
+#else
+ if ((infd = open(filename, O_RDONLY)) < 0)
+#endif
inputerror("cannot open");
inbufptr = inbufend = inbuf;
}
@@ -173,21 +175,30 @@ char *filename;
PUBLIC void openout(filename)
char *filename;
{
- struct stat statbuf;
+ mode_t oldmask;
outputname = filename;
+#ifdef O_BINARY
if ((outfd = open(filename, O_BINARY|O_RDWR|O_CREAT|O_TRUNC, CREAT_PERMS)) == ERR)
+#else
+ if ((outfd = creat(filename, CREAT_PERMS)) == ERR)
+#endif
outputerror("cannot open");
- if (fstat(outfd, &statbuf) != 0)
- outputerror("cannot stat");
- outputperms = statbuf.st_mode;
+
+ oldmask = umask(0); umask(oldmask);
+ outputperms = ((CREAT_PERMS | EXEC_PERMS) & ~oldmask);
chmod(filename, outputperms & ~EXEC_PERMS);
+
#ifdef REL_OUTPUT
drelbufptr = drelbuf;
#endif
outbufptr = outbuf;
#ifdef REL_OUTPUT
- if ((trelfd = open(filename, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, CREAT_PERMS)) == ERR)
+#ifdef O_BINARY
+ if ((trelfd = open(filename, O_BINARY|O_WRONLY, CREAT_PERMS)) == ERR)
+#else
+ if ((trelfd = open(filename, O_WRONLY, CREAT_PERMS)) == ERR)
+#endif
outputerror("cannot reopen");
trelbufptr = trelbuf;
#endif
@@ -556,11 +567,11 @@ PUBLIC void usage()
#ifdef REL_OUTPUT
errexit("\
[-03NMdimrstz[-]] [-llib_extension] [-o outfile] [-Ccrtfile]\n\
- [-Llibdir] [-Olibfile] [-T textaddr] [-D dataaddr] infile...");
+ [-Llibdir] [-Olibfile] [-T textaddr] [-D dataaddr] [-H heapsize] infile...");
#else
errexit("\
[-03NMdimstz[-]] [-llib_extension] [-o outfile] [-Ccrtfile]\n\
- [-Llibdir] [-Olibfile] [-T textaddr] [-D dataaddr] infile...");
+ [-Llibdir] [-Olibfile] [-T textaddr] [-D dataaddr] [-H heapsize] infile...");
#endif
}
diff --git a/ld/ld.c b/ld/ld.c
index a98618e..1de55ce 100644
--- a/ld/ld.c
+++ b/ld/ld.c
@@ -17,6 +17,7 @@
PUBLIC bin_off_t text_base_value = 0; /* XXX */
PUBLIC bin_off_t data_base_value = 0; /* XXX */
+PUBLIC bin_off_t heap_top_value = 0; /* XXX */
PUBLIC int headerless = 0;
PUBLIC char hexdigit[] = "0123456789abcdef";
@@ -77,6 +78,7 @@ char **argv;
static char libsuffix[] = ".a";
char *outfilename;
char *tfn;
+ int icount=0;
ioinit(argv[0]);
objinit();
@@ -90,7 +92,10 @@ char **argv;
{
arg = argv[argn];
if (*arg != '-')
+ {
readsyms(arg, flag['t']);
+ icount++;
+ }
else
switch (arg[1])
{
@@ -132,6 +137,7 @@ char **argv;
infilename = tfn;
/*fatalerror(tfn); * XXX - need to describe failure */
readsyms(infilename, flag['t']);
+ icount++;
break;
case 'L': /* library path */
if (lastlib < MAX_LIBS)
@@ -167,12 +173,24 @@ char **argv;
if (errno != 0)
use_error("invalid data address");
break;
+ case 'H': /* heap top address */
+ if (arg[2] == 0 && ++argn >= argc)
+ usage();
+ errno = 0;
+ if (arg[2] == 0 )
+ heap_top_value = strtoul(argv[argn], (char **)0, 16);
+ else
+ heap_top_value = strtoul(arg+2, (char **)0, 16);
+ if (errno != 0)
+ use_error("invalid heap top");
+ break;
case 'l': /* library name */
tfn = buildname(libprefix, arg + 2, libsuffix);
if ((infilename = expandlib(tfn)) == NUL_PTR)
infilename = tfn;
/* fatalerror(tfn); * XXX */
readsyms(infilename, flag['t']);
+ icount++;
break;
case 'o': /* output file name */
if (arg[2] != 0 || ++argn >= argc || outfilename != NUL_PTR)
@@ -183,6 +201,7 @@ char **argv;
usage();
}
}
+ if(icount==0) fatalerror("no input files");
#ifdef REL_OUTPUT
#ifndef MSDOS
diff --git a/ld/syshead.h b/ld/syshead.h
index f5f32ea..7e110ab 100644
--- a/ld/syshead.h
+++ b/ld/syshead.h
@@ -6,15 +6,14 @@
#endif
#ifndef POSIX_HEADERS_MISSING
-#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <unistd.h>
#include <fcntl.h>
#endif
#ifdef MSDOS
#undef POSIX_HEADERS_MISSING
-
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -27,10 +26,6 @@
#define STDOUT_FILENO 0
#endif
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
/******************************************************************************/
/* EEEEyuk!! */
@@ -54,8 +49,6 @@ void *memset P((void *s, int c, unsigned n));
#endif
#ifdef POSIX_HEADERS_MISSING
-#include <sys/types.h>
-#include <sys/stat.h>
#define R_OK 0
int access P((const char *path, int amode));
@@ -76,3 +69,12 @@ mode_t umask P((int oldmask));
int write P((int fd, const void *buf, unsigned nbytes));
#endif
+#ifndef O_RDONLY
+#define O_RDONLY 0
+#endif
+#ifndef O_WRONLY
+#define O_WRONLY 1
+#endif
+#ifndef O_RDWR
+#define O_RDWR 2
+#endif
diff --git a/ld/writebin.c b/ld/writebin.c
index 60440f7..a001b5d 100644
--- a/ld/writebin.c
+++ b/ld/writebin.c
@@ -341,9 +341,9 @@ bool_pt arguzp;
if( headerless ) setsym("__segoff", (bin_off_t)(segadj[1]-segadj[0])/0x10);
if( !bits32 )
{
- if( etextoffset > 65535L )
+ if( etextoffset > 65536L )
fatalerror("text segment too large for 16bit");
- if( endoffset > 65535L )
+ if( endoffset > 65536L )
fatalerror("data segment too large for 16bit");
}
@@ -915,8 +915,7 @@ PRIVATE void writeheader()
if (!reloc_output)
#endif
{
- if (uzp)
- offtocn((char *) &header.a_entry, page_size(),
+ offtocn((char *) &header.a_entry, btextoffset,
sizeof header.a_entry);
#ifndef STANDARD_GNU_A_OUT
offtocn((char *) &header.a_total, (bin_off_t)
diff --git a/ld/writex86.c b/ld/writex86.c
index 2b0f00a..5dd3e8d 100644
--- a/ld/writex86.c
+++ b/ld/writex86.c
@@ -263,9 +263,9 @@ bool_pt arguzp;
if( headerless ) setsym("__segoff", (bin_off_t)(segadj[1]-segadj[0])/0x10);
if( !bits32 )
{
- if( etextoffset > 65535L )
+ if( etextoffset > 65536L )
fatalerror("text segment too large for 16bit");
- if( endoffset > 65535L )
+ if( endoffset > 65536L )
fatalerror("data segment too large for 16bit");
}
@@ -528,9 +528,11 @@ PRIVATE void writeheader()
if (uzp)
offtocn((char *) &header.a_entry, page_size(),
sizeof header.a_entry);
- offtocn((char *) &header.a_total, (bin_off_t)
- (endoffset < 0x00008000L ? endoffset+0x8000L :
- (endoffset < 0x00010000L ? 0x00010000L : endoffset + 0x0008000L)),
+ if( heap_top_value < 0x100 || endoffset > heap_top_value-0x100)
+ heap_top_value = endoffset + 0x8000;
+ if( heap_top_value > 0x10000 && !bits32 ) heap_top_value = 0x10000;
+
+ offtocn((char *) &header.a_total, (bin_off_t) heap_top_value,
sizeof header.a_total);
if( FILEHEADERLENGTH )
writeout((char *) &header, FILEHEADERLENGTH);
diff --git a/ld/x86_aout.h b/ld/x86_aout.h
index f6a7b94..bd58346 100644
--- a/ld/x86_aout.h
+++ b/ld/x86_aout.h
@@ -90,7 +90,7 @@ struct reloc {
#define S_BSS ((unsigned short)-4)
struct nlist { /* symbol table entry */
- char n_name[24]; /* symbol name */
+ char n_name[8]; /* symbol name */
long n_value; /* value */
unsigned char n_sclass; /* storage class */
unsigned char n_numaux; /* number of auxiliary entries (not used) */