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