diff --git a/lld/MachO/Symbols.h b/lld/MachO/Symbols.h --- a/lld/MachO/Symbols.h +++ b/lld/MachO/Symbols.h @@ -11,6 +11,7 @@ #include "InputSection.h" #include "Target.h" +#include "lld/Common/ErrorHandler.h" #include "lld/Common/Strings.h" #include "llvm/Object/Archive.h" @@ -44,6 +45,8 @@ uint64_t getVA() const; + uint64_t getFileOffset() const; + protected: Symbol(Kind k, StringRefZ name) : symbolKind(k), name(name) {} @@ -102,6 +105,12 @@ return 0; } +inline uint64_t Symbol::getFileOffset() const { + if (auto *d = dyn_cast(this)) + return d->isec->getFileOffset() + d->value; + llvm_unreachable("attempt to get an offset from an undefined symbol"); +} + union SymbolUnion { alignas(Defined) char a[sizeof(Defined)]; alignas(Undefined) char b[sizeof(Undefined)]; diff --git a/lld/MachO/Symbols.cpp b/lld/MachO/Symbols.cpp --- a/lld/MachO/Symbols.cpp +++ b/lld/MachO/Symbols.cpp @@ -8,8 +8,6 @@ #include "Symbols.h" #include "InputFiles.h" -#include "lld/Common/ErrorHandler.h" -#include "lld/Common/Strings.h" using namespace llvm; using namespace lld; diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h --- a/lld/MachO/SyntheticSections.h +++ b/lld/MachO/SyntheticSections.h @@ -9,6 +9,7 @@ #ifndef LLD_MACHO_SYNTHETIC_SECTIONS_H #define LLD_MACHO_SYNTHETIC_SECTIONS_H +#include "Config.h" #include "ExportTrie.h" #include "InputSection.h" #include "OutputSection.h" @@ -66,7 +67,7 @@ public: PageZeroSection(); bool isHidden() const override { return true; } - size_t getSize() const override { return ImageBase; } + size_t getSize() const override { return PageZeroSize; } uint64_t getFileSize() const override { return 0; } void writeTo(uint8_t *buf) const override {} }; diff --git a/lld/MachO/Target.h b/lld/MachO/Target.h --- a/lld/MachO/Target.h +++ b/lld/MachO/Target.h @@ -27,7 +27,7 @@ // deprecating 32-bit apps. WordSize = 8, PageSize = 4096, - ImageBase = 4096, + PageZeroSize = 1ull << 32, // XXX should be 4096 for 32-bit targets MaxAlignmentPowerOf2 = 32, }; diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -168,7 +168,7 @@ auto *c = reinterpret_cast(buf); c->cmd = LC_MAIN; c->cmdsize = getSize(); - c->entryoff = config->entry->getVA() - ImageBase; + c->entryoff = config->entry->getFileOffset(); c->stacksize = 0; } }; diff --git a/lld/test/MachO/entry-symbol.s b/lld/test/MachO/entry-symbol.s --- a/lld/test/MachO/entry-symbol.s +++ b/lld/test/MachO/entry-symbol.s @@ -1,13 +1,28 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-apple-darwin %s -o %t.o -# RUN: lld -flavor darwinnew -o /dev/null %t.o -e _not_main -# RUN: not lld -flavor darwinnew -o /dev/null %t.o -e _missing 2>&1 | FileCheck %s -# RUN: not lld -flavor darwinnew -o /dev/null %t.o 2>&1 | FileCheck %s --check-prefix=DEFAULT-ENTRY +# RUN: lld -flavor darwinnew -o %t %t.o -e _not_main +# RUN: llvm-objdump --macho --all-headers --syms %t | FileCheck %s +# CHECK-LABEL: SYMBOL TABLE +# CHECK-NEXT: {{0*}}[[#%x, ENTRY_ADDR:]] {{.*}} __TEXT,__text _not_main +# CHECK: cmd LC_MAIN +# CHECK-NEXT: cmdsize 24 +# CHECK-NEXT: entryoff [[#ENTRYOFF:]] +# CHECK: sectname __text +# CHECK-NEXT: segname __TEXT +## Note: the following checks assume that the entry symbol is right at the +## beginning of __text. +# CHECK-NEXT: addr 0x{{0*}}[[#ENTRY_ADDR]] +# CHECK-NEXT: size +# CHECK-NEXT: offset [[#ENTRYOFF]] + -# CHECK: error: undefined symbol: _missing +# RUN: not lld -flavor darwinnew -o /dev/null %t.o -e _missing 2>&1 | FileCheck %s --check-prefix=UNDEFINED +# UNDEFINED: error: undefined symbol: _missing +# RUN: not lld -flavor darwinnew -o /dev/null %t.o 2>&1 | FileCheck %s --check-prefix=DEFAULT-ENTRY # DEFAULT-ENTRY: error: undefined symbol: _main .text .global _not_main _not_main: - ret + movq $0, %rax + retq diff --git a/lld/test/MachO/segments.s b/lld/test/MachO/segments.s --- a/lld/test/MachO/segments.s +++ b/lld/test/MachO/segments.s @@ -9,8 +9,8 @@ # CHECK: Cmd: LC_SEGMENT_64 # CHECK: Name: __PAGEZERO # CHECK: Size: 72 -# CHECK: vmaddr: -# CHECK: vmsize: +# CHECK: vmaddr: 0x0 +# CHECK: vmsize: 0x100000000 # CHECK: fileoff: 0 # CHECK: filesize: 0 ## The kernel won't execute a binary with the wrong protections for __PAGEZERO. @@ -23,7 +23,7 @@ # CHECK: Cmd: LC_SEGMENT_64 # CHECK: Name: __TEXT # CHECK: Size: 152 -# CHECK: vmaddr: +# CHECK: vmaddr: 0x100000000 # CHECK: vmsize: ## dyld3 assumes that the __TEXT segment starts from the file header # CHECK: fileoff: 0 diff --git a/lld/test/MachO/x86-64-reloc-signed.s b/lld/test/MachO/x86-64-reloc-signed.s --- a/lld/test/MachO/x86-64-reloc-signed.s +++ b/lld/test/MachO/x86-64-reloc-signed.s @@ -4,18 +4,18 @@ # RUN: llvm-objdump -D %t | FileCheck %s # CHECK: <_main>: -# CHECK-NEXT: movl {{.*}} # 2000 <_s> +# CHECK-NEXT: movl {{.*}} # 100001000 <_s> # CHECK-NEXT: callq {{.*}} -# CHECK-NEXT: movl {{.*}} # 2002 <_s+0x2> +# CHECK-NEXT: movl {{.*}} # 100001002 <_s+0x2> # CHECK-NEXT: callq {{.*}} -# CHECK-NEXT: movb {{.*}} # 2000 <_s> +# CHECK-NEXT: movb {{.*}} # 100001000 <_s> # CHECK-NEXT: callq {{.*}} # CHECK: <__not_text>: -# CHECK-NEXT: movl {{.*}} # 2005 +# CHECK-NEXT: movl {{.*}} # 100001005 # CHECK-NEXT: callq {{.*}} -# CHECK-NEXT: movl {{.*}} # 2007 +# CHECK-NEXT: movl {{.*}} # 100001007 # CHECK-NEXT: callq {{.*}} -# CHECK-NEXT: movb {{.*}} # 2005 +# CHECK-NEXT: movb {{.*}} # 100001005 # CHECK-NEXT: callq {{.*}} .section __TEXT,__text diff --git a/lld/test/MachO/x86-64-reloc-unsigned.s b/lld/test/MachO/x86-64-reloc-unsigned.s --- a/lld/test/MachO/x86-64-reloc-unsigned.s +++ b/lld/test/MachO/x86-64-reloc-unsigned.s @@ -3,9 +3,9 @@ # RUN: lld -flavor darwinnew -o %t %t.o # RUN: llvm-objdump --full-contents %t | FileCheck %s # CHECK: Contents of section foo: -# CHECK: 2000 08200000 00000000 +# CHECK: 100001000 08100000 01000000 # CHECK: Contents of section bar: -# CHECK: 2008 11311111 01000000 +# CHECK: 100001008 11211111 02000000 .globl _main, _foo, _bar