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