source: trunk/binutils/gas/config/obj-bout.c@ 2446

Last change on this file since 2446 was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 10.5 KB
Line 
1/* b.out object file format
2 Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1996, 2000, 2001, 2002
3 Free Software Foundation, Inc.
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
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
20 02111-1307, USA. */
21
22#include "as.h"
23#include "obstack.h"
24
25/* In: segT Out: N_TYPE bits */
26const short seg_N_TYPE[] =
27{
28 N_ABS,
29 N_TEXT,
30 N_DATA,
31 N_BSS,
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 */
39};
40
41const segT N_TYPE_seg[N_TYPE + 2] =
42{ /* N_TYPE == 0x1E = 32-2 */
43 SEG_UNKNOWN, /* N_UNDF == 0 */
44 SEG_GOOF,
45 SEG_ABSOLUTE, /* N_ABS == 2 */
46 SEG_GOOF,
47 SEG_TEXT, /* N_TEXT == 4 */
48 SEG_GOOF,
49 SEG_DATA, /* N_DATA == 6 */
50 SEG_GOOF,
51 SEG_BSS, /* N_BSS == 8 */
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,
56 SEG_REGISTER, /* dummy N_REGISTER for regs = 30 */
57 SEG_GOOF,
58};
59
60static void obj_bout_line PARAMS ((int));
61
62const pseudo_typeS obj_pseudo_table[] =
63{
64 {"line", obj_bout_line, 0}, /* Source code line number. */
65
66/* coff debugging directives. Currently ignored silently. */
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
81 {NULL, NULL, 0} /* End sentinel. */
82};
83
84/* Relocation. */
85
86/* Crawl along a fixS chain. Emit the segment's relocations. */
87
88void
89obj_emit_relocations (where, fixP, segment_address_in_file)
90 char **where;
91 fixS *fixP; /* Fixup chain for this segment. */
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);
108 *where += sizeof (struct relocation_info);
109 } /* if there's a symbol */
110 } /* for each fixup */
111}
112
113/* Aout file generation & utilities . */
114
115/* Convert a lvalue to machine dependent data. */
116
117void
118obj_header_append (where, headers)
119 char **where;
120 object_headers *headers;
121{
122 /* Always leave in host byte order. */
123
124 headers->header.a_talign = section_alignment[SEG_TEXT];
125
126 /* Force to at least 2. */
127 if (headers->header.a_talign < 2)
128 {
129 headers->header.a_talign = 2;
130 }
131
132 headers->header.a_dalign = section_alignment[SEG_DATA];
133 headers->header.a_balign = section_alignment[SEG_BSS];
134
135 headers->header.a_tload = 0;
136 headers->header.a_dload =
137 md_section_align (SEG_DATA, H_GET_TEXT_SIZE (headers));
138
139 headers->header.a_relaxable = linkrelax;
140
141#ifdef CROSS_COMPILE
142 md_number_to_chars (*where, headers->header.a_magic, sizeof (headers->header.a_magic));
143 *where += sizeof (headers->header.a_magic);
144 md_number_to_chars (*where, headers->header.a_text, sizeof (headers->header.a_text));
145 *where += sizeof (headers->header.a_text);
146 md_number_to_chars (*where, headers->header.a_data, sizeof (headers->header.a_data));
147 *where += sizeof (headers->header.a_data);
148 md_number_to_chars (*where, headers->header.a_bss, sizeof (headers->header.a_bss));
149 *where += sizeof (headers->header.a_bss);
150 md_number_to_chars (*where, headers->header.a_syms, sizeof (headers->header.a_syms));
151 *where += sizeof (headers->header.a_syms);
152 md_number_to_chars (*where, headers->header.a_entry, sizeof (headers->header.a_entry));
153 *where += sizeof (headers->header.a_entry);
154 md_number_to_chars (*where, headers->header.a_trsize, sizeof (headers->header.a_trsize));
155 *where += sizeof (headers->header.a_trsize);
156 md_number_to_chars (*where, headers->header.a_drsize, sizeof (headers->header.a_drsize));
157 *where += sizeof (headers->header.a_drsize);
158 md_number_to_chars (*where, headers->header.a_tload, sizeof (headers->header.a_tload));
159 *where += sizeof (headers->header.a_tload);
160 md_number_to_chars (*where, headers->header.a_dload, sizeof (headers->header.a_dload));
161 *where += sizeof (headers->header.a_dload);
162 md_number_to_chars (*where, headers->header.a_talign, sizeof (headers->header.a_talign));
163 *where += sizeof (headers->header.a_talign);
164 md_number_to_chars (*where, headers->header.a_dalign, sizeof (headers->header.a_dalign));
165 *where += sizeof (headers->header.a_dalign);
166 md_number_to_chars (*where, headers->header.a_balign, sizeof (headers->header.a_balign));
167 *where += sizeof (headers->header.a_balign);
168 md_number_to_chars (*where, headers->header.a_relaxable, sizeof (headers->header.a_relaxable));
169 *where += sizeof (headers->header.a_relaxable);
170#else /* ! CROSS_COMPILE */
171 append (where, (char *) &headers->header, sizeof (headers->header));
172#endif /* ! CROSS_COMPILE */
173}
174
175void
176obj_symbol_to_chars (where, symbolP)
177 char **where;
178 symbolS *symbolP;
179{
180 md_number_to_chars ((char *) &(S_GET_OFFSET (symbolP)),
181 S_GET_OFFSET (symbolP),
182 sizeof (S_GET_OFFSET (symbolP)));
183
184 md_number_to_chars ((char *) &(S_GET_DESC (symbolP)),
185 S_GET_DESC (symbolP),
186 sizeof (S_GET_DESC (symbolP)));
187
188 md_number_to_chars ((char *) &symbolP->sy_symbol.n_value,
189 S_GET_VALUE (symbolP),
190 sizeof (symbolP->sy_symbol.n_value));
191
192 append (where, (char *) &symbolP->sy_symbol, sizeof (obj_symbol_type));
193}
194
195void
196obj_emit_symbols (where, symbol_rootP)
197 char **where;
198 symbolS *symbol_rootP;
199{
200 symbolS *symbolP;
201
202 /* Emit all symbols left in the symbol chain. */
203 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
204 {
205 /* Used to save the offset of the name. It is used to point to
206 the string in memory but must be a file offset. */
207 char *temp;
208
209 temp = S_GET_NAME (symbolP);
210 S_SET_OFFSET (symbolP, symbolP->sy_name_offset);
211
212 /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */
213 if (!S_IS_DEBUG (symbolP) && !S_IS_DEFINED (symbolP))
214 S_SET_EXTERNAL (symbolP);
215
216 obj_symbol_to_chars (where, symbolP);
217 S_SET_NAME (symbolP, temp);
218 }
219}
220
221void
222obj_symbol_new_hook (symbolP)
223 symbolS *symbolP;
224{
225 S_SET_OTHER (symbolP, 0);
226 S_SET_DESC (symbolP, 0);
227}
228
229static void
230obj_bout_line (ignore)
231 int ignore ATTRIBUTE_UNUSED;
232{
233 /* Assume delimiter is part of expression. */
234 /* BSD4.2 as fails with delightful bug, so we are not being
235 incompatible here. */
236 new_logical_line ((char *) NULL, (int) (get_absolute_expression ()));
237 demand_empty_rest_of_line ();
238}
239
240void
241obj_read_begin_hook ()
242{
243}
244
245void
246obj_crawl_symbol_chain (headers)
247 object_headers *headers;
248{
249 symbolS **symbolPP;
250 symbolS *symbolP;
251 int symbol_number = 0;
252
253 tc_crawl_symbol_chain (headers);
254
255 symbolPP = &symbol_rootP; /* -> last symbol chain link. */
256 while ((symbolP = *symbolPP) != NULL)
257 {
258 if (flag_readonly_data_in_text && (S_GET_SEGMENT (symbolP) == SEG_DATA))
259 {
260 S_SET_SEGMENT (symbolP, SEG_TEXT);
261 } /* if pusing data into text */
262
263 resolve_symbol_value (symbolP);
264
265 /* Skip symbols which were equated to undefined or common
266 symbols. */
267 if (symbolP->sy_value.X_op == O_symbol
268 && (! S_IS_DEFINED (symbolP) || S_IS_COMMON (symbolP)))
269 {
270 *symbolPP = symbol_next (symbolP);
271 continue;
272 }
273
274 /* OK, here is how we decide which symbols go out into the
275 brave new symtab. Symbols that do are:
276
277 * symbols with no name (stabd's?)
278 * symbols with debug info in their N_TYPE
279
280 Symbols that don't are:
281 * symbols that are registers
282 * symbols with \1 as their 3rd character (numeric labels)
283 * "local labels" as defined by S_LOCAL_NAME(name)
284 if the -L switch was passed to gas.
285
286 All other symbols are output. We complain if a deleted
287 symbol was marked external. */
288
289 if (1
290 && !S_IS_REGISTER (symbolP)
291 && (!S_GET_NAME (symbolP)
292 || S_IS_DEBUG (symbolP)
293#ifdef TC_I960
294 /* FIXME-SOON this ifdef seems highly dubious to me. xoxorich. */
295 || !S_IS_DEFINED (symbolP)
296 || S_IS_EXTERNAL (symbolP)
297#endif /* TC_I960 */
298 || (S_GET_NAME (symbolP)[0] != '\001'
299 && (flag_keep_locals || !S_LOCAL_NAME (symbolP)))))
300 {
301 symbolP->sy_number = symbol_number++;
302
303 /* The + 1 after strlen account for the \0 at the end of
304 each string. */
305 if (!S_IS_STABD (symbolP))
306 {
307 /* Ordinary case. */
308 symbolP->sy_name_offset = string_byte_count;
309 string_byte_count += strlen (S_GET_NAME (symbolP)) + 1;
310 }
311 else /* .Stabd case. */
312 symbolP->sy_name_offset = 0;
313 symbolPP = &(symbolP->sy_next);
314 }
315 else
316 {
317 if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP))
318 {
319 as_bad (_("Local symbol %s never defined"),
320 S_GET_NAME (symbolP));
321 } /* Oops. */
322
323 /* Unhook it from the chain. */
324 *symbolPP = symbol_next (symbolP);
325 } /* if this symbol should be in the output */
326 } /* for each symbol */
327
328 H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number);
329}
330
331/* Find strings by crawling along symbol table chain. */
332
333void
334obj_emit_strings (where)
335 char **where;
336{
337 symbolS *symbolP;
338
339#ifdef CROSS_COMPILE
340 /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */
341 md_number_to_chars (*where, string_byte_count, sizeof (string_byte_count));
342 *where += sizeof (string_byte_count);
343#else /* CROSS_COMPILE */
344 append (where, (char *) &string_byte_count,
345 (unsigned long) sizeof (string_byte_count));
346#endif /* CROSS_COMPILE */
347
348 for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP))
349 {
350 if (S_GET_NAME (symbolP))
351 append (where, S_GET_NAME (symbolP),
352 (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1));
353 } /* Walk symbol chain. */
354}
Note: See TracBrowser for help on using the repository browser.