title: How to get an entry point address in binary image file generated by objcopy?
body: <p>I am building an emulator of the Risk-V CPU for own educational purposes. I have small POC working and want to build example programs and test them on the emulator.</p>
  <p>I'm trying to build example program in Rust and seems like I made some decent progress, but I got stuck when I have to load compiled program to the memory of my emulator and transfer CPU execution to that program.</p>
  <p>Test program:</p>
  <pre class="lang-rust prettyprint-override"><code>#![no_std]
  #![no_main]
  
  use core::panic::PanicInfo;
  
  #[no_mangle]
  pub extern &quot;C&quot; fn _start() -&gt; ! {
      loop {
          for i in 0..1000 {
              unsafe {
                  let r = i as *mut u32;
                  // This can panic because (500 - i) can be 0
                  *r = 20000 % (500 - i);
              }
          }
      }
  }
  
  #[panic_handler]
  fn panic(_info: &amp;PanicInfo) -&gt; ! {
      loop {}
  }
  </code></pre>
  <p>build:</p>
  <pre class="lang-sh prettyprint-override"><code>$ cargo build --target riscv32i-unknown-none-elf --release
  </code></pre>
  <p>generating binary image from elf target:</p>
  <pre class="lang-sh prettyprint-override"><code>riscv32-unknown-linux-gnu-objcopy -g -O binary \
    target/riscv32i-unknown-none-elf/release/sample1 \
    target/riscv32i-unknown-none-elf/release/sample1.bin
  </code></pre>
  <p>This works fine so far and generates me binary file with size 5156 bytes.</p>
  <p>I inspected .bin file and it looks &quot;legit binary&quot; to me.
  I found some readable strings in the beginning of the file (like <code>attempt to calculate the remainder with a divisor of zero</code>) - looks like they are related to code which handles panic which can happen if I'm doing <code>% 0</code>.
  In the end of file I found something that looks like riskv32i instructions (easy to notice them since least significant bits are <code>11</code>).
  Rest of the file is filled with zeros.</p>
  <p>Place where I stuck is I cannot figure out:</p>
  <ol>
  <li>At which offset am I supposed to load this bin image file into memory of my virtual CPU? I don't think it's OK to load it at 0x0 address, because there is useful info in the beginning of the image and I don't think it's cool for the program to read it from address 0x0.</li>
  <li>After program is loaded, I need to transfer CPU execution to the entry point of my program (<code>_start</code>). How can I find out which address is the entry point so I can put this address into <code>pc</code> register before starting CPU cycles? It's obviously not in the beginning of the image (there are human readable strings there).</li>
  <li>Is there a way to make this entry point address stable, so all programs which I write will have the same entry point address, so I don't have to do tweaks for each of programs I compile?</li>
  </ol>
  <p>I may went wrong way when I used <code>objcopy</code>. If that's the case, please let me know what's the appropriate way to load ELF file into a homemade CPU emulator.</p>
  <p>Update: Linker arguments, (as provided by <code>RUSTFLAGS=&quot;-Z print-link-args&quot; cargo build --target riscv32i-unknown-none-elf --release --verbose</code>):</p>
  <pre class="lang-sh prettyprint-override"><code>rust-lld \
      -flavor \
      gnu \
      -L \
      /home/kris/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/riscv32i-unknown-none-elf/lib \
      /mnt/c/src/ws/cpu/sample1/target/riscv32i-unknown-none-elf/release/deps/sample1-4813691a581d1819.sample1.251h7tq6-cgu.0.rcgu.o \
      /mnt/c/src/ws/cpu/sample1/target/riscv32i-unknown-none-elf/release/deps/sample1-4813691a581d1819.sample1.251h7tq6-cgu.1.rcgu.o -o \
      /mnt/c/src/ws/cpu/sample1/target/riscv32i-unknown-none-elf/release/deps/sample1-4813691a581d1819 \
      --gc-sections \
      -L \
      /mnt/c/src/ws/cpu/sample1/target/riscv32i-unknown-none-elf/release/deps \
      -L \
      /mnt/c/src/ws/cpu/sample1/target/release/deps \
      -L \
      /home/kris/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/riscv32i-unknown-none-elf/lib \
      -Bstatic \
      /home/kris/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/riscv32i-unknown-none-elf/lib/librustc_std_workspace_core-6d1cf467df9db3bb.rlib \
      /home/kris/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/riscv32i-unknown-none-elf/lib/libcore-a1a0b4993598bfe4.rlib \
      /home/kris/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/riscv32i-unknown-none-elf/lib/libcompiler_builtins-a229bbbccd019775.rlib \
      -Bdynamic
  </code></pre>
  <p><em>I know that there are some important things missing in the program, like initializing stack pointer register. I'm planning to take care about that after I figure out loading logic</em></p>