<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Sep 30, 2014 at 2:29 PM, Tim Northover <span dir="ltr"><<a href="mailto:tnorthover@apple.com" target="_blank">tnorthover@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: tnorthover<br>
Date: Tue Sep 30 16:29:54 2014<br>
New Revision: 218703<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=218703&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=218703&view=rev</a><br>
Log:<br>
[mach-o] create __unwind_info section on x86_64<br>
<br>
This is a minimally useful pass to construct the __unwind_info section in a<br>
final object from the various __compact_unwind inputs. Currently it doesn't<br>
produce any compressed pages, only works for x86_64 and will fail if any<br>
function ends up without __compact_unwind.<br>
<br>
rdar://problem/18208653<br>
<br>
Added:<br>
lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp<br>
lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml<br>
Modified:<br>
lld/trunk/include/lld/Core/DefinedAtom.h<br>
lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h<br>
lld/trunk/lib/Core/DefinedAtom.cpp<br>
lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h<br>
lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp<br>
lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp<br>
lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp<br>
lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp<br>
lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt<br>
lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp<br>
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp<br>
lld/trunk/lib/ReaderWriter/MachO/MachOPasses.h<br>
lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp<br>
lld/trunk/test/mach-o/exe-offsets.yaml<br>
lld/trunk/test/mach-o/exe-segment-overlap.yaml<br>
<br>
Modified: lld/trunk/include/lld/Core/DefinedAtom.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/DefinedAtom.h?rev=218703&r1=218702&r2=218703&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/DefinedAtom.h?rev=218703&r1=218702&r2=218703&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/include/lld/Core/DefinedAtom.h (original)<br>
+++ lld/trunk/include/lld/Core/DefinedAtom.h Tue Sep 30 16:29:54 2014<br>
@@ -137,6 +137,7 @@ public:<br>
typeDTraceDOF, // runtime data for Dtrace [Darwin]<br>
typeTempLTO, // temporary atom for bitcode reader<br>
typeCompactUnwindInfo, // runtime data for unwinder [Darwin]<br>
+ typeProcessedUnwindInfo,// compressed compact unwind info [Darwin]<br>
typeThunkTLV, // thunk used to access a TLV [Darwin]<br>
typeTLVInitialData, // initial data for a TLV [Darwin]<br>
typeTLVInitialZeroFill, // TLV initial zero fill data [Darwin]<br>
<br>
Modified: lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=218703&r1=218702&r2=218703&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=218703&r1=218702&r2=218703&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h (original)<br>
+++ lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h Tue Sep 30 16:29:54 2014<br>
@@ -214,6 +214,9 @@ public:<br>
// GOT creation Pass should be run.<br>
bool needsGOTPass() const;<br>
<br>
+ /// Pass to transform __compact_unwind into __unwind_info should be run.<br>
+ bool needsCompactUnwindPass() const;<br>
+<br>
/// Magic symbol name stubs will need to help lazy bind.<br>
StringRef binderSymbolName() const;<br>
<br>
<br>
Modified: lld/trunk/lib/Core/DefinedAtom.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/DefinedAtom.cpp?rev=218703&r1=218702&r2=218703&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Core/DefinedAtom.cpp?rev=218703&r1=218702&r2=218703&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/Core/DefinedAtom.cpp (original)<br>
+++ lld/trunk/lib/Core/DefinedAtom.cpp Tue Sep 30 16:29:54 2014<br>
@@ -41,6 +41,7 @@ DefinedAtom::ContentPermissions DefinedA<br>
case typeLiteral16:<br>
case typeDTraceDOF:<br>
case typeCompactUnwindInfo:<br>
+ case typeProcessedUnwindInfo:<br>
case typeRONote:<br>
case typeNoAlloc:<br>
return permR__;<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h?rev=218703&r1=218702&r2=218703&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h?rev=218703&r1=218702&r2=218703&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler.h Tue Sep 30 16:29:54 2014<br>
@@ -53,6 +53,20 @@ public:<br>
/// Used by GOTPass to update GOT References<br>
virtual void updateReferenceToGOT(const Reference *, bool targetIsNowGOT) {}<br>
<br>
+ /// Does this architecture make use of __unwind_info sections for exception<br>
+ /// handling? If so, it will need a separate pass to create them.<br>
+ virtual bool needsCompactUnwind() = 0;<br>
+<br>
+ /// Returns the kind of reference to use to synthesize a 32-bit image-offset<br>
+ /// value, used in the __unwind_info section.<br>
+ virtual Reference::KindValue imageOffsetKind() = 0;<br>
+<br>
+ /// Returns the kind of reference to use to synthesize a 32-bit image-offset<br>
+ /// indirect value. Used for personality functions in the __unwind_info<br>
+ /// section.<br>
+ virtual Reference::KindValue imageOffsetKindIndirect() = 0;<br>
+<br>
+<br>
/// Used by normalizedFromAtoms() to know where to generated rebasing and<br>
/// binding info in final executables.<br>
virtual bool isPointer(const Reference &) = 0;<br>
@@ -126,6 +140,7 @@ public:<br>
/// Copy raw content then apply all fixup References on an Atom.<br>
virtual void generateAtomContent(const DefinedAtom &atom, bool relocatable,<br>
FindAddressForAtom findAddress,<br>
+ uint64_t imageBaseAddress,<br>
uint8_t *atomContentBuffer) = 0;<br>
<br>
/// Used in -r mode to convert a Reference to a mach-o relocation.<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp?rev=218703&r1=218702&r2=218703&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp?rev=218703&r1=218702&r2=218703&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm.cpp Tue Sep 30 16:29:54 2014<br>
@@ -36,6 +36,17 @@ public:<br>
bool isCallSite(const Reference &) override;<br>
bool isPointer(const Reference &) override;<br>
bool isPairedReloc(const normalized::Relocation &) override;<br>
+<br>
+ bool needsCompactUnwind() override {<br>
+ return false;<br>
+ }<br>
+ Reference::KindValue imageOffsetKind() override {<br>
+ return invalid;<br>
+ }<br>
+ Reference::KindValue imageOffsetKindIndirect() override {<br>
+ return invalid;<br>
+ }<br>
+<br>
std::error_code getReferenceInfo(const normalized::Relocation &reloc,<br>
const DefinedAtom *inAtom,<br>
uint32_t offsetInAtom,<br>
@@ -59,6 +70,7 @@ public:<br>
<br>
void generateAtomContent(const DefinedAtom &atom, bool relocatable,<br>
FindAddressForAtom findAddress,<br>
+ uint64_t imageBaseAddress,<br>
uint8_t *atomContentBuffer) override;<br>
<br>
void appendSectionRelocations(const DefinedAtom &atom,<br>
@@ -904,9 +916,10 @@ void ArchHandler_arm::applyFixupFinal(co<br>
}<br>
<br>
void ArchHandler_arm::generateAtomContent(const DefinedAtom &atom,<br>
- bool relocatable,<br>
- FindAddressForAtom findAddress,<br>
- uint8_t *atomContentBuffer) {<br>
+ bool relocatable,<br>
+ FindAddressForAtom findAddress,<br>
+ uint64_t imageBaseAddress,<br>
+ uint8_t *atomContentBuffer) {<br>
// Copy raw bytes.<br>
memcpy(atomContentBuffer, atom.rawContent().data(), atom.size());<br>
// Apply fix-ups.<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp?rev=218703&r1=218702&r2=218703&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp?rev=218703&r1=218702&r2=218703&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp Tue Sep 30 16:29:54 2014<br>
@@ -76,6 +76,17 @@ public:<br>
bool isCallSite(const Reference &) override;<br>
bool isPointer(const Reference &) override;<br>
bool isPairedReloc(const normalized::Relocation &) override;<br>
+<br>
+ bool needsCompactUnwind() override {<br>
+ return false;<br>
+ }<br>
+ Reference::KindValue imageOffsetKind() override {<br>
+ return invalid;<br>
+ }<br>
+ Reference::KindValue imageOffsetKindIndirect() override {<br>
+ return invalid;<br>
+ }<br>
+<br>
std::error_code getReferenceInfo(const normalized::Relocation &reloc,<br>
const DefinedAtom *inAtom,<br>
uint32_t offsetInAtom,<br>
@@ -103,6 +114,7 @@ public:<br>
<br>
void generateAtomContent(const DefinedAtom &atom, bool relocatable,<br>
FindAddressForAtom findAddress,<br>
+ uint64_t imageBaseAddress,<br>
uint8_t *atomContentBuffer) override;<br>
<br>
void appendSectionRelocations(const DefinedAtom &atom,<br>
@@ -440,6 +452,7 @@ std::error_code ArchHandler_arm64::getPa<br>
void ArchHandler_arm64::generateAtomContent(const DefinedAtom &atom,<br>
bool relocatable,<br>
FindAddressForAtom findAddress,<br>
+ uint64_t imageBaseAddress,<br>
uint8_t *atomContentBuffer) {<br>
// Copy raw bytes.<br>
memcpy(atomContentBuffer, atom.rawContent().data(), atom.size());<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp?rev=218703&r1=218702&r2=218703&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp?rev=218703&r1=218702&r2=218703&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86.cpp Tue Sep 30 16:29:54 2014<br>
@@ -36,6 +36,17 @@ public:<br>
bool isCallSite(const Reference &) override;<br>
bool isPointer(const Reference &) override;<br>
bool isPairedReloc(const normalized::Relocation &) override;<br>
+<br>
+ bool needsCompactUnwind() override {<br>
+ return false;<br>
+ }<br>
+ Reference::KindValue imageOffsetKind() override {<br>
+ return invalid;<br>
+ }<br>
+ Reference::KindValue imageOffsetKindIndirect() override {<br>
+ return invalid;<br>
+ }<br>
+<br>
std::error_code getReferenceInfo(const normalized::Relocation &reloc,<br>
const DefinedAtom *inAtom,<br>
uint32_t offsetInAtom,<br>
@@ -59,6 +70,7 @@ public:<br>
<br>
void generateAtomContent(const DefinedAtom &atom, bool relocatable,<br>
FindAddressForAtom findAddress,<br>
+ uint64_t imageBaseAddress,<br>
uint8_t *atomContentBuffer) override;<br>
<br>
void appendSectionRelocations(const DefinedAtom &atom,<br>
@@ -364,9 +376,10 @@ ArchHandler_x86::getPairReferenceInfo(co<br>
}<br>
<br>
void ArchHandler_x86::generateAtomContent(const DefinedAtom &atom,<br>
- bool relocatable,<br>
- FindAddressForAtom findAddress,<br>
- uint8_t *atomContentBuffer) {<br>
+ bool relocatable,<br>
+ FindAddressForAtom findAddress,<br>
+ uint64_t imageBaseAddress,<br>
+ uint8_t *atomContentBuffer) {<br>
// Copy raw bytes.<br>
memcpy(atomContentBuffer, atom.rawContent().data(), atom.size());<br>
// Apply fix-ups.<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp?rev=218703&r1=218702&r2=218703&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp?rev=218703&r1=218702&r2=218703&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp Tue Sep 30 16:29:54 2014<br>
@@ -46,6 +46,9 @@ public:<br>
case ripRel32Got:<br>
canBypassGOT = false;<br>
return true;<br>
+ case imageOffsetGot:<br>
+ canBypassGOT = false;<br>
+ return true;<br>
default:<br>
return false;<br>
}<br>
@@ -55,8 +58,30 @@ public:<br>
void updateReferenceToGOT(const Reference *ref, bool targetNowGOT) override {<br>
assert(ref->kindNamespace() == Reference::KindNamespace::mach_o);<br>
assert(ref->kindArch() == Reference::KindArch::x86_64);<br>
- const_cast<Reference *>(ref)<br>
+<br>
+ switch (ref->kindValue()) {<br>
+ case ripRel32Got:<br>
+ assert(targetNowGOT && "target must be GOT");<br>
+ case ripRel32GotLoad:<br>
+ const_cast<Reference *>(ref)<br>
->setKindValue(targetNowGOT ? ripRel32 : ripRel32GotLoadNowLea);<br>
+ break;<br>
+ case imageOffsetGot:<br>
+ const_cast<Reference *>(ref)->setKindValue(imageOffset);<br>
+ break;<br>
+ default:<br>
+ llvm_unreachable("unknown GOT reference kind");<br>
+ }<br>
+ }<br>
+<br>
+ bool needsCompactUnwind() override {<br>
+ return true;<br>
+ }<br>
+ Reference::KindValue imageOffsetKind() override {<br>
+ return imageOffset;<br>
+ }<br>
+ Reference::KindValue imageOffsetKindIndirect() override {<br>
+ return imageOffsetGot;<br>
}<br>
<br>
const StubInfo &stubInfo() override { return _sStubInfo; }<br>
@@ -64,6 +89,7 @@ public:<br>
bool isCallSite(const Reference &) override;<br>
bool isPointer(const Reference &) override;<br>
bool isPairedReloc(const normalized::Relocation &) override;<br>
+<br>
std::error_code getReferenceInfo(const normalized::Relocation &reloc,<br>
const DefinedAtom *inAtom,<br>
uint32_t offsetInAtom,<br>
@@ -91,6 +117,7 @@ public:<br>
<br>
void generateAtomContent(const DefinedAtom &atom, bool relocatable,<br>
FindAddressForAtom findAddress,<br>
+ uint64_t imageBase,<br>
uint8_t *atomContentBuffer) override;<br>
<br>
void appendSectionRelocations(const DefinedAtom &atom,<br>
@@ -130,6 +157,11 @@ private:<br>
/// to "leaq _foo(%rip), %rax<br>
lazyPointer, /// Location contains a lazy pointer.<br>
lazyImmediateLocation, /// Location contains immediate value used in stub.<br>
+<br>
+ imageOffset, /// Location contains offset of atom in final image<br>
+ imageOffsetGot, /// Location contains offset of GOT entry for atom in<br>
+ /// final image (typically personality function).<br>
+<br>
};<br>
<br>
Reference::KindValue kindFromReloc(const normalized::Relocation &reloc);<br>
@@ -138,7 +170,7 @@ private:<br>
<br>
void applyFixupFinal(const Reference &ref, uint8_t *location,<br>
uint64_t fixupAddress, uint64_t targetAddress,<br>
- uint64_t inAtomAddress);<br>
+ uint64_t inAtomAddress, uint64_t imageBaseAddress);<br>
<br>
void applyFixupRelocatable(const Reference &ref, uint8_t *location,<br>
uint64_t fixupAddress,<br>
@@ -165,6 +197,7 @@ const Registry::KindStrings ArchHandler_<br>
LLD_KIND_STRING_ENTRY(pointer64), LLD_KIND_STRING_ENTRY(pointer64Anon),<br>
LLD_KIND_STRING_ENTRY(delta32), LLD_KIND_STRING_ENTRY(delta64),<br>
LLD_KIND_STRING_ENTRY(delta32Anon), LLD_KIND_STRING_ENTRY(delta64Anon),<br>
+ LLD_KIND_STRING_ENTRY(imageOffset), LLD_KIND_STRING_ENTRY(imageOffsetGot),<br>
LLD_KIND_STRING_END<br>
};<br>
<br>
@@ -382,6 +415,7 @@ ArchHandler_x86_64::getPairReferenceInfo<br>
void ArchHandler_x86_64::generateAtomContent(const DefinedAtom &atom,<br>
bool relocatable,<br>
FindAddressForAtom findAddress,<br>
+ uint64_t imageBaseAddress,<br>
uint8_t *atomContentBuffer) {<br>
// Copy raw bytes.<br>
memcpy(atomContentBuffer, atom.rawContent().data(), atom.size());<br>
@@ -400,8 +434,8 @@ void ArchHandler_x86_64::generateAtomCon<br>
atomAddress);<br>
} else {<br>
applyFixupFinal(*ref, &atomContentBuffer[offset],<br>
- fixupAddress, targetAddress,<br>
- atomAddress);<br>
+ fixupAddress, targetAddress,<br>
+ atomAddress, imageBaseAddress);<br>
}<br>
}<br>
}<br>
@@ -410,7 +444,8 @@ void ArchHandler_x86_64::applyFixupFinal<br>
uint8_t *location,<br>
uint64_t fixupAddress,<br>
uint64_t targetAddress,<br>
- uint64_t inAtomAddress) {<br>
+ uint64_t inAtomAddress,<br>
+ uint64_t imageBaseAddress) {<br>
if (ref.kindNamespace() != Reference::KindNamespace::mach_o)<br>
return;<br>
assert(ref.kindArch() == Reference::KindArch::x86_64);<br>
@@ -455,6 +490,10 @@ void ArchHandler_x86_64::applyFixupFinal<br>
case lazyImmediateLocation:<br>
// do nothing<br>
return;<br>
+ case imageOffset:<br>
+ case imageOffsetGot:<br>
+ write32(*loc32, _swap, (targetAddress - imageBaseAddress) + ref.addend());<br>
+ return;<br>
case invalid:<br>
// Fall into llvm_unreachable().<br>
break;<br>
@@ -514,6 +553,10 @@ void ArchHandler_x86_64::applyFixupReloc<br>
case lazyImmediateLocation:<br>
llvm_unreachable("lazy reference kind implies Stubs pass was run");<br>
return;<br>
+ case imageOffset:<br>
+ case imageOffsetGot:<br>
+ llvm_unreachable("image offset implies __unwind_info");<br>
+ return;<br>
case invalid:<br>
// Fall into llvm_unreachable().<br>
break;<br>
@@ -605,6 +648,10 @@ void ArchHandler_x86_64::appendSectionRe<br>
case lazyImmediateLocation:<br>
llvm_unreachable("lazy reference kind implies Stubs pass was run");<br>
return;<br>
+ case imageOffset:<br>
+ case imageOffsetGot:<br>
+ llvm_unreachable("__unwind_info references should have been resolved");<br>
+ return;<br>
case invalid:<br>
// Fall into llvm_unreachable().<br>
break;<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt?rev=218703&r1=218702&r2=218703&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt?rev=218703&r1=218702&r2=218703&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt Tue Sep 30 16:29:54 2014<br>
@@ -4,6 +4,7 @@ add_lld_library(lldMachO<br>
ArchHandler_arm64.cpp<br>
ArchHandler_x86.cpp<br>
ArchHandler_x86_64.cpp<br>
+ CompactUnwindPass.cpp<br>
GOTPass.cpp<br>
MachOLinkingContext.cpp<br>
MachONormalizedFileBinaryReader.cpp<br>
<br>
Added: lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp?rev=218703&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp?rev=218703&view=auto</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp (added)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/CompactUnwindPass.cpp Tue Sep 30 16:29:54 2014<br>
@@ -0,0 +1,456 @@<br>
+//===- lib/ReaderWriter/MachO/CompactUnwindPass.cpp -----------------------===//<br>
+//<br>
+// The LLVM Linker<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+///<br>
+/// \file<br>
+///<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "ArchHandler.h"<br>
+#include "File.h"<br>
+#include "MachOPasses.h"<br>
+#include "MachONormalizedFileBinaryUtils.h"<br>
+<br>
+#include "lld/Core/DefinedAtom.h"<br>
+#include "lld/Core/File.h"<br>
+#include "lld/Core/LLVM.h"<br>
+#include "lld/Core/Reference.h"<br>
+#include "lld/Core/Simple.h"<br>
+<br>
+#include "llvm/ADT/DenseMap.h"<br>
+#include "llvm/Support/Debug.h"<br>
+#include "llvm/Support/Endian.h"<br>
+#include "llvm/Support/Format.h"<br>
+<br>
+#define DEBUG_TYPE "macho-compact-unwind"<br>
+<br>
+namespace lld {<br>
+namespace mach_o {<br>
+<br>
+namespace {<br>
+struct CompactUnwindEntry {<br>
+ const Atom *rangeStart;<br>
+ const Atom *personalityFunction;<br>
+ const Atom *lsdaLocation;<br>
+<br>
+ uint32_t rangeLength;<br>
+ uint32_t encoding;<br>
+};<br>
+<br>
+struct UnwindInfoPage {<br>
+ std::vector<CompactUnwindEntry> entries;<br>
+};<br>
+}<br>
+<br>
+class UnwindInfoAtom : public SimpleDefinedAtom {<br>
+public:<br>
+ UnwindInfoAtom(ArchHandler &archHandler, const File &file, bool swap,<br>
+ std::vector<uint32_t> commonEncodings,<br>
+ std::vector<const Atom *> personalities,<br>
+ std::vector<UnwindInfoPage> pages, uint32_t numLSDAs)<br>
+ : SimpleDefinedAtom(file), _archHandler(archHandler),<br>
+ _commonEncodingsOffset(7 * sizeof(uint32_t)),<br>
+ _personalityArrayOffset(_commonEncodingsOffset +<br>
+ commonEncodings.size() * sizeof(uint32_t)),<br>
+ _topLevelIndexOffset(_personalityArrayOffset +<br>
+ personalities.size() * sizeof(uint32_t)),<br>
+ _lsdaIndexOffset(_topLevelIndexOffset +<br>
+ 3 * (pages.size() + 1) * sizeof(uint32_t)),<br>
+ _firstPageOffset(_lsdaIndexOffset + 2 * numLSDAs * sizeof(uint32_t)),<br>
+ _swap(swap) {<br>
+<br>
+ addHeader(commonEncodings.size(), personalities.size(), pages.size());<br>
+ addCommonEncodings(commonEncodings);<br>
+ addPersonalityFunctions(personalities);<br>
+ addTopLevelIndexes(pages);<br>
+ addLSDAIndexes(pages, numLSDAs);<br>
+ addSecondLevelPages(pages);<br>
+ }<br>
+<br>
+ ContentType contentType() const override {<br>
+ return DefinedAtom::typeProcessedUnwindInfo;<br>
+ }<br>
+<br>
+ Alignment alignment() const override { return Alignment(2); }<br>
+<br>
+ uint64_t size() const override { return _contents.size(); }<br>
+<br>
+ ContentPermissions permissions() const override {<br>
+ return DefinedAtom::permR__;<br>
+ }<br>
+<br>
+ ArrayRef<uint8_t> rawContent() const override { return _contents; }<br>
+<br>
+ void addHeader(uint32_t numCommon, uint32_t numPersonalities,<br>
+ uint32_t numPages) {<br>
+ using normalized::write32;<br>
+<br>
+ uint32_t headerSize = 7 * sizeof(uint32_t);<br>
+ _contents.resize(headerSize);<br>
+<br>
+ int32_t *headerEntries = (int32_t *)_contents.data();<br>
+ // version<br>
+ write32(headerEntries[0], _swap, 1);<br>
+ // commonEncodingsArraySectionOffset<br>
+ write32(headerEntries[1], _swap, _commonEncodingsOffset);<br>
+ // commonEncodingsArrayCount<br>
+ write32(headerEntries[2], _swap, numCommon);<br>
+ // personalityArraySectionOffset<br>
+ write32(headerEntries[3], _swap, _personalityArrayOffset);<br>
+ // personalityArrayCount<br>
+ write32(headerEntries[4], _swap, numPersonalities);<br>
+ // indexSectionOffset<br>
+ write32(headerEntries[5], _swap, _topLevelIndexOffset);<br>
+ // indexCount<br>
+ write32(headerEntries[6], _swap, numPages + 1);<br>
+ }<br>
+<br>
+ /// Add the list of common encodings to the section; this is simply an array<br>
+ /// of uint32_t compact values. Size has already been specified in the header.<br>
+ void addCommonEncodings(std::vector<uint32_t> &commonEncodings) {<br>
+ using normalized::write32;<br>
+<br>
+ _contents.resize(_commonEncodingsOffset +<br>
+ commonEncodings.size() * sizeof(uint32_t));<br>
+ int32_t *commonEncodingsArea =<br>
+ (int32_t *)&_contents[_commonEncodingsOffset];<br></blockquote><div><br></div><div>It doesn't seem to be guaranteed that _commonEncodingsOffset is a valid index. If I add</div><div><br></div><div> <span style="color:rgb(0,0,0)">assert(_commonEncodingsOffset < _contents.size());</span></div><div><br></div><div>many tests start failing.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
+<br>
+ for (uint32_t encoding : commonEncodings)<br>
+ write32(*commonEncodingsArea++, _swap, encoding);<br>
+ }<br>
+<br>
+ void addPersonalityFunctions(std::vector<const Atom *> personalities) {<br>
+ _contents.resize(_personalityArrayOffset +<br>
+ personalities.size() * sizeof(uint32_t));<br>
+<br>
+ for (unsigned i = 0; i < personalities.size(); ++i)<br>
+ addImageReferenceIndirect(_personalityArrayOffset + i * sizeof(uint32_t),<br>
+ personalities[i]);<br>
+ }<br>
+<br>
+ void addTopLevelIndexes(std::vector<UnwindInfoPage> &pages) {<br>
+ using normalized::write32;<br>
+<br>
+ uint32_t numIndexes = pages.size() + 1;<br>
+ _contents.resize(_topLevelIndexOffset + numIndexes * 3 * sizeof(uint32_t));<br>
+<br>
+ uint32_t pageLoc = _firstPageOffset;<br>
+<br>
+ // The most difficult job here is calculating the LSDAs; everything else<br>
+ // follows fairly naturally, but we can't state where the first<br>
+ int32_t *indexData = (int32_t *)&_contents[_topLevelIndexOffset];<br>
+ uint32_t numLSDAs = 0;<br>
+ for (unsigned i = 0; i < pages.size(); ++i) {<br>
+ // functionOffset<br>
+ addImageReference(_topLevelIndexOffset + 3 * i * sizeof(uint32_t),<br>
+ pages[i].entries[0].rangeStart);<br>
+ // secondLevelPagesSectionOffset<br>
+ write32(indexData[3 * i + 1], _swap, pageLoc);<br>
+ write32(indexData[3 * i + 2], _swap,<br>
+ _lsdaIndexOffset + numLSDAs * 2 * sizeof(uint32_t));<br>
+<br>
+ for (auto &entry : pages[i].entries)<br>
+ if (entry.lsdaLocation)<br>
+ ++numLSDAs;<br>
+ }<br>
+<br>
+ // Finally, write out the final sentinel index<br>
+ CompactUnwindEntry &finalEntry = pages[pages.size() - 1].entries.back();<br>
+ addImageReference(_topLevelIndexOffset +<br>
+ 3 * pages.size() * sizeof(uint32_t),<br>
+ finalEntry.rangeStart, finalEntry.rangeLength);<br>
+ // secondLevelPagesSectionOffset => 0<br>
+ indexData[3 * pages.size() + 2] =<br>
+ _lsdaIndexOffset + numLSDAs * 2 * sizeof(uint32_t);<br>
+ }<br>
+<br>
+ void addLSDAIndexes(std::vector<UnwindInfoPage> &pages, uint32_t numLSDAs) {<br>
+ _contents.resize(_lsdaIndexOffset + numLSDAs * 2 * sizeof(uint32_t));<br>
+<br>
+ uint32_t curOffset = _lsdaIndexOffset;<br>
+ for (auto &page : pages) {<br>
+ for (auto &entry : page.entries) {<br>
+ if (!entry.lsdaLocation)<br>
+ continue;<br>
+<br>
+ addImageReference(curOffset, entry.rangeStart);<br>
+ addImageReference(curOffset + sizeof(uint32_t), entry.lsdaLocation);<br>
+ curOffset += 2 * sizeof(uint32_t);<br>
+ }<br>
+ }<br>
+ }<br>
+<br>
+ void addSecondLevelPages(std::vector<UnwindInfoPage> &pages) {<br>
+ for (auto &page : pages) {<br>
+ addRegularSecondLevelPage(page);<br>
+ }<br>
+ }<br>
+<br>
+ void addRegularSecondLevelPage(const UnwindInfoPage &page) {<br>
+ uint32_t curPageOffset = _contents.size();<br>
+ const int16_t headerSize = sizeof(uint32_t) + 2 * sizeof(uint16_t);<br>
+ uint32_t curPageSize =<br>
+ headerSize + 2 * page.entries.size() * sizeof(uint32_t);<br>
+ _contents.resize(curPageOffset + curPageSize);<br>
+<br>
+ using normalized::write32;<br>
+ using normalized::write16;<br>
+ // 2 => regular page<br>
+ write32(*(int32_t *)&_contents[curPageOffset], _swap, 2);<br>
+ // offset of 1st entry<br>
+ write16(*(int16_t *)&_contents[curPageOffset + 4], _swap, headerSize);<br>
+ write16(*(int16_t *)&_contents[curPageOffset + 6], _swap,<br>
+ page.entries.size());<br>
+<br>
+ uint32_t pagePos = curPageOffset + headerSize;<br>
+ for (auto &entry : page.entries) {<br>
+ addImageReference(pagePos, entry.rangeStart);<br>
+ write32(reinterpret_cast<int32_t *>(_contents.data() + pagePos)[1], _swap,<br>
+ entry.encoding);<br>
+ pagePos += 2 * sizeof(uint32_t);<br>
+ }<br>
+ }<br>
+<br>
+ void addImageReference(uint32_t offset, const Atom *dest,<br>
+ Reference::Addend addend = 0) {<br>
+ addReference(Reference::KindNamespace::mach_o, _archHandler.kindArch(),<br>
+ _archHandler.imageOffsetKind(), offset, dest, addend);<br>
+ }<br>
+<br>
+ void addImageReferenceIndirect(uint32_t offset, const Atom *dest) {<br>
+ addReference(Reference::KindNamespace::mach_o, _archHandler.kindArch(),<br>
+ _archHandler.imageOffsetKindIndirect(), offset, dest, 0);<br>
+ }<br>
+<br>
+private:<br>
+ mach_o::ArchHandler &_archHandler;<br>
+ std::vector<uint8_t> _contents;<br>
+ uint32_t _commonEncodingsOffset;<br>
+ uint32_t _personalityArrayOffset;<br>
+ uint32_t _topLevelIndexOffset;<br>
+ uint32_t _lsdaIndexOffset;<br>
+ uint32_t _firstPageOffset;<br>
+ bool _swap;<br>
+};<br>
+<br>
+/// Pass for instantiating and optimizing GOT slots.<br>
+///<br>
+class CompactUnwindPass : public Pass {<br>
+public:<br>
+ CompactUnwindPass(const MachOLinkingContext &context)<br>
+ : _context(context), _archHandler(_context.archHandler()),<br>
+ _file("<mach-o Compact Unwind Pass>"),<br>
+ _swap(!MachOLinkingContext::isHostEndian(_context.arch())) {}<br>
+<br>
+private:<br>
+ void perform(std::unique_ptr<MutableFile> &mergedFile) override {<br>
+ DEBUG(llvm::dbgs() << "MachO Compact Unwind pass\n");<br>
+<br>
+ // First collect all __compact_unwind entries, addressable by the function<br>
+ // it's referring to.<br>
+ std::map<const Atom *, CompactUnwindEntry> unwindLocs;<br>
+ std::vector<const Atom *> personalities;<br>
+ uint32_t numLSDAs = 0;<br>
+<br>
+ collectCompactUnwindEntries(mergedFile, unwindLocs, personalities,<br>
+ numLSDAs);<br>
+<br>
+ // FIXME: if there are more than 4 personality functions then we need to<br>
+ // defer to DWARF info for the ones we don't put in the list. They should<br>
+ // also probably be sorted by frequency.<br>
+ assert(personalities.size() <= 4);<br>
+<br>
+ // Now sort the entries by final address and fixup the compact encoding to<br>
+ // its final form (i.e. set personality function bits & create DWARF<br>
+ // references where needed).<br>
+ std::vector<CompactUnwindEntry> unwindInfos =<br>
+ createUnwindInfoEntries(mergedFile, unwindLocs, personalities);<br>
+<br>
+ // Finally, we can start creating pages based on these entries.<br>
+<br>
+ DEBUG(llvm::dbgs() << " Splitting entries into pages\n");<br>
+ // FIXME: we split the entries into pages naively: lots of 4k pages followed<br>
+ // by a small one. ld64 tried to minimize space and align them to real 4k<br>
+ // boundaries. That might be worth doing, or perhaps we could perform some<br>
+ // minor balancing for expected number of lookups.<br>
+ std::vector<UnwindInfoPage> pages;<br>
+ unsigned pageStart = 0;<br>
+ do {<br>
+ pages.push_back(UnwindInfoPage());<br>
+<br>
+ // FIXME: we only create regular pages at the moment. These can hold up to<br>
+ // 1021 entries according to the documentation.<br>
+ unsigned entriesInPage =<br>
+ std::min(1021U, (unsigned)unwindInfos.size() - pageStart);<br>
+<br>
+ std::copy(unwindInfos.begin() + pageStart,<br>
+ unwindInfos.begin() + pageStart + entriesInPage,<br>
+ std::back_inserter(pages.back().entries));<br>
+ pageStart += entriesInPage;<br>
+<br>
+ DEBUG(llvm::dbgs()<br>
+ << " Page from " << pages.back().entries[0].rangeStart->name()<br>
+ << " to " << pages.back().entries.back().rangeStart->name() << " + "<br>
+ << llvm::format("0x%x", pages.back().entries.back().rangeLength)<br>
+ << " has " << entriesInPage << " entries\n");<br>
+ } while (pageStart < unwindInfos.size());<br>
+<br>
+ // FIXME: we should also erase all compact-unwind atoms; their job is done.<br>
+ UnwindInfoAtom *unwind = new (_file.allocator())<br>
+ UnwindInfoAtom(_archHandler, _file, _swap, std::vector<uint32_t>(),<br>
+ personalities, pages, numLSDAs);<br>
+ mergedFile->addAtom(*unwind);<br>
+ }<br>
+<br>
+ void collectCompactUnwindEntries(<br>
+ std::unique_ptr<MutableFile> &mergedFile,<br>
+ std::map<const Atom *, CompactUnwindEntry> &unwindLocs,<br>
+ std::vector<const Atom *> &personalities, uint32_t &numLSDAs) {<br>
+ DEBUG(llvm::dbgs() << " Collecting __compact_unwind entries\n");<br>
+<br>
+ for (const DefinedAtom *atom : mergedFile->defined()) {<br>
+ if (atom->contentType() != DefinedAtom::typeCompactUnwindInfo)<br>
+ continue;<br>
+<br>
+ auto unwindEntry = extractCompactUnwindEntry(atom);<br>
+ unwindLocs.insert(std::make_pair(unwindEntry.rangeStart, unwindEntry));<br>
+<br>
+ DEBUG(llvm::dbgs() << " Entry for " << unwindEntry.rangeStart->name()<br>
+ << ", encoding="<br>
+ << llvm::format("0x%08x", unwindEntry.encoding));<br>
+ if (unwindEntry.personalityFunction)<br>
+ DEBUG(llvm::dbgs() << ", personality="<br>
+ << unwindEntry.personalityFunction->name()<br>
+ << ", lsdaLoc=" << unwindEntry.lsdaLocation->name());<br>
+ DEBUG(llvm::dbgs() << '\n');<br>
+<br>
+ // Count number of LSDAs we see, since we need to know how big the index<br>
+ // will be while laying out the section.<br>
+ if (unwindEntry.lsdaLocation)<br>
+ ++numLSDAs;<br>
+<br>
+ // Gather the personality functions now, so that they're in deterministic<br>
+ // order (derived from the DefinedAtom order).<br>
+ if (unwindEntry.personalityFunction) {<br>
+ auto pFunc = std::find(personalities.begin(), personalities.end(),<br>
+ unwindEntry.personalityFunction);<br>
+ if (pFunc == personalities.end())<br>
+ personalities.push_back(unwindEntry.personalityFunction);<br>
+ }<br>
+ }<br>
+ }<br>
+<br>
+ CompactUnwindEntry extractCompactUnwindEntry(const DefinedAtom *atom) {<br>
+ CompactUnwindEntry entry = {nullptr, nullptr, nullptr, 0, 0};<br>
+<br>
+ for (const Reference *ref : *atom) {<br>
+ switch (ref->offsetInAtom()) {<br>
+ case 0:<br>
+ // FIXME: there could legitimately be functions with multiple encoding<br>
+ // entries. However, nothing produces them at the moment.<br>
+ assert(ref->addend() == 0 && "unexpected offset into function");<br>
+ entry.rangeStart = ref->target();<br>
+ break;<br>
+ case 0x10:<br>
+ assert(ref->addend() == 0 && "unexpected offset into personality fn");<br>
+ entry.personalityFunction = ref->target();<br>
+ break;<br>
+ case 0x18:<br>
+ assert(ref->addend() == 0 && "unexpected offset into LSDA atom");<br>
+ entry.lsdaLocation = ref->target();<br>
+ break;<br>
+ }<br>
+ }<br>
+<br>
+ using normalized::read32;<br>
+ entry.rangeLength =<br>
+ read32(_swap, ((uint32_t *)atom->rawContent().data())[2]);<br>
+ entry.encoding = read32(_swap, ((uint32_t *)atom->rawContent().data())[3]);<br>
+ return entry;<br>
+ }<br>
+<br>
+ /// Every atom defined in __TEXT,__text needs an entry in the final<br>
+ /// __unwind_info section (in order). These comes from two sources:<br>
+ /// + Input __compact_unwind sections where possible (after adding the<br>
+ /// personality function offset which is only known now).<br>
+ /// + A synthesised reference to __eh_frame if there's no __compact_unwind<br>
+ /// or too many personality functions to be accommodated.<br>
+ std::vector<CompactUnwindEntry> createUnwindInfoEntries(<br>
+ const std::unique_ptr<MutableFile> &mergedFile,<br>
+ const std::map<const Atom *, CompactUnwindEntry> &unwindLocs,<br>
+ const std::vector<const Atom *> &personalities) {<br>
+ std::vector<CompactUnwindEntry> unwindInfos;<br>
+<br>
+ DEBUG(llvm::dbgs() << " Creating __unwind_info entries\n");<br>
+ // The final order in the __unwind_info section must be derived from the<br>
+ // order of typeCode atoms, since that's how they'll be put into the object<br>
+ // file eventually (yuck!).<br>
+ for (const DefinedAtom *atom : mergedFile->defined()) {<br>
+ if (atom->contentType() != DefinedAtom::typeCode)<br>
+ continue;<br>
+<br>
+ unwindInfos.push_back(<br>
+ finalizeUnwindInfoEntryForAtom(atom, unwindLocs, personalities));<br>
+<br>
+ DEBUG(llvm::dbgs() << " Entry for " << atom->name()<br>
+ << ", final encoding="<br>
+ << llvm::format("0x%08x", unwindInfos.back().encoding)<br>
+ << '\n');<br>
+ }<br>
+<br>
+ return unwindInfos;<br>
+ }<br>
+<br>
+ CompactUnwindEntry finalizeUnwindInfoEntryForAtom(<br>
+ const DefinedAtom *function,<br>
+ const std::map<const Atom *, CompactUnwindEntry> &unwindLocs,<br>
+ const std::vector<const Atom *> &personalities) {<br>
+ auto unwindLoc = unwindLocs.find(function);<br>
+<br>
+ // FIXME: we should synthesize a DWARF compact unwind entry before claiming<br>
+ // there's no unwind if a __compact_unwind atom doesn't exist.<br>
+ if (unwindLoc == unwindLocs.end()) {<br>
+ CompactUnwindEntry entry;<br>
+ memset(&entry, 0, sizeof(CompactUnwindEntry));<br>
+ entry.rangeStart = function;<br>
+ entry.rangeLength = function->size();<br>
+ return entry;<br>
+ }<br>
+<br>
+ CompactUnwindEntry entry = unwindLoc->second;<br>
+ auto personality = std::find(personalities.begin(), personalities.end(),<br>
+ entry.personalityFunction);<br>
+ uint32_t personalityIdx = personality == personalities.end()<br>
+ ? 0<br>
+ : personality - personalities.begin() + 1;<br>
+<br>
+ // FIXME: We should also use DWARF when there isn't enough room for the<br>
+ // personality function in the compact encoding.<br>
+ assert(personalityIdx < 4 && "too many personality functions");<br>
+<br>
+ entry.encoding |= personalityIdx << 28;<br>
+<br>
+ if (entry.lsdaLocation)<br>
+ entry.encoding |= 1U << 30;<br>
+<br>
+ return entry;<br>
+ }<br>
+<br>
+ const MachOLinkingContext &_context;<br>
+ mach_o::ArchHandler &_archHandler;<br>
+ MachOFile _file;<br>
+ bool _swap;<br>
+};<br>
+<br>
+void addCompactUnwindPass(PassManager &pm, const MachOLinkingContext &ctx) {<br>
+ assert(ctx.needsCompactUnwindPass());<br>
+ pm.add(std::unique_ptr<Pass>(new CompactUnwindPass(ctx)));<br>
+}<br>
+<br>
+} // end namesapce mach_o<br>
+} // end namesapce lld<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=218703&r1=218702&r2=218703&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=218703&r1=218702&r2=218703&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Tue Sep 30 16:29:54 2014<br>
@@ -281,6 +281,16 @@ bool MachOLinkingContext::needsGOTPass()<br>
}<br>
}<br>
<br>
+bool MachOLinkingContext::needsCompactUnwindPass() const {<br>
+ switch (_outputMachOType) {<br>
+ case MH_EXECUTE:<br>
+ case MH_DYLIB:<br>
+ case MH_BUNDLE:<br>
+ return archHandler().needsCompactUnwind();<br>
+ default:<br>
+ return false;<br>
+ }<br>
+}<br>
<br>
StringRef MachOLinkingContext::binderSymbolName() const {<br>
return archHandler().stubInfo().binderSymbolName;<br>
@@ -511,6 +521,8 @@ void MachOLinkingContext::addPasses(Pass<br>
pm.add(std::unique_ptr<Pass>(new LayoutPass(registry())));<br>
if (needsStubsPass())<br>
mach_o::addStubsPass(pm, *this);<br>
+ if (needsCompactUnwindPass())<br>
+ mach_o::addCompactUnwindPass(pm, *this);<br>
if (needsGOTPass())<br>
mach_o::addGOTPass(pm, *this);<br>
}<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=218703&r1=218702&r2=218703&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=218703&r1=218702&r2=218703&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Tue Sep 30 16:29:54 2014<br>
@@ -220,6 +220,7 @@ const MachOFinalSectionFromAtomType sect<br>
ENTRY("__TEXT", "__stub_helper", S_REGULAR, typeStubHelper),<br>
ENTRY("__TEXT", "__gcc_except_tab", S_REGULAR, typeLSDA),<br>
ENTRY("__TEXT", "__eh_frame", S_COALESCED, typeCFI),<br>
+ ENTRY("__TEXT", "__unwind_info", S_REGULAR, typeProcessedUnwindInfo),<br>
ENTRY("__DATA", "__data", S_REGULAR, typeData),<br>
ENTRY("__DATA", "__const", S_REGULAR, typeConstData),<br>
ENTRY("__DATA", "__cfstring", S_REGULAR, typeCFString),<br>
@@ -565,7 +566,8 @@ void Util::copySectionContent(Normalized<br>
for (AtomInfo &ai : si->atomsAndOffsets) {<br>
uint8_t *atomContent = reinterpret_cast<uint8_t*><br>
(§ionContent[ai.offsetInSection]);<br>
- _archHandler.generateAtomContent(*ai.atom, r, addrForAtom, atomContent);<br>
+ _archHandler.generateAtomContent(*ai.atom, r, addrForAtom,<br>
+ _context.baseAddress(), atomContent);<br>
}<br>
}<br>
}<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/MachO/MachOPasses.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOPasses.h?rev=218703&r1=218702&r2=218703&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOPasses.h?rev=218703&r1=218702&r2=218703&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/MachO/MachOPasses.h (original)<br>
+++ lld/trunk/lib/ReaderWriter/MachO/MachOPasses.h Tue Sep 30 16:29:54 2014<br>
@@ -18,6 +18,7 @@ namespace mach_o {<br>
<br>
void addStubsPass(PassManager &pm, const MachOLinkingContext &ctx);<br>
void addGOTPass(PassManager &pm, const MachOLinkingContext &ctx);<br>
+void addCompactUnwindPass(PassManager &pm, const MachOLinkingContext &ctx);<br>
<br>
} // namespace mach_o<br>
} // namespace lld<br>
<br>
Modified: lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp?rev=218703&r1=218702&r2=218703&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp?rev=218703&r1=218702&r2=218703&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp (original)<br>
+++ lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp Tue Sep 30 16:29:54 2014<br>
@@ -439,6 +439,7 @@ template <> struct ScalarEnumerationTrai<br>
io.enumCase(value, "dtraceDOF", DefinedAtom::typeDTraceDOF);<br>
io.enumCase(value, "lto-temp", DefinedAtom::typeTempLTO);<br>
io.enumCase(value, "compact-unwind", DefinedAtom::typeCompactUnwindInfo);<br>
+ io.enumCase(value, "unwind-info", DefinedAtom::typeProcessedUnwindInfo);<br>
io.enumCase(value, "tlv-thunk", DefinedAtom::typeThunkTLV);<br>
io.enumCase(value, "tlv-data", DefinedAtom::typeTLVInitialData);<br>
io.enumCase(value, "tlv-zero-fill", DefinedAtom::typeTLVInitialZeroFill);<br>
<br>
Modified: lld/trunk/test/mach-o/exe-offsets.yaml<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/exe-offsets.yaml?rev=218703&r1=218702&r2=218703&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/exe-offsets.yaml?rev=218703&r1=218702&r2=218703&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/test/mach-o/exe-offsets.yaml (original)<br>
+++ lld/trunk/test/mach-o/exe-offsets.yaml Tue Sep 30 16:29:54 2014<br>
@@ -54,6 +54,9 @@ global-symbols:<br>
# CHECK: Offset: 0<br>
<br>
# CHECK-LABEL: Section {<br>
+# CHECK: Name: __unwind_info<br>
+<br>
+# CHECK-LABEL: Section {<br>
# CHECK: Name: __data<br>
# CHECK: Segment: __DATA<br>
# CHECK: Size: 0x5<br>
<br>
Modified: lld/trunk/test/mach-o/exe-segment-overlap.yaml<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/exe-segment-overlap.yaml?rev=218703&r1=218702&r2=218703&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/exe-segment-overlap.yaml?rev=218703&r1=218702&r2=218703&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/test/mach-o/exe-segment-overlap.yaml (original)<br>
+++ lld/trunk/test/mach-o/exe-segment-overlap.yaml Tue Sep 30 16:29:54 2014<br>
@@ -43,7 +43,10 @@ global-symbols:<br>
# CHECK: Name: __text<br>
# CHECK: Segment: __TEXT<br>
# CHECK: Size: 0x1<br>
-# CHECK: Offset: 4095<br>
+# CHECK: Offset: 4027<br>
+<br>
+# CHECK-LABEL: Section {<br>
+# CHECK: Name: __unwind_info<br>
<br>
# CHECK-LABEL: Section {<br>
# CHECK: Name: __data<br>
<br>
Added: lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml?rev=218703&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml?rev=218703&view=auto</a><br>
==============================================================================<br>
--- lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml (added)<br>
+++ lld/trunk/test/mach-o/unwind-info-simple-x86_64.yaml Tue Sep 30 16:29:54 2014<br>
@@ -0,0 +1,71 @@<br>
+# RUN: lld -flavor darwin -arch x86_64 %s -o %t -e _main %p/Inputs/libSystem.yaml<br>
+# RUN: llvm-objdump -unwind-info %t | FileCheck %s<br>
+<br>
+# CHECK: Contents of __unwind_info section:<br>
+# CHECK: Version: 0x1<br>
+# CHECK: Common encodings array section offset: 0x1c<br>
+# CHECK: Number of common encodings in array: 0x0<br>
+# CHECK: Personality function array section offset: 0x1c<br>
+# CHECK: Number of personality functions in array: 0x1<br>
+# CHECK: Index array section offset: 0x20<br>
+# CHECK: Number of indices in array: 0x2<br>
+# CHECK: Common encodings: (count = 0)<br>
+# CHECK: Personality functions: (count = 1)<br>
+# CHECK: personality[1]: 0x00001000<br>
+# CHECK: Top level indices: (count = 2)<br>
+# CHECK: [0]: function offset=0x00000f7e, 2nd level page offset=0x00000040, LSDA offset=0x00000038<br>
+# CHECK: [1]: function offset=0x00000f80, 2nd level page offset=0x00000000, LSDA offset=0x00000040<br>
+# CHECK: LSDA descriptors:<br>
+# CHECK: [0]: function offset=0x00000f7e, LSDA offset=0x00000f80<br>
+# CHECK: Second level indices:<br>
+# CHECK: Second level index[0]: offset in section=0x00000040, base function offset=0x00000f7e<br>
+# CHECK: [0]: function offset=0x00000f7e, encoding=0x51000000<br>
+# CHECK: [1]: function offset=0x00000f7f, encoding=0x01000000<br>
+<br>
+--- !native<br>
+path: '<linker-internal>'<br>
+defined-atoms:<br>
+ - name: GCC_except_table1<br>
+ type: unwind-lsda<br>
+ content: [ FF, 9B, A2, 80, 80, 00, 03, 1A, 08, 00, 00, 00,<br>
+ 05, 00, 00, 00, 1A, 00, 00, 00, 01, 0D, 00, 00,<br>
+ 00, 64, 00, 00, 00, 00, 00, 00, 00, 00, 01, 00,<br>
+ 04, 00, 00, 00 ]<br>
+ - type: compact-unwind<br>
+ content: [ 40, 00, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00,<br>
+ 00, 00, 00, 41, 00, 00, 00, 00, 00, 00, 00, 00,<br>
+ E0, 00, 00, 00, 00, 00, 00, 00 ]<br>
+ references:<br>
+ - kind: pointer64Anon<br>
+ offset: 0<br>
+ target: __Z3barv<br>
+ - kind: pointer64<br>
+ offset: 16<br>
+ target: ___gxx_personality_v0<br>
+ - kind: pointer64Anon<br>
+ offset: 24<br>
+ target: GCC_except_table1<br>
+ - type: compact-unwind<br>
+ content: [ C0, 00, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00,<br>
+ 00, 00, 00, 01, 00, 00, 00, 00, 00, 00, 00, 00,<br>
+ 00, 00, 00, 00, 00, 00, 00, 00 ]<br>
+ references:<br>
+ - kind: pointer64Anon<br>
+ offset: 0<br>
+ target: _main<br>
+<br>
+ - name: __Z3barv<br>
+ scope: global<br>
+ content: [ C3 ]<br>
+ - name: _main<br>
+ scope: global<br>
+ content: [ C3 ]<br>
+ references:<br>
+ - kind: branch32<br>
+ offset: 9<br>
+ target: __Z3barv<br>
+<br>
+shared-library-atoms:<br>
+ - name: ___gxx_personality_v0<br>
+ load-name: '/usr/lib/libc++abi.dylib'<br>
+ type: unknown<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>