[lld] r279726 - [ELF] - Implemented --oformat binary option.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 25 02:05:47 PDT 2016
Author: grimar
Date: Thu Aug 25 04:05:47 2016
New Revision: 279726
URL: http://llvm.org/viewvc/llvm-project?rev=279726&view=rev
Log:
[ELF] - Implemented --oformat binary option.
-oformat output-format
`-oformat' option can be used to specify the binary format for the output object file.
Patch implements binary format output type.
Differential revision: https://reviews.llvm.org/D23769
Added:
lld/trunk/test/ELF/oformat-binary.s
Modified:
lld/trunk/ELF/Config.h
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/Options.td
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=279726&r1=279725&r2=279726&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Thu Aug 25 04:05:47 2016
@@ -92,6 +92,7 @@ struct Configuration {
bool Mips64EL = false;
bool NoGnuUnique;
bool NoUndefinedVersion;
+ bool OFormatBinary;
bool Pic;
bool Pie;
bool PrintGcSections;
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=279726&r1=279725&r2=279726&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Thu Aug 25 04:05:47 2016
@@ -334,6 +334,16 @@ static UnresolvedPolicy getUnresolvedSym
return UnresolvedPolicy::Error;
}
+static bool isOutputFormatBinary(opt::InputArgList &Args) {
+ if (auto *Arg = Args.getLastArg(OPT_oformat)) {
+ StringRef S = Arg->getValue();
+ if (S == "binary")
+ return true;
+ error("unknown --oformat value: " + S);
+ }
+ return false;
+}
+
// Initializes Config members by the command line options.
void LinkerDriver::readConfigs(opt::InputArgList &Args) {
for (auto *Arg : Args.filtered(OPT_L))
@@ -450,6 +460,8 @@ void LinkerDriver::readConfigs(opt::Inpu
}
}
+ Config->OFormatBinary = isOutputFormatBinary(Args);
+
for (auto *Arg : Args.filtered(OPT_undefined))
Config->Undefined.push_back(Arg->getValue());
Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=279726&r1=279725&r2=279726&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Thu Aug 25 04:05:47 2016
@@ -119,6 +119,9 @@ def no_undefined_version: F<"no-undefine
def o: JoinedOrSeparate<["-"], "o">, MetaVarName<"<path>">,
HelpText<"Path to file to write output">;
+def oformat: Separate<["--"], "oformat">, MetaVarName<"<format>">,
+ HelpText<"Specify the binary format for the output object file">;
+
def pie: F<"pie">, HelpText<"Create a position independent executable">;
def print_gc_sections: F<"print-gc-sections">,
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=279726&r1=279725&r2=279726&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Aug 25 04:05:47 2016
@@ -58,6 +58,7 @@ private:
std::vector<Phdr> createPhdrs();
void assignAddresses();
void assignFileOffsets();
+ void assignFileOffsetsBinary();
void setPhdrs();
void fixHeaders();
void fixSectionAlignments();
@@ -65,6 +66,7 @@ private:
void openFile();
void writeHeader();
void writeSections();
+ void writeSectionsBinary();
void writeBuildId();
std::unique_ptr<FileOutputBuffer> Buffer;
@@ -268,7 +270,12 @@ template <class ELFT> void Writer<ELFT>:
fixSectionAlignments();
assignAddresses();
}
- assignFileOffsets();
+
+ if (!Config->OFormatBinary)
+ assignFileOffsets();
+ else
+ assignFileOffsetsBinary();
+
setPhdrs();
fixAbsoluteSymbols();
}
@@ -276,8 +283,12 @@ template <class ELFT> void Writer<ELFT>:
openFile();
if (HasError)
return;
- writeHeader();
- writeSections();
+ if (!Config->OFormatBinary) {
+ writeHeader();
+ writeSections();
+ } else {
+ writeSectionsBinary();
+ }
writeBuildId();
if (HasError)
return;
@@ -1056,8 +1067,10 @@ template <class ELFT> void Writer<ELFT>:
// Assign VAs (addresses at run-time) to output sections.
template <class ELFT> void Writer<ELFT>::assignAddresses() {
- uintX_t VA = Config->ImageBase + Out<ELFT>::ElfHeader->getSize() +
- Out<ELFT>::ProgramHeaders->getSize();
+ uintX_t VA = Config->ImageBase;
+ if (!Config->OFormatBinary)
+ VA +=
+ Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize();
uintX_t ThreadBssOffset = 0;
for (OutputSectionBase<ELFT> *Sec : OutputSections) {
@@ -1097,25 +1110,34 @@ static uintX_t getFileAlignment(uintX_t
return alignTo(Off, Target->PageSize, Sec->getVA());
}
+template <class ELFT, class uintX_t>
+void setOffset(OutputSectionBase<ELFT> *Sec, uintX_t &Off) {
+ if (Sec->getType() == SHT_NOBITS) {
+ Sec->setFileOffset(Off);
+ return;
+ }
+
+ Off = getFileAlignment<ELFT>(Off, Sec);
+ Sec->setFileOffset(Off);
+ Off += Sec->getSize();
+}
+
+template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {
+ uintX_t Off = 0;
+ for (OutputSectionBase<ELFT> *Sec : OutputSections)
+ if (Sec->getFlags() & SHF_ALLOC)
+ setOffset(Sec, Off);
+ FileSize = alignTo(Off, sizeof(uintX_t));
+}
+
// Assign file offsets to output sections.
template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
uintX_t Off = 0;
+ setOffset(Out<ELFT>::ElfHeader, Off);
+ setOffset(Out<ELFT>::ProgramHeaders, Off);
- auto Set = [&](OutputSectionBase<ELFT> *Sec) {
- if (Sec->getType() == SHT_NOBITS) {
- Sec->setFileOffset(Off);
- return;
- }
-
- Off = getFileAlignment<ELFT>(Off, Sec);
- Sec->setFileOffset(Off);
- Off += Sec->getSize();
- };
-
- Set(Out<ELFT>::ElfHeader);
- Set(Out<ELFT>::ProgramHeaders);
for (OutputSectionBase<ELFT> *Sec : OutputSections)
- Set(Sec);
+ setOffset(Sec, Off);
SectionHeaderOff = alignTo(Off, sizeof(uintX_t));
FileSize = SectionHeaderOff + (OutputSections.size() + 1) * sizeof(Elf_Shdr);
@@ -1262,6 +1284,13 @@ template <class ELFT> void Writer<ELFT>:
Buffer = std::move(*BufferOrErr);
}
+template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
+ uint8_t *Buf = Buffer->getBufferStart();
+ for (OutputSectionBase<ELFT> *Sec : OutputSections)
+ if (Sec->getFlags() & SHF_ALLOC)
+ Sec->writeTo(Buf + Sec->getFileOff());
+}
+
// Write section contents to a mmap'ed file.
template <class ELFT> void Writer<ELFT>::writeSections() {
uint8_t *Buf = Buffer->getBufferStart();
Added: lld/trunk/test/ELF/oformat-binary.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/oformat-binary.s?rev=279726&view=auto
==============================================================================
--- lld/trunk/test/ELF/oformat-binary.s (added)
+++ lld/trunk/test/ELF/oformat-binary.s Thu Aug 25 04:05:47 2016
@@ -0,0 +1,28 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: ld.lld -o %t.out %t --oformat binary
+# RUN: hexdump -C %t.out | FileCheck %s
+# CHECK: 00000000 90 11 22 00 00 00 00 00
+# CHECK-NOT: 00000010
+
+## Check case when linkerscript is used.
+# RUN: echo "SECTIONS { . = 0x1000; }" > %t.script
+# RUN: ld.lld -o %t2.out --script %t.script %t --oformat binary
+# RUN: hexdump -C %t2.out | FileCheck %s
+
+# RUN: not ld.lld -o %t3.out %t --oformat foo 2>&1 \
+# RUN: | FileCheck %s --check-prefix ERR
+# ERR: unknown --oformat value: foo
+
+.text
+.align 4
+.globl _start
+_start:
+ nop
+
+.section .mysec.1,"ax"
+.byte 0x11
+
+.section .mysec.2,"ax"
+.byte 0x22
More information about the llvm-commits
mailing list