[lld] r258197 - Add an ObjCPass to the MachO linker.
Pete Cooper via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 19 13:54:22 PST 2016
Author: pete
Date: Tue Jan 19 15:54:21 2016
New Revision: 258197
URL: http://llvm.org/viewvc/llvm-project?rev=258197&view=rev
Log:
Add an ObjCPass to the MachO linker.
This pass currently emits an objc image info section if one is required.
This section contains the aggregated version and flags for all of the input
files.
Added:
lld/trunk/lib/ReaderWriter/MachO/ObjCPass.cpp
lld/trunk/test/mach-o/objc-image-info-pass-output.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/CMakeLists.txt
lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
lld/trunk/lib/ReaderWriter/MachO/MachOPasses.h
lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
Modified: lld/trunk/include/lld/Core/DefinedAtom.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/Core/DefinedAtom.h?rev=258197&r1=258196&r2=258197&view=diff
==============================================================================
--- lld/trunk/include/lld/Core/DefinedAtom.h (original)
+++ lld/trunk/include/lld/Core/DefinedAtom.h Tue Jan 19 15:54:21 2016
@@ -134,6 +134,7 @@ public:
typeCStringPtr, // pointer to UTF8 C string [Darwin]
typeObjCClassPtr, // pointer to ObjC class [Darwin]
typeObjC2CategoryList, // pointers to ObjC category [Darwin]
+ typeObjCImageInfo, // pointer to ObjC class [Darwin]
typeDTraceDOF, // runtime data for Dtrace [Darwin]
typeInterposingTuples, // tuples of interposing info for dyld [Darwin]
typeTempLTO, // temporary atom for bitcode reader
Modified: lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h?rev=258197&r1=258196&r2=258197&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/MachOLinkingContext.h Tue Jan 19 15:54:21 2016
@@ -154,7 +154,8 @@ public:
void setBaseAddress(uint64_t baseAddress) { _baseAddress = baseAddress; }
ObjCConstraint objcConstraint() const { return _objcConstraint; }
- void setObjcConstraint(ObjCConstraint v) { _objcConstraint = v; }
+
+ uint32_t swiftVersion() const { return _swiftVersion; }
/// \brief Checks whether a given path on the filesystem exists.
///
@@ -310,6 +311,9 @@ public:
/// Pass to add shims switching between thumb and arm mode.
bool needsShimPass() const;
+ /// Pass to add objc image info and optimized objc data.
+ bool needsObjCPass() 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=258197&r1=258196&r2=258197&view=diff
==============================================================================
--- lld/trunk/lib/Core/DefinedAtom.cpp (original)
+++ lld/trunk/lib/Core/DefinedAtom.cpp Tue Jan 19 15:54:21 2016
@@ -43,6 +43,7 @@ DefinedAtom::ContentPermissions DefinedA
case typeProcessedUnwindInfo:
case typeRONote:
case typeNoAlloc:
+ case typeObjCImageInfo:
return permR__;
case typeData:
Modified: lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt?rev=258197&r1=258196&r2=258197&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt Tue Jan 19 15:54:21 2016
@@ -13,6 +13,7 @@ add_lld_library(lldMachO
MachONormalizedFileFromAtoms.cpp
MachONormalizedFileToAtoms.cpp
MachONormalizedFileYAML.cpp
+ ObjCPass.cpp
ShimPass.cpp
StubsPass.cpp
TLVPass.cpp
Modified: lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp?rev=258197&r1=258196&r2=258197&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachOLinkingContext.cpp Tue Jan 19 15:54:21 2016
@@ -326,6 +326,11 @@ bool MachOLinkingContext::needsCompactUn
}
}
+bool MachOLinkingContext::needsObjCPass() const {
+ // ObjC pass is only needed if any of the inputs were ObjC.
+ return _objcConstraint != objc_unknown;
+}
+
bool MachOLinkingContext::needsShimPass() const {
// Shim pass only used in final executables.
if (_outputMachOType == MH_OBJECT)
@@ -590,6 +595,10 @@ bool MachOLinkingContext::validateImpl(r
}
void MachOLinkingContext::addPasses(PassManager &pm) {
+ // objc pass should be before layout pass. Otherwise test cases may contain
+ // no atoms which confuses the layout pass.
+ if (needsObjCPass())
+ mach_o::addObjCPass(pm, *this);
mach_o::addLayoutPass(pm, *this);
if (needsStubsPass())
mach_o::addStubsPass(pm, *this);
@@ -1060,6 +1069,7 @@ std::error_code MachOLinkingContext::han
// Swift versions are different.
return make_dynamic_error_code("different swift versions");
}
+
return std::error_code();
}
Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp?rev=258197&r1=258196&r2=258197&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp Tue Jan 19 15:54:21 2016
@@ -88,6 +88,7 @@ const MachORelocatableSectionToAtomType
ENTRY("__DATA", "__thread_data", S_THREAD_LOCAL_REGULAR, typeTLVInitialData),
ENTRY("__DATA", "__thread_bss", S_THREAD_LOCAL_ZEROFILL,
typeTLVInitialZeroFill),
+ ENTRY("__DATA", "__objc_imageinfo", S_REGULAR, typeObjCImageInfo),
ENTRY("", "", S_INTERPOSING, typeInterposingTuples),
ENTRY("__LD", "__compact_unwind", S_REGULAR,
typeCompactUnwindInfo),
@@ -867,52 +868,35 @@ std::error_code addEHFrameReferences(con
return ehFrameErr;
}
-std::error_code parseObjCImageInfo(const NormalizedFile &normalizedFile,
+std::error_code parseObjCImageInfo(const Section §,
+ const NormalizedFile &normalizedFile,
MachOFile &file) {
- const Section *imageInfoSection = nullptr;
- for (auto §ion : normalizedFile.sections) {
- if (section.segmentName == "__OBJC" &&
- section.sectionName == "__image_info") {
- imageInfoSection = §ion;
- break;
- }
- if (section.segmentName == "__DATA" &&
- section.sectionName == "__objc_imageinfo") {
- imageInfoSection = §ion;
- break;
- }
- }
-
- // No image info section so nothing to do.
- if (!imageInfoSection)
- return std::error_code();
-
// struct objc_image_info {
// uint32_t version; // initially 0
// uint32_t flags;
// };
- ArrayRef<uint8_t> content = imageInfoSection->content;
+ ArrayRef<uint8_t> content = sect.content;
if (content.size() != 8)
- return make_dynamic_error_code(imageInfoSection->segmentName + "/" +
- imageInfoSection->sectionName +
+ return make_dynamic_error_code(sect.segmentName + "/" +
+ sect.sectionName +
" in file " + file.path() +
" should be 8 bytes in size");
const bool isBig = MachOLinkingContext::isBigEndian(normalizedFile.arch);
uint32_t version = read32(content.data(), isBig);
if (version)
- return make_dynamic_error_code(imageInfoSection->segmentName + "/" +
- imageInfoSection->sectionName +
+ return make_dynamic_error_code(sect.segmentName + "/" +
+ sect.sectionName +
" in file " + file.path() +
" should have version=0");
uint32_t flags = read32(content.data() + 4, isBig);
if (flags & (MachOLinkingContext::objc_supports_gc |
MachOLinkingContext::objc_gc_only))
- return make_dynamic_error_code(imageInfoSection->segmentName + "/" +
- imageInfoSection->sectionName +
+ return make_dynamic_error_code(sect.segmentName + "/" +
+ sect.sectionName +
" in file " + file.path() +
" uses GC. This is not supported");
@@ -951,6 +935,11 @@ dylibToAtoms(const NormalizedFile &norma
namespace normalized {
+static bool isObjCImageInfo(const Section §) {
+ return (sect.segmentName == "__OBJC" && sect.sectionName == "__image_info") ||
+ (sect.segmentName == "__DATA" && sect.sectionName == "__objc_imageinfo");
+}
+
std::error_code
normalizedObjectToAtoms(MachOFile *file,
const NormalizedFile &normalizedFile,
@@ -964,6 +953,18 @@ normalizedObjectToAtoms(MachOFile *file,
DEBUG(llvm::dbgs() << "Creating atoms: "; sect.dump());
if (isDebugInfoSection(sect))
continue;
+
+
+ // If the file contains an objc_image_info struct, then we should parse the
+ // ObjC flags and Swift version.
+ if (isObjCImageInfo(sect)) {
+ if (std::error_code ec = parseObjCImageInfo(sect, normalizedFile, *file))
+ return ec;
+ // We then skip adding atoms for this section as we use the ObjCPass to
+ // re-emit this data after it has been aggregated for all files.
+ continue;
+ }
+
bool customSectionName;
DefinedAtom::ContentType atomType = atomTypeFromSection(sect,
customSectionName);
@@ -1007,11 +1008,6 @@ normalizedObjectToAtoms(MachOFile *file,
if (std::error_code ec = addEHFrameReferences(normalizedFile, *file, *handler))
return ec;
- // If the file contains an objc_image_info struct, then we should parse the
- // ObjC flags and Swift version.
- if (std::error_code ec = parseObjCImageInfo(normalizedFile, *file))
- return ec;
-
// Process mach-o data-in-code regions array. That information is encoded in
// atoms as References at each transition point.
unsigned nextIndex = 0;
Modified: lld/trunk/lib/ReaderWriter/MachO/MachOPasses.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachOPasses.h?rev=258197&r1=258196&r2=258197&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachOPasses.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachOPasses.h Tue Jan 19 15:54:21 2016
@@ -21,6 +21,7 @@ void addStubsPass(PassManager &pm, const
void addGOTPass(PassManager &pm, const MachOLinkingContext &ctx);
void addTLVPass(PassManager &pm, const MachOLinkingContext &ctx);
void addCompactUnwindPass(PassManager &pm, const MachOLinkingContext &ctx);
+void addObjCPass(PassManager &pm, const MachOLinkingContext &ctx);
void addShimPass(PassManager &pm, const MachOLinkingContext &ctx);
} // namespace mach_o
Added: lld/trunk/lib/ReaderWriter/MachO/ObjCPass.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ObjCPass.cpp?rev=258197&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ObjCPass.cpp (added)
+++ lld/trunk/lib/ReaderWriter/MachO/ObjCPass.cpp Tue Jan 19 15:54:21 2016
@@ -0,0 +1,126 @@
+//===- lib/ReaderWriter/MachO/ObjCPass.cpp -------------------------------===//
+//
+// The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//===----------------------------------------------------------------------===//
+
+#include "ArchHandler.h"
+#include "File.h"
+#include "MachOPasses.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 "lld/ReaderWriter/MachOLinkingContext.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
+
+namespace lld {
+namespace mach_o {
+
+//
+// ObjC Image Info Atom created by the ObjC pass.
+//
+class ObjCImageInfoAtom : public SimpleDefinedAtom {
+public:
+ ObjCImageInfoAtom(const File &file,
+ MachOLinkingContext::ObjCConstraint objCConstraint,
+ uint32_t swiftVersion)
+ : SimpleDefinedAtom(file) {
+
+ Data.info.version = 0;
+
+ switch (objCConstraint) {
+ case MachOLinkingContext::objc_unknown:
+ llvm_unreachable("Shouldn't run the objc pass without a constraint");
+ case MachOLinkingContext::objc_supports_gc:
+ case MachOLinkingContext::objc_gc_only:
+ llvm_unreachable("GC is not supported");
+ case MachOLinkingContext::objc_retainReleaseForSimulator:
+ // The retain/release for simulator flag is already the correct
+ // encoded value for the data so just set it here.
+ Data.info.flags = (uint32_t)objCConstraint;
+ break;
+ case MachOLinkingContext::objc_retainRelease:
+ // We don't need to encode this flag, so just leave the flags as 0.
+ Data.info.flags = 0;
+ break;
+ }
+
+ Data.info.flags |= (swiftVersion << 8);
+ }
+
+ ContentType contentType() const override {
+ return DefinedAtom::typeObjCImageInfo;
+ }
+
+ Alignment alignment() const override {
+ return 4;
+ }
+
+ uint64_t size() const override {
+ return 8;
+ }
+
+ ContentPermissions permissions() const override {
+ return DefinedAtom::permR__;
+ }
+
+ ArrayRef<uint8_t> rawContent() const override {
+ return llvm::makeArrayRef(Data.bytes, size());
+ }
+
+private:
+
+ struct objc_image_info {
+ uint32_t version;
+ uint32_t flags;
+ };
+
+ union {
+ objc_image_info info;
+ uint8_t bytes[8];
+ } Data;
+};
+
+class ObjCPass : public Pass {
+public:
+ ObjCPass(const MachOLinkingContext &context)
+ : _ctx(context),
+ _file("<mach-o objc pass>") {
+ _file.setOrdinal(_ctx.getNextOrdinalAndIncrement());
+ }
+
+ std::error_code perform(SimpleFile &mergedFile) override {
+ // Add the image info.
+ mergedFile.addAtom(*getImageInfo());
+
+ return std::error_code();
+ }
+
+private:
+
+ const DefinedAtom* getImageInfo() {
+ return new (_file.allocator()) ObjCImageInfoAtom(_file,
+ _ctx.objcConstraint(),
+ _ctx.swiftVersion());
+ }
+
+ const MachOLinkingContext &_ctx;
+ MachOFile _file;
+};
+
+
+
+void addObjCPass(PassManager &pm, const MachOLinkingContext &ctx) {
+ pm.add(llvm::make_unique<ObjCPass>(ctx));
+}
+
+} // end namespace mach_o
+} // end 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=258197&r1=258196&r2=258197&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp (original)
+++ lld/trunk/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp Tue Jan 19 15:54:21 2016
@@ -418,6 +418,8 @@ template <> struct ScalarEnumerationTrai
DefinedAtom::typeObjCClassPtr);
io.enumCase(value, "objc-category-list",
DefinedAtom::typeObjC2CategoryList);
+ io.enumCase(value, "objc-image-info",
+ DefinedAtom::typeObjCImageInfo);
io.enumCase(value, "objc-class1", DefinedAtom::typeObjC1Class);
io.enumCase(value, "dtraceDOF", DefinedAtom::typeDTraceDOF);
io.enumCase(value, "interposing-tuples",
Added: lld/trunk/test/mach-o/objc-image-info-pass-output.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/objc-image-info-pass-output.yaml?rev=258197&view=auto
==============================================================================
--- lld/trunk/test/mach-o/objc-image-info-pass-output.yaml (added)
+++ lld/trunk/test/mach-o/objc-image-info-pass-output.yaml Tue Jan 19 15:54:21 2016
@@ -0,0 +1,30 @@
+# RUN: lld -flavor darwin -ios_simulator_version_min 5.0 -arch x86_64 -r %s -o %t -print_atoms | FileCheck %s
+
+# Make sure that we have an objc image info in the output. It should have
+# been generated by the objc pass.
+
+--- !mach-o
+arch: x86_64
+file-type: MH_OBJECT
+flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+compat-version: 0.0
+current-version: 0.0
+has-UUID: false
+OS: unknown
+sections:
+ - segment: __DATA
+ section: __objc_imageinfo
+ type: S_REGULAR
+ attributes: [ S_ATTR_NO_DEAD_STRIP ]
+ address: 0x0000000000000100
+ content: [ 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00 ]
+...
+
+# CHECK: --- !native
+# CHECK: path: '<linker-internal>'
+# CHECK: defined-atoms:
+# CHECK: - scope: hidden
+# CHECK: type: objc-image-info
+# CHECK: content: [ 00, 00, 00, 00, 20, 02, 00, 00 ]
+# CHECK: alignment: 4
+# CHECK: ...
\ No newline at end of file
More information about the llvm-commits
mailing list