1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23#ifndef RLD
24/*
25 * This file contains the routines to do relocation for the i860.  Since this is
26 * a RISC machine that has items to be relocated that are not always 32 bits
27 * wide and that two different references to the same symbol may share the same
28 * high 16 bits scattered relocation can't be performed.  It is treated as an
29 * error in the object file to see a scattered relocation entry.  And it is an
30 * interal error if any section has fine relocations (this may be relaxed at
31 * some time in the future if all the cases can be delt with).
32 */
33#include <stdlib.h>
34#include <stdio.h>
35#include <stdarg.h>
36#include <mach/mach.h>
37#include <mach-o/loader.h>
38#include <mach-o/reloc.h>
39#include <mach-o/i860/reloc.h>
40#include <mach-o/nlist.h>
41#include "stuff/bool.h"
42#include "stuff/bytesex.h"
43
44#include "ld.h"
45#include "live_refs.h"
46#include "objects.h"
47#include "sections.h"
48#include "pass1.h"
49#include "symbols.h"
50#include "pass2.h"
51#include "generic_reloc.h"
52#include "i860_reloc.h"
53#include "dylibs.h"
54
55/*
56 * i860_reloc() relocates the contents of the specified section for the
57 * relocation entries using the section map from the current object (cur_obj).
58 */
59__private_extern__
60void
61i860_reloc(
62char *contents,
63struct relocation_info *relocs,
64struct section_map *section_map)
65{
66    unsigned long i, j, symbolnum, value;
67    unsigned long instruction, immediate;
68    struct nlist *nlists;
69    char *strings;
70    enum bool force_extern_reloc;
71    struct undefined_map *undefined_map;
72    struct merged_symbol *merged_symbol;
73    struct section_map *local_map, *pair_local_map;
74    struct relocation_info *reloc, *pair_reloc;
75    struct scattered_relocation_info *sreloc, *spair_reloc;
76    unsigned long r_address, r_symbolnum, r_pcrel, r_length, r_extern,
77		  r_scattered, r_value, pair_r_symbolnum, pair_r_value;
78    enum reloc_type_i860 r_type, pair_r_type;
79    unsigned short other_half;
80    unsigned long offset;
81
82#ifdef DEBUG
83	/*
84	 * The compiler "warnings: `merged_symbol', `local_map' and `immediate'
85	 * may be used uninitialized in this function" can safely be ignored
86	 */
87	merged_symbol = NULL;
88	local_map = NULL;
89	immediate = 0;
90	pair_local_map = NULL;
91	pair_r_symbolnum = 0;
92	pair_r_value = 0;
93	other_half = 0;
94	offset = 0;
95#endif /* DEBUG */
96
97	for(i = 0; i < section_map->s->nreloc; i++){
98	    force_extern_reloc = FALSE;
99	    /*
100	     * Break out the fields of the relocation entry and set pointer to
101	     * the type of relocation entry it is (for updating later).
102	     */
103	    if((relocs[i].r_address & R_SCATTERED) != 0){
104		sreloc = (struct scattered_relocation_info *)(relocs + i);
105		reloc = NULL;
106		r_scattered = 1;
107		r_address = sreloc->r_address;
108		r_pcrel = sreloc->r_pcrel;
109		r_length = sreloc->r_length;
110		r_value = sreloc->r_value;
111		r_type = (enum reloc_type_i860)sreloc->r_type;
112		r_extern = 0;
113		/*
114		 * Since the r_value field is reserved in a I860_RELOC_PAIR
115		 * type to report the correct error a check for a stray
116		 * I860_RELOC_PAIR relocation types needs to be done before
117		 * it is assumed that r_value is legal.  A I860_RELOC_PAIR
118		 * only follows I860_RELOC_HIGH, I860_RELOC_HIGHADJ and
119		 * I860_RELOC_SECTDIFF relocation types and it is an error
120		 * to see one otherwise.
121		 */
122		if(r_type == I860_RELOC_PAIR){
123		    error_with_cur_obj("stray relocation I860_RELOC_PAIR entry "
124			"(%lu) in section (%.16s,%.16s)", i,
125			section_map->s->segname, section_map->s->sectname);
126		    continue;
127		}
128		/* calculate the r_symbolnum (n_sect) from the r_value */
129		r_symbolnum = 0;
130		for(j = 0; j < cur_obj->nsection_maps; j++){
131		    if(r_value >= cur_obj->section_maps[j].s->addr &&
132		       r_value < cur_obj->section_maps[j].s->addr +
133				 cur_obj->section_maps[j].s->size){
134			r_symbolnum = j + 1;
135			break;
136		    }
137		}
138		if(r_symbolnum == 0){
139		    /*
140		     * The edge case where the last address past then end of
141		     * of the last section is referenced.
142		     */
143		    for(j = 0; j < cur_obj->nsection_maps; j++){
144			if(r_value == cur_obj->section_maps[j].s->addr +
145				      cur_obj->section_maps[j].s->size){
146			    r_symbolnum = j + 1;
147			    break;
148			}
149		    }
150		    if(r_symbolnum == 0){
151			error_with_cur_obj("r_value (0x%x) field of relocation "
152			    "entry %lu in section (%.16s,%.16s) out of range",
153			    (unsigned int)r_value, i, section_map->s->segname,
154			    section_map->s->sectname);
155			return;
156		    }
157		}
158	    }
159	    else{
160		reloc = relocs + i;
161		sreloc = NULL;
162		r_scattered = 0;
163		r_address = reloc->r_address;
164		r_pcrel = reloc->r_pcrel;
165		r_length = reloc->r_length;
166		r_extern = reloc->r_extern;
167		r_symbolnum = reloc->r_symbolnum;
168		r_type = (enum reloc_type_i860)reloc->r_type;
169		r_value = 0;
170	    }
171	    /*
172	     * I860_RELOC_PAIR relocation types only follow I860_RELOC_HIGH,
173	     * I860_RELOC_HIGHADJ and I860_RELOC_SECTDIFF relocation types and
174	     * it is an error to see one otherwise.
175	     */
176	    if(r_type == I860_RELOC_PAIR){
177		error_with_cur_obj("stray relocation I860_RELOC_PAIR entry "
178		    "(%lu) in section (%.16s,%.16s)", i,
179		    section_map->s->segname, section_map->s->sectname);
180		continue;
181	    }
182	    /*
183	     * The r_address field is really an offset into the contents of the
184	     * section and must reference something inside the section (Note
185	     * that this is not the case for I860_RELOC_PAIR entries but this
186	     * can't be one with the above check).
187	     */
188	    if(r_address >= section_map->s->size){
189		error_with_cur_obj("r_address (0x%x) field of relocation entry "
190		    "%lu in section (%.16s,%.16s) out of range",
191		    (unsigned int)r_address, i, section_map->s->segname,
192		    section_map->s->sectname);
193		return;
194	    }
195	    /*
196	     * If this relocation type is to have a pair make sure it is there
197	     * and then break out it's fields.
198	     */
199	    pair_r_type = (enum reloc_type_i860)0;
200	    pair_reloc = NULL;
201	    spair_reloc = NULL;
202	    if(r_type == I860_RELOC_HIGH || r_type == I860_RELOC_HIGHADJ){
203		if(i + 1 < section_map->s->nreloc){
204		    pair_reloc = relocs + i + 1;
205		    if((pair_reloc->r_address & R_SCATTERED) != 0){
206			spair_reloc = (struct scattered_relocation_info *)
207				      pair_reloc;
208			pair_reloc  = NULL;
209			pair_r_type = (enum reloc_type_i860)spair_reloc->r_type;
210			other_half  = spair_reloc->r_address & 0xffff;
211		    }
212		    else{
213			pair_r_type = (enum reloc_type_i860)pair_reloc->r_type;
214			other_half  = pair_reloc->r_address & 0xffff;
215		    }
216		}
217		if((pair_reloc == NULL && spair_reloc == NULL) ||
218		   pair_r_type != I860_RELOC_PAIR){
219		    error_with_cur_obj("relocation entry (%lu) in section "
220			"(%.16s,%.16s) missing following associated "
221			"I860_RELOC_PAIR entry", i, section_map->s->segname,
222			section_map->s->sectname);
223		    continue;
224		}
225	    }
226	    else if(r_type == I860_RELOC_SECTDIFF){
227		if(r_scattered != 1){
228		    error_with_cur_obj("relocation entry (%lu) in section "
229			"(%.16s,%.16s) r_type is I860_RELOC_SECTDIFF but "
230			"relocation entry not scattered type", i,
231			section_map->s->segname, section_map->s->sectname);
232		    continue;
233		}
234		if(i + 1 < section_map->s->nreloc){
235		    pair_reloc = relocs + i + 1;
236		    if((pair_reloc->r_address & R_SCATTERED) != 0){
237			spair_reloc = (struct scattered_relocation_info *)
238				      pair_reloc;
239			pair_reloc = NULL;
240			pair_r_type = (enum reloc_type_i860)spair_reloc->r_type;
241			pair_r_value = spair_reloc->r_value;
242		    }
243		    else{
244			error_with_cur_obj("relocation entry (%lu) in section "
245			    "(%.16s,%.16s) following associated relocation "
246			    "entry not scattered type", i,
247			    section_map->s->segname, section_map->s->sectname);
248			continue;
249		    }
250		}
251		if((pair_reloc == NULL && spair_reloc == NULL) ||
252		   pair_r_type != I860_RELOC_PAIR){
253		    error_with_cur_obj("relocation entry (%lu) in section "
254			"(%.16s,%.16s) missing following associated "
255			"I860_RELOC_PAIR entry", i, section_map->s->segname,
256			section_map->s->sectname);
257		    continue;
258		}
259		/*
260		 * Calculate the pair_r_symbolnum (n_sect) from the
261		 * pair_r_value.
262		 */
263		pair_r_symbolnum = 0;
264		for(j = 0; j < cur_obj->nsection_maps; j++){
265		    if(pair_r_value >= cur_obj->section_maps[j].s->addr &&
266		       pair_r_value < cur_obj->section_maps[j].s->addr +
267				 cur_obj->section_maps[j].s->size){
268			pair_r_symbolnum = j + 1;
269			break;
270		    }
271		}
272		if(pair_r_symbolnum == 0){
273		    error_with_cur_obj("r_value (0x%x) field of relocation "
274			"entry %lu in section (%.16s,%.16s) out of range",
275			(unsigned int)r_value, i + 1, section_map->s->segname,
276			section_map->s->sectname);
277		    return;
278		}
279	    }
280	    /*
281	     * If r_extern is set this relocation entry is an external entry
282	     * else it is a local entry.
283	     */
284	    if(r_extern){
285		/*
286		 * This is an external relocation entry.  So the value to be
287		 * added to the item to be relocated is the value of the symbol.
288		 * r_symbolnum is an index into the input file's symbol table
289		 * of the symbol being refered to.  The symbol must be an
290		 * undefined or coalesced symbol to be used in an external
291		 * relocation entry.
292		 */
293		if(r_symbolnum >= cur_obj->symtab->nsyms){
294		    error_with_cur_obj("r_symbolnum (%lu) field of external "
295			"relocation entry %lu in section (%.16s,%.16s) out of "
296			"range", r_symbolnum, i, section_map->s->segname,
297			section_map->s->sectname);
298		    return;
299		}
300		symbolnum = r_symbolnum;
301		undefined_map = bsearch(&symbolnum, cur_obj->undefined_maps,
302		    cur_obj->nundefineds, sizeof(struct undefined_map),
303		    (int (*)(const void *, const void *))undef_bsearch);
304		if(undefined_map != NULL){
305		    merged_symbol = undefined_map->merged_symbol;
306		}
307		else{
308		    nlists = (struct nlist *)(cur_obj->obj_addr +
309					      cur_obj->symtab->symoff);
310		    strings = (char *)(cur_obj->obj_addr +
311				       cur_obj->symtab->stroff);
312		    if((nlists[symbolnum].n_type & N_EXT) != N_EXT){
313			error_with_cur_obj("r_symbolnum (%lu) field of external"
314			    " relocation entry %lu in section (%.16s,%.16s) "
315			    "refers to a non-external symbol", symbolnum, i,
316			    section_map->s->segname, section_map->s->sectname);
317			return;
318		    }
319		    /*
320		     * We must allow and create references to defined global
321		     * coalesced symbols with external relocation entries so
322		     * that the dynamic linker can relocate all references to
323		     * the same symbol.
324		     */
325		    if((nlists[symbolnum].n_type & N_TYPE) == N_SECT &&
326		       (cur_obj->section_maps[nlists[symbolnum].n_sect-1].
327			s->flags & SECTION_TYPE) == S_COALESCED){
328			merged_symbol = lookup_symbol(strings +
329					     nlists[symbolnum].n_un.n_strx);
330			if(merged_symbol->name_len == 0){
331			    fatal("internal error, in i860_reloc() failed to "
332			          "lookup coalesced symbol %s", strings +
333				  nlists[symbolnum].n_un.n_strx);
334			}
335		    }
336		    else{
337			if((nlists[symbolnum].n_type & N_EXT) != N_EXT ||
338			   (nlists[symbolnum].n_type & N_TYPE) != N_UNDF){
339			    error_with_cur_obj("r_symbolnum (%lu) field of "
340				"external relocation entry %lu in section "
341				"(%.16s,%.16s) refers to a non-undefined "
342				"symbol", symbolnum, i, section_map->s->segname,
343				 section_map->s->sectname);
344			    return;
345			}
346			print_obj_name(cur_obj);
347			fatal("internal error, in i860_reloc() symbol index %lu"
348			    " in above file not in undefined map", symbolnum);
349		    }
350		}
351		if((merged_symbol->nlist.n_type & N_TYPE) == N_SECT &&
352		   (get_output_section(merged_symbol->nlist.n_sect)->
353		    flags & SECTION_TYPE) == S_COALESCED){
354		    if(((merged_symbol->nlist.n_type & N_PEXT) == N_PEXT &&
355			keep_private_externs == FALSE) ||
356		       dynamic == FALSE ||
357		       (output_for_dyld && has_dynamic_linker_command))
358			force_extern_reloc = FALSE;
359		    else
360			force_extern_reloc = TRUE;
361		}
362		/*
363		 * If this is an indirect symbol resolve indirection (all chains
364		 * of indirect symbols have been resolved so that they point at
365		 * a symbol that is not an indirect symbol).
366		 */
367		if((merged_symbol->nlist.n_type & N_TYPE) == N_INDR)
368		    merged_symbol = (struct merged_symbol *)
369				    merged_symbol->nlist.n_value;
370		/*
371		 * If the symbol is undefined (or common) or a global coalesced
372		 * symbol where we need to force an external relocation entry
373		 * and we are not prebinding no relocation is done.  Or if the
374		 * output file is a multi module MH_DYLIB no relocation is done
375		 * unless the symbol is a private extern or we are prebinding.
376		 */
377		if(((merged_symbol->nlist.n_type & N_TYPE) == N_UNDF) ||
378		   (force_extern_reloc == TRUE && prebinding == FALSE) ||
379		   ((filetype == MH_DYLIB && multi_module_dylib == TRUE) &&
380		    (((merged_symbol->nlist.n_type & N_PEXT) != N_PEXT) &&
381		     prebinding == FALSE) ) )
382		    value = 0;
383		else{
384		    value = merged_symbol->nlist.n_value;
385		    /*
386		     * To know which type (local or scattered) of relocation
387		     * entry to convert this one to (if relocation entries are
388		     * saved) the offset to be added to the symbol's value is
389		     * needed to see if it reaches outside the block in which
390		     * the symbol is in.  In here if the offset is not zero then
391		     * it is assumed to reach out of the block and a scattered
392		     * relocation entry is used.
393		     */
394		    if(r_type == I860_RELOC_VANILLA){
395			switch(r_length){
396			case 0: /* byte */
397			    offset = get_byte((char *)(contents + r_address));
398			    break;
399			case 1: /* word (2 byte) */
400			    offset = get_short((short *)(contents + r_address));
401			    break;
402			case 2: /* long (4 byte) */
403			    offset = get_long((long *)(contents + r_address));
404			    break;
405			default:
406			    /* the error check is catched below */
407			    break;
408			}
409			if(r_pcrel)
410			    offset += section_map->s->addr + r_address;
411		    }
412		    else{
413			instruction = get_long((long *)(contents + r_address));
414			switch(r_type){
415			case I860_RELOC_HIGH:
416			    offset = ((instruction & 0xffff) << 16) |
417				     other_half;
418			    break;
419			case I860_RELOC_HIGHADJ:
420			    if(other_half & 0x8000)
421				offset = ((instruction & 0xffff) << 16) +
422					 (other_half | 0xffff0000);
423			    else
424				offset = ((instruction & 0xffff) << 16) +
425					 other_half;
426			    break;
427			case I860_RELOC_LOW0:
428			    offset = instruction & 0xffff;
429			    if((offset & 0x8000) != 0)
430				offset |= 0xffff0000;
431			    break;
432			case I860_RELOC_LOW1:
433			    offset = instruction & 0xfffe;
434			    if((offset & 0x8000) != 0)
435				offset |= 0xffff0000;
436			    break;
437			case I860_RELOC_LOW2:
438			    offset = instruction & 0xfffc;
439			    if((offset & 0x8000) != 0)
440				offset |= 0xffff0000;
441			    break;
442			case I860_RELOC_LOW3:
443			    offset = instruction & 0xfff8;
444			    if((offset & 0x8000) != 0)
445				offset |= 0xffff0000;
446			    break;
447			case I860_RELOC_LOW4:
448			    offset = instruction &0xfff0;
449			    if((offset & 0x8000) != 0)
450				offset |= 0xffff0000;
451			    break;
452			case I860_RELOC_SPLIT0:
453			    offset = ((instruction >> 5) & 0xf800) |
454				     (instruction & 0x7ff);
455			    if((offset & 0x8000) != 0)
456				offset |= 0xffff0000;
457			    /*
458			     * This is used both for a 16 bit immediate or a
459			     * branch instruction.  If it is a branch
460			     * instruction then r_pcrel is set and the
461			     * immediate is a 32 bit word displacement
462			     * otherwise it is a byte displacement and r_pcrel
463			     * is not set.
464			     */
465			    if(r_pcrel)
466				offset <<= 2; /* long to byte address */
467			    break;
468			case I860_RELOC_SPLIT1:
469			    offset = ((instruction >> 5) & 0xf800) |
470				     (instruction & 0x7fe);
471			    if((offset & 0x8000) != 0)
472				offset |= 0xffff0000;
473			    break;
474			case I860_RELOC_SPLIT2:
475			    offset = ((instruction >> 5) & 0xf800) |
476				     (instruction & 0x7fc);
477			    /* sign extend if needed */
478			    if((offset & 0x8000) != 0)
479				offset |= 0xffff0000;
480			    break;
481			case I860_RELOC_BRADDR:
482			    offset = instruction & 0x03ffffff;
483			    if((offset & 0x02000000) != 0)
484				offset |= 0xfc000000;
485			    /*
486			     * The immediate is always a 32 bit word
487			     * displacement.
488			     */
489			    offset <<= 2;
490			    break;
491			default:
492			    /* the error check is catched below */
493			    break;
494			}
495		    }
496		}
497
498		if((merged_symbol->nlist.n_type & N_TYPE) == N_SECT)
499		    output_sections[merged_symbol->nlist.n_sect]->referenced =
500									   TRUE;
501	    }
502	    else{
503		/*
504		 * This is a local relocation entry (the value to which the item
505		 * to be relocated is refering to is defined in section number
506		 * r_symbolnum).  So the address of that section in the input
507		 * file is subtracted and the value of that section in the
508		 * output is added to the item being relocated.
509		 */
510		value = 0;
511		/*
512		 * If the symbol is not in any section the value to be added to
513		 * the item to be relocated is the zero above and any pc
514		 * relative change in value added below.
515		 */
516		if(r_symbolnum != R_ABS){
517		    if(r_symbolnum > cur_obj->nsection_maps){
518			error_with_cur_obj("r_symbolnum (%lu) field of local "
519			    "relocation entry %lu in section (%.16s,%.16s) "
520			    "out of range", r_symbolnum, i,
521			    section_map->s->segname, section_map->s->sectname);
522			return;
523		    }
524		    local_map = &(cur_obj->section_maps[r_symbolnum - 1]);
525		    local_map->output_section->referenced = TRUE;
526		    if(local_map->s->flags & S_ATTR_DEBUG){
527			error_with_cur_obj("illegal reference to debug section,"
528			    " from non-debug section (%.16s,%.16s) via "
529			    "relocation entry (%lu) to section (%.16s,%.16s)",
530			    section_map->s->segname, section_map->s->sectname,
531			    i, local_map->s->segname, local_map->s->sectname);
532			return;
533		    }
534		    pair_local_map = NULL;
535		    if(r_type == I860_RELOC_SECTDIFF){
536			pair_local_map =
537			    &(cur_obj->section_maps[pair_r_symbolnum - 1]);
538			pair_local_map->output_section->referenced = TRUE;
539			if(pair_local_map->s->flags & S_ATTR_DEBUG){
540			    error_with_cur_obj("illegal reference to debug "
541				"section, from non-debug section (%.16s,%.16s) "
542				"via relocation entry (%lu) to section (%.16s,"
543				"%.16s)", section_map->s->segname,
544				section_map->s->sectname, i,
545				pair_local_map->s->segname,
546				pair_local_map->s->sectname);
547			    return;
548			}
549		    }
550		    if(local_map->nfine_relocs == 0 &&
551		       (pair_local_map == NULL ||
552			pair_local_map->nfine_relocs == 0) ){
553			if(r_type == I860_RELOC_SECTDIFF){
554			    value = - local_map->s->addr
555				    + (local_map->output_section->s.addr +
556				       local_map->offset)
557				    + pair_local_map->s->addr
558				    - (pair_local_map->output_section->s.addr +
559				       pair_local_map->offset);
560			}
561			else{
562			    value = - local_map->s->addr
563				    + (local_map->output_section->s.addr +
564				       local_map->offset);
565			}
566		    }
567		    else{
568			/*
569			 * For items to be relocated that refer to a section
570			 * with fine relocation it is an interal error for the
571			 * i860 cputype.
572			 */
573			fatal("internal error, in i860_reloc() section (%.16s,"
574			      "%.16s) has fine relocs", local_map->s->segname,
575			      local_map->s->sectname);
576		    }
577		}
578	    }
579	    if(r_pcrel){
580		/*
581		 * This is a relocation entry is also pc relative which means
582		 * the value of the pc will get added to it when it is executed.
583		 * The item being relocated has the value of the pc in the input
584		 * file subtracted from it.  So to relocate this the value of
585		 * pc in the input file is added and then value of the output
586		 * pc is subtracted (since the offset into the section remains
587		 * constant it is not added in and then subtracted out).
588		 */
589		if(section_map->nfine_relocs == 0)
590		    value += + section_map->s->addr /* + r_address */
591			     - (section_map->output_section->s.addr +
592				section_map->offset /* + r_address */);
593		else{
594		    /*
595		     * For items to be relocated that refer to a section
596		     * with fine relocation it is an interal error for the
597		     * i860 cputype.
598		     */
599		    fatal("internal error, in i860_reloc() section (%.16s,"
600			  "%.16s) has fine relocs", local_map->s->segname,
601			  local_map->s->sectname);
602		}
603	    }
604
605	    /*
606	     * Do "vanilla" and "sectdiff" relocation just like in
607	     * generic_reloc() first.
608	     */
609	    if(r_type == I860_RELOC_VANILLA ||
610	       r_type == I860_RELOC_SECTDIFF){
611		switch(r_length){
612		case 0: /* byte */
613		    value += get_byte((char *)(contents + r_address));
614		    if( (value & 0xffffff00) &&
615		       ((value & 0xffffff80) != 0xffffff80))
616			error_with_cur_obj("relocation for entry %lu in section"
617			    " (%.16s,%.16s) does not fit in 1 byte", i,
618			    section_map->s->segname, section_map->s->sectname);
619		    set_byte((char *)(contents + r_address), value);
620		    break;
621		case 1: /* word (2 byte) */
622		    value += get_short((short *)(contents + r_address));
623		    if( (value & 0xffff0000) &&
624		       ((value & 0xffff8000) != 0xffff8000))
625			error_with_cur_obj("relocation for entry %lu in section"
626			    " (%.16s,%.16s) does not fit in 2 bytes", i,
627			    section_map->s->segname, section_map->s->sectname);
628		    set_short((short *)(contents + r_address), value);
629		    break;
630		case 2: /* long (4 byte) */
631		    value += get_long((long *)(contents + r_address));
632		    set_long((long *)(contents + r_address), value);
633		    break;
634		default:
635		    error_with_cur_obj("r_length field of relocation entry %lu "
636			"in section (%.16s,%.16s) invalid", i,
637			section_map->s->segname, section_map->s->sectname);
638		    return;
639		}
640	    }
641	    /*
642	     * Do i860 specific relocation based on the r_type.
643	     */
644	    else{
645		instruction = get_long((long *)(contents + r_address));
646		switch(r_type){
647		case I860_RELOC_HIGH:
648		    immediate = ((instruction & 0xffff) << 16) | other_half;
649		    immediate += value;
650		    instruction = (instruction & 0xffff0000) |
651				  ((immediate >> 16) & 0xffff);
652		    other_half = immediate & 0xffff;
653		    break;
654		case I860_RELOC_HIGHADJ:
655		    if(other_half & 0x8000)
656			immediate = ((instruction & 0xffff) << 16) +
657				    (other_half | 0xffff0000);
658		    else
659			immediate = ((instruction & 0xffff) << 16) + other_half;
660		    immediate += value;
661		    if(immediate & 0x8000)
662			instruction = (instruction & 0xffff0000) |
663				      (((immediate >> 16) + 1) & 0xffff);
664		    else
665			instruction = (instruction & 0xffff0000) |
666				      ((immediate >> 16) & 0xffff);
667		    other_half = immediate & 0xffff;
668		    break;
669		case I860_RELOC_LOW0:
670		    immediate = instruction & 0xffff;
671		    if((immediate & 0x8000) != 0)
672			immediate |= 0xffff0000;
673		    immediate += value;
674		    instruction = (instruction & 0xffff0000) |
675				  (immediate & 0xffff);
676		    break;
677		case I860_RELOC_LOW1:
678		    immediate = instruction & 0xfffe;
679		    if((immediate & 0x8000) != 0)
680			immediate |= 0xffff0000;
681		    immediate += value;
682		    instruction = (instruction & 0xffff0001) |
683				  (immediate & 0xfffe);
684		    break;
685		case I860_RELOC_LOW2:
686		    immediate = instruction & 0xfffc;
687		    if((immediate & 0x8000) != 0)
688			immediate |= 0xffff0000;
689		    immediate += value;
690		    instruction = (instruction & 0xffff0003) |
691				  (immediate & 0xfffc);
692		    break;
693		case I860_RELOC_LOW3:
694		    immediate = instruction & 0xfff8;
695		    if((immediate & 0x8000) != 0)
696			immediate |= 0xffff0000;
697		    immediate += value;
698		    instruction = (instruction & 0xffff0007) |
699				  (immediate & 0xfff8);
700		    break;
701		case I860_RELOC_LOW4:
702		    immediate = instruction &0xfff0;
703		    if((immediate & 0x8000) != 0)
704			immediate |= 0xffff0000;
705		    immediate += value;
706		    instruction = (instruction & 0xffff000f) |
707				  (immediate & 0xfff0);
708		    break;
709		case I860_RELOC_SPLIT0:
710		    immediate = ((instruction >> 5) & 0xf800) |
711				(instruction & 0x7ff);
712		    if((immediate & 0x8000) != 0)
713			immediate |= 0xffff0000;
714		    /*
715		     * This is used both for a 16 bit immediate or a branch
716		     * instruction.  If it is a branch instruction then r_pcrel
717		     * is set and the immediate is a 32 bit word displacement
718		     * otherwise it is a byte displacement and r_pcrel is not
719		     * set.
720		     */
721		    if(r_pcrel)
722			immediate <<= 2;	/* long to byte address */
723		    immediate += value;
724		    if(r_pcrel)
725			immediate >>= 2;	/* Back to long address */
726		    instruction = (instruction & 0xffe0f800) |
727				  ((immediate & 0xf800) << 5) |
728				  (immediate & 0x7ff);
729		    break;
730		case I860_RELOC_SPLIT1:
731		    immediate = ((instruction >> 5) & 0xf800) |
732				(instruction & 0x7fe);
733		    if((immediate & 0x8000) != 0)
734			immediate |= 0xffff0000;
735		    immediate += value;
736		    instruction = (instruction & 0xffe0f801) |
737				  ((immediate & 0xf800) << 5) |
738				  (immediate & 0x7fe);
739		    break;
740		case I860_RELOC_SPLIT2:
741		    immediate = ((instruction >> 5) & 0xf800) |
742				(instruction & 0x7fc);
743		    if((immediate & 0x8000) != 0)
744			immediate |= 0xffff0000;
745		    immediate += value;
746		    instruction = (instruction & 0xffe0f803) |
747				  ((immediate & 0xf800) << 5) |
748				  (immediate & 0x7FC);
749		    break;
750		case I860_RELOC_BRADDR:
751		    immediate = instruction & 0x03ffffff;
752		    if((immediate & 0x02000000) != 0)
753			immediate |= 0xfc000000;
754		    /*
755		     * The immediate is always a 32 bit word displacement.
756		     */
757		    immediate <<= 2;
758		    immediate += value;
759		    immediate >>= 2;
760		    instruction = (instruction & 0xfc000000) |
761		    		  (immediate & 0x03ffffff);
762		    break;
763		case I860_RELOC_PAIR:
764		default:
765		    error_with_cur_obj("r_type field of relocation entry %lu "
766			"in section (%.16s,%.16s) invalid", i,
767			section_map->s->segname, section_map->s->sectname);
768		    continue;
769		}
770		set_long((long *)(contents + r_address), instruction);
771	    }
772
773	    /*
774	     * If relocation entries are to be saved in the output file then
775	     * update the entry for the output file.
776	     */
777	    if(save_reloc || output_for_dyld){
778		if(r_extern){
779		    /*
780		     * For external relocation entries that the symbol is
781		     * defined (not undefined or common) but not when we are
782		     * forcing an external relocation entry for a global
783		     * coalesced symbol and if the output file is not a multi
784		     * module MH_DYLIB or the symbol is a private extern, it is
785		     * changed to a local relocation entry using the section
786		     * that symbol is defined in.  If still undefined or forcing
787		     * an external relocation entry for a global coalesced
788		     * symbol, then the index of the symbol in the output file
789		     * is set into r_symbolnum.
790		     */
791		    if((merged_symbol->nlist.n_type & N_TYPE) != N_UNDF &&
792			(merged_symbol->nlist.n_type & N_TYPE) != N_PBUD &&
793			force_extern_reloc == FALSE &&
794			((filetype != MH_DYLIB ||
795			  multi_module_dylib == FALSE) ||
796			 (merged_symbol->nlist.n_type & N_PEXT) == N_PEXT)){
797			reloc->r_extern = 0;
798			reloc->r_extern = 0;
799			/*
800			 * If this symbol was in the base file then no futher
801			 * relocation can ever be done (the symbols in the base
802			 * file are fixed). Or if the symbol was an absolute
803			 * symbol.
804			 */
805			if(merged_symbol->definition_object == base_obj ||
806			   (merged_symbol->nlist.n_type & N_TYPE) == N_ABS){
807				reloc->r_symbolnum = R_ABS;
808			}
809			else{
810			    /*
811			     * The symbol that this relocation entry is refering
812			     * to is defined so convert this external relocation
813			     * entry into a local or scattered relocation entry.
814			     * If the item to be relocated has an offset added
815			     * to the symbol's value make it a scattered
816			     * relocation entry else make it a local relocation
817			     * entry.
818			     */
819			    if(offset == 0){
820				reloc->r_symbolnum =merged_symbol->nlist.n_sect;
821			    }
822			    else{
823				sreloc = (struct scattered_relocation_info *)
824					 reloc;
825				r_scattered = 1;
826				sreloc->r_scattered = r_scattered;
827				sreloc->r_address = r_address;
828				sreloc->r_pcrel = r_pcrel;
829				sreloc->r_length = r_length;
830				sreloc->r_type = r_type;
831				sreloc->r_value = merged_symbol->nlist.n_value;
832			    }
833			}
834		    }
835		    else{
836			reloc->r_symbolnum =
837				      merged_symbol_output_index(merged_symbol);
838		    }
839		}
840		else if(r_scattered == 0){
841		    /*
842		     * For local relocation entries the section number is
843		     * changed to the section number in the output file.
844		     */
845		    if(reloc->r_symbolnum != R_ABS)
846			reloc->r_symbolnum =
847				      local_map->output_section->output_sectnum;
848		}
849		else{
850		    /*
851		     * For scattered relocation entries the r_value field is
852		     * relocated.
853		     */
854		    sreloc->r_value += - local_map->s->addr
855				       + (local_map->output_section->s.addr +
856				          local_map->offset);
857		}
858		/*
859		 * The offset in the r_address field has to be updated to where
860		 * this contents appears in the output file.
861		 */
862		if(r_scattered == 0){
863		    reloc->r_address += section_map->offset;
864		}
865		else{
866		    sreloc->r_address += section_map->offset;
867		}
868		/*
869		 * If their was a paired relocation entry then update the
870		 * paired relocation entry.
871		 */
872		if(pair_r_type == I860_RELOC_PAIR){
873		    if(pair_reloc != NULL)
874			pair_reloc->r_address = other_half;
875		    else if(spair_reloc != NULL){
876			if(r_type == I860_RELOC_SECTDIFF){
877			    /*
878			     * For I860_RELOC_SECTDIFF relocation entries (which
879			     * are always scattered types) the r_value field is
880			     * relocated.
881			     */
882			    spair_reloc->r_value +=
883				- pair_local_map->s->addr
884				+ (pair_local_map->output_section->s.addr +
885				   pair_local_map->offset);
886			}
887			else{
888			    spair_reloc->r_address = other_half;
889			}
890		    }
891		    else{
892			fatal("internal error, in i860_reloc() pair_r_type "
893			    "is I860_RELOC_PAIR but pair_reloc and spair_reloc "
894			    "are NULL");
895		    }
896		}
897	    }
898	    /*
899	     * If their was a paired relocation entry then it has been processed
900	     * so skip it by incrementing the index of the relocation entry that
901	     * is being processed.
902	     */
903	    if(pair_r_type == I860_RELOC_PAIR)
904		i++;
905	}
906}
907#endif /* !defined(RLD) */
908