title: Why can't I pipe assembler output to stdout?
body: <p><strong>[edit]</strong><br>
  This was just kind of a though experiment I had where I wanted to see if I could trick the kernel in to executing an elf from an unnamed pipe with process substitution with /lib64/ld-linux-x86-64.so.2, I knew it was a shot in the dark but I was just hoping to see if anyone could give me an answer as to why it didn't work</p>
  
  <pre><code>$ /lib64/ld-linux-x86-64.so.2 &lt;(gcc -c -xc &lt;(echo $'#include &lt;stdio.h&gt;\n\nint main(){\nprintf("I work\\n");\nreturn 0;\n}') -o /dev/stdout)
  /tmp/ccf5sMql.s: Assembler messages:
  /tmp/ccf5sMql.s: Fatal error: can't write /dev/stdout: Illegal seek
  as: BFD version 2.25.1-22.base.el7  assertion fail elf.c:2660
  as: BFD version 2.25.1-22.base.el7  assertion fail elf.c:2660
  /tmp/ccf5sMql.s: Fatal error: can't close /dev/stdout: Illegal seek
  /dev/fd/63: error while loading shared libraries: /dev/fd/63: file too short
  </code></pre>
  
  <p>I figured that it may have been possible due to varying results I was getting.</p>
  
  <pre><code>$ /lib64/ld-linux-x86-64.so.2 &lt;(gcc -fPIC -pie -xc &lt;(echo $'#include 
  &lt;stdio.h&gt;\n\nint main(){\nprintf("I work\\n");\nreturn 0;\n}') -o 
  /dev/stdout|cat|perl -ne 'chomp;printf')
  /dev/fd/63: error while loading shared libraries: /dev/fd/63: ELF load 
  command past end of file
  $ /lib64/ld-linux-x86-64.so.2 &lt;(gcc -fPIC -pie -xc &lt;(echo $'#include 
  &lt;stdio.h&gt;\n\nint main(){\nprintf("I work\\n");\nreturn 0;\n}') -o 
  /dev/stdout|cat|perl -0 -ne 'chomp;printf')
  /dev/fd/63: error while loading shared libraries: /dev/fd/63: ELF file ABI 
  version invalid
  </code></pre>
  
  <p>So I was playing around with ASM and noticed that you can't assemble or link output to stdout.</p>
  
  <pre><code>$ as /tmp/lol.s -o /dev/stdout
  /tmp/lol.s: Assembler messages:
  /tmp/lol.s: Fatal error: can't write /dev/stdout: Illegal seek
  as: BFD version 2.25.1-22.base.el7  assertion fail elf.c:2660
  as: BFD version 2.25.1-22.base.el7  assertion fail elf.c:2660
  
  
  as /tmp/lol.s -o /tmp/test.o
  $ ld /tmp/test.o -o what -lc
  ld: warning: cannot find entry symbol _start; defaulting to 00000000004002a0
  
  
  $ exec 9&lt; &lt;(ld /tmp/test.o -o /dev/stdout -lc)
  ld: warning: cannot find entry symbol _start; defaulting to 00000000004002a0
  ld: final link failed: Illegal seek
  </code></pre>
  
  <p>Given the code as follows:</p>
  
  <pre><code>.file   "63"
  .section        .rodata
  .LC0:
  .string "I work"
  .text
  .globl  main
  .type   main, @function
  main:
  .LFB0:
  .cfi_startproc
  pushq   %rbp
  .cfi_def_cfa_offset 16
  .cfi_offset 6, -16
  movq    %rsp, %rbp
  .cfi_def_cfa_register 6
  movl    $.LC0, %edi
  call    puts
  movl    $0, %eax
  popq    %rbp
  .cfi_def_cfa 7, 8
  ret
  .cfi_endproc
  .LFE0:
  .size   main, .-main
  .ident  "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-16)"
  .section        .note.GNU-stack,"",@progbits
  .file   "63"
  .section        .rodata
  </code></pre>
  
  <p>Can anyone tell me why it isn't possible to assemble objects or link objects to stdout?  Please be as in depth as possible.  To see the full process that a compiler goes to in order to generate that code, you can use the following:</p>
  
  <pre><code>$ exec 7&lt; &lt;(gcc -c -xc &lt;(echo $'#include &lt;stdio.h&gt;\n\nint main(){\nprintf("I work\\n");\nreturn 0;\n}') -o /dev/stdout)
  </code></pre>
  
  <p>If you assemble and link the assembly I provided earlier and want to execute it properly you'll need to call /lib64/ld-linux-x86-64.so.2 /path/to/output otherwise it will just say bad elf interpreter.</p>
  
  <pre><code># ./what
  bash: ./what: /lib/ld64.so.1: bad ELF interpreter: No such file or directory
  
  # /lib64/ld-linux-x86-64.so.2 ./what
  I work
  </code></pre>