[llvm-commits] [llvm] r117448 - in /llvm/trunk: lib/MC/ELFObjectWriter.cpp lib/MC/MCParser/ELFAsmParser.cpp test/MC/ELF/symref.s
Rafael Espindola
rafael.espindola at gmail.com
Wed Oct 27 08:18:17 PDT 2010
Author: rafael
Date: Wed Oct 27 10:18:17 2010
New Revision: 117448
URL: http://llvm.org/viewvc/llvm-project?rev=117448&view=rev
Log:
Add support for the .symver directive. This is really ugly, but most of it is
contained in the ELF object writer.
Added:
llvm/trunk/test/MC/ELF/symref.s
Modified:
llvm/trunk/lib/MC/ELFObjectWriter.cpp
llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp
Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=117448&r1=117447&r2=117448&view=diff
==============================================================================
--- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
+++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Wed Oct 27 10:18:17 2010
@@ -134,6 +134,7 @@
};
SmallPtrSet<const MCSymbol *, 16> UsedInReloc;
+ DenseMap<const MCSymbol *, const MCSymbol *> Renames;
llvm::DenseMap<const MCSectionData*,
std::vector<ELFRelocationEntry> > Relocations;
@@ -292,8 +293,7 @@
void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout);
- void ExecutePostLayoutBinding(MCAssembler &Asm) {
- }
+ void ExecutePostLayoutBinding(MCAssembler &Asm);
void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
uint64_t Address, uint64_t Offset,
@@ -449,6 +449,30 @@
return *S;
}
+void ELFObjectWriterImpl::ExecutePostLayoutBinding(MCAssembler &Asm) {
+ // The presence of symbol versions causes undefined symbols and
+ // versions declared with @@@ to be renamed.
+
+ 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);
+ const StringRef &AliasName = Alias.getName();
+ size_t Pos = AliasName.find('@');
+ if (Pos == StringRef::npos)
+ continue;
+
+ StringRef Rest(AliasName.begin() + Pos);
+ if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
+ continue;
+
+ std::pair<const MCSymbol *, const MCSymbol *> t(&Symbol, &Alias);
+ Renames.insert(t);
+ }
+}
+
void ELFObjectWriterImpl::WriteSymbol(MCDataFragment *F, ELFSymbolData &MSD,
const MCAsmLayout &Layout) {
MCSymbolData &OrigData = *MSD.SymbolData;
@@ -593,6 +617,9 @@
bool IsPCRel = isFixupKindX86PCRel(Fixup.getKind());
if (!Target.isAbsolute()) {
Symbol = &AliasedSymbol(Target.getSymA()->getSymbol());
+ const MCSymbol *Renamed = Renames.lookup(Symbol);
+ if (Renamed)
+ Symbol = Renamed;
MCSymbolData &SD = Asm.getSymbolData(*Symbol);
MCFragment *F = SD.getFragment();
@@ -765,10 +792,13 @@
}
static bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data,
- bool Used) {
+ bool Used, bool Renamed) {
if (Used)
return true;
+ if (Renamed)
+ return false;
+
const MCSymbol &Symbol = Data.getSymbol();
const MCSymbol &A = AliasedSymbol(Symbol);
@@ -821,40 +851,52 @@
ie = Asm.symbol_end(); it != ie; ++it) {
const MCSymbol &Symbol = it->getSymbol();
- if (!isInSymtab(Asm, *it, UsedInReloc.count(&Symbol)))
+ if (!isInSymtab(Asm, *it, UsedInReloc.count(&Symbol),
+ Renames.count(&Symbol)))
continue;
ELFSymbolData MSD;
MSD.SymbolData = it;
bool Local = isLocal(*it);
+ const MCSymbol &RefSymbol = AliasedSymbol(Symbol);
if (it->isCommon()) {
assert(!Local);
MSD.SectionIndex = ELF::SHN_COMMON;
} else if (Symbol.isAbsolute()) {
MSD.SectionIndex = ELF::SHN_ABS;
- } else if (Symbol.isVariable()) {
- const MCSymbol &RefSymbol = AliasedSymbol(Symbol);
- if (RefSymbol.isDefined()) {
- MSD.SectionIndex = SectionIndexMap.lookup(&RefSymbol.getSection());
- assert(MSD.SectionIndex && "Invalid section index!");
- }
- } else if (Symbol.isUndefined()) {
- assert(!Local);
+ } 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 if (Symbol.isVariable()) {
+ MSD.SectionIndex = SectionIndexMap.lookup(&RefSymbol.getSection());
+ assert(MSD.SectionIndex && "Invalid section index!");
} else {
MSD.SectionIndex = SectionIndexMap.lookup(&Symbol.getSection());
assert(MSD.SectionIndex && "Invalid section index!");
}
- uint64_t &Entry = StringIndexMap[Symbol.getName()];
+ // The @@@ in symbol version is replaced with @ in undefined symbols and
+ // @@ in defined ones.
+ StringRef Name = Symbol.getName();
+ size_t Pos = Name.find("@@@");
+ std::string FinalName;
+ if (Pos != StringRef::npos) {
+ StringRef Prefix(Name.begin(), Pos);
+ unsigned n = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
+ StringRef Suffix(Name.begin() + Pos + n);
+ FinalName = Prefix.str() + Suffix.str();
+ } else {
+ FinalName = Name.str();
+ }
+
+ uint64_t &Entry = StringIndexMap[FinalName];
if (!Entry) {
Entry = StringTable.size();
- StringTable += Symbol.getName();
+ StringTable += FinalName;
StringTable += '\x00';
}
MSD.StringIndex = Entry;
Modified: llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp?rev=117448&r1=117447&r2=117448&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/ELFAsmParser.cpp Wed Oct 27 10:18:17 2010
@@ -12,6 +12,7 @@
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
@@ -51,6 +52,7 @@
AddDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous");
AddDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type");
AddDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident");
+ AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver");
}
// FIXME: Part of this logic is duplicated in the MCELFStreamer. What is
@@ -116,6 +118,7 @@
bool ParseDirectivePrevious(StringRef, SMLoc);
bool ParseDirectiveType(StringRef, SMLoc);
bool ParseDirectiveIdent(StringRef, SMLoc);
+ bool ParseDirectiveSymver(StringRef, SMLoc);
private:
bool ParseSectionName(StringRef &SectionName);
@@ -377,6 +380,33 @@
return false;
}
+/// ParseDirectiveSymver
+/// ::= .symver foo, bar2 at zed
+bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
+ StringRef Name;
+ if (getParser().ParseIdentifier(Name))
+ return TokError("expected identifier in directive");
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("expected a comma");
+
+ Lex();
+
+ StringRef AliasName;
+ if (getParser().ParseIdentifier(AliasName))
+ return TokError("expected identifier in directive");
+
+ if (AliasName.find('@') == StringRef::npos)
+ return TokError("expected a '@' in the name");
+
+ MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName);
+ MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
+ const MCExpr *Value = MCSymbolRefExpr::Create(Sym, getContext());
+
+ getStreamer().EmitAssignment(Alias, Value);
+ return false;
+}
+
namespace llvm {
MCAsmParserExtension *createELFAsmParser() {
Added: llvm/trunk/test/MC/ELF/symref.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/symref.s?rev=117448&view=auto
==============================================================================
--- llvm/trunk/test/MC/ELF/symref.s (added)
+++ llvm/trunk/test/MC/ELF/symref.s Wed Oct 27 10:18:17 2010
@@ -0,0 +1,142 @@
+// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump | FileCheck %s
+
+defined1:
+defined2:
+defined3:
+ .symver defined1, bar1 at zed
+ .symver undefined1, bar2 at zed
+
+ .symver defined2, bar3@@zed
+
+ .symver defined3, bar5@@@zed
+ .symver undefined3, bar6@@@zed
+
+ .long defined1
+ .long undefined1
+ .long defined2
+ .long defined3
+ .long undefined3
+
+// CHECK: # Symbol 0x00000001
+// CHECK-NEXT: (('st_name', 0x00000013) # 'bar1 at zed'
+// CHECK-NEXT: ('st_bind', 0x00000000)
+// CHECK-NEXT: ('st_type', 0x00000000)
+// CHECK-NEXT: ('st_other', 0x00000000)
+// CHECK-NEXT: ('st_shndx', 0x00000001)
+// CHECK-NEXT: ('st_value', 0x00000000)
+// CHECK-NEXT: ('st_size', 0x00000000)
+// CHECK-NEXT: ),
+// CHECK-NEXT: # Symbol 0x00000002
+// CHECK-NEXT: (('st_name', 0x00000025) # 'bar3@@zed'
+// CHECK-NEXT: ('st_bind', 0x00000000)
+// CHECK-NEXT: ('st_type', 0x00000000)
+// CHECK-NEXT: ('st_other', 0x00000000)
+// CHECK-NEXT: ('st_shndx', 0x00000001)
+// CHECK-NEXT: ('st_value', 0x00000000)
+// CHECK-NEXT: ('st_size', 0x00000000)
+// CHECK-NEXT: ),
+// CHECK-NEXT: # Symbol 0x00000003
+// CHECK-NEXT: (('st_name', 0x0000002f) # 'bar5@@zed'
+// CHECK-NEXT: ('st_bind', 0x00000000)
+// CHECK-NEXT: ('st_type', 0x00000000)
+// CHECK-NEXT: ('st_other', 0x00000000)
+// CHECK-NEXT: ('st_shndx', 0x00000001)
+// CHECK-NEXT: ('st_value', 0x00000000)
+// CHECK-NEXT: ('st_size', 0x00000000)
+// CHECK-NEXT: ),
+// CHECK-NEXT: # Symbol 0x00000004
+// CHECK-NEXT: (('st_name', 0x00000001) # 'defined1'
+// CHECK-NEXT: ('st_bind', 0x00000000)
+// CHECK-NEXT: ('st_type', 0x00000000)
+// CHECK-NEXT: ('st_other', 0x00000000)
+// CHECK-NEXT: ('st_shndx', 0x00000001)
+// CHECK-NEXT: ('st_value', 0x00000000)
+// CHECK-NEXT: ('st_size', 0x00000000)
+// CHECK-NEXT: ),
+// CHECK-NEXT: # Symbol 0x00000005
+// CHECK-NEXT: (('st_name', 0x0000000a) # 'defined2'
+// CHECK-NEXT: ('st_bind', 0x00000000)
+// CHECK-NEXT: ('st_type', 0x00000000)
+// CHECK-NEXT: ('st_other', 0x00000000)
+// CHECK-NEXT: ('st_shndx', 0x00000001)
+// CHECK-NEXT: ('st_value', 0x00000000)
+// CHECK-NEXT: ('st_size', 0x00000000)
+// CHECK-NEXT: ),
+// CHECK-NEXT: # Symbol 0x00000006
+// CHECK-NEXT: (('st_name', 0x00000000) # ''
+// CHECK-NEXT: ('st_bind', 0x00000000)
+// CHECK-NEXT: ('st_type', 0x00000003)
+// CHECK-NEXT: ('st_other', 0x00000000)
+// CHECK-NEXT: ('st_shndx', 0x00000001)
+// CHECK-NEXT: ('st_value', 0x00000000)
+// CHECK-NEXT: ('st_size', 0x00000000)
+// CHECK-NEXT: ),
+// CHECK-NEXT: # Symbol 0x00000007
+// CHECK-NEXT: (('st_name', 0x00000000) # ''
+// CHECK-NEXT: ('st_bind', 0x00000000)
+// CHECK-NEXT: ('st_type', 0x00000003)
+// CHECK-NEXT: ('st_other', 0x00000000)
+// CHECK-NEXT: ('st_shndx', 0x00000002)
+// CHECK-NEXT: ('st_value', 0x00000000)
+// CHECK-NEXT: ('st_size', 0x00000000)
+// CHECK-NEXT: ),
+// CHECK-NEXT: # Symbol 0x00000008
+// CHECK-NEXT: (('st_name', 0x00000000) # ''
+// CHECK-NEXT: ('st_bind', 0x00000000)
+// CHECK-NEXT: ('st_type', 0x00000003)
+// CHECK-NEXT: ('st_other', 0x00000000)
+// CHECK-NEXT: ('st_shndx', 0x00000003)
+// CHECK-NEXT: ('st_value', 0x00000000)
+// CHECK-NEXT: ('st_size', 0x00000000)
+// CHECK-NEXT: ),
+// CHECK-NEXT: # Symbol 0x00000009
+// CHECK-NEXT: (('st_name', 0x0000001c) # 'bar2 at zed'
+// CHECK-NEXT: ('st_bind', 0x00000001)
+// CHECK-NEXT: ('st_type', 0x00000000)
+// CHECK-NEXT: ('st_other', 0x00000000)
+// CHECK-NEXT: ('st_shndx', 0x00000000)
+// CHECK-NEXT: ('st_value', 0x00000000)
+// CHECK-NEXT: ('st_size', 0x00000000)
+// CHECK-NEXT: ),
+// CHECK-NEXT: # Symbol 0x0000000a
+// CHECK-NEXT: (('st_name', 0x00000039) # 'bar6 at zed'
+// CHECK-NEXT: ('st_bind', 0x00000001)
+// CHECK-NEXT: ('st_type', 0x00000000)
+// CHECK-NEXT: ('st_other', 0x00000000)
+// CHECK-NEXT: ('st_shndx', 0x00000000)
+// CHECK-NEXT: ('st_value', 0x00000000)
+// CHECK-NEXT: ('st_size', 0x00000000)
+// CHECK-NEXT: ),
+// CHECK-NEXT:])
+
+// CHECK: # Relocation 0x00000000
+// CHECK-NEXT: (('r_offset', 0x00000000)
+// CHECK-NEXT: ('r_sym', 0x00000006)
+// CHECK-NEXT: ('r_type', 0x0000000a)
+// CHECK-NEXT: ('r_addend', 0x00000000)
+// CHECK-NEXT: ),
+// CHECK-NEXT: # Relocation 0x00000001
+// CHECK-NEXT: (('r_offset', 0x00000004)
+// CHECK-NEXT: ('r_sym', 0x00000009)
+// CHECK-NEXT: ('r_type', 0x0000000a)
+// CHECK-NEXT: ('r_addend', 0x00000000)
+// CHECK-NEXT: ),
+// CHECK-NEXT: # Relocation 0x00000002
+// CHECK-NEXT: (('r_offset', 0x00000008)
+// CHECK-NEXT: ('r_sym', 0x00000006)
+// CHECK-NEXT: ('r_type', 0x0000000a)
+// CHECK-NEXT: ('r_addend', 0x00000000)
+// CHECK-NEXT: ),
+// CHECK-NEXT: # Relocation 0x00000003
+// CHECK-NEXT: (('r_offset', 0x0000000c)
+// CHECK-NEXT: ('r_sym', 0x00000006)
+// CHECK-NEXT: ('r_type', 0x0000000a)
+// CHECK-NEXT: ('r_addend', 0x00000000)
+// CHECK-NEXT: ),
+// CHECK-NEXT: # Relocation 0x00000004
+// CHECK-NEXT: (('r_offset', 0x00000010)
+// CHECK-NEXT: ('r_sym', 0x0000000a)
+// CHECK-NEXT: ('r_type', 0x0000000a)
+// CHECK-NEXT: ('r_addend', 0x00000000)
+// CHECK-NEXT: ),
+// CHECK-NEXT:])
More information about the llvm-commits
mailing list