• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- lib/MC/MCAtom.cpp - MCAtom 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/MCAtom.h"
11 #include "llvm/MC/MCModule.h"
12 #include "llvm/Support/ErrorHandling.h"
13 
14 using namespace llvm;
15 
addInst(const MCInst & I,uint64_t Address,unsigned Size)16 void MCAtom::addInst(const MCInst &I, uint64_t Address, unsigned Size) {
17   assert(Type == TextAtom && "Trying to add MCInst to a non-text atom!");
18 
19   assert(Address < End+Size &&
20          "Instruction not contiguous with end of atom!");
21   if (Address > End)
22     Parent->remap(this, Begin, End+Size);
23 
24   Text.push_back(std::make_pair(Address, I));
25 }
26 
addData(const MCData & D)27 void MCAtom::addData(const MCData &D) {
28   assert(Type == DataAtom && "Trying to add MCData to a non-data atom!");
29   Parent->remap(this, Begin, End+1);
30 
31   Data.push_back(D);
32 }
33 
split(uint64_t SplitPt)34 MCAtom *MCAtom::split(uint64_t SplitPt) {
35   assert((SplitPt > Begin && SplitPt <= End) &&
36          "Splitting at point not contained in atom!");
37 
38   // Compute the new begin/end points.
39   uint64_t LeftBegin = Begin;
40   uint64_t LeftEnd = SplitPt - 1;
41   uint64_t RightBegin = SplitPt;
42   uint64_t RightEnd = End;
43 
44   // Remap this atom to become the lower of the two new ones.
45   Parent->remap(this, LeftBegin, LeftEnd);
46 
47   // Create a new atom for the higher atom.
48   MCAtom *RightAtom = Parent->createAtom(Type, RightBegin, RightEnd);
49 
50   // Split the contents of the original atom between it and the new one.  The
51   // precise method depends on whether this is a data or a text atom.
52   if (isDataAtom()) {
53     std::vector<MCData>::iterator I = Data.begin() + (RightBegin - LeftBegin);
54 
55     assert(I != Data.end() && "Split point not found in range!");
56 
57     std::copy(I, Data.end(), RightAtom->Data.end());
58     Data.erase(I, Data.end());
59   } else if (isTextAtom()) {
60     std::vector<std::pair<uint64_t, MCInst> >::iterator I = Text.begin();
61 
62     while (I != Text.end() && I->first < SplitPt) ++I;
63 
64     assert(I != Text.end() && "Split point not found in disassembly!");
65     assert(I->first == SplitPt &&
66            "Split point does not fall on instruction boundary!");
67 
68     std::copy(I, Text.end(), RightAtom->Text.end());
69     Text.erase(I, Text.end());
70   } else
71     llvm_unreachable("Unknown atom type!");
72 
73   return RightAtom;
74 }
75 
truncate(uint64_t TruncPt)76 void MCAtom::truncate(uint64_t TruncPt) {
77   assert((TruncPt >= Begin && TruncPt < End) &&
78          "Truncation point not contained in atom!");
79 
80   Parent->remap(this, Begin, TruncPt);
81 
82   if (isDataAtom()) {
83     Data.resize(TruncPt - Begin + 1);
84   } else if (isTextAtom()) {
85     std::vector<std::pair<uint64_t, MCInst> >::iterator I = Text.begin();
86 
87     while (I != Text.end() && I->first <= TruncPt) ++I;
88 
89     assert(I != Text.end() && "Truncation point not found in disassembly!");
90     assert(I->first == TruncPt+1 &&
91            "Truncation point does not fall on instruction boundary");
92 
93     Text.erase(I, Text.end());
94   } else
95     llvm_unreachable("Unknown atom type!");
96 }
97 
98