mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-24 09:29:42 +00:00
Move common symbol related information from MCSectionData to MCSymbol.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238583 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
052a7becbe
commit
82fdcc0e7f
@ -34,39 +34,17 @@ class MCSymbolData {
|
|||||||
/// if it is private extern (bit 1).
|
/// if it is private extern (bit 1).
|
||||||
PointerIntPair<MCFragment *, 2> Fragment;
|
PointerIntPair<MCFragment *, 2> Fragment;
|
||||||
|
|
||||||
union {
|
|
||||||
/// Offset - The offset to apply to the fragment address to form this
|
|
||||||
/// symbol's value.
|
|
||||||
uint64_t Offset;
|
|
||||||
|
|
||||||
/// CommonSize - The size of the symbol, if it is 'common'.
|
|
||||||
uint64_t CommonSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// CommonAlign - The alignment of the symbol, if it is 'common', or -1.
|
|
||||||
//
|
|
||||||
// FIXME: Pack this in with other fields?
|
|
||||||
unsigned CommonAlign = -1U;
|
|
||||||
|
|
||||||
/// Flags - The Flags field is used by object file implementations to store
|
/// Flags - The Flags field is used by object file implementations to store
|
||||||
/// additional per symbol information which is not easily classified.
|
/// additional per symbol information which is not easily classified.
|
||||||
uint32_t Flags = 0;
|
uint32_t Flags = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MCSymbolData() { Offset = 0; }
|
MCSymbolData() {}
|
||||||
|
|
||||||
MCFragment *getFragment() const { return Fragment.getPointer(); }
|
MCFragment *getFragment() const { return Fragment.getPointer(); }
|
||||||
void setFragment(MCFragment *Value) { Fragment.setPointer(Value); }
|
void setFragment(MCFragment *Value) { Fragment.setPointer(Value); }
|
||||||
|
|
||||||
uint64_t getOffset() const {
|
|
||||||
assert(!isCommon());
|
|
||||||
return Offset;
|
|
||||||
}
|
|
||||||
void setOffset(uint64_t Value) {
|
|
||||||
assert(!isCommon());
|
|
||||||
Offset = Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// \name Symbol Attributes
|
/// \name Symbol Attributes
|
||||||
/// @{
|
/// @{
|
||||||
@ -81,31 +59,6 @@ public:
|
|||||||
Fragment.setInt((Fragment.getInt() & ~2) | (unsigned(Value) << 1));
|
Fragment.setInt((Fragment.getInt() & ~2) | (unsigned(Value) << 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isCommon - Is this a 'common' symbol.
|
|
||||||
bool isCommon() const { return CommonAlign != -1U; }
|
|
||||||
|
|
||||||
/// setCommon - Mark this symbol as being 'common'.
|
|
||||||
///
|
|
||||||
/// \param Size - The size of the symbol.
|
|
||||||
/// \param Align - The alignment of the symbol.
|
|
||||||
void setCommon(uint64_t Size, unsigned Align) {
|
|
||||||
assert(getOffset() == 0);
|
|
||||||
CommonSize = Size;
|
|
||||||
CommonAlign = Align;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// getCommonSize - Return the size of a 'common' symbol.
|
|
||||||
uint64_t getCommonSize() const {
|
|
||||||
assert(isCommon() && "Not a 'common' symbol!");
|
|
||||||
return CommonSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// getCommonAlignment - Return the alignment of a 'common' symbol.
|
|
||||||
unsigned getCommonAlignment() const {
|
|
||||||
assert(isCommon() && "Not a 'common' symbol!");
|
|
||||||
return CommonAlign;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// getFlags - Get the (implementation defined) symbol flags.
|
/// getFlags - Get the (implementation defined) symbol flags.
|
||||||
uint32_t getFlags() const { return Flags; }
|
uint32_t getFlags() const { return Flags; }
|
||||||
|
|
||||||
@ -167,6 +120,19 @@ class MCSymbol {
|
|||||||
/// symbol has no size this field will be NULL.
|
/// symbol has no size this field will be NULL.
|
||||||
const MCExpr *SymbolSize = nullptr;
|
const MCExpr *SymbolSize = nullptr;
|
||||||
|
|
||||||
|
/// The alignment of the symbol, if it is 'common', or -1.
|
||||||
|
//
|
||||||
|
// FIXME: Pack this in with other fields?
|
||||||
|
unsigned CommonAlign = -1U;
|
||||||
|
|
||||||
|
union {
|
||||||
|
/// The offset to apply to the fragment address to form this symbol's value.
|
||||||
|
uint64_t Offset;
|
||||||
|
|
||||||
|
/// The size of the symbol, if it is 'common'.
|
||||||
|
uint64_t CommonSize;
|
||||||
|
};
|
||||||
|
|
||||||
mutable MCSymbolData Data;
|
mutable MCSymbolData Data;
|
||||||
|
|
||||||
private: // MCContext creates and uniques these.
|
private: // MCContext creates and uniques these.
|
||||||
@ -174,7 +140,9 @@ private: // MCContext creates and uniques these.
|
|||||||
friend class MCContext;
|
friend class MCContext;
|
||||||
MCSymbol(const StringMapEntry<bool> *Name, bool isTemporary)
|
MCSymbol(const StringMapEntry<bool> *Name, bool isTemporary)
|
||||||
: Name(Name), Section(nullptr), Value(nullptr), IsTemporary(isTemporary),
|
: Name(Name), Section(nullptr), Value(nullptr), IsTemporary(isTemporary),
|
||||||
IsRedefinable(false), IsUsed(false), HasData(false), Index(0) {}
|
IsRedefinable(false), IsUsed(false), HasData(false), Index(0) {
|
||||||
|
Offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
MCSymbol(const MCSymbol &) = delete;
|
MCSymbol(const MCSymbol &) = delete;
|
||||||
void operator=(const MCSymbol &) = delete;
|
void operator=(const MCSymbol &) = delete;
|
||||||
@ -295,6 +263,40 @@ public:
|
|||||||
|
|
||||||
const MCExpr *getSize() const { return SymbolSize; }
|
const MCExpr *getSize() const { return SymbolSize; }
|
||||||
|
|
||||||
|
uint64_t getOffset() const {
|
||||||
|
assert(!isCommon());
|
||||||
|
return Offset;
|
||||||
|
}
|
||||||
|
void setOffset(uint64_t Value) {
|
||||||
|
assert(!isCommon());
|
||||||
|
Offset = Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the size of a 'common' symbol.
|
||||||
|
uint64_t getCommonSize() const {
|
||||||
|
assert(isCommon() && "Not a 'common' symbol!");
|
||||||
|
return CommonSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Mark this symbol as being 'common'.
|
||||||
|
///
|
||||||
|
/// \param Size - The size of the symbol.
|
||||||
|
/// \param Align - The alignment of the symbol.
|
||||||
|
void setCommon(uint64_t Size, unsigned Align) {
|
||||||
|
assert(getOffset() == 0);
|
||||||
|
CommonSize = Size;
|
||||||
|
CommonAlign = Align;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the alignment of a 'common' symbol.
|
||||||
|
unsigned getCommonAlignment() const {
|
||||||
|
assert(isCommon() && "Not a 'common' symbol!");
|
||||||
|
return CommonAlign;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Is this a 'common' symbol.
|
||||||
|
bool isCommon() const { return CommonAlign != -1U; }
|
||||||
|
|
||||||
/// print - Print the value to the stream \p OS.
|
/// print - Print the value to the stream \p OS.
|
||||||
void print(raw_ostream &OS) const;
|
void print(raw_ostream &OS) const;
|
||||||
|
|
||||||
|
@ -360,8 +360,8 @@ void ELFObjectWriter::writeHeader(const MCAssembler &Asm) {
|
|||||||
uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym,
|
uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym,
|
||||||
const MCAsmLayout &Layout) {
|
const MCAsmLayout &Layout) {
|
||||||
MCSymbolData &Data = Sym.getData();
|
MCSymbolData &Data = Sym.getData();
|
||||||
if (Data.isCommon() && Data.isExternal())
|
if (Sym.isCommon() && Data.isExternal())
|
||||||
return Data.getCommonAlignment();
|
return Sym.getCommonAlignment();
|
||||||
|
|
||||||
uint64_t Res;
|
uint64_t Res;
|
||||||
if (!Layout.getSymbolOffset(Sym, Res))
|
if (!Layout.getSymbolOffset(Sym, Res))
|
||||||
@ -459,7 +459,7 @@ void ELFObjectWriter::writeSymbol(SymbolTableWriter &Writer,
|
|||||||
|
|
||||||
// This has to be in sync with when computeSymbolTable uses SHN_ABS or
|
// This has to be in sync with when computeSymbolTable uses SHN_ABS or
|
||||||
// SHN_COMMON.
|
// SHN_COMMON.
|
||||||
bool IsReserved = !Base || OrigData.isCommon();
|
bool IsReserved = !Base || MSD.Symbol->isCommon();
|
||||||
|
|
||||||
// Binding and Type share the same byte as upper and lower nibbles
|
// Binding and Type share the same byte as upper and lower nibbles
|
||||||
uint8_t Binding = MCELF::GetBinding(OrigData);
|
uint8_t Binding = MCELF::GetBinding(OrigData);
|
||||||
@ -832,7 +832,7 @@ void ELFObjectWriter::computeSymbolTable(
|
|||||||
|
|
||||||
if (Symbol.isAbsolute()) {
|
if (Symbol.isAbsolute()) {
|
||||||
MSD.SectionIndex = ELF::SHN_ABS;
|
MSD.SectionIndex = ELF::SHN_ABS;
|
||||||
} else if (SD.isCommon()) {
|
} else if (Symbol.isCommon()) {
|
||||||
assert(!Local);
|
assert(!Local);
|
||||||
MSD.SectionIndex = ELF::SHN_COMMON;
|
MSD.SectionIndex = ELF::SHN_COMMON;
|
||||||
} else if (Symbol.isUndefined()) {
|
} else if (Symbol.isUndefined()) {
|
||||||
|
@ -127,7 +127,7 @@ static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbol &S,
|
|||||||
S.getName() + "'");
|
S.getName() + "'");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Val = Layout.getFragmentOffset(SD.getFragment()) + SD.getOffset();
|
Val = Layout.getFragmentOffset(SD.getFragment()) + S.getOffset();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,8 +195,7 @@ const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const {
|
|||||||
|
|
||||||
const MCSymbol &ASym = A->getSymbol();
|
const MCSymbol &ASym = A->getSymbol();
|
||||||
const MCAssembler &Asm = getAssembler();
|
const MCAssembler &Asm = getAssembler();
|
||||||
const MCSymbolData &ASD = ASym.getData();
|
if (ASym.isCommon()) {
|
||||||
if (ASD.isCommon()) {
|
|
||||||
// FIXME: we should probably add a SMLoc to MCExpr.
|
// FIXME: we should probably add a SMLoc to MCExpr.
|
||||||
Asm.getContext().reportFatalError(SMLoc(),
|
Asm.getContext().reportFatalError(SMLoc(),
|
||||||
"Common symbol " + ASym.getName() +
|
"Common symbol " + ASym.getName() +
|
||||||
@ -1189,12 +1188,7 @@ void MCSymbolData::dump() const {
|
|||||||
|
|
||||||
OS << "<MCSymbolData"
|
OS << "<MCSymbolData"
|
||||||
<< " Fragment:" << getFragment();
|
<< " Fragment:" << getFragment();
|
||||||
if (!isCommon())
|
|
||||||
OS << " Offset:" << getOffset();
|
|
||||||
OS << " Flags:" << getFlags();
|
OS << " Flags:" << getFlags();
|
||||||
if (isCommon())
|
|
||||||
OS << " (common, size:" << getCommonSize()
|
|
||||||
<< " align: " << getCommonAlignment() << ")";
|
|
||||||
if (isExternal())
|
if (isExternal())
|
||||||
OS << " (external)";
|
OS << " (external)";
|
||||||
if (isPrivateExtern())
|
if (isPrivateExtern())
|
||||||
|
@ -328,7 +328,7 @@ void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
|||||||
struct LocalCommon L = {Symbol, Size, ByteAlignment};
|
struct LocalCommon L = {Symbol, Size, ByteAlignment};
|
||||||
LocalCommons.push_back(L);
|
LocalCommons.push_back(L);
|
||||||
} else {
|
} else {
|
||||||
SD.setCommon(Size, ByteAlignment);
|
Symbol->setCommon(Size, ByteAlignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
Symbol->setSize(MCConstantExpr::Create(Size, getContext()));
|
Symbol->setSize(MCConstantExpr::Create(Size, getContext()));
|
||||||
|
@ -475,7 +475,7 @@ static void AttemptToFoldSymbolOffsetDifference(
|
|||||||
const MCSymbolData &BD = SB.getData();
|
const MCSymbolData &BD = SB.getData();
|
||||||
|
|
||||||
if (AD.getFragment() == BD.getFragment()) {
|
if (AD.getFragment() == BD.getFragment()) {
|
||||||
Addend += (AD.getOffset() - BD.getOffset());
|
Addend += (SA.getOffset() - SB.getOffset());
|
||||||
|
|
||||||
// Pointers to Thumb symbols need to have their low-bit set to allow
|
// Pointers to Thumb symbols need to have their low-bit set to allow
|
||||||
// for interworking.
|
// for interworking.
|
||||||
|
@ -392,7 +392,7 @@ void MCMachOStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
|||||||
|
|
||||||
MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
|
MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
|
||||||
SD.setExternal(true);
|
SD.setExternal(true);
|
||||||
SD.setCommon(Size, ByteAlignment);
|
Symbol->setCommon(Size, ByteAlignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCMachOStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
void MCMachOStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
||||||
@ -470,7 +470,8 @@ void MCMachOStreamer::FinishImpl() {
|
|||||||
MCSymbolData &SD = Symbol.getData();
|
MCSymbolData &SD = Symbol.getData();
|
||||||
if (getAssembler().isSymbolLinkerVisible(Symbol) && SD.getFragment()) {
|
if (getAssembler().isSymbolLinkerVisible(Symbol) && SD.getFragment()) {
|
||||||
// An atom defining symbol should never be internal to a fragment.
|
// An atom defining symbol should never be internal to a fragment.
|
||||||
assert(SD.getOffset() == 0 && "Invalid offset in atom defining symbol!");
|
assert(Symbol.getOffset() == 0 &&
|
||||||
|
"Invalid offset in atom defining symbol!");
|
||||||
DefiningSymbolMap[SD.getFragment()] = &Symbol;
|
DefiningSymbolMap[SD.getFragment()] = &Symbol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
|
|||||||
for (MCSymbol *Sym : PendingLabels) {
|
for (MCSymbol *Sym : PendingLabels) {
|
||||||
MCSymbolData *SD = &Sym->getData();
|
MCSymbolData *SD = &Sym->getData();
|
||||||
SD->setFragment(F);
|
SD->setFragment(F);
|
||||||
SD->setOffset(FOffset);
|
Sym->setOffset(FOffset);
|
||||||
}
|
}
|
||||||
PendingLabels.clear();
|
PendingLabels.clear();
|
||||||
}
|
}
|
||||||
@ -72,9 +72,9 @@ bool MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
|
|||||||
if (!isa<MCDataFragment>(HiD.getFragment()))
|
if (!isa<MCDataFragment>(HiD.getFragment()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
assert(HiD.getOffset() >= LoD.getOffset() &&
|
assert(Hi->getOffset() >= Lo->getOffset() &&
|
||||||
"Expected Hi to be greater than Lo");
|
"Expected Hi to be greater than Lo");
|
||||||
EmitIntValue(HiD.getOffset() - LoD.getOffset(), Size);
|
EmitIntValue(Hi->getOffset() - Lo->getOffset(), Size);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,7 +173,7 @@ void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) {
|
|||||||
if (F && !(getAssembler().isBundlingEnabled() &&
|
if (F && !(getAssembler().isBundlingEnabled() &&
|
||||||
getAssembler().getRelaxAll())) {
|
getAssembler().getRelaxAll())) {
|
||||||
SD.setFragment(F);
|
SD.setFragment(F);
|
||||||
SD.setOffset(F->getContents().size());
|
Symbol->setOffset(F->getContents().size());
|
||||||
} else {
|
} else {
|
||||||
PendingLabels.push_back(Symbol);
|
PendingLabels.push_back(Symbol);
|
||||||
}
|
}
|
||||||
|
@ -373,13 +373,13 @@ void MachObjectWriter::WriteNlist(MachSymbolData &MSD,
|
|||||||
Address = AliaseeInfo->StringIndex;
|
Address = AliaseeInfo->StringIndex;
|
||||||
else if (Symbol->isDefined())
|
else if (Symbol->isDefined())
|
||||||
Address = getSymbolAddress(OrigSymbol, Layout);
|
Address = getSymbolAddress(OrigSymbol, Layout);
|
||||||
else if (Data.isCommon()) {
|
else if (Symbol->isCommon()) {
|
||||||
// Common symbols are encoded with the size in the address
|
// Common symbols are encoded with the size in the address
|
||||||
// field, and their alignment in the flags.
|
// field, and their alignment in the flags.
|
||||||
Address = Data.getCommonSize();
|
Address = Symbol->getCommonSize();
|
||||||
|
|
||||||
// Common alignment is packed into the 'desc' bits.
|
// Common alignment is packed into the 'desc' bits.
|
||||||
if (unsigned Align = Data.getCommonAlignment()) {
|
if (unsigned Align = Symbol->getCommonAlignment()) {
|
||||||
unsigned Log2Size = Log2_32(Align);
|
unsigned Log2Size = Log2_32(Align);
|
||||||
assert((1U << Log2Size) == Align && "Invalid 'common' alignment!");
|
assert((1U << Log2Size) == Align && "Invalid 'common' alignment!");
|
||||||
if (Log2Size > 15)
|
if (Log2Size > 15)
|
||||||
|
@ -365,8 +365,8 @@ void WinCOFFObjectWriter::defineSection(MCSectionCOFF const &Sec) {
|
|||||||
static uint64_t getSymbolValue(const MCSymbol &Symbol,
|
static uint64_t getSymbolValue(const MCSymbol &Symbol,
|
||||||
const MCAsmLayout &Layout) {
|
const MCAsmLayout &Layout) {
|
||||||
const MCSymbolData &Data = Symbol.getData();
|
const MCSymbolData &Data = Symbol.getData();
|
||||||
if (Data.isCommon() && Data.isExternal())
|
if (Symbol.isCommon() && Data.isExternal())
|
||||||
return Data.getCommonSize();
|
return Symbol.getCommonSize();
|
||||||
|
|
||||||
uint64_t Res;
|
uint64_t Res;
|
||||||
if (!Layout.getSymbolOffset(Symbol, Res))
|
if (!Layout.getSymbolOffset(Symbol, Res))
|
||||||
@ -765,7 +765,7 @@ void WinCOFFObjectWriter::RecordRelocation(
|
|||||||
Reloc.Symb = coff_symbol->Section->Symbol;
|
Reloc.Symb = coff_symbol->Section->Symbol;
|
||||||
FixedValue +=
|
FixedValue +=
|
||||||
Layout.getFragmentOffset(coff_symbol->MC->getData().getFragment()) +
|
Layout.getFragmentOffset(coff_symbol->MC->getData().getFragment()) +
|
||||||
coff_symbol->MC->getData().getOffset();
|
coff_symbol->MC->getOffset();
|
||||||
} else
|
} else
|
||||||
Reloc.Symb = coff_symbol;
|
Reloc.Symb = coff_symbol;
|
||||||
|
|
||||||
|
@ -196,7 +196,7 @@ void MCWinCOFFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
|
|||||||
|
|
||||||
MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
|
MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
|
||||||
SD.setExternal(true);
|
SD.setExternal(true);
|
||||||
SD.setCommon(Size, ByteAlignment);
|
Symbol->setCommon(Size, ByteAlignment);
|
||||||
|
|
||||||
if (!T.isKnownWindowsMSVCEnvironment() && ByteAlignment > 1) {
|
if (!T.isKnownWindowsMSVCEnvironment() && ByteAlignment > 1) {
|
||||||
SmallString<128> Directive;
|
SmallString<128> Directive;
|
||||||
|
Loading…
Reference in New Issue
Block a user