* bfd.c (bfd_get_error, bfd_set_error): New functions.
[external/binutils.git] / bfd / aout-encap.c
1 /* BFD back-end for a.out files encapsulated with COFF headers.
2    Copyright (C) 1990-1991 Free Software Foundation, Inc.
3
4 This file is part of BFD, the Binary File Descriptor library.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
19
20 /* THIS MODULE IS NOT FINISHED.  IT PROBABLY DOESN'T EVEN COMPILE.  */
21
22 #if 0
23 #define PAGE_SIZE       4096
24 #define SEGMENT_SIZE    PAGE_SIZE
25 #define TEXT_START_ADDR 0
26 #define ARCH 32
27 #define BYTES_IN_WORD 4
28 #endif
29
30 #include "bfd.h"
31 #include <sysdep.h>
32 #include "libbfd.h"
33 #include <aout/aout64.h>
34 #include "aout/stab_gnu.h"
35 #include "aout/ar.h"
36 #include "libaout.h"           /* BFD a.out internal data structures */
37
38 bfd_target *encap_real_callback ();
39
40 bfd_target *
41 DEFUN(encap_object_p,(abfd),
42      bfd *abfd)
43 {
44   unsigned char magicbuf[4]; /* Raw bytes of magic number from file */
45   unsigned long magic;          /* Swapped magic number */
46   short coff_magic;
47   struct external_exec exec_bytes;
48   struct internal_exec exec;
49
50   bfd_set_error (bfd_error_system_call);
51
52   if (bfd_read ((PTR)magicbuf, 1, sizeof (magicbuf), abfd) !=
53       sizeof (magicbuf))
54     return 0;
55   
56   coff_magic = bfd_h_get_16 (abfd, magicbuf);
57   if (coff_magic != COFF_MAGIC)
58     return 0;                   /* Not an encap coff file */
59
60   __header_offset_temp==COFF_MAGIC ? sizeof(struct coffheader) : 0)
61   (fseek ((f), HEADER_OFFSET((f)), 1))
62
63   magic = bfd_h_get_32 (abfd, magicbuf);
64
65   if (N_BADMAG (*((struct internal_exec *) &magic))) return 0;
66
67   struct external_exec exec_bytes;
68   if (bfd_read ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd)
69       != EXEC_BYTES_SIZE) {
70     bfd_set_error (bfd_error_wrong_format);
71     return 0;
72   }
73   NAME(aout,swap_exec_header_in)(abfd, &exec_bytes, &exec);
74
75   return aout_32_some_aout_object_p (abfd, &exec, encap_realcallback);
76 }
77
78 /* Finish up the reading of a encapsulated-coff a.out file header */
79 bfd_target *
80 DEFUN(encap_real_callback,(abfd),
81       bfd *abfd)
82 {
83   struct internal_exec *execp = exec_hdr (abfd);
84   
85   MY(callback)(abfd, execp);
86   
87   /* If we have a coff header, it can give us better values for
88      text_start and exec_data_start.  This is particularly useful
89      for remote debugging of embedded systems.  */
90   if (N_FLAGS(exec_aouthdr) & N_FLAGS_COFF_ENCAPSULATE)
91   {
92           struct coffheader ch;
93           int val;
94           val = lseek (execchan, -(sizeof (AOUTHDR) + sizeof (ch)), 1);
95           if (val == -1)
96                   perror_with_name (filename);
97           val = myread (execchan, &ch, sizeof (ch));
98           if (val < 0)
99                   perror_with_name (filename);
100           text_start = ch.text_start;
101           exec_data_start = ch.data_start;
102   } else
103          {
104           text_start =
105             IS_OBJECT_FILE (exec_aouthdr) ? 0 : N_TXTADDR (exec_aouthdr);
106           exec_data_start = IS_OBJECT_FILE (exec_aouthdr)
107             ? exec_aouthdr.a_text : N_DATADDR (exec_aouthdr);
108   }
109
110   /* Determine the architecture and machine type of the object file.  */
111   bfd_default_set_arch_mach(abfd, bfd_arch_m68k, 0); /* FIXME */
112
113   return abfd->xvec;
114 }
115
116 /* Write an object file in Encapsulated COFF format.
117    Section contents have already been written.  We write the
118    file header, symbols, and relocation.  */
119
120 boolean
121 DEFUN(encap_write_object_contents,(abfd),
122       bfd *abfd)
123 {
124   bfd_size_type data_pad = 0;
125   struct external_exec exec_bytes;
126   struct internal_exec *execp = exec_hdr (abfd);
127
128 /****** FIXME:  Fragments from the old GNU LD program for dealing with
129         encap coff.  */
130 struct coffheader coffheader;
131 int need_coff_header;
132
133   /* Determine whether to count the header as part of
134      the text size, and initialize the text size accordingly.
135      This depends on the kind of system and on the output format selected.  */
136
137   N_SET_MAGIC (outheader, magic);
138 #ifdef INITIALIZE_HEADER
139   INITIALIZE_HEADER;
140 #endif
141
142   text_size = sizeof (struct exec);
143 #ifdef COFF_ENCAPSULATE
144   if (relocatable_output == 0 && file_table[0].just_syms_flag == 0)
145     {
146       need_coff_header = 1;
147       /* set this flag now, since it will change the values of N_TXTOFF, etc */
148       N_SET_FLAGS (outheader, N_FLAGS_COFF_ENCAPSULATE);
149       text_size += sizeof (struct coffheader);
150     }
151 #endif
152
153 #ifdef COFF_ENCAPSULATE
154   if (need_coff_header)
155     {
156       /* We are encapsulating BSD format within COFF format.  */
157       struct coffscn *tp, *dp, *bp;
158
159       tp = &coffheader.scns[0];
160       dp = &coffheader.scns[1];
161       bp = &coffheader.scns[2];
162
163       strcpy (tp->s_name, ".text");
164       tp->s_paddr = text_start;
165       tp->s_vaddr = text_start;
166       tp->s_size = text_size;
167       tp->s_scnptr = sizeof (struct coffheader) + sizeof (struct exec);
168       tp->s_relptr = 0;
169       tp->s_lnnoptr = 0;
170       tp->s_nreloc = 0;
171       tp->s_nlnno = 0;
172       tp->s_flags = 0x20;
173       strcpy (dp->s_name, ".data");
174       dp->s_paddr = data_start;
175       dp->s_vaddr = data_start;
176       dp->s_size = data_size;
177       dp->s_scnptr = tp->s_scnptr + tp->s_size;
178       dp->s_relptr = 0;
179       dp->s_lnnoptr = 0;
180       dp->s_nreloc = 0;
181       dp->s_nlnno = 0;
182       dp->s_flags = 0x40;
183       strcpy (bp->s_name, ".bss");
184       bp->s_paddr = dp->s_vaddr + dp->s_size;
185       bp->s_vaddr = bp->s_paddr;
186       bp->s_size = bss_size;
187       bp->s_scnptr = 0;
188       bp->s_relptr = 0;
189       bp->s_lnnoptr = 0;
190       bp->s_nreloc = 0;
191       bp->s_nlnno = 0;
192       bp->s_flags = 0x80;
193
194       coffheader.f_magic = COFF_MAGIC;
195       coffheader.f_nscns = 3;
196       /* store an unlikely time so programs can
197        * tell that there is a bsd header
198        */
199       coffheader.f_timdat = 1;
200       coffheader.f_symptr = 0;
201       coffheader.f_nsyms = 0;
202       coffheader.f_opthdr = 28;
203       coffheader.f_flags = 0x103;
204       /* aouthdr */
205       coffheader.magic = ZMAGIC;
206       coffheader.vstamp = 0;
207       coffheader.tsize = tp->s_size;
208       coffheader.dsize = dp->s_size;
209       coffheader.bsize = bp->s_size;
210       coffheader.entry = outheader.a_entry;
211       coffheader.text_start = tp->s_vaddr;
212       coffheader.data_start = dp->s_vaddr;
213     }
214 #endif
215
216 #ifdef COFF_ENCAPSULATE
217   if (need_coff_header)
218     mywrite (&coffheader, sizeof coffheader, 1, outdesc);
219 #endif
220
221 #ifndef COFF_ENCAPSULATE
222   padfile (N_TXTOFF (outheader) - sizeof outheader, outdesc);
223 #endif
224
225   text_size -= N_TXTOFF (outheader);
226   WRITE_HEADERS(abfd, execp);
227   return true;
228 }
229
230 #define MY_write_object_content encap_write_object_contents
231 #define MY_object_p encap_object_p
232
233 #include "aout-target.h"