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.
92 lines
2.4 KiB
92 lines
2.4 KiB
//===- MipsLA25Stub.cpp ---------------------------------------------------===//
|
|
//
|
|
// The MCLinker Project
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#include "mcld/LD/ResolveInfo.h"
|
|
#include "MipsLA25Stub.h"
|
|
#include "MipsLDBackend.h"
|
|
|
|
namespace {
|
|
|
|
const uint32_t STUB[] = {
|
|
0x3c190000, // lui $25,%hi(func)
|
|
0x08000000, // j func
|
|
0x27390000, // add $25,$25,%lo(func)
|
|
0x00000000 // nop
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
namespace mcld {
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// MipsLA25Stub
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
MipsLA25Stub::MipsLA25Stub(const MipsGNULDBackend& pTarget)
|
|
: m_Target(pTarget),
|
|
m_Name("MipsLA25_Prototype"),
|
|
m_pData(STUB),
|
|
m_Size(sizeof(STUB)) {
|
|
addFixup(0, 0x0, llvm::ELF::R_MIPS_HI16);
|
|
addFixup(4, 0x0, llvm::ELF::R_MIPS_26);
|
|
addFixup(8, 0x0, llvm::ELF::R_MIPS_LO16);
|
|
}
|
|
|
|
MipsLA25Stub::MipsLA25Stub(const MipsGNULDBackend& pTarget,
|
|
const uint32_t* pData,
|
|
size_t pSize,
|
|
const_fixup_iterator pBegin,
|
|
const_fixup_iterator pEnd)
|
|
: m_Target(pTarget), m_Name("pic"), m_pData(pData), m_Size(pSize) {
|
|
for (const_fixup_iterator it = pBegin, ie = pEnd; it != ie; ++it)
|
|
addFixup(**it);
|
|
}
|
|
|
|
bool MipsLA25Stub::isMyDuty(const Relocation& pReloc,
|
|
uint64_t pSource,
|
|
uint64_t pTargetSymValue) const {
|
|
if (llvm::ELF::R_MIPS_26 != pReloc.type())
|
|
return false;
|
|
|
|
const ResolveInfo* rsym = pReloc.symInfo();
|
|
|
|
if (!rsym->isDefine())
|
|
return false;
|
|
|
|
if (rsym->isDyn() || rsym->isUndef())
|
|
return false;
|
|
|
|
if (!m_Target.hasNonPICBranch(rsym))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
const std::string& MipsLA25Stub::name() const {
|
|
return m_Name;
|
|
}
|
|
|
|
const uint8_t* MipsLA25Stub::getContent() const {
|
|
return reinterpret_cast<const uint8_t*>(m_pData);
|
|
}
|
|
|
|
size_t MipsLA25Stub::size() const {
|
|
return m_Size;
|
|
}
|
|
|
|
size_t MipsLA25Stub::alignment() const {
|
|
return 4;
|
|
}
|
|
|
|
Stub* MipsLA25Stub::doClone() {
|
|
return new MipsLA25Stub(
|
|
m_Target, m_pData, m_Size, fixup_begin(), fixup_end());
|
|
}
|
|
|
|
} // namespace mcld
|