Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lld/ELF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2618,6 +2618,13 @@ void LinkerDriver::compileBitcodeFiles(bool skipLinkedOutput) {
auto *obj = cast<ObjFile<ELFT>>(file.get());
obj->parse(/*ignoreComdats=*/true);

for (typename ELFT::Sym elfSym : obj->template getGlobalELFSyms<ELFT>()) {
StringRef elfSymName = check(elfSym.getName(obj->getStringTable()));
if (Symbol *sym = ctx.symtab->find(elfSymName))
if (sym->type == STT_NOTYPE)
sym->type = elfSym.getType();
}

// For defined symbols in non-relocatable output,
// compute isExported and parse '@'.
if (!ctx.arg.relocatable)
Expand Down
38 changes: 38 additions & 0 deletions lld/test/ELF/lto/aarch64-pac-got-func.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
; REQUIRES: aarch64

; RUN: llvm-as %s -o %t.o
; RUN: ld.lld %t.o -shared -o %t
; RUN: llvm-readelf -r -x.got %t | FileCheck %s

; CHECK: Relocation section '.rela.dyn' at offset 0x2a8 contains 2 entries:
; CHECK-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
; CHECK-NEXT: 00000000000203d8 0000000100000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 foo + 0
; CHECK-NEXT: 00000000000203e0 0000000200000412 R_AARCH64_AUTH_GLOB_DAT 0000000000000000 var + 0

; CHECK: Hex dump of section '.got':
; CHECK-NEXT: 0x000203d8 00000000 00000080 00000000 000000a0
;; ^^ 0b10000000 bit 63 address diversity = true, bits 61..60 key = IA
;; ^^ 0b10100000 bit 63 address diversity = true, bits 61..60 key = DA

target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64-unknown-linux-gnu"

@var = external global ptr

declare void @foo()

define void @bar() #0 {
entry:
store ptr ptrauth (ptr @foo, i32 0), ptr @var
Copy link
Member

@MaskRay MaskRay Apr 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps rename var to something else then add

store ptr ptrauth (ptr @func, i32 0), ptr @g
store ptr ptrauth (ptr @func_undef, i32 0), ptr @g
store ptr ptrauth (ptr @var_undef, i32 0), ptr @g
store ptr ptrauth (ptr @var, i32 0), ptr @g

Use llvm.used so that the symbols will not be optimized out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use llvm.used so that the symbols will not be optimized out.

Maybe I'm doing smth wrong, but it looks like that llvm.used has no effect and only the symbol from the last store operation is present in GOT. This is what I've added to the code (right before @bar definition, just in case):

@llvm.used = appending global [4 x ptr] [ ptr @func, ptr @func_undef, ptr @var, ptr @var_undef], section "llvm.metadata"

Adding @g to this array, removing section "llvm.metadata", moving this array definition to the end of the file does not change the behavior.

This smells like a bug, given llvm.used description from IR reference: https://llvm.org/docs/LangRef.html#the-llvm-used-global-variable.

@MaskRay does this look like a bug for you as well, or maybe I'm just mis-using this special array?

As for now, I've just used a separate global for each store - g1, g2, g3, g4. Not elegant, but at least it works :)

ret void
}

define void @_start() {
entry:
ret void
}

attributes #0 = {"target-features"="+pauth"}

!llvm.module.flags = !{!0}
!0 = !{i32 8, !"ptrauth-elf-got", i32 1}