Summary: So far we've only supported symbol relocations.
Reviewers: ruiu, pcc, MaskRay, smeenai, alexshap, gkm, Ktwu, christylee
Subscribers: llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D79211
for (const section_64 &sec : sections) {
InputSection *isec = make<InputSection>();
isec->file = this;
+ isec->header = &sec;
isec->name = StringRef(sec.sectname, strnlen(sec.sectname, 16));
isec->segname = StringRef(sec.segname, strnlen(sec.segname, 16));
isec->data = {buf + sec.offset, static_cast<size_t>(sec.size)};
r.type = rel.r_type;
r.offset = rel.r_address;
r.addend = target->getImplicitAddend(buf + sec.offset + r.offset, r.type);
- if (rel.r_extern)
+ if (rel.r_extern) {
r.target = symbols[rel.r_symbolnum];
- else {
- error("TODO: Non-extern relocations are not supported");
- continue;
+ } else {
+ if (rel.r_symbolnum == 0 || rel.r_symbolnum > sections.size())
+ fatal("invalid section index in relocation for offset " +
+ std::to_string(r.offset) + " in section " + sec.sectname +
+ " of " + getName());
+ r.target = sections[rel.r_symbolnum - 1];
}
}
relocs.push_back(r);
for (Reloc &r : relocs) {
uint64_t va = 0;
+ uint64_t addend = r.addend;
if (auto *s = r.target.dyn_cast<Symbol *>()) {
if (auto *dylibSymbol = dyn_cast<DylibSymbol>(s)) {
va = target->getDylibSymbolVA(*dylibSymbol, r.type);
}
} else if (auto *isec = r.target.dyn_cast<InputSection *>()) {
va = isec->getVA();
- } else {
- llvm_unreachable("Unknown relocation target");
+ // The implicit addend for pcrel section relocations is the pcrel offset
+ // in terms of the addresses in the input file. Here we adjust it so that
+ // it describes the offset from the start of the target section.
+ // TODO: Figure out what to do for non-pcrel section relocations.
+ // TODO: The offset of 4 is probably not right for ARM64.
+ addend -= isec->header->addr - (header->addr + r.offset + 4);
}
- uint64_t val = va + r.addend;
+ uint64_t val = va + addend;
if (1) // TODO: handle non-pcrel relocations
val -= getVA() + r.offset;
target->relocateOne(buf + r.offset, r.type, val);
InputFile *file = nullptr;
StringRef name;
StringRef segname;
+ // This provides access to the address of the section in the input file.
+ const llvm::MachO::section_64 *header;
OutputSection *parent = nullptr;
uint64_t outSecOff = 0;
# CHECK-LABEL: <_main>:
## Test X86_64_RELOC_BRANCH
# CHECK: callq 0x[[#%x, F_ADDR]] <_f>
-## Test X86_64_RELOC_SIGNED
+## Test extern (symbol) X86_64_RELOC_SIGNED
# CHECK: leaq [[#%u, STR_OFF:]](%rip), %rsi
# CHECK-NEXT: [[#%x, CSTRING_ADDR - STR_OFF]]
+## Test non-extern (section) X86_64_RELOC_SIGNED
+# CHECK: leaq [[#%u, LSTR_OFF:]](%rip), %rsi
+# CHECK-NEXT: [[#%x, CSTRING_ADDR + 22 - LSTR_OFF]]
.section __TEXT,__text
.globl _main, _f
_f:
movl $0x2000004, %eax # write() syscall
mov $1, %rdi # stdout
- leaq str(%rip), %rsi
- mov $13, %rdx # length of str
+ leaq _str(%rip), %rsi
+ mov $21, %rdx # length of str
+ syscall
+
+ movl $0x2000004, %eax # write() syscall
+ mov $1, %rdi # stdout
+ leaq L_.str(%rip), %rsi
+ mov $15, %rdx # length of str
syscall
ret
.section __TEXT,__cstring
-str:
- .asciz "Hello world!\n"
+## References to this generate a symbol relocation
+_str:
+ .asciz "Local defined symbol\n"
+## References to this generate a section relocation
+L_.str:
+ .asciz "Private symbol\n"
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o
# RUN: lld -flavor darwinnew -o %t %t.o
-# RUN: llvm-objdump -d %t | FileCheck %s
+# RUN: llvm-objdump -D %t | FileCheck %s
# CHECK: <_main>:
# CHECK-NEXT: movl {{.*}} # 2000 <_s>
# CHECK-NEXT: callq {{.*}}
# CHECK-NEXT: movb {{.*}} # 2000 <_s>
# CHECK-NEXT: callq {{.*}}
+# CHECK: <__not_text>:
+# CHECK-NEXT: movl {{.*}} # 2005
+# CHECK-NEXT: callq {{.*}}
+# CHECK-NEXT: movl {{.*}} # 2007
+# CHECK-NEXT: callq {{.*}}
+# CHECK-NEXT: movb {{.*}} # 2005
+# CHECK-NEXT: callq {{.*}}
.section __TEXT,__text
.globl _main
_main:
+ ## Symbol relocations
movl $0x434241, _s(%rip) # X86_64_RELOC_SIGNED_4
callq _f
movl $0x44, _s+2(%rip) # X86_64_RELOC_SIGNED_2
syscall
ret
+.section __TEXT,__not_text
+ ## Section relocations. We intentionally put them in a separate section since
+ ## the __text section typically starts at an address of zero in object files,
+ ## and so does not fully exercise the relocation logic.
+ movl $0x434241, L._s(%rip) # X86_64_RELOC_SIGNED_4
+ callq _f
+ movl $0x44, L._s+2(%rip) # X86_64_RELOC_SIGNED_2
+ callq _f
+ movb $0x45, L._s(%rip) # X86_64_RELOC_SIGNED_1
+ callq _f
+ ret
+
.section __DATA,__data
.globl _s
_s:
.space 5
+
+## Create a new section to force the assembler to use a section relocation for
+## the private symbol L._s. Otherwise, it will instead use a nearby non-private
+## symbol to create a symbol relocation plus an addend.
+.section __DATA,__foo
+L._s:
+ .space 5