12159047fSniklas /* Yet Another Try at encapsulating bsd object files in coff.
2*5f210c2aSfgsch    Copyright 1988, 1989, 1991 Free Software Foundation, Inc.
32159047fSniklas    Written by Pace Willisson 12/9/88
42159047fSniklas 
52159047fSniklas    This file is obsolete.  It needs to be converted to just define a bunch
62159047fSniklas    of stuff that BFD can use to do coff-encapsulated files.  --gnu@cygnus.com
72159047fSniklas 
82159047fSniklas This program is free software; you can redistribute it and/or modify
92159047fSniklas it under the terms of the GNU General Public License as published by
102159047fSniklas the Free Software Foundation; either version 2 of the License, or
112159047fSniklas (at your option) any later version.
122159047fSniklas 
132159047fSniklas This program is distributed in the hope that it will be useful,
142159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
152159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
162159047fSniklas GNU General Public License for more details.
172159047fSniklas 
182159047fSniklas You should have received a copy of the GNU General Public License
192159047fSniklas along with this program; if not, write to the Free Software
202159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
212159047fSniklas 
222159047fSniklas /*
232159047fSniklas  * We only use the coff headers to tell the kernel
242159047fSniklas  * how to exec the file.  Therefore, the only fields that need to
252159047fSniklas  * be filled in are the scnptr and vaddr for the text and data
262159047fSniklas  * sections, and the vaddr for the bss.  As far as coff is concerned,
272159047fSniklas  * there is no symbol table, relocation, or line numbers.
282159047fSniklas  *
292159047fSniklas  * A normal bsd header (struct exec) is placed after the coff headers,
302159047fSniklas  * and before the real text.  I defined a the new fields 'a_machtype'
312159047fSniklas  * and a_flags.  If a_machtype is M_386, and a_flags & A_ENCAP is
322159047fSniklas  * true, then the bsd header is preceeded by a coff header.  Macros
332159047fSniklas  * like N_TXTOFF and N_TXTADDR use this field to find the bsd header.
342159047fSniklas  *
352159047fSniklas  * The only problem is to track down the bsd exec header.  The
362159047fSniklas  * macros HEADER_OFFSET, etc do this.
372159047fSniklas  */
382159047fSniklas 
392159047fSniklas #define N_FLAGS_COFF_ENCAPSULATE 0x20 /* coff header precedes bsd header */
402159047fSniklas 
412159047fSniklas /* Describe the COFF header used for encapsulation.  */
422159047fSniklas 
432159047fSniklas struct coffheader
442159047fSniklas {
452159047fSniklas   /* filehdr */
462159047fSniklas   unsigned short f_magic;
472159047fSniklas   unsigned short f_nscns;
482159047fSniklas   long f_timdat;
492159047fSniklas   long f_symptr;
502159047fSniklas   long f_nsyms;
512159047fSniklas   unsigned short f_opthdr;
522159047fSniklas   unsigned short f_flags;
532159047fSniklas   /* aouthdr */
542159047fSniklas   short magic;
552159047fSniklas   short vstamp;
562159047fSniklas   long tsize;
572159047fSniklas   long dsize;
582159047fSniklas   long bsize;
592159047fSniklas   long entry;
602159047fSniklas   long text_start;
612159047fSniklas   long data_start;
622159047fSniklas   struct coffscn
632159047fSniklas     {
642159047fSniklas       char s_name[8];
652159047fSniklas       long s_paddr;
662159047fSniklas       long s_vaddr;
672159047fSniklas       long s_size;
682159047fSniklas       long s_scnptr;
692159047fSniklas       long s_relptr;
702159047fSniklas       long s_lnnoptr;
712159047fSniklas       unsigned short s_nreloc;
722159047fSniklas       unsigned short s_nlnno;
732159047fSniklas       long s_flags;
742159047fSniklas     } scns[3];
752159047fSniklas };
762159047fSniklas 
772159047fSniklas /* Describe some of the parameters of the encapsulation,
782159047fSniklas    including how to find the encapsulated BSD header.  */
792159047fSniklas 
802159047fSniklas /* FIXME, this is dumb.  The same tools can't handle a.outs for different
812159047fSniklas    architectures, just because COFF_MAGIC is different; so you need a
822159047fSniklas    separate GNU nm for every architecture!!?  Unfortunately, it needs to
832159047fSniklas    be this way, since the COFF_MAGIC value is determined by the kernel
842159047fSniklas    we're trying to fool here.  */
852159047fSniklas 
862159047fSniklas #define COFF_MAGIC_I386 0514 /* I386MAGIC */
872159047fSniklas #define COFF_MAGIC_M68K 0520 /* MC68MAGIC */
882159047fSniklas #define	COFF_MAGIC_A29K 0x17A	/* Used by asm29k cross-tools */
892159047fSniklas 
902159047fSniklas #ifdef COFF_MAGIC
912159047fSniklas short __header_offset_temp;
922159047fSniklas #define HEADER_OFFSET(f) \
932159047fSniklas 	(__header_offset_temp = 0, \
942159047fSniklas 	 fread ((char *)&__header_offset_temp, sizeof (short), 1, (f)), \
952159047fSniklas 	 fseek ((f), -sizeof (short), 1), \
962159047fSniklas 	 __header_offset_temp==COFF_MAGIC ? sizeof(struct coffheader) : 0)
972159047fSniklas #else
982159047fSniklas #define HEADER_OFFSET(f) 0
992159047fSniklas #endif
1002159047fSniklas 
1012159047fSniklas #define HEADER_SEEK(f) (fseek ((f), HEADER_OFFSET((f)), 1))
1022159047fSniklas 
1032159047fSniklas /* Describe the characteristics of the BSD header
1042159047fSniklas    that appears inside the encapsulation.  */
1052159047fSniklas 
1062159047fSniklas /* Encapsulated coff files that are linked ZMAGIC have a text segment
1072159047fSniklas    offset just past the header (and a matching TXTADDR), excluding
1082159047fSniklas    the headers from the text segment proper but keeping the physical
1092159047fSniklas    layout and the virtual memory layout page-aligned.
1102159047fSniklas 
1112159047fSniklas    Non-encapsulated a.out files that are linked ZMAGIC have a text
1122159047fSniklas    segment that starts at 0 and an N_TXTADR similarly offset to 0.
1132159047fSniklas    They too are page-aligned with each other, but they include the
1142159047fSniklas    a.out header as part of the text.
1152159047fSniklas 
1162159047fSniklas    The _N_HDROFF gets sizeof struct exec added to it, so we have
1172159047fSniklas    to compensate here.  See <a.out.gnu.h>.  */
1182159047fSniklas 
1192159047fSniklas #undef _N_HDROFF
1202159047fSniklas #undef N_TXTADDR
1212159047fSniklas #undef N_DATADDR
1222159047fSniklas 
1232159047fSniklas #define _N_HDROFF(x) ((N_FLAGS(x) & N_FLAGS_COFF_ENCAPSULATE) ? \
1242159047fSniklas 		      sizeof (struct coffheader) : 0)
1252159047fSniklas 
1262159047fSniklas /* Address of text segment in memory after it is loaded.  */
1272159047fSniklas #define N_TXTADDR(x) \
1282159047fSniklas 	((N_FLAGS(x) & N_FLAGS_COFF_ENCAPSULATE) ? \
1292159047fSniklas 	 sizeof (struct coffheader) + sizeof (struct exec) : 0)
1302159047fSniklas #define SEGMENT_SIZE 0x400000
1312159047fSniklas 
1322159047fSniklas #define N_DATADDR(x) \
1332159047fSniklas 	((N_FLAGS(x) & N_FLAGS_COFF_ENCAPSULATE) ? \
1342159047fSniklas 	 (SEGMENT_SIZE + ((N_TXTADDR(x)+(x).a_text-1) & ~(SEGMENT_SIZE-1))) : \
1352159047fSniklas 	 (N_TXTADDR(x)+(x).a_text))
136