diff -2rcN binutils-1.8.x/Makefile binutils-1.8.x-amiga/Makefile *** binutils-1.8.x/Makefile Wed Nov 27 22:48:58 1991 --- binutils-1.8.x-amiga/Makefile Mon Jul 18 23:46:58 1994 *************** *** 20,26 **** ! GNUCC = gcc -O ! #CC = gcc -O ! bindir=/usr/local/bin # for BSD systems --- 20,36 ---- ! GNUCC = gcc ! bindir=/gnu/bin ! ! # for AmigaDOS systems ! CFLAGS = -O2 ! LDFLAGS = -s ! # for AmigaDOS Cross-Compiler ! # CFLAGS = -O2 -DMCH_AMIGA -DCROSS_LINKER ! # Don't include gprof. ! PROGS = $(archpfx)ld $(archpfx)size \ ! $(archpfx)nm $(archpfx)strip $(archpfx)ar $(archpfx)ranlib ! CC = gcc ! bindir=/gnu/bin # for BSD systems *************** *** 30,35 **** # on most systems (trouble with N_DATADDR). I've fixed some of # those problems, though. ! PROGS = $(archpfx)gprof $(archpfx)ld $(archpfx)size \ ! $(archpfx)nm $(archpfx)strip $(archpfx)ar $(archpfx)ranlib # for USG systems using COFF_ENCAPSULATE --- 40,45 ---- # on most systems (trouble with N_DATADDR). I've fixed some of # those problems, though. ! #PROGS = $(archpfx)gprof $(archpfx)ld $(archpfx)size \ ! # $(archpfx)nm $(archpfx)strip $(archpfx)ar $(archpfx)ranlib # for USG systems using COFF_ENCAPSULATE *************** *** 37,43 **** # Note that you should leave a copy of `ar' in this directory # after you install it, since `ranlib' will try to run it from here. ! CFLAGS = -DWYSE -DUSG -DCOFF_ENCAPSULATE -DPORTAR -DNON_NATIVE -DPIGNAL_MISSING ! PROGS = ld size nm strip ar robotussin objdump ranlib gprof ! SIGNAME = signame.o # On ALTOS systems, add -DALTOS to CFLAGS. --- 47,53 ---- # Note that you should leave a copy of `ar' in this directory # after you install it, since `ranlib' will try to run it from here. ! #CFLAGS = -g -DUSG -DCOFF_ENCAPSULATE -DPORTAR -DNON_NATIVE -DPIGNAL_MISSING ! #PROGS = ld size nm strip ar robotussin objdump ranlib gprof ! #SIGNAME = signame.o # On ALTOS systems, add -DALTOS to CFLAGS. *************** *** 45,49 **** #incompatiable functions from -lPW (like index()), but if you #want to be lazy, uncomment this line ! ALLOCALIBS = -lPW # For HP-UX systems --- 55,59 ---- #incompatiable functions from -lPW (like index()), but if you #want to be lazy, uncomment this line ! #ALLOCALIBS = -lPW # For HP-UX systems *************** *** 84,88 **** CPLUS_DEM = $(archpfx)cplus-dem.o ! LIBS=$(MALLOC) $(ALLOCALIBS) $(SIGNAME) all: $(PROGS) --- 94,98 ---- CPLUS_DEM = $(archpfx)cplus-dem.o ! LIBS=$(ALLOCALIBS) $(SIGNAME) all: $(PROGS) *************** *** 91,111 **** # LIBS is used here since ld needs to use alloca. # Alternatively, compile it with GNU C--then the compiler handles alloca. ! $(CC) $(CFLAGS) -o $(archpfx)ld $(archpfx)ld.o $(GNU_GETOPT_LONG) $(CPLUS_DEM) $(LIBS) $(archpfx)size: $(archpfx)size.o ! $(CC) $(CFLAGS) -o $(archpfx)size $(archpfx)size.o $(archpfx)nm: $(archpfx)nm.o $(GNU_GETOPT_LONG) $(CPLUS_DEM) $(MALLOC) ! $(CC) $(CFLAGS) -o $(archpfx)nm $(archpfx)nm.o \ $(GNU_GETOPT_LONG) $(CPLUS_DEM) $(LIBS) $(MALLOC) $(archpfx)strip: $(archpfx)strip.o $(GNU_GETOPT_LONG) ! $(CC) $(CFLAGS) -o $(archpfx)strip $(archpfx)strip.o $(GNU_GETOPT_LONG) $(LIBS) $(archpfx)ar: $(archpfx)ar.o ! $(CC) $(CFLAGS) -o $(archpfx)ar $(archpfx)ar.o $(LIBS) $(archpfx)gprof: $(archpfx)gprof.o $(GNU_GETOPT_LONG) $(CPLUS_DEM) ! $(GNUCC) $(CFLAGS) -o $(archpfx)gprof $(archpfx)gprof.o \ $(GNU_GETOPT_LONG) $(CPLUS_DEM) $(LIBS) $(archpfx)gprof.o: gprof.c gmon.h --- 101,121 ---- # LIBS is used here since ld needs to use alloca. # Alternatively, compile it with GNU C--then the compiler handles alloca. ! $(CC) $(LDFLAGS) -o $(archpfx)ld $(archpfx)ld.o $(GNU_GETOPT_LONG) $(CPLUS_DEM) $(LIBS) $(archpfx)size: $(archpfx)size.o ! $(CC) $(LDFLAGS) -o $(archpfx)size $(archpfx)size.o $(archpfx)nm: $(archpfx)nm.o $(GNU_GETOPT_LONG) $(CPLUS_DEM) $(MALLOC) ! $(CC) $(LDFLAGS) -o $(archpfx)nm $(archpfx)nm.o \ $(GNU_GETOPT_LONG) $(CPLUS_DEM) $(LIBS) $(MALLOC) $(archpfx)strip: $(archpfx)strip.o $(GNU_GETOPT_LONG) ! $(CC) $(LDFLAGS) -o $(archpfx)strip $(archpfx)strip.o $(GNU_GETOPT_LONG) $(LIBS) $(archpfx)ar: $(archpfx)ar.o ! $(CC) $(LDFLAGS) -o $(archpfx)ar $(archpfx)ar.o $(LIBS) $(archpfx)gprof: $(archpfx)gprof.o $(GNU_GETOPT_LONG) $(CPLUS_DEM) ! $(GNUCC) $(LDFLAGS) -o $(archpfx)gprof $(archpfx)gprof.o \ $(GNU_GETOPT_LONG) $(CPLUS_DEM) $(LIBS) $(archpfx)gprof.o: gprof.c gmon.h *************** *** 113,127 **** $(archpfx)ranlib: $(archpfx)ranlib.o $(GNU_GETOPT_LONG) ! $(CC) $(CFLAGS) -o $(archpfx)ranlib $(archpfx)ranlib.o $(GNU_GETOPT_LONG) $(LIBS) $(archpfx)ranlib.o: ranlib.c ! $(CC) -c $(CFLAGS) -DAR_PROG=\"/usr/local/gnu/binutils/ar\" ranlib.c $(OUTPUT_OPTION) $(archpfx)objdump: $(archpfx)objdump.o $(GNU_GETOPT_LONG) a.out.gnu.h ! $(CC) $(CFLAGS) -o $(archpfx)objdump $(archpfx)objdump.o \ $(GNU_GETOPT_LONG) $(LIBS) # Robotussin is NOT part of `all'. $(archpfx)robotussin: $(archpfx)robotussin.o ! $(CC) $(CFLAGS) -o $(archpfx)robotussin $(archpfx)robotussin.o libc.a: $(archpfx)robotussin libconvert $(archpfx)ar --- 123,137 ---- $(archpfx)ranlib: $(archpfx)ranlib.o $(GNU_GETOPT_LONG) ! $(CC) $(LDFLAGS) -o $(archpfx)ranlib $(archpfx)ranlib.o $(GNU_GETOPT_LONG) $(LIBS) $(archpfx)ranlib.o: ranlib.c ! $(CC) -c $(CFLAGS) -DAR_PROG=\"$(bindir)/ar\" ranlib.c $(OUTPUT_OPTION) $(archpfx)objdump: $(archpfx)objdump.o $(GNU_GETOPT_LONG) a.out.gnu.h ! $(CC) $(LDFLAGS) -o $(archpfx)objdump $(archpfx)objdump.o \ $(GNU_GETOPT_LONG) $(LIBS) # Robotussin is NOT part of `all'. $(archpfx)robotussin: $(archpfx)robotussin.o ! $(CC) $(LDFLAGS) -o $(archpfx)robotussin $(archpfx)robotussin.o libc.a: $(archpfx)robotussin libconvert $(archpfx)ar *************** *** 146,150 **** install: $(PROGS) for file in $(PROGS); do \ ! cp $$file $(bindir)/$${file}.new; \ ! mv $(bindir)/$${file}.new $(bindir)/$$file; \ done --- 156,161 ---- install: $(PROGS) for file in $(PROGS); do \ ! cp $${file} $(bindir)/$${file}.new; \ ! mv $(bindir)/$${file} $(bindir)/$${file}.bak; \ ! mv $(bindir)/$${file}.new $(bindir)/$${file}; \ done diff -2rcN binutils-1.8.x/ar.c binutils-1.8.x-amiga/ar.c *** binutils-1.8.x/ar.c Wed Jun 13 05:47:50 1990 --- binutils-1.8.x-amiga/ar.c Wed Sep 22 12:45:59 1993 *************** *** 993,996 **** --- 993,997 ---- close (outdesc); + #ifndef amigados if (!appendflag) if (rename (tempname, archive)) *************** *** 998,1001 **** --- 999,1011 ---- close_archive (); + #else + /* we *have* to close the file before we rename it, because otherwise + * AmigaDOS will just abort with OBJECT_IN_USE_ERROR */ + close_archive (); + + if (!appendflag) + if (rename (tempname, archive)) + pfatal_with_name (tempname); + #endif } *************** *** 1957,1961 **** --- 1967,1973 ---- unsigned int size; { + #ifndef __STDC__ extern char *malloc (); + #endif char *result = malloc (size); if (result == 0) *************** *** 1969,1973 **** --- 1981,1987 ---- unsigned int size; { + #ifndef __STDC__ extern char *realloc (); + #endif char *result = realloc (ptr, size); if (result == 0) diff -2rcN binutils-1.8.x/cplus-dem.c binutils-1.8.x-amiga/cplus-dem.c *** binutils-1.8.x/cplus-dem.c Wed Jun 13 05:42:34 1990 --- binutils-1.8.x-amiga/cplus-dem.c Wed Sep 22 12:45:32 1993 *************** *** 49,53 **** #if !defined(sequent) && !defined(NeXT) ! #include #else #define memcpy(s1, s2, n) strncpy(s1, s2, n) --- 49,53 ---- #if !defined(sequent) && !defined(NeXT) ! /* #include */ #else #define memcpy(s1, s2, n) strncpy(s1, s2, n) diff -2rcN binutils-1.8.x/ld.c binutils-1.8.x-amiga/ld.c *** binutils-1.8.x/ld.c Sat Jun 18 00:10:10 1994 --- binutils-1.8.x-amiga/ld.c Sat Jul 30 13:26:33 1994 *************** *** 17,23 **** /* Written by Richard Stallman with some help from Eric Albert. ! Set, indirect, and warning symbol features added by Randy Smith. */ #include #include #include --- 17,38 ---- /* Written by Richard Stallman with some help from Eric Albert. ! Set, indirect, and warning symbol features added by Randy Smith. ! Support for generation of Amiga load files added by Markus Wild. ! Flavor extension by Fred Fish ! Modified for AmigaDOS cross-linker by Philippe Brand ! Bug fixes by Matthias Fleischer ! Additional work by Gunther Nikl */ + #ifdef amigados + #ifndef STANDARD_SEARCH_DIRS + #define STANDARD_SEARCH_DIRS "gnu:lib","gnu:os-lib" + #endif + #endif + + #if defined(amigados) && defined(CROSS_LINKER) + #include + #else #include + #endif #include #include *************** *** 31,34 **** --- 46,51 ---- #include #endif + /* JPB, 7 Jun 1992: MAXNAMLEN required for long name hack. */ + #include #if !defined(A_OUT) && !defined(MACH_O) *************** *** 40,46 **** --- 57,98 ---- #include "a.out.encap.h" #else + #if defined(amigados) && defined(CROSS_LINKER) + # include + #else #include #endif #endif + #endif + + #ifdef MCH_AMIGA + #define HUNK_INSTEAD_OF_A_OUT + int number_of_code_hunk, + code_mem_type, + number_of_data_hunk, + data_mem_type, + number_of_bss_hunk, + bss_mem_type, + number_of_debug_hunk, + current_hunk = 0, + offset_of_debug_hunk, + amiga_symbols_only, + long_data_hunk = 1, + databss_together = 0, + numdatadata_relocs = 0, + output_datadata_relocs = 0, + datadata_relocs_offset = 0; + #define LONGSIZE(l) ((((l) + 3) & ~3) >> 2) + /* this is the private format of the debug-hunk: */ + struct debug_hunk { + unsigned long id; /* Filesystem-imposed: HUNK_DEBUG (0x3f1) */ + unsigned long len; /* "" : length in longs -> LONGSIZE(real_lenght) */ + /* the following part is somehow a truncated exec-struct: */ + unsigned long magic; /* should be ZMAGIC (just for fun:-)), to be recognised + * by the other tools as this special frame */ + unsigned long syms; /* size of symbol-table */ + unsigned long strs; /* size of string table */ + /* here follows the actual data */ + } dh; + #endif #ifdef MACH_O *************** *** 105,109 **** char *progname; ! /* System dependencies */ --- 157,161 ---- char *progname; ! /* System dependencies */ *************** *** 191,194 **** --- 243,262 ---- #endif /* Sun. */ + #ifdef amigados + /* same trick as with sun[23] */ + /* Set the machine type according to the machine type of the .o files. + If they are all sun2 (68010), then the type of the executable is sun2. + If any is sun3 (68020), then the type of the executable is sun3. + This is consistent with the Sun loader and more useful than having + it depend on which machine you are on when you run ld. */ + static int amiga_machtype = MID_SUN010; + #define INITIALIZE_HEADER outheader.a_machtype = amiga_machtype + #define READ_HEADER_HOOK(machtype) \ + if (machtype == MID_SUN020) \ + { \ + amiga_machtype = MID_SUN020; \ + } + #endif + #ifdef ALTOS #define INITIALIZE_HEADER N_SET_MACHTYPE (outheader, M_68020) *************** *** 230,233 **** --- 298,305 ---- #define SEEK_CUR 1 #endif + /* Phil.B: 1-Apr-94: same trick for SEEK_END */ + #ifndef SEEK_END + #define SEEK_END L_XTND + #endif /* *************** *** 369,372 **** --- 441,445 ---- #undef RELOC_ADD_EXTRA #define RELOC_PCREL_P(r) ((r)->r_pcrel) + #define RELOC_BASEREL_P(r) ((r)->r_baserel) #define RELOC_VALUE_RIGHTSHIFT(r) 0 #define RELOC_TARGET_SIZE(r) ((r)->r_length) *************** *** 385,389 **** #endif ! /* Special global symbol types understood by GNU LD. */ --- 458,462 ---- #endif ! /* Special global symbol types understood by GNU LD. */ *************** *** 532,536 **** #endif /* not __GNU_STAB__ */ ! /* Symbol table */ --- 605,609 ---- #endif /* not __GNU_STAB__ */ ! /* Symbol table */ *************** *** 685,689 **** symbol *etext_symbol_alt; symbol *end_symbol_alt; ! /* Kinds of files potentially understood by the linker. */ --- 758,770 ---- symbol *etext_symbol_alt; symbol *end_symbol_alt; ! ! #ifdef amigados ! symbol *sdata_symbol; /* the symbol __sdata */ ! symbol *text_size_symbol; ! symbol *data_size_symbol; ! symbol *bss_size_symbol; ! symbol *datadata_reloc_symbol = 0; ! #endif ! /* Kinds of files potentially understood by the linker. */ *************** *** 821,825 **** /* Length of that vector. */ int number_of_files; ! /* When loading the text and data, we can avoid doing a close and another open between members of the same library. --- 902,906 ---- /* Length of that vector. */ int number_of_files; ! /* When loading the text and data, we can avoid doing a close and another open between members of the same library. *************** *** 868,874 **** --- 949,960 ---- #endif + #if 0 /* Descriptor for writing that file with `mywrite'. */ int outdesc; + #endif + + /* use outstream instead of outdesc thru the whole file, it's MUCH faster.. */ + FILE *outstream = (FILE *) 0; /* The following are computed by `digest_symbols'. */ *************** *** 910,913 **** --- 996,1003 ---- written. */ unsigned long *set_vectors; + #ifdef HUNK_INSTEAD_OF_A_OUT + /* which vector entry has to be relocated? */ + unsigned char *rel_vectors; + #endif /* Amount of cleared space to leave at the end of the text segment. */ *************** *** 930,934 **** int library_member_offset; }; ! /* Record most of the command options. */ --- 1020,1024 ---- int library_member_offset; }; ! /* Record most of the command options. */ *************** *** 994,997 **** --- 1084,1091 ---- int n_search_dirs; + /* Vector of flavors to search for. */ + char **flavors; + int n_flavors; + /* Non zero means to create the output executable. Cleared by nonfatal errors. */ *************** *** 1008,1017 **** --- 1102,1117 ---- int cl_refs_allocated; + /* JPB, 7 Jun 1992: Global variable needed for long name hack. */ + static int ar_hdr_size; + #ifndef bcopy void bcopy (), bzero (); #endif + #ifndef __STDC__ char *malloc (), *realloc (); void free (); + #endif + char *getenv (); char *xmalloc (); char *xrealloc (); *************** *** 1035,1038 **** --- 1135,1153 ---- void write_header (); void write_text (); + #ifdef HUNK_INSTEAD_OF_A_OUT + void write_datadata_relocs (); + void write_hunk_header (); + void conditionally_rewrite_headers (); + void write_bss (); + void init_reloc_hunk (); + void add_to_reloc_hunk (); + void write_reloc_hunk (); + void init_symbol_hunks (); + void add_to_symbol_hunk (); + void write_symbol_hunk (); + void look_for_symbols (); + void look_for_file_symbols (); + void relocate_set_vectors (); + #endif void read_file_relocation (); void write_data (); *************** *** 1046,1050 **** char *get_file_name (); symbol *getsym (), *getsym_soft (); ! int main (argc, argv) --- 1161,1166 ---- char *get_file_name (); symbol *getsym (), *getsym_soft (); ! int compare_longs (), compare_strings (); ! int main (argc, argv) *************** *** 1052,1059 **** int argc; { page_size = getpagesize (); progname = argv[0]; ! #ifdef RLIMIT_STACK /* Avoid dumping core on large .o files. */ { --- 1168,1186 ---- int argc; { + /* Phil.B 09-Jul-94: use 4KB as page size in order to be compatible with Gigamem + although getpagesize() is present in ixemul.library, we want to compile + without it */ + #ifdef amigados + page_size = 4096; + #else page_size = getpagesize (); + #endif progname = argv[0]; ! /* Phil.B 09-Jul-94: amigados doesn't have stack growing so this is not ! necessary and more than that disable ld to be compiled using libnix ! BTW as for now those functions returns 0 in ixemul.library. ! That's emulation! ;-) */ ! #if defined(RLIMIT_STACK) && !defined(amigados) /* Avoid dumping core on large .o files. */ { *************** *** 1091,1094 **** --- 1218,1224 ---- force_executable = 0; set_element_prefixes = 0; + #ifdef HUNK_INSTEAD_OF_A_OUT + amiga_symbols_only = 1; + #endif /* Initialize the cumulative counts of symbols. */ *************** *** 1149,1157 **** exit (!make_executable); } ! void add_cmdline_ref (); static struct option longopts[] = { {"d", 0, 0, 'd'}, {"dc", 0, 0, 'd'}, /* For Sun compatibility. */ --- 1279,1317 ---- exit (!make_executable); } ! ! #ifdef amigados ! /* support hunk loading to a chip or fast memory */ ! void set_mem_type(char *argstr, int memtype) ! { ! static char memstr[]="cdb"; ! ! if (!argstr) ! argstr=memstr; ! ! if (strchr(argstr,'c')||strchr(argstr,'t')) ! code_mem_type=memtype; ! ! if (strchr(argstr,'d')) ! data_mem_type=memtype; ! ! if (strchr(argstr,'b')) ! bss_mem_type=memtype; ! } ! #endif ! void add_cmdline_ref (); static struct option longopts[] = { + #ifdef HUNK_INSTEAD_OF_A_OUT + {"amiga-debug-hunk", 0, 0, 'a'}, + {"databss-together", 0, 0, 'b'}, + {"datadata-reloc", 0, 0, 'c'}, + {"msmall-code", 0, 0, 129}, /* ignore.. */ + {"flavor", 1, 0, 'f'}, + {"chip",2, 0, 'g'}, + {"fast",2, 0, 'h'}, + {"shortdata", 0, 0, 'm'}, + #endif {"d", 0, 0, 'd'}, {"dc", 0, 0, 'd'}, /* For Sun compatibility. */ *************** *** 1208,1211 **** --- 1368,1384 ---- Also process most options completely. */ + #ifdef amigados + /* Phil.B: 27-Feb-94 default is to strip all symbols if LDSTRIP is set */ + if (getenv("LDSTRIP")) + strip_symbols = STRIP_ALL; + + /* G.Nikl: 10-Jun-94 if LDSHORTDATA is found a "short" data hunk will be + created. bss will be allocated via the hunk header. default is to dump + the bss part in the data area as zeros */ + + if (getenv("LDSHORTDATA")) + long_data_hunk = 0; + #endif /* amigados */ + while ((optc = getopt_long_only (argc, argv, SHORTOPTS, longopts, &longind)) != EOF) *************** *** 1225,1228 **** --- 1398,1415 ---- break; + #ifdef HUNK_INSTEAD_OF_A_OUT + case 'a': + amiga_symbols_only = 0; + break; + + case 'b': + databss_together = 1; + break; + + case 'c': + output_datadata_relocs = 1; + break; + #endif + case 'd': force_common_definition = 1; *************** *** 1237,1244 **** --- 1424,1450 ---- break; + case 'f': + n_flavors++; + flavors = (char **) xrealloc (flavors, n_flavors * sizeof (char *)); + flavors[n_flavors - 1] = optarg; + break; + + #ifdef HUNK_INSTEAD_OF_A_OUT + case 'g': + set_mem_type(optarg,1<<30); + break; + + case 'h': + set_mem_type(optarg,2<<30); + break; + #endif case 'l': number_of_files++; break; + case 'm': + long_data_hunk = 0; + break; + case 'n': if (output_style && output_style != OUTPUT_READONLY_TEXT) *************** *** 1364,1367 **** --- 1570,1583 ---- } + if (n_flavors > 1) + { + register int i; + + if (trace_files) + for (i=0; ifilename); desc = open (string, O_RDONLY, 0); if (desc > 0) --- 1819,1835 ---- for (i = 0; i < n_search_dirs; i++) { ! register char *string; ! ! string = search_dirs[i]; ! if (n_flavors > 0) ! { ! int count; ! for (count = 0; count < n_flavors; count++) ! { ! string = concat (string, "/", flavors[count]); ! } ! } ! string = concat (string, "/", entry->filename); ! if (trace_files) fprintf (stderr, "Look for %s\n", string); desc = open (string, O_RDONLY, 0); if (desc > 0) *************** *** 1614,1617 **** --- 1841,1879 ---- free (string); } + /* Phil.B 30-Jul-94 if we couldn't find file using serch_dirs + then we try removing trailing path one by one */ + if ((desc <= 0) && (n_flavors > 0)) + { + if (trace_files) fprintf (stderr, "Climbing into flavors\n"); + for (i = 0; i < n_search_dirs; i++) + { + register int j; + register char *string; + + for (j = n_flavors; j >= 0; j--) + { + int count; + string = search_dirs[i]; + /* Phil.B 29-Jul-94 Special condition is made so that + if j = 0 we don't copy flavor because we want to test + search path without any flavor added. */ + for (count = 1; count <= j ; count++) + { + string = concat (string, "/", flavors[count-1]); + } + string = concat (string, "/", entry->filename); + if (trace_files) fprintf (stderr, "Look for %s\n", string); + desc = open (string, O_RDONLY, 0); + if (desc > 0) + { + entry->filename = string; + entry->search_dirs_flag = 0; + break; + } + free (string); + } + if (desc > 0) break; + } + } } else *************** *** 1679,1683 **** return result; } ! /* Medium-level input routines for rel files. */ --- 1941,1945 ---- return result; } ! /* Medium-level input routines for rel files. */ *************** *** 2045,2049 **** fatal_with_file ("premature end of file in strings of ", entry); } ! /* Read in the symbols of all input files. */ --- 2307,2311 ---- fatal_with_file ("premature end of file in strings of ", entry); } ! /* Read in the symbols of all input files. */ *************** *** 2098,2102 **** file_close (); } ! /* Enter the external symbol defs and refs of ENTRY in the hash table. */ --- 2360,2364 ---- file_close (); } ! /* Enter the external symbol defs and refs of ENTRY in the hash table. */ *************** *** 2121,2124 **** --- 2383,2396 ---- { set_symbol_count++; + + /* Matthias Fleischer 25-Apr-94: fix bug in ld that prevents + symboltables for objects in the data hunk from working. */ + #ifdef HUNK_INSTEAD_OF_A_OUT + /* Count pointers in the symbol table, too */ + if ((p->n_type&~N_EXT)==N_SETD|| + (p->n_type&~N_EXT)==N_SETB) + numdatadata_relocs++; + #endif + if (output_style != OUTPUT_RELOCATABLE) enter_global_ref (p, p->n_un.n_strx + entry->strings, entry); *************** *** 2376,2380 **** } ! /* Searching libraries */ --- 2648,2652 ---- } ! /* Searching libraries */ *************** *** 2453,2458 **** --- 2725,2755 ---- namelen++); + /* JPB, 7 Jun 1992: Support for long file names. Set the global variable + ar_hdr_size to the real length of the header. + The code for extracting the long name is pretty much stolen + from the BSD ar (archive.c, version 5.7). + This is a *really* ugly hack! + */ + #if 1 + ar_hdr_size = sizeof(struct ar_hdr); + if (!bcmp(hdr1.ar_name,AR_EFMT1,sizeof(AR_EFMT1) -1)) + { + namelen = atoi(hdr1.ar_name + sizeof(AR_EFMT1) -1); + if (namelen <= 0 || namelen > MAXNAMLEN) + fatal_with_file("malformatted long name of archive member in ",library_entry); + ar_hdr_size += namelen; + name = (char *) xmalloc (namelen+1); + if (read(desc,name,namelen) != namelen) + fatal_with_file("malformatted long name of archive member in ",library_entry); + } + else + { + name = (char *) xmalloc (namelen+1); + strncpy (name, hdr1.ar_name, namelen); + } + #else name = (char *) xmalloc (namelen+1); strncpy (name, hdr1.ar_name, namelen); + #endif name[namelen] = 0; *************** *** 2462,2466 **** --- 2759,2767 ---- subentry->strings = 0; subentry->subfiles = 0; + #if 1 + subentry->starting_offset = subfile_offset + ar_hdr_size; + #else subentry->starting_offset = subfile_offset + sizeof hdr1; + #endif subentry->superfile = library_entry; subentry->library_flag = 0; *************** *** 2474,2478 **** return subentry; } ! int subfile_wanted_p (); --- 2775,2779 ---- return subentry; } ! int subfile_wanted_p (); *************** *** 2623,2627 **** free (symdef_data); } ! /* Handle a subentry for a file with no __.SYMDEF. */ --- 2924,2928 ---- free (symdef_data); } ! /* Handle a subentry for a file with no __.SYMDEF. */ *************** *** 2676,2684 **** process_subentry (desc, subentry, entry, &prev); this_subfile_offset += member_length + sizeof (struct ar_hdr); if (this_subfile_offset & 1) this_subfile_offset++; } } ! /* ENTRY is an entry for a library member. Its symbols have been read into core, but not entered. --- 2977,2993 ---- process_subentry (desc, subentry, entry, &prev); + #if 1 + /* JPB, 7 Jun 1992: Can't count on sizeof(ar_hdr) to be the size of the entire + header: Long names extends the header. This is a *really* + ugly hack, using a global variable! */ + + this_subfile_offset += member_length + ar_hdr_size; + #else this_subfile_offset += member_length + sizeof (struct ar_hdr); + #endif if (this_subfile_offset & 1) this_subfile_offset++; } } ! /* ENTRY is an entry for a library member. Its symbols have been read into core, but not entered. *************** *** 2778,2782 **** return 0; } ! void consider_file_section_lengths (), relocate_file_addresses (); --- 3087,3091 ---- return 0; } ! void consider_file_section_lengths (), relocate_file_addresses (); *************** *** 2801,2805 **** --- 3110,3118 ---- initialize_text_start (); + #ifdef HUNK_INSTEAD_OF_A_OUT + text_size = 0; + #else text_size = text_header_size; + #endif /* Compute total size of sections */ *************** *** 2810,2813 **** --- 3123,3127 ---- Include the padding in the text segment size. */ + #ifndef HUNK_INSTEAD_OF_A_OUT if (output_style == OUTPUT_READONLY_TEXT || output_style == OUTPUT_DEMAND_PAGED) { *************** *** 2815,2818 **** --- 3129,3145 ---- text_size += text_pad; } + #endif + + #ifdef HUNK_INSTEAD_OF_A_OUT + /* they go into text if they are required */ + if (output_datadata_relocs && numdatadata_relocs) + { + if (datadata_reloc_symbol) + datadata_reloc_symbol->value = text_size; + + /* 1 long for the size, then the vector */ + text_size += (1 + numdatadata_relocs) * 4; + } + #endif /* Now that the text_size is known, initialize the data start address; *************** *** 2821,2824 **** --- 3148,3157 ---- initialize_data_start (); + #ifdef HUNK_INSTEAD_OF_A_OUT + data_pad = 0; + #endif + + + #ifndef HUNK_INSTEAD_OF_A_OUT /* Make sure bss starts out aligned as much as anyone can want. */ { *************** *** 2828,2831 **** --- 3161,3165 ---- data_size = new_data_size; } + #endif /* Set up the set element vector */ *************** *** 2837,2845 **** --- 3171,3189 ---- vector, plus a word for each symbol for a zero at the end of the vector (for incremental linking). */ + #if 0 + /* I think this is the other way round !? ### mw */ + set_sect_size = (2 * set_symbol_count + set_vector_count) * sizeof (unsigned long); + #else + set_sect_size + = (2 * set_vector_count + set_symbol_count) * sizeof (unsigned long); + #endif set_sect_start = data_start + data_size; data_size += set_sect_size; set_vectors = (unsigned long *) xmalloc (set_sect_size); + #ifdef HUNK_INSTEAD_OF_A_OUT + rel_vectors = (unsigned char *) xmalloc (set_sect_size/sizeof(unsigned long)); + #endif setv_fill_count = 0; } *************** *** 2889,2893 **** --- 3233,3253 ---- multiple_def_count++; } + + #ifdef HUNK_INSTEAD_OF_A_OUT + /* don't relocate absolute symbols in sets */ + rel_vectors[setv_fill_count] = ( ((type & ~N_EXT) != N_SETA) ); + + /* Matthias Fleischer 25-Apr-94: fix bug in ld that prevents + symboltables for objects in the data hunk from working. */ + + /* This is some kind of hack, but doing this cleaner would be + much more complicated */ + set_vectors[setv_fill_count++] = p->n_value + +( (type & ~N_EXT) == N_SETD ? text_size : 0 ) + +( (type & ~N_EXT) == N_SETB ? data_size : 0 ); + #else set_vectors[setv_fill_count++] = p->n_value; + #endif + } else if ((type & N_EXT) && type != (N_UNDF | N_EXT)) *************** *** 2932,2936 **** --- 3292,3302 ---- - data_size - data_start); + #ifdef HUNK_INSTEAD_OF_A_OUT + sp->value = bss_size; + if (databss_together) + sp->value += data_start + data_size; + #else sp->value = data_start + data_size + bss_size; + #endif sp->defined = N_BSS | N_EXT; bss_size += com; *************** *** 2952,2955 **** --- 3318,3322 ---- = (sp->value - set_sect_start) / sizeof (unsigned long); unsigned long i, tmp; + unsigned char tmp2; set_vectors[length_word_index] *************** *** 2965,2968 **** --- 3332,3342 ---- = set_vectors[setv_fill_count - i]; set_vectors[setv_fill_count - i] = tmp; + #ifdef HUNK_INSTEAD_OF_A_OUT + /* reverse relocation vector too! */ + tmp2 = rel_vectors[length_word_index + i]; + rel_vectors[length_word_index + i] + = rel_vectors[setv_fill_count - i]; + rel_vectors[setv_fill_count - i] = tmp2; + #endif } *************** *** 2995,2998 **** --- 3369,3385 ---- } + #ifdef amigados + { + if (sdata_symbol) + sdata_symbol->value = data_start; + if (text_size_symbol) + text_size_symbol->value = text_size; + if (data_size_symbol) + data_size_symbol->value = data_size; + if (bss_size_symbol) + bss_size_symbol->value = bss_size; + } + #endif + { int edata_value = data_start + data_size; *************** *** 3014,3020 **** --- 3401,3409 ---- data_pad_additional = specified_data_size - data_size; + #ifndef HUNK_INSTEAD_OF_A_OUT if (output_style == OUTPUT_DEMAND_PAGED) data_pad_additional = ((data_pad_additional + data_size + page_size - 1) & (- page_size)) - data_size; + #endif bss_size -= data_pad_additional; *************** *** 3025,3030 **** data_pad += data_pad_additional; } } ! /* Accumulate the section sizes of input file ENTRY into the section sizes of the output file. */ --- 3414,3451 ---- data_pad += data_pad_additional; } + + #ifdef HUNK_INSTEAD_OF_A_OUT + /* if there is some code, assign it next hunk_number */ + if (text_size) + number_of_code_hunk = current_hunk++; + else + number_of_code_hunk = -1; + + if (data_size) + number_of_data_hunk = current_hunk++; + else + number_of_data_hunk = -1; + + if (bss_size) + number_of_bss_hunk = current_hunk++; + else + number_of_bss_hunk = -1; + + if (databss_together) + { + if (data_size && bss_size) + { + current_hunk --; + number_of_bss_hunk = number_of_data_hunk; + } + } + + if (strip_symbols != STRIP_ALL && !amiga_symbols_only) + number_of_debug_hunk = current_hunk++; + else + number_of_debug_hunk = -1; + #endif } ! /* Accumulate the section sizes of input file ENTRY into the section sizes of the output file. */ *************** *** 3047,3050 **** --- 3468,3495 ---- text_reloc_size += entry->text_reloc_size; data_reloc_size += entry->data_reloc_size; + + #ifdef HUNK_INSTEAD_OF_A_OUT + if (! output_datadata_relocs) + return; + + /* have to guess at how many datadata-relocs we might have. This number + is larger than the real thing, because I have to include the references + to UNDF symbols as well. */ + { + struct relocation_info *r, *re, *reloc; + int desc = file_open (entry); + + reloc = (struct relocation_info *) alloca (entry->data_reloc_size); + lseek (desc, entry->starting_offset + entry->data_reloc_offset, L_SET); + if (entry->data_reloc_size != read (desc, reloc, entry->data_reloc_size)) + fatal_with_file ("premature eof in data relocation of ", entry); + + for (r = reloc, re = reloc + entry->data_reloc_size/sizeof(*re); r < re; r++) + if (RELOC_EXTERN_P (r) || ((RELOC_TYPE (r) & N_TYPE) != N_TEXT)) + numdatadata_relocs ++; + + file_close (); + } + #endif } *************** *** 3063,3067 **** been, we would get the wrong results here. */ entry->data_start_address += data_start; ! entry->bss_start_address += data_start + data_size; { --- 3508,3517 ---- been, we would get the wrong results here. */ entry->data_start_address += data_start; ! ! #ifdef HUNK_INSTEAD_OF_A_OUT ! if (databss_together) ! #endif ! entry->bss_start_address += data_start + data_size; ! { *************** *** 3081,3086 **** p->n_value += entry->text_start_address - entry->orig_text_address; break; - case N_DATA: case N_SETV: case N_SETD: /* Data segment symbol. Subtract the address of the --- 3531,3536 ---- p->n_value += entry->text_start_address - entry->orig_text_address; break; case N_SETV: + case N_DATA: case N_SETD: /* Data segment symbol. Subtract the address of the *************** *** 3099,3103 **** } } ! void describe_file_sections (), list_file_locals (); --- 3549,3553 ---- } } ! void describe_file_sections (), list_file_locals (); *************** *** 3175,3179 **** } ! /* Static vars for do_warnings and subroutines of it */ int list_unresolved_refs; /* List unresolved refs */ --- 3625,3629 ---- } ! /* Static vars for do_warnings and subroutines of it */ int list_unresolved_refs; /* List unresolved refs */ *************** *** 3193,3197 **** }; - void qsort (); /* * Helper routines for do_file_warnings. --- 3643,3646 ---- *************** *** 3673,3677 **** entry->strings = 0; /* Since it will dissapear anyway. */ } ! do_warnings (outfile) FILE *outfile; --- 4122,4126 ---- entry->strings = 0; /* Since it will dissapear anyway. */ } ! do_warnings (outfile) FILE *outfile; *************** *** 3692,3696 **** make_executable = 0; } ! #ifdef A_OUT --- 4141,4145 ---- make_executable = 0; } ! #ifdef A_OUT *************** *** 3713,3716 **** --- 4162,4170 ---- int magic; + #ifdef HUNK_INSTEAD_OF_A_OUT + text_start = 0; + return; + #endif + switch (output_style) { *************** *** 3771,3774 **** --- 4225,4233 ---- initialize_a_out_data_start () { + #ifdef HUNK_INSTEAD_OF_A_OUT + data_start = 0; + return; + #endif + outheader.a_text = text_size; #ifdef sequent *************** *** 3924,3935 **** write_a_out_header () { ! lseek (outdesc, 0L, 0); #ifdef COFF_ENCAPSULATE if (need_coff_header) ! mywrite (&coffheader, sizeof coffheader, 1, outdesc); #endif ! mywrite (&outheader, sizeof (struct exec), 1, outdesc); /* Output whatever padding is required in the executable file --- 4383,4394 ---- write_a_out_header () { ! fseek (outstream, 0L, 0); #ifdef COFF_ENCAPSULATE if (need_coff_header) ! mywrite (&coffheader, sizeof coffheader, 1, outstream); #endif ! mywrite (&outheader, sizeof (struct exec), 1, outstream); /* Output whatever padding is required in the executable file *************** *** 3937,3946 **** #ifndef COFF_ENCAPSULATE ! padfile (N_TXTOFF (outheader) - sizeof outheader, outdesc); #endif } #endif ! #ifdef MACH_O --- 4396,4405 ---- #ifndef COFF_ENCAPSULATE ! padfile (N_TXTOFF (outheader) - sizeof outheader, outstream); #endif } #endif ! #ifdef MACH_O *************** *** 4146,4150 **** thread_state state; ! lseek (outdesc, 0L, 0); --- 4605,4609 ---- thread_state state; ! fseek (outstream, 0L, 0); *************** *** 4252,4256 **** m_object.symseg = symseg; #endif ! mywrite((char *) &m_object, 1, sizeof m_object, outdesc); break; --- 4711,4715 ---- m_object.symseg = symseg; #endif ! mywrite((char *) &m_object, 1, sizeof m_object, outstream); break; *************** *** 4306,4310 **** m_exec.symseg = symseg; #endif ! mywrite((char *) &m_exec, 1, sizeof m_exec, outdesc); break; } --- 4765,4769 ---- m_exec.symseg = symseg; #endif ! mywrite((char *) &m_exec, 1, sizeof m_exec, outstream); break; } *************** *** 4387,4391 **** #endif ! /* The following functions are simple switches according to the output style. */ --- 4846,4850 ---- #endif ! /* The following functions are simple switches according to the output style. */ *************** *** 4485,4488 **** --- 4944,4951 ---- write_header () { + #ifdef HUNK_INSTEAD_OF_A_OUT + conditionally_rewrite_headers (); + return; + #else #ifdef A_OUT if (output_file_type == IS_A_OUT) *************** *** 4499,4505 **** } #endif fatal ("unknown output file type (enum file_type)", (char *) 0); } ! /* Write the output file */ --- 4962,4969 ---- } #endif + #endif fatal ("unknown output file type (enum file_type)", (char *) 0); } ! /* Write the output file */ *************** *** 4520,4539 **** (void) unlink (output_filename); ! outdesc = open (output_filename, O_WRONLY | O_CREAT | O_TRUNC, 0666); ! if (outdesc < 0) perror_name (output_filename); ! if (fstat (outdesc, &statbuf) < 0) perror_name (output_filename); filemode = statbuf.st_mode; chmod (output_filename, filemode & ~0111); /* Calculate the offsets of the various pieces of the output file. */ compute_section_offsets (); /* Output the text and data segments, relocating as we go. */ write_text (); write_data (); /* Output the merged relocation info, if requested with `-r'. */ --- 4984,5049 ---- (void) unlink (output_filename); ! outstream = fopen (output_filename, "w"); ! if (outstream == 0) perror_name (output_filename); ! #ifndef MCH_AMIGA ! if (fstat (fileno (outstream), &statbuf) < 0) perror_name (output_filename); filemode = statbuf.st_mode; + /* this wouldn't work anyway, "file in use, error"... */ chmod (output_filename, filemode & ~0111); + #endif + + /* on the Amiga, the following call DOES set the symbol offset, but + * it does it wrong, we'll be able to do it right, as soon as all the + * other data has been written.. */ /* Calculate the offsets of the various pieces of the output file. */ compute_section_offsets (); + #ifdef HUNK_INSTEAD_OF_A_OUT + /* get ready to collect information where all symbols + * go. Since this has to be done only once, we'll later be able to + * output the right symbol-hunk after the right (code/data/bss-)hunk. */ + init_symbol_hunks (); + look_for_symbols (); + #endif + /* Output the text and data segments, relocating as we go. */ write_text (); write_data (); + #ifdef HUNK_INSTEAD_OF_A_OUT + if (datadata_relocs_offset) + write_datadata_relocs (); + + write_bss (); + if (number_of_debug_hunk != -1) + { + /* ok, lets output the start of the debug hunk */ + fseek (outstream, 0L, SEEK_END); + offset_of_debug_hunk = ftell (outstream); + + dh.id = 0x3f1; /* HUNK_DEBUG */ + dh.len = 0; /* we'll fill this in later */ + dh.magic = ZMAGIC; /* when wishes came true... */ + dh.syms = outheader.a_syms; + mywrite(&dh, sizeof dh, 1, outstream); + + output_syms_offset = ftell (outstream); + output_strs_offset = output_syms_offset + dh.syms; + + /* since we later will seek forward and backward to fill in each files + * symbol- and string-table, we have to create the needed space, that + * will be seeked over, since on an empty file, lseek(fd, 10, 0) will + * position to byte 10 on Unix, but will just generate an error under + * AmigaDOS and stay at position 0. */ + + /* this will just write garbage, but thats enough:-)) */ + mywrite(&output_strs_offset, dh.syms+4, 1, outstream); + fseek (outstream, output_syms_offset, 0); + } + #endif /* Output the merged relocation info, if requested with `-r'. */ *************** *** 4548,4559 **** compute_more_section_offsets (); /* Copy any GDB symbol segments from input files. */ write_symsegs (); /* Now that everything is known about the output file, write its header. */ write_header (); ! close (outdesc); mask = umask (0); umask (mask); --- 5058,5077 ---- compute_more_section_offsets (); + #ifndef HUNK_INSTEAD_OF_A_OUT + /* I don't support GDB-symbol segments, they aren't used anymore by + * the newer versions of gdb, BUT of course, if somebody needs them.. + * that's exactly why I introduced the "dh.strs" Parameter, so that + * you could - as in Unix - append these segments at the end of the file */ + /* Copy any GDB symbol segments from input files. */ write_symsegs (); + #endif /* Now that everything is known about the output file, write its header. */ write_header (); ! fclose (outstream); + #ifndef HUNK_INSTEAD_OF_A_OUT mask = umask (0); umask (mask); *************** *** 4561,4567 **** if (chmod (output_filename, filemode | (0111 & ~mask)) == -1) perror_name (output_filename); } ! void modify_location (), perform_relocation (), copy_text (), copy_data (); /* Relocate the text segment of each input file --- 5079,5089 ---- if (chmod (output_filename, filemode | (0111 & ~mask)) == -1) perror_name (output_filename); + #endif } ! void modify_location (), perform_relocation (), copy_text (), copy_data (); + #ifdef HUNK_INSTEAD_OF_A_OUT + void write_hunk_header(); + #endif /* Relocate the text segment of each input file *************** *** 4574,4580 **** fprintf (stderr, "Copying and relocating text:\n\n"); ! lseek (outdesc, output_text_offset + text_header_size, 0); each_full_file (copy_text, 0); file_close (); --- 5096,5133 ---- fprintf (stderr, "Copying and relocating text:\n\n"); ! #ifdef HUNK_INSTEAD_OF_A_OUT ! /* this is a definitive write, we don't need to rewrite this out, since ! * the yet undefined sizes of the reloc-hunks don't go into the ! * header-hunk */ ! write_hunk_header(outstream); ! init_reloc_hunk(); ! ! /* and if there's no code-hunk, we can return here.. no sense in ! * complicately doing just nothing... */ ! if (number_of_code_hunk == -1) return; ! ! /* else start the code-hunk */ ! { ! long code_header[2]; ! code_header[0] = 0x3e9; ! code_header[1] = LONGSIZE(text_size); ! mywrite(code_header, 1, sizeof code_header, outstream); ! } ! #else ! fseek (outstream, output_text_offset + text_header_size, 0); ! #endif each_full_file (copy_text, 0); + #ifdef HUNK_INSTEAD_OF_A_OUT + if (output_datadata_relocs && numdatadata_relocs) + { + int i, zero = 0; + /* include the size-field, -> <= . The `real' values come later */ + datadata_relocs_offset = ftell (outstream); + for (i = 0; i <= numdatadata_relocs; i ++) + mywrite (&zero, 1, sizeof (long), outstream); + } + #endif + file_close (); *************** *** 4582,4586 **** fprintf (stderr, "\n"); ! padfile (text_pad, outdesc); } --- 5135,5148 ---- fprintf (stderr, "\n"); ! padfile (text_pad, outstream); ! ! #ifdef HUNK_INSTEAD_OF_A_OUT ! write_reloc_hunk(); ! write_symbol_hunk(number_of_code_hunk); ! { ! long hunk_end = 0x3f2; ! mywrite(&hunk_end, 1, sizeof(long), outstream); ! } ! #endif } *************** *** 4687,4691 **** /* Relocate the text according to the text relocation. */ - perform_relocation (bytes, entry->text_start_address - entry->orig_text_address, entry->text_size, reloc, entry->text_reloc_size, entry); --- 5249,5252 ---- *************** *** 4693,4699 **** /* Write the relocated text to the output file. */ ! mywrite (bytes, 1, entry->text_size, outdesc); } ! /* Relocate the data segment of each input file and write to the output file. */ --- 5254,5260 ---- /* Write the relocated text to the output file. */ ! mywrite (bytes, 1, entry->text_size, outstream); } ! /* Relocate the data segment of each input file and write to the output file. */ *************** *** 4705,4709 **** fprintf (stderr, "Copying and relocating data:\n\n"); ! lseek (outdesc, output_data_offset, 0); each_full_file (copy_data, 0); --- 5266,5290 ---- fprintf (stderr, "Copying and relocating data:\n\n"); ! #ifndef HUNK_INSTEAD_OF_A_OUT ! fseek (outstream, output_data_offset, 0); ! #else ! /* just have to hope that the file is positioned correctly.. */ ! init_reloc_hunk(); ! /* start a data-hunk, if there is data to be output */ ! if (number_of_data_hunk == -1) return; ! ! { ! long data_header[2]; ! int size; ! data_header[0] = 0x3ea; ! size = LONGSIZE(data_size); ! /* create long data hunk? */ ! if (long_data_hunk && databss_together) ! size=LONGSIZE(data_size+bss_size); ! data_header[1] = size; ! ! mywrite(data_header, 1, sizeof data_header, outstream); ! } ! #endif each_full_file (copy_data, 0); *************** *** 4714,4724 **** if (set_vector_count) ! mywrite (set_vectors, 2 * set_symbol_count + set_vector_count, ! sizeof (unsigned long), outdesc); if (trace_files) fprintf (stderr, "\n"); ! padfile (data_pad, outdesc); } --- 5295,5337 ---- if (set_vector_count) ! { ! #ifdef HUNK_INSTEAD_OF_A_OUT ! /* this and mywrite later: inverted set_symbol_count and ! * set_vector_count, guess they were mixed up before ### mw */ ! ! relocate_set_vectors (set_vectors, rel_vectors, ! 2 * set_vector_count + set_symbol_count); ! #endif ! #if 0 ! mywrite (set_vectors, 2 * set_symbol_count + set_vector_count, ! sizeof (unsigned long), outstream); ! #else ! mywrite (set_vectors, 2 * set_vector_count + set_symbol_count, ! sizeof (unsigned long), outstream); ! #endif ! } if (trace_files) fprintf (stderr, "\n"); ! padfile (data_pad, outstream); ! ! #ifdef HUNK_INSTEAD_OF_A_OUT ! ! if (long_data_hunk && databss_together && bss_size) ! { ! /* dump zeros */ ! int i, zero = 0; ! for (i = 0; i < LONGSIZE(bss_size); i++) ! mywrite (&zero, 1, sizeof (long), outstream); ! } ! ! write_reloc_hunk(); ! write_symbol_hunk(number_of_data_hunk); ! { ! long hunk_end = 0x3f2; ! mywrite(&hunk_end, 1, sizeof(long), outstream); ! } ! #endif } *************** *** 4766,4775 **** fatal_with_file ("premature eof in data section of ", entry); ! perform_relocation (bytes, entry->data_start_address - entry->orig_data_address, ! entry->data_size, reloc, entry->data_reloc_size, entry); ! mywrite (bytes, 1, entry->data_size, outdesc); } ! /* Relocate ENTRY's text or data section contents. DATA is the address of the contents, in core. --- 5379,5392 ---- fatal_with_file ("premature eof in data section of ", entry); ! perform_relocation (bytes, entry->data_start_address ! #ifndef HUNK_INSTEAD_OF_A_OUT ! - entry->orig_data_address ! #endif ! , ! entry->data_size, reloc, entry->data_reloc_size, entry); ! mywrite (bytes, 1, entry->data_size, outstream); } ! /* Relocate ENTRY's text or data section contents. DATA is the address of the contents, in core. *************** *** 4797,4800 **** --- 5414,5421 ---- int bss_relocation = entry->bss_start_address - entry->orig_bss_address; + #ifdef HUNK_INSTEAD_OF_A_OUT + int this_hunk; + #endif + for (; p < end; p++) { *************** *** 4802,4805 **** --- 5423,5431 ---- register int addr = RELOC_ADDRESS(p); register unsigned int mask = 0; + #ifdef HUNK_INSTEAD_OF_A_OUT + int ext_abs; + + ext_abs = 0; + #endif if (addr >= data_size) *************** *** 4828,4831 **** --- 5454,5489 ---- else relocation = sp->value; + + #ifdef HUNK_INSTEAD_OF_A_OUT + if ((sp->defined & ~N_EXT) == N_ABS) + /* sort of a kludge.. the only external symbol (not pcrelative) + * we can really resolve.. */ + ext_abs = 1; + else if ((sp->defined & ~N_EXT) == N_TEXT || + (sp->defined & ~N_EXT) == N_SETT) + { + this_hunk = number_of_code_hunk; + if (RELOC_BASEREL_P (p)) + { + fprintf (stderr, "symn = $%x, extern = %d, addr = $%lx.\n", + p->r_symbolnum, p->r_extern, p->r_address); + fatal_with_file ("base relative text relocation in ", entry); + } + } + else if ((sp->defined & ~N_EXT) == N_DATA || + (sp->defined & ~N_EXT) == N_SETD || + (sp->defined & ~N_EXT) == N_SETV) + { + this_hunk = number_of_data_hunk; + } + else if ((sp->defined & ~N_EXT) == N_BSS || + (sp->defined & ~N_EXT) == N_UNDF || + (sp->defined & ~N_EXT) == N_SETB) + { + this_hunk = number_of_bss_hunk; + } + else + fatal_with_file ("external symbol with unknown type $%x in ", entry, sp->defined); + #endif } else switch (RELOC_TYPE(p)) *************** *** 4833,4847 **** case N_TEXT: case N_TEXT | N_EXT: ! relocation = text_relocation; break; case N_DATA: case N_DATA | N_EXT: ! relocation = data_relocation; break; case N_BSS: case N_BSS | N_EXT: ! relocation = bss_relocation; break; --- 5491,5531 ---- case N_TEXT: case N_TEXT | N_EXT: ! if (RELOC_BASEREL_P (p)) ! { ! fprintf (stderr, "symn = $%x, extern = %d, addr = $%lx.\n", ! p->r_symbolnum, p->r_extern, p->r_address); ! fatal_with_file ("base relative text relocation in ", entry); ! } ! else ! relocation = text_relocation; ! #ifdef HUNK_INSTEAD_OF_A_OUT ! this_hunk = number_of_code_hunk; ! #endif break; case N_DATA: case N_DATA | N_EXT: ! #ifdef HUNK_INSTEAD_OF_A_OUT ! if (RELOC_BASEREL_P (p)) ! relocation = entry->data_start_address; ! else ! #endif ! relocation = data_relocation; ! #ifdef HUNK_INSTEAD_OF_A_OUT ! this_hunk = number_of_data_hunk; ! #endif break; case N_BSS: case N_BSS | N_EXT: ! #ifdef HUNK_INSTEAD_OF_A_OUT ! if (RELOC_BASEREL_P (p)) ! relocation = entry->bss_start_address - entry->data_size; ! else ! #endif ! relocation = bss_relocation; ! #ifdef HUNK_INSTEAD_OF_A_OUT ! this_hunk = number_of_bss_hunk; ! #endif break; *************** *** 4855,4861 **** --- 5539,5570 ---- } + #ifdef HUNK_INSTEAD_OF_A_OUT + /* in this case, ONLY relocate those pc-relative 32bit jumps, that + * gas generates, since they are position independent, this gives + * a HUGE.. 'if' inside of '#ifdef' oh well... */ + if (RELOC_PCREL_P(p) || RELOC_BASEREL_P(p) || ext_abs) { + + /* VERY BIG KLUDGE AHEAD! Since this amiga hunk format is really + * limited, 8bit and 16bit references are always defined to be + * pc-relative (according to the AmigaDOS RM 2nd ed). BUT if such + * a symbol is resolved by an absolute symbol then it's not considered + * to be pc-relative any more. This is nowhere documented, but you + * couldn't get + * jsr _LVOOpen(a6) + * to work if you wouldn't do it this way. */ + if (ext_abs) RELOC_PCREL_P(p) = 0; + + #endif if (RELOC_PCREL_P(p)) relocation -= pc_relocation; + /* if base relative, subtract 64k/2, so we get a larger range */ + if (RELOC_BASEREL_P(p)) + { + if (! databss_together) + fatal_with_file ("Reloc is base relative. Specify -databss-together in ", entry); + relocation -= 0x7ffe; + } + #ifdef RELOC_ADD_EXTRA relocation += RELOC_ADD_EXTRA(p); *************** *** 4896,4900 **** relocation <<= RELOC_TARGET_BITPOS(p); mask <<= RELOC_TARGET_BITPOS(p); - switch (RELOC_TARGET_SIZE(p)) { --- 5605,5608 ---- *************** *** 4904,4907 **** --- 5612,5618 ---- else if (RELOC_MEMORY_ADD_P(p)) relocation += mask & *(char *) (data + addr); + if (relocation < -128 || relocation > 127) + fatal_with_file ("Byte reloc overflow in ", entry); + *(char *) (data + addr) &= ~mask; *(char *) (data + addr) |= relocation; *************** *** 4909,4919 **** case 1: ! if (RELOC_MEMORY_SUB_P(p)) relocation -= mask & *(short *) (data + addr); else if (RELOC_MEMORY_ADD_P(p)) relocation += mask & *(short *) (data + addr); *(short *) (data + addr) &= ~mask; *(short *) (data + addr) |= relocation; break; case 2: --- 5620,5648 ---- case 1: ! { ! int r=relocation; ! ! if (RELOC_MEMORY_SUB_P(p)) relocation -= mask & *(short *) (data + addr); else if (RELOC_MEMORY_ADD_P(p)) relocation += mask & *(short *) (data + addr); + + if (relocation < -32768 || relocation > 32767) + { + fprintf (stderr, "relocation = $%lx, bsr = %d, pcr = %d, r= $%lx\n", + relocation, RELOC_BASEREL_P(p), RELOC_PCREL_P (p), r); + fprintf (stderr, "textr = $%x, datar = $%x, bssr = $%x\n", + text_relocation, data_relocation, bss_relocation); + fprintf (stderr, "symn = $%x, extern = %d, addr = $%lx.\n", + p->r_symbolnum, p->r_extern, p->r_address); + fprintf (stderr, "data_size = %d, bss_size = %d.\n", + data_size, bss_size); + fatal_with_file ("Word reloc overflow in ", entry); + } + *(short *) (data + addr) &= ~mask; *(short *) (data + addr) |= relocation; break; + } case 2: *************** *** 4938,4941 **** --- 5667,5671 ---- else if (RELOC_MEMORY_ADD_P(p)) relocation += mask & *(long *) (data + addr); + *(long *) (data + addr) &= ~mask; *(long *) (data + addr) |= relocation; *************** *** 4946,4952 **** fatal_with_file ("Unimplemented relocation field length in ", entry); } } } ! /* For OUTPUT_RELOCATABLE only: write out the relocation, relocating the addresses-to-be-relocated. */ --- 5676,5713 ---- fatal_with_file ("Unimplemented relocation field length in ", entry); } + + #ifdef HUNK_INSTEAD_OF_A_OUT + /* now finish this huge 'if' .. */ + } + else + { + /* this only deals with 32bit relocs, the Amiga-loader + * doesn't support 1 or 2 byte relocs, they are only defined + * inside program-units (commonly known as object-files:-)) */ + + if (RELOC_TARGET_SIZE(p) != 2) + fatal_with_file ("unsupported reloc-size in ", entry); + + /* Phil.B: 06-Apr-94 same kludge as above for host with stricter alignment + than the taget. */ + #ifdef CROSS_LINKER + { + /* Thing to relocate. */ + long thing; + bcopy (data + addr, &thing, sizeof (thing)); + thing += relocation; + bcopy (&thing, data + addr, sizeof (thing)); + } + #else + *(long *) (data + addr) += relocation; + #endif /* CROSS_LINKER */ + + addr += pc_relocation; + add_to_reloc_hunk(this_hunk, addr); + } + #endif } } ! /* For OUTPUT_RELOCATABLE only: write out the relocation, relocating the addresses-to-be-relocated. */ *************** *** 4996,5000 **** /* Write out the relocations of all files, remembered from copy_text. */ ! lseek (outdesc, output_trel_offset, 0); each_full_file (coptxtrel, 0); --- 5757,5761 ---- /* Write out the relocations of all files, remembered from copy_text. */ ! fseek (outstream, output_trel_offset, 0); each_full_file (coptxtrel, 0); *************** *** 5002,5006 **** fprintf (stderr, "\nWriting data relocation:\n\n"); ! lseek (outdesc, output_drel_offset, 0); each_full_file (copdatrel, 0); --- 5763,5767 ---- fprintf (stderr, "\nWriting data relocation:\n\n"); ! fseek (outstream, output_drel_offset, 0); each_full_file (copdatrel, 0); *************** *** 5077,5081 **** #endif ! mywrite (entry->textrel, 1, entry->text_reloc_size, outdesc); } --- 5838,5842 ---- #endif ! mywrite (entry->textrel, 1, entry->text_reloc_size, outstream); } *************** *** 5156,5162 **** #endif ! mywrite (entry->datarel, 1, entry->data_reloc_size, outdesc); } ! void write_file_syms (); void write_string_table (); --- 5917,5923 ---- #endif ! mywrite (entry->datarel, 1, entry->data_reloc_size, outstream); } ! void write_file_syms (); void write_string_table (); *************** *** 5193,5198 **** } - FILE *outstream = (FILE *) 0; - /* Write the contents of `strtab_vector' into the string table. This is done once for each file's local&debugger symbols --- 5954,5957 ---- *************** *** 5204,5211 **** register int i; ! lseek (outdesc, output_strs_offset + output_strs_size, 0); if (!outstream) outstream = fdopen (outdesc, "w"); for (i = 0; i < strtab_index; i++) --- 5963,5972 ---- register int i; ! fseek (outstream, output_strs_offset + output_strs_size, 0); + #if 0 if (!outstream) outstream = fdopen (outdesc, "w"); + #endif for (i = 0; i < strtab_index; i++) *************** *** 5221,5225 **** perror_name (output_filename); } ! /* Write the symbol table and string table of the output file. */ --- 5982,5986 ---- perror_name (output_filename); } ! /* Write the symbol table and string table of the output file. */ *************** *** 5249,5252 **** --- 6010,6019 ---- register struct nlist *bufp = buf; + #ifdef HUNK_INSTEAD_OF_A_OUT + /* this enables us to output "regular" amiga symbols without + * the BSD-like debug-hunk */ + if (number_of_debug_hunk == -1) return; + #endif + /* Size of string table includes the bytes that store the size. */ strtab_size = sizeof strtab_size; *************** *** 5371,5376 **** /* Output the buffer full of `struct nlist's. */ ! lseek (outdesc, output_syms_offset + output_syms_size, 0); ! mywrite (buf, sizeof (struct nlist), bufp - buf, outdesc); output_syms_size += sizeof (struct nlist) * (bufp - buf); --- 6138,6143 ---- /* Output the buffer full of `struct nlist's. */ ! fseek (outstream, output_syms_offset + output_syms_size, 0); ! mywrite (buf, sizeof (struct nlist), bufp - buf, outstream); output_syms_size += sizeof (struct nlist) * (bufp - buf); *************** *** 5381,5386 **** first word of the string table. */ ! lseek (outdesc, output_strs_offset, 0); ! mywrite (&strtab_size, sizeof (int), 1, outdesc); /* Write the strings for the global symbols. */ --- 6148,6153 ---- first word of the string table. */ ! fseek (outstream, output_strs_offset, 0); ! mywrite (&strtab_size, sizeof (int), 1, outstream); /* Write the strings for the global symbols. */ *************** *** 5388,5392 **** write_string_table (); } ! /* Write the local and debugger symbols of file ENTRY. Increment *SYMS_WRITTEN_ADDR for each symbol that is written. */ --- 6155,6159 ---- write_string_table (); } ! /* Write the local and debugger symbols of file ENTRY. Increment *SYMS_WRITTEN_ADDR for each symbol that is written. */ *************** *** 5490,5495 **** /* All the symbols are now in BUF; write them. */ ! lseek (outdesc, output_syms_offset + output_syms_size, 0); ! mywrite (buf, sizeof (struct nlist), bufp - buf, outdesc); output_syms_size += sizeof (struct nlist) * (bufp - buf); --- 6257,6262 ---- /* All the symbols are now in BUF; write them. */ ! fseek (outstream, output_syms_offset + output_syms_size, 0); ! mywrite (buf, sizeof (struct nlist), bufp - buf, outstream); output_syms_size += sizeof (struct nlist) * (bufp - buf); *************** *** 5500,5504 **** entry->strings = 0; /* Since it will dissapear anyway. */ } ! /* Copy any GDB symbol segments from the input files to the output file. The contents of the symbol segment is copied without change --- 6267,6271 ---- entry->strings = 0; /* Since it will dissapear anyway. */ } ! /* Copy any GDB symbol segments from the input files to the output file. The contents of the symbol segment is copied without change *************** *** 5510,5514 **** write_symsegs () { ! lseek (outdesc, output_symseg_offset, 0); each_file (write_file_symseg, 0); } --- 6277,6281 ---- write_symsegs () { ! fseek (outstream, output_symseg_offset, 0); each_file (write_file_symseg, 0); } *************** *** 5545,5549 **** /* Write the modified root into the output file. */ ! mywrite (&root, sizeof root, 1, outdesc); /* Copy the rest of the symbol segment unchanged. */ --- 6312,6316 ---- /* Write the modified root into the output file. */ ! mywrite (&root, sizeof root, 1, outstream); /* Copy the rest of the symbol segment unchanged. */ *************** *** 5558,5567 **** fatal_with_file ("premature end of file in symbol segment of ", entry); total -= len; ! mywrite (buffer, len, 1, outdesc); } file_close (); } ! /* Define a special symbol (etext, edata, or end). NAME is the name of the symbol, with a leading underscore (whether or not this --- 6325,6334 ---- fatal_with_file ("premature end of file in symbol segment of ", entry); total -= len; ! mywrite (buffer, len, 1, outstream); } file_close (); } ! /* Define a special symbol (etext, edata, or end). NAME is the name of the symbol, with a leading underscore (whether or not this *************** *** 5617,5620 **** --- 6384,6413 ---- symbol_define ("__end", N_BSS | N_EXT, &end_symbol_alt); + #ifdef amigados + if (output_datadata_relocs) + symbol_define ("___datadata_relocs", N_TEXT | N_EXT, &datadata_reloc_symbol); + + symbol_define ("__sdata", N_DATA | N_EXT, &sdata_symbol); + symbol_define ("___text_size", N_ABS | N_EXT, &text_size_symbol); + symbol_define ("___data_size", N_ABS | N_EXT, &data_size_symbol); + symbol_define ("___bss_size", N_ABS | N_EXT, &bss_size_symbol); + { + symbol *a_symbol; + symbol_define ("___machtype", N_ABS | N_EXT, &a_symbol); + if (a_symbol) + a_symbol->value = amiga_machtype; + + symbol_define ("___databss_together", N_ABS | N_EXT, &a_symbol); + if (a_symbol) + a_symbol->value = databss_together; + + if (databss_together) + { + symbol_define ("___a4_init", N_DATA | N_EXT, &a_symbol); + if (a_symbol) + a_symbol->value = data_start + 0x7ffe; + } + } + #endif #ifdef sun { *************** *** 5659,5663 **** return k; } ! /* Get the symbol table entry for the global symbol named KEY. Create one if there is none. */ --- 6452,6456 ---- return k; } ! /* Get the symbol table entry for the global symbol named KEY. Create one if there is none. */ *************** *** 5726,5730 **** return 0; } ! /* Report a usage error. Like fatal except prints a usage summary. */ --- 6519,6523 ---- return 0; } ! /* Report a usage error. Like fatal except prints a usage summary. */ *************** *** 5740,5743 **** --- 6533,6546 ---- fprintf (stderr, "\n"); } + #ifdef HUNK_INSTEAD_OF_A_OUT + fprintf (stderr, "\ + Usage: %s [-d] [-dc] [-dp] [-e symbol] [-l lib] [-n] [-noinhibit-exec]\n\ + [-nostdlib] [-o file] [-r] [-s] [-t] [-u symbol] [-x] [-y symbol]\n\ + [-z] [-A file] [-Bstatic] [-D size] [-L libdir] [-M] [-N]\n\ + [-S] [-T[{text,data}] addr] [-V prefix] [-X] \n\ + [{-a,-amiga-debug-hunk}] [{-f,-flavor} flavor] [file...]\n\ + [-chip {c,d,b}] [-fast {c,d,b}] [-m,-shortdata]\n", + progname); + #else fprintf (stderr, "\ Usage: %s [-d] [-dc] [-dp] [-e symbol] [-l lib] [-n] [-noinhibit-exec]\n\ *************** *** 5746,5749 **** --- 6549,6553 ---- [-S] [-T[{text,data}] addr] [-V prefix] [-X] [file...]\n", progname); + #endif exit (1); } *************** *** 5766,5775 **** void ! fatal_with_file (string, entry) char *string; struct file_entry *entry; { fprintf (stderr, "%s: ", progname); ! fprintf (stderr, string); print_file_name (entry, stderr); fprintf (stderr, "\n"); --- 6570,6579 ---- void ! fatal_with_file (string, entry, arg) char *string; struct file_entry *entry; { fprintf (stderr, "%s: ", progname); ! fprintf (stderr, string, arg); print_file_name (entry, stderr); fprintf (stderr, "\n"); *************** *** 5785,5793 **** { extern int errno, sys_nerr; - extern char *sys_errlist[]; char *s; if (errno < sys_nerr) ! s = concat ("", sys_errlist[errno], " for %s"); else s = "cannot open %s"; --- 6589,6596 ---- { extern int errno, sys_nerr; char *s; if (errno < sys_nerr) ! s = concat ("", strerror (errno), " for %s"); else s = "cannot open %s"; *************** *** 5803,5811 **** { extern int errno, sys_nerr; - extern char *sys_errlist[]; char *s; if (errno < sys_nerr) ! s = concat ("", sys_errlist[errno], " for "); else s = "cannot open "; --- 6606,6613 ---- { extern int errno, sys_nerr; char *s; if (errno < sys_nerr) ! s = concat ("", strerror (errno), " for "); else s = "cannot open "; *************** *** 5825,5839 **** } ! /* Output COUNT*ELTSIZE bytes of data at BUF to the descriptor DESC. */ void ! mywrite (buf, count, eltsize, desc) char *buf; int count; int eltsize; ! int desc; { register int val; register int bytes = count * eltsize; --- 6627,6642 ---- } ! /* Output COUNT*ELTSIZE bytes of data at BUF to the descriptor DESC. */ void ! mywrite (buf, count, eltsize, stream) char *buf; int count; int eltsize; ! FILE *stream; { + #if 0 register int val; register int bytes = count * eltsize; *************** *** 5847,5859 **** bytes -= val; } } ! /* Output PADDING zero-bytes to descriptor OUTDESC. PADDING may be negative; in that case, do nothing. */ void ! padfile (padding, outdesc) int padding; ! int outdesc; { register char *buf; --- 6650,6665 ---- bytes -= val; } + #else + fwrite (buf, eltsize, count, stream); + #endif } ! /* Output PADDING zero-bytes to descriptor OUTSTREAM. PADDING may be negative; in that case, do nothing. */ void ! padfile (padding, outstream) int padding; ! FILE *outstream; { register char *buf; *************** *** 5863,5867 **** buf = (char *) alloca (padding); bzero (buf, padding); ! mywrite (buf, padding, 1, outdesc); } --- 6669,6673 ---- buf = (char *) alloca (padding); bzero (buf, padding); ! mywrite (buf, padding, 1, outstream); } *************** *** 5904,5909 **** int size; { register char *result = malloc (size); ! if (!result) fatal ("virtual memory exhausted", 0); return result; --- 6710,6716 ---- int size; { + extern char *malloc(); register char *result = malloc (size); ! if (!result && size) fatal ("virtual memory exhausted", 0); return result; *************** *** 5917,5926 **** int size; { ! register char *result = realloc (ptr, size); if (!result) fatal ("virtual memory exhausted", 0); return result; } ! #ifdef USG --- 6724,6734 ---- int size; { ! extern char *malloc(), *realloc(); ! register char *result = ptr ? realloc (ptr, size) : malloc (size); if (!result) fatal ("virtual memory exhausted", 0); return result; } ! #ifdef USG *************** *** 5953,5954 **** --- 6761,7409 ---- } #endif + + #ifdef HUNK_INSTEAD_OF_A_OUT + /* the whole rest of the file is used for managment of hunks and subhunks.. */ + + /* this is the amiga-equivalent of struct exec */ + struct simple_hunk_header { + long id, /* this will be 0x3f3 */ + zero, + table_size, + first_hunk, + last_hunk, + sizes[4]; /* there can be at most a code,data,bss & debug hunk */ + }; + + /* this writes out a hunk header, depending on the information collected + * so far, it will only create hunks, that really exist, so if your data- + * size is zero, you won't get a data-hunk at all. */ + + void + write_hunk_header(outfd) + int outfd; + { + struct simple_hunk_header sh; + int this_hunk, header_size; + + sh.id = 0x3f3; /* HUNK_HEADER */ + sh.zero = 0; + sh.table_size = current_hunk; + sh.first_hunk = 0; + sh.last_hunk = current_hunk - 1; + + this_hunk = 0; + if (number_of_code_hunk != -1) + sh.sizes[this_hunk++] = code_mem_type|LONGSIZE(text_size); + + if (number_of_data_hunk != -1) + { + int size = LONGSIZE(data_size); + if (databss_together) + { + if (long_data_hunk || !output_datadata_relocs) + size=LONGSIZE(data_size+bss_size); + if (data_mem_type == 0) + data_mem_type=bss_mem_type; + } + sh.sizes[this_hunk++] = data_mem_type|size; + } + + if (!databss_together && number_of_bss_hunk != -1) + sh.sizes[this_hunk++] = bss_mem_type|LONGSIZE(bss_size); + + if (number_of_debug_hunk != -1) + sh.sizes[this_hunk++] = 0; /* to be filled in later */ + + header_size = sizeof(sh) - (4-this_hunk)*sizeof(long); + mywrite(&sh, 1, header_size, outfd); + } + + /* if we really write out a debug hunk, this fills in the remaining + * spots, that are known only at the end of load-file output */ + + void + conditionally_rewrite_headers () + { + long size_of_debug_hunk, + end_hunk = 0x3f2, + eof; + + /* if we don't want a debug hunk, just return */ + if (number_of_debug_hunk == -1) return; + + /* while we're at it, since we started the debug-hunk, lets finish it + * now. */ + fseek (outstream, 0L, 2); + eof = ftell (outstream); + dh.strs = eof - offset_of_debug_hunk - sizeof(dh) - dh.syms; + /* just to be sure, we HAVE to pad to a long-boundery */ + if (eof & 3) + { + long zero = 0; + + mywrite(&zero, 4 - (eof & 3), 1, outstream); + eof = (eof + 3) & ~3; + } + + mywrite(&end_hunk, sizeof(long), 1, outstream); + + /* ok, so calculate the size of the debug hunk. This is the + * size of the debug_header plus the symbol and string tables, + * but it doesn't include the 2 longs, that identify the hunk and + * its length, whence the "- 2*sizeof(long)" */ + size_of_debug_hunk = eof - offset_of_debug_hunk - 2*sizeof(long); + /* we actually need the size in longs.. */ + size_of_debug_hunk = LONGSIZE(size_of_debug_hunk); + + /* now first patch the debug-hunk itself, afterwards the load-file header */ + fseek (outstream, offset_of_debug_hunk, 0); + dh.len = size_of_debug_hunk; + mywrite(&dh, sizeof dh, 1, outstream); + + /* now the main header, this involves calculating, at which offset we + * find the index for the debug hunk */ + fseek (outstream, (5 + number_of_debug_hunk)*sizeof(long), 0); + mywrite(&size_of_debug_hunk, sizeof(long), 1, outstream); + fseek (outstream, 0L, 2); + /* that's it! */ + } + + /* this is the only information that we can store in a regular amiga + * symbol, just its value, nothing further, that's why I added the + * debug-hunk-feature */ + + typedef struct { + char *sym_name; + long sym_offset; + } simple_symbol; + + /* we'll only define symbols after at most 3 hunks, ie. the code, data + * and bss hunk, but not after the debug hunk, whence the index 3 */ + + simple_symbol *hunk_sym_tab[3]; + int hunk_sym_tab_size[3], hunk_sym_tab_index[3]; + + void + init_symbol_hunks() + { + int i; + + if (trace_files) fprintf(stderr, "init_symbol_hunks()\n"); + + for (i = 0; i < 3; i++) + { + hunk_sym_tab[i] = + (simple_symbol *) xmalloc((hunk_sym_tab_size[i] = 10) * + sizeof(simple_symbol)); + hunk_sym_tab_index[i] = 0; + } + } + + /* this should go into libc, well, it wasn't there, so... */ + + char * + strsave(str) + char *str; + { + char *cp; + int len = strlen(str); + if (len) + { + cp = xmalloc(len+1); + strcpy(cp, str); + } + else + cp = NULL; + return cp; + } + + void + add_to_symbol_hunk(hunk_num, name, offset) + int hunk_num; + char *name; + long offset; + { + if (hunk_num == -1) return; + if (hunk_num >= 3) fatal ("invalid hunk_number: %d\n", hunk_num); + + /* no checks for duplicate symbols. Since it is legitimate to have + * symbols with the same name, we can't strip them.. just make + * sure not to call this function multiple times with the same + * symbol, since it won't be detected, and you'll get several + * labels for the same offset... + */ + + if (trace_files) fprintf(stderr, "add_to_symbol_hunk(%d, %s, %d)\n", + hunk_num, name, offset); + + hunk_sym_tab[hunk_num][hunk_sym_tab_index[hunk_num]].sym_offset = offset; + hunk_sym_tab[hunk_num][hunk_sym_tab_index[hunk_num]++].sym_name = + strsave(name); + + if (hunk_sym_tab_index[hunk_num] == hunk_sym_tab_size[hunk_num]) + hunk_sym_tab[hunk_num] = (simple_symbol *) + xrealloc(hunk_sym_tab[hunk_num], + (hunk_sym_tab_size[hunk_num] <<= 1) * + sizeof(simple_symbol)); + } + + int + compare_simple_symbols(l1, l2) + simple_symbol *l1, *l2; + { + return l1->sym_offset - l2->sym_offset; + } + + /* this writes the symbol subhunk #hunk_num, you call this just after + * you created your {code,data,bss}-hunk */ + + void + write_symbol_hunk(hunk_num) + int hunk_num; + { + int i, j; + simple_symbol *tab; + long size, index; + + if (hunk_num == -1) return; + if (hunk_num >= 3) fatal ("invalid hunk_number: %d\n", hunk_num); + + tab = hunk_sym_tab[hunk_num]; + size = hunk_sym_tab_size[hunk_num]; + index = hunk_sym_tab_index[hunk_num]; + + /* kind of abused as general debug-flag:-) */ + if (trace_files) fprintf(stderr, + "wsh: hnum=%d,size=%d,index=%d\n", + hunk_num,size,index); + + if (index > 0) + { + qsort(tab, index, sizeof(simple_symbol), compare_simple_symbols); + + j = 0x3f0; /* HUNK_SYMBOL */ + mywrite(&j, 1, sizeof(long), outstream); + + for (i = 0; i < index; i++) + { + register simple_symbol *ss = tab+i; + int len = strlen (ss->sym_name); + + j = LONGSIZE (len); + mywrite(&j, 1, sizeof(long), outstream); + + mywrite(ss->sym_name, 1, len, outstream); + if (len < 4*j) + padfile (4*j - len, outstream); + + mywrite(&(ss->sym_offset), 1, sizeof(long), outstream); + } + + j = 0; + mywrite(&j, 1, sizeof(long), outstream); + } + } + + /* now follow the quite similar routines for dealing with + * reloc-subhunks, the difference to the symbol-subhunks is, that reloc + * subhunks can be output only after the {code,data}-Hunks, AND there + * can be more than one after each of them */ + + long *hunk_rel_tab[3], hunk_rel_tab_size[3], hunk_rel_tab_index[3]; + + void + init_reloc_hunk() + { + int i; + + if (trace_files) fprintf(stderr, "init_reloc_hunk()\n"); + + for (i = 0; i < 3; i++) + { + hunk_rel_tab[i] = + (long *) xmalloc((hunk_rel_tab_size[i] = 10) * sizeof(long)); + hunk_rel_tab_index[i] = 0; + } + } + + void + add_to_reloc_hunk(hunk_num, offset) + int hunk_num; + long offset; + { + /* no checks for duplicate symbols, they will show up when we sort + * the table, and we will strip them off before writing out the table */ + + if (trace_files) fprintf(stderr, "add_to_reloc_hunk(%d, %d)\n", hunk_num, offset); + + hunk_rel_tab[hunk_num][hunk_rel_tab_index[hunk_num]++] = offset; + + if (hunk_rel_tab_index[hunk_num] == hunk_rel_tab_size[hunk_num]) + hunk_rel_tab[hunk_num] = (long *) + xrealloc(hunk_rel_tab[hunk_num], + (hunk_rel_tab_size[hunk_num] <<= 1) * sizeof(long)); + } + + int + compare_longs(l1, l2) + long *l1, *l2; + { + return *l1 - *l2; + } + + int + compare_strings (s1p, s2p) + char **s1p; + char **s2p; + { + return (strcmp (*s1p, *s2p)); + } + + void + write_reloc_hunk() + { + int i, j; + long *tab, size, index; + /* only write a hunk-header & -end, if we really output some relocs */ + int did_start_hunk = 0; + + for (i = 0; i < 3; i++) + { + tab = hunk_rel_tab[i]; + size = hunk_rel_tab_size[i]; + index = hunk_rel_tab_index[i]; + + /* kind of abused as general debug-flag:-) */ + if (trace_files) fprintf(stderr, + "wrh: i=%d,size=%d,index=%d\n", + i,size,index); + + if (index > 0) + { + qsort(tab, index, sizeof(long), compare_longs); + + /* kick out duplicate symbols.. I don't know, what + * the loader would do, if it had to relocate the same + * address twice.. BTW: can this happen or can't it???? */ + for (j = 0; j < index-1; ) + { + if (tab[j] == tab[j+1]) + bcopy(tab+j+1, tab+j, ((index--)-j-1)*sizeof(long)); + else + j++; + } + + if (!did_start_hunk++) + { + j = 0x3ec; /* HUNK_RELOC32 */ + mywrite(&j, 1, sizeof(long), outstream); + } + + mywrite(&index, 1, sizeof(long), outstream); + mywrite(&i, 1, sizeof(long), outstream); + mywrite(tab, 1, index*sizeof(long), outstream); + hunk_rel_tab_index[i] = index; + } + } + if (did_start_hunk) + { + j = 0; + mywrite(&j, 1, sizeof(long), outstream); + } + } + + + void + write_datadata_relocs () + { + int numdd, i, prev; + + prev = ftell (outstream); + fseek (outstream, datadata_relocs_offset, L_SET); + + numdd = hunk_rel_tab_index[number_of_data_hunk]; + if (numdd > numdatadata_relocs) + fatal ("found more data-data relocs than estimated!\n", 0); + + mywrite (&numdd, 1, sizeof (long), outstream); + if (numdd) + mywrite (hunk_rel_tab[number_of_data_hunk], numdd, sizeof (long), outstream); + + fseek (outstream, prev, L_SET); + } + + + /* create the bss hunk if needed */ + + void + write_bss() + { + long bss_hunk[2]; + if (!databss_together && bss_size) + { + bss_hunk[0] = 0x3eb; + bss_hunk[1] = LONGSIZE(bss_size); + mywrite(bss_hunk, 1, sizeof bss_hunk, outstream); + write_symbol_hunk(number_of_bss_hunk); + bss_hunk[0] = 0x3f2; /* HUNK_END */ + mywrite(bss_hunk, 1, sizeof(long), outstream); + } + } + + /* this scans one object file for its symbols, and deposits them in + * the symbol-hunk tables for later output */ + + void + look_for_file_syms (entry) + struct file_entry *entry; + { + register struct nlist *p = entry->symbols; + register struct nlist *end = p + entry->syms_size / sizeof (struct nlist); + + #if 0 + /* don't do this, it only confuses most amiga disassemblers.. */ + + /* Generate a local symbol for the start of this file's text. */ + + if (discard_locals != DISCARD_ALL) + add_to_symbol_hunk(number_of_code_hunk, entry->local_sym_name, + entry->text_start_address); + #endif + + /* Read the file's string table. */ + + entry->strings = (char *) alloca (entry->strs_size); + read_entry_strings (file_open (entry), entry); + + for (; p < end; p++) + { + register unsigned char type = p->n_type; + register int write = 0; + int this_hunk; + char *cp; + + /* WRITE gets 1 for a non-global symbol that should be written. */ + + if (SET_ELEMENT_P (type)) /* This occurs even if global. These */ + /* types of symbols are never written */ + /* globally, though they are stored */ + /* globally. */ + write = output_style == OUTPUT_RELOCATABLE; + else if (!(type & (N_STAB | N_EXT))) + /* ordinary local symbol */ + write = ((discard_locals != DISCARD_ALL) + && !(discard_locals == DISCARD_L && + (p->n_un.n_strx + entry->strings)[0] == LPREFIX) + && type != N_WARNING); + + else if (!(type & N_EXT)) + /* debugger symbol */ + write = (strip_symbols == STRIP_NONE); + + /* skip STAB symbols if present */ + write = write && !(type & N_STAB); + + /* those weird types are NOT output in the normal symbols:-)) */ + write = write && (type != N_ABS && type != (N_ABS|N_EXT)); + + /* don't know where those symbols come from, they're well suited to + * crash enforcer, and they're not `real' symbols anyway.. */ + if (p->n_un.n_strx > entry->strs_size) continue; + + /* symbols that end with a dot are only useful for gdb, + * not for a normal amiga debugger (currently gcc_compiled. and + * gcc_compiled2.) so skip them in this section */ + + /* check to see, whether this string ends with a dot */ + if (write && p->n_un.n_strx) + { + cp = rindex (p->n_un.n_strx + entry->strings, '.'); + + write = write && !(cp && !cp[1]); + + #if 0 + printf ("%s >%s<\n", write ? "adding" : "skipping", p->n_un.n_strx + entry->strings); + #endif + } + + if (write) + { + if (p->n_un.n_strx) + { + switch (type & ~N_EXT) + { + case N_TEXT: + this_hunk = number_of_code_hunk; + break; + case N_SETV: + case N_DATA: + this_hunk = number_of_data_hunk; + break; + case N_UNDF: + case N_BSS: + this_hunk = number_of_bss_hunk; + break; + default: + error ("unknown type %d while trying to build lsymhunk", type); + goto skip1; + } + + add_to_symbol_hunk(this_hunk, p->n_un.n_strx + entry->strings, + p->n_value); + skip1: ; + } + } + } + } + + /* scan all input files for symbols and store them in the symbolhunk tables */ + + void + look_for_symbols() + { + int this_hunk; + int i; + symbol *sp; + + if (strip_symbols == STRIP_ALL) + return; + + /* Write the local symbols defined by the various files. */ + + each_file (look_for_file_syms, 0); + file_close (); + + /* Scan the symbol hash table, bucket by bucket. */ + + for (i = 0; i < TABSIZE; i++) + for (sp = symtab[i]; sp; sp = sp->link) + { + struct nlist nl; + + /* Compute a `struct nlist' for the symbol. */ + + nl.n_value = 0; + + if (sp->defined || sp->referenced) + { + /* common condition needs to be before undefined condition */ + /* because unallocated commons are set undefined in */ + /* digest_symbols */ + if (sp->defined > 1) /* defined with known type */ + { + /* If the target of an indirect symbol has been + defined and we are outputting an executable, + resolve the indirection; it's no longer needed */ + if (output_style != OUTPUT_RELOCATABLE + && ((sp->defined & ~N_EXT) == N_INDR) + && (((symbol *) sp->value)->defined > 1)) + { + symbol *newsp = (symbol *) sp->value; + nl.n_type = newsp->defined; + nl.n_value = newsp->value; + } + else + { + nl.n_type = sp->defined; + if (sp->defined != (N_INDR | N_EXT)) + nl.n_value = sp->value; + else + nl.n_value = 0; + } + } + else if (sp->max_common_size) /* defined as common but not allocated. */ + { + /* happens only with -r and not -d */ + /* write out a common definition */ + nl.n_type = N_UNDF | N_EXT; + nl.n_value = sp->max_common_size; + } + else if (!sp->defined) /* undefined -- legit only if -r */ + { + nl.n_type = N_UNDF | N_EXT; + nl.n_value = 0; + } + else + fatal ("internal error: %s defined in mysterious way", sp->name); + + switch (nl.n_type & ~N_EXT) + { + case N_TEXT: + this_hunk = number_of_code_hunk; + break; + case N_SETV: + case N_DATA: + this_hunk = number_of_data_hunk; + break; + case N_UNDF: + case N_BSS: + this_hunk = number_of_bss_hunk; + break; + case N_ABS: + break; + default: + error ("unknown type %d while trying to build symhunk", nl.n_type); + goto skip2; + } + + /* sigh, there is no equivalent in the symbol section of a load + * file on the amiga, have to forget about those symbols */ + if ((nl.n_type & ~N_EXT) == N_ABS) + continue; + + add_to_symbol_hunk(this_hunk, sp->name, nl.n_value); + skip2: ; + } + } + } + + void + relocate_set_vectors (vectors, relvectors, num_entries) + unsigned long *vectors; + unsigned char *relvectors; + int num_entries; + { + unsigned long i; + unsigned long offset = set_sect_start; + int hunk_num; + + while (num_entries-- > 0) + { + /* the number of entries for this symbol */ + i = *vectors++; offset += 4; relvectors++; + while (num_entries --, i--) + { + /* relocation ok? */ + if (*relvectors) + { + hunk_num = number_of_code_hunk; + if (*vectors >= text_size) + { + if (*vectors >= text_size + data_size) + { + hunk_num = number_of_bss_hunk; + if (databss_together) + *vectors -= text_size; + else + *vectors -= text_size + data_size; + } + else + { + hunk_num = number_of_data_hunk; + *vectors -= text_size; + } + } + add_to_reloc_hunk (hunk_num, offset); + } + ++vectors; + offset += 4; + ++relvectors; + } + /* check.. HAS to be zero */ + if (*vectors) + fatal ("set-vector corrupt, num_entries = %d", num_entries); + vectors++; offset += 4; relvectors++; --num_entries; + } + } + #endif + diff -2rcN binutils-1.8.x/objdump.c binutils-1.8.x-amiga/objdump.c *** binutils-1.8.x/objdump.c Sat Dec 30 00:16:07 1989 --- binutils-1.8.x-amiga/objdump.c Wed Sep 22 12:45:33 1993 *************** *** 25,30 **** #include "getopt.h" #ifndef COFF_ENCAPSULATE ! #include /* Tell a.out.gnu.h not to try to redefine some things. */ #define __STRUCT_EXEC_OVERRIDE__ --- 25,34 ---- #include "getopt.h" + #ifdef MCH_AMIGA + #define getpagesize() 256 + #endif + #ifndef COFF_ENCAPSULATE ! #include /* Tell a.out.gnu.h not to try to redefine some things. */ #define __STRUCT_EXEC_OVERRIDE__ diff -2rcN binutils-1.8.x/ranlib.c binutils-1.8.x-amiga/ranlib.c *** binutils-1.8.x/ranlib.c Thu Mar 1 00:18:42 1990 --- binutils-1.8.x-amiga/ranlib.c Sat Jul 30 17:15:25 1994 *************** *** 55,59 **** char *prog = AR_PROG; ! char *prog_pref = "/usr/local/gnubin/ar"; int --- 55,59 ---- char *prog = AR_PROG; ! char *prog_pref = "/gnu/bin/ar"; int diff -2rcN binutils-1.8.x/strip.c binutils-1.8.x-amiga/strip.c *** binutils-1.8.x/strip.c Mon Jun 11 21:40:01 1990 --- binutils-1.8.x-amiga/strip.c Wed Sep 22 12:45:43 1993 *************** *** 72,76 **** /* If BSD, we can use `ftruncate'. */ ! #ifndef USG #define HAVE_FTRUNCATE #endif --- 72,76 ---- /* If BSD, we can use `ftruncate'. */ ! #if !defined(USG) && !defined(MCH_AMIGA) #define HAVE_FTRUNCATE #endif *************** *** 288,293 **** --- 288,295 ---- /* Handle any signal that came in while they were deferred. */ + #ifndef MCH_AMIGA if (delayed_signal) kill (getpid (), delayed_signal); + #endif } *************** *** 929,932 **** --- 931,935 ---- #ifdef USG + #ifndef MCH_AMIGA rename (from, to) *************** *** 941,944 **** --- 944,948 ---- } + #endif #endif