Coverage Report

Created: 2019-05-19 14:56

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/lib/ReaderWriter/MachO/ObjCPass.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- lib/ReaderWriter/MachO/ObjCPass.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
//===----------------------------------------------------------------------===//
10
11
#include "ArchHandler.h"
12
#include "File.h"
13
#include "MachONormalizedFileBinaryUtils.h"
14
#include "MachOPasses.h"
15
#include "lld/Common/LLVM.h"
16
#include "lld/Core/DefinedAtom.h"
17
#include "lld/Core/File.h"
18
#include "lld/Core/Reference.h"
19
#include "lld/Core/Simple.h"
20
#include "lld/ReaderWriter/MachOLinkingContext.h"
21
#include "llvm/ADT/DenseMap.h"
22
#include "llvm/ADT/STLExtras.h"
23
24
namespace lld {
25
namespace mach_o {
26
27
///
28
/// ObjC Image Info Atom created by the ObjC pass.
29
///
30
class ObjCImageInfoAtom : public SimpleDefinedAtom {
31
public:
32
  ObjCImageInfoAtom(const File &file, bool isBig,
33
                    MachOLinkingContext::ObjCConstraint objCConstraint,
34
                    uint32_t swiftVersion)
35
2
      : SimpleDefinedAtom(file) {
36
2
37
2
    Data.info.version = 0;
38
2
39
2
    switch (objCConstraint) {
40
2
    case MachOLinkingContext::objc_unknown:
41
0
      llvm_unreachable("Shouldn't run the objc pass without a constraint");
42
2
    case MachOLinkingContext::objc_supports_gc:
43
0
    case MachOLinkingContext::objc_gc_only:
44
0
      llvm_unreachable("GC is not supported");
45
2
    case MachOLinkingContext::objc_retainReleaseForSimulator:
46
2
      // The retain/release for simulator flag is already the correct
47
2
      // encoded value for the data so just set it here.
48
2
      Data.info.flags = (uint32_t)objCConstraint;
49
2
      break;
50
0
    case MachOLinkingContext::objc_retainRelease:
51
0
      // We don't need to encode this flag, so just leave the flags as 0.
52
0
      Data.info.flags = 0;
53
0
      break;
54
2
    }
55
2
56
2
    Data.info.flags |= (swiftVersion << 8);
57
2
58
2
    normalized::write32(Data.bytes + 4, Data.info.flags, isBig);
59
2
  }
60
61
2
  ~ObjCImageInfoAtom() override = default;
62
63
14
  ContentType contentType() const override {
64
14
    return DefinedAtom::typeObjCImageInfo;
65
14
  }
66
67
3
  Alignment alignment() const override {
68
3
    return 4;
69
3
  }
70
71
12
  uint64_t size() const override {
72
12
    return 8;
73
12
  }
74
75
1
  ContentPermissions permissions() const override {
76
1
    return DefinedAtom::permR__;
77
1
  }
78
79
5
  ArrayRef<uint8_t> rawContent() const override {
80
5
    return llvm::makeArrayRef(Data.bytes, size());
81
5
  }
82
83
private:
84
85
  struct objc_image_info  {
86
    uint32_t  version;
87
    uint32_t  flags;
88
  };
89
90
  union {
91
    objc_image_info info;
92
    uint8_t bytes[8];
93
  } Data;
94
};
95
96
class ObjCPass : public Pass {
97
public:
98
  ObjCPass(const MachOLinkingContext &context)
99
      : _ctx(context),
100
2
        _file(*_ctx.make_file<MachOFile>("<mach-o objc pass>")) {
101
2
    _file.setOrdinal(_ctx.getNextOrdinalAndIncrement());
102
2
  }
103
104
2
  llvm::Error perform(SimpleFile &mergedFile) override {
105
2
    // Add the image info.
106
2
    mergedFile.addAtom(*getImageInfo());
107
2
108
2
    return llvm::Error::success();
109
2
  }
110
111
private:
112
113
2
  const DefinedAtom* getImageInfo() {
114
2
    bool IsBig = MachOLinkingContext::isBigEndian(_ctx.arch());
115
2
    return new (_file.allocator()) ObjCImageInfoAtom(_file, IsBig,
116
2
                                                     _ctx.objcConstraint(),
117
2
                                                     _ctx.swiftVersion());
118
2
  }
119
120
  const MachOLinkingContext   &_ctx;
121
  MachOFile                   &_file;
122
};
123
124
125
126
2
void addObjCPass(PassManager &pm, const MachOLinkingContext &ctx) {
127
2
  pm.add(llvm::make_unique<ObjCPass>(ctx));
128
2
}
129
130
} // end namespace mach_o
131
} // end namespace lld