diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-08-26 13:58:10 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-08-26 13:58:10 +0000 |
commit | 3f6a960f9c9ad27f2ac573020df414e8b8cdda04 (patch) | |
tree | 0207ce4dc49bf5e6867099a361ccb91e3dd56273 /include/llvm/MC | |
parent | be9635569401b9a40984c02c6e171aa9da9ad0a2 (diff) | |
download | llvm-3f6a960f9c9ad27f2ac573020df414e8b8cdda04.tar.gz llvm-3f6a960f9c9ad27f2ac573020df414e8b8cdda04.tar.bz2 llvm-3f6a960f9c9ad27f2ac573020df414e8b8cdda04.tar.xz |
llvm-mc/Mach-O: Add support for relocations.
- I haven't really tried to find the "right" way to store the fixups or apply
them, yet. This works, but isn't particularly elegant or fast.
- Still no evaluation support, so we don't actually ever not turn a fixup into
a relocation entry.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80089 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/MC')
-rw-r--r-- | include/llvm/MC/MCAssembler.h | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 74a4748658..dc3f5c0f58 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -246,11 +246,45 @@ class MCSectionData : public ilist_node<MCSectionData> { void operator=(const MCSectionData&); // DO NOT IMPLEMENT public: + /// Fixup - Represent a fixed size region of bytes inside some fragment which + /// needs to be rewritten. This region will either be rewritten by the + /// assembler or cause a relocation entry to be generated. + struct Fixup { + /// Fragment - The fragment containing the fixup. + MCFragment *Fragment; + + /// Offset - The offset inside the fragment which needs to be rewritten. + uint64_t Offset; + + /// Value - The expression to eventually write into the fragment. + // + // FIXME: We could probably get away with requiring the client to pass in an + // owned reference whose lifetime extends past that of the fixup. + MCValue Value; + + /// Size - The fixup size. + unsigned Size; + + /// FixedValue - The value to replace the fix up by. + // + // FIXME: This should not be here. + uint64_t FixedValue; + + public: + Fixup(MCFragment &_Fragment, uint64_t _Offset, const MCValue &_Value, + unsigned _Size) + : Fragment(&_Fragment), Offset(_Offset), Value(_Value), Size(_Size), + FixedValue(0) {} + }; + typedef iplist<MCFragment> FragmentListType; typedef FragmentListType::const_iterator const_iterator; typedef FragmentListType::iterator iterator; + typedef std::vector<Fixup>::const_iterator const_fixup_iterator; + typedef std::vector<Fixup>::iterator fixup_iterator; + private: iplist<MCFragment> Fragments; const MCSection &Section; @@ -274,6 +308,12 @@ private: /// initialized. uint64_t FileSize; + /// LastFixupLookup - Cache for the last looked up fixup. + mutable unsigned LastFixupLookup; + + /// Fixups - The list of fixups in this section. + std::vector<Fixup> Fixups; + /// @} public: @@ -303,11 +343,39 @@ public: bool empty() const { return Fragments.empty(); } /// @} + /// @name Fixup Access + /// @{ + + std::vector<Fixup> &getFixups() { + return Fixups; + } + + fixup_iterator fixup_begin() { + return Fixups.begin(); + } + + fixup_iterator fixup_end() { + return Fixups.end(); + } + + size_t fixup_size() const { return Fixups.size(); } + + /// @} /// @name Assembler Backend Support /// @{ // // FIXME: This could all be kept private to the assembler implementation. + /// LookupFixup - Look up the fixup for the given \arg Fragment and \arg + /// Offset. + /// + /// If multiple fixups exist for the same fragment and offset it is undefined + /// which one is returned. + // + // FIXME: This isn't horribly slow in practice, but there are much nicer + // solutions to applying the fixups. + const Fixup *LookupFixup(const MCFragment *Fragment, uint64_t Offset) const; + uint64_t getAddress() const { assert(Address != ~UINT64_C(0) && "Address not set!"); return Address; |