Skip to content

Commit 52daf9d

Browse files
committed
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 [email protected] 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
1 parent 42ac59f commit 52daf9d

File tree

14 files changed

+217
-35
lines changed

14 files changed

+217
-35
lines changed

include/llvm/MC/MCNaCl.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//===- MCNaCl.h - NaCl-specific code for MC --------------------*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
namespace llvm {
11+
class MCContext;
12+
class MCStreamer;
13+
class Triple;
14+
/// Initialize target-specific bundle alignment and emit target-specific NaCl
15+
/// ELF note sections.
16+
void initializeNaClMCStreamer(MCStreamer &Streamer, MCContext &Ctx,
17+
const Triple &TheTriple);
18+
}

include/llvm/Support/ELF.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,13 @@ enum {
13241324
PF_MASKPROC = 0xf0000000 // Bits for processor-specific semantics.
13251325
};
13261326

1327+
// @LOCALMOD-BEGIN
1328+
// Note segment descriptor types (for object files).
1329+
enum {
1330+
NT_VERSION = 1 // Note contains a version string.
1331+
};
1332+
// @LOCALMOD-END
1333+
13271334
// Dynamic table entry for ELF32.
13281335
struct Elf32_Dyn
13291336
{

lib/MC/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ add_llvm_library(LLVMMC
2323
MCMachOStreamer.cpp
2424
MCMachObjectTargetWriter.cpp
2525
MCModule.cpp
26+
MCNaCl.cpp
2627
MCNullStreamer.cpp
2728
MCObjectFileInfo.cpp
2829
MCObjectStreamer.cpp

lib/MC/MCNaCl.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//===- lib/MC/MCNaCl.cpp - NaCl-specific MC implementation ----------------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "llvm/MC/MCNaCl.h"
11+
#include "llvm/ADT/Triple.h"
12+
#include "llvm/MC/MCContext.h"
13+
#include "llvm/MC/MCSectionELF.h"
14+
#include "llvm/MC/MCStreamer.h"
15+
#include "llvm/Support/ELF.h"
16+
17+
static const char NoteNamespace[] = "NaCl";
18+
19+
namespace llvm {
20+
void initializeNaClMCStreamer(MCStreamer &Streamer, MCContext &Ctx,
21+
const Triple &TheTriple) {
22+
assert(TheTriple.isOSNaCl());
23+
const char *NoteName;
24+
const char *NoteArch;
25+
unsigned BundleAlign;
26+
switch (TheTriple.getArch()) {
27+
case Triple::arm:
28+
NoteName = ".note.NaCl.ABI.arm";
29+
NoteArch = "arm";
30+
BundleAlign = 4;
31+
break;
32+
case Triple::mipsel:
33+
NoteName = ".note.NaCl.ABI.mipsel";
34+
NoteArch = "mipsel";
35+
BundleAlign = 4;
36+
break;
37+
case Triple::x86:
38+
NoteName = ".note.NaCl.ABI.x86-32";
39+
NoteArch = "x86-32";
40+
BundleAlign = 5;
41+
break;
42+
case Triple::x86_64:
43+
NoteName = ".note.NaCl.ABI.x86-64";
44+
NoteArch = "x86-64";
45+
BundleAlign = 5;
46+
break;
47+
default:
48+
report_fatal_error("Unsupported architecture for NaCl");
49+
}
50+
51+
// Set bundle-alignment as required by the NaCl ABI for the target.
52+
Streamer.EmitBundleAlignMode(BundleAlign);
53+
54+
// Emit an ELF Note section in its own COMDAT group which identifies NaCl
55+
// object files to the gold linker, so it can use the NaCl layout.
56+
const MCSection *Note = Ctx.getELFSection(
57+
NoteName, ELF::SHT_NOTE, ELF::SHF_ALLOC | ELF::SHF_GROUP,
58+
SectionKind::getReadOnly(), 0, NoteName);
59+
60+
// TODO(dschuff) This should probably use PushSection and PopSection, but
61+
// PopSection will assert if there haven't been any other sections switched to
62+
// yet.
63+
Streamer.SwitchSection(Note);
64+
Streamer.EmitIntValue(strlen(NoteNamespace) + 1, 4);
65+
Streamer.EmitIntValue(strlen(NoteArch) + 1, 4);
66+
Streamer.EmitIntValue(ELF::NT_VERSION, 4);
67+
Streamer.EmitBytes(NoteNamespace);
68+
Streamer.EmitIntValue(0, 1); // NUL terminator
69+
Streamer.EmitValueToAlignment(4);
70+
Streamer.EmitBytes(NoteArch);
71+
Streamer.EmitIntValue(0, 1); // NUL terminator
72+
Streamer.EmitValueToAlignment(4);
73+
}
74+
} // namespace llvm

lib/Target/ARM/ARMAsmPrinter.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "llvm/MC/MCELFStreamer.h"
4141
#include "llvm/MC/MCInst.h"
4242
#include "llvm/MC/MCInstBuilder.h"
43+
#include "llvm/MC/MCNaCl.h"
4344
#include "llvm/MC/MCObjectStreamer.h"
4445
#include "llvm/MC/MCSectionMachO.h"
4546
#include "llvm/MC/MCStreamer.h"
@@ -733,11 +734,15 @@ void ARMAsmPrinter::EmitStartOfAsmFile(Module &M) {
733734
emitAttributes();
734735

735736
// @LOCALMOD-BEGIN
736-
if (Subtarget->isTargetNaCl() && OutStreamer.hasRawTextSupport()) {
737-
std::string str;
738-
raw_string_ostream OS(str);
739-
EmitSFIHeaders(OS);
740-
OutStreamer.EmitRawText(StringRef(OS.str()));
737+
if (Subtarget->isTargetNaCl()) {
738+
if (OutStreamer.hasRawTextSupport()) {
739+
std::string str;
740+
raw_string_ostream OS(str);
741+
EmitSFIHeaders(OS);
742+
OutStreamer.EmitRawText(StringRef(OS.str()));
743+
}
744+
initializeNaClMCStreamer(OutStreamer, OutContext,
745+
Subtarget->getTargetTriple());
741746
}
742747
// @LOCALMOD-END
743748
}

lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -208,13 +208,9 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
208208
if (TheTriple.isOSWindows()) {
209209
llvm_unreachable("ARM does not support Windows COFF format");
210210
}
211-
// @LOCALMOD-BEGIN
212-
MCStreamer *Streamer = createARMELFStreamer(Ctx, MAB, OS, Emitter, false,
213-
NoExecStack, TheTriple.getArch() == Triple::thumb);
214-
if (TheTriple.isOSNaCl())
215-
Streamer->EmitBundleAlignMode(4);
216-
return Streamer;
217-
// @LOCALMOD-END
211+
212+
return createARMELFStreamer(Ctx, MAB, OS, Emitter, false, NoExecStack,
213+
TheTriple.getArch() == Triple::thumb);
218214
}
219215

220216
static MCInstPrinter *createARMMCInstPrinter(const Target &T,

lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -132,16 +132,7 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
132132
bool NoExecStack) {
133133
Triple TheTriple(TT);
134134

135-
// @LOCALMOD-BEGIN
136-
if (TheTriple.isOSNaCl()) {
137-
MCStreamer *Streamer = createMipsELFStreamer(Ctx, MAB, _OS, _Emitter,
138-
RelaxAll, NoExecStack);
139-
Streamer->EmitBundleAlignMode(4);
140-
return Streamer;
141-
} else {
142-
return createMipsELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack);
143-
}
144-
// @LOCALMOD-END
135+
return createMipsELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack);
145136
}
146137

