-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
[lld] Add target support for SystemZ (s390x) #75643
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
// glibc < 2.39 used to align .init and .fini code at a 4-byte boundary. | ||
// This file aims to recreate that behavior. | ||
.section .init,"ax",@progbits | ||
.align 4 | ||
lg %r4, 272(%r15) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
# REQUIRES: systemz | ||
# RUN: llvm-mc -filetype=obj -triple=s390x-unknown-linux %s -o %t.o | ||
# RUN: ld.lld --hash-style=sysv -discard-all -shared %t.o -o %t.so | ||
# RUN: llvm-readelf --file-header --program-headers --section-headers --dynamic-table %t.so | FileCheck %s | ||
|
||
# Exits with return code 55 on linux. | ||
.text | ||
lghi 2,55 | ||
svc 1 | ||
|
||
# CHECK: ELF Header: | ||
# CHECK-NEXT: Magic: 7f 45 4c 46 02 02 01 00 00 00 00 00 00 00 00 00 | ||
# CHECK-NEXT: Class: ELF64 | ||
# CHECK-NEXT: Data: 2's complement, big endian | ||
# CHECK-NEXT: Version: 1 (current) | ||
# CHECK-NEXT: OS/ABI: UNIX - System V | ||
# CHECK-NEXT: ABI Version: 0 | ||
# CHECK-NEXT: Type: DYN (Shared object file) | ||
# CHECK-NEXT: Machine: IBM S/390 | ||
# CHECK-NEXT: Version: 0x1 | ||
# CHECK-NEXT: Entry point address: 0x0 | ||
# CHECK-NEXT: Start of program headers: 64 (bytes into file) | ||
# CHECK-NEXT: Start of section headers: 768 (bytes into file) | ||
# CHECK-NEXT: Flags: 0x0 | ||
# CHECK-NEXT: Size of this header: 64 (bytes) | ||
# CHECK-NEXT: Size of program headers: 56 (bytes) | ||
# CHECK-NEXT: Number of program headers: 7 | ||
# CHECK-NEXT: Size of section headers: 64 (bytes) | ||
# CHECK-NEXT: Number of section headers: 11 | ||
# CHECK-NEXT: Section header string table index: 9 | ||
|
||
# CHECK: Section Headers: | ||
# CHECK-NEXT: [Nr] Name Type Address Off Size ES Flg Lk Inf Al | ||
# CHECK-NEXT: [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 | ||
# CHECK-NEXT: [ 1] .dynsym DYNSYM 00000000000001c8 0001c8 000018 18 A 3 1 8 | ||
# CHECK-NEXT: [ 2] .hash HASH 00000000000001e0 0001e0 000010 04 A 1 0 4 | ||
# CHECK-NEXT: [ 3] .dynstr STRTAB 00000000000001f0 0001f0 000001 00 A 0 0 1 | ||
# CHECK-NEXT: [ 4] .text PROGBITS 00000000000011f4 0001f4 000006 00 AX 0 0 4 | ||
# CHECK-NEXT: [ 5] .dynamic DYNAMIC 0000000000002200 000200 000060 10 WA 3 0 8 | ||
# CHECK-NEXT: [ 6] .relro_padding NOBITS 0000000000002260 000260 000da0 00 WA 0 0 1 | ||
# CHECK-NEXT: [ 7] .comment PROGBITS 0000000000000000 000260 000008 01 MS 0 0 1 | ||
# CHECK-NEXT: [ 8] .symtab SYMTAB 0000000000000000 000268 000030 18 10 2 8 | ||
# CHECK-NEXT: [ 9] .shstrtab STRTAB 0000000000000000 000298 000058 00 0 0 1 | ||
# CHECK-NEXT: [10] .strtab STRTAB 0000000000000000 0002f0 00000a 00 0 0 1 | ||
|
||
# CHECK: Program Headers: | ||
# CHECK-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align | ||
# CHECK-NEXT: PHDR 0x000040 0x0000000000000040 0x0000000000000040 0x000188 0x000188 R 0x8 | ||
# CHECK-NEXT: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001f1 0x0001f1 R 0x1000 | ||
# CHECK-NEXT: LOAD 0x0001f4 0x00000000000011f4 0x00000000000011f4 0x000006 0x000006 R E 0x1000 | ||
# CHECK-NEXT: LOAD 0x000200 0x0000000000002200 0x0000000000002200 0x000060 0x000e00 RW 0x1000 | ||
# CHECK-NEXT: DYNAMIC 0x000200 0x0000000000002200 0x0000000000002200 0x000060 0x000060 RW 0x8 | ||
# CHECK-NEXT: GNU_RELRO 0x000200 0x0000000000002200 0x0000000000002200 0x000060 0x000e00 R 0x1 | ||
# CHECK-NEXT: GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x0 | ||
|
||
# CHECK: Dynamic section at offset 0x200 contains 6 entries: | ||
# CHECK-NEXT: Tag Type Name/Value | ||
# CHECK-NEXT: 0x0000000000000006 (SYMTAB) 0x1c8 | ||
# CHECK-NEXT: 0x000000000000000b (SYMENT) 24 (bytes) | ||
# CHECK-NEXT: 0x0000000000000005 (STRTAB) 0x1f0 | ||
# CHECK-NEXT: 0x000000000000000a (STRSZ) 1 (bytes) | ||
# CHECK-NEXT: 0x0000000000000004 (HASH) 0x1e0 | ||
# CHECK-NEXT: 0x0000000000000000 (NULL) 0x0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# REQUIRES: systemz | ||
# RUN: llvm-mc -filetype=obj -triple=s390x-unknown-linux %s -o %t.o | ||
# RUN: ld.lld -m elf64_s390 %t.o -o %t1 | ||
# RUN: llvm-readelf --file-header %t1 | FileCheck %s | ||
# RUN: ld.lld %t.o -o %t2 | ||
# RUN: llvm-readelf --file-header %t2 | FileCheck %s | ||
# RUN: echo 'OUTPUT_FORMAT(elf64-s390)' > %t.script | ||
# RUN: ld.lld %t.script %t.o -o %t3 | ||
# RUN: llvm-readelf --file-header %t3 | FileCheck %s | ||
|
||
# CHECK: ELF Header: | ||
# CHECK-NEXT: Magic: 7f 45 4c 46 02 02 01 00 00 00 00 00 00 00 00 00 | ||
# CHECK-NEXT: Class: ELF64 | ||
# CHECK-NEXT: Data: 2's complement, big endian | ||
# CHECK-NEXT: Version: 1 (current) | ||
# CHECK-NEXT: OS/ABI: UNIX - System V | ||
# CHECK-NEXT: ABI Version: 0 | ||
# CHECK-NEXT: Type: EXEC (Executable file) | ||
# CHECK-NEXT: Machine: IBM S/390 | ||
# CHECK-NEXT: Version: 0x1 | ||
# CHECK-NEXT: Entry point address: | ||
# CHECK-NEXT: Start of program headers: 64 (bytes into file) | ||
# CHECK-NEXT: Start of section headers: | ||
# CHECK-NEXT: Flags: 0x0 | ||
# CHECK-NEXT: Size of this header: 64 (bytes) | ||
# CHECK-NEXT: Size of program headers: 56 (bytes) | ||
|
||
.globl _start | ||
_start: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
; REQUIRES: systemz | ||
;; Test we can infer the e_machine value EM_S390 from a bitcode file. | ||
|
||
; RUN: llvm-as %s -o %t.o | ||
; RUN: ld.lld %t.o -o %t | ||
; RUN: llvm-readobj -h %t | FileCheck %s | ||
|
||
; CHECK: Class: 64-bit | ||
; CHECK: DataEncoding: BigEndian | ||
; CHECK: Machine: EM_S390 | ||
|
||
target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64" | ||
target triple = "s390x-unknown-linux-gnu" | ||
|
||
define void @_start() { | ||
entry: | ||
ret void | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# REQUIRES: systemz | ||
# RUN: llvm-mc -filetype=obj -triple=s390x-unknown-linux %s -o %t.o | ||
# RUN: llvm-mc -filetype=obj -triple=s390x-unknown-linux %p/Inputs/shared.s -o %t2.o | ||
# RUN: ld.lld -shared %t2.o -soname=%t2.so -o %t2.so | ||
|
||
# RUN: ld.lld -dynamic-linker /lib/ld64.so.1 %t.o %t2.so -o %t | ||
# RUN: llvm-readelf -S -r %t | FileCheck %s | ||
|
||
# CHECK: .got PROGBITS {{.*}} {{.*}} 000020 00 WA 0 0 8 | ||
|
||
# CHECK: Relocation section '.rela.dyn' at offset {{.*}} contains 1 entries: | ||
# CHECK: {{.*}} 000000010000000a R_390_GLOB_DAT 0000000000000000 bar + 0 | ||
|
||
.global _start | ||
_start: | ||
lgrl %r1,bar@GOT |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# REQUIRES: systemz | ||
## Verify that R_390_GOTENT optimization is not performed on misaligned symbols. | ||
|
||
# RUN: llvm-mc -filetype=obj -relax-relocations -triple=s390x-unknown-linux %s -o %t.o | ||
# RUN: ld.lld %t.o -o %t1 | ||
# RUN: llvm-readelf -S -r -x .got -x .got.plt %t1 | FileCheck --check-prefixes=CHECK %s | ||
# RUN: llvm-objdump --no-print-imm-hex -d %t1 | FileCheck --check-prefix=DISASM %s | ||
|
||
## We retain one .got entry for the unaligned symbol. | ||
# CHECK: Name Type Address Off Size ES Flg Lk Inf Al | ||
# CHECK: .got PROGBITS 00000000010021e0 0001e0 000020 00 WA 0 0 8 | ||
# CHECK-NEXT: .relro_padding NOBITS 0000000001002200 000200 000e00 00 WA 0 0 1 | ||
# CHECK-NEXT: .data PROGBITS 0000000001003200 000200 000006 00 WA 0 0 2 | ||
|
||
# CHECK-LABEL: Hex dump of section '.got': | ||
# CHECK-NEXT: 0x010021e0 00000000 00000000 00000000 00000000 | ||
# CHECK-NEXT: 0x010021f0 00000000 00000000 00000000 01003205 | ||
|
||
# DISASM: Disassembly of section .text: | ||
# DISASM: <_start>: | ||
# DISASM-NEXT: larl %r1, 0x1003200 | ||
# DISASM-NEXT: larl %r1, 0x1003200 | ||
# DISASM-NEXT: lgrl %r1, 0x10021f8 | ||
# DISASM-NEXT: lgrl %r1, 0x10021f8 | ||
|
||
.data | ||
.globl var_align | ||
.hidden var_align | ||
.align 2 | ||
var_align: | ||
.long 0 | ||
|
||
.data | ||
.globl var_unalign | ||
.hidden var_unalign | ||
.align 2 | ||
.byte 0 | ||
var_unalign: | ||
.byte 0 | ||
|
||
.text | ||
.globl _start | ||
.type _start, @function | ||
_start: | ||
lgrl %r1, var_align@GOT | ||
lgrl %r1, var_align@GOT | ||
lgrl %r1, var_unalign@GOT | ||
lgrl %r1, var_unalign@GOT |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I investigated this in the weekend. Seems an unfortunate ABI issue where Local-Exec is unnecessarily inefficient
https://maskray.me/blog/2024-02-11-toolchain-notes-on-z-architecture#initial-exec-tls-model
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, exactly. Both Initial-Exec and Local-Exec sequences end up being LGRL+LGF, so any rewrite wouldn't actually be an optimization here. Also, to rewrite into local-exec we'd have to allocate a constant pool entry slot somewhere, which is difficult for the linker. Easier to just keep using the (already allocated) GOT slot.
Now, if we could use a more efficient Local-Exec sequence, this might be a different story. Back when the ABI was defined, the architecture didn't yet have LGFI, so there wasn't really a way to load even a 32-bit constant without constant pool. (B.t.w. are we certain that TLS offsets on a 64-bit platform can be restricted to 32 bits?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the explanation. I've rewritten the paragraph to:
Optimizing the code sequence to local-exec is straightforward: changing the first instruction to
lgfi %r1, a@NTPOFF
.However, LGFI (Load Immediate) is part of the extended-immediate facility (September 2005), introduced with System z9 109, unavailable when the ABI was defined.
I got the "z9 109" information from New z/Architecture Instructions that Can Save You Time & ...
We can. A 2GiB static TLS block almost assuredly won't work. It means that the dynamic loader needs to allocate 2GiB thread stack upfront for each new thread. The memory use is just not affordable.
#77128