|
14 | 14 | // support position-independent code (PIC) on PPC32.
|
15 | 15 | //
|
16 | 16 | // A position-independent function typically contains the following code
|
17 |
| -// in its prologue to obtain its own own address: |
| 17 | +// in the prologue to obtain its own address: |
18 | 18 | //
|
19 | 19 | // mflr r0 // save the current return address to %r0
|
20 | 20 | // bcl 20, 31, 4 // call the next instruction as if it were a function
|
|
26 | 26 | // constants. A PIC function usually computes its .got2+0x8000 and set it
|
27 | 27 | // to %r30. This scheme allows the function to access global objects
|
28 | 28 | // defined in the same input file with a single %r30-relative load/store
|
29 |
| -// instructions with a 16-bit offset, given that the object file doesn't |
| 29 | +// instruction with a 16-bit offset, given that the object file doesn't |
30 | 30 | // contain more than 65535 global objects.
|
31 | 31 | //
|
32 | 32 | // Since each object file has its own .got2, %r30 refers to different
|
33 |
| -// places in a merged .got2 for two functions came from different input |
34 |
| -// files. Therefore, %r30 makes sense only within a single function. |
| 33 | +// places in a merged .got2 for two functions that are came from different |
| 34 | +// input files. Therefore, %r30 makes sense only within a single function. |
35 | 35 | //
|
36 | 36 | // Technically, we can reuse a %r30 value in our PLT if we create a PLT
|
37 | 37 | // _for each input file_ (that's what GNU ld seems to be doing), but that
|
38 | 38 | // doesn't seems to worth its complexity. Our PLT simply doesn't rely on a
|
39 | 39 | // %r30 value.
|
| 40 | +// |
| 41 | +// https://github.com/rui314/mold/wiki/ppc32-psabi.pdf |
40 | 42 |
|
41 | 43 | #include "mold.h"
|
42 | 44 |
|
@@ -300,7 +302,7 @@ void InputSection<E>::apply_reloc_alloc(Context<E> &ctx, u8 *base) {
|
300 | 302 | case R_PPC_PLTCALL:
|
301 | 303 | break;
|
302 | 304 | default:
|
303 |
| - Fatal(ctx) << *this << ": apply_reloc_alloc relocation: " << rel; |
| 305 | + unreachable(); |
304 | 306 | }
|
305 | 307 |
|
306 | 308 | #undef S
|
@@ -337,10 +339,14 @@ void InputSection<E>::apply_reloc_nonalloc(Context<E> &ctx, u8 *base) {
|
337 | 339 |
|
338 | 340 | switch (rel.r_type) {
|
339 | 341 | case R_PPC_ADDR32:
|
340 |
| - *(ub32 *)loc = S + A; |
| 342 | + if (std::optional<u64> val = get_tombstone(sym, frag)) |
| 343 | + *(ub32 *)loc = *val; |
| 344 | + else |
| 345 | + *(ub32 *)loc = S + A; |
341 | 346 | break;
|
342 | 347 | default:
|
343 |
| - Fatal(ctx) << *this << ": apply_reloc_nonalloc: " << rel; |
| 348 | + Fatal(ctx) << *this << ": invalid relocation for non-allocated sections: " |
| 349 | + << rel; |
344 | 350 | }
|
345 | 351 |
|
346 | 352 | #undef S
|
@@ -433,7 +439,7 @@ void InputSection<E>::scan_relocations(Context<E> &ctx) {
|
433 | 439 | case R_PPC_PLTCALL:
|
434 | 440 | break;
|
435 | 441 | default:
|
436 |
| - Fatal(ctx) << *this << ": scan_relocations: " << rel; |
| 442 | + Error(ctx) << *this << ": unknown relocation: " << rel; |
437 | 443 | }
|
438 | 444 | }
|
439 | 445 | }
|
|
0 commit comments