mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-26 23:32:58 +00:00
COFF: Fix weak external aliases.
Differential Revision: http://llvm-reviews.chandlerc.com/D700 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180034 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2fdbbe307d
commit
4974b972e7
@ -147,8 +147,7 @@ public:
|
||||
object_t *createCOFFEntity(StringRef Name, list_t &List);
|
||||
|
||||
void DefineSection(MCSectionData const &SectionData);
|
||||
void DefineSymbol(MCSymbol const &Symbol,
|
||||
MCSymbolData const &SymbolData,
|
||||
void DefineSymbol(MCSymbolData const &SymbolData,
|
||||
MCAssembler &Assembler);
|
||||
|
||||
void MakeSymbolReal(COFFSymbol &S, size_t Index);
|
||||
@ -410,25 +409,23 @@ void WinCOFFObjectWriter::DefineSection(MCSectionData const &SectionData) {
|
||||
|
||||
/// This function takes a section data object from the assembler
|
||||
/// and creates the associated COFF symbol staging object.
|
||||
void WinCOFFObjectWriter::DefineSymbol(MCSymbol const &Symbol,
|
||||
MCSymbolData const &SymbolData,
|
||||
void WinCOFFObjectWriter::DefineSymbol(MCSymbolData const &SymbolData,
|
||||
MCAssembler &Assembler) {
|
||||
MCSymbol const &Symbol = SymbolData.getSymbol();
|
||||
COFFSymbol *coff_symbol = GetOrCreateCOFFSymbol(&Symbol);
|
||||
|
||||
coff_symbol->Data.Type = (SymbolData.getFlags() & 0x0000FFFF) >> 0;
|
||||
coff_symbol->Data.StorageClass = (SymbolData.getFlags() & 0x00FF0000) >> 16;
|
||||
SymbolMap[&Symbol] = coff_symbol;
|
||||
|
||||
if (SymbolData.getFlags() & COFF::SF_WeakExternal) {
|
||||
coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
|
||||
|
||||
if (Symbol.isVariable()) {
|
||||
coff_symbol->Data.StorageClass = COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL;
|
||||
const MCSymbolRefExpr *SymRef =
|
||||
dyn_cast<MCSymbolRefExpr>(Symbol.getVariableValue());
|
||||
|
||||
// FIXME: This assert message isn't very good.
|
||||
assert(Symbol.getVariableValue()->getKind() == MCExpr::SymbolRef &&
|
||||
"Value must be a SymbolRef!");
|
||||
if (!SymRef)
|
||||
report_fatal_error("Weak externals may only alias symbols");
|
||||
|
||||
coff_symbol->Other = GetOrCreateCOFFSymbol(&Symbol);
|
||||
coff_symbol->Other = GetOrCreateCOFFSymbol(&SymRef->getSymbol());
|
||||
} else {
|
||||
std::string WeakName = std::string(".weak.")
|
||||
+ Symbol.getName().str()
|
||||
@ -448,23 +445,29 @@ void WinCOFFObjectWriter::DefineSymbol(MCSymbol const &Symbol,
|
||||
coff_symbol->Aux[0].Aux.WeakExternal.TagIndex = 0;
|
||||
coff_symbol->Aux[0].Aux.WeakExternal.Characteristics =
|
||||
COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY;
|
||||
|
||||
coff_symbol->MCData = &SymbolData;
|
||||
} else {
|
||||
const MCSymbolData &ResSymData =
|
||||
Assembler.getSymbolData(Symbol.AliasedSymbol());
|
||||
|
||||
coff_symbol->Data.Type = (ResSymData.getFlags() & 0x0000FFFF) >> 0;
|
||||
coff_symbol->Data.StorageClass = (ResSymData.getFlags() & 0x00FF0000) >> 16;
|
||||
|
||||
// If no storage class was specified in the streamer, define it here.
|
||||
if (coff_symbol->Data.StorageClass == 0) {
|
||||
bool external = ResSymData.isExternal() || (ResSymData.Fragment == NULL);
|
||||
|
||||
coff_symbol->Data.StorageClass =
|
||||
external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC;
|
||||
}
|
||||
|
||||
if (ResSymData.Fragment != NULL)
|
||||
coff_symbol->Section =
|
||||
SectionMap[&ResSymData.Fragment->getParent()->getSection()];
|
||||
|
||||
coff_symbol->MCData = &ResSymData;
|
||||
}
|
||||
|
||||
// If no storage class was specified in the streamer, define it here.
|
||||
if (coff_symbol->Data.StorageClass == 0) {
|
||||
bool external = SymbolData.isExternal() || (SymbolData.Fragment == NULL);
|
||||
|
||||
coff_symbol->Data.StorageClass =
|
||||
external ? COFF::IMAGE_SYM_CLASS_EXTERNAL : COFF::IMAGE_SYM_CLASS_STATIC;
|
||||
}
|
||||
|
||||
if (SymbolData.Fragment != NULL)
|
||||
coff_symbol->Section =
|
||||
SectionMap[&SymbolData.Fragment->getParent()->getSection()];
|
||||
|
||||
// Bind internal COFF symbol to MC symbol.
|
||||
coff_symbol->MCData = &SymbolData;
|
||||
SymbolMap[&Symbol] = coff_symbol;
|
||||
}
|
||||
|
||||
/// making a section real involves assigned it a number and putting
|
||||
@ -620,9 +623,7 @@ void WinCOFFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm,
|
||||
for (MCAssembler::const_symbol_iterator i = Asm.symbol_begin(),
|
||||
e = Asm.symbol_end(); i != e; i++) {
|
||||
if (ExportSymbol(*i, Asm)) {
|
||||
const MCSymbol &Alias = i->getSymbol();
|
||||
const MCSymbol &Symbol = Alias.AliasedSymbol();
|
||||
DefineSymbol(Alias, Asm.getSymbolData(Symbol), Asm);
|
||||
DefineSymbol(*i, Asm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,9 @@ LBB0_2: # %return
|
||||
|
||||
.weak _test_weak
|
||||
|
||||
.weak _test_weak_alias
|
||||
_test_weak_alias=_main
|
||||
|
||||
// CHECK: Symbols [
|
||||
|
||||
// CHECK: Symbol {
|
||||
@ -55,3 +58,18 @@ LBB0_2: # %return
|
||||
// CHECK-NEXT: StorageClass: External
|
||||
// CHECK-NEXT: AuxSymbolCount: 0
|
||||
// CHECK-NEXT: }
|
||||
|
||||
// CHECK: Symbol {
|
||||
// CHECK: Name: _test_weak_alias
|
||||
// CHECK-NEXT: Value: 0
|
||||
// CHECK-NEXT: Section: (0)
|
||||
// CHECK-NEXT: BaseType: Null
|
||||
// CHECK-NEXT: ComplexType: Null
|
||||
// CHECK-NEXT: StorageClass: WeakExternal
|
||||
// CHECK-NEXT: AuxSymbolCount: 1
|
||||
// CHECK-NEXT: AuxWeakExternal {
|
||||
// CHECK-NEXT: Linked: _main
|
||||
// CHECK-NEXT: Search: Library
|
||||
// CHECK-NEXT: Unused: (00 00 00 00 00 00 00 00 00 00)
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
|
Loading…
x
Reference in New Issue
Block a user