Commit | Line | Data |
---|---|---|
985fca12 SC |
1 | /*doc* |
2 | @section Relocations | |
3 | ||
4 | Bfd maintains relocations in much the same was as it maintains | |
5 | symbols; they are left alone until required, then read in en-mass and | |
6 | traslated into an internal form. There is a common routine | |
7 | @code{bfd_perform_relocation} which acts upon the canonical form to to | |
8 | the actual fixup. | |
9 | ||
10 | Note that relocations are maintained on a per section basis, whilst | |
11 | symbols are maintained on a per bfd basis. | |
12 | ||
13 | All a back end has to do to fit the bfd interface is to create as many | |
14 | @code{struct reloc_cache_entry} as there are relocations in a | |
15 | particuar section, and fill in the right bits: | |
16 | ||
17 | @menu | |
18 | * typedef arelent:: | |
19 | * reloc handling functions:: | |
20 | @end menu | |
21 | ||
22 | */ | |
23 | #include "sysdep.h" | |
24 | #include "bfd.h" | |
25 | #include "libbfd.h" | |
26 | /*doc | |
27 | *node typedef arelent, Relocations, reloc handling functions, Relocations | |
28 | @section typedef arelent | |
29 | ||
30 | ||
31 | */ | |
32 | ||
33 | /*proto* bfd_perform_relocation | |
34 | The relocation routine returns as a status an enumerated type: | |
35 | ||
36 | *+++ | |
37 | ||
38 | $typedef enum bfd_reloc_status { | |
39 | No errors detected | |
40 | ||
41 | $ bfd_reloc_ok, | |
42 | ||
43 | The relocation was performed, but there was an overflow. | |
44 | ||
45 | $ bfd_reloc_overflow, | |
46 | ||
47 | The address to relocate was not within the section supplied | |
48 | ||
49 | $ bfd_reloc_outofrange, | |
50 | ||
51 | Used by special functions | |
52 | ||
53 | $ bfd_reloc_continue, | |
54 | ||
55 | Unused | |
56 | ||
57 | $ bfd_reloc_notsupported, | |
58 | ||
59 | Unsupported relocation size requested. | |
60 | ||
61 | $ bfd_reloc_other, | |
62 | ||
63 | The symbol to relocate against was undefined. | |
64 | ||
65 | $ bfd_reloc_undefined, | |
66 | ||
67 | The relocaction was performed, but may not be ok - presently generated | |
68 | only when linking i960 coff files with i960 b.out symbols. | |
69 | ||
70 | $ bfd_reloc_dangerous | |
71 | $ } | |
72 | $ bfd_reloc_status_enum_type; | |
73 | ||
74 | *--- | |
75 | ||
76 | */ | |
77 | ||
78 | /*proto* | |
79 | ||
80 | *+++ | |
81 | ||
82 | $typedef struct reloc_cache_entry | |
83 | ${ | |
84 | ||
85 | A pointer into the canonical table of pointers | |
86 | ||
87 | $ struct symbol_cache_entry **sym_ptr_ptr; | |
88 | ||
89 | offset in section | |
90 | ||
91 | $ rawdata_offset address; | |
92 | ||
93 | addend for relocation value | |
94 | ||
95 | $ bfd_vma addend; | |
96 | ||
97 | if sym is null this is the section | |
98 | ||
99 | $ struct sec *section; | |
100 | ||
101 | Pointer to how to perform the required relocation | |
102 | ||
103 | $ struct reloc_howto_struct *howto; | |
104 | $} arelent; | |
105 | ||
106 | *--- | |
107 | ||
108 | */ | |
109 | ||
110 | /*doc* | |
111 | @table @code | |
112 | @item sym_ptr_ptr | |
113 | The symbol table pointer points to a pointer to the symbol ascociated with the | |
114 | relocation request. This would naturaly be the pointer into the table | |
115 | returned by the back end's get_symtab action. @xref{Symbols}. The | |
116 | symbol is referenced through a pointer to a pointer so that tools like | |
117 | the linker can fixup all the symbols of the same name by modifying | |
118 | only one pointer. The relocation routine looks in the symbol and uses | |
119 | the base of the section the symbol is attatched to and the value of | |
120 | the symbol as the initial relocation offset. If the symbol pointer is | |
121 | zero, then the section provided is looked up. | |
122 | @item address | |
123 | The address field gives the offset in bytes from the base of the | |
124 | section data which owns the relocation record to the first byte of | |
125 | relocatable information. The actual data relocated will be relative to | |
126 | this point - for example, a relocation type which modifies the bottom | |
127 | two bytes of a four byte word would not touch the first byte pointed | |
128 | to in a big endian world. | |
129 | @item addend | |
130 | The addend is a value provided by the back end to be added (!) to the | |
131 | relocation offset. It's interpretation is dependent upon the howto. | |
132 | For example, on the 68k the code: | |
133 | ||
134 | *+ | |
135 | char foo[]; | |
136 | main() | |
137 | { | |
138 | return foo[0x12345678]; | |
139 | } | |
140 | *- | |
141 | Could be compiled into: | |
142 | ||
143 | *+ | |
144 | linkw fp,#-4 | |
145 | moveb @@#12345678,d0 | |
146 | extbl d0 | |
147 | unlk fp | |
148 | rts | |
149 | *- | |
150 | ||
151 | This could create a reloc pointing to foo, but leave the offset in the data | |
152 | (something like) | |
153 | ||
154 | *+ | |
155 | RELOCATION RECORDS FOR [.text]: | |
156 | OFFSET TYPE VALUE | |
157 | 00000006 32 _foo | |
158 | ||
159 | 00000000 4e56 fffc ; linkw fp,#-4 | |
160 | 00000004 1039 1234 5678 ; moveb @@#12345678,d0 | |
161 | 0000000a 49c0 ; extbl d0 | |
162 | 0000000c 4e5e ; unlk fp | |
163 | 0000000e 4e75 ; rts | |
164 | *- | |
165 | Using coff and an 88k, some instructions don't have enough space in them to | |
166 | represent the full address range, and pointers have to be loaded in | |
167 | two parts. So you'd get something like: | |
168 | ||
169 | *+ | |
170 | or.u r13,r0,hi16(_foo+0x12345678) | |
171 | ld.b r2,r13,lo16(_foo+0x12345678) | |
172 | jmp r1 | |
173 | *- | |
174 | This whould create two relocs, both pointing to _foo, and with 0x12340000 | |
175 | in their addend field. The data would consist of: | |
176 | ||
177 | *+ | |
178 | ||
179 | RELOCATION RECORDS FOR [.text]: | |
180 | OFFSET TYPE VALUE | |
181 | 00000002 HVRT16 _foo+0x12340000 | |
182 | 00000006 LVRT16 _foo+0x12340000 | |
183 | ||
184 | 00000000 5da05678 ; or.u r13,r0,0x5678 | |
185 | 00000004 1c4d5678 ; ld.b r2,r13,0x5678 | |
186 | 00000008 f400c001 ; jmp r1 | |
187 | *- | |
188 | The relocation routine digs out the value from the data, adds it to | |
189 | the addend to get the original offset and then adds the value of _foo. | |
190 | Note that all 32 bits have to be kept around somewhere, to cope with | |
191 | carry from bit 15 to bit 16. | |
192 | ||
193 | On further example is the sparc and the a.out format. The sparc has a | |
194 | similar problem to the 88k, in that some instructions don't have | |
195 | room for an entire offset, but on the sparc the parts are created odd | |
196 | sized lumps. The designers of the a.out format chose not to use the | |
197 | data within the section for storing part of the offset; all the offset | |
198 | is kept within the reloc. Any thing in the data should be ignored. | |
199 | ||
200 | *+ | |
201 | save %sp,-112,%sp | |
202 | sethi %hi(_foo+0x12345678),%g2 | |
203 | ldsb [%g2+%lo(_foo+0x12345678)],%i0 | |
204 | ret | |
205 | restore | |
206 | *- | |
207 | Both relocs contains a pointer to foo, and the offsets would contain junk. | |
208 | ||
209 | *+ | |
210 | RELOCATION RECORDS FOR [.text]: | |
211 | OFFSET TYPE VALUE | |
212 | 00000004 HI22 _foo+0x12345678 | |
213 | 00000008 LO10 _foo+0x12345678 | |
214 | ||
215 | 00000000 9de3bf90 ; save %sp,-112,%sp | |
216 | 00000004 05000000 ; sethi %hi(_foo+0),%g2 | |
217 | 00000008 f048a000 ; ldsb [%g2+%lo(_foo+0)],%i0 | |
218 | 0000000c 81c7e008 ; ret | |
219 | 00000010 81e80000 ; restore | |
220 | *- | |
221 | @item section | |
222 | The section field is only used when the symbol pointer field is null. | |
223 | It supplies the section into which the data should be relocated. The | |
224 | field's main use comes from assemblers which do most of the symbol fixups | |
225 | themselves; an assembler may take an internal reference to a label, | |
226 | but since it knows where the label is, it can turn the relocation | |
227 | request from a symbol lookup into a section relative relocation - the | |
228 | relocation emitted has no symbol, just a section to relocate against. | |
229 | ||
230 | I'm not sure what it means when both a symbol pointer an a section | |
231 | pointer are present. Some formats use this sort of mechanism to | |
232 | describe PIC relocations, but bfd can't to that sort of thing yet. | |
233 | @item howto | |
234 | The howto field can be imagined as a relocation instruction. It is a | |
235 | pointer to a struct which contains information on what to do with all | |
236 | the other information in the reloc record and data section. A back end | |
237 | would normally have a relocation instruction set and turn relocations | |
238 | into pointers to the correct structure on input - but it would be | |
239 | possible to create each howto field on demand. | |
240 | @end table | |
241 | */ | |
242 | ||
243 | ||
244 | /*proto* reloc_howto_type | |
245 | The @code{reloc_howto_type} is a structure which contains all the | |
246 | information that bfd needs to know to tie up a back end's data. | |
247 | ||
248 | *+++ | |
249 | ||
250 | $typedef CONST struct reloc_howto_struct | |
251 | ${ | |
252 | The type field has mainly a documetary use - the back end can to what | |
253 | it wants with it, though the normally the back end's external idea of | |
254 | what a reloc number would be would be stored in this field. For | |
255 | example, the a PC relative word relocation in a coff environment would | |
256 | have the type 023 - because that's what the outside world calls a | |
257 | R_PCRWORD reloc. | |
258 | ||
259 | $ unsigned int type; | |
260 | ||
261 | The value the final relocation is shifted right by. This drops | |
262 | unwanted data from the relocation. | |
263 | ||
264 | $ unsigned int rightshift; | |
265 | ||
266 | The size of the item to be relocated - 0, is one byte, 1 is 2 bytes, 3 | |
267 | is four bytes. | |
268 | ||
269 | $ unsigned int size; | |
270 | ||
271 | Now obsolete | |
272 | ||
273 | $ unsigned int bitsize; | |
274 | ||
275 | Notes that the relocation is relative to the location in the data | |
276 | section of the addend. The relocation function will subtract from the | |
277 | relocation value the address of the location being relocated. | |
278 | ||
279 | $ boolean pc_relative; | |
280 | ||
281 | Now obsolete | |
282 | ||
283 | $ unsigned int bitpos; | |
284 | ||
285 | Now obsolete | |
286 | ||
287 | $ boolean absolute; | |
288 | ||
289 | Causes the relocation routine to return an error if overflow is | |
290 | detected when relocating. | |
291 | ||
292 | $ boolean complain_on_overflow; | |
293 | ||
294 | If this field is non null, then the supplied function is called rather | |
295 | than the normal function. This allows really strange relocation | |
296 | methods to be accomodated (eg, i960 callj instructions). | |
297 | ||
298 | $ bfd_reloc_status_enum_type (*special_function)(); | |
299 | ||
300 | The textual name of the relocation type. | |
301 | ||
302 | $ char *name; | |
303 | ||
304 | When performing a partial link, some formats must modify the | |
305 | relocations rather than the data - this flag signals this. | |
306 | ||
307 | $ boolean partial_inplace; | |
308 | ||
309 | The src_mask is used to select what parts of the read in data are to | |
310 | be used in the relocation sum. Eg, if this was an 8 bit bit of data | |
311 | which we read and relocated, this would be 0x000000ff. When we have | |
312 | relocs which have an addend, such as sun4 extended relocs, the value | |
313 | in the offset part of a relocating field is garbage so we never use | |
314 | it. In this case the mask would be 0x00000000. | |
315 | ||
316 | $ bfd_word src_mask; | |
317 | The dst_mask is what parts of the instruction are replaced into the | |
318 | instruction. In most cases src_mask == dst_mask, except in the above | |
319 | special case, where dst_mask would be 0x000000ff, and src_mask would | |
320 | be 0x00000000. | |
321 | ||
322 | $ bfd_word dst_mask; | |
323 | ||
324 | When some formats create PC relative instructions, they leave the | |
325 | value of the pc of the place being relocated in the offset slot of the | |
326 | instruction, so that a PC relative relocation can be made just by | |
327 | adding in an ordinary offset (eg sun3 a.out). Some formats leave the | |
328 | displacement part of an instruction empty (eg m88k bcs), this flag | |
329 | signals the fact. | |
330 | ||
331 | $ boolean pcrel_offset; | |
332 | $} reloc_howto_type; | |
333 | *--- | |
334 | ||
335 | */ | |
336 | ||
337 | /*proto* HOWTO | |
338 | The HOWTO define is horrible and will go away. | |
339 | *+ | |
340 | #define HOWTO(C, R,S,B, P, BI, ABS, O, SF, NAME, INPLACE, MASKSRC, MASKDST, PC) \ | |
341 | {(unsigned)C,R,S,B, P, BI, ABS,O,SF,NAME,INPLACE,MASKSRC,MASKDST,PC} | |
342 | *- | |
343 | ||
344 | */ | |
345 | ||
346 | /*proto* reloc_chain | |
347 | *+ | |
348 | typedef unsigned char bfd_byte; | |
349 | ||
350 | typedef struct relent_chain { | |
351 | arelent relent; | |
352 | struct relent_chain *next; | |
353 | } arelent_chain; | |
354 | ||
355 | *- | |
356 | ||
357 | */ | |
358 | ||
359 | ||
360 | ||
361 | /*proto* | |
362 | If an output_bfd is supplied to this function the generated image | |
363 | will be relocatable, the relocations are copied to the output file | |
364 | after they have been changed to reflect the new state of the world. | |
365 | There are two ways of reflecting the results of partial linkage in an | |
366 | output file; by modifying the output data in place, and by modifying | |
367 | the relocation record. Some native formats (eg basic a.out and basic | |
368 | coff) have no way of specifying an addend in the relocation type, so | |
369 | the addend has to go in the output data. This is no big deal since in | |
370 | these formats the output data slot will always be big enough for the | |
371 | addend. Complex reloc types with addends were invented to solve just | |
372 | this problem. | |
373 | *; PROTO(bfd_reloc_status_enum_type, | |
374 | bfd_perform_relocation, | |
375 | (bfd * abfd, | |
376 | arelent *reloc_entry, | |
377 | PTR data, | |
378 | asection *input_section, | |
379 | bfd *output_bfd)); | |
380 | */ | |
381 | ||
382 | ||
383 | bfd_reloc_status_enum_type | |
384 | DEFUN(bfd_perform_relocation,(abfd, | |
385 | reloc_entry, | |
386 | data, | |
387 | input_section, | |
388 | output_bfd), | |
389 | bfd *abfd AND | |
390 | arelent *reloc_entry AND | |
391 | PTR data AND | |
392 | asection *input_section AND | |
393 | bfd *output_bfd) | |
394 | { | |
395 | bfd_vma relocation; | |
396 | bfd_reloc_status_enum_type flag = bfd_reloc_ok; | |
397 | bfd_vma addr = reloc_entry->address ; | |
398 | bfd_vma output_base = 0; | |
399 | reloc_howto_type *howto = reloc_entry->howto; | |
400 | asection *reloc_target_output_section; | |
401 | asection *reloc_target_input_section; | |
402 | asymbol *symbol; | |
403 | ||
404 | if (reloc_entry->sym_ptr_ptr) { | |
405 | symbol = *( reloc_entry->sym_ptr_ptr); | |
406 | if ((symbol->flags & BSF_UNDEFINED) && output_bfd == (bfd *)NULL) { | |
407 | flag = bfd_reloc_undefined; | |
408 | } | |
409 | } | |
410 | else { | |
411 | symbol = (asymbol*)NULL; | |
412 | } | |
413 | ||
414 | if (howto->special_function){ | |
415 | bfd_reloc_status_enum_type cont; | |
416 | cont = howto->special_function(abfd, | |
417 | reloc_entry, | |
418 | symbol, | |
419 | data, | |
420 | input_section); | |
421 | if (cont != bfd_reloc_continue) return cont; | |
422 | } | |
423 | ||
424 | /* | |
425 | Work out which section the relocation is targetted at and the | |
426 | initial relocation command value. | |
427 | */ | |
428 | ||
429 | ||
430 | if (symbol != (asymbol *)NULL){ | |
431 | if (symbol->flags & BSF_FORT_COMM) { | |
432 | relocation = 0; | |
433 | } | |
434 | else { | |
435 | relocation = symbol->value; | |
436 | } | |
437 | if (symbol->section != (asection *)NULL) | |
438 | { | |
439 | reloc_target_input_section = symbol->section; | |
440 | } | |
441 | else { | |
442 | reloc_target_input_section = (asection *)NULL; | |
443 | } | |
444 | } | |
445 | else if (reloc_entry->section != (asection *)NULL) | |
446 | { | |
447 | relocation = 0; | |
448 | reloc_target_input_section = reloc_entry->section; | |
449 | } | |
450 | else { | |
451 | relocation = 0; | |
452 | reloc_target_input_section = (asection *)NULL; | |
453 | } | |
454 | ||
455 | ||
456 | if (reloc_target_input_section != (asection *)NULL) { | |
457 | ||
458 | reloc_target_output_section = | |
459 | reloc_target_input_section->output_section; | |
460 | ||
461 | if (output_bfd && howto->partial_inplace==false) { | |
462 | output_base = 0; | |
463 | } | |
464 | else { | |
465 | output_base = reloc_target_output_section->vma; | |
466 | ||
467 | } | |
468 | ||
469 | relocation += output_base + reloc_target_input_section->output_offset; | |
470 | } | |
471 | ||
472 | relocation += reloc_entry->addend ; | |
473 | ||
474 | ||
475 | if(reloc_entry->address > (bfd_vma)(input_section->size)) | |
476 | { | |
477 | return bfd_reloc_outofrange; | |
478 | } | |
479 | ||
480 | ||
481 | if (howto->pc_relative == true) | |
482 | { | |
483 | /* | |
484 | Anything which started out as pc relative should end up that | |
485 | way too. | |
486 | ||
487 | There are two ways we can see a pcrel instruction. Sometimes | |
488 | the pcrel displacement has been partially calculated, it | |
489 | includes the distance from the start of the section to the | |
490 | instruction in it (eg sun3), and sometimes the field is | |
491 | totally blank - eg m88kbcs. | |
492 | */ | |
493 | ||
494 | ||
495 | relocation -= | |
496 | output_base + input_section->output_offset; | |
497 | ||
498 | if (howto->pcrel_offset == true) { | |
499 | relocation -= reloc_entry->address; | |
500 | } | |
501 | ||
502 | } | |
503 | ||
504 | if (output_bfd!= (bfd *)NULL) { | |
505 | if ( howto->partial_inplace == false) { | |
506 | /* | |
507 | This is a partial relocation, and we want to apply the relocation | |
508 | to the reloc entry rather than the raw data. Modify the reloc | |
509 | inplace to reflect what we now know. | |
510 | */ | |
511 | reloc_entry->addend = relocation ; | |
512 | reloc_entry->section = reloc_target_input_section; | |
513 | if (reloc_target_input_section != (asection *)NULL) { | |
514 | /* If we know the output section we can forget the symbol */ | |
515 | reloc_entry->sym_ptr_ptr = (asymbol**)NULL; | |
516 | } | |
517 | reloc_entry->address += | |
518 | input_section->output_offset; | |
519 | return flag; | |
520 | } | |
521 | else | |
522 | { | |
523 | /* This is a partial relocation, but inplace, so modify the | |
524 | reloc record a bit | |
525 | */ | |
526 | ||
527 | } | |
528 | } | |
529 | ||
530 | reloc_entry->addend = 0; | |
531 | ||
532 | ||
533 | /* | |
534 | Either we are relocating all the way, or we don't want to apply | |
535 | the relocation to the reloc entry (probably because there isn't | |
536 | any room in the output format to describe addends to relocs) | |
537 | */ | |
538 | relocation >>= howto->rightshift; | |
539 | ||
540 | /* Shift everything up to where it's going to be used */ | |
541 | ||
542 | relocation <<= howto->bitpos; | |
543 | ||
544 | /* Wait for the day when all have the mask in them */ | |
545 | ||
546 | /* What we do: | |
547 | i instruction to be left alone | |
548 | o offset within instruction | |
549 | r relocation offset to apply | |
550 | S src mask | |
551 | D dst mask | |
552 | N ~dst mask | |
553 | A part 1 | |
554 | B part 2 | |
555 | R result | |
556 | ||
557 | Do this: | |
558 | i i i i i o o o o o from bfd_get<size> | |
559 | and S S S S S to get the size offset we want | |
560 | + r r r r r r r r r r to get the final value to place | |
561 | and D D D D D to chop to right size | |
562 | ----------------------- | |
563 | A A A A A | |
564 | And this: | |
565 | ... i i i i i o o o o o from bfd_get<size> | |
566 | and N N N N N get instruction | |
567 | ----------------------- | |
568 | ... B B B B B | |
569 | ||
570 | And then: | |
571 | B B B B B | |
572 | or A A A A A | |
573 | ----------------------- | |
574 | R R R R R R R R R R put into bfd_put<size> | |
575 | */ | |
576 | ||
577 | #define DOIT(x) \ | |
578 | x = ( (x & ~howto->dst_mask) | (((x & howto->src_mask) + relocation) & howto->dst_mask)) | |
579 | ||
580 | switch (howto->size) | |
581 | { | |
582 | case 0: | |
583 | { | |
584 | char x = bfd_get_8(abfd, (char *)data + addr); | |
585 | DOIT(x); | |
586 | bfd_put_8(abfd,x, (unsigned char *) data + addr); | |
587 | } | |
588 | break; | |
589 | ||
590 | case 1: | |
591 | { | |
592 | short x = bfd_get_16(abfd, (bfd_byte *)data + addr); | |
593 | DOIT(x); | |
594 | bfd_put_16(abfd, x, (unsigned char *)data + addr); | |
595 | } | |
596 | break; | |
597 | case 2: | |
598 | { | |
599 | long x = bfd_get_32(abfd, (bfd_byte *) data + addr); | |
600 | DOIT(x); | |
601 | bfd_put_32(abfd,x, (bfd_byte *)data + addr); | |
602 | } | |
603 | break; | |
604 | case 3: | |
605 | /* Do nothing */ | |
606 | break; | |
607 | default: | |
608 | return bfd_reloc_other; | |
609 | } | |
610 | ||
611 | return flag; | |
612 | } |