From 6a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sat, 12 May 2012 14:30:47 +0000 Subject: [PATCH] ELF: Add support for the asm .version directive. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156712 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/MC/MCParser/ELFAsmParser.cpp | 28 ++++++++++++++++++++++++++++ test/MC/ELF/version.s | 17 +++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 test/MC/ELF/version.s diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp index ffc400b203f..9316bb1c1cd 100644 --- a/lib/MC/MCParser/ELFAsmParser.cpp +++ b/lib/MC/MCParser/ELFAsmParser.cpp @@ -64,6 +64,7 @@ public: AddDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type"); AddDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident"); AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver"); + AddDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version"); AddDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref"); AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak"); AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local"); @@ -141,6 +142,7 @@ public: bool ParseDirectiveType(StringRef, SMLoc); bool ParseDirectiveIdent(StringRef, SMLoc); bool ParseDirectiveSymver(StringRef, SMLoc); + bool ParseDirectiveVersion(StringRef, SMLoc); bool ParseDirectiveWeakref(StringRef, SMLoc); bool ParseDirectiveSymbolAttribute(StringRef, SMLoc); @@ -548,6 +550,32 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) { return false; } +/// ParseDirectiveVersion +/// ::= .version string +bool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) { + if (getLexer().isNot(AsmToken::String)) + return TokError("unexpected token in '.version' directive"); + + StringRef Data = getTok().getIdentifier(); + + Lex(); + + const MCSection *Note = + getContext().getELFSection(".note", ELF::SHT_NOTE, 0, + SectionKind::getReadOnly()); + + getStreamer().PushSection(); + getStreamer().SwitchSection(Note); + getStreamer().EmitIntValue(Data.size()+1, 4); // namesz. + getStreamer().EmitIntValue(0, 4); // descsz = 0 (no description). + getStreamer().EmitIntValue(1, 4); // type = NT_VERSION. + getStreamer().EmitBytes(Data, 0); // name. + getStreamer().EmitIntValue(0, 1); // terminate the string. + getStreamer().EmitValueToAlignment(4); // ensure 4 byte alignment. + getStreamer().PopSection(); + return false; +} + /// ParseDirectiveWeakref /// ::= .weakref foo, bar bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) { diff --git a/test/MC/ELF/version.s b/test/MC/ELF/version.s new file mode 100644 index 00000000000..31e952afeb4 --- /dev/null +++ b/test/MC/ELF/version.s @@ -0,0 +1,17 @@ +// RUN: llvm-mc -filetype=obj -triple i386-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s + +.version "1234" +.version "123" + +// CHECK: (('sh_name', 0x0000000c) # '.note' +// CHECK-NEXT: ('sh_type', 0x00000007) +// CHECK-NEXT: ('sh_flags', 0x00000000) +// CHECK-NEXT: ('sh_addr', 0x00000000) +// CHECK-NEXT: ('sh_offset', 0x00000034) +// CHECK-NEXT: ('sh_size', 0x00000024) +// CHECK-NEXT: ('sh_link', 0x00000000) +// CHECK-NEXT: ('sh_info', 0x00000000) +// CHECK-NEXT: ('sh_addralign', 0x00000004) +// CHECK-NEXT: ('sh_entsize', 0x00000000) +// CHECK-NEXT: ('_section_data', '05000000 00000000 01000000 31323334 00000000 04000000 00000000 01000000 31323300') +// CHECK-NEXT: ),