98 lines
3.0 KiB
C++
98 lines
3.0 KiB
C++
//===- lib/MC/MCAtom.cpp - MCAtom implementation --------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/MC/MCAtom.h"
|
|
#include "llvm/MC/MCModule.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
using namespace llvm;
|
|
|
|
void MCAtom::addInst(const MCInst &I, uint64_t Address, unsigned Size) {
|
|
assert(Type == TextAtom && "Trying to add MCInst to a non-text atom!");
|
|
|
|
assert(Address < End+Size &&
|
|
"Instruction not contiguous with end of atom!");
|
|
if (Address > End)
|
|
Parent->remap(this, Begin, End+Size);
|
|
|
|
Text.push_back(std::make_pair(Address, I));
|
|
}
|
|
|
|
void MCAtom::addData(const MCData &D) {
|
|
assert(Type == DataAtom && "Trying to add MCData to a non-data atom!");
|
|
Parent->remap(this, Begin, End+1);
|
|
|
|
Data.push_back(D);
|
|
}
|
|
|
|
MCAtom *MCAtom::split(uint64_t SplitPt) {
|
|
assert((SplitPt > Begin && SplitPt <= End) &&
|
|
"Splitting at point not contained in atom!");
|
|
|
|
// Compute the new begin/end points.
|
|
uint64_t LeftBegin = Begin;
|
|
uint64_t LeftEnd = SplitPt - 1;
|
|
uint64_t RightBegin = SplitPt;
|
|
uint64_t RightEnd = End;
|
|
|
|
// Remap this atom to become the lower of the two new ones.
|
|
Parent->remap(this, LeftBegin, LeftEnd);
|
|
|
|
// Create a new atom for the higher atom.
|
|
MCAtom *RightAtom = Parent->createAtom(Type, RightBegin, RightEnd);
|
|
|
|
// Split the contents of the original atom between it and the new one. The
|
|
// precise method depends on whether this is a data or a text atom.
|
|
if (isDataAtom()) {
|
|
std::vector<MCData>::iterator I = Data.begin() + (RightBegin - LeftBegin);
|
|
|
|
assert(I != Data.end() && "Split point not found in range!");
|
|
|
|
std::copy(I, Data.end(), RightAtom->Data.end());
|
|
Data.erase(I, Data.end());
|
|
} else if (isTextAtom()) {
|
|
std::vector<std::pair<uint64_t, MCInst> >::iterator I = Text.begin();
|
|
|
|
while (I != Text.end() && I->first < SplitPt) ++I;
|
|
|
|
assert(I != Text.end() && "Split point not found in disassembly!");
|
|
assert(I->first == SplitPt &&
|
|
"Split point does not fall on instruction boundary!");
|
|
|
|
std::copy(I, Text.end(), RightAtom->Text.end());
|
|
Text.erase(I, Text.end());
|
|
} else
|
|
llvm_unreachable("Unknown atom type!");
|
|
|
|
return RightAtom;
|
|
}
|
|
|
|
void MCAtom::truncate(uint64_t TruncPt) {
|
|
assert((TruncPt >= Begin && TruncPt < End) &&
|
|
"Truncation point not contained in atom!");
|
|
|
|
Parent->remap(this, Begin, TruncPt);
|
|
|
|
if (isDataAtom()) {
|
|
Data.resize(TruncPt - Begin + 1);
|
|
} else if (isTextAtom()) {
|
|
std::vector<std::pair<uint64_t, MCInst> >::iterator I = Text.begin();
|
|
|
|
while (I != Text.end() && I->first <= TruncPt) ++I;
|
|
|
|
assert(I != Text.end() && "Truncation point not found in disassembly!");
|
|
assert(I->first == TruncPt+1 &&
|
|
"Truncation point does not fall on instruction boundary");
|
|
|
|
Text.erase(I, Text.end());
|
|
} else
|
|
llvm_unreachable("Unknown atom type!");
|
|
}
|
|
|