xref: /freebsd/contrib/llvm-project/lld/MachO/ObjC.cpp (revision ec0ea6efa1ad229d75c394c1a9b9cac33af2b1d3)
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 "llvm/BinaryFormat/MachO.h"
16 
17 using namespace llvm;
18 using namespace llvm::MachO;
19 using namespace lld;
20 using namespace lld::macho;
21 
22 template <class LP> static bool hasObjCSection(MemoryBufferRef mb) {
23   using Section = typename LP::section;
24 
25   auto *hdr =
26       reinterpret_cast<const typename LP::mach_header *>(mb.getBufferStart());
27   if (hdr->magic != LP::magic)
28     return false;
29 
30   if (const auto *c =
31           findCommand<typename LP::segment_command>(hdr, LP::segmentLCType)) {
32     auto sectionHeaders =
33         ArrayRef<Section>{reinterpret_cast<const Section *>(c + 1), c->nsects};
34     for (const Section &sec : sectionHeaders) {
35       StringRef sectname(sec.sectname,
36                          strnlen(sec.sectname, sizeof(sec.sectname)));
37       StringRef segname(sec.segname, strnlen(sec.segname, sizeof(sec.segname)));
38       if ((segname == segment_names::data &&
39            sectname == section_names::objcCatList) ||
40           (segname == segment_names::text &&
41            sectname == section_names::swift)) {
42         return true;
43       }
44     }
45   }
46   return false;
47 }
48 
49 bool macho::hasObjCSection(MemoryBufferRef mb) {
50   if (target->wordSize == 8)
51     return ::hasObjCSection<LP64>(mb);
52   else
53     return ::hasObjCSection<ILP32>(mb);
54 }
55