#include "ObjC.h"
#include "ConcatOutputSection.h"
#include "InputFiles.h"
#include "InputSection.h"
#include "Layout.h"
#include "OutputSegment.h"
#include "SyntheticSections.h"
#include "Target.h"
#include "lld/Common/ErrorHandler.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/BinaryFormat/MachO.h"
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Support/TimeProfiler.h"
usingnamespacellvm;
usingnamespacellvm::MachO;
usingnamespacelld;
usingnamespacelld::macho;
template <class LP> static bool objectHasObjCSection(MemoryBufferRef mb) { … }
static bool objectHasObjCSection(MemoryBufferRef mb) { … }
bool macho::hasObjCSection(MemoryBufferRef mb) { … }
namespace {
#define FOR_EACH_CATEGORY_FIELD …
CREATE_LAYOUT_CLASS(Category, FOR_EACH_CATEGORY_FIELD);
#undef FOR_EACH_CATEGORY_FIELD
#define FOR_EACH_CLASS_FIELD …
CREATE_LAYOUT_CLASS(Class, FOR_EACH_CLASS_FIELD);
#undef FOR_EACH_CLASS_FIELD
#define FOR_EACH_RO_CLASS_FIELD …
CREATE_LAYOUT_CLASS(ROClass, FOR_EACH_RO_CLASS_FIELD);
#undef FOR_EACH_RO_CLASS_FIELD
#define FOR_EACH_LIST_HEADER …
CREATE_LAYOUT_CLASS(ListHeader, FOR_EACH_LIST_HEADER);
#undef FOR_EACH_LIST_HEADER
#define FOR_EACH_PROTOCOL_LIST_HEADER …
CREATE_LAYOUT_CLASS(ProtocolListHeader, FOR_EACH_PROTOCOL_LIST_HEADER);
#undef FOR_EACH_PROTOCOL_LIST_HEADER
#define FOR_EACH_METHOD …
CREATE_LAYOUT_CLASS(Method, FOR_EACH_METHOD);
#undef FOR_EACH_METHOD
enum MethodContainerKind { … };
struct MethodContainer { … };
enum MethodKind { … };
struct ObjcClass { … };
}
class ObjcCategoryChecker { … };
ObjcCategoryChecker::ObjcCategoryChecker()
: … { … }
void ObjcCategoryChecker::parseMethods(const ConcatInputSection *methodsIsec,
const Symbol *methodContainerSym,
const ConcatInputSection *containerIsec,
MethodContainerKind mcKind,
MethodKind mKind) { … }
void ObjcCategoryChecker::parseCategory(const ConcatInputSection *catIsec) { … }
void ObjcCategoryChecker::parseClass(const Defined *classSym) { … }
void objc::checkCategories() { … }
namespace {
class ObjcCategoryMerger { … };
SmallVector<std::unique_ptr<SmallVector<uint8_t>>>
ObjcCategoryMerger::generatedSectionData;
ObjcCategoryMerger::ObjcCategoryMerger(
std::vector<ConcatInputSection *> &_allInputSections)
: … { … }
void ObjcCategoryMerger::collectSectionWriteInfoFromIsec(
const InputSection *isec, InfoWriteSection &catWriteInfo) { … }
Symbol *
ObjcCategoryMerger::tryGetSymbolAtIsecOffset(const ConcatInputSection *isec,
uint32_t offset) { … }
Defined *ObjcCategoryMerger::tryFindDefinedOnIsec(const InputSection *isec,
uint32_t offset) { … }
Defined *
ObjcCategoryMerger::tryGetDefinedAtIsecOffset(const ConcatInputSection *isec,
uint32_t offset) { … }
Defined *ObjcCategoryMerger::getClassRo(const Defined *classSym,
bool getMetaRo) { … }
void ObjcCategoryMerger::tryEraseDefinedAtIsecOffset(
const ConcatInputSection *isec, uint32_t offset) { … }
void ObjcCategoryMerger::collectCategoryWriterInfoFromCategory(
const InfoInputCategory &catInfo) { … }
void ObjcCategoryMerger::parseProtocolListInfo(
const ConcatInputSection *isec, uint32_t secOffset,
PointerListInfo &ptrList, [[maybe_unused]] SourceLanguage sourceLang) { … }
ObjcCategoryMerger::PointerListInfo
ObjcCategoryMerger::parseProtocolListInfo(const ConcatInputSection *isec,
uint32_t secOffset,
SourceLanguage sourceLang) { … }
void ObjcCategoryMerger::parsePointerListInfo(const ConcatInputSection *isec,
uint32_t secOffset,
PointerListInfo &ptrList) { … }
void ObjcCategoryMerger::parseCatInfoToExtInfo(const InfoInputCategory &catInfo,
ClassExtensionInfo &extInfo) { … }
Defined *ObjcCategoryMerger::emitAndLinkProtocolList(
Defined *parentSym, uint32_t linkAtOffset,
const ClassExtensionInfo &extInfo, const PointerListInfo &ptrList) { … }
void ObjcCategoryMerger::emitAndLinkPointerList(
Defined *parentSym, uint32_t linkAtOffset,
const ClassExtensionInfo &extInfo, const PointerListInfo &ptrList) { … }
Defined *
ObjcCategoryMerger::emitCatListEntrySec(const std::string &forCategoryName,
const std::string &forBaseClassName,
ObjFile *objFile) { … }
Defined *ObjcCategoryMerger::emitCategoryBody(const std::string &name,
const Defined *nameSym,
const Symbol *baseClassSym,
const std::string &baseClassName,
ObjFile *objFile) { … }
Defined *ObjcCategoryMerger::emitCategoryName(const std::string &name,
ObjFile *objFile) { … }
Defined *ObjcCategoryMerger::emitCategory(const ClassExtensionInfo &extInfo) { … }
void ObjcCategoryMerger::mergeCategoriesIntoSingleCategory(
std::vector<InfoInputCategory> &categories) { … }
void ObjcCategoryMerger::createSymbolReference(Defined *refFrom,
const Symbol *refTo,
uint32_t offset,
const Reloc &relocTemplate) { … }
DenseSet<const Symbol *> ObjcCategoryMerger::collectNlCategories() { … }
void ObjcCategoryMerger::collectAndValidateCategoriesData() { … }
void ObjcCategoryMerger::generateCatListForNonErasedCategories(
const MapVector<ConcatInputSection *, std::set<uint64_t>>
catListToErasedOffsets) { … }
void ObjcCategoryMerger::eraseISec(ConcatInputSection *isec) { … }
void ObjcCategoryMerger::eraseMergedCategories() { … }
void ObjcCategoryMerger::doMerge() { … }
void ObjcCategoryMerger::doCleanup() { … }
StringRef ObjcCategoryMerger::newStringData(const char *str) { … }
SmallVector<uint8_t> &ObjcCategoryMerger::newSectionData(uint32_t size) { … }
}
void objc::mergeCategories() { … }
void objc::doCleanup() { … }
ObjcCategoryMerger::SourceLanguage
ObjcCategoryMerger::getClassSymSourceLang(const Defined *classSym) { … }
void ObjcCategoryMerger::mergeCategoriesIntoBaseClass(
const Defined *baseClass, std::vector<InfoInputCategory> &categories) { … }
void ObjcCategoryMerger::eraseSymbolAtIsecOffset(ConcatInputSection *isec,
uint32_t offset) { … }