Commit | Line | Data |
---|---|---|
252b5132 | 1 | /* b.out object file format |
44f2f9d2 | 2 | Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002, |
aef6203b | 3 | 2003, 2005 Free Software Foundation, Inc. |
252b5132 RH |
4 | |
5 | This file is part of GAS, the GNU Assembler. | |
6 | ||
7 | GAS is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as | |
9 | published by the Free Software Foundation; either version 2, | |
10 | or (at your option) any later version. | |
11 | ||
12 | GAS is distributed in the hope that it will be useful, but | |
13 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | |
15 | the GNU General Public License for more details. | |
16 | ||
8fc2b121 ILT |
17 | You should have received a copy of the GNU General Public License |
18 | along with GAS; see the file COPYING. If not, write to the Free | |
19 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |
351aa9f6 | 20 | 02111-1307, USA. */ |
252b5132 RH |
21 | |
22 | #include "as.h" | |
23 | #include "obstack.h" | |
351aa9f6 | 24 | |
ea1562b3 | 25 | /* In: segT Out: N_TYPE bits. */ |
351aa9f6 | 26 | const short seg_N_TYPE[] = |
252b5132 RH |
27 | { |
28 | N_ABS, | |
29 | N_TEXT, | |
30 | N_DATA, | |
31 | N_BSS, | |
ea1562b3 NC |
32 | N_UNDF, /* Unknown. */ |
33 | N_UNDF, /* Error. */ | |
34 | N_UNDF, /* Expression. */ | |
35 | N_UNDF, /* Debug. */ | |
36 | N_UNDF, /* Ntv. */ | |
37 | N_UNDF, /* Ptv. */ | |
38 | N_REGISTER, /* Register. */ | |
252b5132 RH |
39 | }; |
40 | ||
41 | const segT N_TYPE_seg[N_TYPE + 2] = | |
351aa9f6 KH |
42 | { /* N_TYPE == 0x1E = 32-2 */ |
43 | SEG_UNKNOWN, /* N_UNDF == 0 */ | |
252b5132 | 44 | SEG_GOOF, |
351aa9f6 | 45 | SEG_ABSOLUTE, /* N_ABS == 2 */ |
252b5132 | 46 | SEG_GOOF, |
351aa9f6 | 47 | SEG_TEXT, /* N_TEXT == 4 */ |
252b5132 | 48 | SEG_GOOF, |
351aa9f6 | 49 | SEG_DATA, /* N_DATA == 6 */ |
252b5132 | 50 | SEG_GOOF, |
351aa9f6 | 51 | SEG_BSS, /* N_BSS == 8 */ |
252b5132 RH |
52 | SEG_GOOF, |
53 | SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, | |
54 | SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, | |
55 | SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, | |
ea1562b3 | 56 | SEG_REGISTER, /* Dummy N_REGISTER for regs = 30. */ |
252b5132 RH |
57 | SEG_GOOF, |
58 | }; | |
59 | ||
351aa9f6 | 60 | /* Relocation. */ |
252b5132 | 61 | |
351aa9f6 | 62 | /* Crawl along a fixS chain. Emit the segment's relocations. */ |
252b5132 | 63 | |
252b5132 | 64 | void |
ea1562b3 NC |
65 | obj_emit_relocations (char **where, |
66 | fixS *fixP, /* Fixup chain for this segment. */ | |
67 | relax_addressT segment_address_in_file) | |
252b5132 RH |
68 | { |
69 | for (; fixP; fixP = fixP->fx_next) | |
70 | { | |
71 | if (fixP->fx_done == 0 | |
72 | || fixP->fx_r_type != NO_RELOC) | |
73 | { | |
74 | symbolS *sym; | |
75 | ||
76 | sym = fixP->fx_addsy; | |
77 | while (sym->sy_value.X_op == O_symbol | |
78 | && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym))) | |
79 | sym = sym->sy_value.X_add_symbol; | |
80 | fixP->fx_addsy = sym; | |
81 | ||
82 | tc_bout_fix_to_chars (*where, fixP, segment_address_in_file); | |
44f2f9d2 | 83 | *where += md_reloc_size; |
ea1562b3 NC |
84 | } |
85 | } | |
351aa9f6 | 86 | } |
252b5132 | 87 | |
dcd619be | 88 | /* Aout file generation & utilities . */ |
252b5132 | 89 | |
351aa9f6 | 90 | /* Convert a lvalue to machine dependent data. */ |
252b5132 | 91 | |
252b5132 | 92 | void |
ea1562b3 | 93 | obj_header_append (char **where, object_headers *headers) |
252b5132 | 94 | { |
351aa9f6 | 95 | /* Always leave in host byte order. */ |
44f2f9d2 | 96 | char *p; |
252b5132 RH |
97 | |
98 | headers->header.a_talign = section_alignment[SEG_TEXT]; | |
99 | ||
351aa9f6 | 100 | /* Force to at least 2. */ |
252b5132 | 101 | if (headers->header.a_talign < 2) |
ea1562b3 | 102 | headers->header.a_talign = 2; |
252b5132 RH |
103 | |
104 | headers->header.a_dalign = section_alignment[SEG_DATA]; | |
105 | headers->header.a_balign = section_alignment[SEG_BSS]; | |
106 | ||
107 | headers->header.a_tload = 0; | |
351aa9f6 KH |
108 | headers->header.a_dload = |
109 | md_section_align (SEG_DATA, H_GET_TEXT_SIZE (headers)); | |
252b5132 RH |
110 | |
111 | headers->header.a_relaxable = linkrelax; | |
112 | ||
44f2f9d2 AM |
113 | p = *where; |
114 | host_number_to_chars (p, headers->header.a_magic, 4); | |
115 | p += 4; | |
116 | host_number_to_chars (p, headers->header.a_text, 4); | |
117 | p += 4; | |
118 | host_number_to_chars (p, headers->header.a_data, 4); | |
119 | p += 4; | |
120 | host_number_to_chars (p, headers->header.a_bss, 4); | |
121 | p += 4; | |
122 | host_number_to_chars (p, headers->header.a_syms, 4); | |
123 | p += 4; | |
124 | host_number_to_chars (p, headers->header.a_entry, 4); | |
125 | p += 4; | |
126 | host_number_to_chars (p, headers->header.a_trsize, 4); | |
127 | p += 4; | |
128 | host_number_to_chars (p, headers->header.a_drsize, 4); | |
129 | p += 4; | |
130 | host_number_to_chars (p, headers->header.a_tload, 4); | |
131 | p += 4; | |
132 | host_number_to_chars (p, headers->header.a_dload, 4); | |
133 | p += 4; | |
134 | *p++ = headers->header.a_talign; | |
135 | *p++ = headers->header.a_dalign; | |
136 | *p++ = headers->header.a_balign; | |
137 | *p++ = headers->header.a_relaxable; | |
138 | *where = p; | |
351aa9f6 | 139 | } |
252b5132 RH |
140 | |
141 | void | |
ea1562b3 | 142 | obj_symbol_to_chars (char **where, symbolS *symbolP) |
252b5132 | 143 | { |
44f2f9d2 | 144 | char *p = *where; |
ea1562b3 | 145 | |
44f2f9d2 AM |
146 | host_number_to_chars (p, S_GET_OFFSET (symbolP), 4); |
147 | p += 4; | |
148 | /* Can't use S_GET_TYPE here as it masks. */ | |
149 | *p++ = symbolP->sy_symbol.n_type; | |
150 | *p++ = symbolP->sy_symbol.n_other; | |
151 | host_number_to_chars (p, S_GET_DESC (symbolP), 2); | |
152 | p += 2; | |
153 | host_number_to_chars (p, S_GET_VALUE (symbolP), 4); | |
154 | p += 4; | |
155 | *where = p; | |
351aa9f6 | 156 | } |
252b5132 RH |
157 | |
158 | void | |
ea1562b3 | 159 | obj_emit_symbols (char **where, symbolS *symbol_rootP) |
252b5132 RH |
160 | { |
161 | symbolS *symbolP; | |
162 | ||
351aa9f6 | 163 | /* Emit all symbols left in the symbol chain. */ |
252b5132 RH |
164 | for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) |
165 | { | |
351aa9f6 KH |
166 | /* Used to save the offset of the name. It is used to point to |
167 | the string in memory but must be a file offset. */ | |
252b5132 RH |
168 | char *temp; |
169 | ||
170 | temp = S_GET_NAME (symbolP); | |
171 | S_SET_OFFSET (symbolP, symbolP->sy_name_offset); | |
172 | ||
351aa9f6 | 173 | /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */ |
252b5132 RH |
174 | if (!S_IS_DEBUG (symbolP) && !S_IS_DEFINED (symbolP)) |
175 | S_SET_EXTERNAL (symbolP); | |
176 | ||
177 | obj_symbol_to_chars (where, symbolP); | |
178 | S_SET_NAME (symbolP, temp); | |
179 | } | |
351aa9f6 | 180 | } |
252b5132 RH |
181 | |
182 | void | |
ea1562b3 | 183 | obj_symbol_new_hook (symbolS *symbolP) |
252b5132 RH |
184 | { |
185 | S_SET_OTHER (symbolP, 0); | |
186 | S_SET_DESC (symbolP, 0); | |
187 | } | |
188 | ||
189 | static void | |
ea1562b3 | 190 | obj_bout_line (int ignore ATTRIBUTE_UNUSED) |
252b5132 | 191 | { |
351aa9f6 KH |
192 | /* Assume delimiter is part of expression. */ |
193 | /* BSD4.2 as fails with delightful bug, so we are not being | |
194 | incompatible here. */ | |
ea1562b3 | 195 | new_logical_line (NULL, (int) (get_absolute_expression ())); |
252b5132 | 196 | demand_empty_rest_of_line (); |
351aa9f6 | 197 | } |
252b5132 RH |
198 | |
199 | void | |
ea1562b3 | 200 | obj_read_begin_hook (void) |
252b5132 RH |
201 | { |
202 | } | |
203 | ||
204 | void | |
ea1562b3 | 205 | obj_crawl_symbol_chain (object_headers *headers) |
252b5132 RH |
206 | { |
207 | symbolS **symbolPP; | |
208 | symbolS *symbolP; | |
209 | int symbol_number = 0; | |
210 | ||
211 | tc_crawl_symbol_chain (headers); | |
212 | ||
351aa9f6 | 213 | symbolPP = &symbol_rootP; /* -> last symbol chain link. */ |
252b5132 RH |
214 | while ((symbolP = *symbolPP) != NULL) |
215 | { | |
216 | if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_DATA)) | |
217 | { | |
218 | S_SET_SEGMENT (symbolP, SEG_TEXT); | |
ea1562b3 | 219 | } |
252b5132 | 220 | |
6386f3a7 | 221 | resolve_symbol_value (symbolP); |
252b5132 RH |
222 | |
223 | /* Skip symbols which were equated to undefined or common | |
224 | symbols. */ | |
225 | if (symbolP->sy_value.X_op == O_symbol | |
226 | && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP))) | |
227 | { | |
228 | *symbolPP = symbol_next (symbolP); | |
229 | continue; | |
230 | } | |
231 | ||
232 | /* OK, here is how we decide which symbols go out into the | |
233 | brave new symtab. Symbols that do are: | |
351aa9f6 | 234 | |
252b5132 RH |
235 | * symbols with no name (stabd's?) |
236 | * symbols with debug info in their N_TYPE | |
351aa9f6 | 237 | |
252b5132 RH |
238 | Symbols that don't are: |
239 | * symbols that are registers | |
240 | * symbols with \1 as their 3rd character (numeric labels) | |
241 | * "local labels" as defined by S_LOCAL_NAME(name) | |
242 | if the -L switch was passed to gas. | |
252b5132 | 243 | |
351aa9f6 KH |
244 | All other symbols are output. We complain if a deleted |
245 | symbol was marked external. */ | |
252b5132 RH |
246 | |
247 | if (1 | |
248 | && !S_IS_REGISTER (symbolP) | |
249 | && (!S_GET_NAME (symbolP) | |
250 | || S_IS_DEBUG (symbolP) | |
251 | #ifdef TC_I960 | |
351aa9f6 | 252 | /* FIXME-SOON this ifdef seems highly dubious to me. xoxorich. */ |
252b5132 RH |
253 | || !S_IS_DEFINED (symbolP) |
254 | || S_IS_EXTERNAL (symbolP) | |
ea1562b3 | 255 | #endif |
351aa9f6 KH |
256 | || (S_GET_NAME (symbolP)[0] != '\001' |
257 | && (flag_keep_locals || !S_LOCAL_NAME (symbolP))))) | |
252b5132 RH |
258 | { |
259 | symbolP->sy_number = symbol_number++; | |
260 | ||
351aa9f6 KH |
261 | /* The + 1 after strlen account for the \0 at the end of |
262 | each string. */ | |
252b5132 RH |
263 | if (!S_IS_STABD (symbolP)) |
264 | { | |
351aa9f6 | 265 | /* Ordinary case. */ |
252b5132 RH |
266 | symbolP->sy_name_offset = string_byte_count; |
267 | string_byte_count += strlen (S_GET_NAME (symbolP)) + 1; | |
268 | } | |
351aa9f6 | 269 | else /* .Stabd case. */ |
252b5132 | 270 | symbolP->sy_name_offset = 0; |
8141c27d | 271 | symbolPP = &(symbolP->sy_next); |
252b5132 RH |
272 | } |
273 | else | |
274 | { | |
275 | if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP)) | |
ea1562b3 NC |
276 | as_bad (_("Local symbol %s never defined"), |
277 | S_GET_NAME (symbolP)); | |
252b5132 | 278 | |
351aa9f6 | 279 | /* Unhook it from the chain. */ |
252b5132 | 280 | *symbolPP = symbol_next (symbolP); |
ea1562b3 NC |
281 | } |
282 | } | |
252b5132 RH |
283 | |
284 | H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number); | |
285 | } | |
286 | ||
351aa9f6 | 287 | /* Find strings by crawling along symbol table chain. */ |
252b5132 RH |
288 | |
289 | void | |
ea1562b3 | 290 | obj_emit_strings (char **where) |
252b5132 RH |
291 | { |
292 | symbolS *symbolP; | |
293 | ||
44f2f9d2 AM |
294 | md_number_to_chars (*where, string_byte_count, 4); |
295 | *where += 4; | |
252b5132 RH |
296 | |
297 | for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) | |
ea1562b3 NC |
298 | if (S_GET_NAME (symbolP)) |
299 | append (where, S_GET_NAME (symbolP), | |
300 | (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1)); | |
252b5132 | 301 | } |
ea1562b3 NC |
302 | |
303 | const pseudo_typeS obj_pseudo_table[] = | |
304 | { | |
305 | {"line", obj_bout_line, 0}, /* Source code line number. */ | |
306 | ||
307 | /* COFF debugging directives. Currently ignored silently. */ | |
308 | {"def", s_ignore, 0}, | |
309 | {"dim", s_ignore, 0}, | |
310 | {"endef", s_ignore, 0}, | |
311 | {"ln", s_ignore, 0}, | |
312 | {"scl", s_ignore, 0}, | |
313 | {"size", s_ignore, 0}, | |
314 | {"tag", s_ignore, 0}, | |
315 | {"type", s_ignore, 0}, | |
316 | {"val", s_ignore, 0}, | |
317 | ||
318 | /* Other stuff we don't handle. */ | |
319 | {"ABORT", s_ignore, 0}, | |
320 | {"ident", s_ignore, 0}, | |
321 | ||
322 | {NULL, NULL, 0} | |
323 | }; | |
324 |