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