aboutsummaryrefslogtreecommitdiff
path: root/lib/ReaderWriter/MachO/Atoms.h
blob: e186f06ab4fb0efef539736da5c2504a686dd86f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
//===- lib/ReaderWriter/MachO/Atoms.h -------------------------------------===//
//
//                             The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef LLD_READER_WRITER_MACHO_ATOMS_H
#define LLD_READER_WRITER_MACHO_ATOMS_H

#include "lld/Core/Simple.h"

namespace lld {
namespace mach_o {
class MachODefinedAtom : public SimpleDefinedAtom {
public:
  MachODefinedAtom(const File &f, const StringRef name, Scope scope,
                   ContentType type, Merge merge, bool thumb, bool noDeadStrip,
                   const ArrayRef<uint8_t> content, Alignment align)
      : SimpleDefinedAtom(f), _name(name), _content(content),
        _align(align), _contentType(type), _scope(scope), _merge(merge),
        _thumb(thumb), _noDeadStrip(noDeadStrip) {}

  // Constructor for zero-fill content
  MachODefinedAtom(const File &f, const StringRef name, Scope scope,
                   uint64_t size, bool noDeadStrip, Alignment align)
      : SimpleDefinedAtom(f), _name(name),
        _content(ArrayRef<uint8_t>(nullptr, size)), _align(align),
        _contentType(DefinedAtom::typeZeroFill),
        _scope(scope), _merge(mergeNo), _thumb(false),
        _noDeadStrip(noDeadStrip) {}

  uint64_t size() const override { return _content.size(); }

  ContentType contentType() const override { return _contentType; }

  Alignment alignment() const override { return _align; }

  StringRef name() const override { return _name; }

  Scope scope() const override { return _scope; }

  Merge merge() const override { return _merge; }

  DeadStripKind deadStrip() const override {
    if (_contentType == DefinedAtom::typeInitializerPtr)
      return deadStripNever;
    if (_contentType == DefinedAtom::typeTerminatorPtr)
      return deadStripNever;
    if (_noDeadStrip)
      return deadStripNever;
    return deadStripNormal;
  }

  ArrayRef<uint8_t> rawContent() const override {
    // Note: Zerofill atoms have a content pointer which is null.
    return _content;
  }

  bool isThumb() const { return _thumb; }

  void addReference(uint32_t offsetInAtom, uint16_t relocType,
                    const Atom *target, Reference::Addend addend,
                    Reference::KindArch arch = Reference::KindArch::x86_64,
                    Reference::KindNamespace ns
                     = Reference::KindNamespace::mach_o) {
    SimpleDefinedAtom::addReference(ns, arch, relocType, offsetInAtom, target,
                                    addend);
  }

private:
  const StringRef _name;
  const ArrayRef<uint8_t> _content;
  const DefinedAtom::Alignment _align;
  const ContentType _contentType;
  const Scope _scope;
  const Merge _merge;
  const bool _thumb;
  const bool _noDeadStrip;
};

class MachODefinedCustomSectionAtom : public MachODefinedAtom {
public:
  MachODefinedCustomSectionAtom(const File &f, const StringRef name,
                                Scope scope, ContentType type, Merge merge,
                                bool thumb, bool noDeadStrip,
                                const ArrayRef<uint8_t> content,
                                StringRef sectionName, Alignment align)
      : MachODefinedAtom(f, name, scope, type, merge, thumb, noDeadStrip,
                         content, align),
        _sectionName(sectionName) {}

  SectionChoice sectionChoice() const override {
    return DefinedAtom::sectionCustomRequired;
  }

  StringRef customSectionName() const override {
    return _sectionName;
  }
private:
  StringRef _sectionName;
};


class MachOTentativeDefAtom : public SimpleDefinedAtom {
public:
  MachOTentativeDefAtom(const File &f, const StringRef name, Scope scope,
                        uint64_t size, DefinedAtom::Alignment align)
      : SimpleDefinedAtom(f), _name(name), _scope(scope), _size(size),
        _align(align) {}

  uint64_t size() const override { return _size; }

  Merge merge() const override { return DefinedAtom::mergeAsTentative; }

  ContentType contentType() const override { return DefinedAtom::typeZeroFill; }

  Alignment alignment() const override { return _align; }

  StringRef name() const override { return _name; }

  Scope scope() const override { return _scope; }

  ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); }

private:
  const StringRef _name;
  const Scope _scope;
  const uint64_t _size;
  const DefinedAtom::Alignment _align;
};

class MachOSharedLibraryAtom : public SharedLibraryAtom {
public:
  MachOSharedLibraryAtom(const File &file, StringRef name,
                         StringRef dylibInstallName, bool weakDef)
      : SharedLibraryAtom(), _file(file), _name(name),
        _dylibInstallName(dylibInstallName) {}
  virtual ~MachOSharedLibraryAtom() {}

  StringRef loadName() const override { return _dylibInstallName; }

  bool canBeNullAtRuntime() const override {
    // FIXME: this may actually be changeable. For now, all symbols are strongly
    // defined though.
    return false;
  }

  const File &file() const override { return _file; }

  StringRef name() const override { return _name; }

  Type type() const override {
    // Unused in MachO (I think).
    return Type::Unknown;
  }

  uint64_t size() const override {
    // Unused in MachO (I think)
    return 0;
  }

private:
  const File &_file;
  StringRef _name;
  StringRef _dylibInstallName;
};


} // mach_o
} // lld

#endif