forked from OSchip/llvm-project
MCAssembler: Switch MCAsmFixup to storing MCFixupKind instead of just a size.
llvm-svn: 96094
This commit is contained in:
parent
97867a9cfc
commit
3374835b46
|
@ -14,6 +14,7 @@
|
|||
#include "llvm/ADT/ilist.h"
|
||||
#include "llvm/ADT/ilist_node.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/MC/MCFixup.h"
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include <vector> // FIXME: Shouldn't be needed.
|
||||
|
||||
|
@ -37,8 +38,8 @@ struct MCAsmFixup {
|
|||
/// Value - The expression to eventually write into the fragment.
|
||||
const MCExpr *Value;
|
||||
|
||||
/// Size - The fixup size.
|
||||
unsigned Size;
|
||||
/// Kind - The fixup kind.
|
||||
MCFixupKind Kind;
|
||||
|
||||
/// FixedValue - The value to replace the fix up by.
|
||||
//
|
||||
|
@ -46,8 +47,8 @@ struct MCAsmFixup {
|
|||
uint64_t FixedValue;
|
||||
|
||||
public:
|
||||
MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, unsigned _Size)
|
||||
: Offset(_Offset), Value(&_Value), Size(_Size), FixedValue(0) {}
|
||||
MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, MCFixupKind _Kind)
|
||||
: Offset(_Offset), Value(&_Value), Kind(_Kind), FixedValue(0) {}
|
||||
};
|
||||
|
||||
class MCFragment : public ilist_node<MCFragment> {
|
||||
|
|
|
@ -89,6 +89,18 @@ public:
|
|||
unsigned getOffset() const { return Offset; }
|
||||
|
||||
const MCExpr *getValue() const { return Value; }
|
||||
|
||||
/// getKindForSize - Return the generic fixup kind for a value with the given
|
||||
/// size. It is an error to pass an unsupported size.
|
||||
static MCFixupKind getKindForSize(unsigned Size) {
|
||||
switch (Size) {
|
||||
default: assert(0 && "Invalid generic fixup size!");
|
||||
case 1: return FK_Data_1;
|
||||
case 2: return FK_Data_2;
|
||||
case 4: return FK_Data_4;
|
||||
case 8: return FK_Data_8;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
|
|
@ -47,6 +47,16 @@ static bool isVirtualSection(const MCSection &Section) {
|
|||
return (Type == MCSectionMachO::S_ZEROFILL);
|
||||
}
|
||||
|
||||
static unsigned getFixupKindLog2Size(MCFixupKind Kind) {
|
||||
switch (Kind) {
|
||||
default: llvm_unreachable("invalid fixup kind!");
|
||||
case FK_Data_1: return 0;
|
||||
case FK_Data_2: return 1;
|
||||
case FK_Data_4: return 2;
|
||||
case FK_Data_8: return 3;
|
||||
}
|
||||
}
|
||||
|
||||
class MachObjectWriter {
|
||||
// See <mach-o/loader.h>.
|
||||
enum {
|
||||
|
@ -426,8 +436,7 @@ public:
|
|||
Value2 = SD->getFragment()->getAddress() + SD->getOffset();
|
||||
}
|
||||
|
||||
unsigned Log2Size = Log2_32(Fixup.Size);
|
||||
assert((1U << Log2Size) == Fixup.Size && "Invalid fixup size!");
|
||||
unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
|
||||
|
||||
// The value which goes in the fixup is current value of the expression.
|
||||
Fixup.FixedValue = Value - Value2 + Target.getConstant();
|
||||
|
@ -512,8 +521,7 @@ public:
|
|||
// The value which goes in the fixup is current value of the expression.
|
||||
Fixup.FixedValue = Value + Target.getConstant();
|
||||
|
||||
unsigned Log2Size = Log2_32(Fixup.Size);
|
||||
assert((1U << Log2Size) == Fixup.Size && "Invalid fixup size!");
|
||||
unsigned Log2Size = getFixupKindLog2Size(Fixup.Kind);
|
||||
|
||||
// struct relocation_info (8 bytes)
|
||||
MachRelocationEntry MRE;
|
||||
|
@ -880,8 +888,12 @@ public:
|
|||
}
|
||||
|
||||
void ApplyFixup(const MCAsmFixup &Fixup, MCDataFragment &DF) {
|
||||
unsigned Size = 1 << getFixupKindLog2Size(Fixup.Kind);
|
||||
|
||||
// FIXME: Endianness assumption.
|
||||
for (unsigned i = 0; i != Fixup.Size; ++i)
|
||||
assert(Fixup.Offset + Size <= DF.getContents().size() &&
|
||||
"Invalid fixup offset!");
|
||||
for (unsigned i = 0; i != Size; ++i)
|
||||
DF.getContents()[Fixup.Offset + i] = uint8_t(Fixup.FixedValue >> (i * 8));
|
||||
}
|
||||
};
|
||||
|
@ -1186,8 +1198,8 @@ void MCAssembler::Finish() {
|
|||
namespace llvm {
|
||||
|
||||
raw_ostream &operator<<(raw_ostream &OS, const MCAsmFixup &AF) {
|
||||
OS << "<MCAsmFixup" << " Offset:" << AF.Offset << " Value:" << AF.Value
|
||||
<< " Size:" << AF.Size << ">";
|
||||
OS << "<MCAsmFixup" << " Offset:" << AF.Offset << " Value:" << *AF.Value
|
||||
<< " Kind:" << AF.Kind << ">";
|
||||
return OS;
|
||||
}
|
||||
|
||||
|
@ -1224,7 +1236,7 @@ void MCDataFragment::dump() {
|
|||
if (i) OS << ",";
|
||||
OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
|
||||
}
|
||||
OS << "]";
|
||||
OS << "] (" << getContents().size() << " bytes)";
|
||||
|
||||
if (!getFixups().empty()) {
|
||||
OS << ",\n ";
|
||||
|
|
|
@ -347,7 +347,8 @@ void MCMachOStreamer::EmitValue(const MCExpr *Value, unsigned Size,
|
|||
DF->getContents().push_back(uint8_t(AbsValue >> (i * 8)));
|
||||
} else {
|
||||
DF->getFixups().push_back(MCAsmFixup(DF->getContents().size(),
|
||||
*AddValueSymbols(Value), Size));
|
||||
*AddValueSymbols(Value),
|
||||
MCFixup::getKindForSize(Size)));
|
||||
DF->getContents().resize(DF->getContents().size() + Size, 0);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue