xref: /openbsd-src/gnu/usr.bin/binutils/bfd/aout-encap.c (revision c074d1c999f3e07019cd5e9a2f190b057ef3b935)
12159047fSniklas /* BFD back-end for a.out files encapsulated with COFF headers.
2*c074d1c9Sdrahn    Copyright 1990, 1991, 1994, 1995, 2000, 2001, 2002, 2003
3*c074d1c9Sdrahn    Free Software Foundation, Inc.
42159047fSniklas 
52159047fSniklas This file is part of BFD, the Binary File Descriptor library.
62159047fSniklas 
72159047fSniklas This program is free software; you can redistribute it and/or modify
82159047fSniklas it under the terms of the GNU General Public License as published by
92159047fSniklas the Free Software Foundation; either version 2 of the License, or
102159047fSniklas (at your option) any later version.
112159047fSniklas 
122159047fSniklas This program is distributed in the hope that it will be useful,
132159047fSniklas but WITHOUT ANY WARRANTY; without even the implied warranty of
142159047fSniklas MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
152159047fSniklas GNU General Public License for more details.
162159047fSniklas 
172159047fSniklas You should have received a copy of the GNU General Public License
182159047fSniklas along with this program; if not, write to the Free Software
192159047fSniklas Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
202159047fSniklas 
212159047fSniklas /* THIS MODULE IS NOT FINISHED.  IT PROBABLY DOESN'T EVEN COMPILE.  */
222159047fSniklas 
232159047fSniklas #if 0
242159047fSniklas #define	TARGET_PAGE_SIZE	4096
252159047fSniklas #define	SEGMENT_SIZE	TARGET_PAGE_SIZE
262159047fSniklas #define TEXT_START_ADDR 0
272159047fSniklas #endif
282159047fSniklas 
292159047fSniklas #include "bfd.h"
30*c074d1c9Sdrahn #include "sysdep.h"
312159047fSniklas #include "libbfd.h"
32*c074d1c9Sdrahn #include "aout/aout64.h"
332159047fSniklas #include "aout/stab_gnu.h"
342159047fSniklas #include "aout/ar.h"
352159047fSniklas #include "libaout.h"           /* BFD a.out internal data structures */
362159047fSniklas 
372159047fSniklas const bfd_target *encap_real_callback ();
382159047fSniklas 
392159047fSniklas const bfd_target *
encap_object_p(abfd)402159047fSniklas encap_object_p (abfd)
412159047fSniklas      bfd *abfd;
422159047fSniklas {
432159047fSniklas   unsigned char magicbuf[4]; /* Raw bytes of magic number from file */
442159047fSniklas   unsigned long magic;		/* Swapped magic number */
452159047fSniklas   short coff_magic;
462159047fSniklas   struct external_exec exec_bytes;
472159047fSniklas   struct internal_exec exec;
48*c074d1c9Sdrahn   bfd_size_type amt = sizeof (magicbuf);
492159047fSniklas 
50*c074d1c9Sdrahn   if (bfd_bread ((PTR) magicbuf, amt, abfd) != amt)
512159047fSniklas     {
522159047fSniklas       if (bfd_get_error () != bfd_error_system_call)
532159047fSniklas 	bfd_set_error (bfd_error_wrong_format);
542159047fSniklas       return 0;
552159047fSniklas     }
562159047fSniklas 
57*c074d1c9Sdrahn   coff_magic = H_GET_16 (abfd, magicbuf);
582159047fSniklas   if (coff_magic != COFF_MAGIC)
592159047fSniklas     return 0;			/* Not an encap coff file */
602159047fSniklas 
61*c074d1c9Sdrahn   magic = H_GET_32 (abfd, magicbuf);
622159047fSniklas 
63*c074d1c9Sdrahn   if (N_BADMAG (*((struct internal_exec *) &magic)))
64*c074d1c9Sdrahn     return 0;
652159047fSniklas 
66*c074d1c9Sdrahn   if (bfd_seek (abfd, (file_ptr) sizeof (struct coffheader), SEEK_SET) != 0)
67*c074d1c9Sdrahn     return 0;
682159047fSniklas 
69*c074d1c9Sdrahn   amt = EXEC_BYTES_SIZE;
70*c074d1c9Sdrahn   if (bfd_bread ((PTR) &exec_bytes, amt, abfd) != amt)
71*c074d1c9Sdrahn     {
722159047fSniklas       if (bfd_get_error () != bfd_error_system_call)
732159047fSniklas 	bfd_set_error (bfd_error_wrong_format);
742159047fSniklas       return 0;
752159047fSniklas     }
762159047fSniklas   NAME(aout,swap_exec_header_in) (abfd, &exec_bytes, &exec);
772159047fSniklas 
782159047fSniklas   return aout_32_some_aout_object_p (abfd, &exec, encap_realcallback);
792159047fSniklas }
802159047fSniklas 
81*c074d1c9Sdrahn /* Finish up the reading of an encapsulated-coff a.out file header.  */
822159047fSniklas const bfd_target *
encap_real_callback(abfd)832159047fSniklas encap_real_callback (abfd)
842159047fSniklas      bfd *abfd;
852159047fSniklas {
862159047fSniklas   struct internal_exec *execp = exec_hdr (abfd);
872159047fSniklas 
882159047fSniklas   MY(callback) (abfd, execp);
892159047fSniklas 
902159047fSniklas   /* If we have a coff header, it can give us better values for
912159047fSniklas      text_start and exec_data_start.  This is particularly useful
922159047fSniklas      for remote debugging of embedded systems.  */
932159047fSniklas   if (N_FLAGS(exec_aouthdr) & N_FLAGS_COFF_ENCAPSULATE)
942159047fSniklas     {
952159047fSniklas       struct coffheader ch;
962159047fSniklas       int val;
972159047fSniklas       val = lseek (execchan, -(sizeof (AOUTHDR) + sizeof (ch)), 1);
982159047fSniklas       if (val == -1)
992159047fSniklas 	perror_with_name (filename);
1002159047fSniklas       val = myread (execchan, &ch, sizeof (ch));
1012159047fSniklas       if (val < 0)
1022159047fSniklas 	perror_with_name (filename);
1032159047fSniklas       text_start = ch.text_start;
1042159047fSniklas       exec_data_start = ch.data_start;
105*c074d1c9Sdrahn     }
106*c074d1c9Sdrahn   else
1072159047fSniklas     {
1082159047fSniklas       text_start =
1092159047fSniklas 	IS_OBJECT_FILE (exec_aouthdr) ? 0 : N_TXTADDR (exec_aouthdr);
110*c074d1c9Sdrahn       exec_data_start = (IS_OBJECT_FILE (exec_aouthdr)
111*c074d1c9Sdrahn 			 ? exec_aouthdr.a_text
112*c074d1c9Sdrahn 			 : N_DATADDR (exec_aouthdr));
1132159047fSniklas     }
1142159047fSniklas 
1152159047fSniklas   /* Determine the architecture and machine type of the object file.  */
1162159047fSniklas   bfd_default_set_arch_mach(abfd, bfd_arch_m68k, 0); /* FIXME */
1172159047fSniklas 
1182159047fSniklas   return abfd->xvec;
1192159047fSniklas }
1202159047fSniklas 
1212159047fSniklas /* Write an object file in Encapsulated COFF format.
1222159047fSniklas    Section contents have already been written.  We write the
1232159047fSniklas    file header, symbols, and relocation.  */
1242159047fSniklas 
125*c074d1c9Sdrahn bfd_boolean
encap_write_object_contents(abfd)1262159047fSniklas encap_write_object_contents (abfd)
1272159047fSniklas      bfd *abfd;
1282159047fSniklas {
1292159047fSniklas   bfd_size_type data_pad = 0;
1302159047fSniklas   struct external_exec exec_bytes;
1312159047fSniklas   struct internal_exec *execp = exec_hdr (abfd);
1322159047fSniklas 
133*c074d1c9Sdrahn   /* FIXME:  Fragments from the old GNU LD program for dealing with
1342159047fSniklas      encap coff.  */
1352159047fSniklas   struct coffheader coffheader;
1362159047fSniklas   int need_coff_header;
1372159047fSniklas 
1382159047fSniklas   /* Determine whether to count the header as part of
1392159047fSniklas      the text size, and initialize the text size accordingly.
1402159047fSniklas      This depends on the kind of system and on the output format selected.  */
1412159047fSniklas 
1422159047fSniklas   N_SET_MAGIC (outheader, magic);
1432159047fSniklas #ifdef INITIALIZE_HEADER
1442159047fSniklas   INITIALIZE_HEADER;
1452159047fSniklas #endif
1462159047fSniklas 
1472159047fSniklas   text_size = sizeof (struct exec);
1482159047fSniklas #ifdef COFF_ENCAPSULATE
1492159047fSniklas   if (relocatable_output == 0 && file_table[0].just_syms_flag == 0)
1502159047fSniklas     {
1512159047fSniklas       need_coff_header = 1;
1522159047fSniklas       /* set this flag now, since it will change the values of N_TXTOFF, etc */
1532159047fSniklas       N_SET_FLAGS (outheader, aout_backend_info (abfd)->exec_hdr_flags);
1542159047fSniklas       text_size += sizeof (struct coffheader);
1552159047fSniklas     }
1562159047fSniklas #endif
1572159047fSniklas 
1582159047fSniklas #ifdef COFF_ENCAPSULATE
1592159047fSniklas   if (need_coff_header)
1602159047fSniklas     {
1612159047fSniklas       /* We are encapsulating BSD format within COFF format.  */
1622159047fSniklas       struct coffscn *tp, *dp, *bp;
1632159047fSniklas 
1642159047fSniklas       tp = &coffheader.scns[0];
1652159047fSniklas       dp = &coffheader.scns[1];
1662159047fSniklas       bp = &coffheader.scns[2];
1672159047fSniklas 
1682159047fSniklas       strcpy (tp->s_name, ".text");
1692159047fSniklas       tp->s_paddr = text_start;
1702159047fSniklas       tp->s_vaddr = text_start;
1712159047fSniklas       tp->s_size = text_size;
1722159047fSniklas       tp->s_scnptr = sizeof (struct coffheader) + sizeof (struct exec);
1732159047fSniklas       tp->s_relptr = 0;
1742159047fSniklas       tp->s_lnnoptr = 0;
1752159047fSniklas       tp->s_nreloc = 0;
1762159047fSniklas       tp->s_nlnno = 0;
1772159047fSniklas       tp->s_flags = 0x20;
1782159047fSniklas       strcpy (dp->s_name, ".data");
1792159047fSniklas       dp->s_paddr = data_start;
1802159047fSniklas       dp->s_vaddr = data_start;
1812159047fSniklas       dp->s_size = data_size;
1822159047fSniklas       dp->s_scnptr = tp->s_scnptr + tp->s_size;
1832159047fSniklas       dp->s_relptr = 0;
1842159047fSniklas       dp->s_lnnoptr = 0;
1852159047fSniklas       dp->s_nreloc = 0;
1862159047fSniklas       dp->s_nlnno = 0;
1872159047fSniklas       dp->s_flags = 0x40;
1882159047fSniklas       strcpy (bp->s_name, ".bss");
1892159047fSniklas       bp->s_paddr = dp->s_vaddr + dp->s_size;
1902159047fSniklas       bp->s_vaddr = bp->s_paddr;
1912159047fSniklas       bp->s_size = bss_size;
1922159047fSniklas       bp->s_scnptr = 0;
1932159047fSniklas       bp->s_relptr = 0;
1942159047fSniklas       bp->s_lnnoptr = 0;
1952159047fSniklas       bp->s_nreloc = 0;
1962159047fSniklas       bp->s_nlnno = 0;
1972159047fSniklas       bp->s_flags = 0x80;
1982159047fSniklas 
1992159047fSniklas       coffheader.f_magic = COFF_MAGIC;
2002159047fSniklas       coffheader.f_nscns = 3;
2012159047fSniklas       /* store an unlikely time so programs can
2022159047fSniklas        * tell that there is a bsd header
2032159047fSniklas        */
2042159047fSniklas       coffheader.f_timdat = 1;
2052159047fSniklas       coffheader.f_symptr = 0;
2062159047fSniklas       coffheader.f_nsyms = 0;
2072159047fSniklas       coffheader.f_opthdr = 28;
2082159047fSniklas       coffheader.f_flags = 0x103;
2092159047fSniklas       /* aouthdr */
2102159047fSniklas       coffheader.magic = ZMAGIC;
2112159047fSniklas       coffheader.vstamp = 0;
2122159047fSniklas       coffheader.tsize = tp->s_size;
2132159047fSniklas       coffheader.dsize = dp->s_size;
2142159047fSniklas       coffheader.bsize = bp->s_size;
2152159047fSniklas       coffheader.entry = outheader.a_entry;
2162159047fSniklas       coffheader.text_start = tp->s_vaddr;
2172159047fSniklas       coffheader.data_start = dp->s_vaddr;
2182159047fSniklas     }
2192159047fSniklas #endif
2202159047fSniklas 
2212159047fSniklas #ifdef COFF_ENCAPSULATE
2222159047fSniklas   if (need_coff_header)
2232159047fSniklas     mywrite (&coffheader, sizeof coffheader, 1, outdesc);
2242159047fSniklas #endif
2252159047fSniklas 
2262159047fSniklas #ifndef COFF_ENCAPSULATE
2272159047fSniklas   padfile (N_TXTOFF (outheader) - sizeof outheader, outdesc);
2282159047fSniklas #endif
2292159047fSniklas 
2302159047fSniklas   text_size -= N_TXTOFF (outheader);
2312159047fSniklas   WRITE_HEADERS(abfd, execp);
232*c074d1c9Sdrahn   return TRUE;
2332159047fSniklas }
2342159047fSniklas 
2352159047fSniklas #define MY_write_object_content encap_write_object_contents
2362159047fSniklas #define MY_object_p encap_object_p
2372159047fSniklas #define MY_exec_hdr_flags N_FLAGS_COFF_ENCAPSULATE
2382159047fSniklas 
2392159047fSniklas #include "aout-target.h"
240