llvm/lld/MachO/ObjC.cpp

//===- ObjC.cpp -----------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#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 {};

} // namespace

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) {}

// Get the class's ro_data symbol. If getMetaRo is true, then we will return
// the meta-class's ro_data symbol. Otherwise, we will return the class
// (instance) ro_data symbol.
Defined *ObjcCategoryMerger::getClassRo(const Defined *classSym,
                                        bool getMetaRo) {}

// Given an ConcatInputSection or CStringInputSection and an offset, if there is
// a symbol(Defined) at that offset, then erase the symbol (mark it not live)
void ObjcCategoryMerger::tryEraseDefinedAtIsecOffset(
    const ConcatInputSection *isec, uint32_t offset) {}

void ObjcCategoryMerger::collectCategoryWriterInfoFromCategory(
    const InfoInputCategory &catInfo) {}

// Parse a protocol list that might be linked to ConcatInputSection at a given
// offset. The format of the protocol list is different than other lists (prop
// lists, method lists) so we need to parse it differently
void ObjcCategoryMerger::parseProtocolListInfo(
    const ConcatInputSection *isec, uint32_t secOffset,
    PointerListInfo &ptrList, [[maybe_unused]] SourceLanguage sourceLang) {}

// Parse a protocol list and return the PointerListInfo for it
ObjcCategoryMerger::PointerListInfo
ObjcCategoryMerger::parseProtocolListInfo(const ConcatInputSection *isec,
                                          uint32_t secOffset,
                                          SourceLanguage sourceLang) {}

// Parse a pointer list that might be linked to ConcatInputSection at a given
// offset. This can be used for instance methods, class methods, instance props
// and class props since they have the same format.
void ObjcCategoryMerger::parsePointerListInfo(const ConcatInputSection *isec,
                                              uint32_t secOffset,
                                              PointerListInfo &ptrList) {}

// Here we parse all the information of an input category (catInfo) and
// append the parsed info into the structure which will contain all the
// information about how a class is extended (extInfo)
void ObjcCategoryMerger::parseCatInfoToExtInfo(const InfoInputCategory &catInfo,
                                               ClassExtensionInfo &extInfo) {}

// Generate a protocol list (including header) and link it into the parent at
// the specified offset.
Defined *ObjcCategoryMerger::emitAndLinkProtocolList(
    Defined *parentSym, uint32_t linkAtOffset,
    const ClassExtensionInfo &extInfo, const PointerListInfo &ptrList) {}

// Generate a pointer list (including header) and link it into the parent at the
// specified offset. This is used for instance and class methods and
// proprieties.
void ObjcCategoryMerger::emitAndLinkPointerList(
    Defined *parentSym, uint32_t linkAtOffset,
    const ClassExtensionInfo &extInfo, const PointerListInfo &ptrList) {}

// This method creates an __objc_catlist ConcatInputSection with a single slot
Defined *
ObjcCategoryMerger::emitCatListEntrySec(const std::string &forCategoryName,
                                        const std::string &forBaseClassName,
                                        ObjFile *objFile) {}

// Here we generate the main category body and link the name and base class into
// it. We don't link any other info yet like the protocol and class/instance
// methods/props.
Defined *ObjcCategoryMerger::emitCategoryBody(const std::string &name,
                                              const Defined *nameSym,
                                              const Symbol *baseClassSym,
                                              const std::string &baseClassName,
                                              ObjFile *objFile) {}

// This writes the new category name (for the merged category) into the binary
// and returns the sybmol for it.
Defined *ObjcCategoryMerger::emitCategoryName(const std::string &name,
                                              ObjFile *objFile) {}

// This method fully creates a new category from the given ClassExtensionInfo.
// It creates the category name, body and method/protocol/prop lists and links
// them all together. Then it creates a new __objc_catlist entry and adds the
// category to it. Calling this method will fully generate a category which will
// be available in the final binary.
Defined *ObjcCategoryMerger::emitCategory(const ClassExtensionInfo &extInfo) {}

// This method merges all the categories (sharing a base class) into a single
// category.
void ObjcCategoryMerger::mergeCategoriesIntoSingleCategory(
    std::vector<InfoInputCategory> &categories) {}

void ObjcCategoryMerger::createSymbolReference(Defined *refFrom,
                                               const Symbol *refTo,
                                               uint32_t offset,
                                               const Reloc &relocTemplate) {}

// Get the list of categories in the '__objc_nlcatlist' section. We can't
// optimize these as they have a '+load' method that has to be called at
// runtime.
DenseSet<const Symbol *> ObjcCategoryMerger::collectNlCategories() {}

void ObjcCategoryMerger::collectAndValidateCategoriesData() {}

// In the input we have multiple __objc_catlist InputSection, each of which may
// contain links to multiple categories. Of these categories, we will merge (and
// erase) only some. There will be some categories that will remain untouched
// (not erased). For these not erased categories, we generate new __objc_catlist
// entries since the parent __objc_catlist entry will be erased
void ObjcCategoryMerger::generateCatListForNonErasedCategories(
    const MapVector<ConcatInputSection *, std::set<uint64_t>>
        catListToErasedOffsets) {}

void ObjcCategoryMerger::eraseISec(ConcatInputSection *isec) {}

// This fully erases the merged categories, including their body, their names,
// their method/protocol/prop lists and the __objc_catlist entries that link to
// them.
void ObjcCategoryMerger::eraseMergedCategories() {}

void ObjcCategoryMerger::doMerge() {}

void ObjcCategoryMerger::doCleanup() {}

StringRef ObjcCategoryMerger::newStringData(const char *str) {}

SmallVector<uint8_t> &ObjcCategoryMerger::newSectionData(uint32_t size) {}

} // namespace

void objc::mergeCategories() {}

void objc::doCleanup() {}

ObjcCategoryMerger::SourceLanguage
ObjcCategoryMerger::getClassSymSourceLang(const Defined *classSym) {}
void ObjcCategoryMerger::mergeCategoriesIntoBaseClass(
    const Defined *baseClass, std::vector<InfoInputCategory> &categories) {}

// Erase the symbol at a given offset in an InputSection
void ObjcCategoryMerger::eraseSymbolAtIsecOffset(ConcatInputSection *isec,
                                                 uint32_t offset) {}