diff --git a/riscv-elf.adoc b/riscv-elf.adoc index e1979a7b..e5d5d4bb 100644 --- a/riscv-elf.adoc +++ b/riscv-elf.adoc @@ -643,6 +643,19 @@ The PLT (Procedure Linkage Table) exists to allow function calls between dynamically linked shared objects. Each dynamic object has its own GOT (Global Offset Table) and PLT (Procedure Linkage Table). +RISC-V has defined several PLT styles, which used for different situation, +the default PLT sytle should be used if the program is not met the condition for +using all other PLT sytle. + +[[plt-style]] +.PLT styles +[cols="1,2"] +[width=70%] +|=== +| Default PLT | - +| Unlabeled landing pad PLT | Must use this PLT style when `GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED` is set. +|=== + The first entry of a shared object PLT is a special entry that calls `_dl_runtime_resolve` to resolve the GOT offset for the called function. The `_dl_runtime_resolve` function in the dynamic loader resolves the @@ -650,8 +663,9 @@ GOT offsets lazily on the first call to any function, except when `LD_BIND_NOW` is set in which case the GOT entries are populated by the dynamic linker before the executable is started. Lazy resolution of GOT entries is intended to speed up program loading by deferring symbol -resolution to the first time the function is called. The first entry -in the PLT occupies two 16 byte entries: +resolution to the first time the function is called. + +The first entry in the PLT occupies two 16 byte entries for the default PLT style: [,asm] ---- @@ -665,11 +679,29 @@ in the PLT occupies two 16 byte entries: jr t3 ---- -Subsequent function entry stubs in the PLT take up 16 bytes and load a -function pointer from the GOT. On the first call to a function, the -entry redirects to the first PLT entry which calls `_dl_runtime_resolve` -and fills in the GOT entry for subsequent calls to the function: +And occupies three 16 byte entries for the simple landing pad PLT style: +[,asm] +---- +1: lpad 0 + auipc t2, %pcrel_hi(.got.plt) + sub t1, t1, t3 # shifted .got.plt offset + hdr size + 16 + l[w|d] t3, %pcrel_lo(1b)(t2) # _dl_runtime_resolve + addi t1, t1, -(hdr size + 16) # shifted .got.plt offset + addi t0, t2, %pcrel_lo(1b) # &.got.plt + srli t1, t1, log2(16/PTRSIZE) # .got.plt offset + l[w|d] t0, PTRSIZE(t0) # link map + jr t3 + nop + nop + nop +---- +Subsequent function entry stubs in the PLT take up 16 bytes. +On the first call to a function, the entry redirects to the first PLT entry +which calls `_dl_runtime_resolve` and fills in the GOT entry for subsequent +calls to the function. + +The code sequences of the PLT entry for the default PLT style: [,asm] ---- 1: auipc t3, %pcrel_hi(function@.got.plt) @@ -678,6 +710,15 @@ and fills in the GOT entry for subsequent calls to the function: nop ---- +The code sequences of the PLT entry for the the simple landing pad PLT style: +[,asm] +---- +1: lpad 0 + auipc t3, %pcrel_hi(function@.got.plt) + l[w|d] t3, %pcrel_lo(1b)(t3) + jalr t1, t3 +---- + ==== Procedure Calls `R_RISCV_CALL` and `R_RISCV_CALL_PLT` relocations are associated with @@ -1361,6 +1402,58 @@ that a linker or runtime loader needs to check for compatibility. The linker should ignore and discard unknown bits in program properties, and issue warnings or errors. +<> provides details of the RISC-V ELF program property; the +meaning of each column is given below: + + +Name:: The name of the program property type, omitting the prefix of `GNU_PROPERTY_RISCV_`. + +Value:: The type value for the program property type. + +Size:: The data type size hold within this program property type. + +Description:: Additional information about the program property type. + + +[[rv-prog-prop-type]] +.RISC-V-specific program property types +[cols="3,3,2,5"] +[width=100%] +|=== +| Name | Value | Size | Description + +| FEATURE_1_AND | 0xc0000000 | 4-bytes | RISC-V processor-specific features used in program. +|=== + +==== GNU_PROPERTY_RISCV_FEATURE_1_AND + + +`GNU_PROPERTY_RISCV_FEATURE_1_AND` describes a set of features, where each bit +represents a different feature. The linker should perform a bitwise AND +operation when merging different objects. + +[%autowidth] +|=== +| Bit | Bit Name +| 0 | GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED +| 1 | GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS +|=== + +`GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED` This bit indicate that all +executable sections are built to be compatible with the landing pad mechanism +provided by the `Zicfilp` extension. An executable or shared library with this +bit set is required to generate PLTs with the landing pad (`lpad`) instruction, +and all label are set to `0`. + +`GNU_PROPERTY_RISCV_FEATURE_1_CFI_SS`: This bit indicate that all executable +sections are built to be compatible with the shadow stack mechanism provided by +the `Zicfiss` extension. Loading an executable or shared library with this bit +set requires the execution environment to provide either the `Zicfiss` extension +or the `Zimop` extension. When the executable or shared library is compiled with +compressed instructions then loading an executable with this bit set requires +the execution environment to provide the `Zicfiss` extension or to provide both +the `Zcmop` and `Zimop` extensions. + === Mapping Symbol The section can have a mixture of code and data or code with different ISAs.