[lld] r279726 - [ELF] - Implemented --oformat binary option.
Tom Stellard via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 1 13:53:52 PDT 2016
On Thu, Aug 25, 2016 at 09:05:47AM -0000, George Rimar via llvm-commits wrote:
> 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
Hi,
'hexdump -C' should be replaced with 'llvm-objdump -s' to avoid adding a
dependency on an external tool
-Tom
> +
> +# 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
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list