| //===- 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 "llvm/BinaryFormat/MachO.h" |
| #include "llvm/Bitcode/BitcodeReader.h" |
| |
| using namespace llvm; |
| using namespace llvm::MachO; |
| using namespace lld; |
| using namespace lld::macho; |
| |
| template <class LP> static bool objectHasObjCSection(MemoryBufferRef mb) { |
| using SectionHeader = typename LP::section; |
| |
| auto *hdr = |
| reinterpret_cast<const typename LP::mach_header *>(mb.getBufferStart()); |
| if (hdr->magic != LP::magic) |
| return false; |
| |
| if (const auto *c = |
| findCommand<typename LP::segment_command>(hdr, LP::segmentLCType)) { |
| auto sectionHeaders = ArrayRef<SectionHeader>{ |
| reinterpret_cast<const SectionHeader *>(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 == section_names::swift)) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| static bool objectHasObjCSection(MemoryBufferRef mb) { |
| if (target->wordSize == 8) |
| return ::objectHasObjCSection<LP64>(mb); |
| else |
| return ::objectHasObjCSection<ILP32>(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; |
| } |
| } |