Commit | Line | Data |
---|---|---|
69ebee86 JG |
1 | /* BFD back-end data structures for a.out (and similar) files. |
2 | ||
3 | We try to encapsulate the differences in a few routines, and otherwise | |
4 | share large masses of code. This means we only have to fix bugs in | |
5 | one place, most of the time. */ | |
6 | ||
4a81b561 DHW |
7 | /* Copyright (C) 1990, 1991 Free Software Foundation, Inc. |
8 | ||
9 | This file is part of BFD, the Binary File Diddler. | |
10 | ||
11 | BFD is free software; you can redistribute it and/or modify | |
12 | it under the terms of the GNU General Public License as published by | |
13 | the Free Software Foundation; either version 1, or (at your option) | |
14 | any later version. | |
15 | ||
16 | BFD is distributed in the hope that it will be useful, | |
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | GNU General Public License for more details. | |
20 | ||
21 | You should have received a copy of the GNU General Public License | |
22 | along with BFD; see the file COPYING. If not, write to | |
23 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
24 | ||
25 | /* $Id$ */ | |
26 | ||
c0e5039e JG |
27 | #ifdef __STDC__ |
28 | #define CAT3(a,b,c) a##b##c | |
29 | #else | |
30 | #define CAT3(a,b,c) a/**/b/**/c | |
31 | #endif | |
32 | ||
33 | ||
34 | #if ARCH_SIZE==64 | |
35 | #define GET_WORD bfd_h_get_64 | |
36 | #define GET_SWORD (int64_type)GET_WORD | |
37 | #define PUT_WORD bfd_h_put_64 | |
38 | #define NAME(x,y) CAT3(x,_64_,y) | |
39 | #define JNAME(x) CAT(x,_64) | |
40 | #define BYTES_IN_WORD 8 | |
41 | #else | |
42 | #define GET_WORD bfd_h_get_32 | |
43 | #define GET_SWORD (int32_type)GET_WORD | |
44 | #define PUT_WORD bfd_h_put_32 | |
45 | #define NAME(x,y) CAT3(x,_32_,y) | |
46 | #define JNAME(x) CAT(x,_32) | |
47 | #define BYTES_IN_WORD 4 | |
48 | #endif | |
49 | ||
69ebee86 JG |
50 | #define adata(bfd) ((struct aoutdata *) ((bfd)->tdata)) |
51 | #define exec_hdr(bfd) (adata(bfd)->hdr) | |
52 | #define obj_textsec(bfd) (adata(bfd)->textsec) | |
53 | #define obj_datasec(bfd) (adata(bfd)->datasec) | |
54 | #define obj_bsssec(bfd) (adata(bfd)->bsssec) | |
55 | #define obj_sym_filepos(bfd) (adata(bfd)->sym_filepos) | |
56 | #define obj_str_filepos(bfd) (adata(bfd)->str_filepos) | |
4a81b561 | 57 | |
69ebee86 | 58 | #define obj_reloc_entry_size(bfd) (adata(bfd)->reloc_entry_size) |
4a81b561 | 59 | |
69ebee86 | 60 | typedef struct aout_symbol { |
4a81b561 DHW |
61 | asymbol symbol; |
62 | short desc; | |
69ebee86 JG |
63 | char other; |
64 | unsigned char type; | |
4a81b561 DHW |
65 | } aout_symbol_type; |
66 | ||
69ebee86 | 67 | struct aoutdata { |
c0e5039e | 68 | struct internal_exec *hdr; /* exec file header */ |
4a81b561 DHW |
69 | aout_symbol_type *symbols; /* symtab for input bfd */ |
70 | ||
71 | ||
72 | /* For ease, we do this */ | |
73 | asection *textsec; | |
74 | asection *datasec; | |
75 | asection *bsssec; | |
76 | ||
77 | /* We remember these offsets so that after check_file_format, we have | |
78 | no dependencies on the particular format of the exec_hdr. */ | |
79 | file_ptr sym_filepos; | |
80 | file_ptr str_filepos; | |
4a81b561 | 81 | |
69ebee86 JG |
82 | /* Size of a relocation entry */ |
83 | unsigned reloc_entry_size; | |
84 | }; | |
4a81b561 | 85 | |
4a81b561 | 86 | |
69ebee86 | 87 | #define obj_outsymbols(bfd) ((PTR)(((struct aoutdata *) ((bfd)->tdata))->outsymbols)) |
4a81b561 DHW |
88 | |
89 | ||
fc723380 JG |
90 | /* We take the address of the first element of an asymbol to ensure that the |
91 | * macro is only ever applied to an asymbol */ | |
4a81b561 DHW |
92 | #define aout_symbol(asymbol) ((aout_symbol_type *)(&(asymbol)->the_bfd)) |
93 | ||
69ebee86 JG |
94 | /*#define obj_symbols(bfd) ((((struct aoutdata *) ((bfd)->tdata))->symbols))*/ |
95 | #define obj_aout_symbols(bfd) ((((struct aoutdata *) (bfd)->tdata))->symbols) | |
96 | #define obj_arch_flags(bfd) ((((struct aoutdata *) (bfd)->tdata))->arch_flags) | |
97 | ||
98 | #define get_tdata(x) ((struct aoutdata *)((x)->tdata)) | |
99 | ||
c0e5039e | 100 | /* Prototype declarations for functions defined in aoutx.h */ |
69ebee86 | 101 | |
c0e5039e | 102 | PROTO (boolean, NAME(aout,squirt_out_relocs),(bfd *abfd, asection *section)); |
69ebee86 | 103 | |
c0e5039e | 104 | PROTO (bfd_target *, NAME(aout,some_aout_object_p), (bfd *abfd, |
69ebee86 | 105 | bfd_target *(*callback)())); |
c0e5039e JG |
106 | PROTO (boolean, NAME(aout,mkobject), (bfd *abfd)); |
107 | PROTO (enum machine_type, NAME(aout,machine_type), (enum bfd_architecture arch, | |
69ebee86 | 108 | unsigned long machine)); |
c0e5039e | 109 | PROTO (boolean, NAME(aout,set_arch_mach), (bfd *abfd, enum bfd_architecture arch, |
69ebee86 JG |
110 | unsigned long machine)); |
111 | ||
c0e5039e JG |
112 | PROTO (boolean, NAME(aout,new_section_hook), (bfd *abfd, asection *newsect)); |
113 | PROTO (boolean, NAME(aout,set_section_contents), (bfd *abfd, sec_ptr section, | |
114 | PTR location, file_ptr offset, bfd_size_type count)); | |
115 | ||
116 | PROTO (asymbol *,NAME(aout,make_empty_symbol), (bfd *abfd)); | |
117 | PROTO (boolean, NAME(aout,slurp_symbol_table), (bfd *abfd)); | |
118 | PROTO (void, NAME(aout,write_syms), (bfd *abfd)); | |
119 | PROTO (void, NAME(aout,reclaim_symbol_table), (bfd *abfd)); | |
120 | PROTO (unsigned int, NAME(aout,get_symtab_upper_bound), (bfd *abfd)); | |
121 | PROTO (unsigned int, NAME(aout,get_symtab), (bfd *abfd, asymbol **location)); | |
122 | PROTO (boolean, NAME(aout,slurp_reloc_table), (bfd *abfd, sec_ptr asect, | |
69ebee86 | 123 | asymbol **symbols)); |
c0e5039e | 124 | PROTO (unsigned int, NAME(aout,canonicalize_reloc), (bfd *abfd, sec_ptr section, |
69ebee86 | 125 | arelent **relptr, asymbol **symbols)); |
c0e5039e JG |
126 | PROTO (unsigned int, NAME(aout,get_reloc_upper_bound), (bfd *abfd, sec_ptr asect)); |
127 | PROTO (void, NAME(aout,reclaim_reloc), (bfd *ignore_abfd, sec_ptr ignore)); | |
128 | PROTO (alent *, NAME(aout,get_lineno), (bfd *ignore_abfd, asymbol *ignore_symbol)); | |
129 | PROTO (void, NAME(aout,print_symbol), (bfd *ignore_abfd, PTR file, | |
69ebee86 | 130 | asymbol *symbol, bfd_print_symbol_enum_type how)); |
c0e5039e JG |
131 | PROTO (boolean, NAME(aout,close_and_cleanup), (bfd *abfd)); |
132 | PROTO (boolean, NAME(aout,find_nearest_line), (bfd *abfd, asection *section, | |
69ebee86 JG |
133 | asymbol **symbols, bfd_vma offset, CONST char **filename_ptr, |
134 | CONST char **functionname_ptr, unsigned int *line_ptr)); | |
c0e5039e | 135 | PROTO (int, NAME(aout,sizeof_headers), (bfd *ignore_abfd, boolean exec)); |
69ebee86 | 136 | |
69ebee86 | 137 | |
c0e5039e JG |
138 | PROTO (void, NAME(aout,swap_exec_header_in), (bfd *abfd, |
139 | struct external_exec *raw_bytes, struct internal_exec *execp)); | |
69ebee86 | 140 | |
c0e5039e JG |
141 | PROTO (void, NAME(aout,swap_exec_header_out),(bfd *abfd, struct internal_exec *execp, |
142 | struct external_exec *raw_bytes)); | |
69ebee86 JG |
143 | |
144 | /* A.out uses the generic versions of these routines... */ | |
145 | ||
c0e5039e JG |
146 | #define aout_32_get_section_contents bfd_generic_get_section_contents |
147 | #define aout_32_close_and_cleanup bfd_generic_close_and_cleanup | |
148 | ||
149 | #define aout_64_get_section_contents bfd_generic_get_section_contents | |
150 | #define aout_64_close_and_cleanup bfd_generic_close_and_cleanup | |
151 | ||
152 | /* Calculate the file positions of the parts of a newly read aout header */ | |
153 | #define WORK_OUT_FILE_POSITIONS(abfd, execp) \ | |
154 | obj_datasec (abfd)->vma = N_DATADDR(*execp); \ | |
155 | obj_bsssec (abfd)->vma = N_BSSADDR(*execp); \ | |
156 | obj_textsec (abfd)->vma = N_TXTADDR(*execp); \ | |
157 | \ | |
158 | /* The file offsets of the sections */ \ | |
159 | obj_textsec (abfd)->filepos = N_TXTOFF (*execp); \ | |
160 | obj_datasec (abfd)->filepos = N_DATOFF (*execp); \ | |
161 | \ | |
162 | /* The file offsets of the relocation info */ \ | |
163 | obj_textsec (abfd)->rel_filepos = N_TRELOFF(*execp); \ | |
164 | obj_datasec (abfd)->rel_filepos = N_DRELOFF(*execp); \ | |
165 | \ | |
166 | /* The file offsets of the string table and symbol table. */ \ | |
167 | obj_sym_filepos (abfd) = N_SYMOFF (*execp); \ | |
168 | obj_str_filepos (abfd) = N_STROFF (*execp); \ | |
169 | ||
170 | ||
171 | #define WRITE_HEADERS(abfd, execp) \ | |
172 | { \ | |
173 | if (abfd->flags & D_PAGED) \ | |
174 | { \ | |
175 | execp->a_text = obj_textsec (abfd)->size + EXEC_BYTES_SIZE; \ | |
176 | N_SET_MAGIC (*execp, ZMAGIC); \ | |
177 | } \ | |
178 | else if (abfd->flags & WP_TEXT) \ | |
179 | { \ | |
180 | N_SET_MAGIC (*execp, NMAGIC); \ | |
181 | } \ | |
182 | else { \ | |
183 | N_SET_MAGIC(*execp, OMAGIC); \ | |
184 | } \ | |
185 | if (abfd->flags & D_PAGED) \ | |
186 | { \ | |
187 | data_pad = ((obj_datasec(abfd)->size + PAGE_SIZE -1) \ | |
188 | & (- PAGE_SIZE)) - obj_datasec(abfd)->size; \ | |
189 | \ | |
190 | if (data_pad > obj_bsssec(abfd)->size) \ | |
191 | execp->a_bss = 0; \ | |
192 | else \ | |
193 | execp->a_bss = obj_bsssec(abfd)->size - data_pad; \ | |
194 | execp->a_data = obj_datasec(abfd)->size + data_pad; \ | |
195 | } \ | |
196 | else \ | |
197 | { \ | |
198 | execp->a_data = obj_datasec (abfd)->size; \ | |
199 | execp->a_bss = obj_bsssec (abfd)->size; \ | |
200 | } \ | |
201 | \ | |
202 | execp->a_syms = bfd_get_symcount (abfd) * EXTERNAL_LIST_SIZE; \ | |
203 | execp->a_entry = bfd_get_start_address (abfd); \ | |
204 | \ | |
205 | execp->a_trsize = ((obj_textsec (abfd)->reloc_count) * \ | |
206 | obj_reloc_entry_size (abfd)); \ | |
207 | execp->a_drsize = ((obj_datasec (abfd)->reloc_count) * \ | |
208 | obj_reloc_entry_size (abfd)); \ | |
209 | NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \ | |
210 | \ | |
211 | bfd_seek (abfd, 0L, false); \ | |
212 | bfd_write ((PTR) &exec_bytes, 1, EXEC_BYTES_SIZE, abfd); \ | |
213 | /* Now write out reloc info, followed by syms and strings */ \ | |
214 | \ | |
215 | if (bfd_get_symcount (abfd) != 0) \ | |
216 | { \ | |
217 | bfd_seek (abfd, \ | |
218 | (long)(N_SYMOFF(*execp)), false); \ | |
219 | \ | |
220 | NAME(aout,write_syms)(abfd); \ | |
221 | \ | |
222 | bfd_seek (abfd, (long)(N_TRELOFF(*execp)), false); \ | |
223 | \ | |
224 | if (!NAME(aout,squirt_out_relocs) (abfd, obj_textsec (abfd))) return false; \ | |
225 | bfd_seek (abfd, (long)(N_DRELOFF(*execp)), false); \ | |
226 | \ | |
227 | if (!NAME(aout,squirt_out_relocs)(abfd, obj_datasec (abfd))) return false; \ | |
228 | } \ | |
229 | } |