147138
extern "C" void LLVMInitializeMipsTargetMC() {

lib/Target/Mips/MipsAsmPrinter.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "llvm/IR/Instructions.h"
3535
#include "llvm/MC/MCAsmInfo.h"
3636
#include "llvm/MC/MCInst.h"
37+
#include "llvm/MC/MCNaCl.h"
3738
#include "llvm/MC/MCStreamer.h"
3839
#include "llvm/MC/MCSymbol.h"
3940
#include "llvm/Support/ELF.h"
@@ -568,11 +569,15 @@ void MipsAsmPrinter::EmitStartOfAsmFile(Module &M) {
568569
OutStreamer.EmitRawText(StringRef("\t.previous"));
569570

570571
// @LOCALMOD-START
571-
if (Subtarget->isTargetNaCl() && OutStreamer.hasRawTextSupport()) {
572-
std::string str;
573-
raw_string_ostream OS(str);
574-
EmitMipsSFIHeaders(OS);
575-
OutStreamer.EmitRawText(StringRef(OS.str()));
572+
if (Subtarget->isTargetNaCl()) {
573+
if (OutStreamer.hasRawTextSupport()) {
574+
std::string str;
575+
raw_string_ostream OS(str);
576+
EmitMipsSFIHeaders(OS);
577+
OutStreamer.EmitRawText(StringRef(OS.str()));
578+
}
579+
initializeNaClMCStreamer(OutStreamer, OutContext,
580+
Triple(Subtarget->getTargetTriple()));
576581
}
577582
// @LOCALMOD-END
578583
}

lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -366,14 +366,7 @@ static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
366366
if (TheTriple.isOSWindows() && TheTriple.getEnvironment() != Triple::ELF)
367367
return createWinCOFFStreamer(Ctx, MAB, *_Emitter, _OS, RelaxAll);
368368

369-
// @LOCALMOD-BEGIN
370-
MCStreamer *Streamer = createELFStreamer(Ctx, MAB, _OS, _Emitter,
371-
RelaxAll, NoExecStack);
372-
if (TheTriple.isOSNaCl())
373-
Streamer->EmitBundleAlignMode(5);
374-
375-
return Streamer;
376-
// @LOCALMOD-END
369+
return createELFStreamer(Ctx, MAB, _OS, _Emitter, RelaxAll, NoExecStack);
377370
}
378371

379372
static MCInstPrinter *createX86MCInstPrinter(const Target &T,

lib/Target/X86/X86AsmPrinter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "llvm/MC/MCAsmInfo.h"
3232
#include "llvm/MC/MCContext.h"
3333
#include "llvm/MC/MCExpr.h"
34+
#include "llvm/MC/MCNaCl.h"
3435
#include "llvm/MC/MCSectionMachO.h"
3536
#include "llvm/MC/MCStreamer.h"
3637
#include "llvm/MC/MCSymbol.h"
@@ -547,6 +548,11 @@ bool X86AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
547548
void X86AsmPrinter::EmitStartOfAsmFile(Module &M) {
548549
if (Subtarget->isTargetEnvMacho())
549550
OutStreamer.SwitchSection(getObjFileLowering().getTextSection());
551+
// @LOCALMOD-BEGIN
552+
if (Subtarget->isTargetNaCl())
553+
initializeNaClMCStreamer(OutStreamer, OutContext,
554+
Subtarget->getTargetTriple());
555+
// @LOCALMOD-END
550556
}
551557

552558

test/MC/ARM/elf-note-nacl.ll

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
; RUN: llc -filetype=obj -mtriple armv7-none-nacl-gnueabi %s -o - \
2+
; RUN: | llvm-objdump -triple armv7 -s - | FileCheck %s
3+
4+
; Tests that NaCl object files contain an ELF note section that identifies them
5+
; to the binutils gold linker
6+
7+
define void @main() {
8+
ret void
9+
}
10+
11+
; There appears to be no way for llvm-objdump to show flags for sections, or
12+
; to dump groups like readelf.
13+
; CHECK: .group
14+
; CHECK: .note.NaCl.ABI.arm
15+
; The contents of the words in the note section should be:
16+
; sizeof "NaCl"
17+
; sizeof "arm"
18+
; 1 (NT_VERSION)
19+
; "NaCl" with nul termination and padding to align 4
20+
; "arm" with nul termination and padding to align 4
21+
; CHECK-NEXT: 0000 05000000 04000000 01000000 4e61436c
22+
; CHECK-NEXT: 0010 00000000 61726d00

test/MC/Mips/elf-note-nacl.ll

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
; RUN: llc -filetype=obj -mtriple mipsel-none-nacl %s -o - \
2+
; RUN: | llvm-objdump -triple mipsel -s - | FileCheck %s
3+
4+
; Tests that NaCl object files contain an ELF note section that identifies them
5+
; to the binutils gold linker
6+
7+
define void @main() {
8+
ret void
9+
}
10+
11+
; There appears to be no way for llvm-objdump to show flags for sections, or
12+
; to dump groups like readelf.
13+
; CHECK: .group
14+
; CHECK: .note.NaCl.ABI.mipsel
15+
; The contents of the words in the note section should be:
16+
; sizeof "NaCl"
17+
; sizeof "mipsel"
18+
; 1 (NT_VERSION)
19+
; "NaCl" with nul termination and padding to align 4
20+
; "mipsel" with nul termination and padding to align 4
21+
; CHECK-NEXT: 0000 05000000 07000000 01000000 4e61436c
22+
; CHECK-NEXT: 0010 00000000 6d697073 656c0000

test/MC/X86/elf-note-nacl.ll

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
; RUN: llc -filetype=obj -mtriple i686-none-nacl %s -o - \
2+
; RUN: | llvm-objdump -triple i686 -s - | FileCheck --check-prefix=I386 %s
3+
4+
; RUN: llc -filetype=obj -mtriple x86_64-none-nacl %s -o - \
5+
; RUN: | llvm-objdump -triple x86_64 -s - | FileCheck --check-prefix=X8664 %s
6+
7+
; Tests that NaCl object files contain an ELF note section that identifies them
8+
; to the binutils gold linker
9+
10+
define void @main() {
11+
ret void
12+
}
13+
14+
; There appears to be no way for llvm-objdump to show flags for sections, or
15+
; to dump groups like readelf.
16+
; I386: .group
17+
; I386: .note.NaCl.ABI.x86-32
18+
; The contents of the words in the note section should be:
19+
; sizeof "NaCl"
20+
; sizeof "x86-32"
21+
; 1 (NT_VERSION)
22+
; "NaCl" with nul termination and padding to align 4
23+
; "x86-32" with nul termination and padding to align 4
24+
; I386-NEXT: 0000 05000000 07000000 01000000 4e61436c
25+
; I386-NEXT: 0010 00000000 7838362d 33320000
26+
27+
; X8664: .group
28+
; X8664: .note.NaCl.ABI.x86-64
29+
; The contents of the words in the note section should be:
30+
; sizeof "NaCl"
31+
; sizeof "x86-64"
32+
; 1 (NT_VERSION)
33+
; "NaCl" with nul termination and padding to align 4
34+
; q"x86-64" with nul termination and padding to align 4
35+
; X8664-NEXT: 0000 05000000 07000000 01000000 4e61436c
36+
; X8664-NEXT: 0010 00000000 7838362d 36340000

tools/llvm-mc/llvm-mc.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "llvm/MC/MCContext.h"
2121
#include "llvm/MC/MCInstPrinter.h"
2222
#include "llvm/MC/MCInstrInfo.h"
23+
#include "llvm/MC/MCNaCl.h"
2324
#include "llvm/MC/MCObjectFileInfo.h"
2425
#include "llvm/MC/MCParser/AsmLexer.h"
2526
#include "llvm/MC/MCRegisterInfo.h"
@@ -453,6 +454,11 @@ int main(int argc, char **argv) {
453454
Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB,
454455
FOS, CE, RelaxAll,
455456
NoExecStack));
457+
// @LOCALMOD-BEGIN
458+
Triple T(TripleName);
459+
if (T.isOSNaCl())
460+
initializeNaClMCStreamer(*Str.get(), Ctx, T);
461+
// @LOCALMOD-END
456462
}
457463

458464
int Res = 1;

0 commit comments

Comments
 (0)