@@ -18,14 +18,13 @@ However, some code models can't access the whole address space. The linker may
1818raise an error if it cannot adjust the instructions to access the target address
1919in the current code model.
2020
21- === Small
21+ === Small code model
2222
2323The small code model, or `medlow`, allows the code to address the whole RV32
2424address space or the lower 2 GiB of the RV64 address space.
2525By using the instructions `lui` and `ld` or `st`, when referring to an object, or
2626`addi`, when calculating an address literal, for example,
2727a 32-bit address literal can be produced.
28- This code model is not position independent.
2928
3029The following instructions show how to load a value, store a value, or calculate
3130an address in the `medlow` code model.
@@ -45,15 +44,14 @@ an address in the `medlow` code model.
4544 addi a0, a0, %lo(symbol)
4645----
4746
48- === Medium
47+ === Medium code model
4948
5049The medium code model, or `medany`, allows the code to address the range
5150between -2 GiB and +2 GiB from its position. By using the instructions `auipc`
5251and `ld` or `st`, when referring to an object, or
5352`addi`, when calculating an address literal, for example,
5453a signed 32-bit offset, relative to the value of the `pc` register,
5554can be produced.
56- This code model is position independent.
5755
5856As a special edge-case, undefined weak symbols must still be supported, whose
5957addresses will be 0 and may be out of range depending on the address at which
@@ -84,6 +82,34 @@ an address in the medany code model.
8482 addi a0, a0, %pcrel_lo(2b)
8583----
8684
85+ NOTE: Although the generated code is technically position independent, it's not
86+ suitable for ELF shared libraries due to differing symbol interposition rules;
87+ for that, please use the medium position independent code model below.
88+
89+ === Medium position independent code model
90+
91+ This model is similar to the medium code model, but uses the global offset
92+ table (GOT) for non-local symbol addresses.
93+
94+ [,asm]
95+ ----
96+ # Load value from a local symbol
97+ 0: auipc a0, %pcrel_hi(symbol)
98+ lw a0, %pcrel_lo(0b)(a0)
99+
100+ # Store value to a local symbol
101+ 1: auipc a0, %pcrel_hi(symbol)
102+ sw a1, %pcrel_lo(1b)(a0)
103+
104+ # Calculate address of a local symbol
105+ 2: auipc a0, %pcrel_hi(symbol)
106+ addi a0, a0, %pcrel_lo(2b)
107+
108+ # Calculate address of non-local symbol
109+ 3: auipc a0, %got_pcrel_hi(symbol)
110+ l[w|d] a0, a0, %pcrel_lo(3b)
111+ ----
112+
87113== Dynamic Linking
88114
89115Run-time linkers that use lazy binding must preserve all argument registers
0 commit comments