Home | History | Annotate | Download | only in MC
      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 
     15 using namespace llvm;
     16 
     17 static bool AtomComp(const MCAtom *L, uint64_t Addr) {
     18   return L->getEndAddr() < Addr;
     19 }
     20 
     21 void 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 
     36 MCTextAtom *MCModule::createTextAtom(uint64_t Begin, uint64_t End) {
     37   MCTextAtom *NewAtom = new MCTextAtom(this, Begin, End);
     38   map(NewAtom);
     39   return NewAtom;
     40 }
     41 
     42 MCDataAtom *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.
     49 void 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 
     67 const 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 
     75 MCAtom *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 
     83 MCFunction *MCModule::createFunction(const StringRef &Name) {
     84   Functions.push_back(new MCFunction(Name));
     85   return Functions.back();
     86 }
     87 
     88 MCModule::~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