Skip to content

Commit 1a22c51

Browse files
authored
Document __global_pointer$ and R_RISCV_GPREL Relocation (#134)
1 parent 1111ad4 commit 1a22c51

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

riscv-elf.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -532,8 +532,10 @@ A | Addend field in the relocation entry associated with the symbol
532532
B | Base address of a shared object loaded into memory
533533
G | Offset of the symbol into the GOT (Global Offset Table)
534534
S | Value of the symbol in the symbol table
535-
GP | Global Pointer register (x3)
535+
GP | Value of `__global_pointer$` symbol.
536536

537+
**Global Pointer**: It is assumed that program startup code will load the value
538+
of the `__global_pointer$` symbol into register `gp` (aka `x3`).
537539

538540
### Absolute Addresses
539541

@@ -555,9 +557,24 @@ The following assembly and relocations show loading an absolute address:
555557

556558
```
557559
lui a0,%hi(symbol) # R_RISCV_HI20 (symbol)
558-
addi a0,a0,%lo(symbol) # R_RISCV_LO12 (symbol)
560+
addi a0,a0,%lo(symbol) # R_RISCV_LO12_I (symbol)
559561
```
560562

563+
**GP-Relative Relocations**: If `symbol` is within the range of a signed 12-bit
564+
immediate offset from `__global_pointer$`, then the address can be loaded with a
565+
single instruction which has one relocation, a `R_RISCV_GPREL_I` or
566+
`R_RISCV_GPREL_S`.
567+
568+
The instruction is an I-Type instruction (add immediate or load) with an
569+
`R_RISCV_GPREL_I` or an S-type instruction (store) with an `R_RISCV_GPREL_S`
570+
relocation. The following assembly show loading a gp-relative address:
571+
572+
```
573+
addi a0, gp, 0 # R_RISCV_GPREL_I (symbol)
574+
```
575+
576+
This relies on the value of `__global_pointer$` being loaded into `gp` (aka
577+
`x3`). This can be used by linker relaxation to delete the `lui` instruction.
561578

562579
### Global Offset Table
563580

0 commit comments

Comments
 (0)