mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 20:32:21 +00:00
[MC][COFF] Delay handling symbol aliases when writing
Fixes PR14447 and PR9034. Patch by Nico Rieck! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173839 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d855049576
commit
0933134a30
@ -147,7 +147,9 @@ public:
|
|||||||
object_t *createCOFFEntity(StringRef Name, list_t &List);
|
object_t *createCOFFEntity(StringRef Name, list_t &List);
|
||||||
|
|
||||||
void DefineSection(MCSectionData const &SectionData);
|
void DefineSection(MCSectionData const &SectionData);
|
||||||
void DefineSymbol(MCSymbolData const &SymbolData, MCAssembler &Assembler);
|
void DefineSymbol(MCSymbol const &Symbol,
|
||||||
|
MCSymbolData const &SymbolData,
|
||||||
|
MCAssembler &Assembler);
|
||||||
|
|
||||||
void MakeSymbolReal(COFFSymbol &S, size_t Index);
|
void MakeSymbolReal(COFFSymbol &S, size_t Index);
|
||||||
void MakeSectionReal(COFFSection &S, size_t Number);
|
void MakeSectionReal(COFFSection &S, size_t Number);
|
||||||
@ -408,9 +410,10 @@ void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) {
|
|||||||
|
|
||||||
/// This function takes a section data object from the assembler
|
/// This function takes a section data object from the assembler
|
||||||
/// and creates the associated COFF symbol staging object.
|
/// and creates the associated COFF symbol staging object.
|
||||||
void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
|
void WinCOFFObjectWriter::DefineSymbol(MCSymbol const &Symbol,
|
||||||
|
MCSymbolData const &SymbolData,
|
||||||
MCAssembler &Assembler) {
|
MCAssembler &Assembler) {
|
||||||
COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&SymbolData.getSymbol());
|
COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol);
|
||||||
|
|
||||||
coff_symbol->Data.Type = (SymbolData.getFlags() & 0x0000FFFF) >> 0;
|
coff_symbol->Data.Type = (SymbolData.getFlags() & 0x0000FFFF) >> 0;
|
||||||
coff_symbol->Data.StorageClass = (SymbolData.getFlags() & 0x00FF0000) >> 16;
|
coff_symbol->Data.StorageClass = (SymbolData.getFlags() & 0x00FF0000) >> 16;
|
||||||
@ -418,9 +421,9 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
|
|||||||
if (SymbolData.getFlags() & COFF::SF_WeakExternal) {
|
if (SymbolData.getFlags() & COFF::SF_WeakExternal) {
|
||||||
coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
|
coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
|
||||||
|
|
||||||
if (SymbolData.getSymbol().isVariable()) {
|
if (Symbol.isVariable()) {
|
||||||
coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
|
coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
|
||||||
const MCExpr *Value = SymbolData.getSymbol().getVariableValue();
|
const MCExpr *Value = Symbol.getVariableValue();
|
||||||
|
|
||||||
// FIXME: This assert message isn't very good.
|
// FIXME: This assert message isn't very good.
|
||||||
assert(Value->getKind() == MCExpr::SymbolRef &&
|
assert(Value->getKind() == MCExpr::SymbolRef &&
|
||||||
@ -428,10 +431,10 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
|
|||||||
|
|
||||||
const MCSymbolRefExpr *SymbolRef =
|
const MCSymbolRefExpr *SymbolRef =
|
||||||
static_cast<const MCSymbolRefExpr *>(Value);
|
static_cast<const MCSymbolRefExpr *>(Value);
|
||||||
coff_symbol->Other = GetOrCreateCOFFSymbol(&SymbolRef->getSymbol());
|
coff_symbol->Other = GetOrCreateCOFFSymbol(&Symbol);
|
||||||
} else {
|
} else {
|
||||||
std::string WeakName = std::string(".weak.")
|
std::string WeakName = std::string(".weak.")
|
||||||
+ SymbolData.getSymbol().getName().str()
|
+ Symbol.getName().str()
|
||||||
+ ".default";
|
+ ".default";
|
||||||
COFFSymbol *WeakDefault = createSymbol(WeakName);
|
COFFSymbol *WeakDefault = createSymbol(WeakName);
|
||||||
WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
|
WeakDefault->Data.SectionNumber = COFF::IMAGE_SYM_ABSOLUTE;
|
||||||
@ -464,7 +467,7 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
|
|||||||
|
|
||||||
// Bind internal COFF symbol to MC symbol.
|
// Bind internal COFF symbol to MC symbol.
|
||||||
coff_symbol->MCData = &SymbolData;
|
coff_symbol->MCData = &SymbolData;
|
||||||
SymbolMap[&SymbolData.getSymbol()] = coff_symbol;
|
SymbolMap[&Symbol] = coff_symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// making a section real involves assigned it a number and putting
|
/// making a section real involves assigned it a number and putting
|
||||||
@ -619,8 +622,11 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
|
|||||||
|
|
||||||
for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(),
|
for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(),
|
||||||
e = Asm.symbol_end(); i != e; i++) {
|
e = Asm.symbol_end(); i != e; i++) {
|
||||||
if (ExportSymbol(*i, Asm))
|
if (ExportSymbol(*i, Asm)) {
|
||||||
DefineSymbol(*i, Asm);
|
const MCSymbol &Alias = i->getSymbol();
|
||||||
|
const MCSymbol &Symbol = Alias.AliasedSymbol();
|
||||||
|
DefineSymbol(Alias, Asm.getSymbolData(Symbol), Asm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,6 @@ public:
|
|||||||
virtual void EmitDebugLabel(MCSymbol *Symbol);
|
virtual void EmitDebugLabel(MCSymbol *Symbol);
|
||||||
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
|
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag);
|
||||||
virtual void EmitThumbFunc(MCSymbol *Func);
|
virtual void EmitThumbFunc(MCSymbol *Func);
|
||||||
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value);
|
|
||||||
virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
|
virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute);
|
||||||
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
|
virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue);
|
||||||
virtual void BeginCOFFSymbolDef(MCSymbol const *Symbol);
|
virtual void BeginCOFFSymbolDef(MCSymbol const *Symbol);
|
||||||
@ -201,44 +200,6 @@ void WinCOFFStreamer::EmitThumbFunc(MCSymbol *Func) {
|
|||||||
llvm_unreachable("not implemented");
|
llvm_unreachable("not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinCOFFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
|
|
||||||
assert((Symbol->isInSection()
|
|
||||||
? Symbol->getSection().getVariant() == MCSection::SV_COFF
|
|
||||||
: true) && "Got non COFF section in the COFF backend!");
|
|
||||||
// FIXME: This is all very ugly and depressing. What needs to happen here
|
|
||||||
// depends on quite a few things that are all part of relaxation, which we
|
|
||||||
// don't really even do.
|
|
||||||
|
|
||||||
if (Value->getKind() != MCExpr::SymbolRef) {
|
|
||||||
MCObjectStreamer::EmitAssignment(Symbol, Value);
|
|
||||||
} else {
|
|
||||||
// FIXME: This is a horrible way to do this :(. This should really be
|
|
||||||
// handled after we are done with the MC* objects and immediately before
|
|
||||||
// writing out the object file when we know exactly what the symbol should
|
|
||||||
// look like in the coff symbol table. I'm not doing that now because the
|
|
||||||
// COFF object writer doesn't have a clearly defined separation between MC
|
|
||||||
// data structures, the object writers data structures, and the raw, POD,
|
|
||||||
// data structures that get written to disk.
|
|
||||||
|
|
||||||
// Copy over the aliased data.
|
|
||||||
MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol);
|
|
||||||
const MCSymbolData &RealSD = getAssembler().getOrCreateSymbolData(
|
|
||||||
dyn_cast<const MCSymbolRefExpr>(Value)->getSymbol());
|
|
||||||
|
|
||||||
// FIXME: This is particularly nasty because it breaks as soon as any data
|
|
||||||
// members of MCSymbolData change.
|
|
||||||
SD.CommonAlign = RealSD.CommonAlign;
|
|
||||||
SD.CommonSize = RealSD.CommonSize;
|
|
||||||
SD.Flags = RealSD.Flags;
|
|
||||||
SD.Fragment = RealSD.Fragment;
|
|
||||||
SD.Index = RealSD.Index;
|
|
||||||
SD.IsExternal = RealSD.IsExternal;
|
|
||||||
SD.IsPrivateExtern = RealSD.IsPrivateExtern;
|
|
||||||
SD.Offset = RealSD.Offset;
|
|
||||||
SD.SymbolSize = RealSD.SymbolSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
|
void WinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol,
|
||||||
MCSymbolAttr Attribute) {
|
MCSymbolAttr Attribute) {
|
||||||
assert(Symbol && "Symbol must be non-null!");
|
assert(Symbol && "Symbol must be non-null!");
|
||||||
|
@ -23,8 +23,11 @@ _bar:
|
|||||||
.long 0 # 0x0
|
.long 0 # 0x0
|
||||||
|
|
||||||
|
|
||||||
|
# Order is important here. Assign _bar_alias_alias before _bar_alias.
|
||||||
.globl _foo_alias
|
.globl _foo_alias
|
||||||
_foo_alias = _foo
|
_foo_alias = _foo
|
||||||
|
.globl _bar_alias_alias
|
||||||
|
_bar_alias_alias = _bar_alias
|
||||||
.globl _bar_alias
|
.globl _bar_alias
|
||||||
_bar_alias = _bar
|
_bar_alias = _bar
|
||||||
|
|
||||||
@ -52,6 +55,14 @@ _bar_alias = _bar
|
|||||||
// CHECK-NEXT: StorageClass = [[FOO_STORAGE_CLASS]]
|
// CHECK-NEXT: StorageClass = [[FOO_STORAGE_CLASS]]
|
||||||
// CHECK-NEXT: NumberOfAuxSymbols = [[FOO_NUMBER_OF_AUX_SYMBOLS]]
|
// CHECK-NEXT: NumberOfAuxSymbols = [[FOO_NUMBER_OF_AUX_SYMBOLS]]
|
||||||
|
|
||||||
|
// CHECK: Name = {{_?}}bar_alias_alias
|
||||||
|
// CHECK-NEXT: Value = [[BAR_VALUE]]
|
||||||
|
// CHECK-NEXT: SectionNumber = [[BAR_SECTION_NUMBER]]
|
||||||
|
// CHECK-NEXT: SimpleType = [[BAR_SIMPLE_TYPE]]
|
||||||
|
// CHECK-NEXT: ComplexType = [[BAR_COMPLEX_TYPE]]
|
||||||
|
// CHECK-NEXT: StorageClass = [[BAR_STORAGE_CLASS]]
|
||||||
|
// CHECK-NEXT: NumberOfAuxSymbols = [[BAR_NUMBER_OF_AUX_SYMBOLS]]
|
||||||
|
|
||||||
// CHECK: Name = {{_?}}bar_alias
|
// CHECK: Name = {{_?}}bar_alias
|
||||||
// CHECK-NEXT: Value = [[BAR_VALUE]]
|
// CHECK-NEXT: Value = [[BAR_VALUE]]
|
||||||
// CHECK-NEXT: SectionNumber = [[BAR_SECTION_NUMBER]]
|
// CHECK-NEXT: SectionNumber = [[BAR_SECTION_NUMBER]]
|
||||||
|
Loading…
Reference in New Issue
Block a user