//===- 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 "InputFiles.h" #include "InputSection.h" #include "OutputSegment.h" #include "Target.h" #include "lld/Common/ErrorHandler.h" #include "llvm/BinaryFormat/MachO.h" #include "llvm/Bitcode/BitcodeReader.h" using namespace llvm; using namespace llvm::MachO; using namespace lld; using namespace lld::macho; template static bool objectHasObjCSection(MemoryBufferRef mb) { using SectionHeader = typename LP::section; auto *hdr = reinterpret_cast(mb.getBufferStart()); if (hdr->magic != LP::magic) return false; if (const auto *c = findCommand(hdr, LP::segmentLCType)) { auto sectionHeaders = ArrayRef{ reinterpret_cast(c + 1), c->nsects}; for (const SectionHeader &secHead : sectionHeaders) { StringRef sectname(secHead.sectname, strnlen(secHead.sectname, sizeof(secHead.sectname))); StringRef segname(secHead.segname, strnlen(secHead.segname, sizeof(secHead.segname))); if ((segname == segment_names::data && sectname == section_names::objcCatList) || (segname == segment_names::text && sectname.startswith(section_names::swift))) { return true; } } } return false; } static bool objectHasObjCSection(MemoryBufferRef mb) { if (target->wordSize == 8) return ::objectHasObjCSection(mb); else return ::objectHasObjCSection(mb); } bool macho::hasObjCSection(MemoryBufferRef mb) { switch (identify_magic(mb.getBuffer())) { case file_magic::macho_object: return objectHasObjCSection(mb); case file_magic::bitcode: return check(isBitcodeContainingObjCCategory(mb)); default: return false; } }