You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
6.0 KiB
208 lines
6.0 KiB
//===- Operand.cpp --------------------------------------------------------===//
|
|
//
|
|
// The MCLinker Project
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#include "mcld/Script/Operand.h"
|
|
|
|
#include "mcld/Fragment/Fragment.h"
|
|
#include "mcld/LD/LDSection.h"
|
|
#include "mcld/LD/SectionData.h"
|
|
#include "mcld/Support/GCFactory.h"
|
|
#include "mcld/Support/raw_ostream.h"
|
|
|
|
#include <llvm/Support/ManagedStatic.h>
|
|
|
|
namespace mcld {
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Operand
|
|
//===----------------------------------------------------------------------===//
|
|
Operand::Operand(Type pType) : ExprToken(ExprToken::OPERAND), m_Type(pType) {
|
|
}
|
|
|
|
Operand::~Operand() {
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// SymOperand
|
|
//===----------------------------------------------------------------------===//
|
|
typedef GCFactory<SymOperand, MCLD_SYMBOLS_PER_INPUT> SymOperandFactory;
|
|
static llvm::ManagedStatic<SymOperandFactory> g_SymOperandFactory;
|
|
|
|
SymOperand::SymOperand() : Operand(Operand::SYMBOL), m_Value(0) {
|
|
}
|
|
|
|
SymOperand::SymOperand(const std::string& pName)
|
|
: Operand(Operand::SYMBOL), m_Name(pName), m_Value(0) {
|
|
}
|
|
|
|
void SymOperand::dump() const {
|
|
mcld::outs() << m_Name;
|
|
}
|
|
|
|
bool SymOperand::isDot() const {
|
|
assert(!m_Name.empty());
|
|
return m_Name.size() == 1 && m_Name[0] == '.';
|
|
}
|
|
|
|
SymOperand* SymOperand::create(const std::string& pName) {
|
|
SymOperand* result = g_SymOperandFactory->allocate();
|
|
new (result) SymOperand(pName);
|
|
return result;
|
|
}
|
|
|
|
void SymOperand::destroy(SymOperand*& pOperand) {
|
|
g_SymOperandFactory->destroy(pOperand);
|
|
g_SymOperandFactory->deallocate(pOperand);
|
|
pOperand = NULL;
|
|
}
|
|
|
|
void SymOperand::clear() {
|
|
g_SymOperandFactory->clear();
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// IntOperand
|
|
//===----------------------------------------------------------------------===//
|
|
typedef GCFactory<IntOperand, MCLD_SYMBOLS_PER_INPUT> IntOperandFactory;
|
|
static llvm::ManagedStatic<IntOperandFactory> g_IntOperandFactory;
|
|
|
|
IntOperand::IntOperand() : Operand(Operand::INTEGER), m_Value(0) {
|
|
}
|
|
|
|
IntOperand::IntOperand(uint64_t pValue)
|
|
: Operand(Operand::INTEGER), m_Value(pValue) {
|
|
}
|
|
|
|
void IntOperand::dump() const {
|
|
mcld::outs() << m_Value;
|
|
}
|
|
|
|
IntOperand* IntOperand::create(uint64_t pValue) {
|
|
IntOperand* result = g_IntOperandFactory->allocate();
|
|
new (result) IntOperand(pValue);
|
|
return result;
|
|
}
|
|
|
|
void IntOperand::destroy(IntOperand*& pOperand) {
|
|
g_IntOperandFactory->destroy(pOperand);
|
|
g_IntOperandFactory->deallocate(pOperand);
|
|
pOperand = NULL;
|
|
}
|
|
|
|
void IntOperand::clear() {
|
|
g_IntOperandFactory->clear();
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// SectOperand
|
|
//===----------------------------------------------------------------------===//
|
|
typedef GCFactory<SectOperand, MCLD_SECTIONS_PER_INPUT> SectOperandFactory;
|
|
static llvm::ManagedStatic<SectOperandFactory> g_SectOperandFactory;
|
|
SectOperand::SectOperand() : Operand(Operand::SECTION) {
|
|
}
|
|
|
|
SectOperand::SectOperand(const std::string& pName)
|
|
: Operand(Operand::SECTION), m_Name(pName) {
|
|
}
|
|
|
|
void SectOperand::dump() const {
|
|
mcld::outs() << m_Name;
|
|
}
|
|
|
|
SectOperand* SectOperand::create(const std::string& pName) {
|
|
SectOperand* result = g_SectOperandFactory->allocate();
|
|
new (result) SectOperand(pName);
|
|
return result;
|
|
}
|
|
|
|
void SectOperand::destroy(SectOperand*& pOperand) {
|
|
g_SectOperandFactory->destroy(pOperand);
|
|
g_SectOperandFactory->deallocate(pOperand);
|
|
pOperand = NULL;
|
|
}
|
|
|
|
void SectOperand::clear() {
|
|
g_SectOperandFactory->clear();
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// SectDescOperand
|
|
//===----------------------------------------------------------------------===//
|
|
typedef GCFactory<SectDescOperand, MCLD_SECTIONS_PER_INPUT>
|
|
SectDescOperandFactory;
|
|
static llvm::ManagedStatic<SectDescOperandFactory> g_SectDescOperandFactory;
|
|
SectDescOperand::SectDescOperand()
|
|
: Operand(Operand::SECTION_DESC), m_pOutputDesc(NULL) {
|
|
}
|
|
|
|
SectDescOperand::SectDescOperand(const SectionMap::Output* pOutputDesc)
|
|
: Operand(Operand::SECTION_DESC), m_pOutputDesc(pOutputDesc) {
|
|
}
|
|
|
|
void SectDescOperand::dump() const {
|
|
assert(m_pOutputDesc != NULL);
|
|
mcld::outs() << m_pOutputDesc->getSection()->name();
|
|
}
|
|
|
|
SectDescOperand* SectDescOperand::create(
|
|
const SectionMap::Output* pOutputDesc) {
|
|
SectDescOperand* result = g_SectDescOperandFactory->allocate();
|
|
new (result) SectDescOperand(pOutputDesc);
|
|
return result;
|
|
}
|
|
|
|
void SectDescOperand::destroy(SectDescOperand*& pOperand) {
|
|
g_SectDescOperandFactory->destroy(pOperand);
|
|
g_SectDescOperandFactory->deallocate(pOperand);
|
|
pOperand = NULL;
|
|
}
|
|
|
|
void SectDescOperand::clear() {
|
|
g_SectDescOperandFactory->clear();
|
|
}
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// FragOperand
|
|
//===----------------------------------------------------------------------===//
|
|
typedef GCFactory<FragOperand, MCLD_SYMBOLS_PER_INPUT> FragOperandFactory;
|
|
static llvm::ManagedStatic<FragOperandFactory> g_FragOperandFactory;
|
|
|
|
FragOperand::FragOperand() : Operand(Operand::FRAGMENT), m_pFragment(NULL) {
|
|
}
|
|
|
|
FragOperand::FragOperand(Fragment& pFragment)
|
|
: Operand(Operand::FRAGMENT), m_pFragment(&pFragment) {
|
|
}
|
|
|
|
void FragOperand::dump() const {
|
|
mcld::outs() << "fragment";
|
|
}
|
|
|
|
uint64_t FragOperand::value() const {
|
|
return m_pFragment->getOffset() +
|
|
m_pFragment->getParent()->getSection().addr();
|
|
}
|
|
|
|
FragOperand* FragOperand::create(Fragment& pFragment) {
|
|
FragOperand* result = g_FragOperandFactory->allocate();
|
|
new (result) FragOperand(pFragment);
|
|
return result;
|
|
}
|
|
|
|
void FragOperand::destroy(FragOperand*& pOperand) {
|
|
g_FragOperandFactory->destroy(pOperand);
|
|
g_FragOperandFactory->deallocate(pOperand);
|
|
pOperand = NULL;
|
|
}
|
|
|
|
void FragOperand::clear() {
|
|
g_FragOperandFactory->clear();
|
|
}
|
|
|
|
} // namespace mcld
|