summaryrefslogtreecommitdiff
path: root/include/llvm/MC
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-08-26 13:58:10 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-08-26 13:58:10 +0000
commit3f6a960f9c9ad27f2ac573020df414e8b8cdda04 (patch)
tree0207ce4dc49bf5e6867099a361ccb91e3dd56273 /include/llvm/MC
parentbe9635569401b9a40984c02c6e171aa9da9ad0a2 (diff)
downloadllvm-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.h68
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;