diff options
author | Derek Schuff <dschuff@chromium.org> | 2013-05-10 16:00:11 -0700 |
---|---|---|
committer | Derek Schuff <dschuff@chromium.org> | 2013-05-10 16:00:11 -0700 |
commit | 52daf9d821c963f84dd312ff90921bfe1b1cc0a1 (patch) | |
tree | 8f94ccf4841f2a0bbfdb19bf3b230f7ad220e8ff | |
parent | 42ac59f56fb0d473f84b6be738a64e80b09557d1 (diff) |
LLVM: Add ELF Note section to NaCl object files identifying them as such to gold
This is needed to switch the native linker to one based on upstream binutils
2.23
R=mseaborn@chromium.org
BUG= https://code.google.com/p/nativeclient/issues/detail?id=2971
also related to bug https://code.google.com/p/nativeclient/issues/detail?id=3424
Review URL: https://codereview.chromium.org/15067009
-rw-r--r-- | include/llvm/MC/MCNaCl.h | 18 | ||||
-rw-r--r-- | include/llvm/Support/ELF.h | 7 | ||||
-rw-r--r-- | lib/MC/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/MC/MCNaCl.cpp | 74 | ||||
-rw-r--r-- | lib/Target/ARM/ARMAsmPrinter.cpp | 15 | ||||
-rw-r--r-- | lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp | 10 | ||||
-rw-r--r-- | lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp | 11 | ||||
-rw-r--r-- | lib/Target/Mips/MipsAsmPrinter.cpp | 15 | ||||
-rw-r--r-- | lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp | 9 | ||||
-rw-r--r-- | lib/Target/X86/X86AsmPrinter.cpp | 6 | ||||
-rw-r--r-- | test/MC/ARM/elf-note-nacl.ll | 22 | ||||
-rw-r--r-- | test/MC/Mips/elf-note-nacl.ll | 22 | ||||
-rw-r--r-- | test/MC/X86/elf-note-nacl.ll | 36 | ||||
-rw-r--r-- | tools/llvm-mc/llvm-mc.cpp | 6 |
14 files changed, 217 insertions, 35 deletions
diff --git a/include/llvm/MC/MCNaCl.h b/include/llvm/MC/MCNaCl.h new file mode 100644 index 0000000000..cf9b23ec1c --- /dev/null +++ b/include/llvm/MC/MCNaCl.h @@ -0,0 +1,18 @@ +//===- MCNaCl.h - NaCl-specific code for MC --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +namespace llvm { +class MCContext; +class MCStreamer; +class Triple; +/// Initialize target-specific bundle alignment and emit target-specific NaCl +/// ELF note sections. +void initializeNaClMCStreamer(MCStreamer &Streamer, MCContext &Ctx, + const Triple &TheTriple); +} diff --git a/include/llvm/Support/ELF.h b/include/llvm/Support/ELF.h index 5e70debea1..d665cbd18f 100644 --- a/include/llvm/Support/ELF.h +++ b/include/llvm/Support/ELF.h @@ -1324,6 +1324,13 @@ enum { PF_MASKPROC = 0xf0000000 // Bits for processor-specific semantics. }; +// @LOCALMOD-BEGIN +// Note segment descriptor types (for object files). +enum { + NT_VERSION = 1 // Note contains a version string. +}; +// @LOCALMOD-END + // Dynamic table entry for ELF32. struct Elf32_Dyn { diff --git a/lib/MC/CMakeLists.txt b/lib/MC/CMakeLists.txt index db882c020b..f2f78333b7 100644 --- a/lib/MC/CMakeLists.txt +++ b/lib/MC/CMakeLists.txt @@ -23,6 +23,7 @@ add_llvm_library(LLVMMC MCMachOStreamer.cpp MCMachObjectTargetWriter.cpp MCModule.cpp + MCNaCl.cpp MCNullStreamer.cpp MCObjectFileInfo.cpp MCObjectStreamer.cpp diff --git a/lib/MC/MCNaCl.cpp b/lib/MC/MCNaCl.cpp new file mode 100644 index 0000000000..4a6363d6c0 --- /dev/null +++ b/lib/MC/MCNaCl.cpp @@ -0,0 +1,74 @@ +//===- lib/MC/MCNaCl.cpp - NaCl-specific MC implementation ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCNaCl.h" +#include "llvm/ADT/Triple.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/Support/ELF.h" + +static const char NoteNamespace[] = "NaCl"; + +namespace llvm { +void initializeNaClMCStreamer(MCStreamer &Streamer, MCContext &Ctx, + const Triple &TheTriple) { + assert(TheTriple.isOSNaCl()); + const char *NoteName; + const char *NoteArch; + unsigned BundleAlign; + switch (TheTriple.getArch()) { + case Triple::arm: + NoteName = ".note.NaCl.ABI.arm"; + NoteArch = "arm"; + BundleAlign = 4; + break; + case Triple::mipsel: + NoteName = ".note.NaCl.ABI.mipsel"; + NoteArch = "mipsel"; + BundleAlign = 4; + break; + case Triple::x86: + NoteName = ".note.NaCl.ABI.x86-32"; + NoteArch = "x86-32"; + BundleAlign = 5; + break; + case Triple::x86_64: + NoteName = ".note.NaCl.ABI.x86-64"; + NoteArch = "x86-64"; + BundleAlign = 5; + break; + default: + report_fatal_error("Unsupported architecture for NaCl"); + } + + // Set bundle-alignment as required by the NaCl ABI for the target. + Streamer.EmitBundleAlignMode(BundleAlign); + + // Emit an ELF Note section in its own COMDAT group which identifies NaCl + // object files to the gold linker, so it can use the NaCl layout. + const MCSection *Note = Ctx.getELFSection( + NoteName, ELF::SHT_NOTE, ELF::SHF_ALLOC | ELF::SHF_GROUP, + SectionKind::getReadOnly(), 0, NoteName); + + // TODO(dschuff) This should probably use PushSection and PopSection, but + // PopSection will assert if there haven't been any other sections switched to + // yet. + Streamer.SwitchSection(Note); + Streamer.EmitIntValue(strlen(NoteNamespace) + 1, 4); + Streamer.EmitIntValue(strlen(NoteArch) + 1, 4); + Streamer.EmitIntValue(ELF::NT_VERSION, 4); + Streamer.EmitBytes(NoteNamespace); + Streamer.EmitIntValue(0, 1); // NUL terminator + Streamer.EmitValueToAlignment(4); + Streamer.EmitBytes(NoteArch); + Streamer.EmitIntValue(0, 1); // NUL terminator + Streamer.EmitValueToAlignment(4); +} +} // namespace llvm diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index c48df8a96f..0143d95c19 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -40,6 +40,7 @@ #include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstBuilder.h" +#include "llvm/MC/MCNaCl.h" #include "llvm/MC/MCObjectStreamer.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" @@ -733,11 +734,15 @@ void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) { emitAttributes(); // @LOCALMOD-BEGIN - if (Subtarget->isTargetNaCl() && OutStreamer.hasRawTextSupport()) { - std::string str; - raw_string_ostream OS(str); - EmitSFIHeaders(OS); - OutStreamer.EmitRawText(StringRef(OS.str())); + if (Subtarget->isTargetNaCl()) { + if (OutStreamer.hasRawTextSupport()) { + std::string str; + raw_string_ostream OS(str); + EmitSFIHeaders(OS); + OutStreamer.EmitRawText(StringRef(OS.str())); + } + initializeNaClMCStreamer(OutStreamer, OutContext, + Subtarget->getTargetTriple()); } // @LOCALMOD-END } diff --git a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index 2c155aaf40..3d6e99f664 100644 --- a/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -208,13 +208,9 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT, if (TheTriple.isOSWindows()) { llvm_unreachable("ARM does not support Windows COFF format"); } - // @LOCALMOD-BEGIN - MCStreamer *Streamer = createARMELFStreamer(Ctx, MAB, OS, Emitter, false, - NoExecStack, TheTriple.getArch() == Triple::thumb); - if (TheTriple.isOSNaCl()) - Streamer->EmitBundleAlignMode(4); - return Streamer; - // @LOCALMOD-END + + return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, NoExecStack, + TheTriple.getArch() == Triple::thumb); } static MCInstPrinter *createARMMCInstPrinter(const Target &T, diff --git a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp index 2e2f4b9612..be83b54b61 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp @@ -132,16 +132,7 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT, bool NoExecStack) { Triple TheTriple(TT); - // @LOCALMOD-BEGIN - if (TheTriple.isOSNaCl()) { - MCStreamer *Streamer = createMipsELFStreamer(Ctx, MAB, _OS, _Emitter, - RelaxAll, NoExecStack); - Streamer->EmitBundleAlignMode(4); - return Streamer; - } else { - return createMipsELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack); - } - // @LOCALMOD-END + return createMipsELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack); } extern "C" void LLVMInitializeMipsTargetMC() { diff --git a/lib/Target/Mips/MipsAsmPrinter.cpp b/lib/Target/Mips/MipsAsmPrinter.cpp index 61fb94d531..fc45fd273f 100644 --- a/lib/Target/Mips/MipsAsmPrinter.cpp +++ b/lib/Target/Mips/MipsAsmPrinter.cpp @@ -34,6 +34,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCNaCl.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/ELF.h" @@ -568,11 +569,15 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) { OutStreamer.EmitRawText(StringRef("\t.previous")); // @LOCALMOD-START - if (Subtarget->isTargetNaCl() && OutStreamer.hasRawTextSupport()) { - std::string str; - raw_string_ostream OS(str); - EmitMipsSFIHeaders(OS); - OutStreamer.EmitRawText(StringRef(OS.str())); + if (Subtarget->isTargetNaCl()) { + if (OutStreamer.hasRawTextSupport()) { + std::string str; + raw_string_ostream OS(str); + EmitMipsSFIHeaders(OS); + OutStreamer.EmitRawText(StringRef(OS.str())); + } + initializeNaClMCStreamer(OutStreamer, OutContext, + Triple(Subtarget->getTargetTriple())); } // @LOCALMOD-END } diff --git a/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp index c67bb944b6..5e84530cd7 100644 --- a/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp +++ b/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp @@ -366,14 +366,7 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT, if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF) return createWinCOFFStreamer(Ctx, MAB, *_Emitter, _OS, RelaxAll); - // @LOCALMOD-BEGIN - MCStreamer *Streamer = createELFStreamer(Ctx, MAB, _OS, _Emitter, - RelaxAll, NoExecStack); - if (TheTriple.isOSNaCl()) - Streamer->EmitBundleAlignMode(5); - - return Streamer; - // @LOCALMOD-END + return createELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack); } static MCInstPrinter *createX86MCInstPrinter(const Target &T, diff --git a/lib/Target/X86/X86AsmPrinter.cpp b/lib/Target/X86/X86AsmPrinter.cpp index 2eb75b558b..032d83aac0 100644 --- a/lib/Target/X86/X86AsmPrinter.cpp +++ b/lib/Target/X86/X86AsmPrinter.cpp @@ -31,6 +31,7 @@ #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCNaCl.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" @@ -547,6 +548,11 @@ bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, void X86AsmPrinter::EmitStartOfAsmFile(Module &M) { if (Subtarget->isTargetEnvMacho()) OutStreamer.SwitchSection(getObjFileLowering().getTextSection()); + // @LOCALMOD-BEGIN + if (Subtarget->isTargetNaCl()) + initializeNaClMCStreamer(OutStreamer, OutContext, + Subtarget->getTargetTriple()); + // @LOCALMOD-END } diff --git a/test/MC/ARM/elf-note-nacl.ll b/test/MC/ARM/elf-note-nacl.ll new file mode 100644 index 0000000000..8551cf52b4 --- /dev/null +++ b/test/MC/ARM/elf-note-nacl.ll @@ -0,0 +1,22 @@ +; RUN: llc -filetype=obj -mtriple armv7-none-nacl-gnueabi %s -o - \ +; RUN: | llvm-objdump -triple armv7 -s - | FileCheck %s + +; Tests that NaCl object files contain an ELF note section that identifies them +; to the binutils gold linker + +define void @main() { + ret void +} + +; There appears to be no way for llvm-objdump to show flags for sections, or +; to dump groups like readelf. +; CHECK: .group +; CHECK: .note.NaCl.ABI.arm +; The contents of the words in the note section should be: +; sizeof "NaCl" +; sizeof "arm" +; 1 (NT_VERSION) +; "NaCl" with nul termination and padding to align 4 +; "arm" with nul termination and padding to align 4 +; CHECK-NEXT: 0000 05000000 04000000 01000000 4e61436c +; CHECK-NEXT: 0010 00000000 61726d00 diff --git a/test/MC/Mips/elf-note-nacl.ll b/test/MC/Mips/elf-note-nacl.ll new file mode 100644 index 0000000000..0361eff25e --- /dev/null +++ b/test/MC/Mips/elf-note-nacl.ll @@ -0,0 +1,22 @@ +; RUN: llc -filetype=obj -mtriple mipsel-none-nacl %s -o - \ +; RUN: | llvm-objdump -triple mipsel -s - | FileCheck %s + +; Tests that NaCl object files contain an ELF note section that identifies them +; to the binutils gold linker + +define void @main() { + ret void +} + +; There appears to be no way for llvm-objdump to show flags for sections, or +; to dump groups like readelf. +; CHECK: .group +; CHECK: .note.NaCl.ABI.mipsel +; The contents of the words in the note section should be: +; sizeof "NaCl" +; sizeof "mipsel" +; 1 (NT_VERSION) +; "NaCl" with nul termination and padding to align 4 +; "mipsel" with nul termination and padding to align 4 +; CHECK-NEXT: 0000 05000000 07000000 01000000 4e61436c +; CHECK-NEXT: 0010 00000000 6d697073 656c0000 diff --git a/test/MC/X86/elf-note-nacl.ll b/test/MC/X86/elf-note-nacl.ll new file mode 100644 index 0000000000..ce15455c84 --- /dev/null +++ b/test/MC/X86/elf-note-nacl.ll @@ -0,0 +1,36 @@ +; RUN: llc -filetype=obj -mtriple i686-none-nacl %s -o - \ +; RUN: | llvm-objdump -triple i686 -s - | FileCheck --check-prefix=I386 %s + +; RUN: llc -filetype=obj -mtriple x86_64-none-nacl %s -o - \ +; RUN: | llvm-objdump -triple x86_64 -s - | FileCheck --check-prefix=X8664 %s + +; Tests that NaCl object files contain an ELF note section that identifies them +; to the binutils gold linker + +define void @main() { + ret void +} + +; There appears to be no way for llvm-objdump to show flags for sections, or +; to dump groups like readelf. +; I386: .group +; I386: .note.NaCl.ABI.x86-32 +; The contents of the words in the note section should be: +; sizeof "NaCl" +; sizeof "x86-32" +; 1 (NT_VERSION) +; "NaCl" with nul termination and padding to align 4 +; "x86-32" with nul termination and padding to align 4 +; I386-NEXT: 0000 05000000 07000000 01000000 4e61436c +; I386-NEXT: 0010 00000000 7838362d 33320000 + +; X8664: .group +; X8664: .note.NaCl.ABI.x86-64 +; The contents of the words in the note section should be: +; sizeof "NaCl" +; sizeof "x86-64" +; 1 (NT_VERSION) +; "NaCl" with nul termination and padding to align 4 +; q"x86-64" with nul termination and padding to align 4 +; X8664-NEXT: 0000 05000000 07000000 01000000 4e61436c +; X8664-NEXT: 0010 00000000 7838362d 36340000 diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index 243899bb88..11304454f0 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -20,6 +20,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCInstPrinter.h" #include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCNaCl.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCParser/AsmLexer.h" #include "llvm/MC/MCRegisterInfo.h" @@ -453,6 +454,11 @@ int main(int argc, char **argv) { Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB, FOS, CE, RelaxAll, NoExecStack)); + // @LOCALMOD-BEGIN + Triple T(TripleName); + if (T.isOSNaCl()) + initializeNaClMCStreamer(*Str.get(), Ctx, T); + // @LOCALMOD-END } int Res = 1; |