-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[LLD][RISCV][Zicfilp] Generate unlabeled landing pad-style PLT #145461
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
To support dynamic linking when Zicfilp is enabled, lpad insns are inserted into PLTs. This patch generates the unlabeled landing pad-style PLT, in which all the lpads have label "0", when ZICFILP-unlabeled is enabled: --- PLT Header: ``` lpad 0 1: 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 ``` --- PLT Entry: ``` lpad 0 1: auipc t3, %pcrel_hi([email protected]) l[w|d] t3, %pcrel_lo(1b)(t3) jalr t1, t3 ```
@llvm/pr-subscribers-lld-elf Author: Ming-Yi Lai (mylai-mtk) ChangesTo support dynamic linking when Zicfilp is enabled, lpad insns are inserted into PLTs. This patch generates the unlabeled landing pad-style PLT, in which all the lpads have label --- PLT Header:
--- PLT Entry:
(The PLT format is specified in the psABI draft at <riscv-non-isa/riscv-elf-psabi-doc#417>) Full diff: https://github.com/llvm/llvm-project/pull/145461.diff 2 Files Affected:
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 72d83159ad8ac..33d3fdcc60ff8 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -27,7 +27,7 @@ using namespace lld::elf;
namespace {
-class RISCV final : public TargetInfo {
+class RISCV : public TargetInfo {
public:
RISCV(Ctx &);
uint32_t calcEFlags() const override;
@@ -1065,6 +1065,66 @@ void RISCV::finalizeRelax(int passes) const {
}
}
+namespace {
+
+class RISCVCfiLpUnlabeledPLT final : public RISCV {
+public:
+ RISCVCfiLpUnlabeledPLT(Ctx &ctx);
+ void writePltHeader(uint8_t *buf) const override;
+ void writePlt(uint8_t *buf, const Symbol &sym,
+ uint64_t pltEntryAddr) const override;
+};
+
+} // namespace
+
+RISCVCfiLpUnlabeledPLT::RISCVCfiLpUnlabeledPLT(Ctx &ctx) : RISCV(ctx) {
+ pltHeaderSize = 48;
+}
+
+void RISCVCfiLpUnlabeledPLT::writePltHeader(uint8_t *buf) const {
+ // lpad 0
+ // 1: auipc t2, %pcrel_hi(.got.plt)
+ // sub t1, t1, t3
+ // l[wd] t3, %pcrel_lo(1b)(t2); t3 = _dl_runtime_resolve
+ // addi t1, t1, -pltHeaderSize-16; t1 = &.plt[i] - &.plt[0]
+ // addi t0, t2, %pcrel_lo(1b)
+ // srli t1, t1, (rv64?1:2); t1 = &.got.plt[i] - &.got.plt[0]
+ // l[wd] t0, Wordsize(t0); t0 = link_map
+ // jr t3
+ // nop
+ // nop
+ // nop
+ const uint32_t offset =
+ ctx.in.gotPlt->getVA() - (ctx.in.plt->getVA() + 4 /* offset for lpad */);
+ const uint32_t load = ctx.arg.is64 ? LD : LW;
+ write32le(buf + 0, utype(AUIPC, 0, 0)); // lpad 0
+ write32le(buf + 4, utype(AUIPC, X_T2, hi20(offset)));
+ write32le(buf + 8, rtype(SUB, X_T1, X_T1, X_T3));
+ write32le(buf + 12, itype(load, X_T3, X_T2, lo12(offset)));
+ write32le(buf + 16, itype(ADDI, X_T1, X_T1, -ctx.target->pltHeaderSize - 16));
+ write32le(buf + 20, itype(ADDI, X_T0, X_T2, lo12(offset)));
+ write32le(buf + 24, itype(SRLI, X_T1, X_T1, ctx.arg.is64 ? 1 : 2));
+ write32le(buf + 28, itype(load, X_T0, X_T0, ctx.arg.wordsize));
+ write32le(buf + 32, itype(JALR, 0, X_T3, 0));
+ write32le(buf + 36, itype(ADDI, 0, 0, 0)); // nop
+ write32le(buf + 40, itype(ADDI, 0, 0, 0)); // nop
+ write32le(buf + 44, itype(ADDI, 0, 0, 0)); // nop
+}
+
+void RISCVCfiLpUnlabeledPLT::writePlt(uint8_t *buf, const Symbol &sym,
+ uint64_t pltEntryAddr) const {
+ // lpad 0
+ // 1: auipc t3, %pcrel_hi([email protected])
+ // l[wd] t3, %pcrel_lo(1b)(t3)
+ // jalr t1, t3
+ const uint32_t offset =
+ sym.getGotPltVA(ctx) - (pltEntryAddr + 4 /* offset for lpad */);
+ write32le(buf + 0, utype(AUIPC, 0, 0)); // lpad 0
+ write32le(buf + 4, utype(AUIPC, X_T3, hi20(offset)));
+ write32le(buf + 8, itype(ctx.arg.is64 ? LD : LW, X_T3, X_T3, lo12(offset)));
+ write32le(buf + 12, itype(JALR, X_T1, X_T3, 0));
+}
+
namespace {
// Representation of the merged .riscv.attributes input sections. The psABI
// specifies merge policy for attributes. E.g. if we link an object without an
@@ -1357,4 +1417,12 @@ void elf::mergeRISCVAttributesSections(Ctx &ctx) {
mergeAttributesSection(ctx, sections));
}
-void elf::setRISCVTargetInfo(Ctx &ctx) { ctx.target.reset(new RISCV(ctx)); }
+void elf::setRISCVTargetInfo(Ctx &ctx) {
+ RISCV *target;
+ if (ctx.arg.andFeatures & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED)
+ target = new RISCVCfiLpUnlabeledPLT(ctx);
+ else
+ target = new RISCV(ctx);
+
+ ctx.target.reset(target);
+}
diff --git a/lld/test/ELF/riscv-plt-cfi-lp-unlabeled.s b/lld/test/ELF/riscv-plt-cfi-lp-unlabeled.s
new file mode 100644
index 0000000000000..4a80081ecc258
--- /dev/null
+++ b/lld/test/ELF/riscv-plt-cfi-lp-unlabeled.s
@@ -0,0 +1,135 @@
+# REQUIRES: riscv
+# RUN: rm -rf %t && split-file %s %t && cd %t
+
+# RUN: llvm-mc -filetype=obj -triple=riscv32 rv32-foo.s -o foo32.o
+# RUN: ld.lld -shared foo32.o -soname=libfoo32.so -z zicfilp-unlabeled-report=error --fatal-warnings -o libfoo32.so
+# RUN: llvm-mc -filetype=obj -triple=riscv32 rv32-start.s -o start32.o
+# RUN: ld.lld start32.o libfoo32.so -z zicfilp-unlabeled-report=error --fatal-warnings -o out32
+# RUN: llvm-readelf -S out32 | FileCheck --check-prefix=SEC32 %s
+# RUN: llvm-objdump -d --no-show-raw-insn --mattr=+experimental-zicfilp out32 | FileCheck --check-prefixes=DIS,DIS32 %s
+
+# RUN: llvm-mc -filetype=obj -triple=riscv64 rv64-foo.s -o foo64.o
+# RUN: ld.lld -shared foo64.o -soname=libfoo64.so -z zicfilp-unlabeled-report=error --fatal-warnings -o libfoo64.so
+# RUN: llvm-mc -filetype=obj -triple=riscv64 rv64-start.s -o start64.o
+# RUN: ld.lld start64.o libfoo64.so -z zicfilp-unlabeled-report=error --fatal-warnings -o out64
+# RUN: llvm-readelf -S out64 | FileCheck --check-prefix=SEC64 %s
+# RUN: llvm-objdump -d --no-show-raw-insn --mattr=+experimental-zicfilp out64 | FileCheck --check-prefixes=DIS,DIS64 %s
+
+# SEC32: .plt PROGBITS {{0*}}00011210
+# SEC32: .got.plt PROGBITS {{0*}}000132b8
+
+# SEC64: .plt PROGBITS {{0*}}00011330
+# SEC64: .got.plt PROGBITS {{0*}}00013440
+
+# DIS: Disassembly of section .plt:
+# DIS: <.plt>:
+# DIS-NEXT: lpad 0x0
+# DIS-NEXT: auipc t2, 0x2
+# DIS-NEXT: sub t1, t1, t3
+# DIS32-NEXT: lw t3, 0xa4(t2)
+# DIS64-NEXT: ld t3, 0x10c(t2)
+# DIS-NEXT: addi t1, t1, -0x40
+# DIS32-NEXT: addi t0, t2, 0xa4
+# DIS64-NEXT: addi t0, t2, 0x10c
+# DIS32-NEXT: srli t1, t1, 0x2
+# DIS64-NEXT: srli t1, t1, 0x1
+# DIS32-NEXT: lw t0, 0x4(t0)
+# DIS64-NEXT: ld t0, 0x8(t0)
+# DIS-NEXT: jr t3
+# DIS-NEXT: nop
+# DIS-NEXT: nop
+# DIS-NEXT: nop
+
+# DIS: lpad 0x0
+# DIS-NEXT: auipc t3, 0x2
+# DIS32-NEXT: lw t3, 0x7c(t3)
+# DIS64-NEXT: ld t3, 0xec(t3)
+# DIS-NEXT: jalr t1, t3
+
+#--- rv32-start.s
+
+.section ".note.gnu.property", "a"
+.balign 4
+.4byte 4
+.4byte (ndesc_end - ndesc_begin)
+.4byte 0x5 // NT_GNU_PROPERTY_TYPE_0
+.asciz "GNU"
+ndesc_begin:
+.balign 4
+.4byte 0xc0000000 // GNU_PROPERTY_RISCV_FEATURE_1_AND
+.4byte 4
+.4byte 1 // GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED
+.balign 4
+ndesc_end:
+
+.text
+.global _start, foo
+
+_start:
+ call foo@plt
+
+#--- rv32-foo.s
+
+.section ".note.gnu.property", "a"
+.balign 4
+.4byte 4
+.4byte (ndesc_end - ndesc_begin)
+.4byte 0x5 // NT_GNU_PROPERTY_TYPE_0
+.asciz "GNU"
+ndesc_begin:
+.balign 4
+.4byte 0xc0000000 // GNU_PROPERTY_RISCV_FEATURE_1_AND
+.4byte 4
+.4byte 1 // GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED
+.balign 4
+ndesc_end:
+
+.text
+.global foo
+.type foo, @function
+foo:
+ ret
+
+#--- rv64-start.s
+
+.section ".note.gnu.property", "a"
+.balign 8
+.4byte 4
+.4byte (ndesc_end - ndesc_begin)
+.4byte 0x5 // NT_GNU_PROPERTY_TYPE_0
+.asciz "GNU"
+ndesc_begin:
+.balign 8
+.4byte 0xc0000000 // GNU_PROPERTY_RISCV_FEATURE_1_AND
+.4byte 4
+.4byte 1 // GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED
+.balign 8
+ndesc_end:
+
+.text
+.global _start, foo
+
+_start:
+ call foo@plt
+
+#--- rv64-foo.s
+
+.section ".note.gnu.property", "a"
+.balign 8
+.4byte 4
+.4byte (ndesc_end - ndesc_begin)
+.4byte 0x5 // NT_GNU_PROPERTY_TYPE_0
+.asciz "GNU"
+ndesc_begin:
+.balign 8
+.4byte 0xc0000000 // GNU_PROPERTY_RISCV_FEATURE_1_AND
+.4byte 4
+.4byte 1 // GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED
+.balign 8
+ndesc_end:
+
+.text
+.global foo
+.type foo, @function
+foo:
+ ret
|
@llvm/pr-subscribers-lld Author: Ming-Yi Lai (mylai-mtk) ChangesTo support dynamic linking when Zicfilp is enabled, lpad insns are inserted into PLTs. This patch generates the unlabeled landing pad-style PLT, in which all the lpads have label --- PLT Header:
--- PLT Entry:
(The PLT format is specified in the psABI draft at <riscv-non-isa/riscv-elf-psabi-doc#417>) Full diff: https://github.com/llvm/llvm-project/pull/145461.diff 2 Files Affected:
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 72d83159ad8ac..33d3fdcc60ff8 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -27,7 +27,7 @@ using namespace lld::elf;
namespace {
-class RISCV final : public TargetInfo {
+class RISCV : public TargetInfo {
public:
RISCV(Ctx &);
uint32_t calcEFlags() const override;
@@ -1065,6 +1065,66 @@ void RISCV::finalizeRelax(int passes) const {
}
}
+namespace {
+
+class RISCVCfiLpUnlabeledPLT final : public RISCV {
+public:
+ RISCVCfiLpUnlabeledPLT(Ctx &ctx);
+ void writePltHeader(uint8_t *buf) const override;
+ void writePlt(uint8_t *buf, const Symbol &sym,
+ uint64_t pltEntryAddr) const override;
+};
+
+} // namespace
+
+RISCVCfiLpUnlabeledPLT::RISCVCfiLpUnlabeledPLT(Ctx &ctx) : RISCV(ctx) {
+ pltHeaderSize = 48;
+}
+
+void RISCVCfiLpUnlabeledPLT::writePltHeader(uint8_t *buf) const {
+ // lpad 0
+ // 1: auipc t2, %pcrel_hi(.got.plt)
+ // sub t1, t1, t3
+ // l[wd] t3, %pcrel_lo(1b)(t2); t3 = _dl_runtime_resolve
+ // addi t1, t1, -pltHeaderSize-16; t1 = &.plt[i] - &.plt[0]
+ // addi t0, t2, %pcrel_lo(1b)
+ // srli t1, t1, (rv64?1:2); t1 = &.got.plt[i] - &.got.plt[0]
+ // l[wd] t0, Wordsize(t0); t0 = link_map
+ // jr t3
+ // nop
+ // nop
+ // nop
+ const uint32_t offset =
+ ctx.in.gotPlt->getVA() - (ctx.in.plt->getVA() + 4 /* offset for lpad */);
+ const uint32_t load = ctx.arg.is64 ? LD : LW;
+ write32le(buf + 0, utype(AUIPC, 0, 0)); // lpad 0
+ write32le(buf + 4, utype(AUIPC, X_T2, hi20(offset)));
+ write32le(buf + 8, rtype(SUB, X_T1, X_T1, X_T3));
+ write32le(buf + 12, itype(load, X_T3, X_T2, lo12(offset)));
+ write32le(buf + 16, itype(ADDI, X_T1, X_T1, -ctx.target->pltHeaderSize - 16));
+ write32le(buf + 20, itype(ADDI, X_T0, X_T2, lo12(offset)));
+ write32le(buf + 24, itype(SRLI, X_T1, X_T1, ctx.arg.is64 ? 1 : 2));
+ write32le(buf + 28, itype(load, X_T0, X_T0, ctx.arg.wordsize));
+ write32le(buf + 32, itype(JALR, 0, X_T3, 0));
+ write32le(buf + 36, itype(ADDI, 0, 0, 0)); // nop
+ write32le(buf + 40, itype(ADDI, 0, 0, 0)); // nop
+ write32le(buf + 44, itype(ADDI, 0, 0, 0)); // nop
+}
+
+void RISCVCfiLpUnlabeledPLT::writePlt(uint8_t *buf, const Symbol &sym,
+ uint64_t pltEntryAddr) const {
+ // lpad 0
+ // 1: auipc t3, %pcrel_hi([email protected])
+ // l[wd] t3, %pcrel_lo(1b)(t3)
+ // jalr t1, t3
+ const uint32_t offset =
+ sym.getGotPltVA(ctx) - (pltEntryAddr + 4 /* offset for lpad */);
+ write32le(buf + 0, utype(AUIPC, 0, 0)); // lpad 0
+ write32le(buf + 4, utype(AUIPC, X_T3, hi20(offset)));
+ write32le(buf + 8, itype(ctx.arg.is64 ? LD : LW, X_T3, X_T3, lo12(offset)));
+ write32le(buf + 12, itype(JALR, X_T1, X_T3, 0));
+}
+
namespace {
// Representation of the merged .riscv.attributes input sections. The psABI
// specifies merge policy for attributes. E.g. if we link an object without an
@@ -1357,4 +1417,12 @@ void elf::mergeRISCVAttributesSections(Ctx &ctx) {
mergeAttributesSection(ctx, sections));
}
-void elf::setRISCVTargetInfo(Ctx &ctx) { ctx.target.reset(new RISCV(ctx)); }
+void elf::setRISCVTargetInfo(Ctx &ctx) {
+ RISCV *target;
+ if (ctx.arg.andFeatures & GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED)
+ target = new RISCVCfiLpUnlabeledPLT(ctx);
+ else
+ target = new RISCV(ctx);
+
+ ctx.target.reset(target);
+}
diff --git a/lld/test/ELF/riscv-plt-cfi-lp-unlabeled.s b/lld/test/ELF/riscv-plt-cfi-lp-unlabeled.s
new file mode 100644
index 0000000000000..4a80081ecc258
--- /dev/null
+++ b/lld/test/ELF/riscv-plt-cfi-lp-unlabeled.s
@@ -0,0 +1,135 @@
+# REQUIRES: riscv
+# RUN: rm -rf %t && split-file %s %t && cd %t
+
+# RUN: llvm-mc -filetype=obj -triple=riscv32 rv32-foo.s -o foo32.o
+# RUN: ld.lld -shared foo32.o -soname=libfoo32.so -z zicfilp-unlabeled-report=error --fatal-warnings -o libfoo32.so
+# RUN: llvm-mc -filetype=obj -triple=riscv32 rv32-start.s -o start32.o
+# RUN: ld.lld start32.o libfoo32.so -z zicfilp-unlabeled-report=error --fatal-warnings -o out32
+# RUN: llvm-readelf -S out32 | FileCheck --check-prefix=SEC32 %s
+# RUN: llvm-objdump -d --no-show-raw-insn --mattr=+experimental-zicfilp out32 | FileCheck --check-prefixes=DIS,DIS32 %s
+
+# RUN: llvm-mc -filetype=obj -triple=riscv64 rv64-foo.s -o foo64.o
+# RUN: ld.lld -shared foo64.o -soname=libfoo64.so -z zicfilp-unlabeled-report=error --fatal-warnings -o libfoo64.so
+# RUN: llvm-mc -filetype=obj -triple=riscv64 rv64-start.s -o start64.o
+# RUN: ld.lld start64.o libfoo64.so -z zicfilp-unlabeled-report=error --fatal-warnings -o out64
+# RUN: llvm-readelf -S out64 | FileCheck --check-prefix=SEC64 %s
+# RUN: llvm-objdump -d --no-show-raw-insn --mattr=+experimental-zicfilp out64 | FileCheck --check-prefixes=DIS,DIS64 %s
+
+# SEC32: .plt PROGBITS {{0*}}00011210
+# SEC32: .got.plt PROGBITS {{0*}}000132b8
+
+# SEC64: .plt PROGBITS {{0*}}00011330
+# SEC64: .got.plt PROGBITS {{0*}}00013440
+
+# DIS: Disassembly of section .plt:
+# DIS: <.plt>:
+# DIS-NEXT: lpad 0x0
+# DIS-NEXT: auipc t2, 0x2
+# DIS-NEXT: sub t1, t1, t3
+# DIS32-NEXT: lw t3, 0xa4(t2)
+# DIS64-NEXT: ld t3, 0x10c(t2)
+# DIS-NEXT: addi t1, t1, -0x40
+# DIS32-NEXT: addi t0, t2, 0xa4
+# DIS64-NEXT: addi t0, t2, 0x10c
+# DIS32-NEXT: srli t1, t1, 0x2
+# DIS64-NEXT: srli t1, t1, 0x1
+# DIS32-NEXT: lw t0, 0x4(t0)
+# DIS64-NEXT: ld t0, 0x8(t0)
+# DIS-NEXT: jr t3
+# DIS-NEXT: nop
+# DIS-NEXT: nop
+# DIS-NEXT: nop
+
+# DIS: lpad 0x0
+# DIS-NEXT: auipc t3, 0x2
+# DIS32-NEXT: lw t3, 0x7c(t3)
+# DIS64-NEXT: ld t3, 0xec(t3)
+# DIS-NEXT: jalr t1, t3
+
+#--- rv32-start.s
+
+.section ".note.gnu.property", "a"
+.balign 4
+.4byte 4
+.4byte (ndesc_end - ndesc_begin)
+.4byte 0x5 // NT_GNU_PROPERTY_TYPE_0
+.asciz "GNU"
+ndesc_begin:
+.balign 4
+.4byte 0xc0000000 // GNU_PROPERTY_RISCV_FEATURE_1_AND
+.4byte 4
+.4byte 1 // GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED
+.balign 4
+ndesc_end:
+
+.text
+.global _start, foo
+
+_start:
+ call foo@plt
+
+#--- rv32-foo.s
+
+.section ".note.gnu.property", "a"
+.balign 4
+.4byte 4
+.4byte (ndesc_end - ndesc_begin)
+.4byte 0x5 // NT_GNU_PROPERTY_TYPE_0
+.asciz "GNU"
+ndesc_begin:
+.balign 4
+.4byte 0xc0000000 // GNU_PROPERTY_RISCV_FEATURE_1_AND
+.4byte 4
+.4byte 1 // GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED
+.balign 4
+ndesc_end:
+
+.text
+.global foo
+.type foo, @function
+foo:
+ ret
+
+#--- rv64-start.s
+
+.section ".note.gnu.property", "a"
+.balign 8
+.4byte 4
+.4byte (ndesc_end - ndesc_begin)
+.4byte 0x5 // NT_GNU_PROPERTY_TYPE_0
+.asciz "GNU"
+ndesc_begin:
+.balign 8
+.4byte 0xc0000000 // GNU_PROPERTY_RISCV_FEATURE_1_AND
+.4byte 4
+.4byte 1 // GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED
+.balign 8
+ndesc_end:
+
+.text
+.global _start, foo
+
+_start:
+ call foo@plt
+
+#--- rv64-foo.s
+
+.section ".note.gnu.property", "a"
+.balign 8
+.4byte 4
+.4byte (ndesc_end - ndesc_begin)
+.4byte 0x5 // NT_GNU_PROPERTY_TYPE_0
+.asciz "GNU"
+ndesc_begin:
+.balign 8
+.4byte 0xc0000000 // GNU_PROPERTY_RISCV_FEATURE_1_AND
+.4byte 4
+.4byte 1 // GNU_PROPERTY_RISCV_FEATURE_1_CFI_LP_UNLABELED
+.balign 8
+ndesc_end:
+
+.text
+.global foo
+.type foo, @function
+foo:
+ ret
|
These sequences look right to me. This is following the AArch64 way of creating subclasses, which should work, but may be more complexity than we need? I don't feel qualified to make that call for certain. |
Yes, for the unlabeled-style PLT, this is a bit more complex than needed, but if you don't insist I change it, I would prefer to keep it as it is now due to the following reasons:
|
To support dynamic linking when Zicfilp is enabled, lpad insns are inserted into PLTs. This patch generates the unlabeled landing pad-style PLT, in which all the lpads have label
0
, when ZICFILP-unlabeled is enabled:--- PLT Header:
--- PLT Entry:
(The PLT format is specified in the psABI draft at riscv-non-isa/riscv-elf-psabi-doc#417)