Useful commands - puranikvinit/newlib GitHub Wiki

Running 64- and 32-bit RISC-V binaries, respectively:

# Use rv64gc_* for 64-bit ISA
spike pk -p -s a.out
spike --isa=$MARCH riscv32-unknown-elf/bin/pk -p -s a.out


To change the compile options when compiling standalone newlib, use:

make CFLAGS="your options here" -j$(nproc)

You can change its optimization level. If you use -Os or -Oz, either will define the __OPTIMIZE_SIZE__ macro. Use CCASFLAGS to change options for the assembler.


When compiling binaries, you can use the -g flag, which adds debugging info to the binary. It doesn't interfere with optimizations. There are multiple levels of debugging. -g3 and -ggdb3 are the highest. Use -fno-builtin to prevent the compiler from replacing various library function calls with special versions. The -frecord-gcc-switches option saves the command line that was invoked to compile a C file into an ELF section named .GCC.command.line. You can dump its contents with readelf -p .GCC.command.line [filename].

Another useful option is -Wa,-L which passes -L to the assembler. This preserves local symbols, such as local labels for assembly files. It looks like the RISC-V toolchain does it by default (but stock gcc on my system does not). Be aware that if you're linking, the linker may remove them. I don't know how to unset the -X option passed to the linker (it's included by default).

You can use either objdump (the RISC-V toolchain version) or gdb to disassemble binaries (if you're disassembling binaries that use the Zilsd or Zclsd extensions, use llvm-objdump from the LLVM project instead). The --disassembler-color=on option for objdump is very useful (I recommend creating an alias with alias because typing it out is very tedious). Disassemble a single function with --disassemble=<name>. -M no-aliases is useful to see compressed instructions without relying on the instruction bytes. -S displays source code intermixed with disassembly (remember to add debugging), and -l adds the source file name and line number. Keep in mind that debugging with a high level of optimization (e.g., -O3) will interfere with debugging and potentially give you misleading results (e.g., you're not really at this specific line of source code).


When compiling binaries with clang, bear in mind that the default architecture string for compilation is rv32im, use the -march=$MARCH flag to compile to not end up compiling with the M extension.

⚠️ **GitHub.com Fallback** ⚠️