eirik@labs.labs.tek.com (Eirik Fuller) (11/15/89)
I just finished bootstrapping gcc on a sun386 with the GNU assembler and the GNU linker. In order to do this, I had to modify robotussin. Because I have no idea what effect the changes I made will have on other COFF systems, I wrapped them in "#ifdef sun386". I also made some changes to gcc source files in order to use the GNU toolset; that code should soon appear on bug-gcc (gnu.gcc.bug). After applying these diffs, compile with -DPORTAR -DCOFF_ENCAPSULATE Depending on how you configure gcc, you might also want -Dnounderscore, though I did not wind up using it. If you run out of stack space while running GNU ar or GNU ld (this manifests itself as a segment violation), you should link in alloca.c from the gcc sources, and get rid of the "#define alloca" in ar.c and ld.c; or you could try to get Sun to fix this annoying "feature". *** robotussin.c Sat Apr 22 21:21:03 1989 --- sun386-robotussin.c Sat Nov 11 21:06:22 1989 *************** *** 71,76 **** --- 71,84 ---- #define sizeof_reloc (RELSZ) #define sizeof_section (SCNHSZ) #define sizeof_coff_header (FILHSZ) + /* + Without the following, compiling this is a pain on a BSD4.3 Vax. + Though that might not seem useful, the compatibility of byte order + between a Vax and a 386 can come in handy for cross-debugging + */ + #ifdef NO_VFPRINTF + #define vfprintf(fp, format, ap) _doprnt (format, ap, fp) + #endif /* not HAVE_VPRINTF */ extern long lseek (); extern void exit (); *************** *** 161,166 **** --- 169,185 ---- } } + #ifdef sun386 + /* + The purpose of the following kludge is to cope with the discrepancy + between coff_data_header.s_vaddr and coff_text_header.s_size; in a BSD + object file, they are assumed equal. It should be ok to use + coff_data_header.s_paddr, since it has no other apparent use. + */ + coff_data_header.s_paddr = coff_text_header.s_size; + coff_bss_header.s_paddr = coff_data_header.s_size + coff_text_header.s_size; + #endif + /* ** Pass1 thru the symbol table - count usable symbols and map ** old symbol #'s into new ones (as used by relocation *************** *** 194,199 **** --- 213,226 ---- if (verbose_flag) printf ("map %d to %d\n", i, symbol_count); symbol_map[i] = symbol_count++; + #ifdef sun386 + if (coff_sym_listp[i].n_scnum == data_sect_num) + coff_sym_listp[i].n_value -= + coff_data_header.s_vaddr - coff_data_header.s_paddr; + else if (coff_sym_listp[i].n_scnum == bss_sect_num) + coff_sym_listp[i].n_value -= + coff_bss_header.s_vaddr - coff_bss_header.s_paddr; + #endif } else { *************** *** 404,409 **** --- 431,440 ---- { if (read (fd_in, &coff_reloc, sizeof_reloc) != sizeof_reloc) error ("can't read relocation entry"); + #ifdef sun386 + coff_reloc.r_vaddr -= + section_headerp->s_vaddr - section_headerp->s_paddr; + #endif if (verbose_flag) printf ("vaddr = 0x%x, symndx = %d\n", coff_reloc.r_vaddr, coff_reloc.r_symndx); /* *************** *** 454,459 **** --- 485,520 ---- { if (symbol_map[coff_reloc.r_symndx] == -1) error ("Oops! possible bug - reloc reference to ignored symbol"); + #ifdef sun386 + { + int offset=0; + switch (-symbol_map[coff_reloc.r_symndx]) + { + case N_DATA: + offset = coff_data_header.s_vaddr - coff_data_header.s_paddr; + break; + case N_BSS: + offset = coff_bss_header.s_vaddr - coff_bss_header.s_paddr; + break; + } + switch (coff_reloc.r_type) + { + case R_RELBYTE: + *((char *) (text_and_data + coff_reloc.r_vaddr)) -= offset; + break; + case R_RELWORD: + *((short *) (text_and_data + coff_reloc.r_vaddr)) -= offset; + break; + case R_RELLONG: + case R_DIR32: + case R_PCRLONG: + *((int *) (text_and_data + coff_reloc.r_vaddr)) -= offset; + break; + default: + error ("unknown relocation type 0%o", coff_reloc.r_type); + } + } + #endif reloc_infop->r_symbolnum = -symbol_map[coff_reloc.r_symndx]; reloc_infop->r_extern = 0; } *************** *** 461,466 **** --- 522,531 ---- ** COFF address includes the section address - BSD doesn't, so ** subtract it out. */ + #ifdef sun386 + coff_reloc.r_vaddr += + section_headerp->s_vaddr - section_headerp->s_paddr; + #endif reloc_infop->r_address = coff_reloc.r_vaddr - section_headerp->s_vaddr; switch (coff_reloc.r_type) {