42

I am learning to write ARM code using the GCC toolchain. I've run into a few GCC options that I cannot find documentation for. Could someone please help explain what they do?

  • -specs=nosys.specs
  • -specs=nano.specs
  • -specs=rdimon.specs
  • -lnosys

How do -specs=nosys.specs and -lnosys relate? Do you use them together, or are they exclusive of each other, or something else?

And nano, I've gathered to imply using the newlib-nano library. I've seen this used in conjunction with -lm and -lc. Does this just give you the standard libc and libm functions?

What does rdimon stand for? I understand it is for "semihosting", which means using the host IO somehow. Does this mean I can printf to the host console? I can find no documentation on how to actually use this.

If there is a source of truth for all of this somewhere that I haven't found, please let me know.

Thanks for any help on clarifying.

jf_
  • 3,099
  • 2
  • 13
  • 31
puritii
  • 1,069
  • 1
  • 7
  • 18
  • 'rdimon' is something like 'remote dispatch interface monitor'. It installs code that mimics a syscall, but runs a 'bkpt' instruction which traps via a debugger which then executes the code on the host. So there is a small set of stubs on the target which are syscalls for 'open' which end up opening a file on the host (same for read()/write(), etc). You need to run `initialise_monitor_handles()` to install them and the code will **ONLY** run under a JTAG/SW debugger. – artless noise Aug 08 '22 at 19:05

1 Answers1

36

Gcc uses specs-strings, which control which subprocesses to run and what parameters it shall pass to them. The behavior defined by the spec-strings can be overridden using spec-files, whose purpose and syntax is documented here: https://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html

Looking at these spec files in the lib folder of the gcc tool chain (e.g. /usr/lib/arm-none-eabi/lib) we can see that the mentioned spec files define which standard library is to be used by the linker.

For example, nosys.specs just defines that system calls should be implemented as stubs that return errors when called (-lnosys). The choice of libc in this case depends on whether nano should be used. With %G the libgcc spec-string is processed, which defines the parameters passed to the linker.

nosys.specs:

%rename link_gcc_c_sequence                nosys_link_gcc_c_sequence

*nosys_libgloss:
-lnosys

*nosys_libc:
%{!specs=nano.specs:-lc} %{specs=nano.specs:-lc_nano}

*link_gcc_c_sequence:
%(nosys_link_gcc_c_sequence) --start-group %G %(nosys_libc) %(nosys_libgloss) --end-group

nano.specs defines the system include path and library parameters to use newlib-nano. The spec file contains replacements for -lc and others to nano equivalents, e.g. -lc_nano. So using it in conjunction with these will make gcc still pass nano libaries to the linker.

Using rdimon.specs, -lrdimon is passed as the libgloss part of the standard library. This basically means that you can use system calls (and also printf), but this relies on a debugger being attached, and the CPU may crash if no debugger is present.

jf_
  • 3,099
  • 2
  • 13
  • 31
  • 1
    hi, it was helpful. I saw "-spec=aem.ve-specs" somewhere. can you tell me something about this too? – Chan Kim Jan 26 '21 at 12:06
  • 5
    Does it make sense to set both specs in a compile command ("-specs=nano.specs -specs=nosys.specs") and what are the effects you would expect? Does this override contents (e.g. functions) of the nano.specs by nosys.specs or does it "only" add non-existing content? – Guti_Haz Jan 29 '21 at 21:35
  • 2
    @ChanKim seems to me that aem.ve-specs also passes -lrdimon. But there are different ones around, so to really know you can look into the file in your toolchain. – jf_ Jan 29 '21 at 22:17
  • 3
    @Guti_Haz you can have multiple specs files, and they are processed in order. As these contain directives that may override spec strings, they may conflict. But you can see in the files that they often just append options, so both changes are applied. – jf_ Jan 29 '21 at 22:45
  • 4
    When you add nano and nosys in that order you get -lnosys and -lc_nano. – jf_ Jan 29 '21 at 23:01