mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
MC: Move assembler-backend's fixup list into the fragment.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@95926 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
27ade18431
commit
cb7d743b42
@ -31,9 +31,6 @@ class MCSymbol;
|
||||
/// which needs to be rewritten. This region will either be rewritten by the
|
||||
/// assembler or cause a relocation entry to be generated.
|
||||
struct MCAsmFixup {
|
||||
/// Fragment - The fragment containing the fixup.
|
||||
MCFragment *Fragment;
|
||||
|
||||
/// Offset - The offset inside the fragment which needs to be rewritten.
|
||||
uint64_t Offset;
|
||||
|
||||
@ -49,16 +46,18 @@ struct MCAsmFixup {
|
||||
uint64_t FixedValue;
|
||||
|
||||
public:
|
||||
MCAsmFixup(MCFragment &_Fragment, uint64_t _Offset, const MCExpr &_Value,
|
||||
unsigned _Size)
|
||||
: Fragment(&_Fragment), Offset(_Offset), Value(&_Value), Size(_Size),
|
||||
FixedValue(0) {}
|
||||
MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, unsigned _Size)
|
||||
: Offset(_Offset), Value(&_Value), Size(_Size), FixedValue(0) {}
|
||||
};
|
||||
|
||||
class MCFragment : public ilist_node<MCFragment> {
|
||||
MCFragment(const MCFragment&); // DO NOT IMPLEMENT
|
||||
void operator=(const MCFragment&); // DO NOT IMPLEMENT
|
||||
|
||||
public:
|
||||
typedef std::vector<MCAsmFixup>::const_iterator const_fixup_iterator;
|
||||
typedef std::vector<MCAsmFixup>::iterator fixup_iterator;
|
||||
|
||||
public:
|
||||
enum FragmentType {
|
||||
FT_Data,
|
||||
@ -86,6 +85,11 @@ private:
|
||||
/// FileSize - The file size of this section. This is ~0 until initialized.
|
||||
uint64_t FileSize;
|
||||
|
||||
/// Fixups - The list of fixups in this fragment.
|
||||
//
|
||||
// FIXME: This should be sunk into MCDataFragment.
|
||||
std::vector<MCAsmFixup> Fixups;
|
||||
|
||||
/// @}
|
||||
|
||||
protected:
|
||||
@ -107,6 +111,39 @@ public:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// @name Fixup Access
|
||||
/// @{
|
||||
|
||||
/// 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. This will be fixed by sinking fixups into
|
||||
// data fragments exclusively.
|
||||
const MCAsmFixup *LookupFixup(uint64_t Offset) const {
|
||||
for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
|
||||
if (Fixups[i].Offset == Offset)
|
||||
return &Fixups[i];
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::vector<MCAsmFixup> &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
|
||||
/// @{
|
||||
//
|
||||
@ -313,14 +350,13 @@ class MCSectionData : public ilist_node<MCSectionData> {
|
||||
void operator=(const MCSectionData&); // DO NOT IMPLEMENT
|
||||
|
||||
public:
|
||||
|
||||
typedef iplist<MCFragment> FragmentListType;
|
||||
|
||||
typedef FragmentListType::const_iterator const_iterator;
|
||||
typedef FragmentListType::iterator iterator;
|
||||
|
||||
typedef std::vector<MCAsmFixup>::const_iterator const_fixup_iterator;
|
||||
typedef std::vector<MCAsmFixup>::iterator fixup_iterator;
|
||||
typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
|
||||
typedef FragmentListType::reverse_iterator reverse_iterator;
|
||||
|
||||
private:
|
||||
iplist<MCFragment> Fragments;
|
||||
@ -345,12 +381,6 @@ 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<MCAsmFixup> Fixups;
|
||||
|
||||
/// HasInstructions - Whether this section has had instructions emitted into
|
||||
/// it.
|
||||
unsigned HasInstructions : 1;
|
||||
@ -379,45 +409,22 @@ public:
|
||||
iterator end() { return Fragments.end(); }
|
||||
const_iterator end() const { return Fragments.end(); }
|
||||
|
||||
reverse_iterator rbegin() { return Fragments.rbegin(); }
|
||||
const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
|
||||
|
||||
reverse_iterator rend() { return Fragments.rend(); }
|
||||
const_reverse_iterator rend() const { return Fragments.rend(); }
|
||||
|
||||
size_t size() const { return Fragments.size(); }
|
||||
|
||||
bool empty() const { return Fragments.empty(); }
|
||||
|
||||
/// @}
|
||||
/// @name Fixup Access
|
||||
/// @{
|
||||
|
||||
std::vector<MCAsmFixup> &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 MCAsmFixup *LookupFixup(const MCFragment *Fragment,
|
||||
uint64_t Offset) const;
|
||||
|
||||
uint64_t getAddress() const {
|
||||
assert(Address != ~UINT64_C(0) && "Address not set!");
|
||||
return Address;
|
||||
|
@ -402,12 +402,12 @@ public:
|
||||
uint32_t Word0;
|
||||
uint32_t Word1;
|
||||
};
|
||||
void ComputeScatteredRelocationInfo(MCAssembler &Asm,
|
||||
void ComputeScatteredRelocationInfo(MCAssembler &Asm, MCFragment &Fragment,
|
||||
MCAsmFixup &Fixup,
|
||||
const MCValue &Target,
|
||||
DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap,
|
||||
std::vector<MachRelocationEntry> &Relocs) {
|
||||
uint32_t Address = Fixup.Fragment->getOffset() + Fixup.Offset;
|
||||
uint32_t Address = Fragment.getOffset() + Fixup.Offset;
|
||||
unsigned IsPCRel = 0;
|
||||
unsigned Type = RIT_Vanilla;
|
||||
|
||||
@ -453,7 +453,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void ComputeRelocationInfo(MCAssembler &Asm,
|
||||
void ComputeRelocationInfo(MCAssembler &Asm, MCFragment &Fragment,
|
||||
MCAsmFixup &Fixup,
|
||||
DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap,
|
||||
std::vector<MachRelocationEntry> &Relocs) {
|
||||
@ -466,11 +466,11 @@ public:
|
||||
if (Target.getSymB() ||
|
||||
(Target.getSymA() && !Target.getSymA()->isUndefined() &&
|
||||
Target.getConstant()))
|
||||
return ComputeScatteredRelocationInfo(Asm, Fixup, Target,
|
||||
return ComputeScatteredRelocationInfo(Asm, Fragment, Fixup, Target,
|
||||
SymbolMap, Relocs);
|
||||
|
||||
// See <reloc.h>.
|
||||
uint32_t Address = Fixup.Fragment->getOffset() + Fixup.Offset;
|
||||
uint32_t Address = Fragment.getOffset() + Fixup.Offset;
|
||||
uint32_t Value = 0;
|
||||
unsigned Index = 0;
|
||||
unsigned IsPCRel = 0;
|
||||
@ -766,17 +766,19 @@ public:
|
||||
// is written.
|
||||
std::vector<MachRelocationEntry> RelocInfos;
|
||||
uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
|
||||
for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie;
|
||||
++it) {
|
||||
for (MCAssembler::iterator it = Asm.begin(),
|
||||
ie = Asm.end(); it != ie; ++it) {
|
||||
MCSectionData &SD = *it;
|
||||
|
||||
// The assembler writes relocations in the reverse order they were seen.
|
||||
//
|
||||
// FIXME: It is probably more complicated than this.
|
||||
unsigned NumRelocsStart = RelocInfos.size();
|
||||
for (unsigned i = 0, e = SD.fixup_size(); i != e; ++i)
|
||||
ComputeRelocationInfo(Asm, SD.getFixups()[e - i - 1], SymbolMap,
|
||||
RelocInfos);
|
||||
for (MCSectionData::reverse_iterator it2 = SD.rbegin(),
|
||||
ie2 = SD.rend(); it2 != ie2; ++it2)
|
||||
for (unsigned i = 0, e = it2->fixup_size(); i != e; ++i)
|
||||
ComputeRelocationInfo(Asm, *it2, it2->getFixups()[e - i - 1],
|
||||
SymbolMap, RelocInfos);
|
||||
|
||||
unsigned NumRelocs = RelocInfos.size() - NumRelocsStart;
|
||||
uint64_t SectionStart = SectionDataStart + SD.getAddress();
|
||||
@ -905,35 +907,12 @@ MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
|
||||
Address(~UINT64_C(0)),
|
||||
Size(~UINT64_C(0)),
|
||||
FileSize(~UINT64_C(0)),
|
||||
LastFixupLookup(~0),
|
||||
HasInstructions(false)
|
||||
{
|
||||
if (A)
|
||||
A->getSectionList().push_back(this);
|
||||
}
|
||||
|
||||
const MCAsmFixup *MCSectionData::LookupFixup(const MCFragment *Fragment,
|
||||
uint64_t Offset) const {
|
||||
// Use a one level cache to turn the common case of accessing the fixups in
|
||||
// order into O(1) instead of O(N).
|
||||
unsigned i = LastFixupLookup, Count = Fixups.size(), End = Fixups.size();
|
||||
if (i >= End)
|
||||
i = 0;
|
||||
while (Count--) {
|
||||
const MCAsmFixup &F = Fixups[i];
|
||||
if (F.Fragment == Fragment && F.Offset == Offset) {
|
||||
LastFixupLookup = i;
|
||||
return &F;
|
||||
}
|
||||
|
||||
++i;
|
||||
if (i == End)
|
||||
i = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* *** */
|
||||
|
||||
MCSymbolData::MCSymbolData() : Symbol(0) {}
|
||||
@ -997,10 +976,13 @@ void MCAssembler::LayoutSection(MCSectionData &SD) {
|
||||
break;
|
||||
|
||||
// Otherwise, add fixups for the values.
|
||||
for (uint64_t i = 0, e = FF.getCount(); i != e; ++i) {
|
||||
MCAsmFixup Fix(F, i*FF.getValueSize(), FF.getValue(),FF.getValueSize());
|
||||
SD.getFixups().push_back(Fix);
|
||||
}
|
||||
//
|
||||
// FIXME: What we want to do here is lower this to a data fragment once we
|
||||
// realize it will need relocations. This means that the only place we
|
||||
// need to worry about relocations and fixing is on data fragments.
|
||||
for (uint64_t i = 0, e = FF.getCount(); i != e; ++i)
|
||||
FF.getFixups().push_back(MCAsmFixup(i*FF.getValueSize(), FF.getValue(),
|
||||
FF.getValueSize()));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1105,9 +1087,9 @@ static void WriteFileData(raw_ostream &OS, const MCFragment &F,
|
||||
if (!Target.isAbsolute()) {
|
||||
// Find the fixup.
|
||||
//
|
||||
// FIXME: Find a better way to write in the fixes.
|
||||
const MCAsmFixup *Fixup =
|
||||
F.getParent()->LookupFixup(&F, i * FF.getValueSize());
|
||||
// FIXME: Find a better way to write in the fixes (move to
|
||||
// MCDataFragment).
|
||||
const MCAsmFixup *Fixup = FF.LookupFixup(i * FF.getValueSize());
|
||||
assert(Fixup && "Missing fixup for fill value!");
|
||||
Value = Fixup->FixedValue;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user