[lld] ecad968 - Revert "[lld-macho] Warn on method name collisions from category definitions"
Jez Ng via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 8 15:57:56 PST 2023
Author: Jez Ng
Date: 2023-03-08T15:57:24-08:00
New Revision: ecad968f4a517110f978f63d92459f7318e193f5
URL: https://github.com/llvm/llvm-project/commit/ecad968f4a517110f978f63d92459f7318e193f5
DIFF: https://github.com/llvm/llvm-project/commit/ecad968f4a517110f978f63d92459f7318e193f5.diff
LOG: Revert "[lld-macho] Warn on method name collisions from category definitions"
This reverts commit ef122753db7fe8e9a0b7bedd46d2f3668a780fcb.
Apparently it is causing some crashes:
https://reviews.llvm.org/D142916#4178869
Added:
Modified:
lld/MachO/Driver.cpp
lld/MachO/InputFiles.cpp
lld/MachO/InputSection.cpp
lld/MachO/InputSection.h
lld/MachO/ObjC.cpp
lld/MachO/ObjC.h
lld/MachO/Relocations.cpp
lld/MachO/Relocations.h
lld/MachO/UnwindInfoSection.cpp
lld/test/MachO/objc-imageinfo.s
Removed:
lld/MachO/Layout.h
lld/test/MachO/Inputs/MacOSX.sdk/usr/lib/libobjc.tbd
lld/test/MachO/objc-category-conflicts.s
################################################################################
diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp
index 322d7de30b63f..0f2326b305b13 100644
--- a/lld/MachO/Driver.cpp
+++ b/lld/MachO/Driver.cpp
@@ -1920,8 +1920,6 @@ bool macho::link(ArrayRef<const char *> argsArr, llvm::raw_ostream &stdoutOS,
if (config->deadStrip)
markLive();
- objc::checkCategories();
-
// ICF assumes that all literals have been folded already, so we must run
// foldIdenticalLiterals before foldIdenticalSections.
foldIdenticalLiterals();
diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index 65e06a8557d9c..ed0d98a2ececd 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -1272,10 +1272,13 @@ static CIE parseCIE(const InputSection *isec, const EhReader &reader,
}
}
if (personalityAddrOff != 0) {
- const auto *personalityReloc = isec->getRelocAt(personalityAddrOff);
- if (!personalityReloc)
+ auto personalityRelocIt =
+ llvm::find_if(isec->relocs, [=](const macho::Reloc &r) {
+ return r.offset == personalityAddrOff;
+ });
+ if (personalityRelocIt == isec->relocs.end())
reader.failOn(off, "Failed to locate relocation for personality symbol");
- cie.personalitySymbol = personalityReloc->referent.get<macho::Symbol *>();
+ cie.personalitySymbol = personalityRelocIt->referent.get<macho::Symbol *>();
}
return cie;
}
diff --git a/lld/MachO/InputSection.cpp b/lld/MachO/InputSection.cpp
index ff5a15067adcd..1d8d58477139f 100644
--- a/lld/MachO/InputSection.cpp
+++ b/lld/MachO/InputSection.cpp
@@ -135,14 +135,6 @@ std::string InputSection::getSourceLocation(uint64_t off) const {
return {};
}
-const Reloc *InputSection::getRelocAt(uint32_t off) const {
- auto it = llvm::find_if(
- relocs, [=](const macho::Reloc &r) { return r.offset == off; });
- if (it == relocs.end())
- return nullptr;
- return &*it;
-}
-
void ConcatInputSection::foldIdentical(ConcatInputSection *copy) {
align = std::max(align, copy->align);
copy->live = false;
@@ -267,15 +259,6 @@ const StringPiece &CStringInputSection::getStringPiece(uint64_t off) const {
return const_cast<CStringInputSection *>(this)->getStringPiece(off);
}
-size_t CStringInputSection::getStringPieceIndex(uint64_t off) const {
- if (off >= data.size())
- fatal(toString(this) + ": offset is outside the section");
-
- auto it =
- partition_point(pieces, [=](StringPiece p) { return p.inSecOff <= off; });
- return std::distance(pieces.begin(), it) - 1;
-}
-
uint64_t CStringInputSection::getOffset(uint64_t off) const {
const StringPiece &piece = getStringPiece(off);
uint64_t addend = off - piece.inSecOff;
diff --git a/lld/MachO/InputSection.h b/lld/MachO/InputSection.h
index becb01017d633..5a6a205f9047c 100644
--- a/lld/MachO/InputSection.h
+++ b/lld/MachO/InputSection.h
@@ -55,8 +55,6 @@ class InputSection {
// Return the source line corresponding to an address, or the empty string.
// Format: Source.cpp:123 (/path/to/Source.cpp:123)
std::string getSourceLocation(uint64_t off) const;
- // Return the relocation at \p off, if it exists. This does a linear search.
- const Reloc *getRelocAt(uint32_t off) const;
// Whether the data at \p off in this InputSection is live.
virtual bool isLive(uint64_t off) const = 0;
virtual void markLive(uint64_t off) = 0;
@@ -220,10 +218,6 @@ class CStringInputSection final : public InputSection {
return toStringRef(data.slice(begin, end - begin));
}
- StringRef getStringRefAtOffset(uint64_t off) const {
- return getStringRef(getStringPieceIndex(off));
- }
-
// Returns i'th piece as a CachedHashStringRef. This function is very hot when
// string merging is enabled, so we want to inline.
LLVM_ATTRIBUTE_ALWAYS_INLINE
@@ -238,9 +232,6 @@ class CStringInputSection final : public InputSection {
bool deduplicateLiterals = false;
std::vector<StringPiece> pieces;
-
-private:
- size_t getStringPieceIndex(uint64_t off) const;
};
class WordLiteralInputSection final : public InputSection {
diff --git a/lld/MachO/Layout.h b/lld/MachO/Layout.h
deleted file mode 100644
index 6a7653f315e3c..0000000000000
--- a/lld/MachO/Layout.h
+++ /dev/null
@@ -1,74 +0,0 @@
-//===- Layout.h -----------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-// Convenience macros for obtaining offsets of members in structs.
-//
-// Usage:
-//
-// #define FOR_EACH_FOO_FIELD(DO) \
-// DO(Ptr, bar) \
-// DO(uint32_t, baz) \
-// CREATE_LAYOUT_CLASS(Foo, FOR_EACH_FOO_FIELD)
-// #undef FOR_EACH_FOO_FIELD
-//
-// This will generate
-//
-// struct FooLayout {
-// uint32_t barOffset;
-// uint32_t bazOffset;
-// uint32_t totalSize;
-//
-// FooLayout(size_t wordSize) {
-// if (wordSize == 8)
-// init<uint64_t>();
-// else {
-// assert(wordSize == 4);
-// init<uint32_t>();
-// }
-// }
-//
-// private:
-// template <class Ptr> void init() {
-// FOR_EACH_FIELD(_INIT_OFFSET);
-// barOffset = offsetof(Layout<Ptr>, bar);
-// bazOffset = offsetof(Layout<Ptr>, baz);
-// totalSize = sizeof(Layout<Ptr>);
-// }
-// template <class Ptr> struct Layout {
-// Ptr bar;
-// uint32_t baz;
-// };
-// };
-
-#define _OFFSET_FOR_FIELD(_, name) uint32_t name##Offset;
-#define _INIT_OFFSET(type, name) name##Offset = offsetof(Layout<Ptr>, name);
-#define _LAYOUT_ENTRY(type, name) type name;
-
-#define CREATE_LAYOUT_CLASS(className, FOR_EACH_FIELD) \
- struct className##Layout { \
- FOR_EACH_FIELD(_OFFSET_FOR_FIELD) \
- uint32_t totalSize; \
- \
- className##Layout(size_t wordSize) { \
- if (wordSize == 8) \
- init<uint64_t>(); \
- else { \
- assert(wordSize == 4); \
- init<uint32_t>(); \
- } \
- } \
- \
- private: \
- template <class Ptr> void init() { \
- FOR_EACH_FIELD(_INIT_OFFSET); \
- totalSize = sizeof(Layout<Ptr>); \
- } \
- template <class Ptr> struct Layout { \
- FOR_EACH_FIELD(_LAYOUT_ENTRY) \
- }; \
- }
diff --git a/lld/MachO/ObjC.cpp b/lld/MachO/ObjC.cpp
index bdb125859b719..d484c4029f6be 100644
--- a/lld/MachO/ObjC.cpp
+++ b/lld/MachO/ObjC.cpp
@@ -9,12 +9,10 @@
#include "ObjC.h"
#include "InputFiles.h"
#include "InputSection.h"
-#include "Layout.h"
#include "OutputSegment.h"
#include "Target.h"
#include "lld/Common/ErrorHandler.h"
-#include "llvm/ADT/DenseMap.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/Bitcode/BitcodeReader.h"
@@ -68,228 +66,3 @@ bool macho::hasObjCSection(MemoryBufferRef mb) {
return false;
}
}
-
-namespace {
-
-#define FOR_EACH_CATEGORY_FIELD(DO) \
- DO(Ptr, name) \
- DO(Ptr, klass) \
- DO(Ptr, instanceMethods) \
- DO(Ptr, classMethods) \
- DO(Ptr, protocols) \
- DO(Ptr, instanceProps) \
- DO(Ptr, classProps)
-
-CREATE_LAYOUT_CLASS(Category, FOR_EACH_CATEGORY_FIELD);
-
-#undef FOR_EACH_CATEGORY_FIELD
-
-#define FOR_EACH_CLASS_FIELD(DO) \
- DO(Ptr, metaClass) \
- DO(Ptr, superClass) \
- DO(Ptr, methodCache) \
- DO(Ptr, vtable) \
- DO(Ptr, roData)
-
-CREATE_LAYOUT_CLASS(Class, FOR_EACH_CLASS_FIELD);
-
-#undef FOR_EACH_CLASS_FIELD
-
-#define FOR_EACH_RO_CLASS_FIELD(DO) \
- DO(uint32_t, flags) \
- DO(uint32_t, instanceStart) \
- DO(Ptr, instanceSize) \
- DO(Ptr, ivarLayout) \
- DO(Ptr, name) \
- DO(Ptr, baseMethods) \
- DO(Ptr, baseProtocols) \
- DO(Ptr, ivars) \
- DO(Ptr, weakIvarLayout) \
- DO(Ptr, baseProperties)
-
-CREATE_LAYOUT_CLASS(ROClass, FOR_EACH_RO_CLASS_FIELD);
-
-#undef FOR_EACH_RO_CLASS_FIELD
-
-#define FOR_EACH_LIST_HEADER(DO) \
- DO(uint32_t, size) \
- DO(uint32_t, count)
-
-CREATE_LAYOUT_CLASS(ListHeader, FOR_EACH_LIST_HEADER);
-
-#undef FOR_EACH_LIST_HEADER
-
-#define FOR_EACH_METHOD(DO) \
- DO(Ptr, name) \
- DO(Ptr, type) \
- DO(Ptr, impl)
-
-CREATE_LAYOUT_CLASS(Method, FOR_EACH_METHOD);
-
-#undef FOR_EACH_METHOD
-
-enum MethodContainerKind {
- MCK_Class,
- MCK_Category,
-};
-
-struct MethodContainer {
- MethodContainerKind kind;
- const ConcatInputSection *isec;
-};
-
-enum MethodKind {
- MK_Instance,
- MK_Static,
-};
-
-struct ObjcClass {
- DenseMap<CachedHashStringRef, MethodContainer> instanceMethods;
- DenseMap<CachedHashStringRef, MethodContainer> classMethods;
-};
-
-} // namespace
-
-class ObjcCategoryChecker {
-public:
- ObjcCategoryChecker();
- void parseCategory(const ConcatInputSection *catListIsec);
-
-private:
- void parseClass(const Defined *classSym);
- void parseMethods(const ConcatInputSection *methodsIsec,
- const Symbol *methodContainer,
- const ConcatInputSection *containerIsec,
- MethodContainerKind, MethodKind);
-
- CategoryLayout catLayout;
- ClassLayout classLayout;
- ROClassLayout roClassLayout;
- ListHeaderLayout listHeaderLayout;
- MethodLayout methodLayout;
-
- DenseMap<const Symbol *, ObjcClass> classMap;
-};
-
-ObjcCategoryChecker::ObjcCategoryChecker()
- : catLayout(target->wordSize), classLayout(target->wordSize),
- roClassLayout(target->wordSize), listHeaderLayout(target->wordSize),
- methodLayout(target->wordSize) {}
-
-// \p r must point to an offset within a cstring section.
-static StringRef getReferentString(const Reloc &r) {
- if (auto *isec = r.referent.dyn_cast<InputSection *>())
- return cast<CStringInputSection>(isec)->getStringRefAtOffset(r.addend);
- auto *d = cast<Defined>(r.referent.get<Symbol *>());
- return cast<CStringInputSection>(d->isec)->getStringRefAtOffset(d->value + r.addend);
-}
-
-void ObjcCategoryChecker::parseMethods(const ConcatInputSection *methodsIsec,
- const Symbol *methodContainerSym,
- const ConcatInputSection *containerIsec,
- MethodContainerKind mcKind,
- MethodKind mKind) {
- ObjcClass &klass = classMap[methodContainerSym];
- for (const Reloc &r : methodsIsec->relocs) {
- if ((r.offset - listHeaderLayout.totalSize) % methodLayout.totalSize !=
- methodLayout.nameOffset)
- continue;
-
- CachedHashStringRef methodName(getReferentString(r));
- auto &methodMap =
- mKind == MK_Instance ? klass.instanceMethods : klass.classMethods;
- if (methodMap
- .try_emplace(methodName, MethodContainer{mcKind, containerIsec})
- .second)
- continue;
-
- // We have a duplicate; generate a warning message.
- const auto &mc = methodMap.lookup(methodName);
- const Reloc *nameReloc = nullptr;
- if (mc.kind == MCK_Category) {
- nameReloc = mc.isec->getRelocAt(catLayout.nameOffset);
- } else {
- assert(mc.kind == MCK_Class);
- const auto *roIsec = mc.isec->getRelocAt(classLayout.roDataOffset)
- ->getReferentInputSection();
- nameReloc = roIsec->getRelocAt(roClassLayout.nameOffset);
- }
- StringRef containerName = getReferentString(*nameReloc);
- StringRef methPrefix = mKind == MK_Instance ? "-" : "+";
-
- // We should only ever encounter collisions when parsing category methods
- // (since the Class struct is parsed before any of its categories).
- assert(mcKind == MCK_Category);
- StringRef newCatName =
- getReferentString(*containerIsec->getRelocAt(catLayout.nameOffset));
-
- StringRef containerType = mc.kind == MCK_Category ? "category" : "class";
- warn("method '" + methPrefix + methodName.val() +
- "' has conflicting definitions:\n>>> defined in category " +
- newCatName + " from " + toString(containerIsec->getFile()) +
- "\n>>> defined in " + containerType + " " + containerName + " from " +
- toString(mc.isec->getFile()));
- }
-}
-
-void ObjcCategoryChecker::parseCategory(const ConcatInputSection *catIsec) {
- auto *classReloc = catIsec->getRelocAt(catLayout.klassOffset);
- if (!classReloc)
- return;
-
- auto *classSym = classReloc->referent.get<Symbol *>();
- if (auto *d = dyn_cast<Defined>(classSym))
- if (!classMap.count(d))
- parseClass(d);
-
- if (const auto *r = catIsec->getRelocAt(catLayout.classMethodsOffset)) {
- parseMethods(cast<ConcatInputSection>(r->getReferentInputSection()),
- classSym, catIsec, MCK_Category, MK_Static);
- }
-
- if (const auto *r = catIsec->getRelocAt(catLayout.instanceMethodsOffset)) {
- parseMethods(cast<ConcatInputSection>(r->getReferentInputSection()),
- classSym, catIsec, MCK_Category, MK_Instance);
- }
-}
-
-void ObjcCategoryChecker::parseClass(const Defined *classSym) {
- // Given a Class struct, get its corresponding Methods struct
- auto getMethodsIsec =
- [&](const InputSection *classIsec) -> ConcatInputSection * {
- if (const auto *r = classIsec->getRelocAt(classLayout.roDataOffset)) {
- const auto *roIsec =
- cast<ConcatInputSection>(r->getReferentInputSection());
- if (const auto *r = roIsec->getRelocAt(roClassLayout.baseMethodsOffset)) {
- if (auto *methodsIsec =
- cast_or_null<ConcatInputSection>(r->getReferentInputSection()))
- return methodsIsec;
- }
- }
- return nullptr;
- };
-
- const auto *classIsec = cast<ConcatInputSection>(classSym->isec);
-
- // Parse instance methods.
- if (const auto *instanceMethodsIsec = getMethodsIsec(classIsec))
- parseMethods(instanceMethodsIsec, classSym, classIsec, MCK_Class,
- MK_Instance);
-
- // Class methods are contained in the metaclass.
- if (const auto *r = classSym->isec->getRelocAt(classLayout.metaClassOffset))
- if (const auto *classMethodsIsec = getMethodsIsec(
- cast<ConcatInputSection>(r->getReferentInputSection())))
- parseMethods(classMethodsIsec, classSym, classIsec, MCK_Class, MK_Static);
-}
-
-void objc::checkCategories() {
- ObjcCategoryChecker checker;
- for (const InputSection *isec : inputSections) {
- if (isec->getName() == section_names::objcCatList)
- for (const Reloc &r : isec->relocs) {
- auto *catIsec = cast<ConcatInputSection>(r.getReferentInputSection());
- checker.parseCategory(catIsec);
- }
- }
-}
diff --git a/lld/MachO/ObjC.h b/lld/MachO/ObjC.h
index 560c5cc0bc509..67fa4114db007 100644
--- a/lld/MachO/ObjC.h
+++ b/lld/MachO/ObjC.h
@@ -20,9 +20,6 @@ constexpr const char metaclass[] = "_OBJC_METACLASS_$_";
constexpr const char ehtype[] = "_OBJC_EHTYPE_$_";
constexpr const char ivar[] = "_OBJC_IVAR_$_";
-// Check for duplicate method names within related categories / classes.
-void checkCategories();
-
} // namespace objc
bool hasObjCSection(llvm::MemoryBufferRef);
diff --git a/lld/MachO/Relocations.cpp b/lld/MachO/Relocations.cpp
index 4e840c6912cc5..9e5ac69612cfd 100644
--- a/lld/MachO/Relocations.cpp
+++ b/lld/MachO/Relocations.cpp
@@ -21,16 +21,6 @@ using namespace lld::macho;
static_assert(sizeof(void *) != 8 || sizeof(Reloc) == 24,
"Try to minimize Reloc's size; we create many instances");
-InputSection *Reloc::getReferentInputSection() const {
- if (const auto *sym = referent.dyn_cast<Symbol *>()) {
- if (const auto *d = dyn_cast<Defined>(sym))
- return d->isec;
- return nullptr;
- } else {
- return referent.get<InputSection *>();
- }
-}
-
bool macho::validateSymbolRelocation(const Symbol *sym,
const InputSection *isec, const Reloc &r) {
const RelocAttrs &relocAttrs = target->getRelocAttrs(r.type);
diff --git a/lld/MachO/Relocations.h b/lld/MachO/Relocations.h
index 5f161c8fcbfde..023d25a795a0d 100644
--- a/lld/MachO/Relocations.h
+++ b/lld/MachO/Relocations.h
@@ -67,8 +67,6 @@ struct Reloc {
int64_t addend, llvm::PointerUnion<Symbol *, InputSection *> referent)
: type(type), pcrel(pcrel), length(length), offset(offset),
addend(addend), referent(referent) {}
-
- InputSection *getReferentInputSection() const;
};
bool validateSymbolRelocation(const Symbol *, const InputSection *,
diff --git a/lld/MachO/UnwindInfoSection.cpp b/lld/MachO/UnwindInfoSection.cpp
index d480f7ed294a6..b7d0d563360a4 100644
--- a/lld/MachO/UnwindInfoSection.cpp
+++ b/lld/MachO/UnwindInfoSection.cpp
@@ -8,7 +8,6 @@
#include "UnwindInfoSection.h"
#include "InputSection.h"
-#include "Layout.h"
#include "OutputSection.h"
#include "OutputSegment.h"
#include "SymbolTable.h"
@@ -89,18 +88,41 @@ using namespace lld::macho;
// TODO(gkm): how do we align the 2nd-level pages?
-// The various fields in the on-disk representation of each compact unwind
-// entry.
-#define FOR_EACH_CU_FIELD(DO) \
- DO(Ptr, functionAddress) \
- DO(uint32_t, functionLength) \
- DO(compact_unwind_encoding_t, encoding) \
- DO(Ptr, personality) \
- DO(Ptr, lsda)
+// The offsets of various fields in the on-disk representation of each compact
+// unwind entry.
+struct CompactUnwindOffsets {
+ uint32_t functionAddress;
+ uint32_t functionLength;
+ uint32_t encoding;
+ uint32_t personality;
+ uint32_t lsda;
+
+ CompactUnwindOffsets(size_t wordSize) {
+ if (wordSize == 8)
+ init<uint64_t>();
+ else {
+ assert(wordSize == 4);
+ init<uint32_t>();
+ }
+ }
-CREATE_LAYOUT_CLASS(CompactUnwind, FOR_EACH_CU_FIELD);
+private:
+ template <class Ptr> void init() {
+ functionAddress = offsetof(Layout<Ptr>, functionAddress);
+ functionLength = offsetof(Layout<Ptr>, functionLength);
+ encoding = offsetof(Layout<Ptr>, encoding);
+ personality = offsetof(Layout<Ptr>, personality);
+ lsda = offsetof(Layout<Ptr>, lsda);
+ }
-#undef FOR_EACH_CU_FIELD
+ template <class Ptr> struct Layout {
+ Ptr functionAddress;
+ uint32_t functionLength;
+ compact_unwind_encoding_t encoding;
+ Ptr personality;
+ Ptr lsda;
+ };
+};
// LLD's internal representation of a compact unwind entry.
struct CompactUnwindEntry {
@@ -126,7 +148,7 @@ struct SecondLevelPage {
// lengthy definition of UnwindInfoSection.
class UnwindInfoSectionImpl final : public UnwindInfoSection {
public:
- UnwindInfoSectionImpl() : cuLayout(target->wordSize) {}
+ UnwindInfoSectionImpl() : cuOffsets(target->wordSize) {}
uint64_t getSize() const override { return unwindInfoSize; }
void prepare() override;
void finalize() override;
@@ -140,7 +162,7 @@ class UnwindInfoSectionImpl final : public UnwindInfoSection {
uint64_t unwindInfoSize = 0;
std::vector<decltype(symbols)::value_type> symbolsVec;
- CompactUnwindLayout cuLayout;
+ CompactUnwindOffsets cuOffsets;
std::vector<std::pair<compact_unwind_encoding_t, size_t>> commonEncodings;
EncodingMap commonEncodingIndexes;
// The entries here will be in the same order as their originating symbols
@@ -239,7 +261,7 @@ void UnwindInfoSectionImpl::prepareRelocations(ConcatInputSection *isec) {
// compact unwind entries that references them, and thus appear as section
// relocs. There is no need to prepare them. We only prepare relocs for
// personality functions.
- if (r.offset != cuLayout.personalityOffset)
+ if (r.offset != cuOffsets.personality)
continue;
if (auto *s = r.referent.dyn_cast<Symbol *>()) {
@@ -351,13 +373,17 @@ void UnwindInfoSectionImpl::relocateCompactUnwind(
auto buf = reinterpret_cast<const uint8_t *>(d->unwindEntry->data.data()) -
target->wordSize;
cu.functionLength =
- support::endian::read32le(buf + cuLayout.functionLengthOffset);
- cu.encoding = support::endian::read32le(buf + cuLayout.encodingOffset);
+ support::endian::read32le(buf + cuOffsets.functionLength);
+ cu.encoding = support::endian::read32le(buf + cuOffsets.encoding);
for (const Reloc &r : d->unwindEntry->relocs) {
- if (r.offset == cuLayout.personalityOffset)
+ if (r.offset == cuOffsets.personality) {
cu.personality = r.referent.get<Symbol *>();
- else if (r.offset == cuLayout.lsdaOffset)
- cu.lsda = r.getReferentInputSection();
+ } else if (r.offset == cuOffsets.lsda) {
+ if (auto *referentSym = r.referent.dyn_cast<Symbol *>())
+ cu.lsda = cast<Defined>(referentSym)->isec;
+ else
+ cu.lsda = r.referent.get<InputSection *>();
+ }
}
});
}
diff --git a/lld/test/MachO/Inputs/MacOSX.sdk/usr/lib/libobjc.tbd b/lld/test/MachO/Inputs/MacOSX.sdk/usr/lib/libobjc.tbd
deleted file mode 100644
index 9340c4abf93cd..0000000000000
--- a/lld/test/MachO/Inputs/MacOSX.sdk/usr/lib/libobjc.tbd
+++ /dev/null
@@ -1,10 +0,0 @@
---- !tapi-tbd-v3
-archs: [ i386, x86_64, arm64 ]
-uuids: [ 'i386: 00000000-0000-0000-0000-000000000000', 'x86_64: 00000000-0000-0000-0000-000000000001', 'arm64: 00000000-0000-0000-0000-000000000002' ]
-platform: macosx
-install-name: '/usr/lib/libobjc.dylib'
-current-version: 1281
-exports:
- - archs: [ i386, x86_64, arm64 ]
- symbols: [ __objc_empty_cache ]
-...
diff --git a/lld/test/MachO/objc-category-conflicts.s b/lld/test/MachO/objc-category-conflicts.s
deleted file mode 100644
index c88783e751fdb..0000000000000
--- a/lld/test/MachO/objc-category-conflicts.s
+++ /dev/null
@@ -1,252 +0,0 @@
-# REQUIRES: x86
-# RUN: rm -rf %t; split-file %s %t
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat1.s -o %t/cat1.o
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/cat2.s -o %t/cat2.o
-# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos11.0 -I %t %t/klass.s -o %t/klass.o
-# RUN: %lld -dylib -lobjc %t/klass.o -o %t/libklass.dylib
-
-# RUN: %no-fatal-warnings-lld -dylib -lobjc %t/klass.o %t/cat1.o %t/cat2.o -o \
-# RUN: /dev/null 2>&1 | FileCheck %s --check-prefixes=CATCLS,CATCAT
-# RUN: %no-fatal-warnings-lld -dylib -lobjc %t/libklass.dylib %t/cat1.o \
-# RUN: %t/cat2.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=CATCAT
-
-# CATCLS: warning: method '+s1' has conflicting definitions:
-# CATCLS-NEXT: >>> defined in category Cat1 from {{.*}}cat1.o
-# CATCLS-NEXT: >>> defined in class Foo from {{.*}}klass.o
-
-# CATCLS: warning: method '-m1' has conflicting definitions:
-# CATCLS-NEXT: >>> defined in category Cat1 from {{.*}}cat1.o
-# CATCLS-NEXT: >>> defined in class Foo from {{.*}}klass.o
-
-# CATCAT: warning: method '+s2' has conflicting definitions:
-# CATCAT-NEXT: >>> defined in category Cat2 from {{.*}}cat2.o
-# CATCAT-NEXT: >>> defined in category Cat1 from {{.*}}cat1.o
-
-# CATCAT: warning: method '-m2' has conflicting definitions:
-# CATCAT-NEXT: >>> defined in category Cat2 from {{.*}}cat2.o
-# CATCAT-NEXT: >>> defined in category Cat1 from {{.*}}cat1.o
-
-#--- cat1.s
-
-.include "objc-macros.s"
-
-## @interface Foo(Cat1)
-## -(void) m1;
-## -(void) m2;
-## +(void) s1;
-## +(void) s2;
-## @end
-##
-## @implementation Foo(Cat1)
-## -(void) m1 {}
-## -(void) m2 {}
-## +(void) s1 {}
-## +(void) s2 {}
-## @end
-
-.section __DATA,__objc_catlist,regular,no_dead_strip
- .quad __OBJC_$_CATEGORY_Foo_$_Cat1
-
-.section __DATA,__objc_const
-__OBJC_$_CATEGORY_Foo_$_Cat1:
- .objc_classname "Cat1"
- .quad _OBJC_CLASS_$_Foo
- .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_Foo_$_Cat1
- .quad __OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat1
- .quad 0
- .quad 0
- .quad 0
- .long 64
- .space 4
-
-__OBJC_$_CATEGORY_INSTANCE_METHODS_Foo_$_Cat1:
- .long 24 # size of method entry
- .long 2 # number of methods
- .empty_objc_method "m1", "v16 at 0:8", "-[Foo(Cat1) m1]"
- .empty_objc_method "m2", "v16 at 0:8", "-[Foo(Cat2) m2]"
-
-__OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat1:
- .long 24
- .long 2
- .empty_objc_method "s1", "v16 at 0:8", "+[Foo(Cat1) s1]"
- .empty_objc_method "s2", "v16 at 0:8", "+[Foo(Cat1) s2]"
-
-.section __DATA,__objc_imageinfo,regular,no_dead_strip
- .long 0
- .long 64
-
-.subsections_via_symbols
-
-#--- cat2.s
-
-.include "objc-macros.s"
-
-## @interface Foo(Cat2)
-## -(void) m2;
-## +(void) s2;
-## @end
-##
-## @implementation Foo(Cat2)
-## -(void) m2 {}
-## +(void) s2 {}
-## @end
-
-.section __DATA,__objc_catlist,regular,no_dead_strip
- .quad __OBJC_$_CATEGORY_Foo_$_Cat2
-
-.section __DATA,__objc_const
-__OBJC_$_CATEGORY_Foo_$_Cat2:
- .objc_classname "Cat2"
- .quad _OBJC_CLASS_$_Foo
- .quad __OBJC_$_CATEGORY_INSTANCE_METHODS_Foo_$_Cat2
- .quad __OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat2
- .quad 0
- .quad 0
- .quad 0
- .long 64
- .space 4
-
-__OBJC_$_CATEGORY_INSTANCE_METHODS_Foo_$_Cat2:
- .long 24
- .long 1
- .empty_objc_method "m2", "v16 at 0:8", "-[Foo(Cat2) m2]"
-
-__OBJC_$_CATEGORY_CLASS_METHODS_Foo_$_Cat2:
- .long 24
- .long 1
- .empty_objc_method "s2", "v16 at 0:8", "+[Foo(Cat2) m2]"
-
-.section __DATA,__objc_imageinfo,regular,no_dead_strip
- .long 0
- .long 64
-
-.subsections_via_symbols
-
-#--- klass.s
-
-.include "objc-macros.s"
-
-## @interface Foo
-## -(void) m1;
-## +(void) s1;
-## @end
-##
-## @implementation Foo
-## -(void) m1 {}
-## +(void) s1 {}
-## @end
-
-.globl _OBJC_CLASS_$_Foo, _OBJC_METACLASS_$_Foo
-
-.section __DATA,__objc_data
-_OBJC_CLASS_$_Foo:
- .quad _OBJC_METACLASS_$_Foo
- .quad 0
- .quad __objc_empty_cache
- .quad 0
- .quad __OBJC_CLASS_RO_$_Foo
-
-_OBJC_METACLASS_$_Foo:
- .quad _OBJC_METACLASS_$_Foo
- .quad _OBJC_CLASS_$_Foo
- .quad __objc_empty_cache
- .quad 0
- .quad __OBJC_METACLASS_RO_$_Foo
-
-.section __DATA,__objc_const
-__OBJC_METACLASS_RO_$_Foo:
- .long 3
- .long 40
- .long 40
- .space 4
- .quad 0
- .objc_classname "Foo"
- .quad __OBJC_$_CLASS_METHODS_Foo
- .quad 0
- .quad 0
- .quad 0
- .quad 0
-
-__OBJC_CLASS_RO_$_Foo:
- .long 2
- .long 0
- .long 0
- .space 4
- .quad 0
- .objc_classname "Foo"
- .quad __OBJC_$_INSTANCE_METHODS_Foo
- .quad 0
- .quad 0
- .quad 0
- .quad 0
-
-__OBJC_$_CLASS_METHODS_Foo:
- .long 24
- .long 1
- .empty_objc_method "s1", "v16 at 0:8", "+[Foo s1]"
-
-__OBJC_$_INSTANCE_METHODS_Foo:
- .long 24
- .long 1
- .empty_objc_method "m1", "v16 at 0:8", "-[Foo m1]"
-
-.section __DATA,__objc_classlist,regular,no_dead_strip
- .quad _OBJC_CLASS_$_Foo
-
-.section __DATA,__objc_imageinfo,regular,no_dead_strip
- .long 0
- .long 64
-
-.subsections_via_symbols
-
-#--- objc-macros.s
-
-# Macros for taking some of the boilerplate out of defining objc structs.
-
-# NOTE: \@ below is a variable that gets auto-incremented by the assembler on
-# each macro invocation. It serves as a mechanism for generating unique symbol
-# names for each macro call.
-
-.macro .objc_classname name
-
- .section __TEXT,__objc_classname,cstring_literals
- L_OBJC_CLASS_NAME_.\@:
- .asciz "\name"
-
- .section __DATA,__objc_const
- .quad L_OBJC_CLASS_NAME_.\@
-
-.endm
-
-# struct method_t {
-# const char *name;
-# const char *type;
-# void *impl;
-# }
-.macro .objc_method name, type, impl
-
- .section __TEXT,__objc_methname,cstring_literals
- L_OBJC_METH_VAR_NAME_.\@:
- .asciz "\name"
-
- .section __TEXT,__objc_methtype,cstring_literals
- L_OBJC_METH_VAR_TYPE_.\@:
- .asciz "\type"
-
- .section __DATA,__objc_const
- .quad L_OBJC_METH_VAR_NAME_.\@
- .quad L_OBJC_METH_VAR_TYPE_.\@
- .quad "\impl"
-
-.endm
-
-# Generate a method_t with a basic impl that just contains `ret`.
-.macro .empty_objc_method name, type, impl
-
- .text
- "\impl":
- ret
-
- .objc_method "\name", "\type", "\impl"
-
-.endm
diff --git a/lld/test/MachO/objc-imageinfo.s b/lld/test/MachO/objc-imageinfo.s
index f83e93e7c0348..0523aac841c77 100644
--- a/lld/test/MachO/objc-imageinfo.s
+++ b/lld/test/MachO/objc-imageinfo.s
@@ -152,11 +152,14 @@ _OBJC_CLASS_$_FooClass:
.space 40
.section __DATA,__objc_const
+.p2align 3
+__OBJC_$_CATEGORY_INSTANCE_METHODS_FooClass_$_barcat:
+
.p2align 3
__OBJC_$_CATEGORY_FooClass_$_barcat:
.quad L_CAT_NAME
.quad _OBJC_CLASS_$_FooClass
-.quad 0
+.quad __OBJC_$_CATEGORY_INSTANCE_METHODS_FooClass_$_barcat
.quad 0
.quad 0
.quad 0
More information about the llvm-commits
mailing list