1 //===- ObjC.cpp -----------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "ObjC.h" 10 #include "InputFiles.h" 11 #include "InputSection.h" 12 #include "OutputSegment.h" 13 #include "Target.h" 14 15 #include "lld/Common/ErrorHandler.h" 16 #include "llvm/BinaryFormat/MachO.h" 17 #include "llvm/Bitcode/BitcodeReader.h" 18 19 using namespace llvm; 20 using namespace llvm::MachO; 21 using namespace lld; 22 using namespace lld::macho; 23 24 template <class LP> static bool objectHasObjCSection(MemoryBufferRef mb) { 25 using SectionHeader = typename LP::section; 26 27 auto *hdr = 28 reinterpret_cast<const typename LP::mach_header *>(mb.getBufferStart()); 29 if (hdr->magic != LP::magic) 30 return false; 31 32 if (const auto *c = 33 findCommand<typename LP::segment_command>(hdr, LP::segmentLCType)) { 34 auto sectionHeaders = ArrayRef<SectionHeader>{ 35 reinterpret_cast<const SectionHeader *>(c + 1), c->nsects}; 36 for (const SectionHeader &secHead : sectionHeaders) { 37 StringRef sectname(secHead.sectname, 38 strnlen(secHead.sectname, sizeof(secHead.sectname))); 39 StringRef segname(secHead.segname, 40 strnlen(secHead.segname, sizeof(secHead.segname))); 41 if ((segname == segment_names::data && 42 sectname == section_names::objcCatList) || 43 (segname == segment_names::text && 44 sectname.startswith(section_names::swift))) { 45 return true; 46 } 47 } 48 } 49 return false; 50 } 51 52 static bool objectHasObjCSection(MemoryBufferRef mb) { 53 if (target->wordSize == 8) 54 return ::objectHasObjCSection<LP64>(mb); 55 else 56 return ::objectHasObjCSection<ILP32>(mb); 57 } 58 59 bool macho::hasObjCSection(MemoryBufferRef mb) { 60 switch (identify_magic(mb.getBuffer())) { 61 case file_magic::macho_object: 62 return objectHasObjCSection(mb); 63 case file_magic::bitcode: 64 return check(isBitcodeContainingObjCCategory(mb)); 65 default: 66 return false; 67 } 68 } 69