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 /lib/MC | |
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
Diffstat (limited to 'lib/MC')
-rw-r--r-- | lib/MC/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/MC/MCNaCl.cpp | 74 |
2 files changed, 75 insertions, 0 deletions
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 |