Coverage Report

Created: 2017-10-03 07:32

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