1//===- lib/MC/MCModule.cpp - MCModule implementation ----------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/MC/MCModule.h"
11#include "llvm/MC/MCAtom.h"
12#include "llvm/MC/MCFunction.h"
13#include <algorithm>
14
15using namespace llvm;
16
17static bool AtomComp(const MCAtom *L, uint64_t Addr) {
18  return L->getEndAddr() < Addr;
19}
20
21void MCModule::map(MCAtom *NewAtom) {
22  uint64_t Begin = NewAtom->Begin;
23
24  assert(Begin <= NewAtom->End && "Creating MCAtom with endpoints reversed?");
25
26  // Check for atoms already covering this range.
27  AtomListTy::iterator I = std::lower_bound(atom_begin(), atom_end(),
28                                            Begin, AtomComp);
29  assert((I == atom_end() || (*I)->getBeginAddr() > NewAtom->End)
30         && "Offset range already occupied!");
31
32  // Insert the new atom to the list.
33  Atoms.insert(I, NewAtom);
34}
35
36MCTextAtom *MCModule::createTextAtom(uint64_t Begin, uint64_t End) {
37  MCTextAtom *NewAtom = new MCTextAtom(this, Begin, End);
38  map(NewAtom);
39  return NewAtom;
40}
41
42MCDataAtom *MCModule::createDataAtom(uint64_t Begin, uint64_t End) {
43  MCDataAtom *NewAtom = new MCDataAtom(this, Begin, End);
44  map(NewAtom);
45  return NewAtom;
46}
47
48// remap - Update the interval mapping for an atom.
49void MCModule::remap(MCAtom *Atom, uint64_t NewBegin, uint64_t NewEnd) {
50  // Find and erase the old mapping.
51  AtomListTy::iterator I = std::lower_bound(atom_begin(), atom_end(),
52                                            Atom->Begin, AtomComp);
53  assert(I != atom_end() && "Atom offset not found in module!");
54  assert(*I == Atom && "Previous atom mapping was invalid!");
55  Atoms.erase(I);
56
57  // Insert the new mapping.
58  AtomListTy::iterator NewI = std::lower_bound(atom_begin(), atom_end(),
59                                               NewBegin, AtomComp);
60  Atoms.insert(NewI, Atom);
61
62  // Update the atom internal bounds.
63  Atom->Begin = NewBegin;
64  Atom->End = NewEnd;
65}
66
67const MCAtom *MCModule::findAtomContaining(uint64_t Addr) const {
68  AtomListTy::const_iterator I = std::lower_bound(atom_begin(), atom_end(),
69                                                  Addr, AtomComp);
70  if (I != atom_end() && (*I)->getBeginAddr() <= Addr)
71    return *I;
72  return 0;
73}
74
75MCAtom *MCModule::findAtomContaining(uint64_t Addr) {
76  AtomListTy::iterator I = std::lower_bound(atom_begin(), atom_end(),
77                                            Addr, AtomComp);
78  if (I != atom_end() && (*I)->getBeginAddr() <= Addr)
79    return *I;
80  return 0;
81}
82
83MCFunction *MCModule::createFunction(const StringRef &Name) {
84  Functions.push_back(new MCFunction(Name));
85  return Functions.back();
86}
87
88MCModule::~MCModule() {
89  for (AtomListTy::iterator AI = atom_begin(),
90                            AE = atom_end();
91                            AI != AE; ++AI)
92    delete *AI;
93  for (FunctionListTy::iterator FI = func_begin(),
94                                FE = func_end();
95                                FI != FE; ++FI)
96    delete *FI;
97}
98