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,
MCDataFragment *ShndxF,
ELFSymbolData &MSD,
// Binding and Type share the same byte as upper and lower nibbles
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)
Type = ELF::STT_FUNC;
uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
--- /dev/null
+// 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: }