Commit | Line | Data |
---|---|---|
7b374118 NW |
1 | /* write.c - emit .o file - Copyright(C)1986 Free Software Foundation, Inc. |
2 | Copyright (C) 1986,1987 Free Software Foundation, Inc. | |
3 | ||
4 | This file is part of GAS, the GNU Assembler. | |
5 | ||
6 | GAS is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 1, or (at your option) | |
9 | any later version. | |
10 | ||
11 | GAS is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with GAS; see the file COPYING. If not, write to | |
18 | the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
19 | ||
20 | /* | |
21 | ||
22 | Umm, with real good luck, this thing should be set up to do byteordering | |
23 | correctly, but I may have managed to miss a place or two. Treat a.out | |
24 | very carefully until you're SURE that it works. . . | |
25 | ||
26 | In order to cross-assemble the target machine must have an a.out header | |
27 | similar to the one in a.out.h on THIS machine. Byteorder doesn't matter; | |
28 | we take special care of it, but the numbers must be the same SIZE (# of | |
29 | bytes) and in the same PLACE. If this is not true, you will have some | |
30 | trouble. | |
31 | */ | |
32 | ||
33 | #include "as.h" | |
34 | #include "md.h" | |
35 | #include "subsegs.h" | |
36 | #include "obstack.h" | |
37 | #include "struc-symbol.h" | |
38 | #include "write.h" | |
39 | #include "symbols.h" | |
40 | ||
41 | #ifdef SPARC | |
42 | #include "sparc.h" | |
43 | #endif | |
44 | #ifdef I860 | |
45 | #include "i860.h" | |
46 | #endif | |
47 | ||
48 | void append(); | |
49 | ||
50 | #ifdef hpux | |
51 | #define EXEC_MACHINE_TYPE HP9000S200_ID | |
52 | #endif | |
53 | ||
54 | #ifdef DOT_LABEL_PREFIX | |
55 | #define LOCAL_LABEL(name) (name[0] =='.' \ | |
56 | && ( name [1] == 'L' || name [1] == '.' )) | |
57 | #else /* not defined DOT_LABEL_PREFIX */ | |
58 | #define LOCAL_LABEL(name) (name [0] == 'L' ) | |
59 | #endif /* not defined DOT_LABEL_PREFIX */ | |
60 | ||
61 | /* | |
62 | * In: length of relocation (or of address) in chars: 1, 2 or 4. | |
63 | * Out: GNU LD relocation length code: 0, 1, or 2. | |
64 | */ | |
65 | ||
66 | static unsigned char | |
67 | ||
68 | nbytes_r_length [] = { | |
69 | 42, 0, 1, 42, 2 | |
70 | }; | |
71 | ||
72 | ||
73 | static struct frag * text_frag_root; | |
74 | static struct frag * data_frag_root; | |
75 | ||
76 | static struct frag * text_last_frag; /* Last frag in segment. */ | |
77 | static struct frag * data_last_frag; /* Last frag in segment. */ | |
78 | ||
79 | static struct exec the_exec; | |
80 | ||
81 | static long int string_byte_count; | |
82 | ||
83 | static char * the_object_file; | |
84 | ||
85 | #if !defined(SPARC) && !defined(I860) | |
86 | static | |
87 | #endif | |
88 | char * next_object_file_charP; /* Tracks object file bytes. */ | |
89 | ||
90 | static long int size_of_the_object_file; /* # bytes in object file. */ | |
91 | ||
92 | /* static long int length; JF unused */ /* String length, including trailing '\0'. */ | |
93 | ||
94 | static void relax_segment(); | |
95 | void emit_segment(); | |
96 | static relax_addressT relax_align(); | |
97 | static long int fixup_segment(); | |
98 | #if !defined(SPARC) && !defined(I860) | |
99 | static void emit_relocations(); | |
100 | #endif | |
101 | \f/* | |
102 | * fix_new() | |
103 | * | |
104 | * Create a fixS in obstack 'notes'. | |
105 | */ | |
106 | void | |
107 | #if defined(SPARC) || defined(I860) | |
108 | fix_new (frag, where, size, add_symbol, sub_symbol, offset, pcrel, r_type) | |
109 | #else | |
110 | fix_new (frag, where, size, add_symbol, sub_symbol, offset, pcrel) | |
111 | #endif | |
112 | fragS * frag; /* Which frag? */ | |
113 | int where; /* Where in that frag? */ | |
114 | short int size; /* 1, 2 or 4 usually. */ | |
115 | symbolS * add_symbol; /* X_add_symbol. */ | |
116 | symbolS * sub_symbol; /* X_subtract_symbol. */ | |
117 | long int offset; /* X_add_number. */ | |
118 | int pcrel; /* TRUE if PC-relative relocation. */ | |
119 | #if defined(SPARC) || defined(I860) | |
120 | int r_type; | |
121 | #endif | |
122 | { | |
123 | register fixS * fixP; | |
124 | ||
125 | fixP = (fixS *)obstack_alloc(¬es,sizeof(fixS)); | |
126 | ||
127 | fixP -> fx_frag = frag; | |
128 | fixP -> fx_where = where; | |
129 | fixP -> fx_size = size; | |
130 | fixP -> fx_addsy = add_symbol; | |
131 | fixP -> fx_subsy = sub_symbol; | |
132 | fixP -> fx_offset = offset; | |
133 | fixP -> fx_pcrel = pcrel; | |
134 | fixP -> fx_next = * seg_fix_rootP; | |
135 | ||
136 | /* JF these 'cuz of the NS32K stuff */ | |
137 | fixP -> fx_im_disp = 0; | |
138 | fixP -> fx_pcrel_adjust = 0; | |
139 | fixP -> fx_bsr = 0; | |
140 | fixP ->fx_bit_fixP = 0; | |
141 | ||
142 | #if defined(SPARC) || defined(I860) | |
143 | fixP->fx_r_type = r_type; | |
144 | #endif | |
145 | ||
146 | * seg_fix_rootP = fixP; | |
147 | } | |
148 | \f | |
149 | void | |
150 | write_object_file() | |
151 | { | |
152 | register struct frchain * frchainP; /* Track along all frchains. */ | |
153 | register fragS * fragP; /* Track along all frags. */ | |
154 | register struct frchain * next_frchainP; | |
155 | register fragS * * prev_fragPP; | |
156 | register char * name; | |
157 | register symbolS * symbolP; | |
158 | register symbolS ** symbolPP; | |
159 | /* register fixS * fixP; JF unused */ | |
160 | unsigned | |
161 | text_siz, | |
162 | data_siz, | |
163 | syms_siz, | |
164 | tr_siz, | |
165 | dr_siz; | |
166 | void output_file_create(); | |
167 | void output_file_append(); | |
168 | void output_file_close(); | |
169 | #ifdef DONTDEF | |
170 | void gdb_emit(); | |
171 | void gdb_end(); | |
172 | #endif | |
173 | extern long omagic; /* JF magic # to write out. Is different for | |
174 | Suns and Vaxen and other boxes */ | |
175 | ||
176 | #ifdef VMS | |
177 | /* | |
178 | * Under VMS we try to be compatible with VAX-11 "C". Thus, we | |
179 | * call a routine to check for the definition of the procedure | |
180 | * "_main", and if so -- fix it up so that it can be program | |
181 | * entry point. | |
182 | */ | |
183 | VMS_Check_For_Main(); | |
184 | #endif /* VMS */ | |
185 | /* | |
186 | * After every sub-segment, we fake an ".align ...". This conforms to BSD4.2 | |
187 | * brane-damage. We then fake ".fill 0" because that is the kind of frag | |
188 | * that requires least thought. ".align" frags like to have a following | |
189 | * frag since that makes calculating their intended length trivial. | |
190 | */ | |
191 | #define SUB_SEGMENT_ALIGN (2) | |
192 | for ( frchainP=frchain_root; frchainP; frchainP=frchainP->frch_next ) | |
193 | { | |
194 | #ifdef VMS | |
195 | /* | |
196 | * Under VAX/VMS, the linker (and PSECT specifications) | |
197 | * take care of correctly aligning the segments. | |
198 | * Doing the alignment here (on initialized data) can | |
199 | * mess up the calculation of global data PSECT sizes. | |
200 | */ | |
201 | #undef SUB_SEGMENT_ALIGN | |
202 | #define SUB_SEGMENT_ALIGN ((frchainP->frch_seg != SEG_DATA) ? 2 : 0) | |
203 | #endif /* VMS */ | |
204 | subseg_new (frchainP -> frch_seg, frchainP -> frch_subseg); | |
205 | frag_align (SUB_SEGMENT_ALIGN, 0); | |
206 | /* frag_align will have left a new frag. */ | |
207 | /* Use this last frag for an empty ".fill". */ | |
208 | /* | |
209 | * For this segment ... | |
210 | * Create a last frag. Do not leave a "being filled in frag". | |
211 | */ | |
212 | frag_wane (frag_now); | |
213 | frag_now -> fr_fix = 0; | |
214 | know( frag_now -> fr_next == NULL ); | |
215 | /* know( frags . obstack_c_base == frags . obstack_c_next_free ); */ | |
216 | /* Above shows we haven't left a half-completed object on obstack. */ | |
217 | } | |
218 | \f | |
219 | /* | |
220 | * From now on, we don't care about sub-segments. | |
221 | * Build one frag chain for each segment. Linked thru fr_next. | |
222 | * We know that there is at least 1 text frchain & at least 1 data frchain. | |
223 | */ | |
224 | prev_fragPP = &text_frag_root; | |
225 | for ( frchainP=frchain_root; frchainP; frchainP=next_frchainP ) | |
226 | { | |
227 | know( frchainP -> frch_root ); | |
228 | * prev_fragPP = frchainP -> frch_root; | |
229 | prev_fragPP = & frchainP -> frch_last -> fr_next; | |
230 | if ( ((next_frchainP = frchainP->frch_next) == NULL) | |
231 | || next_frchainP == data0_frchainP) | |
232 | { | |
233 | prev_fragPP = & data_frag_root; | |
234 | if ( next_frchainP ) | |
235 | { | |
236 | text_last_frag = frchainP -> frch_last; | |
237 | } | |
238 | else | |
239 | { | |
240 | data_last_frag = frchainP -> frch_last; | |
241 | } | |
242 | } | |
243 | } /* for(each struct frchain) */ | |
244 | ||
245 | /* | |
246 | * We have two segments. If user gave -R flag, then we must put the | |
247 | * data frags into the text segment. Do this before relaxing so | |
248 | * we know to take advantage of -R and make shorter addresses. | |
249 | */ | |
250 | if ( flagseen [ 'R' ] ) | |
251 | { | |
252 | fixS *tmp; | |
253 | ||
254 | text_last_frag -> fr_next = data_frag_root; | |
255 | text_last_frag = data_last_frag; | |
256 | data_last_frag = NULL; | |
257 | data_frag_root = NULL; | |
258 | if(text_fix_root) { | |
259 | for(tmp=text_fix_root;tmp->fx_next;tmp=tmp->fx_next) | |
260 | ; | |
261 | tmp->fx_next=data_fix_root; | |
262 | } else | |
263 | text_fix_root=data_fix_root; | |
264 | data_fix_root=NULL; | |
265 | } | |
266 | ||
267 | relax_segment (text_frag_root, SEG_TEXT); | |
268 | relax_segment (data_frag_root, SEG_DATA); | |
269 | /* | |
270 | * Now the addresses of frags are correct within the segment. | |
271 | */ | |
272 | ||
273 | know( text_last_frag -> fr_type == rs_fill && text_last_frag -> fr_offset == 0 ); | |
274 | text_siz=text_last_frag->fr_address; | |
275 | #ifdef SPARC | |
276 | text_siz= (text_siz+7)&(~7); | |
277 | text_last_frag->fr_address=text_siz; | |
278 | #endif | |
279 | md_number_to_chars((char *)&the_exec.a_text,text_siz, sizeof(the_exec.a_text)); | |
280 | /* the_exec . a_text = text_last_frag -> fr_address; */ | |
281 | \f | |
282 | /* | |
283 | * Join the 2 segments into 1 huge segment. | |
284 | * To do this, re-compute every rn_address in the SEG_DATA frags. | |
285 | * Then join the data frags after the text frags. | |
286 | * | |
287 | * Determine a_data [length of data segment]. | |
288 | */ | |
289 | if (data_frag_root) | |
290 | { | |
291 | register relax_addressT slide; | |
292 | ||
293 | know( text_last_frag -> fr_type == rs_fill && text_last_frag -> fr_offset == 0 ); | |
294 | data_siz=data_last_frag->fr_address; | |
295 | #ifdef SPARC | |
296 | data_siz += (8 - (data_siz % 8)) % 8; | |
297 | data_last_frag->fr_address = data_siz; | |
298 | #endif | |
299 | md_number_to_chars((char *)&the_exec.a_data,data_siz,sizeof(the_exec.a_data)); | |
300 | /* the_exec . a_data = data_last_frag -> fr_address; */ | |
301 | slide = text_siz; /* Address in file of the data segment. */ | |
302 | for (fragP = data_frag_root; | |
303 | fragP; | |
304 | fragP = fragP -> fr_next) | |
305 | { | |
306 | fragP -> fr_address += slide; | |
307 | } | |
308 | know( text_last_frag ); | |
309 | text_last_frag -> fr_next = data_frag_root; | |
310 | } | |
311 | else { | |
312 | md_number_to_chars((char *)&the_exec.a_data,0,sizeof(the_exec.a_data)); | |
313 | data_siz = 0; | |
314 | } | |
315 | ||
316 | bss_address_frag . fr_address = text_siz + data_siz; | |
317 | #ifdef SPARC | |
318 | local_bss_counter=(local_bss_counter+7)&(~7); | |
319 | #endif | |
320 | md_number_to_chars((char *)&the_exec.a_bss,local_bss_counter,sizeof(the_exec.a_bss)); | |
321 | ||
322 | ||
323 | /* | |
324 | * | |
325 | * Crawl the symbol chain. | |
326 | * | |
327 | * For each symbol whose value depends on a frag, take the address of | |
328 | * that frag and subsume it into the value of the symbol. | |
329 | * After this, there is just one way to lookup a symbol value. | |
330 | * Values are left in their final state for object file emission. | |
331 | * We adjust the values of 'L' local symbols, even if we do | |
332 | * not intend to emit them to the object file, because their values | |
333 | * are needed for fix-ups. | |
334 | * | |
335 | * Unless we saw a -L flag, remove all symbols that begin with 'L' | |
336 | * from the symbol chain. | |
337 | * | |
338 | * Count the (length of the nlists of the) (remaining) symbols. | |
339 | * Assign a symbol number to each symbol. | |
340 | * Count the number of string-table chars we will emit. | |
341 | * | |
342 | */ | |
343 | know( zero_address_frag . fr_address == 0 ); | |
344 | string_byte_count = sizeof( string_byte_count ); | |
345 | ||
346 | /* JF deal with forward references first. . . */ | |
347 | for(symbolP=symbol_rootP;symbolP;symbolP=symbolP->sy_next) { | |
348 | if(symbolP->sy_forward) { | |
349 | symbolP->sy_value+=symbolP->sy_forward->sy_value+symbolP->sy_forward->sy_frag->fr_address; | |
350 | symbolP->sy_forward=0; | |
351 | } | |
352 | } | |
353 | symbolPP = & symbol_rootP; /* -> last symbol chain link. */ | |
354 | { | |
355 | register long int symbol_number; | |
356 | ||
357 | symbol_number = 0; | |
358 | while (symbolP = * symbolPP) | |
359 | { | |
360 | name = symbolP -> sy_name; | |
361 | if(flagseen['R'] && (symbolP->sy_nlist.n_type&N_DATA)) { | |
362 | symbolP->sy_nlist.n_type&= ~N_DATA; | |
363 | symbolP->sy_nlist.n_type|= N_TEXT; | |
364 | } | |
365 | /* if(symbolP->sy_forward) { | |
366 | symbolP->sy_value += symbolP->sy_forward->sy_value + symbolP->sy_forward->sy_frag->fr_address; | |
367 | } */ | |
368 | ||
369 | symbolP -> sy_value += symbolP -> sy_frag -> fr_address; | |
370 | /* JF the 128 bit is a hack so stabs like | |
371 | "LET_STMT:23. . ." don't go away */ | |
372 | /* CPH: 128 bit hack is moby loser. N_SO for file "Lower.c" | |
373 | fell through the cracks. I think that N_STAB should be | |
374 | used instead of 128. */ | |
375 | /* JF the \001 bit is to make sure that local labels | |
376 | ( 1: - 9: don't make it into the symtable either */ | |
377 | #ifndef VMS /* Under VMS we need to keep local symbols */ | |
378 | if ( !name || (symbolP->sy_nlist.n_type&N_STAB) | |
379 | || (name[2]!='\001' && (flagseen ['L'] || ! LOCAL_LABEL(name) ))) | |
380 | #endif /* not VMS */ | |
381 | { | |
382 | symbolP -> sy_number = symbol_number ++; | |
383 | #ifndef VMS | |
384 | if (name) | |
385 | { /* Ordinary case. */ | |
386 | symbolP -> sy_name_offset = string_byte_count; | |
387 | string_byte_count += strlen (symbolP -> sy_name) + 1; | |
388 | } | |
389 | else /* .Stabd case. */ | |
390 | #endif /* not VMS */ | |
391 | symbolP -> sy_name_offset = 0; | |
392 | symbolPP = & (symbolP -> sy_next); | |
393 | } | |
394 | #ifndef VMS | |
395 | else | |
396 | * symbolPP = symbolP -> sy_next; | |
397 | #endif /* not VMS */ | |
398 | } /* for each symbol */ | |
399 | ||
400 | syms_siz = sizeof( struct nlist) * symbol_number; | |
401 | md_number_to_chars((char *)&the_exec.a_syms,syms_siz,sizeof(the_exec.a_syms)); | |
402 | /* the_exec . a_syms = sizeof( struct nlist) * symbol_number; */ | |
403 | } | |
404 | ||
405 | /* | |
406 | * Addresses of frags now reflect addresses we use in the object file. | |
407 | * Symbol values are correct. | |
408 | * Scan the frags, converting any ".org"s and ".align"s to ".fill"s. | |
409 | * Also converting any machine-dependent frags using md_convert_frag(); | |
410 | */ | |
411 | subseg_change( SEG_TEXT, 0); | |
412 | ||
413 | for (fragP = text_frag_root; fragP; fragP = fragP -> fr_next) | |
414 | { | |
415 | switch (fragP -> fr_type) | |
416 | { | |
417 | case rs_align: | |
418 | case rs_org: | |
419 | fragP -> fr_type = rs_fill; | |
420 | know( fragP -> fr_var == 1 ); | |
421 | know( fragP -> fr_next ); | |
422 | fragP -> fr_offset | |
423 | = fragP -> fr_next -> fr_address | |
424 | - fragP -> fr_address | |
425 | - fragP -> fr_fix; | |
426 | break; | |
427 | ||
428 | case rs_fill: | |
429 | break; | |
430 | ||
431 | case rs_machine_dependent: | |
432 | md_convert_frag (fragP); | |
433 | /* | |
434 | * After md_convert_frag, we make the frag into a ".space 0". | |
435 | * Md_convert_frag() should set up any fixSs and constants | |
436 | * required. | |
437 | */ | |
438 | frag_wane (fragP); | |
439 | break; | |
440 | ||
441 | #ifndef WORKING_DOT_WORD | |
442 | case rs_broken_word: | |
443 | { | |
444 | struct broken_word *lie; | |
445 | extern md_short_jump_size; | |
446 | extern md_long_jump_size; | |
447 | ||
448 | if(fragP->fr_subtype) { | |
449 | fragP->fr_fix+=md_short_jump_size; | |
450 | for(lie=(struct broken_word *)(fragP->fr_symbol);lie && lie->dispfrag==fragP;lie=lie->next_broken_word) | |
451 | if(lie->added==1) | |
452 | fragP->fr_fix+=md_long_jump_size; | |
453 | } | |
454 | frag_wane(fragP); | |
455 | } | |
456 | break; | |
457 | #endif | |
458 | ||
459 | default: | |
460 | BAD_CASE( fragP -> fr_type ); | |
461 | break; | |
462 | } /* switch (fr_type) */ | |
463 | } /* for each frag. */ | |
464 | ||
465 | #ifndef WORKING_DOT_WORD | |
466 | { | |
467 | struct broken_word *lie; | |
468 | struct broken_word **prevP; | |
469 | ||
470 | prevP= &broken_words; | |
471 | for(lie=broken_words; lie; lie=lie->next_broken_word) | |
472 | if(!lie->added) { | |
473 | #if defined(SPARC) || defined(I860) | |
474 | fix_new( lie->frag, lie->word_goes_here - lie->frag->fr_literal, | |
475 | 2, lie->add, | |
476 | lie->sub, lie->addnum, | |
477 | 0, NO_RELOC); | |
478 | #endif | |
479 | #ifdef NS32K | |
480 | fix_new_ns32k(lie->frag, | |
481 | lie->word_goes_here - lie->frag->fr_literal, | |
482 | 2, | |
483 | lie->add, | |
484 | lie->sub, | |
485 | lie->addnum, | |
486 | 0, 0, 2, 0, 0); | |
487 | #endif | |
488 | #if !defined(SPARC) && !defined(NS32K) && !defined(I860) | |
489 | fix_new( lie->frag, lie->word_goes_here - lie->frag->fr_literal, | |
490 | 2, lie->add, | |
491 | lie->sub, lie->addnum, | |
492 | 0); | |
493 | #endif | |
494 | /* md_number_to_chars(lie->word_goes_here, | |
495 | lie->add->sy_value | |
496 | + lie->addnum | |
497 | - (lie->sub->sy_value), | |
498 | 2); */ | |
499 | *prevP=lie->next_broken_word; | |
500 | } else | |
501 | prevP= &(lie->next_broken_word); | |
502 | ||
503 | for(lie=broken_words;lie;) { | |
504 | struct broken_word *untruth; | |
505 | char *table_ptr; | |
506 | long table_addr; | |
507 | long from_addr, | |
508 | to_addr; | |
509 | int n, | |
510 | m; | |
511 | ||
512 | extern md_short_jump_size; | |
513 | extern md_long_jump_size; | |
514 | void md_create_short_jump(); | |
515 | void md_create_long_jump(); | |
516 | ||
517 | ||
518 | ||
519 | fragP=lie->dispfrag; | |
520 | ||
521 | /* Find out how many broken_words go here */ | |
522 | n=0; | |
523 | for(untruth=lie;untruth && untruth->dispfrag==fragP;untruth=untruth->next_broken_word) | |
524 | if(untruth->added==1) | |
525 | n++; | |
526 | ||
527 | table_ptr=lie->dispfrag->fr_opcode; | |
528 | table_addr=lie->dispfrag->fr_address+(table_ptr - lie->dispfrag->fr_literal); | |
529 | /* Create the jump around the long jumps */ | |
530 | /* This is a short jump from table_ptr+0 to table_ptr+n*long_jump_size */ | |
531 | from_addr=table_addr; | |
532 | to_addr = table_addr + md_short_jump_size + n * md_long_jump_size; | |
533 | md_create_short_jump(table_ptr,from_addr,to_addr,lie->dispfrag,lie->add); | |
534 | table_ptr+=md_short_jump_size; | |
535 | table_addr+=md_short_jump_size; | |
536 | ||
537 | for(m=0;lie && lie->dispfrag==fragP;m++,lie=lie->next_broken_word) { | |
538 | if(lie->added==2) | |
539 | continue; | |
540 | /* Patch the jump table */ | |
541 | /* This is the offset from ??? to table_ptr+0 */ | |
542 | to_addr = table_addr | |
543 | - (lie->sub->sy_value); | |
544 | md_number_to_chars(lie->word_goes_here,to_addr,2); | |
545 | for(untruth=lie->next_broken_word;untruth && untruth->dispfrag==fragP;untruth=untruth->next_broken_word) { | |
546 | if(untruth->use_jump==lie) | |
547 | md_number_to_chars(untruth->word_goes_here,to_addr,2); | |
548 | } | |
549 | ||
550 | /* Install the long jump */ | |
551 | /* this is a long jump from table_ptr+0 to the final target */ | |
552 | from_addr=table_addr; | |
553 | to_addr=lie->add->sy_value+lie->addnum; | |
554 | md_create_long_jump(table_ptr,from_addr,to_addr,lie->dispfrag,lie->add); | |
555 | table_ptr+=md_long_jump_size; | |
556 | table_addr+=md_long_jump_size; | |
557 | } | |
558 | } | |
559 | } | |
560 | #endif | |
561 | #ifndef VMS | |
562 | /* | |
563 | * Scan every FixS performing fixups. We had to wait until now to do | |
564 | * this because md_convert_frag() may have made some fixSs. | |
565 | */ | |
566 | /* the_exec . a_trsize | |
567 | = sizeof(struct relocation_info) * fixup_segment (text_fix_root, N_TEXT); | |
568 | the_exec . a_drsize | |
569 | = sizeof(struct relocation_info) * fixup_segment (data_fix_root, N_DATA); */ | |
570 | ||
571 | tr_siz=sizeof(struct relocation_info) * fixup_segment (text_fix_root, N_TEXT); | |
572 | md_number_to_chars((char *)&the_exec.a_trsize, tr_siz ,sizeof(the_exec.a_trsize)); | |
573 | dr_siz=sizeof(struct relocation_info) * fixup_segment (data_fix_root, N_DATA); | |
574 | md_number_to_chars((char *)&the_exec.a_drsize, dr_siz, sizeof(the_exec.a_drsize)); | |
575 | md_number_to_chars((char *)&the_exec.a_info,omagic,sizeof(the_exec.a_info)); | |
576 | md_number_to_chars((char *)&the_exec.a_entry,0,sizeof(the_exec.a_entry)); | |
577 | ||
578 | #ifdef EXEC_MACHINE_TYPE | |
579 | md_number_to_chars((char *)&the_exec.a_machtype, EXEC_MACHINE_TYPE, sizeof(the_exec.a_machtype)); | |
580 | #endif | |
581 | #ifdef EXEC_VERSION | |
582 | md_number_to_chars((char *)&the_exec.a_version,EXEC_VERSION,sizeof(the_exec.a_version)); | |
583 | #endif | |
584 | ||
585 | /* the_exec . a_entry = 0; */ | |
586 | ||
587 | size_of_the_object_file = | |
588 | sizeof( the_exec ) + | |
589 | text_siz + | |
590 | data_siz + | |
591 | syms_siz + | |
592 | tr_siz + | |
593 | dr_siz + | |
594 | string_byte_count; | |
595 | ||
596 | next_object_file_charP | |
597 | = the_object_file | |
598 | = xmalloc ( size_of_the_object_file ); | |
599 | ||
600 | output_file_create (out_file_name); | |
601 | ||
602 | append (& next_object_file_charP, (char *)(&the_exec), (unsigned long)sizeof(the_exec)); | |
603 | \f | |
604 | /* | |
605 | * Emit code. | |
606 | */ | |
607 | for (fragP = text_frag_root; fragP; fragP = fragP -> fr_next) | |
608 | { | |
609 | register long int count; | |
610 | register char * fill_literal; | |
611 | register long int fill_size; | |
612 | ||
613 | know( fragP -> fr_type == rs_fill ); | |
614 | append (& next_object_file_charP, fragP -> fr_literal, (unsigned long)fragP -> fr_fix); | |
615 | fill_literal= fragP -> fr_literal + fragP -> fr_fix; | |
616 | fill_size = fragP -> fr_var; | |
617 | know( fragP -> fr_offset >= 0 ); | |
618 | for (count = fragP -> fr_offset; count; count --) | |
619 | append (& next_object_file_charP, fill_literal, (unsigned long)fill_size); | |
620 | } /* for each code frag. */ | |
621 | ||
622 | /* | |
623 | * Emit relocations. | |
624 | */ | |
625 | emit_relocations (text_fix_root, (relax_addressT)0); | |
626 | emit_relocations (data_fix_root, text_last_frag -> fr_address); | |
627 | /* | |
628 | * Emit all symbols left in the symbol chain. | |
629 | * Any symbol still undefined is made N_EXT. | |
630 | */ | |
631 | for ( symbolP = symbol_rootP; symbolP; symbolP = symbolP -> sy_next ) | |
632 | { | |
633 | register char * temp; | |
634 | ||
635 | temp = symbolP -> sy_nlist . n_un . n_name; | |
636 | /* JF fix the numbers up. Call by value RULES! */ | |
637 | md_number_to_chars((char *)&(symbolP -> sy_nlist . n_un . n_strx ),symbolP -> sy_name_offset,sizeof(symbolP -> sy_nlist . n_un . n_strx )); | |
638 | md_number_to_chars((char *)&(symbolP->sy_nlist.n_desc),symbolP->sy_nlist.n_desc,sizeof(symbolP -> sy_nlist . n_desc)); | |
639 | md_number_to_chars((char *)&(symbolP->sy_nlist.n_value),symbolP->sy_nlist.n_value,sizeof(symbolP->sy_nlist.n_value)); | |
640 | /* symbolP -> sy_nlist . n_un . n_strx = symbolP -> sy_name_offset; JF replaced by md above */ | |
641 | if (symbolP -> sy_type == N_UNDF) | |
642 | symbolP -> sy_type |= N_EXT; /* Any undefined symbols become N_EXT. */ | |
643 | append (& next_object_file_charP, (char *)(& symbolP -> sy_nlist), | |
644 | (unsigned long)sizeof(struct nlist)); | |
645 | symbolP -> sy_nlist . n_un . n_name = temp; | |
646 | } /* for each symbol */ | |
647 | ||
648 | /* | |
649 | * next_object_file_charP -> slot for next object byte. | |
650 | * Emit strings. | |
651 | * Find strings by crawling along symbol table chain. | |
652 | */ | |
653 | /* Gotta do md_ byte-ordering stuff for string_byte_count first - KWK */ | |
654 | md_number_to_chars((char *)&string_byte_count, string_byte_count, sizeof(string_byte_count)); | |
655 | ||
656 | append (& next_object_file_charP, (char *)&string_byte_count, (unsigned long)sizeof(string_byte_count)); | |
657 | for ( symbolP = symbol_rootP; symbolP; symbolP = symbolP -> sy_next ) | |
658 | { | |
659 | if (symbolP -> sy_name) | |
660 | { /* Ordinary case: not .stabd. */ | |
661 | append (& next_object_file_charP, symbolP -> sy_name, | |
662 | (unsigned long)(strlen (symbolP -> sy_name) + 1)); | |
663 | } | |
664 | } /* for each symbol */ | |
665 | ||
666 | know( next_object_file_charP == the_object_file + size_of_the_object_file ); | |
667 | ||
668 | output_file_append (the_object_file, size_of_the_object_file, out_file_name); | |
669 | ||
670 | #ifdef DONTDEF | |
671 | if (flagseen['G']) /* GDB symbol file to be appended? */ | |
672 | { | |
673 | gdb_emit (out_file_name); | |
674 | gdb_end (); | |
675 | } | |
676 | #endif | |
677 | ||
678 | output_file_close (out_file_name); | |
679 | #else /* VMS */ | |
680 | /* | |
681 | * Now do the VMS-dependent part of writing the object file | |
682 | */ | |
683 | VMS_write_object_file(text_siz, data_siz, text_frag_root, data_frag_root); | |
684 | #endif /* VMS */ | |
685 | } /* write_object_file() */ | |
686 | \f | |
687 | /* | |
688 | * relax_segment() | |
689 | * | |
690 | * Now we have a segment, not a crowd of sub-segments, we can make fr_address | |
691 | * values. | |
692 | * | |
693 | * Relax the frags. | |
694 | * | |
695 | * After this, all frags in this segment have addresses that are correct | |
696 | * within the segment. Since segments live in different file addresses, | |
697 | * these frag addresses may not be the same as final object-file addresses. | |
698 | */ | |
699 | #ifndef VMS | |
700 | static | |
701 | #endif /* not VMS */ | |
702 | void | |
703 | relax_segment (segment_frag_root, segment_type) | |
704 | struct frag * segment_frag_root; | |
705 | segT segment_type; /* N_DATA or N_TEXT */ | |
706 | { | |
707 | register struct frag * fragP; | |
708 | register relax_addressT address; | |
709 | /* register relax_addressT old_address; JF unused */ | |
710 | /* register relax_addressT new_address; JF unused */ | |
711 | ||
712 | know( segment_type == SEG_DATA || segment_type == SEG_TEXT ); | |
713 | ||
714 | /* In case md_estimate_size_before_relax() wants to make fixSs. */ | |
715 | subseg_change (segment_type, 0); | |
716 | ||
717 | /* | |
718 | * For each frag in segment: count and store (a 1st guess of) fr_address. | |
719 | */ | |
720 | address = 0; | |
721 | for ( fragP = segment_frag_root; fragP; fragP = fragP -> fr_next ) | |
722 | { | |
723 | fragP -> fr_address = address; | |
724 | address += fragP -> fr_fix; | |
725 | switch (fragP -> fr_type) | |
726 | { | |
727 | case rs_fill: | |
728 | address += fragP -> fr_offset * fragP -> fr_var; | |
729 | break; | |
730 | ||
731 | case rs_align: | |
732 | address += relax_align (address, fragP -> fr_offset); | |
733 | break; | |
734 | ||
735 | case rs_org: | |
736 | /* | |
737 | * Assume .org is nugatory. It will grow with 1st relax. | |
738 | */ | |
739 | break; | |
740 | ||
741 | case rs_machine_dependent: | |
742 | address += md_estimate_size_before_relax | |
743 | (fragP, seg_N_TYPE [(int) segment_type]); | |
744 | break; | |
745 | ||
746 | #ifndef WORKING_DOT_WORD | |
747 | /* Broken words don't concern us yet */ | |
748 | case rs_broken_word: | |
749 | break; | |
750 | #endif | |
751 | ||
752 | default: | |
753 | BAD_CASE( fragP -> fr_type ); | |
754 | break; | |
755 | } /* switch(fr_type) */ | |
756 | } /* for each frag in the segment */ | |
757 | \f | |
758 | /* | |
759 | * Do relax(). | |
760 | */ | |
761 | { | |
762 | register long int stretch; /* May be any size, 0 or negative. */ | |
763 | /* Cumulative number of addresses we have */ | |
764 | /* relaxed this pass. */ | |
765 | /* We may have relaxed more than one address. */ | |
766 | register long int stretched; /* Have we stretched on this pass? */ | |
767 | /* This is 'cuz stretch may be zero, when, | |
768 | in fact some piece of code grew, and | |
769 | another shrank. If a branch instruction | |
770 | doesn't fit anymore, we could be scrod */ | |
771 | ||
772 | do | |
773 | { | |
774 | stretch = stretched = 0; | |
775 | for (fragP = segment_frag_root; fragP; fragP = fragP -> fr_next) | |
776 | { | |
777 | register long int growth; | |
778 | register long int was_address; | |
779 | /* register long int var; */ | |
780 | register long int offset; | |
781 | register symbolS * symbolP; | |
782 | register long int target; | |
783 | register long int after; | |
784 | register long int aim; | |
785 | ||
786 | was_address = fragP -> fr_address; | |
787 | address = fragP -> fr_address += stretch; | |
788 | symbolP = fragP -> fr_symbol; | |
789 | offset = fragP -> fr_offset; | |
790 | /* var = fragP -> fr_var; */ | |
791 | switch (fragP -> fr_type) | |
792 | { | |
793 | case rs_fill: /* .fill never relaxes. */ | |
794 | growth = 0; | |
795 | break; | |
796 | ||
797 | #ifndef WORKING_DOT_WORD | |
798 | /* JF: This is RMS's idea. I do *NOT* want to be blamed | |
799 | for it I do not want to write it. I do not want to have | |
800 | anything to do with it. This is not the proper way to | |
801 | implement this misfeature. */ | |
802 | case rs_broken_word: | |
803 | { | |
804 | struct broken_word *lie; | |
805 | struct broken_word *untruth; | |
806 | extern int md_short_jump_size; | |
807 | extern int md_long_jump_size; | |
808 | ||
809 | /* Yes this is ugly (storing the broken_word pointer | |
810 | in the symbol slot). Still, this whole chunk of | |
811 | code is ugly, and I don't feel like doing anything | |
812 | about it. Think of it as stubbornness in action */ | |
813 | growth=0; | |
814 | for(lie=(struct broken_word *)(fragP->fr_symbol); | |
815 | lie && lie->dispfrag==fragP; | |
816 | lie=lie->next_broken_word) { | |
817 | ||
818 | if(lie->added) | |
819 | continue; | |
820 | offset= lie->add->sy_frag->fr_address+lie->add->sy_value + lie->addnum - | |
821 | (lie->sub->sy_frag->fr_address+lie->sub->sy_value); | |
822 | if(offset<=-32768 || offset>=32767) { | |
823 | if(flagseen['k']) | |
824 | as_warn(".word %s-%s+%ld didn't fit",lie->add->sy_name,lie->sub->sy_name,lie->addnum); | |
825 | lie->added=1; | |
826 | if(fragP->fr_subtype==0) { | |
827 | fragP->fr_subtype++; | |
828 | growth+=md_short_jump_size; | |
829 | } | |
830 | for(untruth=lie->next_broken_word;untruth && untruth->dispfrag==lie->dispfrag;untruth=untruth->next_broken_word) | |
831 | if(untruth->add->sy_frag==lie->add->sy_frag && untruth->add->sy_value==lie->add->sy_value) { | |
832 | untruth->added=2; | |
833 | untruth->use_jump=lie; | |
834 | } | |
835 | growth+=md_long_jump_size; | |
836 | } | |
837 | } | |
838 | } | |
839 | break; | |
840 | #endif | |
841 | case rs_align: | |
842 | growth = relax_align ((relax_addressT)(address + fragP -> fr_fix), offset) | |
843 | - relax_align ((relax_addressT)(was_address + fragP -> fr_fix), offset); | |
844 | break; | |
845 | ||
846 | case rs_org: | |
847 | target = offset; | |
848 | if (symbolP) | |
849 | { | |
850 | know( ((symbolP -> sy_type & N_TYPE) == N_ABS) || ((symbolP -> sy_type & N_TYPE) == N_DATA) || ((symbolP -> sy_type & N_TYPE) == N_TEXT)); | |
851 | know( symbolP -> sy_frag ); | |
852 | know( (symbolP->sy_type&N_TYPE)!=N_ABS || symbolP->sy_frag==&zero_address_frag ); | |
853 | target += | |
854 | symbolP -> sy_value | |
855 | + symbolP -> sy_frag -> fr_address; | |
856 | } | |
857 | know( fragP -> fr_next ); | |
858 | after = fragP -> fr_next -> fr_address; | |
859 | growth = ((target - after ) > 0) ? (target - after) : 0; | |
860 | /* Growth may be -ve, but variable part */ | |
861 | /* of frag cannot have < 0 chars. */ | |
862 | /* That is, we can't .org backwards. */ | |
863 | ||
864 | growth -= stretch; /* This is an absolute growth factor */ | |
865 | break; | |
866 | ||
867 | case rs_machine_dependent: | |
868 | { | |
869 | register const relax_typeS * this_type; | |
870 | register const relax_typeS * start_type; | |
871 | register relax_substateT next_state; | |
872 | register relax_substateT this_state; | |
873 | ||
874 | start_type = this_type | |
875 | = md_relax_table + (this_state = fragP -> fr_subtype); | |
876 | target = offset; | |
877 | if (symbolP) | |
878 | { | |
879 | know( ((symbolP -> sy_type & N_TYPE) == N_ABS) || ((symbolP -> sy_type & | |
880 | N_TYPE) == N_DATA) || ((symbolP -> sy_type & N_TYPE) == N_TEXT)); | |
881 | know( symbolP -> sy_frag ); | |
882 | know( (symbolP->sy_type&N_TYPE)!=N_ABS || symbolP->sy_frag==&zero_address_frag ); | |
883 | target += | |
884 | symbolP -> sy_value | |
885 | + symbolP -> sy_frag -> fr_address; | |
886 | ||
887 | /* If frag has yet to be reached on this pass, | |
888 | assume it will move by STRETCH just as we did. | |
889 | If this is not so, it will be because some frag | |
890 | between grows, and that will force another pass. */ | |
891 | ||
892 | /* JF was just address */ | |
893 | /* JF also added is_dnrange hack */ | |
894 | /* There's gotta be a better/faster/etc way | |
895 | to do this. . . */ | |
896 | /* gnu@cygnus.com: I changed this from > to >= | |
897 | because I ran into a zero-length frag (fr_fix=0) | |
898 | which was created when the obstack needed a new | |
899 | chunk JUST AFTER the opcode of a branch. Since | |
900 | fr_fix is zero, fr_address of this frag is the same | |
901 | as fr_address of the next frag. This | |
902 | zero-length frag was variable and jumped to .+2 | |
903 | (in the next frag), but since the > comparison | |
904 | below failed (the two were =, not >), "stretch" | |
905 | was not added to the target. Stretch was 178, so | |
906 | the offset appeared to be .-176 instead, which did | |
907 | not fit into a byte branch, so the assembler | |
908 | relaxed the branch to a word. This didn't compare | |
909 | with what happened when the same source file was | |
910 | assembled on other machines, which is how I found it. | |
911 | You might want to think about what other places have | |
912 | trouble with zero length frags... */ | |
913 | ||
914 | if (symbolP->sy_frag->fr_address >= was_address && is_dnrange(fragP,symbolP->sy_frag)) | |
915 | target += stretch; | |
916 | ||
917 | } | |
918 | aim = target - address - fragP -> fr_fix; | |
919 | /* The displacement is affected by the instruction size | |
920 | * for the 32k architecture. I think we ought to be able | |
921 | * to add fragP->fr_pcrel_adjust in all cases (it should be | |
922 | * zero if not used), but just in case it breaks something | |
923 | * else we'll put this inside #ifdef NS32K ... #endif | |
924 | */ | |
925 | #ifdef NS32K | |
926 | aim += fragP->fr_pcrel_adjust; | |
927 | #endif | |
928 | ||
929 | if (aim < 0) | |
930 | { | |
931 | /* Look backwards. */ | |
932 | for (next_state = this_type -> rlx_more; next_state; ) | |
933 | { | |
934 | if (aim >= this_type -> rlx_backward) | |
935 | next_state = 0; | |
936 | else | |
937 | { /* Grow to next state. */ | |
938 | this_type = md_relax_table + (this_state = next_state); | |
939 | next_state = this_type -> rlx_more; | |
940 | } | |
941 | } | |
942 | } | |
943 | else | |
944 | { | |
945 | #ifdef DONTDEF | |
946 | /* JF these next few lines of code are for the mc68020 which can't handle short | |
947 | offsets of zero in branch instructions. What a kludge! */ | |
948 | if(aim==0 && this_state==(1<<2+0)) { /* FOO hard encoded from m.c */ | |
949 | aim=this_type->rlx_forward+1; /* Force relaxation into word mode */ | |
950 | } | |
951 | #endif | |
952 | /* JF end of 68020 code */ | |
953 | /* Look forwards. */ | |
954 | for (next_state = this_type -> rlx_more; next_state; ) | |
955 | { | |
956 | if (aim <= this_type -> rlx_forward) | |
957 | next_state = 0; | |
958 | else | |
959 | { /* Grow to next state. */ | |
960 | this_type = md_relax_table + (this_state = next_state); | |
961 | next_state = this_type -> rlx_more; | |
962 | } | |
963 | } | |
964 | } | |
965 | if (growth = this_type -> rlx_length - start_type -> rlx_length) | |
966 | fragP -> fr_subtype = this_state; | |
967 | } | |
968 | break; | |
969 | ||
970 | default: | |
971 | BAD_CASE( fragP -> fr_type ); | |
972 | break; | |
973 | } | |
974 | if(growth) { | |
975 | stretch += growth; | |
976 | stretched++; | |
977 | } | |
978 | } /* For each frag in the segment. */ | |
979 | } while (stretched); /* Until nothing further to relax. */ | |
980 | } | |
981 | ||
982 | /* | |
983 | * We now have valid fr_address'es for each frag. | |
984 | */ | |
985 | ||
986 | /* | |
987 | * All fr_address's are correct, relative to their own segment. | |
988 | * We have made all the fixS we will ever make. | |
989 | */ | |
990 | } /* relax_segment() */ | |
991 | \f | |
992 | /* | |
993 | * Relax_align. Advance location counter to next address that has 'alignment' | |
994 | * lowest order bits all 0s. | |
995 | */ | |
996 | ||
997 | static relax_addressT /* How many addresses does the .align take? */ | |
998 | relax_align (address, alignment) | |
999 | register relax_addressT address; /* Address now. */ | |
1000 | register long int alignment; /* Alignment (binary). */ | |
1001 | { | |
1002 | relax_addressT mask; | |
1003 | relax_addressT new_address; | |
1004 | ||
1005 | mask = ~ ( (~0) << alignment ); | |
1006 | new_address = (address + mask) & (~ mask); | |
1007 | return (new_address - address); | |
1008 | } | |
1009 | \f | |
1010 | /* | |
1011 | * fixup_segment() | |
1012 | */ | |
1013 | static long int | |
1014 | fixup_segment (fixP, this_segment_type) | |
1015 | register fixS * fixP; | |
1016 | int this_segment_type; /* N_TYPE bits for segment. */ | |
1017 | { | |
1018 | register long int seg_reloc_count; | |
1019 | /* JF these all used to be local to the for loop, but GDB doesn't seem to be able to deal with them there, so I moved them here for a bit. */ | |
1020 | register symbolS * add_symbolP; | |
1021 | register symbolS * sub_symbolP; | |
1022 | register long int add_number; | |
1023 | register int size; | |
1024 | register char * place; | |
1025 | register long int where; | |
1026 | register char pcrel; | |
1027 | register fragS * fragP; | |
1028 | register int add_symbol_N_TYPE; | |
1029 | ||
1030 | ||
1031 | seg_reloc_count = 0; | |
1032 | for ( ; fixP; fixP = fixP -> fx_next) | |
1033 | { | |
1034 | fragP = fixP -> fx_frag; | |
1035 | know( fragP ); | |
1036 | where = fixP -> fx_where; | |
1037 | place = fragP -> fr_literal + where; | |
1038 | size = fixP -> fx_size; | |
1039 | add_symbolP = fixP -> fx_addsy; | |
1040 | sub_symbolP = fixP -> fx_subsy; | |
1041 | add_number = fixP -> fx_offset; | |
1042 | pcrel = fixP -> fx_pcrel; | |
1043 | if(add_symbolP) | |
1044 | add_symbol_N_TYPE = add_symbolP -> sy_type & N_TYPE; | |
1045 | if (sub_symbolP) | |
1046 | { | |
1047 | if(!add_symbolP) /* Its just -sym */ | |
1048 | { | |
1049 | if(sub_symbolP->sy_type!=N_ABS) | |
1050 | as_warn("Negative of non-absolute symbol %s", sub_symbolP->sy_name); | |
1051 | add_number-=sub_symbolP->sy_value; | |
1052 | } | |
1053 | else if ( ((sub_symbolP -> sy_type ^ add_symbol_N_TYPE) & N_TYPE) == 0 | |
1054 | && ( add_symbol_N_TYPE == N_DATA | |
1055 | || add_symbol_N_TYPE == N_TEXT | |
1056 | || add_symbol_N_TYPE == N_BSS | |
1057 | || add_symbol_N_TYPE == N_ABS)) | |
1058 | { | |
1059 | /* Difference of 2 symbols from same segment. */ | |
1060 | /* Can't make difference of 2 undefineds: 'value' means */ | |
1061 | /* something different for N_UNDF. */ | |
1062 | add_number += add_symbolP -> sy_value - sub_symbolP -> sy_value; | |
1063 | add_symbolP = NULL; | |
1064 | fixP -> fx_addsy = NULL; | |
1065 | } | |
1066 | else | |
1067 | { | |
1068 | /* Different segments in subtraction. */ | |
1069 | know( sub_symbolP -> sy_type != (N_ABS | N_EXT)) | |
1070 | if (sub_symbolP -> sy_type == N_ABS) | |
1071 | add_number -= sub_symbolP -> sy_value; | |
1072 | else | |
1073 | { | |
1074 | as_warn("Can't emit reloc {- %s-seg symbol \"%s\"} @ file address %d.", | |
1075 | seg_name[(int)N_TYPE_seg[sub_symbolP->sy_type&N_TYPE]], | |
1076 | sub_symbolP -> sy_name, fragP -> fr_address + where); | |
1077 | } | |
1078 | } | |
1079 | } | |
1080 | if (add_symbolP) | |
1081 | { | |
1082 | if (add_symbol_N_TYPE == this_segment_type && pcrel) | |
1083 | { | |
1084 | /* | |
1085 | * This fixup was made when the symbol's segment was | |
1086 | * SEG_UNKNOWN, but it is now in the local segment. | |
1087 | * So we know how to do the address without relocation. | |
1088 | */ | |
1089 | add_number += add_symbolP -> sy_value; | |
1090 | add_number -= | |
1091 | #ifndef NS32K | |
1092 | size + | |
1093 | #endif | |
1094 | where + fragP -> fr_address; | |
1095 | #if defined(NS32K) && defined(SEQUENT_COMPATABILITY) | |
1096 | if (fragP->fr_bsr) | |
1097 | add_number -= 0x12; /* FOO Kludge alert! */ | |
1098 | #endif | |
1099 | /* Kenny thinks this needs * | |
1100 | /* add_number +=size-2; */ | |
1101 | pcrel = 0; /* Lie. Don't want further pcrel processing. */ | |
1102 | fixP -> fx_addsy = NULL; /* No relocations please. */ | |
1103 | /* | |
1104 | * It would be nice to check that the address does not overflow. | |
1105 | * I didn't do this check because: | |
1106 | * + It is machine dependent in the general case (eg 32032) | |
1107 | * + Compiler output will never need this checking, so why | |
1108 | * slow down the usual case? | |
1109 | */ | |
1110 | } | |
1111 | else | |
1112 | { | |
1113 | switch (add_symbol_N_TYPE) | |
1114 | { | |
1115 | case N_ABS: | |
1116 | add_number += add_symbolP -> sy_value; | |
1117 | fixP -> fx_addsy = NULL; | |
1118 | add_symbolP = NULL; | |
1119 | break; | |
1120 | ||
1121 | case N_BSS: | |
1122 | case N_DATA: | |
1123 | case N_TEXT: | |
1124 | seg_reloc_count ++; | |
1125 | add_number += add_symbolP -> sy_value; | |
1126 | break; | |
1127 | ||
1128 | case N_UNDF: | |
1129 | seg_reloc_count ++; | |
1130 | break; | |
1131 | ||
1132 | default: | |
1133 | BAD_CASE( add_symbol_N_TYPE ); | |
1134 | break; | |
1135 | } /* switch on symbol seg */ | |
1136 | } /* if not in local seg */ | |
1137 | } /* if there was a + symbol */ | |
1138 | if (pcrel) | |
1139 | { | |
1140 | add_number -= | |
1141 | #ifndef NS32K | |
1142 | size + | |
1143 | #endif | |
1144 | where + fragP -> fr_address; | |
1145 | if (add_symbolP == 0) | |
1146 | { | |
1147 | fixP -> fx_addsy = & abs_symbol; | |
1148 | seg_reloc_count ++; | |
1149 | } | |
1150 | } | |
1151 | /* OVE added fx_im_disp for ns32k and others */ | |
1152 | if (!fixP->fx_bit_fixP) { | |
1153 | /* JF I hope this works . . . */ | |
1154 | if((size==1 && (add_number& ~0xFF) && (add_number&~0xFF!=(-1&~0xFF))) || | |
1155 | (size==2 && (add_number& ~0xFFFF) && (add_number&~0xFFFF!=(-1&~0xFFFF)))) | |
1156 | as_warn("Fixup of %d too large for field width of %d",add_number, size); | |
1157 | ||
1158 | switch (fixP->fx_im_disp) { | |
1159 | case 0: | |
1160 | #if defined(SPARC) || defined(I860) | |
1161 | fixP->fx_addnumber = add_number; | |
1162 | md_number_to_imm(place, add_number, size, fixP, this_segment_type); | |
1163 | #else | |
1164 | md_number_to_imm (place, add_number, size); | |
1165 | /* OVE: the immediates, like disps, have lsb at lowest address */ | |
1166 | #endif | |
1167 | break; | |
1168 | case 1: | |
1169 | md_number_to_disp (place, | |
1170 | fixP->fx_pcrel ? add_number+fixP->fx_pcrel_adjust:add_number, | |
1171 | size); | |
1172 | break; | |
1173 | case 2: /* fix requested for .long .word etc */ | |
1174 | md_number_to_chars (place, add_number, size); | |
1175 | break; | |
1176 | default: | |
1177 | as_fatal("Internal error in write.c in fixup_segment"); | |
1178 | } /* OVE: maybe one ought to put _imm _disp _chars in one md-func */ | |
1179 | } else { | |
1180 | md_number_to_field (place, add_number, fixP->fx_bit_fixP); | |
1181 | } | |
1182 | } /* For each fixS in this segment. */ | |
1183 | return (seg_reloc_count); | |
1184 | } /* fixup_segment() */ | |
1185 | \f | |
1186 | ||
1187 | /* The sparc needs its own emit_relocations() */ | |
1188 | #if !defined(SPARC) && !defined(I860) | |
1189 | /* | |
1190 | * emit_relocations() | |
1191 | * | |
1192 | * Crawl along a fixS chain. Emit the segment's relocations. | |
1193 | */ | |
1194 | static void | |
1195 | emit_relocations (fixP, segment_address_in_file) | |
1196 | register fixS * fixP; /* Fixup chain for this segment. */ | |
1197 | relax_addressT segment_address_in_file; | |
1198 | { | |
1199 | struct relocation_info ri; | |
1200 | register symbolS * symbolP; | |
1201 | ||
1202 | /* JF this is for paranoia */ | |
1203 | bzero((char *)&ri,sizeof(ri)); | |
1204 | for ( ; fixP; fixP = fixP -> fx_next) | |
1205 | { | |
1206 | if (symbolP = fixP -> fx_addsy) | |
1207 | { | |
1208 | ||
1209 | #ifdef NS32K | |
1210 | /* These two 'cuz of NS32K */ | |
1211 | ri . r_bsr = fixP -> fx_bsr; | |
1212 | ri . r_disp = fixP -> fx_im_disp; | |
1213 | #endif | |
1214 | ||
1215 | ri . r_length = nbytes_r_length [fixP -> fx_size]; | |
1216 | ri . r_pcrel = fixP -> fx_pcrel; | |
1217 | ri . r_address = fixP -> fx_frag -> fr_address | |
1218 | + fixP -> fx_where | |
1219 | - segment_address_in_file; | |
1220 | if ((symbolP -> sy_type & N_TYPE) == N_UNDF) | |
1221 | { | |
1222 | ri . r_extern = 1; | |
1223 | ri . r_symbolnum = symbolP -> sy_number; | |
1224 | } | |
1225 | else | |
1226 | { | |
1227 | ri . r_extern = 0; | |
1228 | ri . r_symbolnum = symbolP -> sy_type & N_TYPE; | |
1229 | } | |
1230 | ||
1231 | /* | |
1232 | The 68k machines assign bit-fields from higher bits to | |
1233 | lower bits ("left-to-right") within the int. VAXen assign | |
1234 | bit-fields from lower bits to higher bits ("right-to-left"). | |
1235 | Both handle multi-byte numbers in their usual fashion | |
1236 | (Big-endian and little-endian stuff). | |
1237 | Thus we need a machine dependent routine to make | |
1238 | sure the structure is written out correctly. FUN! | |
1239 | */ | |
1240 | md_ri_to_chars((char *) &ri, ri); | |
1241 | append (&next_object_file_charP, (char *)& ri, (unsigned long)sizeof(ri)); | |
1242 | } | |
1243 | } | |
1244 | ||
1245 | } | |
1246 | #endif | |
1247 | ||
1248 | int | |
1249 | is_dnrange(f1,f2) | |
1250 | struct frag *f1,*f2; | |
1251 | { | |
1252 | while(f1) { | |
1253 | if(f1->fr_next==f2) | |
1254 | return 1; | |
1255 | f1=f1->fr_next; | |
1256 | } | |
1257 | return 0; | |
1258 | } | |
1259 | /* End: as-write.c */ |