mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 07:11:49 +00:00
Propagate types from symbol to aliases.
This is similar, but not identical to what gas does. The logic in MC is to just compute the symbol table after parsing the entire file. GAS is mixed, given .type b, @object a = b b: .type b, @function It will propagate the change and make 'a' a function. Given .type b, @object b: a = b .type b, @function the type of 'a' is still object. Since we do the computation in the end, we produce a function in both cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204555 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c8ca83201c
commit
4ff2dadebe
@ -575,6 +575,22 @@ static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) {
|
|||||||
return Type;
|
return Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const MCSymbol *getBaseSymbol(const MCAsmLayout &Layout,
|
||||||
|
const MCSymbol &Symbol) {
|
||||||
|
if (!Symbol.isVariable())
|
||||||
|
return &Symbol;
|
||||||
|
|
||||||
|
const MCExpr *Expr = Symbol.getVariableValue();
|
||||||
|
MCValue Value;
|
||||||
|
if (!Expr->EvaluateAsRelocatable(Value, &Layout))
|
||||||
|
llvm_unreachable("Invalid Expression");
|
||||||
|
assert(!Value.getSymB());
|
||||||
|
const MCSymbolRefExpr *A = Value.getSymA();
|
||||||
|
if (!A)
|
||||||
|
return nullptr;
|
||||||
|
return getBaseSymbol(Layout, A->getSymbol());
|
||||||
|
}
|
||||||
|
|
||||||
void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
|
void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
|
||||||
MCDataFragment *ShndxF,
|
MCDataFragment *ShndxF,
|
||||||
ELFSymbolData &MSD,
|
ELFSymbolData &MSD,
|
||||||
@ -588,7 +604,12 @@ void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
|
|||||||
|
|
||||||
// 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);
|
||||||
uint8_t Type = mergeTypeForSet(MCELF::GetType(OrigData), MCELF::GetType(Data));
|
uint8_t Type = MCELF::GetType(OrigData);
|
||||||
|
const MCSymbol *Base = getBaseSymbol(Layout, OrigData.getSymbol());
|
||||||
|
if (Base) {
|
||||||
|
MCSymbolData BaseSD = Layout.getAssembler().getSymbolData(*Base);
|
||||||
|
Type = mergeTypeForSet(Type, MCELF::GetType(BaseSD));
|
||||||
|
}
|
||||||
if (OrigData.getFlags() & ELF_Other_ThumbFunc)
|
if (OrigData.getFlags() & ELF_Other_ThumbFunc)
|
||||||
Type = ELF::STT_FUNC;
|
Type = ELF::STT_FUNC;
|
||||||
uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
|
uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
|
||||||
|
157
test/MC/ELF/type-propagate.s
Normal file
157
test/MC/ELF/type-propagate.s
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -t - | FileCheck %s
|
||||||
|
|
||||||
|
// This tests that types are propagated from symbols to their aliases. Our
|
||||||
|
// behavior is a bit different than gas. If the type of a symbol changes,
|
||||||
|
// gas will update the type of the aliases only if those aliases were declare
|
||||||
|
// at a point in the file where the aliased symbol was already define.
|
||||||
|
|
||||||
|
// The lines marked with GAS illustrate this difference.
|
||||||
|
|
||||||
|
|
||||||
|
.type sym01, @object
|
||||||
|
sym01:
|
||||||
|
.type sym02, @function
|
||||||
|
sym02:
|
||||||
|
|
||||||
|
sym03 = sym01
|
||||||
|
sym04 = sym03
|
||||||
|
.type sym03, @function
|
||||||
|
sym05 = sym03
|
||||||
|
sym06 = sym01 - sym02
|
||||||
|
sym07 = sym02 - sym01
|
||||||
|
|
||||||
|
sym08 = sym10
|
||||||
|
sym09 = sym10 + 1
|
||||||
|
.type sym10, @object
|
||||||
|
sym10:
|
||||||
|
|
||||||
|
sym11 = sym10
|
||||||
|
sym12 = sym10 + 1
|
||||||
|
.type sym10, @function
|
||||||
|
|
||||||
|
// CHECK: Symbol {
|
||||||
|
// CHECK: Name: sym01
|
||||||
|
// CHECK-NEXT: Value: 0x0
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Local (0x0)
|
||||||
|
// CHECK-NEXT: Type: Object (0x1)
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
// CHECK-NEXT: Section: .text (0x1)
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: Symbol {
|
||||||
|
// CHECK-NEXT: Name: sym02
|
||||||
|
// CHECK-NEXT: Value: 0x0
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Local (0x0)
|
||||||
|
// CHECK-NEXT: Type: Function (0x2)
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
// CHECK-NEXT: Section: .text (0x1)
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: Symbol {
|
||||||
|
// CHECK-NEXT: Name: sym03
|
||||||
|
// CHECK-NEXT: Value: 0x0
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Local (0x0)
|
||||||
|
// CHECK-NEXT: Type: Function (0x2)
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
// CHECK-NEXT: Section: .text (0x1)
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: Symbol {
|
||||||
|
// CHECK-NEXT: Name: sym04
|
||||||
|
// CHECK-NEXT: Value: 0x0
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Local (0x0)
|
||||||
|
// CHECK-NEXT: Type: Object (0x1)
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
// CHECK-NEXT: Section: .text (0x1)
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: Symbol {
|
||||||
|
// CHECK-NEXT: Name: sym05
|
||||||
|
// CHECK-NEXT: Value: 0x0
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Local (0x0)
|
||||||
|
|
||||||
|
// GAS: Type: Function (0x2)
|
||||||
|
// CHECK-NEXT: Type: Object (0x1)
|
||||||
|
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
// CHECK-NEXT: Section: .text (0x1)
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: Symbol {
|
||||||
|
// CHECK-NEXT: Name: sym06
|
||||||
|
// CHECK-NEXT: Value: 0x0
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Local (0x0)
|
||||||
|
// CHECK-NEXT: Type: None (0x0)
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
// CHECK-NEXT: Section: (0xFFF1)
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: Symbol {
|
||||||
|
// CHECK-NEXT: Name: sym07
|
||||||
|
// CHECK-NEXT: Value: 0x0
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Local (0x0)
|
||||||
|
// CHECK-NEXT: Type: None (0x0)
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
// CHECK-NEXT: Section: (0xFFF1)
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: Symbol {
|
||||||
|
// CHECK-NEXT: Name: sym08
|
||||||
|
// CHECK-NEXT: Value: 0x0
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Local (0x0)
|
||||||
|
// CHECK-NEXT: Type: Function (0x2)
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
// CHECK-NEXT: Section: .text (0x1)
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: Symbol {
|
||||||
|
// CHECK-NEXT: Name: sym09
|
||||||
|
// CHECK-NEXT: Value: 0x1
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Local (0x0)
|
||||||
|
|
||||||
|
// GAS: Type: None (0x0)
|
||||||
|
// CHECK-NEXT: Type: Function (0x2)
|
||||||
|
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
|
||||||
|
// GAS: Section: .text (0x1)
|
||||||
|
// CHECK-NEXT: Section: (0xFFF1)
|
||||||
|
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: Symbol {
|
||||||
|
// CHECK-NEXT: Name: sym10
|
||||||
|
// CHECK-NEXT: Value: 0x0
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Local (0x0)
|
||||||
|
// CHECK-NEXT: Type: Function (0x2)
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
// CHECK-NEXT: Section: .text (0x1)
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: Symbol {
|
||||||
|
// CHECK-NEXT: Name: sym11
|
||||||
|
// CHECK-NEXT: Value: 0x0
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Local (0x0)
|
||||||
|
|
||||||
|
// GAS: Type: Object (0x1)
|
||||||
|
// CHECK-NEXT: Type: Function (0x2)
|
||||||
|
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
// CHECK-NEXT: Section: .text (0x1)
|
||||||
|
// CHECK-NEXT: }
|
||||||
|
// CHECK-NEXT: Symbol {
|
||||||
|
// CHECK-NEXT: Name: sym12
|
||||||
|
// CHECK-NEXT: Value: 0x1
|
||||||
|
// CHECK-NEXT: Size: 0
|
||||||
|
// CHECK-NEXT: Binding: Local (0x0)
|
||||||
|
|
||||||
|
// GAS: Type: Object (0x1)
|
||||||
|
// CHECK-NEXT: Type: Function (0x2)
|
||||||
|
|
||||||
|
// CHECK-NEXT: Other: 0
|
||||||
|
|
||||||
|
// GAS: Section: .text (0x1)
|
||||||
|
// CHECK-NEXT: Section: (0xFFF1)
|
||||||
|
|
||||||
|
// CHECK-NEXT: }
|
Loading…
Reference in New Issue
Block a user