title: SIGSEGV when executing 32 bit binary on 64 bit Linux
body: <p>You may have heard of StoneKnifeForth, a project by kragen: <a href="https://github.com/kragen/stoneknifeforth" rel="nofollow noreferrer">https://github.com/kragen/stoneknifeforth</a>. It's a Python program that acts as a small Forth interpreter and a Forth program that acts as a Forth compiler. Therefore you can build a Forth compiler binary using those two in unison.</p>
  
  <p>After porting StoneKnifeForth to C++ (<a href="https://github.com/tekknolagi/stoneknifecpp" rel="nofollow noreferrer">https://github.com/tekknolagi/stoneknifecpp</a>), I noticed that all binaries produced by StoneKnifeForth (either variety) segfault on 64 bit Linux. That is, if you clone stoneknifecpp and run:</p>
  
  <pre><code>make
  ./l01compiler  # produced by the Forth program
  </code></pre>
  
  <p>You'll get the following:</p>
  
  <pre><code>willow% ./l01compiler                 
  [1]    31614 segmentation fault  ./l01compiler
  </code></pre>
  
  <p>This isn't a very interesting error message, obviously, so I thought I would strace it:</p>
  
  <pre><code>willow% strace ./l01compiler
  execve("./l01compiler", ["./l01compiler"], [/* 110 vars */]) = -1 EPERM (Operation not permitted)
  --- SIGSEGV {si_signo=SIGSEGV, si_code=SI_KERNEL, si_addr=0} ---
  +++ killed by SIGSEGV +++
  [1]    31615 segmentation fault (core dumped)  strace ./l01compiler
  </code></pre>
  
  <p>And got... somewhat more information. It looks like the ELF header is wrong <em>somehow</em>, except for the following two interesting tidbits:</p>
  
  <ul>
  <li>It runs fine under 32 bit qemu</li>
  <li>It runs fine if I <code>sudo ./l01compiler</code></li>
  </ul>
  
  <p>I'm a bit of a loss as to why this is, even after internet searching for possible differences between ELF header formats between 32 bit and 64 bit Linux kernels, etc. If anyone has any information, I would be delighted.</p>
  
  <p>I have attached the header below:</p>
  
  <pre><code>willow% readelf -h l01compiler   
  ELF Header:
    Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
    Class:                             ELF32
    Data:                              2's complement, little endian
    Version:                           1 (current)
    OS/ABI:                            UNIX - System V
    ABI Version:                       0
    Type:                              EXEC (Executable file)
    Machine:                           Intel 80386
    Version:                           0x1
    Entry point address:               0x1e39
    Start of program headers:          52 (bytes into file)
    Start of section headers:          0 (bytes into file)
    Flags:                             0x0
    Size of this header:               52 (bytes)
    Size of program headers:           32 (bytes)
    Number of program headers:         1
    Size of section headers:           40 (bytes)
    Number of section headers:         0
    Section header string table index: 0
  </code></pre>