Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/lib/ReaderWriter/MachO/LayoutPass.h
Line
Count
Source
1
//===------ lib/ReaderWriter/MachO/LayoutPass.h - Handles Layout of atoms -===//
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
#ifndef LLD_READER_WRITER_MACHO_LAYOUT_PASS_H
10
#define LLD_READER_WRITER_MACHO_LAYOUT_PASS_H
11
12
#include "lld/Core/File.h"
13
#include "lld/Core/Pass.h"
14
#include "lld/Core/Reader.h"
15
#include "lld/Core/Simple.h"
16
#include "llvm/ADT/DenseMap.h"
17
#include <map>
18
#include <string>
19
#include <vector>
20
21
namespace lld {
22
class DefinedAtom;
23
class SimpleFile;
24
25
namespace mach_o {
26
27
/// This linker pass does the layout of the atoms. The pass is done after the
28
/// order their .o files were found on the command line, then by order of the
29
/// atoms (address) in the .o file.  But some atoms have a preferred location
30
/// in their section (such as pinned to the start or end of the section), so
31
/// the sort must take that into account too.
32
class LayoutPass : public Pass {
33
public:
34
  struct SortKey {
35
    SortKey(OwningAtomPtr<DefinedAtom> &&atom,
36
            const DefinedAtom *root, uint64_t override)
37
732
    : _atom(std::move(atom)), _root(root), _override(override) {}
38
    OwningAtomPtr<DefinedAtom> _atom;
39
    const DefinedAtom *_root;
40
    uint64_t _override;
41
42
    // Note, these are only here to appease MSVC bots which didn't like
43
    // the same methods being implemented/deleted in OwningAtomPtr.
44
    SortKey(SortKey &&key) : _atom(std::move(key._atom)), _root(key._root),
45
1.95k
                             _override(key._override) {
46
1.95k
      key._root = nullptr;
47
1.95k
    }
48
49
1.04k
    SortKey &operator=(SortKey &&key) {
50
1.04k
      _atom = std::move(key._atom);
51
1.04k
      _root = key._root;
52
1.04k
      key._root = nullptr;
53
1.04k
      _override = key._override;
54
1.04k
      return *this;
55
1.04k
    }
56
57
  private:
58
    SortKey(const SortKey &) = delete;
59
    void operator=(const SortKey&) = delete;
60
  };
61
62
  typedef std::function<bool (const DefinedAtom *left, const DefinedAtom *right,
63
                              bool &leftBeforeRight)> SortOverride;
64
65
  LayoutPass(const Registry &registry, SortOverride sorter);
66
67
  /// Sorts atoms in mergedFile by content type then by command line order.
68
  llvm::Error perform(SimpleFile &mergedFile) override;
69
70
170
  ~LayoutPass() override = default;
71
72
private:
73
  // Build the followOn atoms chain as specified by the kindLayoutAfter
74
  // reference type
75
  void buildFollowOnTable(const File::AtomRange<DefinedAtom> &range);
76
77
  // Build a map of Atoms to ordinals for sorting the atoms
78
  void buildOrdinalOverrideMap(const File::AtomRange<DefinedAtom> &range);
79
80
  const Registry &_registry;
81
  SortOverride _customSorter;
82
83
  typedef llvm::DenseMap<const DefinedAtom *, const DefinedAtom *> AtomToAtomT;
84
  typedef llvm::DenseMap<const DefinedAtom *, uint64_t> AtomToOrdinalT;
85
86
  // A map to be used to sort atoms. It represents the order of atoms in the
87
  // result; if Atom X is mapped to atom Y in this map, X will be located
88
  // immediately before Y in the output file. Y might be mapped to another
89
  // atom, constructing a follow-on chain. An atom cannot be mapped to more
90
  // than one atom unless all but one atom are of size zero.
91
  AtomToAtomT _followOnNexts;
92
93
  // A map to be used to sort atoms. It's a map from an atom to its root of
94
  // follow-on chain. A root atom is mapped to itself. If an atom is not in
95
  // _followOnNexts, the atom is not in this map, and vice versa.
96
  AtomToAtomT _followOnRoots;
97
98
  AtomToOrdinalT _ordinalOverrideMap;
99
100
  // Helper methods for buildFollowOnTable().
101
  const DefinedAtom *findAtomFollowedBy(const DefinedAtom *targetAtom);
102
  bool checkAllPrevAtomsZeroSize(const DefinedAtom *targetAtom);
103
104
  void setChainRoot(const DefinedAtom *targetAtom, const DefinedAtom *root);
105
106
  std::vector<SortKey> decorate(File::AtomRange<DefinedAtom> &atomRange) const;
107
108
  void undecorate(File::AtomRange<DefinedAtom> &atomRange,
109
                  std::vector<SortKey> &keys) const;
110
111
  // Check if the follow-on graph is a correct structure. For debugging only.
112
  void checkFollowonChain(const File::AtomRange<DefinedAtom> &range);
113
};
114
115
} // namespace mach_o
116
} // namespace lld
117
118
#endif // LLD_READER_WRITER_MACHO_LAYOUT_PASS_H