forked from OSchip/llvm-project
[ELF][PPC] Allow PT_LOAD to have overlapping p_offset ranges
This change affects the non-linker script case (precisely, when the `SECTIONS` command is not used). It deletes 3 alignments at PT_LOAD boundaries for the default case: the size of a powerpc64 binary can be decreased by at most 192kb. The technique can be ported to other targets. Let me demonstrate the idea with a maxPageSize=65536 example: When assigning the address to the first output section of a new PT_LOAD, if the end p_vaddr of the previous PT_LOAD is 0x10020, we advance to the next multiple of maxPageSize: 0x20000. The new PT_LOAD will thus have p_vaddr=0x20000. Because p_offset and p_vaddr are congruent modulo maxPageSize, p_offset will be 0x20000, leaving a p_offset gap [0x10020, 0x20000) in the output. Alternatively, if we advance to 0x20020, the new PT_LOAD will have p_vaddr=0x20020. We can pick either 0x10020 or 0x20020 for p_offset! Obviously 0x10020 is the choice because it leaves no gap. At runtime, p_vaddr will be rounded down by pagesize (65536 if pagesize=maxPageSize). This PT_LOAD will load additional initial contents from p_offset ranges [0x10000,0x10020), which will also be loaded by the previous PT_LOAD. This is fine if -z noseparate-code is in effect or if we are not transiting between executable and non-executable segments. ld.bfd -z noseparate-code leverages this technique to keep output small. This patch implements the technique in lld, which is mostly effective on targets with large defaultMaxPageSize (AArch64/MIPS/PPC: 65536). The 3 removed alignments can save almost 3*65536 bytes. Two places that rely on p_vaddr%pagesize = 0 have to be updated. 1) We used to round p_memsz(PT_GNU_RELRO) up to commonPageSize (defaults to 4096 on all targets). Now p_vaddr%commonPageSize may be non-zero. The updated formula takes account of that factor. 2) Our TP offsets formulae are only correct if p_vaddr%p_align = 0. Fix them. See the updated comments in InputSection.cpp for details. On targets that we enable the technique (only PPC64 now), we can potentially make `p_vaddr(PT_TLS)%p_align(PT_TLS) != 0` if `sh_addralign(.tdata) < sh_addralign(.tbss)` This exposes many problems in ld.so implementations, especially the offsets of dynamic TLS blocks. Known issues: FreeBSD 13.0-CURRENT rtld-elf (i386/amd64/powerpc/arm64) glibc (HEAD) i386 and x86_64 https://sourceware.org/bugzilla/show_bug.cgi?id=24606 musl<=1.1.22 on TLS Variant I architectures (aarch64/powerpc64/...) So, force p_vaddr%p_align = 0 by rounding dot up to p_align(PT_TLS). The technique will be enabled (with updated tests) for other targets in subsequent patches. Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D64906 llvm-svn: 369343
This commit is contained in:
parent
ebc8fd3c0c
commit
01c7f4b606
|
@ -608,27 +608,39 @@ static int64_t getTlsTpOffset(const Symbol &s) {
|
|||
if (&s == ElfSym::tlsModuleBase)
|
||||
return 0;
|
||||
|
||||
// There are 2 TLS layouts. Among targets we support, x86 uses TLS Variant 2
|
||||
// while most others use Variant 1. At run time TP will be aligned to p_align.
|
||||
|
||||
// Variant 1. TP will be followed by an optional gap (which is the size of 2
|
||||
// pointers on ARM/AArch64, 0 on other targets), followed by alignment
|
||||
// padding, then the static TLS blocks. The alignment padding is added so that
|
||||
// (TP + gap + padding) is congruent to p_vaddr modulo p_align.
|
||||
//
|
||||
// Variant 2. Static TLS blocks, followed by alignment padding are placed
|
||||
// before TP. The alignment padding is added so that (TP - padding -
|
||||
// p_memsz) is congruent to p_vaddr modulo p_align.
|
||||
elf::PhdrEntry *tls = Out::tlsPhdr;
|
||||
switch (config->emachine) {
|
||||
// Variant 1.
|
||||
case EM_ARM:
|
||||
case EM_AARCH64:
|
||||
// Variant 1. The thread pointer points to a TCB with a fixed 2-word size,
|
||||
// followed by a variable amount of alignment padding, followed by the TLS
|
||||
// segment.
|
||||
return s.getVA(0) + alignTo(config->wordsize * 2, Out::tlsPhdr->p_align);
|
||||
case EM_386:
|
||||
case EM_X86_64:
|
||||
// Variant 2. The TLS segment is located just before the thread pointer.
|
||||
return s.getVA(0) - alignTo(Out::tlsPhdr->p_memsz, Out::tlsPhdr->p_align);
|
||||
return s.getVA(0) + config->wordsize * 2 +
|
||||
((tls->p_vaddr - config->wordsize * 2) & (tls->p_align - 1));
|
||||
case EM_MIPS:
|
||||
case EM_PPC:
|
||||
case EM_PPC64:
|
||||
// The thread pointer points to a fixed offset from the start of the
|
||||
// executable's TLS segment. An offset of 0x7000 allows a signed 16-bit
|
||||
// offset to reach 0x1000 of TCB/thread-library data and 0xf000 of the
|
||||
// program's TLS segment.
|
||||
return s.getVA(0) - 0x7000;
|
||||
// Adjusted Variant 1. TP is placed with a displacement of 0x7000, which is
|
||||
// to allow a signed 16-bit offset to reach 0x1000 of TCB/thread-library
|
||||
// data and 0xf000 of the program's TLS segment.
|
||||
return s.getVA(0) + (tls->p_vaddr & (tls->p_align - 1)) - 0x7000;
|
||||
case EM_RISCV:
|
||||
return s.getVA(0);
|
||||
return s.getVA(0) + (tls->p_vaddr & (tls->p_align - 1));
|
||||
|
||||
// Variant 2.
|
||||
case EM_386:
|
||||
case EM_X86_64:
|
||||
return s.getVA(0) - tls->p_memsz -
|
||||
((-tls->p_vaddr - tls->p_memsz) & (tls->p_align - 1));
|
||||
default:
|
||||
llvm_unreachable("unhandled Config->EMachine");
|
||||
}
|
||||
|
|
|
@ -2202,21 +2202,64 @@ void Writer<ELFT>::addPhdrForSection(Partition &part, unsigned shType,
|
|||
part.phdrs.push_back(entry);
|
||||
}
|
||||
|
||||
// The first section of each PT_LOAD, the first section in PT_GNU_RELRO and the
|
||||
// first section after PT_GNU_RELRO have to be page aligned so that the dynamic
|
||||
// linker can set the permissions.
|
||||
// Place the first section of each PT_LOAD to a different page (of maxPageSize).
|
||||
// This is achieved by assigning an alignment expression to addrExpr of each
|
||||
// such section.
|
||||
template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
|
||||
auto pageAlign = [](OutputSection *cmd) {
|
||||
if (cmd && !cmd->addrExpr)
|
||||
cmd->addrExpr = [=] {
|
||||
return alignTo(script->getDot(), config->maxPageSize);
|
||||
};
|
||||
const PhdrEntry *prev;
|
||||
auto pageAlign = [&](const PhdrEntry *p) {
|
||||
OutputSection *cmd = p->firstSec;
|
||||
if (cmd && !cmd->addrExpr) {
|
||||
// Prefer advancing to align(dot, maxPageSize) + dot%maxPageSize to avoid
|
||||
// padding in the file contents.
|
||||
//
|
||||
// When -z separate-code is used we must not have any overlap in pages
|
||||
// between an executable segment and a non-executable segment. We align to
|
||||
// the next maximum page size boundary on transitions between executable
|
||||
// and non-executable segments.
|
||||
//
|
||||
// TODO Enable this technique on all targets.
|
||||
bool enable = config->emachine == EM_PPC64;
|
||||
|
||||
if (!enable || (config->zSeparateCode && prev &&
|
||||
(prev->p_flags & PF_X) != (p->p_flags & PF_X)))
|
||||
cmd->addrExpr = [] {
|
||||
return alignTo(script->getDot(), config->maxPageSize);
|
||||
};
|
||||
// PT_TLS is at the start of the first RW PT_LOAD. If `p` includes PT_TLS,
|
||||
// it must be the RW. Align to p_align(PT_TLS) to make sure
|
||||
// p_vaddr(PT_LOAD)%p_align(PT_LOAD) = 0. Otherwise, if
|
||||
// sh_addralign(.tdata) < sh_addralign(.tbss), we will set p_align(PT_TLS)
|
||||
// to sh_addralign(.tbss), while p_vaddr(PT_TLS)=p_vaddr(PT_LOAD) may not
|
||||
// be congruent to 0 modulo p_align(PT_TLS).
|
||||
//
|
||||
// Technically this is not required, but as of 2019, some dynamic loaders
|
||||
// don't handle p_vaddr%p_align != 0 correctly, e.g. glibc (i386 and
|
||||
// x86-64) doesn't make runtime address congruent to p_vaddr modulo
|
||||
// p_align for dynamic TLS blocks (PR/24606), FreeBSD rtld has the same
|
||||
// bug, musl (TLS Variant 1 architectures) before 1.1.23 handled TLS
|
||||
// blocks correctly. We need to keep the workaround for a while.
|
||||
else if (Out::tlsPhdr && Out::tlsPhdr->firstSec == p->firstSec)
|
||||
cmd->addrExpr = [] {
|
||||
return alignTo(script->getDot(), config->maxPageSize) +
|
||||
alignTo(script->getDot() % config->maxPageSize,
|
||||
Out::tlsPhdr->p_align);
|
||||
};
|
||||
else
|
||||
cmd->addrExpr = [] {
|
||||
return alignTo(script->getDot(), config->maxPageSize) +
|
||||
script->getDot() % config->maxPageSize;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
for (Partition &part : partitions) {
|
||||
prev = nullptr;
|
||||
for (const PhdrEntry *p : part.phdrs)
|
||||
if (p->p_type == PT_LOAD && p->firstSec)
|
||||
pageAlign(p->firstSec);
|
||||
if (p->p_type == PT_LOAD && p->firstSec) {
|
||||
pageAlign(p);
|
||||
prev = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2342,10 +2385,11 @@ template <class ELFT> void Writer<ELFT>::setPhdrs(Partition &part) {
|
|||
p->p_align = std::max<uint64_t>(p->p_align, config->maxPageSize);
|
||||
} else if (p->p_type == PT_GNU_RELRO) {
|
||||
p->p_align = 1;
|
||||
// The glibc dynamic loader rounds the size down, so we need to round up
|
||||
// musl/glibc ld.so rounds the size down, so we need to round up
|
||||
// to protect the last page. This is a no-op on FreeBSD which always
|
||||
// rounds up.
|
||||
p->p_memsz = alignTo(p->p_memsz, config->commonPageSize);
|
||||
p->p_memsz = alignTo(p->p_offset + p->p_memsz, config->commonPageSize) -
|
||||
p->p_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,9 +33,9 @@
|
|||
// CHECK-NEXT: Type: SharedObject (0x3)
|
||||
// CHECK-NEXT: Machine: EM_PPC64 (0x15)
|
||||
// CHECK-NEXT: Version: 1
|
||||
// CHECK-NEXT: Entry: 0x10000
|
||||
// CHECK-NEXT: Entry: 0x1022C
|
||||
// CHECK-NEXT: ProgramHeaderOffset: 0x40
|
||||
// CHECK-NEXT: SectionHeaderOffset: 0x200F8
|
||||
// CHECK-NEXT: SectionHeaderOffset: 0x330
|
||||
// CHECK-NEXT: Flags [ (0x2)
|
||||
// CHECK-NEXT: 0x2
|
||||
// CHECK-NEXT: ]
|
||||
|
@ -127,8 +127,8 @@
|
|||
// CHECK-NEXT: SHF_ALLOC (0x2)
|
||||
// CHECK-NEXT: SHF_EXECINSTR (0x4)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Address: 0x10000
|
||||
// CHECK-NEXT: Offset: 0x10000
|
||||
// CHECK-NEXT: Address: 0x1022C
|
||||
// CHECK-NEXT: Offset: 0x22C
|
||||
// CHECK-NEXT: Size: 12
|
||||
// CHECK-NEXT: Link: 0
|
||||
// CHECK-NEXT: Info: 0
|
||||
|
@ -147,8 +147,8 @@
|
|||
// CHECK-NEXT: SHF_ALLOC (0x2)
|
||||
// CHECK-NEXT: SHF_WRITE (0x1)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Address: 0x20000
|
||||
// CHECK-NEXT: Offset: 0x20000
|
||||
// CHECK-NEXT: Address: 0x20238
|
||||
// CHECK-NEXT: Offset: 0x238
|
||||
// CHECK-NEXT: Size: 96
|
||||
// CHECK-NEXT: Link: 3
|
||||
// CHECK-NEXT: Info: 0
|
||||
|
@ -177,8 +177,8 @@
|
|||
// CHECK-NEXT: SHF_ALLOC (0x2)
|
||||
// CHECK-NEXT: SHF_WRITE (0x1)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Address: 0x30000
|
||||
// CHECK-NEXT: Offset: 0x20060
|
||||
// CHECK-NEXT: Address: 0x30298
|
||||
// CHECK-NEXT: Offset: 0x298
|
||||
// CHECK-NEXT: Size: 0
|
||||
// CHECK-NEXT: Link: 0
|
||||
// CHECK-NEXT: Info: 0
|
||||
|
@ -194,7 +194,7 @@
|
|||
// CHECK-NEXT: SHF_STRINGS (0x20)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Address: 0x0
|
||||
// CHECK-NEXT: Offset: 0x20060
|
||||
// CHECK-NEXT: Offset: 0x298
|
||||
// CHECK-NEXT: Size: 8
|
||||
// CHECK-NEXT: Link: 0
|
||||
// CHECK-NEXT: Info: 0
|
||||
|
@ -211,19 +211,19 @@
|
|||
// CHECK-NEXT: Flags [ (0x0)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Address: 0x0
|
||||
// CHECK-NEXT: Offset: 0x20068
|
||||
// CHECK-NEXT: Offset: 0x2A0
|
||||
// CHECK-NEXT: Size: 48
|
||||
// CHECK-NEXT: Link: 10
|
||||
// CHECK-NEXT: Info: 2
|
||||
// CHECK-NEXT: AddressAlignment: 8
|
||||
// CHECK-NEXT: EntrySize: 24
|
||||
// CHECK-NEXT: SectionData (
|
||||
// LE-NEXT: 0000: 00000000 00000000 00000000 00000000 |................|
|
||||
// LE-NEXT: 0010: 00000000 00000000 01000000 00020500 |................|
|
||||
// LE-NEXT: 0020: 00000200 00000000 00000000 00000000 |................|
|
||||
// BE-NEXT: 0000: 00000000 00000000 00000000 00000000 |................|
|
||||
// BE-NEXT: 0010: 00000000 00000000 00000001 00020005 |................|
|
||||
// BE-NEXT: 0020: 00000000 00020000 00000000 00000000 |................|
|
||||
// LE-NEXT: 0000: 00000000 00000000 00000000 00000000
|
||||
// LE-NEXT: 0010: 00000000 00000000 01000000 00020500
|
||||
// LE-NEXT: 0020: 38020200 00000000 00000000 00000000
|
||||
// BE-NEXT: 0000: 00000000 00000000 00000000 00000000
|
||||
// BE-NEXT: 0010: 00000000 00000000 00000001 00020005
|
||||
// BE-NEXT: 0020: 00000000 00020238 00000000 00000000
|
||||
// CHECK-NEXT: )
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: Section {
|
||||
|
@ -233,7 +233,7 @@
|
|||
// CHECK-NEXT: Flags [ (0x0)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Address: 0x0
|
||||
// CHECK-NEXT: Offset: 0x20098
|
||||
// CHECK-NEXT: Offset: 0x2D0
|
||||
// CHECK-NEXT: Size: 84
|
||||
// CHECK-NEXT: Link: 0
|
||||
// CHECK-NEXT: Info: 0
|
||||
|
@ -255,7 +255,7 @@
|
|||
// CHECK-NEXT: Flags [ (0x0)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Address: 0x0
|
||||
// CHECK-NEXT: Offset: 0x200EC
|
||||
// CHECK-NEXT: Offset: 0x324
|
||||
// CHECK-NEXT: Size: 10
|
||||
// CHECK-NEXT: Link: 0
|
||||
// CHECK-NEXT: Info: 0
|
||||
|
@ -293,9 +293,9 @@
|
|||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ProgramHeader {
|
||||
// CHECK-NEXT: Type: PT_LOAD (0x1)
|
||||
// CHECK-NEXT: Offset: 0x10000
|
||||
// CHECK-NEXT: VirtualAddress: 0x10000
|
||||
// CHECK-NEXT: PhysicalAddress: 0x10000
|
||||
// CHECK-NEXT: Offset: 0x22C
|
||||
// CHECK-NEXT: VirtualAddress: 0x1022C
|
||||
// CHECK-NEXT: PhysicalAddress: 0x1022C
|
||||
// CHECK-NEXT: FileSize: 12
|
||||
// CHECK-NEXT: MemSize: 12
|
||||
// CHECK-NEXT: Flags [ (0x5)
|
||||
|
@ -306,9 +306,9 @@
|
|||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ProgramHeader {
|
||||
// CHECK-NEXT: Type: PT_LOAD (0x1)
|
||||
// CHECK-NEXT: Offset: 0x20000
|
||||
// CHECK-NEXT: VirtualAddress: 0x20000
|
||||
// CHECK-NEXT: PhysicalAddress: 0x20000
|
||||
// CHECK-NEXT: Offset: 0x238
|
||||
// CHECK-NEXT: VirtualAddress: 0x20238
|
||||
// CHECK-NEXT: PhysicalAddress: 0x20238
|
||||
// CHECK-NEXT: FileSize: 96
|
||||
// CHECK-NEXT: MemSize: 96
|
||||
// CHECK-NEXT: Flags [ (0x6)
|
||||
|
@ -319,9 +319,9 @@
|
|||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ProgramHeader {
|
||||
// CHECK-NEXT: Type: PT_DYNAMIC (0x2)
|
||||
// CHECK-NEXT: Offset: 0x20000
|
||||
// CHECK-NEXT: VirtualAddress: 0x20000
|
||||
// CHECK-NEXT: PhysicalAddress: 0x20000
|
||||
// CHECK-NEXT: Offset: 0x238
|
||||
// CHECK-NEXT: VirtualAddress: 0x20238
|
||||
// CHECK-NEXT: PhysicalAddress: 0x20238
|
||||
// CHECK-NEXT: FileSize: 96
|
||||
// CHECK-NEXT: MemSize: 96
|
||||
// CHECK-NEXT: Flags [ (0x6)
|
||||
|
@ -332,11 +332,11 @@
|
|||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ProgramHeader {
|
||||
// CHECK-NEXT: Type: PT_GNU_RELRO (0x6474E552)
|
||||
// CHECK-NEXT: Offset: 0x20000
|
||||
// CHECK-NEXT: VirtualAddress: 0x20000
|
||||
// CHECK-NEXT: PhysicalAddress: 0x20000
|
||||
// CHECK-NEXT: Offset: 0x238
|
||||
// CHECK-NEXT: VirtualAddress: 0x20238
|
||||
// CHECK-NEXT: PhysicalAddress: 0x20238
|
||||
// CHECK-NEXT: FileSize: 96
|
||||
// CHECK-NEXT: MemSize: 4096
|
||||
// CHECK-NEXT: MemSize: 3528
|
||||
// CHECK-NEXT: Flags [ (0x4)
|
||||
// CHECK-NEXT: PF_R (0x4)
|
||||
// CHECK-NEXT: ]
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
|
||||
## FIXME the addend for offset 0x20000 should be TOC base+0x8000+1, not 0x80001.
|
||||
# CHECK: .rela.dyn {
|
||||
# CHECK-NEXT: 0x20000 R_PPC64_RELATIVE - 0x8001
|
||||
# CHECK-NEXT: 0x20008 R_PPC64_RELATIVE - 0x20001
|
||||
# CHECK-NEXT: 0x20010 R_PPC64_ADDR64 external 0x1
|
||||
# CHECK-NEXT: 0x20018 R_PPC64_ADDR64 global 0x1
|
||||
# CHECK-NEXT: 0x303B0 R_PPC64_RELATIVE - 0x8001
|
||||
# CHECK-NEXT: 0x303B8 R_PPC64_RELATIVE - 0x303B1
|
||||
# CHECK-NEXT: 0x303C0 R_PPC64_ADDR64 external 0x1
|
||||
# CHECK-NEXT: 0x303C8 R_PPC64_ADDR64 global 0x1
|
||||
# CHECK-NEXT: }
|
||||
|
||||
.data
|
||||
|
|
|
@ -63,6 +63,6 @@ caller:
|
|||
# CHECK-EMPTY:
|
||||
# CHECK-NEXT: def:
|
||||
# CHECK-NEXT: addis 2, 12, 2
|
||||
# CHECK-NEXT: addi 2, 2, -32616
|
||||
# CHECK-NEXT: addi 2, 2, -32456
|
||||
# CHECK-NEXT: li 3, 55
|
||||
# CHECK-NEXT: blr
|
||||
|
|
|
@ -2,37 +2,37 @@
|
|||
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
|
||||
# RUN: ld.lld --defsym callee=0x12010010 --defsym tail_callee=0x12010020 \
|
||||
# RUN: %t.o -o %t
|
||||
# RUN: -z separate-code %t.o -o %t
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
|
||||
# RUN: ld.lld --defsym callee=0x12010010 --defsym tail_callee=0x12010020 \
|
||||
# RUN: %t.o -o %t
|
||||
# RUN: -z separate-code %t.o -o %t
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
|
||||
# RUN: ld.lld --defsym callee=0xE010014 --defsym tail_callee=0xE010024 \
|
||||
# RUN: %t.o -o %t
|
||||
# RUN: -z separate-code %t.o -o %t
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=NEGOFFSET %s
|
||||
# RUN: ld.lld --defsym callee=0x12010018 --defsym tail_callee=0x12010028 \
|
||||
# RUN: %t.o -o %t
|
||||
# RUN: -z separate-code %t.o -o %t
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=THUNK %s
|
||||
# RUN: llvm-readelf --sections %t | FileCheck --check-prefix=BRANCHLT %s
|
||||
# RUN: not ld.lld --defsym callee=0x1001002D --defsym tail_callee=0x1001002F \
|
||||
# RUN: %t.o -o %t 2>&1 | FileCheck --check-prefix=MISSALIGNED %s
|
||||
# RUN: -z separate-code %t.o -o %t 2>&1 | FileCheck --check-prefix=MISSALIGNED %s
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
|
||||
# RUN: ld.lld --defsym callee=0x12010010 --defsym tail_callee=0x12010020 \
|
||||
# RUN: %t.o -o %t
|
||||
# RUN: -z separate-code %t.o -o %t
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
|
||||
# RUN: ld.lld --defsym callee=0x12010010 --defsym tail_callee=0x12010020 \
|
||||
# RUN: %t.o -o %t
|
||||
# RUN: -z separate-code %t.o -o %t
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
|
||||
# RUN: ld.lld --defsym callee=0xE010014 --defsym tail_callee=0xE010024 \
|
||||
# RUN: %t.o -o %t
|
||||
# RUN: -z separate-code %t.o -o %t
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=NEGOFFSET %s
|
||||
# RUN: ld.lld --defsym callee=0x12010018 --defsym tail_callee=0x12010028 \
|
||||
# RUN: %t.o -o %t
|
||||
# RUN: -z separate-code %t.o -o %t
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=THUNK %s
|
||||
# RUN: llvm-readelf --sections %t | FileCheck --check-prefix=BRANCHLT %s
|
||||
# RUN: not ld.lld --defsym callee=0x1001002D --defsym tail_callee=0x1001002F \
|
||||
# RUN: %t.o -o %t 2>&1 | FileCheck --check-prefix=MISSALIGNED %s
|
||||
# RUN: -z separate-code %t.o -o %t 2>&1 | FileCheck --check-prefix=MISSALIGNED %s
|
||||
|
||||
# MISSALIGNED: ld.lld: error: {{.*}}.o:(.text+0x14): improper alignment for relocation R_PPC64_REL24: 0x19 is not aligned to 4 bytes
|
||||
# MISSALIGNED: ld.lld: error: {{.*}}.o:(.text+0x24): improper alignment for relocation R_PPC64_REL24: 0xB is not aligned to 4 bytes
|
||||
|
@ -72,19 +72,19 @@ test:
|
|||
# .branch_lt[0]
|
||||
# THUNK-LABEL: __long_branch_callee:
|
||||
# THUNK-NEXT: 10010028: addis 12, 2, 1
|
||||
# THUNK-NEXT: ld 12, -32768(12)
|
||||
# THUNK-NEXT: ld 12, -32760(12)
|
||||
# THUNK-NEXT: mtctr 12
|
||||
# THUNK-NEXT: bctr
|
||||
|
||||
# .branch_lt[1]
|
||||
# THUNK-LABEL: __long_branch_tail_callee:
|
||||
# THUNK-NEXT: 10010038: addis 12, 2, 1
|
||||
# THUNK-NEXT: ld 12, -32760(12)
|
||||
# THUNK-NEXT: ld 12, -32752(12)
|
||||
# THUNK-NEXT: mtctr 12
|
||||
# THUNK-NEXT: bctr
|
||||
|
||||
# The offset from the TOC to the .branch_lt section is (-1 << 16) - 32768.
|
||||
# Name Type Address Off Size
|
||||
# BRANCHLT: .got PROGBITS 0000000010020000 020000 000008
|
||||
# BRANCHLT: .branch_lt PROGBITS 0000000010030000 030000 000010
|
||||
# BRANCHLT: .branch_lt PROGBITS 0000000010030008 020008 000010
|
||||
# BRANCHLT-NOT: .plt
|
||||
|
|
|
@ -28,5 +28,7 @@ test:
|
|||
# Verify that we don't overwrite any of the extended opcode bits on a DQ form
|
||||
# instruction.
|
||||
# CHECK-LABEL: test
|
||||
# CHECK: lxv 3, -32768(3)
|
||||
# CHECK: stxv 3, -32768(3)
|
||||
# CHECK: addis 3, 2, 1
|
||||
# CHECK-NEXT: lxv 3, -32752(3)
|
||||
# CHECK-NEXT: addis 3, 2, 1
|
||||
# CHECK-NEXT: stxv 3, -32752(3)
|
||||
|
|
|
@ -137,15 +137,15 @@ k:
|
|||
// OutputRelocs-NEXT: R_PPC64_DTPMOD64
|
||||
|
||||
|
||||
// The got entry for i is at .got+8*3 = 0x420510
|
||||
// The got entry for i is at .got+8*1 = 0x4209e0
|
||||
// i@dtprel = 1024 - 0x8000 = -31744 = 0xffffffffffff8400
|
||||
// HEX-LE: section '.got':
|
||||
// HEX-LE-NEXT: 4204f8 f8844200 00000000 00000000 00000000
|
||||
// HEX-LE-NEXT: 420508 00000000 00000000
|
||||
// HEX-LE-NEXT: 4209d8 d8894200 00000000 00000000 00000000
|
||||
// HEX-LE-NEXT: 4209e8 00000000 00000000
|
||||
|
||||
// HEX-BE: section '.got':
|
||||
// HEX-BE-NEXT: 4204f8 00000000 004284f8 00000000 00000000
|
||||
// HEX-BE-NEXT: 420508 00000000 00000000
|
||||
// HEX-BE-NEXT: 4209d8 00000000 004289d8 00000000 00000000
|
||||
// HEX-BE-NEXT: 4209e8 00000000 00000000
|
||||
|
||||
// Dis: test:
|
||||
// Dis: addi 4, 3, -31744
|
||||
|
|
|
@ -34,12 +34,12 @@ _start:
|
|||
.Lfunc_end0:
|
||||
.size _start, .Lfunc_end0-.Lfunc_begin0
|
||||
|
||||
# NM-DAG: 0000000010028000 d .TOC.
|
||||
# NM-DAG: 0000000010010000 T _start
|
||||
# NM-DAG: 00000000100281f0 d .TOC.
|
||||
# NM-DAG: 00000000100101d0 T _start
|
||||
|
||||
# 0x10010000 = (4097<<16) + 0
|
||||
# CHECK: 10010000: lis 4, 4097
|
||||
# CHECK-NEXT: 10010004: addi 4, 4, 0
|
||||
# .TOC. - _start = (2<<16) - 32768
|
||||
# CHECK-NEXT: 10010008: lis 5, 2
|
||||
# CHECK-NEXT: 1001000c: addi 5, 5, -32768
|
||||
# 0x100101d0 = (4097<<16) + 464
|
||||
# CHECK: 100101d0: lis 4, 4097
|
||||
# CHECK-NEXT: 100101d4: addi 4, 4, 464
|
||||
# .TOC. - _start = (2<<16) - 32736
|
||||
# CHECK-NEXT: 100101d8: lis 5, 2
|
||||
# CHECK-NEXT: 100101dc: addi 5, 5, -32736
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
|
||||
# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
|
||||
|
||||
# CHECK: improper alignment for relocation R_PPC64_TOC16_LO_DS: 0x8001 is not aligned to 16 bytes
|
||||
# CHECK: improper alignment for relocation R_PPC64_TOC16_LO_DS: 0x8009 is not aligned to 16 bytes
|
||||
|
||||
.global test
|
||||
.p2align 4
|
||||
|
@ -21,6 +21,6 @@ test:
|
|||
lxv 3, qword@toc@l(3)
|
||||
blr
|
||||
|
||||
.p2align 4
|
||||
.comm pad, 1, 1
|
||||
.comm qword, 16, 1
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
|
||||
# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
|
||||
|
||||
# CHECK: improper alignment for relocation R_PPC64_TOC16_LO_DS: 0x8001 is not aligned to 4 bytes
|
||||
# CHECK: improper alignment for relocation R_PPC64_TOC16_LO_DS: 0x8009 is not aligned to 4 bytes
|
||||
|
||||
.global test
|
||||
.p2align 4
|
||||
|
@ -21,6 +21,6 @@ test:
|
|||
lwa 3, word@toc@l(3)
|
||||
blr
|
||||
|
||||
.p2align 4
|
||||
.comm pad, 1, 1
|
||||
.comm word, 4, 1
|
||||
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func-global-entry.s -o %t2.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func-local-entry.s -o %t3.o
|
||||
// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.o %t3.o -o %t
|
||||
// RUN: llvm-objdump -d %t | FileCheck %s
|
||||
// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-func-global-entry.s -o %t2.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-func-local-entry.s -o %t3.o
|
||||
// RUN: ld.lld -dynamic-linker /lib64/ld64.so.2 %t.o %t2.o %t3.o -o %t
|
||||
// RUN: llvm-objdump -d %t | FileCheck %s
|
||||
// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
|
||||
|
||||
.text
|
||||
.abiversion 2
|
||||
|
@ -69,12 +69,12 @@ glob:
|
|||
# foo_external_diff+8. Also check that foo_external_same has no global entry
|
||||
# point and we branch to start of foo_external_same.
|
||||
|
||||
// CHECK: _start:
|
||||
// CHECK: 10010020: {{.*}} bl .+144
|
||||
// CHECK: 10010034: {{.*}} bl .+84
|
||||
// CHECK: foo_external_diff:
|
||||
// CHECK-NEXT: 10010080: {{.*}} addis 2, 12, 1
|
||||
// CHECK-NEXT: 10010084: {{.*}} addi 2, 2, 32640
|
||||
// CHECK-NEXT: 10010088: {{.*}} addis 5, 2, 1
|
||||
// CHECK: foo_external_same:
|
||||
// CHECK-NEXT: 100100b0: {{.*}} add 3, 4, 3
|
||||
// CHECK-LABEL: _start:
|
||||
// CHECK: 100101f0: bl .+144
|
||||
// CHECK: 10010204: bl .+84
|
||||
// CHECK-LABEL: foo_external_diff:
|
||||
// CHECK-NEXT: 10010250: addis 2, 12, 2
|
||||
// CHECK-NEXT: 10010254: addi 2, 2, -32696
|
||||
// CHECK-NEXT: 10010258: addis 5, 2, 1
|
||||
// CHECK-LABEL: foo_external_same:
|
||||
// CHECK-NEXT: 10010280: add 3, 4, 3
|
||||
|
|
|
@ -14,43 +14,43 @@
|
|||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
|
||||
# RUN: llvm-readobj -r %t | FileCheck --check-prefix=REL %s
|
||||
|
||||
# NM-DAG: 0000000010028000 d .TOC.
|
||||
# NM-DAG: 0000000010010000 T ifunc
|
||||
# NM-DAG: 0000000010010004 T ifunc2
|
||||
# NM-DAG: 0000000010028248 d .TOC.
|
||||
# NM-DAG: 00000000100101f8 T ifunc
|
||||
# NM-DAG: 00000000100101fc T ifunc2
|
||||
|
||||
# SECTIONS: .plt NOBITS 0000000010030000
|
||||
# SECTIONS: .plt NOBITS 0000000010030250 000250 000010 00 WA 0 0 8
|
||||
|
||||
# __plt_ifunc - . = 0x10010020 - 0x10010010 = 16
|
||||
# __plt_ifunc2 - . = 0x10010044 - 0x10010018 = 28
|
||||
# __plt_ifunc - . = 0x10010218 - 0x10010208 = 16
|
||||
# __plt_ifunc2 - . = 0x1001022c - 0x10010210 = 28
|
||||
# CHECK: _start:
|
||||
# CHECK-NEXT: addis 2, 12, 1
|
||||
# CHECK-NEXT: addi 2, 2, 32760
|
||||
# CHECK-NEXT: 10010010: bl .+16
|
||||
# CHECK-NEXT: addis 2, 12, 2
|
||||
# CHECK-NEXT: addi 2, 2, -32696
|
||||
# CHECK-NEXT: 10010208: bl .+16
|
||||
# CHECK-NEXT: ld 2, 24(1)
|
||||
# CHECK-NEXT: 10010018: bl .+28
|
||||
# CHECK-NEXT: 10010210: bl .+28
|
||||
# CHECK-NEXT: ld 2, 24(1)
|
||||
|
||||
# .plt[0] - .TOC. = 0x10030000 - 0x10028000 = (1<<16) - 32768
|
||||
# .plt[0] - .TOC. = 0x10030250 - 0x10028248 = (1<<16) - 32760
|
||||
# CHECK: __plt_ifunc:
|
||||
# CHECK-NEXT: std 2, 24(1)
|
||||
# CHECK-NEXT: addis 12, 2, 1
|
||||
# CHECK-NEXT: ld 12, -32768(12)
|
||||
# CHECK-NEXT: mtctr 12
|
||||
# CHECK-NEXT: bctr
|
||||
|
||||
# .plt[1] - .TOC. = 0x10030000+8 - 0x10028000 = (1<<16) - 32760
|
||||
# CHECK: __plt_ifunc2:
|
||||
# CHECK-NEXT: std 2, 24(1)
|
||||
# CHECK-NEXT: addis 12, 2, 1
|
||||
# CHECK-NEXT: ld 12, -32760(12)
|
||||
# CHECK-NEXT: mtctr 12
|
||||
# CHECK-NEXT: bctr
|
||||
|
||||
# .plt[1] - .TOC. = 0x10030250+8 - 0x10028248 = (1<<16) - 32752
|
||||
# CHECK: __plt_ifunc2:
|
||||
# CHECK-NEXT: std 2, 24(1)
|
||||
# CHECK-NEXT: addis 12, 2, 1
|
||||
# CHECK-NEXT: ld 12, -32752(12)
|
||||
# CHECK-NEXT: mtctr 12
|
||||
# CHECK-NEXT: bctr
|
||||
|
||||
## Check that we emit 2 R_PPC64_IRELATIVE in .rela.dyn.
|
||||
## glibc powerpc64 does not eagerly resolve R_PPC64_IRELATIVE if they are in .rela.plt.
|
||||
# REL: .rela.dyn {
|
||||
# REL-NEXT: 0x10030000 R_PPC64_IRELATIVE - 0x10010000
|
||||
# REL-NEXT: 0x10030008 R_PPC64_IRELATIVE - 0x10010004
|
||||
# REL-NEXT: 0x10030250 R_PPC64_IRELATIVE - 0x100101F8
|
||||
# REL-NEXT: 0x10030258 R_PPC64_IRELATIVE - 0x100101FC
|
||||
# REL-NEXT: }
|
||||
|
||||
.type ifunc STT_GNU_IFUNC
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// REQUIRES: ppc
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
|
||||
// RUN: ld.lld -shared %t.o -o %t.so
|
||||
// RUN: ld.lld -shared %t.o -z separate-code -o %t.so
|
||||
// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
|
||||
// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
|
||||
// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
|
||||
// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=Dis %s
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
|
||||
// RUN: ld.lld -shared %t.o -o %t.so
|
||||
// RUN: ld.lld -shared %t.o -z separate-code -o %t.so
|
||||
// RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
|
||||
// RUN: llvm-readelf -r %t.so | FileCheck --check-prefix=OutputRelocs %s
|
||||
// RUN: llvm-objdump --section-headers %t.so | FileCheck --check-prefix=CheckGot %s
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# REQUIRES: ppc
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=ppc64le %s -o %t.o
|
||||
# RUN: ld.lld %t.o -o %t
|
||||
# RUN: ld.lld %t.o -z separate-code -o %t
|
||||
# RUN: llvm-nm %t | FileCheck %s
|
||||
|
||||
# CHECK-DAG: 0000000010010000 t __long_branch_callee
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
# REQUIRES: ppc
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
|
||||
# RUN: ld.lld --no-toc-optimize %t.o -o %t
|
||||
# RUN: ld.lld --no-toc-optimize -z separate-code %t.o -o %t
|
||||
# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s
|
||||
# RUN: llvm-readelf -x .branch_lt %t | FileCheck %s -check-prefix=BRANCH-LE
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
|
||||
# RUN: ld.lld --no-toc-optimize %t.o -o %t
|
||||
# RUN: ld.lld --no-toc-optimize -z separate-code %t.o -o %t
|
||||
# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s
|
||||
# RUN: llvm-readelf -x .branch_lt %t | FileCheck %s -check-prefix=BRANCH-BE
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
|
||||
|
@ -82,13 +82,13 @@ a:
|
|||
# CHECK: 12010038: bl .+16
|
||||
|
||||
# BRANCH-LE: section '.branch_lt':
|
||||
# BRANCH-LE-NEXT: 0x12030008 08000110 00000000
|
||||
# BRANCH-LE-NEXT: 0x12030018 08000110 00000000
|
||||
# BRANCH-BE: section '.branch_lt':
|
||||
# BRANCH-BE-NEXT: 0x12030008 00000000 10010008
|
||||
# BRANCH-BE-NEXT: 0x12030018 00000000 10010008
|
||||
|
||||
# .branch_lt - .TOC. = 0x12030008 - 0x12028000 = (1<<16) - 32760
|
||||
# .branch_lt - .TOC. = 0x12030018 - 0x12028000 = (1<<16) - 32744
|
||||
# CHECK: __long_branch_callee:
|
||||
# CHECK-NEXT: 12010048: addis 12, 2, 1
|
||||
# CHECK-NEXT: ld 12, -32760(12)
|
||||
# CHECK-NEXT: ld 12, -32744(12)
|
||||
# CHECK-NEXT: mtctr 12
|
||||
# CHECK-NEXT: bctr
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
|
||||
|
||||
## DT_PLTGOT points to .plt
|
||||
# SEC: .plt NOBITS 0000000010030000 030000 000018
|
||||
# SEC: 0x0000000000000003 (PLTGOT) 0x10030000
|
||||
# SEC: .plt NOBITS 00000000100303e8 0003e8 000018
|
||||
# SEC: 0x0000000000000003 (PLTGOT) 0x100303e8
|
||||
|
||||
## .plt[0] holds the address of _dl_runtime_resolve.
|
||||
## .plt[1] holds the link map.
|
||||
|
@ -24,12 +24,12 @@
|
|||
# RELOC: 0x10030010 R_PPC64_JMP_SLOT foo 0x0
|
||||
|
||||
# CHECK: _start:
|
||||
# CHECK: 10010008: bl .+16
|
||||
# CHECK: 10010298: bl .+16
|
||||
|
||||
# CHECK-LABEL: 0000000010010018 __plt_foo:
|
||||
# CHECK-LABEL: 00000000100102a8 __plt_foo:
|
||||
# CHECK-NEXT: std 2, 24(1)
|
||||
# CHECK-NEXT: addis 12, 2, 0
|
||||
# CHECK-NEXT: ld 12, 32560(12)
|
||||
# CHECK-NEXT: addis 12, 2, 1
|
||||
# CHECK-NEXT: ld 12, -32744(12)
|
||||
# CHECK-NEXT: mtctr 12
|
||||
# CHECK-NEXT: bctr
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t
|
||||
# RUN: ld.lld %t -o %t2
|
||||
# RUN: llvm-objdump -d %t2 | FileCheck %s
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t2 | FileCheck %s
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
|
||||
# RUN: ld.lld %t -o %t2
|
||||
# RUN: llvm-objdump -d %t2 | FileCheck %s
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t2 | FileCheck %s
|
||||
|
||||
# CHECK: Disassembly of section .text:
|
||||
# CHECK-EMPTY:
|
||||
|
@ -19,9 +19,9 @@ _start:
|
|||
li 3,42
|
||||
sc
|
||||
|
||||
# CHECK: 10010000: {{.*}} li 0, 1
|
||||
# CHECK: 10010004: {{.*}} li 3, 42
|
||||
# CHECK: 10010008: {{.*}} sc
|
||||
# CHECK: 10010158: li 0, 1
|
||||
# CHECK: 1001015c: li 3, 42
|
||||
# CHECK: 10010160: sc
|
||||
|
||||
.global bar
|
||||
bar:
|
||||
|
@ -31,8 +31,8 @@ bar:
|
|||
nop
|
||||
blr
|
||||
|
||||
# CHECK: 1001000c: {{.*}} bl .-12
|
||||
# CHECK: 10010010: {{.*}} nop
|
||||
# CHECK: 10010014: {{.*}} bl .-20
|
||||
# CHECK: 10010018: {{.*}} nop
|
||||
# CHECK: 1001001c: {{.*}} blr
|
||||
# CHECK: 10010164: bl .-12
|
||||
# CHECK-NEXT: nop
|
||||
# CHECK-NEXT: 1001016c: bl .-20
|
||||
# CHECK-NEXT: nop
|
||||
# CHECK-NEXT: blr
|
||||
|
|
|
@ -48,11 +48,11 @@ rel64:
|
|||
# REL-NEXT: 0x28 R_PPC64_REL32 .REL32_AND_REL64 0x0
|
||||
# REL-NEXT: }
|
||||
|
||||
# SEC: .REL32_AND_REL64 PROGBITS 0000000010010020
|
||||
# SEC: .REL32_AND_REL64 PROGBITS 00000000100101b4
|
||||
|
||||
## CIE Personality Address: 0x10010020-(0x10000168+2)+4 = 0xfeba
|
||||
## FDE PC Begin: 0x10010020-(0x10000178+8) = 0xfea0
|
||||
## CIE Personality Address: 0x100101b4-(0x10000168+2)+4 = 0x1004e
|
||||
## FDE PC Begin: 0x100101b4-(0x10000178+8) = 0x10034
|
||||
# HEX: section '.eh_frame':
|
||||
# HEX-NEXT: 0x10000158
|
||||
# HEX-NEXT: 0x10000168 {{....}}bafe 00000000
|
||||
# HEX-NEXT: 0x10000178 {{[0-9a-f]+}} {{[0-9a-f]+}} a0fe0000
|
||||
# HEX-NEXT: 0x10000168 {{....}}4e00 01000000 0000{{....}}
|
||||
# HEX-NEXT: 0x10000178 {{[0-9a-f]+}} {{[0-9a-f]+}} 34000100
|
||||
|
|
|
@ -26,31 +26,31 @@ _start:
|
|||
ld 1, .L1@toc@l(2)
|
||||
|
||||
# CHECK-LABEL: Disassembly of section .R_PPC64_TOC16_LO_DS:
|
||||
# CHECK: 1001000c: ld 1, -32768(2)
|
||||
# CHECK: ld 1, -32768(2)
|
||||
|
||||
.section .R_PPC64_TOC16_LO,"ax",@progbits
|
||||
addi 1, 2, .L1@toc@l
|
||||
|
||||
# CHECK-LABEL: Disassembly of section .R_PPC64_TOC16_LO:
|
||||
# CHECK: 10010010: addi 1, 2, -32768
|
||||
# CHECK: addi 1, 2, -32768
|
||||
|
||||
.section .R_PPC64_TOC16_HI,"ax",@progbits
|
||||
addis 1, 2, .L1@toc@h
|
||||
|
||||
# CHECK-LABEL: Disassembly of section .R_PPC64_TOC16_HI:
|
||||
# CHECK: 10010014: addis 1, 2, -1
|
||||
# CHECK: addis 1, 2, -1
|
||||
|
||||
.section .R_PPC64_TOC16_HA,"ax",@progbits
|
||||
addis 1, 2, .L1@toc@ha
|
||||
|
||||
# CHECK-LABEL: Disassembly of section .R_PPC64_TOC16_HA:
|
||||
# CHECK: 10010018: addis 1, 2, 0
|
||||
# CHECK: addis 1, 2, 0
|
||||
|
||||
.section .R_PPC64_ADDR16_LO,"ax",@progbits
|
||||
li 1, .Lfoo@l
|
||||
|
||||
# CHECK-LABEL: Disassembly of section .R_PPC64_ADDR16_LO:
|
||||
# CHECK: li 1, 0
|
||||
# CHECK: li 1, 464
|
||||
|
||||
.section .R_PPC64_ADDR16_HI,"ax",@progbits
|
||||
li 1, .Lfoo@h
|
||||
|
@ -91,11 +91,11 @@ _start:
|
|||
.section .R_PPC64_TOC,"a",@progbits
|
||||
.quad .TOC.@tocbase
|
||||
|
||||
# SEC: .got PROGBITS 0000000010020000
|
||||
# SEC: .got PROGBITS 0000000010020208
|
||||
|
||||
## tocbase = .got+0x8000 = 0x10028000
|
||||
## tocbase = .got+0x8000 = 0x10028208
|
||||
# DATALE-LABEL: section '.R_PPC64_TOC':
|
||||
# DATALE: 00800210 00000000
|
||||
# DATALE: 08820210 00000000
|
||||
|
||||
# DATABE-LABEL: section '.R_PPC64_TOC':
|
||||
# DATABE: 00000000 10028000
|
||||
# DATABE: 00000000 10028208
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# REQUIRES: ppc
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
|
||||
# RUN: ld.lld --no-toc-optimize -shared %t.o -o %t
|
||||
# RUN: ld.lld --no-toc-optimize -shared -z separate-code %t.o -o %t
|
||||
# RUN: llvm-objdump -d -start-address=0x10000 -stop-address=0x10018 %t | FileCheck %s -check-prefix=CALLEE_DUMP
|
||||
# RUN: llvm-objdump -d -start-address=0x2010020 -stop-address=0x2010070 %t | FileCheck %s -check-prefix=CALLER_DUMP
|
||||
# RUN: llvm-readelf --sections %t | FileCheck %s -check-prefix=SECTIONS
|
||||
|
@ -92,11 +92,10 @@ b:
|
|||
# CALLER_DUMP: 2010020: {{.*}} addis 2, 12, 2
|
||||
# CALLER_DUMP: 2010038: {{.*}} bl .+56
|
||||
|
||||
# Verify the thunks contents: TOC-pointer + offset = .branch_lt[0]
|
||||
# 0x20280F0 + 32560 = 0x2030020
|
||||
## .branch_lt[0] - .TOC. =
|
||||
# CALLER_DUMP: __long_branch_callee:
|
||||
# CALLER_DUMP: 2010060: {{.*}} addis 12, 2, 0
|
||||
# CALLER_DUMP: 2010064: {{.*}} ld 12, 32560(12)
|
||||
# CALLER_DUMP: 2010060: {{.*}} addis 12, 2, 1
|
||||
# CALLER_DUMP: 2010064: {{.*}} ld 12, -32712(12)
|
||||
# CALLER_DUMP: 2010068: {{.*}} mtctr 12
|
||||
# CALLER_DUMP: 201006c: {{.*}} bctr
|
||||
|
||||
|
@ -104,11 +103,11 @@ b:
|
|||
# .plt section has a 2 entry header and a single entry for the long branch.
|
||||
# [Nr] Name Type Address Off Size
|
||||
# SECTIONS: [10] .got PROGBITS 00000000020200f0 20200f0 000008
|
||||
# SECTIONS: [13] .plt NOBITS 0000000002030008 2030008 000018
|
||||
# SECTIONS: [14] .branch_lt NOBITS 0000000002030020 2030008 000008
|
||||
# SECTIONS: [13] .plt NOBITS 0000000002030110 2020110 000018
|
||||
# SECTIONS: [14] .branch_lt NOBITS 0000000002030128 2020110 000008
|
||||
|
||||
# There is a relative dynamic relocation for (.plt + 16 bytes), with a base
|
||||
# address equal to callees local entry point (0x10000 + 8).
|
||||
# DYNRELOC: Relocation section '.rela.dyn' at offset 0x{{[0-9a-f]+}} contains 3 entries:
|
||||
# DYNRELOC: Offset Info Type Symbol's Value
|
||||
# DYNRELOC: 0000000002030020 0000000000000016 R_PPC64_RELATIVE 10008
|
||||
# DYNRELOC: 0000000002030128 0000000000000016 R_PPC64_RELATIVE 10008
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=IE %s
|
||||
|
||||
# GD-REL: .rela.dyn {
|
||||
# GD-REL-NEXT: 0x200F0 R_PPC64_DTPMOD64 a 0x0
|
||||
# GD-REL-NEXT: 0x200F8 R_PPC64_DTPREL64 a 0x0
|
||||
# GD-REL-NEXT: 0x20100 R_PPC64_DTPMOD64 b 0x0
|
||||
# GD-REL-NEXT: 0x20108 R_PPC64_DTPREL64 b 0x0
|
||||
# GD-REL-NEXT: 0x20110 R_PPC64_DTPMOD64 c 0x0
|
||||
# GD-REL-NEXT: 0x20118 R_PPC64_DTPREL64 c 0x0
|
||||
# GD-REL-NEXT: 0x20540 R_PPC64_DTPMOD64 a 0x0
|
||||
# GD-REL-NEXT: 0x20548 R_PPC64_DTPREL64 a 0x0
|
||||
# GD-REL-NEXT: 0x20550 R_PPC64_DTPMOD64 b 0x0
|
||||
# GD-REL-NEXT: 0x20558 R_PPC64_DTPREL64 b 0x0
|
||||
# GD-REL-NEXT: 0x20560 R_PPC64_DTPMOD64 c 0x0
|
||||
# GD-REL-NEXT: 0x20568 R_PPC64_DTPREL64 c 0x0
|
||||
# GD-REL-NEXT: }
|
||||
|
||||
## &DTPMOD(a) - .TOC. = &.got[0] - (.got+0x8000) = -32768
|
||||
|
@ -59,8 +59,8 @@
|
|||
# LE-NEXT: addi 3, 3, -28656
|
||||
|
||||
# IE-REL: .rela.dyn {
|
||||
# IE-REL-NEXT: 0x100200C0 R_PPC64_TPREL64 b 0x0
|
||||
# IE-REL-NEXT: 0x100200C8 R_PPC64_TPREL64 c 0x0
|
||||
# IE-REL-NEXT: 0x10020418 R_PPC64_TPREL64 b 0x0
|
||||
# IE-REL-NEXT: 0x10020420 R_PPC64_TPREL64 c 0x0
|
||||
# IE-REL-NEXT: }
|
||||
|
||||
## a is relaxed to use LE.
|
||||
|
|
|
@ -23,10 +23,10 @@
|
|||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=LE %s
|
||||
|
||||
# IE-REL: .rela.dyn {
|
||||
# IE-REL-NEXT: 0x200B0 R_PPC64_TPREL64 c 0x0
|
||||
# IE-REL-NEXT: 0x200C0 R_PPC64_TPREL64 i 0x0
|
||||
# IE-REL-NEXT: 0x200C8 R_PPC64_TPREL64 l 0x0
|
||||
# IE-REL-NEXT: 0x200B8 R_PPC64_TPREL64 s 0x0
|
||||
# IE-REL-NEXT: 0x204A0 R_PPC64_TPREL64 c 0x0
|
||||
# IE-REL-NEXT: 0x204B0 R_PPC64_TPREL64 i 0x0
|
||||
# IE-REL-NEXT: 0x204B8 R_PPC64_TPREL64 l 0x0
|
||||
# IE-REL-NEXT: 0x204A8 R_PPC64_TPREL64 s 0x0
|
||||
# IE-REL-NEXT: }
|
||||
|
||||
# INPUT-REL: R_PPC64_GOT_TPREL16_HA c 0x0
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# REQUIRES: ppc
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o
|
||||
# RUN: ld.lld %t.o -o %t
|
||||
# RUN: llvm-readelf -S -l %t | FileCheck --check-prefix=SEC %s
|
||||
# RUN: llvm-objdump -d %t | FileCheck --check-prefix=DIS %s
|
||||
|
||||
# SEC: Name Type Address Off Size ES Flg Lk Inf Al
|
||||
# SEC: .tdata PROGBITS 0000000010020300 000300 000001 00 WAT 0 0 1
|
||||
# SEC: .tbss NOBITS 0000000010020400 000301 000008 00 WAT 0 0 256
|
||||
|
||||
# SEC: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
|
||||
# SEC: TLS 0x000300 0x0000000010020300 0x0000000010020300 0x000001 0x000108 R 0x100
|
||||
|
||||
## We currently have a hack in Writer.cpp:fixSectionAlignments() to force
|
||||
## p_vaddr(PT_TLS)%p_align(PT_TLS)=0, to work around bugs in some dynamic loaders.
|
||||
|
||||
## p_vaddr rounded down to p_align has TP offset -0x7000.
|
||||
## The first address of PT_TLS (p_vaddr) has TP offset (p_vaddr%p_align - 0x7000).
|
||||
## Once we delete the hack, it is likely p_vaddr%p_align != 0.
|
||||
|
||||
## a@tprel = st_value(a) + p_vaddr%p_align - 0x7000 = .tbss-.tdata + p_vaddr%p_align - 0x7000
|
||||
## = 0x10020400-0x10020300 + 0 - 0x7000 = -28416
|
||||
# DIS: ld 3, -28416(13)
|
||||
|
||||
ld 3, a@tprel(13)
|
||||
|
||||
.section .tdata,"awT"
|
||||
.byte 0
|
||||
|
||||
.section .tbss,"awT"
|
||||
.p2align 8
|
||||
a:
|
||||
.quad 0
|
|
@ -1,4 +1,5 @@
|
|||
# REQUIRES: ppc
|
||||
# XFAIL: *
|
||||
|
||||
# RUN: llvm-readelf -relocations --wide %p/Inputs/ppc64le-quadword-ldst.o | FileCheck --check-prefix=QuadInputRelocs %s
|
||||
|
||||
|
|
|
@ -4,12 +4,15 @@
|
|||
# RUN: llvm-readelf -r %t.o | FileCheck --check-prefix=InputRelocs %s
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
|
||||
# RUN: ld.lld -shared %t2.o -o %t2.so
|
||||
# RUN: ld.lld -shared -soname=t2.so %t2.o -o %t2.so
|
||||
|
||||
## Place all sections in the same segment so that .text and .TOC. are on the same page.
|
||||
# RUN: echo 'PHDRS { all PT_LOAD; }' > %t.script
|
||||
#
|
||||
# RUN: ld.lld %t2.so %t.o -o %t
|
||||
# RUN: ld.lld %t2.so %t.o -T %t.script -o %t
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=Dis %s
|
||||
#
|
||||
# RUN: ld.lld --no-toc-optimize %t2.so %t.o -o %t
|
||||
# RUN: ld.lld %t2.so %t.o -T %t.script --no-toc-optimize -o %t
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefix=NoOpt %s
|
||||
|
||||
# InputRelocs: Relocation section '.rela.text'
|
||||
|
@ -39,18 +42,18 @@ bytes:
|
|||
# Dis-NEXT: addis
|
||||
# Dis-NEXT: addi
|
||||
# Dis-NEXT: nop
|
||||
# Dis-NEXT: lbz 3, 32624(2)
|
||||
# Dis-NEXT: lbz 3, -32752(2)
|
||||
# Dis-NEXT: nop
|
||||
# Dis-NEXT: stb 3, 32625(2)
|
||||
# Dis-NEXT: stb 3, -32751(2)
|
||||
# Dis-NEXT: blr
|
||||
|
||||
# NoOpt-LABEL: bytes:
|
||||
# NoOpt-NEXT: addis
|
||||
# NoOpt-NEXT: addi
|
||||
# NoOpt-NEXT: addis 3, 2, 0
|
||||
# NoOpt-NEXT: lbz 3, 32624(3)
|
||||
# NoOpt-NEXT: lbz 3, -32752(3)
|
||||
# NoOpt-NEXT: addis 4, 2, 0
|
||||
# NoOpt-NEXT: stb 3, 32625(4)
|
||||
# NoOpt-NEXT: stb 3, -32751(4)
|
||||
# NoOpt-NEXT: blr
|
||||
|
||||
.global halfs
|
||||
|
@ -73,22 +76,22 @@ halfs:
|
|||
# Dis-NEXT: addis
|
||||
# Dis-NEXT: addi
|
||||
# Dis-NEXT: nop
|
||||
# Dis-NEXT: lhz 3, 32626(2)
|
||||
# Dis-NEXT: lhz 3, -32750(2)
|
||||
# Dis-NEXT: nop
|
||||
# Dis-NEXT: lha 4, 32626(2)
|
||||
# Dis-NEXT: lha 4, -32750(2)
|
||||
# Dis-NEXT: nop
|
||||
# Dis-NEXT: sth 4, 32628(2)
|
||||
# Dis-NEXT: sth 4, -32748(2)
|
||||
# Dis-NEXT: blr
|
||||
|
||||
# NoOpt-LABEL: halfs:
|
||||
# NoOpt-NEXT: addis
|
||||
# NoOpt-NEXT: addi
|
||||
# NoOpt-NEXT: addis 3, 2, 0
|
||||
# NoOpt-NEXT: lhz 3, 32626(3)
|
||||
# NoOpt-NEXT: lhz 3, -32750(3)
|
||||
# NoOpt-NEXT: addis 4, 2, 0
|
||||
# NoOpt-NEXT: lha 4, 32626(4)
|
||||
# NoOpt-NEXT: lha 4, -32750(4)
|
||||
# NoOpt-NEXT: addis 5, 2, 0
|
||||
# NoOpt-NEXT: sth 4, 32628(5)
|
||||
# NoOpt-NEXT: sth 4, -32748(5)
|
||||
# NoOpt-NEXT: blr
|
||||
|
||||
|
||||
|
@ -112,22 +115,22 @@ words:
|
|||
# Dis-NEXT: addis
|
||||
# Dis-NEXT: addi
|
||||
# Dis-NEXT: nop
|
||||
# Dis-NEXT: lwz 3, 32632(2)
|
||||
# Dis-NEXT: lwz 3, -32744(2)
|
||||
# Dis-NEXT: nop
|
||||
# Dis-NEXT: lwa 4, 32632(2)
|
||||
# Dis-NEXT: lwa 4, -32744(2)
|
||||
# Dis-NEXT: nop
|
||||
# Dis-NEXT: stw 4, 32636(2)
|
||||
# Dis-NEXT: stw 4, -32740(2)
|
||||
# Dis-NEXT: blr
|
||||
|
||||
# NoOpt-LABEL: words
|
||||
# NoOpt-NEXT: addis
|
||||
# NoOpt-NEXT: addi
|
||||
# NoOpt-NEXT: addis 3, 2, 0
|
||||
# NoOpt-NEXT: lwz 3, 32632(3)
|
||||
# NoOpt-NEXT: lwz 3, -32744(3)
|
||||
# NoOpt-NEXT: addis 4, 2, 0
|
||||
# NoOpt-NEXT: lwa 4, 32632(4)
|
||||
# NoOpt-NEXT: lwa 4, -32744(4)
|
||||
# NoOpt-NEXT: addis 5, 2, 0
|
||||
# NoOpt-NEXT: stw 4, 32636(5)
|
||||
# NoOpt-NEXT: stw 4, -32740(5)
|
||||
# NoOpt-NEXT: blr
|
||||
|
||||
.global doublewords
|
||||
|
@ -149,18 +152,18 @@ doublewords:
|
|||
# Dis-NEXT: addis
|
||||
# Dis-NEXT: addi
|
||||
# Dis-NEXT: nop
|
||||
# Dis-NEXT: ld 3, 32640(2)
|
||||
# Dis-NEXT: ld 3, -32736(2)
|
||||
# Dis-NEXT: nop
|
||||
# Dis-NEXT: std 3, 32648(2)
|
||||
# Dis-NEXT: std 3, -32728(2)
|
||||
# Dis-NEXT: blr
|
||||
|
||||
# NoOpt-LABEL: doublewords
|
||||
# NoOpt-NEXT: addis
|
||||
# NoOpt-NEXT: addi
|
||||
# NoOpt-NEXT: addis 3, 2, 0
|
||||
# NoOpt-NEXT: ld 3, 32640(3)
|
||||
# NoOpt-NEXT: ld 3, -32736(3)
|
||||
# NoOpt-NEXT: addis 4, 2, 0
|
||||
# NoOpt-NEXT: std 3, 32648(4)
|
||||
# NoOpt-NEXT: std 3, -32728(4)
|
||||
# NoOpt-NEXT: blr
|
||||
|
||||
.global vec_dq
|
||||
|
@ -182,18 +185,18 @@ vec_dq:
|
|||
# Dis-NEXT: addis
|
||||
# Dis-NEXT: addi
|
||||
# Dis-NEXT: nop
|
||||
# Dis-NEXT: lxv 3, 32656(2)
|
||||
# Dis-NEXT: lxv 3, -32720(2)
|
||||
# Dis-NEXT: nop
|
||||
# Dis-NEXT: stxv 3, 32672(2)
|
||||
# Dis-NEXT: stxv 3, -32704(2)
|
||||
# Dis-NEXT: blr
|
||||
|
||||
# NoOpt-LABEL: vec_dq:
|
||||
# NoOpt-NEXT: addis
|
||||
# NoOpt-NEXT: addi
|
||||
# NoOpt-NEXT: addis 3, 2, 0
|
||||
# NoOpt-NEXT: lxv 3, 32656(3)
|
||||
# NoOpt-NEXT: lxv 3, -32720(3)
|
||||
# NoOpt-NEXT: addis 3, 2, 0
|
||||
# NoOpt-NEXT: stxv 3, 32672(3)
|
||||
# NoOpt-NEXT: stxv 3, -32704(3)
|
||||
# NoOpt-NEXT: blr
|
||||
|
||||
.global vec_ds
|
||||
|
@ -218,26 +221,26 @@ vec_ds:
|
|||
# Dis-NEXT: addis
|
||||
# Dis-NEXT: addi
|
||||
# Dis-NEXT: nop
|
||||
# Dis-NEXT: lxsd 3, 32656(2)
|
||||
# Dis-NEXT: lxsd 3, -32720(2)
|
||||
# Dis-NEXT: nop
|
||||
# Dis-NEXT: stxsd 3, 32672(2)
|
||||
# Dis-NEXT: stxsd 3, -32704(2)
|
||||
# Dis-NEXT: nop
|
||||
# Dis-NEXT: lxssp 3, 32656(2)
|
||||
# Dis-NEXT: lxssp 3, -32720(2)
|
||||
# Dis-NEXT: nop
|
||||
# Dis-NEXT: stxssp 3, 32672(2)
|
||||
# Dis-NEXT: stxssp 3, -32704(2)
|
||||
# Dis-NEXT: blr
|
||||
|
||||
# NoOpt-LABEL: vec_ds:
|
||||
# NoOpt-NEXT: addis
|
||||
# NoOpt-NEXT: addi
|
||||
# NoOpt-NEXT: addis 3, 2, 0
|
||||
# NoOpt-NEXT: lxsd 3, 32656(3)
|
||||
# NoOpt-NEXT: lxsd 3, -32720(3)
|
||||
# NoOpt-NEXT: addis 3, 2, 0
|
||||
# NoOpt-NEXT: stxsd 3, 32672(3)
|
||||
# NoOpt-NEXT: stxsd 3, -32704(3)
|
||||
# NoOpt-NEXT: addis 3, 2, 0
|
||||
# NoOpt-NEXT: lxssp 3, 32656(3)
|
||||
# NoOpt-NEXT: lxssp 3, -32720(3)
|
||||
# NoOpt-NEXT: addis 3, 2, 0
|
||||
# NoOpt-NEXT: stxssp 3, 32672(3)
|
||||
# NoOpt-NEXT: stxssp 3, -32704(3)
|
||||
# NoOpt-NEXT: blr
|
||||
|
||||
|
||||
|
|
|
@ -61,17 +61,16 @@ _start:
|
|||
|
||||
# The .TOC. symbol represents the TOC base address: .got + 0x8000 = 0x10028000,
|
||||
# which is stored in the first entry of .got
|
||||
# NM: 0000000010028000 d .TOC.
|
||||
# NM: 0000000010030000 D global_a
|
||||
# NM: 00000000100281e8 d .TOC.
|
||||
# NM: 00000000100301f0 D global_a
|
||||
# HEX-LE: section '.got':
|
||||
# HEX-LE-NEXT: 0x10020000 00800210 00000000
|
||||
# HEX-LE-NEXT: 0x100201e8 e8810210 00000000
|
||||
# HEX-BE: section '.got':
|
||||
# HEX-BE-NEXT: 0x10020000 00000000 10028000
|
||||
# HEX-BE-NEXT: 0x100201e8 00000000 100281e8
|
||||
|
||||
# r2 stores the TOC base address. To access global_a with r3, it
|
||||
# computes the address with TOC plus an offset.
|
||||
# The offset global_a - .TOC. = 0x10030000 - 0x10028000 = 0x8000
|
||||
# gets materialized as (1 << 16) - 32768.
|
||||
# global_a - .TOC. = 0x100301f0 - 0x100281e8 = (1 << 16) - 32760
|
||||
# CHECK: _start:
|
||||
# CHECK: 10010008: addis 3, 2, 1
|
||||
# CHECK-NEXT: 1001000c: addi 3, 3, -32768
|
||||
# CHECK: 100101d0: addis 3, 2, 1
|
||||
# CHECK-NEXT: 100101d4: addi 3, 3, -32760
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# REQUIRES: ppc
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unkown-linux %p/Inputs/ppc64-toc-relax-shared.s -o %t.o
|
||||
# RUN: ld.lld -shared %t.o -o %t.so
|
||||
# RUN: ld.lld -shared -soname=t.so %t.o -o %t.so
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t1.o
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-toc-relax.s -o %t2.o
|
||||
# RUN: llvm-readobj -r %t1.o | FileCheck --check-prefix=RELOCS %s
|
||||
|
@ -23,20 +23,20 @@
|
|||
# RELOCS-NEXT: 0x14 R_PPC64_TOC16_LO_DS .toc 0x10
|
||||
# RELOCS-NEXT: }
|
||||
|
||||
# SECTIONS: .got PROGBITS 0000000010020090
|
||||
# SECTIONS: .toc PROGBITS 0000000010020090
|
||||
# SECTIONS: .got PROGBITS 00000000100202f8
|
||||
# SECTIONS: .toc PROGBITS 00000000100202f8
|
||||
|
||||
# NM: 0000000010030000 D default
|
||||
# NM: 0000000010030310 D default
|
||||
|
||||
# .LCONST1 is .toc[0].
|
||||
# .LCONST1 - (.got+0x8000) = 0x10020090 - (0x10020090+0x8000) = -32768
|
||||
# .LCONST1 - (.got+0x8000) = 0x10020350 - (0x10020350+0x8000) = -32768
|
||||
# CHECK: nop
|
||||
# CHECK: lwa 3, -32768(2)
|
||||
addis 3, 2, .LCONST1@toc@ha
|
||||
lwa 3, .LCONST1@toc@l(3)
|
||||
|
||||
# .LCONST2 is .toc[1]
|
||||
# .LCONST2 - (.got+0x8000) = 0x10020098 - (0x10020090+0x8000) = -32760
|
||||
# .LCONST2 - (.got+0x8000) = 0x10020358 - (0x10020350+0x8000) = -32760
|
||||
# CHECK: nop
|
||||
# CHECK: ld 4, -32760(2)
|
||||
addis 4, 2, .LCONST2@toc@ha
|
||||
|
@ -45,8 +45,8 @@
|
|||
# .Ldefault is .toc[2]. `default` is not preemptable when producing an executable.
|
||||
# After toc-indirection to toc-relative relaxation, it is loaded using an
|
||||
# offset relative to r2.
|
||||
# CHECK: nop
|
||||
# CHECK: addi 5, 2, 32624
|
||||
# CHECK: addis 5, 2, 1
|
||||
# CHECK: addi 5, 5, -32744
|
||||
# CHECK: lwa 5, 0(5)
|
||||
addis 5, 2, .Ldefault@toc@ha
|
||||
ld 5, .Ldefault@toc@l(5)
|
||||
|
|
|
@ -13,16 +13,16 @@
|
|||
## still perform toc-indirect to toc-relative relaxation because the distance
|
||||
## to the address of the canonical PLT is fixed.
|
||||
|
||||
# SEC: .text PROGBITS 0000000010010000
|
||||
# SEC: .plt NOBITS 0000000010030000
|
||||
# SEC: 0000000010010010 0 FUNC GLOBAL DEFAULT 3 ifunc
|
||||
# SEC: .text PROGBITS 00000000100101e0
|
||||
# SEC: .plt NOBITS 0000000010030200
|
||||
# SEC: 00000000100101f0 0 FUNC GLOBAL DEFAULT 3 ifunc
|
||||
|
||||
## .toc[0] stores the address of the canonical PLT.
|
||||
# HEX: section '.toc':
|
||||
# HEX-NEXT: 0x10020000 10000110 00000000
|
||||
# HEX-NEXT: 0x100201f8 f0010110 00000000
|
||||
|
||||
# REL: .rela.dyn {
|
||||
# REL-NEXT: 0x10030000 R_PPC64_IRELATIVE - 0x10010008
|
||||
# REL-NEXT: 0x10030200 R_PPC64_IRELATIVE - 0x100101e8
|
||||
# REL-NEXT: }
|
||||
|
||||
# DIS: addi 3, 3,
|
||||
|
|
|
@ -17,15 +17,15 @@
|
|||
# SECTIONS: .rodata PROGBITS 00000000100001c8
|
||||
|
||||
# HEX-LE: section '.toc':
|
||||
# HEX-LE-NEXT: 10020008 c8010010 00000000
|
||||
# HEX-LE-NEXT: 10020228 c8010010 00000000
|
||||
|
||||
# HEX-BE: section '.toc':
|
||||
# HEX-BE-NEXT: 10020008 00000000 100001c8
|
||||
# HEX-BE-NEXT: 10020228 00000000 100001c8
|
||||
|
||||
# CHECK-LABEL: _start
|
||||
# CHECK: clrldi 3, 3, 62
|
||||
# CHECK-NEXT: addis 4, 2, -2
|
||||
# CHECK-NEXT: addi 4, 4, -32312
|
||||
# CHECK-NEXT: addis 4, 2, -3
|
||||
# CHECK-NEXT: addi 4, 4, 32680
|
||||
# CHECK-NEXT: sldi 3, 3, 2
|
||||
|
||||
.text
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
# REQUIRES: ppc
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-toc-relax-shared.s -o %t.o
|
||||
# RUN: ld.lld -shared %t.o -o %t.so
|
||||
# RUN: ld.lld -shared -soname=t.so %t.o -o %t.so
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t1.o
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-toc-relax.s -o %t2.o
|
||||
# RUN: llvm-readobj -r %t1.o | FileCheck --check-prefixes=RELOCS-LE,RELOCS %s
|
||||
# RUN: ld.lld %t1.o %t2.o %t.so -o %t
|
||||
# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefixes=COMMON,EXE %s
|
||||
|
||||
# RUN: ld.lld -shared %t1.o %t2.o %t.so -o %t2.so
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t2.so | FileCheck --check-prefixes=COMMON,SHARED %s
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-toc-relax-shared.s -o %t.o
|
||||
# RUN: ld.lld -shared %t.o -o %t.so
|
||||
# RUN: ld.lld -shared -soname=t.so %t.o -o %t.so
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t1.o
|
||||
# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-toc-relax.s -o %t2.o
|
||||
# RUN: llvm-readobj -r %t1.o | FileCheck --check-prefixes=RELOCS-BE,RELOCS %s
|
||||
# RUN: ld.lld %t1.o %t2.o %t.so -o %t
|
||||
# RUN: llvm-nm %t | FileCheck --check-prefix=NM %s
|
||||
# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck --check-prefixes=COMMON,EXE %s
|
||||
|
||||
# RUN: ld.lld -shared %t1.o %t2.o %t.so -o %t2.so
|
||||
|
@ -50,22 +52,22 @@
|
|||
# RELOCS-NEXT: 0x18 R_PPC64_ADDR64 default 0x0
|
||||
# RELOCS-NEXT: }
|
||||
|
||||
# NM-DAG: 0000000010030000 D default
|
||||
# NM-DAG: 0000000010030000 d hidden
|
||||
# NM-DAG: 0000000010040000 d hidden2
|
||||
# NM-DAG: 00000000100303a0 D default
|
||||
# NM-DAG: 00000000100303a0 d hidden
|
||||
# NM-DAG: 00000000100403a0 d hidden2
|
||||
|
||||
# 'hidden' is non-preemptable. It is relaxed.
|
||||
# address(hidden) - (.got+0x8000) = 0x10030000 - (0x100200c0+0x8000) = 32576
|
||||
# COMMON: nop
|
||||
# COMMON: addi 3, 2, 32576
|
||||
# address(hidden) - (.got+0x8000) = 0x100303a0 - (0x10020380+0x8000) = (1<<16) - 32736
|
||||
# COMMON: addis 3, 2, 1
|
||||
# COMMON: addi 3, 3, -32736
|
||||
# COMMON: lwa 3, 0(3)
|
||||
addis 3, 2, .Lhidden@toc@ha
|
||||
ld 3, .Lhidden@toc@l(3)
|
||||
lwa 3, 0(3)
|
||||
|
||||
# address(hidden2) - (.got+0x8000) = 0x10040000 - (0x100200c0+0x8000) = (1<<16)+32576
|
||||
# COMMON: addis 3, 2, 1
|
||||
# COMMON: addi 3, 3, 32576
|
||||
# address(hidden2) - (.got+0x8000) = 0x100403a0 - (0x10020380+0x8000) = (2<<16) - 32736
|
||||
# COMMON: addis 3, 2, 2
|
||||
# COMMON: addi 3, 3, -32736
|
||||
# COMMON: lwa 3, 0(3)
|
||||
addis 3, 2, .Lhidden2@toc@ha
|
||||
ld 3, .Lhidden2@toc@l(3)
|
||||
|
@ -82,9 +84,9 @@
|
|||
lwa 4, 0(4)
|
||||
|
||||
# 'default' has default visibility. It is non-preemptable when producing an executable.
|
||||
# address(default) - (.got+0x8000) = 0x10030000 - (0x100200c0+0x8000) = 32576
|
||||
# EXE: nop
|
||||
# EXE: addi 5, 2, 32576
|
||||
# address(default) - (.got+0x8000) = 0x100303a0 - (0x10020380+0x8000) = (1<<16) - 32736
|
||||
# EXE: addis 5, 2, 1
|
||||
# EXE: addi 5, 5, -32736
|
||||
# EXE: lwa 5, 0(5)
|
||||
|
||||
# SHARED: nop
|
||||
|
|
|
@ -14,11 +14,11 @@
|
|||
# for recursive calls as well as keeps the logic for recursive calls consistent
|
||||
# with non-recursive calls.
|
||||
|
||||
# CHECK-LABEL: 0000000000010000 recursive_func:
|
||||
# CHECK: 10028: bl .+32
|
||||
# CHECK-LABEL: 0000000000010290 recursive_func:
|
||||
# CHECK: 102b8: bl .+32
|
||||
# CHECK-NEXT: ld 2, 24(1)
|
||||
|
||||
# CHECK-LABEL: 0000000000010048 __plt_recursive_func:
|
||||
# CHECK-LABEL: 00000000000102d8 __plt_recursive_func:
|
||||
|
||||
.abiversion 2
|
||||
.section ".text"
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %p/Inputs/ppc64-func.s -o %t3.o
|
||||
// RUN: ld.lld -shared %t2.o -o %t2.so
|
||||
// RUN: ld.lld -shared -soname=t2.so %t2.o -o %t2.so
|
||||
// RUN: ld.lld %t.o %t2.so %t3.o -o %t
|
||||
// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-func.s -o %t3.o
|
||||
// RUN: ld.lld -shared %t2.o -o %t2.so
|
||||
// RUN: ld.lld -shared -soname=t2.so %t2.o -o %t2.so
|
||||
// RUN: ld.lld %t.o %t2.so %t3.o -o %t
|
||||
// RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s
|
||||
|
||||
|
@ -29,9 +29,9 @@ _start:
|
|||
nop
|
||||
bl bar_local
|
||||
// CHECK-LABEL: _start:
|
||||
// CHECK-NEXT: 10010008: bl .+64
|
||||
// CHECK-NEXT: 1001000c: ld 2, 24(1)
|
||||
// CHECK-NEXT: 10010010: bl .-16
|
||||
// CHECK-NEXT: 100102c8: bl .+64
|
||||
// CHECK-NEXT: 100102cc: ld 2, 24(1)
|
||||
// CHECK-NEXT: 100102d0: bl .-16
|
||||
// CHECK-EMPTY:
|
||||
|
||||
# Calling a function in another object file which will have same
|
||||
|
@ -43,16 +43,16 @@ _diff_object:
|
|||
bl foo_not_shared
|
||||
nop
|
||||
// CHECK-LABEL: _diff_object:
|
||||
// CHECK-NEXT: 10010014: bl .+28
|
||||
// CHECK-NEXT: 10010018: bl .+24
|
||||
// CHECK-NEXT: 1001001c: nop
|
||||
// CHECK-NEXT: 100102d4: bl .+28
|
||||
// CHECK-NEXT: 100102d8: bl .+24
|
||||
// CHECK-NEXT: 100102dc: nop
|
||||
|
||||
# Branching to a local function does not need a nop
|
||||
.global noretbranch
|
||||
noretbranch:
|
||||
b bar_local
|
||||
// CHECK-LABEL: noretbranch:
|
||||
// CHECK: 10010020: b .+67108832
|
||||
// CHECK: 100102e0: b .+67108832
|
||||
// CHECK-EMPTY:
|
||||
|
||||
// This should come last to check the end-of-buffer condition.
|
||||
|
@ -61,5 +61,5 @@ last:
|
|||
bl foo
|
||||
nop
|
||||
// CHECK-LABEL: last:
|
||||
// CHECK-NEXT: 10010024: bl .+36
|
||||
// CHECK-NEXT: 10010028: ld 2, 24(1)
|
||||
// CHECK-NEXT: 100102e4: bl .+36
|
||||
// CHECK-NEXT: 100102e8: ld 2, 24(1)
|
||||
|
|
|
@ -24,6 +24,6 @@ _start:
|
|||
# be unreachable. But, we should link successfully. We should not, however,
|
||||
# generate a .plt entry (this would be wasted space). For now, we do nothing
|
||||
# (leaving the zero relative offset present in the input).
|
||||
# CHECK: 10010000: bl .+0
|
||||
# CHECK: 10010004: nop
|
||||
# CHECK: 10010008: blr
|
||||
# CHECK: 10010158: bl .+0
|
||||
# CHECK: 1001015c: nop
|
||||
# CHECK: 10010160: blr
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// REQUIRES: x86
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t.o
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/copy-in-shared.s -o %t2.o
|
||||
// RUN: ld.lld -shared %t.o %t2.o -o %t.so
|
||||
// RUN: ld.lld -shared -soname=t.so %t.o %t2.o -z separate-code -o %t.so
|
||||
|
||||
// A linker script that will map .bss.rel.ro into .bss.
|
||||
// RUN: echo "SECTIONS { \
|
||||
|
@ -9,8 +9,8 @@
|
|||
// RUN: } " > %t.script
|
||||
|
||||
// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t3.o
|
||||
// RUN: ld.lld %t3.o %t.so -z relro -o %t --script=%t.script 2>&1
|
||||
// RUN: llvm-readobj --program-headers %t | FileCheck %s
|
||||
// RUN: ld.lld %t3.o %t.so -z relro -z separate-code -o %t --script=%t.script 2>&1
|
||||
// RUN: llvm-readelf -l %t | FileCheck %s
|
||||
.section .text, "ax", @progbits
|
||||
.global bar
|
||||
.global foo
|
||||
|
@ -27,14 +27,5 @@ _start:
|
|||
// as relro.
|
||||
.space 0x2000
|
||||
|
||||
// CHECK: Type: PT_GNU_RELRO (0x6474E552)
|
||||
// CHECK-NEXT: Offset:
|
||||
// CHECK-NEXT: VirtualAddress:
|
||||
// CHECK-NEXT: PhysicalAddress:
|
||||
// CHECK-NEXT: FileSize:
|
||||
// CHECK-NEXT: MemSize: 4096
|
||||
// CHECK-NEXT: Flags [ (0x4)
|
||||
// CHECK-NEXT: PF_R (0x4)
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: Alignment: 1
|
||||
// CHECK-NEXT: }
|
||||
// CHECK: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
|
||||
// CHECK: GNU_RELRO 0x002150 0x0000000000000150 0x0000000000000150 0x000100 0x000eb0 R 0x1
|
||||
|
|
Loading…
Reference in New Issue