aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2013-05-10 16:00:11 -0700
committerDerek Schuff <dschuff@chromium.org>2013-05-10 16:00:11 -0700
commit52daf9d821c963f84dd312ff90921bfe1b1cc0a1 (patch)
tree8f94ccf4841f2a0bbfdb19bf3b230f7ad220e8ff
parent42ac59f56fb0d473f84b6be738a64e80b09557d1 (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.h18
-rw-r--r--include/llvm/Support/ELF.h7
-rw-r--r--lib/MC/CMakeLists.txt1
-rw-r--r--lib/MC/MCNaCl.cpp74
-rw-r--r--lib/Target/ARM/ARMAsmPrinter.cpp15
-rw-r--r--lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp10
-rw-r--r--lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp11
-rw-r--r--lib/Target/Mips/MipsAsmPrinter.cpp15
-rw-r--r--lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp9
-rw-r--r--lib/Target/X86/X86AsmPrinter.cpp6
-rw-r--r--test/MC/ARM/elf-note-nacl.ll22
-rw-r--r--test/MC/Mips/elf-note-nacl.ll22
-rw-r--r--test/MC/X86/elf-note-nacl.ll36
-rw-r--r--tools/llvm-mc/llvm-mc.cpp6
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;