本文整理汇总了C++中LDSymbol类的典型用法代码示例。如果您正苦于以下问题:C++ LDSymbol类的具体用法?C++ LDSymbol怎么用?C++ LDSymbol使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了LDSymbol类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: switch
void IdenticalCodeFolding::findCandidates(FoldingCandidates& pCandidateList) {
Module::obj_iterator obj, objEnd = m_Module.obj_end();
for (obj = m_Module.obj_begin(); obj != objEnd; ++obj) {
std::set<const LDSection*> funcptr_access_set;
typedef std::map<LDSection*, LDSection*> CandidateMap;
CandidateMap candidate_map;
LDContext::sect_iterator sect, sectEnd = (*obj)->context()->sectEnd();
for (sect = (*obj)->context()->sectBegin(); sect != sectEnd; ++sect) {
switch ((*sect)->kind()) {
case LDFileFormat::TEXT: {
candidate_map.insert(
std::make_pair(*sect, reinterpret_cast<LDSection*>(NULL)));
break;
}
case LDFileFormat::Relocation: {
LDSection* target = (*sect)->getLink();
if (target->kind() == LDFileFormat::TEXT) {
candidate_map[target] = *sect;
}
// Safe icf
if (m_Config.options().getICFMode() == GeneralOptions::ICF::Safe) {
RelocData::iterator rel, relEnd = (*sect)->getRelocData()->end();
for (rel = (*sect)->getRelocData()->begin(); rel != relEnd; ++rel) {
LDSymbol* sym = rel->symInfo()->outSymbol();
if (sym->hasFragRef() && (sym->type() == ResolveInfo::Function)) {
const LDSection* def =
&sym->fragRef()->frag()->getParent()->getSection();
if (!isSymCtorOrDtor(*rel->symInfo()) &&
m_Backend.mayHaveUnsafeFunctionPointerAccess(*target) &&
m_Backend.getRelocator()
->mayHaveFunctionPointerAccess(*rel)) {
funcptr_access_set.insert(def);
}
}
} // for each reloc
}
break;
}
default: {
// skip
break;
}
} // end of switch
} // for each section
CandidateMap::iterator candidate, candidateEnd = candidate_map.end();
for (candidate = candidate_map.begin(); candidate != candidateEnd;
++candidate) {
if ((m_Config.options().getICFMode() == GeneralOptions::ICF::All) ||
(funcptr_access_set.count(candidate->first) == 0)) {
size_t index = m_KeptSections.size();
m_KeptSections[candidate->first] = ObjectAndId(*obj, index);
pCandidateList.push_back(
FoldingCandidate(candidate->first, candidate->second, *obj));
}
} // for each possible candidate
} // for each obj
}
示例2: get
bool SectionSymbolSet::finalize(LDSection& pOutSect,
SymbolTable& pSymTab, bool relocatable)
{
if (!relocatable && pOutSect.size() == 0)
return true;
LDSymbol* sym = get(pOutSect);
assert(NULL != sym);
SectionData* data = NULL;
switch (pOutSect.kind()) {
case LDFileFormat::Relocation:
// Relocation section should not have section symbol.
return true;
case LDFileFormat::EhFrame:
if (EhFrame *ehframe = pOutSect.getEhFrame())
data = ehframe->getSectionData();
break;
default:
data = pOutSect.getSectionData();
break;
}
FragmentRef* frag_ref;
if (data && !data->empty())
frag_ref = FragmentRef::Create(data->front(), 0x0);
else
frag_ref = FragmentRef::Null();
sym->setFragmentRef(frag_ref);
// push symbol into output symbol table
pSymTab.add(*sym);
return true;
}
开发者ID:IllusionRom-deprecated,项目名称:android_platform_frameworks_compile_mclinker,代码行数:34,代码来源:SectionSymbolSet.cpp
示例3: sym_name
void Stub::applyFixup(Relocation& pSrcReloc,
IRBuilder& pBuilder,
BranchIsland& pIsland) {
// build a name for stub symbol
std::string sym_name("__");
sym_name.append(pSrcReloc.symInfo()->name())
.append("_")
.append(name())
.append("@")
.append(pIsland.name());
// create LDSymbol for the stub
LDSymbol* symbol =
pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
sym_name,
ResolveInfo::Function,
ResolveInfo::Define,
ResolveInfo::Local,
size(),
initSymValue(),
FragmentRef::Create(*this, initSymValue()),
ResolveInfo::Default);
setSymInfo(symbol->resolveInfo());
// add relocations of this stub (i.e., set the branch target of the stub)
for (fixup_iterator it = fixup_begin(), ie = fixup_end(); it != ie; ++it) {
Relocation* reloc =
Relocation::Create((*it)->type(),
*(FragmentRef::Create(*this, (*it)->offset())),
(*it)->addend());
reloc->setSymInfo(pSrcReloc.symInfo());
pIsland.addRelocation(*reloc);
}
}
示例4: relaxRelocation
bool MipsGNULDBackend::relaxRelocation(IRBuilder& pBuilder, Relocation& pRel) {
uint64_t sym_value = 0x0;
LDSymbol* symbol = pRel.symInfo()->outSymbol();
if (symbol->hasFragRef()) {
uint64_t value = symbol->fragRef()->getOutputOffset();
uint64_t addr = symbol->fragRef()->frag()->getParent()->getSection().addr();
sym_value = addr + value;
}
Stub* stub = getStubFactory()->create(
pRel, sym_value, pBuilder, *getBRIslandFactory());
if (stub == NULL)
return false;
assert(stub->symInfo() != NULL);
// increase the size of .symtab and .strtab
LDSection& symtab = getOutputFormat()->getSymTab();
LDSection& strtab = getOutputFormat()->getStrTab();
symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym));
strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1);
return true;
}
示例5: assert
void GarbageCollection::getEntrySections(SectionVecTy& pEntry)
{
// all the KEEP sections defined in ldscript are entries, traverse all the
// input sections and check the SectionMap to find the KEEP sections
Module::obj_iterator obj, objEnd = m_Module.obj_end();
SectionMap& sect_map = m_Module.getScript().sectionMap();
for (obj = m_Module.obj_begin(); obj != objEnd; ++obj) {
const std::string input_name = (*obj)->name();
LDContext::sect_iterator sect, sectEnd = (*obj)->context()->sectEnd();
for (sect = (*obj)->context()->sectBegin(); sect != sectEnd; ++sect) {
LDSection* section = *sect;
if (LDFileFormat::Regular != section->kind() &&
LDFileFormat::BSS != section->kind())
continue;
SectionMap::Input* sm_input =
sect_map.find(input_name, section->name()).second;
if ((sm_input != NULL) && (InputSectDesc::Keep == sm_input->policy()))
pEntry.push_back(section);
}
}
// get the sections those the entry symbols defined in
Module::SymbolTable& sym_tab = m_Module.getSymbolTable();
if (LinkerConfig::Exec == m_Config.codeGenType()) {
assert(NULL != m_pEntry);
pEntry.push_back(&m_pEntry->fragRef()->frag()->getParent()->getSection());
}
else {
// when building shared objects, the global define symbols are entries
SymbolCategory::iterator it, end = sym_tab.regularEnd();
for (it = sym_tab.dynamicBegin(); it != end; ++it) {
LDSymbol* sym = *it;
if (!sym->resolveInfo()->isDefine() || !sym->hasFragRef())
continue;
// only the target symbols defined in the concerned sections can make
// the reference
const LDSection* sect =
&sym->fragRef()->frag()->getParent()->getSection();
if (sect->kind() != LDFileFormat::Regular &&
sect->kind() != LDFileFormat::BSS)
continue;
pEntry.push_back(sect);
}
}
}
示例6: result
std::string IdenticalCodeFolding::FoldingCandidate::getContentWithVariables(
const TargetLDBackend& pBackend,
const IdenticalCodeFolding::KeptSections& pKeptSections) {
std::string result(content);
// Compute the variable content from relocs.
std::vector<Relocation*>::const_iterator rel, relEnd = variable_relocs.end();
for (rel = variable_relocs.begin(); rel != relEnd; ++rel) {
LDSymbol* sym = (*rel)->symInfo()->outSymbol();
LDSection* def = &sym->fragRef()->frag()->getParent()->getSection();
// Use the kept section index.
KeptSections::const_iterator it = pKeptSections.find(def);
llvm::format_object<size_t> kept_info("%x", (*it).second.second);
char kept_str[8];
kept_info.print(kept_str, sizeof(kept_str));
result.append(kept_str);
}
return result;
}
示例7: updateAddend
void ARMGNULDBackend::updateAddend(Relocation& pReloc,
const LDSymbol& pInputSym,
const Layout& pLayout) const
{
// Update value keep in addend if we meet a section symbol
if(pReloc.symInfo()->type() == ResolveInfo::Section) {
pReloc.setAddend(pLayout.getOutputOffset(
*pInputSym.fragRef()) + pReloc.addend());
}
}
示例8: findPrototype
/// create - create a stub if needed, otherwise return NULL
Stub* StubFactory::create(Relocation& pReloc,
uint64_t pTargetSymValue,
IRBuilder& pBuilder,
BranchIslandFactory& pBRIslandFactory)
{
// find if there is a prototype stub for the input relocation
Stub* prototype = findPrototype(pReloc,
pReloc.place(),
pTargetSymValue);
if (NULL != prototype) {
// find the island for the input relocation
BranchIsland* island = pBRIslandFactory.find(*(pReloc.targetRef().frag()));
if (NULL == island) {
island = pBRIslandFactory.produce(*(pReloc.targetRef().frag()));
}
// find if there is such a stub in the island already
assert(NULL != island);
Stub* stub = island->findStub(prototype, pReloc);
if (NULL != stub) {
// reset the branch target to the stub instead!
pReloc.setSymInfo(stub->symInfo());
}
else {
// create a stub from the prototype
stub = prototype->clone();
// build a name for stub symbol
std::string name("__");
name.append(pReloc.symInfo()->name());
name.append("_");
name.append(stub->name());
name.append("@");
name.append(island->name());
// create LDSymbol for the stub
LDSymbol* symbol =
pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Resolve>(
name,
ResolveInfo::Function,
ResolveInfo::Define,
ResolveInfo::Local,
stub->size(), // size
stub->initSymValue(), // value
FragmentRef::Create(*stub, stub->initSymValue()),
ResolveInfo::Default);
stub->setSymInfo(symbol->resolveInfo());
// add relocations of this stub (i.e., set the branch target of the stub)
for (Stub::fixup_iterator it = stub->fixup_begin(),
ie = stub->fixup_end(); it != ie; ++it) {
Relocation* reloc = Relocation::Create((*it)->type(),
*(FragmentRef::Create(*stub, (*it)->offset())),
(*it)->addend());
reloc->setSymInfo(pReloc.symInfo());
island->addRelocation(*reloc);
}
// add stub to the branch island
island->addStub(prototype, pReloc, *stub);
// reset the branch target of the input reloc to this stub instead!
pReloc.setSymInfo(stub->symInfo());
return stub;
}
}
return NULL;
}
开发者ID:IllusionRom-deprecated,项目名称:android_platform_frameworks_compile_mclinker,代码行数:70,代码来源:StubFactory.cpp
示例9: assert
void IdenticalCodeFolding::FoldingCandidate::initConstantContent(
const TargetLDBackend& pBackend,
const IdenticalCodeFolding::KeptSections& pKeptSections) {
// Get the static content from text.
assert(sect != NULL && sect->hasSectionData());
SectionData::const_iterator frag, fragEnd = sect->getSectionData()->end();
for (frag = sect->getSectionData()->begin(); frag != fragEnd; ++frag) {
switch (frag->getKind()) {
case Fragment::Region: {
const RegionFragment& region = llvm::cast<RegionFragment>(*frag);
content.append(region.getRegion().begin(), region.size());
break;
}
default: {
// FIXME: Currently we only take care of RegionFragment.
break;
}
}
}
// Get the static content from relocs.
if (reloc_sect != NULL && reloc_sect->hasRelocData()) {
for (Relocation& rel : *reloc_sect->getRelocData()) {
llvm::format_object<Relocation::Type,
Relocation::Address,
Relocation::Address,
Relocation::Address> rel_info("%x%llx%llx%llx",
rel.type(),
rel.symValue(),
rel.addend(),
rel.place());
char rel_str[48];
rel_info.print(rel_str, sizeof(rel_str));
content.append(rel_str);
// Handle the recursive call.
LDSymbol* sym = rel.symInfo()->outSymbol();
if ((sym->type() == ResolveInfo::Function) && sym->hasFragRef()) {
LDSection* def = &sym->fragRef()->frag()->getParent()->getSection();
if (def == sect) {
continue;
}
}
if (!pBackend.isSymbolPreemptible(*rel.symInfo()) && sym->hasFragRef() &&
(pKeptSections.find(
&sym->fragRef()->frag()->getParent()->getSection()) !=
pKeptSections.end())) {
// Mark this reloc as a variable.
variable_relocs.push_back(&rel);
} else {
// TODO: Support inlining merge sections if possible (target-dependent).
if ((sym->binding() == ResolveInfo::Local) ||
(sym->binding() == ResolveInfo::Absolute)) {
// ABS or Local symbols.
content.append(sym->name()).append(obj->name()).append(
obj->path().native());
} else {
content.append(sym->name());
}
}
}
}
}
示例10: hasEntryInStrTab
bool MipsGNULDBackend::hasEntryInStrTab(const LDSymbol& pSym) const {
return ResolveInfo::Section != pSym.type() || m_pGpDispSymbol == &pSym;
}
示例11: assert
bool AArch64GNULDBackend::doRelax(Module& pModule,
IRBuilder& pBuilder,
bool& pFinished) {
assert(getStubFactory() != NULL && getBRIslandFactory() != NULL);
// Number of new stubs added
size_t num_new_stubs = 0;
// String lengh to hold new stub symbols
size_t stubs_strlen = 0;
if (config().targets().fixCA53Erratum835769() ||
config().targets().fixCA53Erratum843419()) {
scanErrata(pModule, pBuilder, num_new_stubs, stubs_strlen);
}
ELFFileFormat* file_format = getOutputFormat();
// check branch relocs and create the related stubs if needed
Module::obj_iterator input, inEnd = pModule.obj_end();
for (input = pModule.obj_begin(); input != inEnd; ++input) {
LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
continue;
RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
Relocation* relocation = llvm::cast<Relocation>(reloc);
switch (relocation->type()) {
case llvm::ELF::R_AARCH64_CALL26:
case llvm::ELF::R_AARCH64_JUMP26: {
// calculate the possible symbol value
uint64_t sym_value = 0x0;
LDSymbol* symbol = relocation->symInfo()->outSymbol();
if (symbol->hasFragRef()) {
uint64_t value = symbol->fragRef()->getOutputOffset();
uint64_t addr =
symbol->fragRef()->frag()->getParent()->getSection().addr();
sym_value = addr + value;
}
if ((relocation->symInfo()->reserved() &
AArch64Relocator::ReservePLT) != 0x0) {
// FIXME: we need to find out the address of the specific plt
// entry
assert(file_format->hasPLT());
sym_value = file_format->getPLT().addr();
}
Stub* stub = getStubFactory()->create(*relocation, // relocation
sym_value, // symbol value
pBuilder,
*getBRIslandFactory());
if (stub != NULL) {
// a stub symbol should be local
assert(stub->symInfo() != NULL && stub->symInfo()->isLocal());
// reset the branch target of the reloc to this stub instead
relocation->setSymInfo(stub->symInfo());
++num_new_stubs;
stubs_strlen += stub->symInfo()->nameSize() + 1;
}
break;
}
default: {
break;
}
} // end of switch
} // for all relocations
} // for all relocation section
} // for all inputs
// Find the first fragment w/ invalid offset due to stub insertion.
std::vector<Fragment*> invalid_frags;
pFinished = true;
for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(),
island_end = getBRIslandFactory()->end();
island != island_end;
++island) {
if ((*island).size() > stubGroupSize()) {
error(diag::err_no_space_to_place_stubs) << stubGroupSize();
return false;
}
if ((*island).numOfStubs() == 0) {
continue;
}
Fragment* exit = &*(*island).end();
if (exit == (*island).begin()->getParent()->end()) {
continue;
}
if (((*island).offset() + (*island).size()) > exit->getOffset()) {
if (invalid_frags.empty() ||
(invalid_frags.back()->getParent() != (*island).getParent())) {
invalid_frags.push_back(exit);
pFinished = false;
}
continue;
}
}
//.........这里部分代码省略.........
示例12: new
LDSymbol* LDSymbol::Create(ResolveInfo& pResolveInfo) {
LDSymbol* result = g_LDSymbolFactory->allocate();
new (result) LDSymbol();
result->setResolveInfo(pResolveInfo);
return result;
}
示例13: assert
bool HexagonLDBackend::doRelax(Module& pModule, IRBuilder& pBuilder,
bool& pFinished)
{
assert(NULL != getStubFactory() && NULL != getBRIslandFactory());
bool isRelaxed = false;
ELFFileFormat* file_format = getOutputFormat();
// check branch relocs and create the related stubs if needed
Module::obj_iterator input, inEnd = pModule.obj_end();
for (input = pModule.obj_begin(); input != inEnd; ++input) {
LDContext::sect_iterator rs, rsEnd = (*input)->context()->relocSectEnd();
for (rs = (*input)->context()->relocSectBegin(); rs != rsEnd; ++rs) {
if (LDFileFormat::Ignore == (*rs)->kind() || !(*rs)->hasRelocData())
continue;
RelocData::iterator reloc, rEnd = (*rs)->getRelocData()->end();
for (reloc = (*rs)->getRelocData()->begin(); reloc != rEnd; ++reloc) {
switch (reloc->type()) {
case llvm::ELF::R_HEX_B22_PCREL:
case llvm::ELF::R_HEX_B15_PCREL:
case llvm::ELF::R_HEX_B7_PCREL:
case llvm::ELF::R_HEX_B13_PCREL:
case llvm::ELF::R_HEX_B9_PCREL: {
Relocation* relocation = llvm::cast<Relocation>(reloc);
uint64_t sym_value = 0x0;
LDSymbol* symbol = relocation->symInfo()->outSymbol();
if (symbol->hasFragRef()) {
uint64_t value = symbol->fragRef()->getOutputOffset();
uint64_t addr =
symbol->fragRef()->frag()->getParent()->getSection().addr();
sym_value = addr + value;
}
Stub* stub = getStubFactory()->create(*relocation, // relocation
sym_value, //symbol value
pBuilder,
*getBRIslandFactory());
if (NULL != stub) {
assert(NULL != stub->symInfo());
// increase the size of .symtab and .strtab
LDSection& symtab = file_format->getSymTab();
LDSection& strtab = file_format->getStrTab();
symtab.setSize(symtab.size() + sizeof(llvm::ELF::Elf32_Sym));
strtab.setSize(strtab.size() + stub->symInfo()->nameSize() + 1);
isRelaxed = true;
}
}
break;
default:
break;
}
}
}
}
// find the first fragment w/ invalid offset due to stub insertion
Fragment* invalid = NULL;
pFinished = true;
for (BranchIslandFactory::iterator island = getBRIslandFactory()->begin(),
island_end = getBRIslandFactory()->end(); island != island_end; ++island)
{
if ((*island).end() == file_format->getText().getSectionData()->end())
break;
Fragment* exit = (*island).end();
if (((*island).offset() + (*island).size()) > exit->getOffset()) {
invalid = exit;
pFinished = false;
break;
}
}
// reset the offset of invalid fragments
while (NULL != invalid) {
invalid->setOffset(invalid->getPrevNode()->getOffset() +
invalid->getPrevNode()->size());
invalid = invalid->getNextNode();
}
// reset the size of .text
if (isRelaxed) {
file_format->getText().setSize(
file_format->getText().getSectionData()->back().getOffset() +
file_format->getText().getSectionData()->back().size());
}
return isRelaxed;
}
示例14: scanLocalReloc
void ARMGNULDBackend::scanLocalReloc(Relocation& pReloc,
const LDSymbol& pInputSym,
MCLinker& pLinker,
const MCLDInfo& pLDInfo,
const Output& pOutput)
{
// rsym - The relocation target symbol
ResolveInfo* rsym = pReloc.symInfo();
updateAddend(pReloc, pInputSym, pLinker.getLayout());
switch(pReloc.type()){
// Set R_ARM_TARGET1 to R_ARM_ABS32
// Ref: GNU gold 1.11 arm.cc, line 9892
case llvm::ELF::R_ARM_TARGET1:
pReloc.setType(llvm::ELF::R_ARM_ABS32);
case llvm::ELF::R_ARM_ABS32:
case llvm::ELF::R_ARM_ABS32_NOI: {
// If buiding PIC object (shared library or PIC executable),
// a dynamic relocations with RELATIVE type to this location is needed.
// Reserve an entry in .rel.dyn
if(isPIC(pLDInfo, pOutput)) {
// create .rel.dyn section if not exist
if(NULL == m_pRelDyn)
createARMRelDyn(pLinker, pOutput);
m_pRelDyn->reserveEntry(*m_pRelocFactory);
// set Rel bit
rsym->setReserved(rsym->reserved() | 0x1u);
}
return;
}
case llvm::ELF::R_ARM_ABS16:
case llvm::ELF::R_ARM_ABS12:
case llvm::ELF::R_ARM_THM_ABS5:
case llvm::ELF::R_ARM_ABS8:
case llvm::ELF::R_ARM_BASE_ABS:
case llvm::ELF::R_ARM_MOVW_ABS_NC:
case llvm::ELF::R_ARM_MOVT_ABS:
case llvm::ELF::R_ARM_THM_MOVW_ABS_NC:
case llvm::ELF::R_ARM_THM_MOVT_ABS: {
// Update value keep in relocation place if we meet a section symbol
if(rsym->type() == ResolveInfo::Section) {
pReloc.target() = pLinker.getLayout().getOutputOffset(
*pInputSym.fragRef()) + pReloc.target();
}
// If building PIC object (shared library or PIC executable),
// a dynamic relocation for this location is needed.
// Reserve an entry in .rel.dyn
if(isPIC(pLDInfo, pOutput)) {
checkValidReloc(pReloc, pLDInfo, pOutput);
// create .rel.dyn section if not exist
if(NULL == m_pRelDyn)
createARMRelDyn(pLinker, pOutput);
m_pRelDyn->reserveEntry(*m_pRelocFactory);
// set Rel bit
rsym->setReserved(rsym->reserved() | 0x1u);
}
return;
}
case llvm::ELF::R_ARM_GOTOFF32:
case llvm::ELF::R_ARM_GOTOFF12: {
// A GOT section is needed
if(NULL == m_pGOT)
createARMGOT(pLinker, pOutput);
return;
}
// Set R_ARM_TARGET2 to R_ARM_GOT_PREL
// Ref: GNU gold 1.11 arm.cc, line 9892
case llvm::ELF::R_ARM_TARGET2:
pReloc.setType(llvm::ELF::R_ARM_GOT_PREL);
case llvm::ELF::R_ARM_GOT_BREL:
case llvm::ELF::R_ARM_GOT_PREL: {
// A GOT entry is needed for these relocation type.
// return if we already create GOT for this symbol
if(rsym->reserved() & 0x6u)
return;
if(NULL == m_pGOT)
createARMGOT(pLinker, pOutput);
m_pGOT->reserveEntry();
// If building PIC object, a dynamic relocation with
// type RELATIVE is needed to relocate this GOT entry.
// Reserve an entry in .rel.dyn
if(isPIC(pLDInfo, pOutput)) {
// create .rel.dyn section if not exist
if(NULL == m_pRelDyn)
createARMRelDyn(pLinker, pOutput);
m_pRelDyn->reserveEntry(*m_pRelocFactory);
// set GOTRel bit
rsym->setReserved(rsym->reserved() | 0x4u);
return;
}
// set GOT bit
rsym->setReserved(rsym->reserved() | 0x2u);
return;
}
//.........这里部分代码省略.........
示例15: findPrototype
/// create - create a stub if needed, otherwise return NULL
Stub* StubFactory::create(Relocation& pReloc,
uint64_t pTargetSymValue,
IRBuilder& pBuilder,
BranchIslandFactory& pBRIslandFactory) {
// find if there is a prototype stub for the input relocation
Stub* stub = NULL;
Stub* prototype = findPrototype(pReloc, pReloc.place(), pTargetSymValue);
if (prototype != NULL) {
const Fragment* frag = pReloc.targetRef().frag();
// find the islands for the input relocation
std::pair<BranchIsland*, BranchIsland*> islands =
pBRIslandFactory.getIslands(*frag);
if (islands.first == NULL) {
// early exit if we can not find the forward island.
return NULL;
}
// find if there is such a stub in the backward island first.
if (islands.second != NULL) {
stub = islands.second->findStub(prototype, pReloc);
}
if (stub != NULL) {
// reset the branch target to the stub instead!
pReloc.setSymInfo(stub->symInfo());
} else {
// find if there is such a stub in the forward island.
stub = islands.first->findStub(prototype, pReloc);
if (stub != NULL) {
// reset the branch target to the stub instead!
pReloc.setSymInfo(stub->symInfo());
} else {
// create a stub from the prototype
stub = prototype->clone();
// build a name for stub symbol
std::string name("__");
name.append(pReloc.symInfo()->name())
.append("_")
.append(stub->name())
.append("@")
.append(islands.first->name());
// create LDSymbol for the stub
LDSymbol* symbol =
pBuilder.AddSymbol<IRBuilder::Force, IRBuilder::Unresolve>(
name,
ResolveInfo::Function,
ResolveInfo::Define,
ResolveInfo::Local,
stub->size(), // size
stub->initSymValue(), // value
FragmentRef::Create(*stub, stub->initSymValue()),
ResolveInfo::Default);
stub->setSymInfo(symbol->resolveInfo());
// add relocations of this stub (i.e., set the branch target of the
// stub)
for (Stub::fixup_iterator it = stub->fixup_begin(),
ie = stub->fixup_end();
it != ie;
++it) {
Relocation* reloc =
Relocation::Create((*it)->type(),
*(FragmentRef::Create(*stub, (*it)->offset())),
(*it)->addend());
reloc->setSymInfo(pReloc.symInfo());
islands.first->addRelocation(*reloc);
}
// add stub to the forward branch island
islands.first->addStub(prototype, pReloc, *stub);
// reset the branch target of the input reloc to this stub instead!
pReloc.setSymInfo(stub->symInfo());
}
}
}
return stub;
}