diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index b979de9322c..ef2901d7497 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -465,14 +465,32 @@ void ELFObjectWriterImpl::ExecutePostLayoutBinding(MCAssembler &Asm) { for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), ie = Asm.symbol_end(); it != ie; ++it) { const MCSymbol &Alias = it->getSymbol(); - if (!Alias.isVariable()) - continue; const MCSymbol &Symbol = AliasedSymbol(Alias); + MCSymbolData &SD = Asm.getSymbolData(Symbol); + + // Undefined symbols are global, but this is the first place we + // are able to set it. + if (Symbol.isUndefined() && !Symbol.isVariable()) { + if (GetBinding(SD) == ELF::STB_LOCAL) { + SetBinding(SD, ELF::STB_GLOBAL); + SetBinding(*it, ELF::STB_GLOBAL); + } + } + + // Not an alias. + if (&Symbol == &Alias) + continue; + StringRef AliasName = Alias.getName(); size_t Pos = AliasName.find('@'); if (Pos == StringRef::npos) continue; + // Aliases defined with .symvar copy the binding from the symbol they alias. + // This is the first place we are able to copy this information. + it->setExternal(SD.isExternal()); + SetBinding(*it, GetBinding(SD)); + StringRef Rest = AliasName.substr(Pos); if (!Symbol.isUndefined() && !Rest.startswith("@@@")) continue; @@ -881,6 +899,7 @@ void ELFObjectWriterImpl::ComputeSymbolTable(MCAssembler &Asm) { MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); Data.setExternal(true); + SetBinding(Data, ELF::STB_GLOBAL); } // Build section lookup table. @@ -916,10 +935,6 @@ void ELFObjectWriterImpl::ComputeSymbolTable(MCAssembler &Asm) { MSD.SectionIndex = ELF::SHN_ABS; } else if (RefSymbol.isUndefined()) { MSD.SectionIndex = ELF::SHN_UNDEF; - // FIXME: Undefined symbols are global, but this is the first place we - // are able to set it. - if (GetBinding(*it) == ELF::STB_LOCAL) - SetBinding(*it, ELF::STB_GLOBAL); } else { MSD.SectionIndex = SectionIndexMap.lookup(&RefSymbol.getSection()); assert(MSD.SectionIndex && "Invalid section index!"); diff --git a/test/MC/ELF/symref.s b/test/MC/ELF/symref.s index df2395e9a08..f1563e58adc 100644 --- a/test/MC/ELF/symref.s +++ b/test/MC/ELF/symref.s @@ -17,6 +17,11 @@ defined3: .long defined3 .long undefined3 + .global global1 + .symver global1, g1@@zed +global1: + + // CHECK: # Symbol 0x00000001 // CHECK-NEXT: (('st_name', 0x00000013) # 'bar1@zed' // CHECK-NEXT: ('st_bind', 0x00000000) @@ -90,6 +95,24 @@ defined3: // CHECK-NEXT: ('st_size', 0x00000000) // CHECK-NEXT: ), // CHECK-NEXT: # Symbol 0x00000009 +// CHECK-NEXT: (('st_name', 0x0000004a) # 'g1@@zed' +// CHECK-NEXT: ('st_bind', 0x00000001) +// CHECK-NEXT: ('st_type', 0x00000000) +// CHECK-NEXT: ('st_other', 0x00000000) +// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_value', 0x00000014) +// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Symbol 0x0000000a +// CHECK-NEXT: (('st_name', 0x00000042) # 'global1' +// CHECK-NEXT: ('st_bind', 0x00000001) +// CHECK-NEXT: ('st_type', 0x00000000) +// CHECK-NEXT: ('st_other', 0x00000000) +// CHECK-NEXT: ('st_shndx', 0x00000001) +// CHECK-NEXT: ('st_value', 0x00000014) +// CHECK-NEXT: ('st_size', 0x00000000) +// CHECK-NEXT: ), +// CHECK-NEXT: # Symbol 0x0000000b // CHECK-NEXT: (('st_name', 0x0000001c) # 'bar2@zed' // CHECK-NEXT: ('st_bind', 0x00000001) // CHECK-NEXT: ('st_type', 0x00000000) @@ -98,7 +121,7 @@ defined3: // CHECK-NEXT: ('st_value', 0x00000000) // CHECK-NEXT: ('st_size', 0x00000000) // CHECK-NEXT: ), -// CHECK-NEXT: # Symbol 0x0000000a +// CHECK-NEXT: # Symbol 0x0000000c // CHECK-NEXT: (('st_name', 0x00000039) # 'bar6@zed' // CHECK-NEXT: ('st_bind', 0x00000001) // CHECK-NEXT: ('st_type', 0x00000000) @@ -117,7 +140,7 @@ defined3: // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000001 // CHECK-NEXT: (('r_offset', 0x00000004) -// CHECK-NEXT: ('r_sym', 0x00000009) +// CHECK-NEXT: ('r_sym', 0x0000000b) // CHECK-NEXT: ('r_type', 0x0000000a) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ), @@ -135,7 +158,7 @@ defined3: // CHECK-NEXT: ), // CHECK-NEXT: # Relocation 0x00000004 // CHECK-NEXT: (('r_offset', 0x00000010) -// CHECK-NEXT: ('r_sym', 0x0000000a) +// CHECK-NEXT: ('r_sym', 0x0000000c) // CHECK-NEXT: ('r_type', 0x0000000a) // CHECK-NEXT: ('r_addend', 0x00000000) // CHECK-NEXT: ),