[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