From: Daniel Dunbar Date: Fri, 19 Mar 2010 03:18:15 +0000 (+0000) Subject: MC/Mach-O/x86_64: Add getAtom[ForAddress]. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=8ad0dccbf2f0c5ecf9fdad93ac0207f6eaabaa1b;p=oota-llvm.git MC/Mach-O/x86_64: Add getAtom[ForAddress]. - These find the defining symbol which identifies the containing atom for a symbol or address. They are currently very slow, but will be eliminated eventually. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@98925 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 620b4f4ec21..4a2a8bf1723 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -636,6 +636,19 @@ private: // FIXME: Make protected once we factor out object writer classes. public: + /// Find the symbol which defines the atom containing given address, inside + /// the given section, or null if there is no such symbol. + // + // FIXME: Eliminate this, it is very slow. + const MCSymbolData *getAtomForAddress(const MCSectionData *Section, + uint64_t Address) const; + + /// Find the symbol which defines the atom containing the given symbol, or + /// null if there is no such symbol. + // + // FIXME: Eliminate this, it is very slow. + const MCSymbolData *getAtom(const MCSymbolData *Symbol) const; + /// Check whether a particular symbol is visible to the linker and is required /// in the symbol table, or whether it can be discarded by the assembler. This /// also effects whether the assembler treats the label as potentially diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 003f0327137..0d4f98cc030 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -1062,6 +1062,42 @@ bool MCAssembler::isSymbolLinkerVisible(const MCSymbolData *SD) const { SD->getFragment()->getParent()->getSection()); } +const MCSymbolData *MCAssembler::getAtomForAddress(const MCSectionData *Section, + uint64_t Address) const { + const MCSymbolData *Best = 0; + for (MCAssembler::const_symbol_iterator it = symbol_begin(), + ie = symbol_end(); it != ie; ++it) { + // Ignore non-linker visible symbols. + if (!isSymbolLinkerVisible(it)) + continue; + + // Ignore symbols not in the same section. + if (!it->getFragment() || it->getFragment()->getParent() != Section) + continue; + + // Otherwise, find the closest symbol preceding this address (ties are + // resolved in favor of the last defined symbol). + if (it->getAddress() <= Address && + (!Best || it->getAddress() >= Best->getAddress())) + Best = it; + } + + return Best; +} + +const MCSymbolData *MCAssembler::getAtom(const MCSymbolData *SD) const { + // Linker visible symbols define atoms. + if (isSymbolLinkerVisible(SD)) + return SD; + + // Absolute and undefined symbols have no defining atom. + if (!SD->getFragment()) + return 0; + + // Otherwise, search by address. + return getAtomForAddress(SD->getFragment()->getParent(), SD->getAddress()); +} + bool MCAssembler::EvaluateFixup(const MCAsmLayout &Layout, MCAsmFixup &Fixup, MCDataFragment *DF, MCValue &Target, uint64_t &Value) const {