]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/obj-bout.c
* configure.in (AC_C_BIGENDIAN): Invoke.
[thirdparty/binutils-gdb.git] / gas / config / obj-bout.c
CommitLineData
252b5132 1/* b.out object file format
44f2f9d2
AM
2 Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002,
3 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
KH
24
25/* In: segT Out: N_TYPE bits */
26const short seg_N_TYPE[] =
252b5132
RH
27{
28 N_ABS,
29 N_TEXT,
30 N_DATA,
31 N_BSS,
351aa9f6
KH
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
41const 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,
351aa9f6 56 SEG_REGISTER, /* dummy N_REGISTER for regs = 30 */
252b5132
RH
57 SEG_GOOF,
58};
59
60static void obj_bout_line PARAMS ((int));
61
62const pseudo_typeS obj_pseudo_table[] =
63{
351aa9f6 64 {"line", obj_bout_line, 0}, /* Source code line number. */
252b5132 65
351aa9f6 66/* coff debugging directives. Currently ignored silently. */
252b5132
RH
67 {"def", s_ignore, 0},
68 {"dim", s_ignore, 0},
69 {"endef", s_ignore, 0},
70 {"ln", s_ignore, 0},
71 {"scl", s_ignore, 0},
72 {"size", s_ignore, 0},
73 {"tag", s_ignore, 0},
74 {"type", s_ignore, 0},
75 {"val", s_ignore, 0},
76
77/* other stuff we don't handle */
78 {"ABORT", s_ignore, 0},
79 {"ident", s_ignore, 0},
80
70658493 81 {NULL, NULL, 0} /* End sentinel. */
351aa9f6
KH
82};
83
84/* Relocation. */
252b5132 85
351aa9f6 86/* Crawl along a fixS chain. Emit the segment's relocations. */
252b5132 87
252b5132
RH
88void
89obj_emit_relocations (where, fixP, segment_address_in_file)
90 char **where;
351aa9f6 91 fixS *fixP; /* Fixup chain for this segment. */
252b5132
RH
92 relax_addressT segment_address_in_file;
93{
94 for (; fixP; fixP = fixP->fx_next)
95 {
96 if (fixP->fx_done == 0
97 || fixP->fx_r_type != NO_RELOC)
98 {
99 symbolS *sym;
100
101 sym = fixP->fx_addsy;
102 while (sym->sy_value.X_op == O_symbol
103 && (! S_IS_DEFINED (sym) || S_IS_COMMON (sym)))
104 sym = sym->sy_value.X_add_symbol;
105 fixP->fx_addsy = sym;
106
107 tc_bout_fix_to_chars (*where, fixP, segment_address_in_file);
44f2f9d2 108 *where += md_reloc_size;
351aa9f6
KH
109 } /* if there's a symbol */
110 } /* for each fixup */
111}
252b5132 112
dcd619be 113/* Aout file generation & utilities . */
252b5132 114
351aa9f6 115/* Convert a lvalue to machine dependent data. */
252b5132 116
252b5132
RH
117void
118obj_header_append (where, headers)
119 char **where;
120 object_headers *headers;
121{
351aa9f6 122 /* Always leave in host byte order. */
44f2f9d2 123 char *p;
252b5132
RH
124
125 headers->header.a_talign = section_alignment[SEG_TEXT];
126
351aa9f6 127 /* Force to at least 2. */
252b5132
RH
128 if (headers->header.a_talign < 2)
129 {
130 headers->header.a_talign = 2;
351aa9f6 131 }
252b5132
RH
132
133 headers->header.a_dalign = section_alignment[SEG_DATA];
134 headers->header.a_balign = section_alignment[SEG_BSS];
135
136 headers->header.a_tload = 0;
351aa9f6
KH
137 headers->header.a_dload =
138 md_section_align (SEG_DATA, H_GET_TEXT_SIZE (headers));
252b5132
RH
139
140 headers->header.a_relaxable = linkrelax;
141
44f2f9d2
AM
142 p = *where;
143 host_number_to_chars (p, headers->header.a_magic, 4);
144 p += 4;
145 host_number_to_chars (p, headers->header.a_text, 4);
146 p += 4;
147 host_number_to_chars (p, headers->header.a_data, 4);
148 p += 4;
149 host_number_to_chars (p, headers->header.a_bss, 4);
150 p += 4;
151 host_number_to_chars (p, headers->header.a_syms, 4);
152 p += 4;
153 host_number_to_chars (p, headers->header.a_entry, 4);
154 p += 4;
155 host_number_to_chars (p, headers->header.a_trsize, 4);
156 p += 4;
157 host_number_to_chars (p, headers->header.a_drsize, 4);
158 p += 4;
159 host_number_to_chars (p, headers->header.a_tload, 4);
160 p += 4;
161 host_number_to_chars (p, headers->header.a_dload, 4);
162 p += 4;
163 *p++ = headers->header.a_talign;
164 *p++ = headers->header.a_dalign;
165 *p++ = headers->header.a_balign;
166 *p++ = headers->header.a_relaxable;
167 *where = p;
351aa9f6 168}
252b5132
RH
169
170void
171obj_symbol_to_chars (where, symbolP)
172 char **where;
173 symbolS *symbolP;
174{
44f2f9d2
AM
175 char *p = *where;
176 host_number_to_chars (p, S_GET_OFFSET (symbolP), 4);
177 p += 4;
178 /* Can't use S_GET_TYPE here as it masks. */
179 *p++ = symbolP->sy_symbol.n_type;
180 *p++ = symbolP->sy_symbol.n_other;
181 host_number_to_chars (p, S_GET_DESC (symbolP), 2);
182 p += 2;
183 host_number_to_chars (p, S_GET_VALUE (symbolP), 4);
184 p += 4;
185 *where = p;
351aa9f6 186}
252b5132
RH
187
188void
189obj_emit_symbols (where, symbol_rootP)
190 char **where;
191 symbolS *symbol_rootP;
192{
193 symbolS *symbolP;
194
351aa9f6 195 /* Emit all symbols left in the symbol chain. */
252b5132
RH
196 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
197 {
351aa9f6
KH
198 /* Used to save the offset of the name. It is used to point to
199 the string in memory but must be a file offset. */
252b5132
RH
200 char *temp;
201
202 temp = S_GET_NAME (symbolP);
203 S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
204
351aa9f6 205 /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */
252b5132
RH
206 if (!S_IS_DEBUG (symbolP) && !S_IS_DEFINED (symbolP))
207 S_SET_EXTERNAL (symbolP);
208
209 obj_symbol_to_chars (where, symbolP);
210 S_SET_NAME (symbolP, temp);
211 }
351aa9f6 212}
252b5132
RH
213
214void
215obj_symbol_new_hook (symbolP)
216 symbolS *symbolP;
217{
218 S_SET_OTHER (symbolP, 0);
219 S_SET_DESC (symbolP, 0);
220}
221
222static void
223obj_bout_line (ignore)
17fc154e 224 int ignore ATTRIBUTE_UNUSED;
252b5132 225{
351aa9f6
KH
226 /* Assume delimiter is part of expression. */
227 /* BSD4.2 as fails with delightful bug, so we are not being
228 incompatible here. */
252b5132
RH
229 new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
230 demand_empty_rest_of_line ();
351aa9f6 231}
252b5132
RH
232
233void
234obj_read_begin_hook ()
235{
236}
237
238void
239obj_crawl_symbol_chain (headers)
240 object_headers *headers;
241{
242 symbolS **symbolPP;
243 symbolS *symbolP;
244 int symbol_number = 0;
245
246 tc_crawl_symbol_chain (headers);
247
351aa9f6 248 symbolPP = &symbol_rootP; /* -> last symbol chain link. */
252b5132
RH
249 while ((symbolP = *symbolPP) != NULL)
250 {
251 if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_DATA))
252 {
253 S_SET_SEGMENT (symbolP, SEG_TEXT);
33b7f697 254 } /* if pushing data into text */
252b5132 255
6386f3a7 256 resolve_symbol_value (symbolP);
252b5132
RH
257
258 /* Skip symbols which were equated to undefined or common
259 symbols. */
260 if (symbolP->sy_value.X_op == O_symbol
261 && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP)))
262 {
263 *symbolPP = symbol_next (symbolP);
264 continue;
265 }
266
267 /* OK, here is how we decide which symbols go out into the
268 brave new symtab. Symbols that do are:
351aa9f6 269
252b5132
RH
270 * symbols with no name (stabd's?)
271 * symbols with debug info in their N_TYPE
351aa9f6 272
252b5132
RH
273 Symbols that don't are:
274 * symbols that are registers
275 * symbols with \1 as their 3rd character (numeric labels)
276 * "local labels" as defined by S_LOCAL_NAME(name)
277 if the -L switch was passed to gas.
252b5132 278
351aa9f6
KH
279 All other symbols are output. We complain if a deleted
280 symbol was marked external. */
252b5132
RH
281
282 if (1
283 && !S_IS_REGISTER (symbolP)
284 && (!S_GET_NAME (symbolP)
285 || S_IS_DEBUG (symbolP)
286#ifdef TC_I960
351aa9f6 287 /* FIXME-SOON this ifdef seems highly dubious to me. xoxorich. */
252b5132
RH
288 || !S_IS_DEFINED (symbolP)
289 || S_IS_EXTERNAL (symbolP)
290#endif /* TC_I960 */
351aa9f6
KH
291 || (S_GET_NAME (symbolP)[0] != '\001'
292 && (flag_keep_locals || !S_LOCAL_NAME (symbolP)))))
252b5132
RH
293 {
294 symbolP->sy_number = symbol_number++;
295
351aa9f6
KH
296 /* The + 1 after strlen account for the \0 at the end of
297 each string. */
252b5132
RH
298 if (!S_IS_STABD (symbolP))
299 {
351aa9f6 300 /* Ordinary case. */
252b5132
RH
301 symbolP->sy_name_offset = string_byte_count;
302 string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
303 }
351aa9f6 304 else /* .Stabd case. */
252b5132 305 symbolP->sy_name_offset = 0;
8141c27d 306 symbolPP = &(symbolP->sy_next);
252b5132
RH
307 }
308 else
309 {
310 if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))
311 {
351aa9f6
KH
312 as_bad (_("Local symbol %s never defined"),
313 S_GET_NAME (symbolP));
314 } /* Oops. */
252b5132 315
351aa9f6 316 /* Unhook it from the chain. */
252b5132 317 *symbolPP = symbol_next (symbolP);
351aa9f6
KH
318 } /* if this symbol should be in the output */
319 } /* for each symbol */
252b5132
RH
320
321 H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
322}
323
351aa9f6 324/* Find strings by crawling along symbol table chain. */
252b5132
RH
325
326void
327obj_emit_strings (where)
328 char **where;
329{
330 symbolS *symbolP;
331
44f2f9d2
AM
332 md_number_to_chars (*where, string_byte_count, 4);
333 *where += 4;
252b5132
RH
334
335 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
336 {
337 if (S_GET_NAME (symbolP))
351aa9f6
KH
338 append (where, S_GET_NAME (symbolP),
339 (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1));
340 } /* Walk symbol chain. */
252b5132 341}