Commit | Line | Data |
---|---|---|
fecd2382 | 1 | /* b.out object file format |
01170860 | 2 | Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc. |
355afbcd | 3 | |
a39116f1 | 4 | This file is part of GAS, the GNU Assembler. |
355afbcd | 5 | |
a39116f1 RP |
6 | GAS is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as | |
8 | published by the Free Software Foundation; either version 2, | |
9 | or (at your option) any later version. | |
355afbcd | 10 | |
a39116f1 RP |
11 | GAS is distributed in the hope that it will be useful, but |
12 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | |
14 | the GNU General Public License for more details. | |
355afbcd | 15 | |
a39116f1 RP |
16 | You should have received a copy of the GNU General Public |
17 | License along with GAS; see the file COPYING. If not, write | |
18 | to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
fecd2382 | 19 | |
fecd2382 RP |
20 | #include "as.h" |
21 | #include "obstack.h" | |
86c094f2 | 22 | #include "aout/stab_gnu.h" |
355afbcd KR |
23 | const short /* in: segT out: N_TYPE bits */ |
24 | seg_N_TYPE[] = | |
25 | { | |
26 | N_ABS, | |
27 | N_TEXT, | |
28 | N_DATA, | |
29 | N_BSS, | |
30 | N_UNDF, /* unknown */ | |
31 | N_UNDF, /* absent */ | |
32 | N_UNDF, /* pass1 */ | |
33 | N_UNDF, /* error */ | |
34 | N_UNDF, /* bignum/flonum */ | |
35 | N_UNDF, /* difference */ | |
36 | N_REGISTER, /* register */ | |
37 | }; | |
38 | ||
39 | const segT N_TYPE_seg[N_TYPE + 2] = | |
40 | { /* N_TYPE == 0x1E = 32-2 */ | |
41 | SEG_UNKNOWN, /* N_UNDF == 0 */ | |
42 | SEG_GOOF, | |
43 | SEG_ABSOLUTE, /* N_ABS == 2 */ | |
44 | SEG_GOOF, | |
45 | SEG_TEXT, /* N_TEXT == 4 */ | |
46 | SEG_GOOF, | |
47 | SEG_DATA, /* N_DATA == 6 */ | |
48 | SEG_GOOF, | |
49 | SEG_BSS, /* N_BSS == 8 */ | |
50 | SEG_GOOF, | |
51 | SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, | |
52 | SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, | |
53 | SEG_GOOF, SEG_GOOF, SEG_GOOF, SEG_GOOF, | |
54 | SEG_REGISTER, /* dummy N_REGISTER for regs = 30 */ | |
55 | SEG_GOOF, | |
fecd2382 RP |
56 | }; |
57 | ||
a87b3269 | 58 | #if __STDC__ == 1 |
355afbcd KR |
59 | static void obj_bout_stab (int what); |
60 | static void obj_bout_line (void); | |
61 | static void obj_bout_desc (void); | |
a87b3269 | 62 | #else /* not __STDC__ */ |
355afbcd KR |
63 | static void obj_bout_desc (); |
64 | static void obj_bout_stab (); | |
65 | static void obj_bout_line (); | |
a87b3269 | 66 | #endif /* not __STDC__ */ |
fecd2382 | 67 | |
355afbcd KR |
68 | const pseudo_typeS obj_pseudo_table[] = |
69 | { | |
70 | /* stabs (aka a.out aka b.out directives for debug symbols) */ | |
71 | {"desc", obj_bout_desc, 0}, /* def */ | |
72 | {"line", obj_bout_line, 0}, /* source code line number */ | |
73 | {"stabd", obj_bout_stab, 'd'},/* stabs */ | |
74 | {"stabn", obj_bout_stab, 'n'},/* stabs */ | |
75 | {"stabs", obj_bout_stab, 's'},/* stabs */ | |
76 | ||
77 | /* coff debugging directives. Currently ignored silently */ | |
78 | {"def", s_ignore, 0}, | |
79 | {"dim", s_ignore, 0}, | |
80 | {"endef", s_ignore, 0}, | |
81 | {"ln", s_ignore, 0}, | |
82 | {"scl", s_ignore, 0}, | |
83 | {"size", s_ignore, 0}, | |
84 | {"tag", s_ignore, 0}, | |
85 | {"type", s_ignore, 0}, | |
86 | {"val", s_ignore, 0}, | |
87 | ||
88 | /* other stuff we don't handle */ | |
89 | {"ABORT", s_ignore, 0}, | |
90 | {"ident", s_ignore, 0}, | |
91 | ||
92 | {NULL} /* end sentinel */ | |
93 | }; /* obj_pseudo_table */ | |
fecd2382 RP |
94 | |
95 | /* Relocation. */ | |
96 | ||
fecd2382 RP |
97 | /* |
98 | * emit_relocations() | |
99 | * | |
100 | * Crawl along a fixS chain. Emit the segment's relocations. | |
101 | */ | |
355afbcd KR |
102 | void |
103 | obj_emit_relocations (where, fixP, segment_address_in_file) | |
104 | char **where; | |
105 | fixS *fixP; /* Fixup chain for this segment. */ | |
106 | relax_addressT segment_address_in_file; | |
fecd2382 | 107 | { |
355afbcd KR |
108 | for (; fixP; fixP = fixP->fx_next) |
109 | { | |
110 | if (fixP->fx_addsy != NULL | |
111 | || fixP->fx_r_type != NO_RELOC) | |
112 | { | |
113 | tc_bout_fix_to_chars (*where, fixP, segment_address_in_file); | |
114 | *where += sizeof (struct relocation_info); | |
115 | } /* if there's a symbol */ | |
116 | } /* for each fixup */ | |
117 | ||
118 | } /* emit_relocations() */ | |
fecd2382 RP |
119 | |
120 | /* Aout file generation & utilities */ | |
121 | ||
122 | /* Convert a lvalue to machine dependent data */ | |
355afbcd KR |
123 | void |
124 | obj_header_append (where, headers) | |
125 | char **where; | |
126 | object_headers *headers; | |
fecd2382 | 127 | { |
355afbcd KR |
128 | /* Always leave in host byte order */ |
129 | ||
130 | headers->header.a_talign = section_alignment[SEG_TEXT]; | |
131 | ||
132 | if (headers->header.a_talign < 2) | |
133 | { | |
134 | headers->header.a_talign = 2; | |
135 | } /* force to at least 2 */ | |
136 | ||
137 | headers->header.a_dalign = section_alignment[SEG_DATA]; | |
138 | headers->header.a_balign = section_alignment[SEG_BSS]; | |
139 | ||
140 | headers->header.a_tload = 0; | |
141 | headers->header.a_dload = md_section_align (SEG_DATA, H_GET_TEXT_SIZE (headers)); | |
142 | ||
143 | headers->header.a_relaxable = linkrelax; | |
462088b8 | 144 | |
8ae35e59 | 145 | #ifdef CROSS_COMPILE |
355afbcd KR |
146 | md_number_to_chars (*where, headers->header.a_magic, sizeof (headers->header.a_magic)); |
147 | *where += sizeof (headers->header.a_magic); | |
148 | md_number_to_chars (*where, headers->header.a_text, sizeof (headers->header.a_text)); | |
149 | *where += sizeof (headers->header.a_text); | |
150 | md_number_to_chars (*where, headers->header.a_data, sizeof (headers->header.a_data)); | |
151 | *where += sizeof (headers->header.a_data); | |
152 | md_number_to_chars (*where, headers->header.a_bss, sizeof (headers->header.a_bss)); | |
153 | *where += sizeof (headers->header.a_bss); | |
154 | md_number_to_chars (*where, headers->header.a_syms, sizeof (headers->header.a_syms)); | |
155 | *where += sizeof (headers->header.a_syms); | |
156 | md_number_to_chars (*where, headers->header.a_entry, sizeof (headers->header.a_entry)); | |
157 | *where += sizeof (headers->header.a_entry); | |
158 | md_number_to_chars (*where, headers->header.a_trsize, sizeof (headers->header.a_trsize)); | |
159 | *where += sizeof (headers->header.a_trsize); | |
160 | md_number_to_chars (*where, headers->header.a_drsize, sizeof (headers->header.a_drsize)); | |
161 | *where += sizeof (headers->header.a_drsize); | |
162 | md_number_to_chars (*where, headers->header.a_tload, sizeof (headers->header.a_tload)); | |
163 | *where += sizeof (headers->header.a_tload); | |
164 | md_number_to_chars (*where, headers->header.a_dload, sizeof (headers->header.a_dload)); | |
165 | *where += sizeof (headers->header.a_dload); | |
166 | md_number_to_chars (*where, headers->header.a_talign, sizeof (headers->header.a_talign)); | |
167 | *where += sizeof (headers->header.a_talign); | |
168 | md_number_to_chars (*where, headers->header.a_dalign, sizeof (headers->header.a_dalign)); | |
169 | *where += sizeof (headers->header.a_dalign); | |
170 | md_number_to_chars (*where, headers->header.a_balign, sizeof (headers->header.a_balign)); | |
171 | *where += sizeof (headers->header.a_balign); | |
172 | md_number_to_chars (*where, headers->header.a_relaxable, sizeof (headers->header.a_relaxable)); | |
173 | *where += sizeof (headers->header.a_relaxable); | |
8ae35e59 | 174 | #else /* ! CROSS_COMPILE */ |
355afbcd | 175 | append (where, (char *) &headers->header, sizeof (headers->header)); |
8ae35e59 | 176 | #endif /* ! CROSS_COMPILE */ |
355afbcd | 177 | } /* a_header_append() */ |
fecd2382 | 178 | |
355afbcd KR |
179 | void |
180 | obj_symbol_to_chars (where, symbolP) | |
181 | char **where; | |
182 | symbolS *symbolP; | |
fecd2382 | 183 | { |
355afbcd KR |
184 | md_number_to_chars ((char *) &(S_GET_OFFSET (symbolP)), S_GET_OFFSET (symbolP), sizeof (S_GET_OFFSET (symbolP))); |
185 | md_number_to_chars ((char *) &(S_GET_DESC (symbolP)), S_GET_DESC (symbolP), sizeof (S_GET_DESC (symbolP))); | |
186 | md_number_to_chars ((char *) &(S_GET_VALUE (symbolP)), S_GET_VALUE (symbolP), sizeof (S_GET_VALUE (symbolP))); | |
8ae35e59 | 187 | |
355afbcd KR |
188 | append (where, (char *) &symbolP->sy_symbol, sizeof (obj_symbol_type)); |
189 | } /* obj_symbol_to_chars() */ | |
fecd2382 | 190 | |
355afbcd KR |
191 | void |
192 | obj_emit_symbols (where, symbol_rootP) | |
193 | char **where; | |
194 | symbolS *symbol_rootP; | |
fecd2382 | 195 | { |
355afbcd KR |
196 | symbolS *symbolP; |
197 | ||
198 | /* | |
a39116f1 RP |
199 | * Emit all symbols left in the symbol chain. |
200 | */ | |
355afbcd KR |
201 | for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) |
202 | { | |
203 | /* Used to save the offset of the name. It is used to point | |
a39116f1 | 204 | to the string in memory but must be a file offset. */ |
355afbcd KR |
205 | char *temp; |
206 | ||
207 | temp = S_GET_NAME (symbolP); | |
208 | S_SET_OFFSET (symbolP, symbolP->sy_name_offset); | |
209 | ||
210 | /* Any symbol still undefined and is not a dbg symbol is made N_EXT. */ | |
211 | if (!S_IS_DEBUG (symbolP) && !S_IS_DEFINED (symbolP)) | |
212 | S_SET_EXTERNAL (symbolP); | |
fecd2382 | 213 | |
355afbcd KR |
214 | obj_symbol_to_chars (where, symbolP); |
215 | S_SET_NAME (symbolP, temp); | |
216 | } | |
217 | } /* emit_symbols() */ | |
218 | ||
219 | void | |
220 | obj_symbol_new_hook (symbolP) | |
221 | symbolS *symbolP; | |
222 | { | |
223 | S_SET_OTHER (symbolP, 0); | |
224 | S_SET_DESC (symbolP, 0); | |
225 | return; | |
226 | } /* obj_symbol_new_hook() */ | |
227 | ||
228 | static void | |
229 | obj_bout_line () | |
fecd2382 | 230 | { |
355afbcd KR |
231 | /* Assume delimiter is part of expression. */ |
232 | /* BSD4.2 as fails with delightful bug, so we */ | |
233 | /* are not being incompatible here. */ | |
234 | new_logical_line ((char *) NULL, (int) (get_absolute_expression ())); | |
235 | demand_empty_rest_of_line (); | |
236 | } /* obj_bout_line() */ | |
fecd2382 RP |
237 | |
238 | /* | |
239 | * stab() | |
240 | * | |
241 | * Handle .stabX directives, which used to be open-coded. | |
242 | * So much creeping featurism overloaded the semantics that we decided | |
243 | * to put all .stabX thinking in one place. Here. | |
244 | * | |
245 | * We try to make any .stabX directive legal. Other people's AS will often | |
246 | * do assembly-time consistency checks: eg assigning meaning to n_type bits | |
247 | * and "protecting" you from setting them to certain values. (They also zero | |
248 | * certain bits before emitting symbols. Tut tut.) | |
249 | * | |
250 | * If an expression is not absolute we either gripe or use the relocation | |
251 | * information. Other people's assemblers silently forget information they | |
252 | * don't need and invent information they need that you didn't supply. | |
253 | * | |
254 | * .stabX directives always make a symbol table entry. It may be junk if | |
255 | * the rest of your .stabX directive is malformed. | |
256 | */ | |
355afbcd KR |
257 | static void |
258 | obj_bout_stab (what) | |
259 | int what; | |
fecd2382 | 260 | { |
355afbcd KR |
261 | register symbolS *symbolP = 0; |
262 | register char *string; | |
263 | int saved_type = 0; | |
264 | int length; | |
265 | int goof; /* TRUE if we have aborted. */ | |
266 | long longint; | |
267 | ||
268 | /* | |
a39116f1 RP |
269 | * Enter with input_line_pointer pointing past .stabX and any following |
270 | * whitespace. | |
271 | */ | |
355afbcd KR |
272 | goof = 0; /* JF who forgot this?? */ |
273 | if (what == 's') | |
274 | { | |
275 | string = demand_copy_C_string (&length); | |
276 | SKIP_WHITESPACE (); | |
277 | if (*input_line_pointer == ',') | |
278 | input_line_pointer++; | |
279 | else | |
280 | { | |
281 | as_bad ("I need a comma after symbol's name"); | |
282 | goof = 1; | |
283 | } | |
284 | } | |
285 | else | |
286 | string = ""; | |
287 | ||
288 | /* | |
a39116f1 RP |
289 | * Input_line_pointer->after ','. String->symbol name. |
290 | */ | |
355afbcd KR |
291 | if (!goof) |
292 | { | |
293 | symbolP = symbol_new (string, | |
294 | SEG_UNKNOWN, | |
295 | 0, | |
296 | (struct frag *) 0); | |
297 | switch (what) | |
298 | { | |
299 | case 'd': | |
300 | S_SET_NAME (symbolP, NULL); /* .stabd feature. */ | |
301 | S_SET_VALUE (symbolP, obstack_next_free (&frags) - | |
302 | frag_now->fr_literal); | |
303 | symbolP->sy_frag = frag_now; | |
304 | break; | |
305 | ||
306 | case 'n': | |
307 | symbolP->sy_frag = &zero_address_frag; | |
308 | break; | |
309 | ||
310 | case 's': | |
311 | symbolP->sy_frag = &zero_address_frag; | |
312 | break; | |
313 | ||
314 | default: | |
315 | BAD_CASE (what); | |
316 | break; | |
fecd2382 | 317 | } |
355afbcd KR |
318 | if (get_absolute_expression_and_terminator (&longint) == ',') |
319 | symbolP->sy_symbol.n_type = saved_type = longint; | |
320 | else | |
321 | { | |
322 | as_bad ("I want a comma after the n_type expression"); | |
323 | goof = 1; | |
324 | input_line_pointer--; /* Backup over a non-',' char. */ | |
fecd2382 | 325 | } |
355afbcd KR |
326 | } |
327 | if (!goof) | |
328 | { | |
329 | if (get_absolute_expression_and_terminator (&longint) == ',') | |
330 | S_SET_OTHER (symbolP, longint); | |
331 | else | |
332 | { | |
333 | as_bad ("I want a comma after the n_other expression"); | |
334 | goof = 1; | |
335 | input_line_pointer--; /* Backup over a non-',' char. */ | |
fecd2382 | 336 | } |
355afbcd KR |
337 | } |
338 | if (!goof) | |
339 | { | |
340 | S_SET_DESC (symbolP, get_absolute_expression ()); | |
341 | if (what == 's' || what == 'n') | |
a39116f1 | 342 | { |
355afbcd KR |
343 | if (*input_line_pointer != ',') |
344 | { | |
345 | as_bad ("I want a comma after the n_desc expression"); | |
346 | goof = 1; | |
347 | } | |
348 | else | |
349 | { | |
350 | input_line_pointer++; | |
351 | } | |
a39116f1 | 352 | } |
355afbcd KR |
353 | } |
354 | if ((!goof) && (what == 's' || what == 'n')) | |
355 | { | |
356 | pseudo_set (symbolP); | |
357 | symbolP->sy_symbol.n_type = saved_type; | |
358 | } | |
359 | #ifndef NO_LISTING | |
360 | { | |
361 | extern int listing; | |
362 | ||
363 | if (listing && !goof) | |
364 | { | |
365 | if (symbolP->sy_symbol.n_type == N_SLINE) | |
366 | { | |
367 | ||
368 | listing_source_line (symbolP->sy_symbol.n_desc); | |
369 | } | |
370 | else if (symbolP->sy_symbol.n_type == N_SO | |
371 | || symbolP->sy_symbol.n_type == N_SOL) | |
372 | { | |
373 | listing_source_file (string); | |
374 | } | |
375 | } | |
376 | } | |
377 | ||
378 | #endif | |
379 | ||
380 | if (goof) | |
381 | ignore_rest_of_line (); | |
382 | else | |
383 | demand_empty_rest_of_line (); | |
384 | } /* obj_bout_stab() */ | |
385 | ||
386 | static void | |
387 | obj_bout_desc () | |
388 | { | |
389 | register char *name; | |
390 | register char c; | |
391 | register char *p; | |
392 | register symbolS *symbolP; | |
393 | register int temp; | |
394 | ||
395 | /* | |
fecd2382 RP |
396 | * Frob invented at RMS' request. Set the n_desc of a symbol. |
397 | */ | |
355afbcd KR |
398 | name = input_line_pointer; |
399 | c = get_symbol_end (); | |
400 | p = input_line_pointer; | |
401 | *p = c; | |
402 | SKIP_WHITESPACE (); | |
403 | if (*input_line_pointer != ',') | |
404 | { | |
405 | *p = 0; | |
406 | as_bad ("Expected comma after name \"%s\"", name); | |
407 | *p = c; | |
408 | ignore_rest_of_line (); | |
409 | } | |
410 | else | |
411 | { | |
412 | input_line_pointer++; | |
413 | temp = get_absolute_expression (); | |
414 | *p = 0; | |
415 | symbolP = symbol_find_or_make (name); | |
416 | *p = c; | |
417 | S_SET_DESC (symbolP, temp); | |
418 | } | |
419 | demand_empty_rest_of_line (); | |
420 | } /* obj_bout_desc() */ | |
fecd2382 | 421 | |
355afbcd KR |
422 | void |
423 | obj_read_begin_hook () | |
424 | { | |
425 | return; | |
426 | } /* obj_read_begin_hook() */ | |
fecd2382 | 427 | |
355afbcd KR |
428 | void |
429 | obj_crawl_symbol_chain (headers) | |
430 | object_headers *headers; | |
fecd2382 | 431 | { |
355afbcd KR |
432 | symbolS **symbolPP; |
433 | symbolS *symbolP; | |
434 | int symbol_number = 0; | |
435 | ||
436 | /* JF deal with forward references first... */ | |
437 | for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) | |
438 | { | |
439 | if (symbolP->sy_forward) | |
440 | { | |
441 | S_SET_VALUE (symbolP, S_GET_VALUE (symbolP) | |
442 | + S_GET_VALUE (symbolP->sy_forward) | |
443 | + symbolP->sy_forward->sy_frag->fr_address); | |
444 | ||
445 | symbolP->sy_forward = 0; | |
446 | } /* if it has a forward reference */ | |
447 | } /* walk the symbol chain */ | |
448 | ||
449 | tc_crawl_symbol_chain (headers); | |
450 | ||
451 | symbolPP = &symbol_rootP; /*->last symbol chain link. */ | |
452 | while ((symbolP = *symbolPP) != NULL) | |
453 | { | |
454 | if (flagseen['R'] && (S_GET_SEGMENT (symbolP) == SEG_DATA)) | |
455 | { | |
456 | S_SET_SEGMENT (symbolP, SEG_TEXT); | |
457 | } /* if pusing data into text */ | |
458 | ||
459 | S_SET_VALUE (symbolP, S_GET_VALUE (symbolP) + symbolP->sy_frag->fr_address); | |
460 | ||
461 | /* OK, here is how we decide which symbols go out into the | |
fecd2382 | 462 | brave new symtab. Symbols that do are: |
355afbcd | 463 | |
fecd2382 RP |
464 | * symbols with no name (stabd's?) |
465 | * symbols with debug info in their N_TYPE | |
355afbcd | 466 | |
fecd2382 RP |
467 | Symbols that don't are: |
468 | * symbols that are registers | |
469 | * symbols with \1 as their 3rd character (numeric labels) | |
470 | * "local labels" as defined by S_LOCAL_NAME(name) | |
471 | if the -L switch was passed to gas. | |
355afbcd | 472 | |
fecd2382 RP |
473 | All other symbols are output. We complain if a deleted |
474 | symbol was marked external. */ | |
355afbcd KR |
475 | |
476 | ||
477 | if (1 | |
478 | && !S_IS_REGISTER (symbolP) | |
479 | && (!S_GET_NAME (symbolP) | |
480 | || S_IS_DEBUG (symbolP) | |
fecd2382 | 481 | #ifdef TC_I960 |
355afbcd KR |
482 | /* FIXME-SOON this ifdef seems highly dubious to me. xoxorich. */ |
483 | || !S_IS_DEFINED (symbolP) | |
484 | || S_IS_EXTERNAL (symbolP) | |
fecd2382 | 485 | #endif /* TC_I960 */ |
355afbcd KR |
486 | || (S_GET_NAME (symbolP)[0] != '\001' && (flagseen['L'] || !S_LOCAL_NAME (symbolP))))) |
487 | { | |
488 | symbolP->sy_number = symbol_number++; | |
489 | ||
490 | /* The + 1 after strlen account for the \0 at the | |
fecd2382 | 491 | end of each string */ |
355afbcd KR |
492 | if (!S_IS_STABD (symbolP)) |
493 | { | |
494 | /* Ordinary case. */ | |
495 | symbolP->sy_name_offset = string_byte_count; | |
496 | string_byte_count += strlen (S_GET_NAME (symbolP)) + 1; | |
497 | } | |
498 | else /* .Stabd case. */ | |
499 | symbolP->sy_name_offset = 0; | |
500 | symbolPP = &(symbol_next (symbolP)); | |
501 | } | |
502 | else | |
503 | { | |
504 | if (S_IS_EXTERNAL (symbolP) || !S_IS_DEFINED (symbolP)) | |
505 | { | |
506 | as_bad ("Local symbol %s never defined", S_GET_NAME (symbolP)); | |
507 | } /* oops. */ | |
508 | ||
509 | /* Unhook it from the chain */ | |
510 | *symbolPP = symbol_next (symbolP); | |
511 | } /* if this symbol should be in the output */ | |
512 | } /* for each symbol */ | |
513 | ||
514 | H_SET_SYMBOL_TABLE_SIZE (headers, symbol_number); | |
515 | ||
516 | return; | |
517 | } /* obj_crawl_symbol_chain() */ | |
fecd2382 RP |
518 | |
519 | /* | |
520 | * Find strings by crawling along symbol table chain. | |
521 | */ | |
522 | ||
355afbcd KR |
523 | void |
524 | obj_emit_strings (where) | |
525 | char **where; | |
fecd2382 | 526 | { |
355afbcd KR |
527 | symbolS *symbolP; |
528 | ||
3cc6716d | 529 | #ifdef CROSS_COMPILE |
355afbcd KR |
530 | /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */ |
531 | md_number_to_chars (*where, string_byte_count, sizeof (string_byte_count)); | |
532 | *where += sizeof (string_byte_count); | |
3cc6716d | 533 | #else /* CROSS_COMPILE */ |
355afbcd | 534 | append (where, (char *) &string_byte_count, (unsigned long) sizeof (string_byte_count)); |
3cc6716d | 535 | #endif /* CROSS_COMPILE */ |
355afbcd KR |
536 | |
537 | for (symbolP = symbol_rootP; symbolP; symbolP = symbol_next (symbolP)) | |
538 | { | |
539 | if (S_GET_NAME (symbolP)) | |
540 | append (where, S_GET_NAME (symbolP), (unsigned long) (strlen (S_GET_NAME (symbolP)) + 1)); | |
541 | } /* walk symbol chain */ | |
542 | ||
543 | return; | |
544 | } /* obj_emit_strings() */ | |
fecd2382 RP |
545 | |
546 | /* | |
547 | * Local Variables: | |
548 | * comment-column: 0 | |
549 | * fill-column: 131 | |
550 | * End: | |
551 | */ | |
552 | ||
553 | /* end of obj-bout.c */ |