Adding a "riscv*-*-none" Tuple to GCC

628 views
Skip to first unread message

Palmer Dabbelt

unread,
Aug 28, 2017, 7:49:47 PM8/28/17
to sw-...@groups.riscv.org
[Just a note for everyone who is freaked out about all this talk of the
toolchain not being an embedded toolchain: this isn't important, it just
changes the defaults for some arguments, and if whatever you're doing works
then there's no reason to worry.]

This was recently discussed in another thread, but I thought I'd start a new
one with a better name in case anyone was ignoring those messages.

We currently have the following toolchain tuples committed upstream in GCC:

* riscv*-*-elf: Toolchains that use newlib as the standard library, but aren't
tied to any specific OS.
* riscv*-*-rtems: Like the above, but with additional RTEMS support. I know
very little about this, we accepted it as a contribution from a user so I
assume it does what they want :).
* riscv*-*-linux-gnu: Targets Linux+glibc. There doesn't seem to be any
controversy here.

The riscv*-*-elf toolchains implicitly link in newlib's libc and libgloss,
which means that if you call a C library function from your code that makes a
system call as part of its implementation, then the compiler will produce a
binary that has those system calls implemented via the standard RISC-V syscall
ABI. As a result, these binaries will run in environments that implement this
ABI: for example, Linux, QEMU's user-mode emulation, or the proxy kernel. In
addition to implicitly linking in these libraries, this toolchain provides
default versions of the various C runtime files (crt*.o) and a linker script,
both of which assume the code is running in an environment that's sufficient to
setup some state for when the program begins executing (a stack, argc/argv,
etc).

None of this is suitable for bare-metal programming, where users want to know
everything that's going on in their program. More specifically:

* Linking libc is sometimes viable, but often times the default newlib has too
big of a footprint. There's options here (newlib-nano is one solution, as
are other C libraries), but those are orthogonal to what's going on here.
* We currently only have an implementation of libgloss that follows the default
syscall ABI, which isn't appropriate when nothing is running to handle the
traps that will be executed.
* The C runtime files generally aren't wanted: the startup code doesn't make
much sense because there's nothing to set up an environment, and the shutdown
code probably shouldn't be run because there's rarely anything to return back
to.
* The linker script is almost certainly wrong, as it assumes it can just go put
any section anywhere. As there's rarely any underlying memory
virtualization, programs tend to need to be linked with a bunch of wacky
constrains on their segments in order to run correctly (.text in flash, .data
in SRAM, for example). This tends to bleed over into the C runtime files as
well.

At SiFive, we've been solving these problems by providing implementations of
the above items that are specific to our hardware implementations, and using
compiler arguments to override these implicit defaults where relevant with our
own implementations:

http://github.com/sifive/freedom-e-sdk/

I'd been trying to avoid having another compiler tuple, as people are already
confused by the four that we commonly use, but it looks like this implicit
linking behavior is causing some trouble so I'm just going to go ahead submit
another tuple pattern upstream to GCC to alleviate these problems. We're going
to call the tuple pattern "riscv*-*-none", which means the toolchains will be
called "riscv32-unknown-none" and "riscv64-unknown-none".

The name was chosen as follows:

* *-none is a name that other toolchains have that behaves this way.
* riscv*-*-none doesn't match any of the existing RISC-V tuples, so if GCC
doesn't support that tuple then you'll get an error.
* riscv{32,64}-unknown-none are the full tuples, which is how we've been naming
the other toolchains.

While I feel like I'm not going to be able to prevent people from arguing about
the naming convention here, I'd at least like to respect these constraints when
you suggest new names.

Here's the options we have for the tuple, along with the direction I'm leaning
for each:

* Do we link libc? No, but I'd be OK changing this if people think it's better
to link libc by default.
* Do we link libgcc? Yes, as these are all internal GCC routines that users
aren't going to be able to implement on their own anyway.
* Do we link libgloss? No, as that's what started this whole mess in the first
place.
* Do we link libnosys? No, after some feedback people would rather have their
empty syscall implementations in some file with their own name on it.
* Do we link crt*.o? No, as these aren't going to work so we shouldn't be
linking them.
* Do we provide a linker script? Yes, as sometimes users can get away with
just passing argument to GCC that tell it where to target.
* Do we support dynamic linking? Yes, because I don't want to deal with the
fallout.

I'd really like to get this matter put to rest, so if you have opinions on what
should be the default set of options for the "riscv*-*-none" toolchains then
now is the time to speak up.

The implementation lives here

https://github.com/riscv/riscv-gcc/commit/950f25b4fdd2f2c31cc7250107a579bff202d3d4

It would be great if you could submit your suggestions as patches, but I can
understand if that's too hard so replying with your suggestions is OK too.

Angelo Bulfone

unread,
Aug 28, 2017, 7:55:09 PM8/28/17
to Palmer Dabbelt, sw-...@groups.riscv.org
Thank you.

--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
To post to this group, send email to sw-...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.
To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/mhng-4365f685-55a9-40e7-98b2-c6a13fa6ca9c%40palmer-si-x1c4.

Jacob Bachmeyer

unread,
Aug 28, 2017, 8:59:33 PM8/28/17
to Palmer Dabbelt, sw-...@groups.riscv.org
Palmer Dabbelt wrote:
> * Do we support dynamic linking? Yes, because I don't want to deal with the
> fallout.

Think about this one a bit: You propose a toolchain configuration
specifically for systems that have no environment, yet want to include
support for a feature that is inherently dependent on an environment?

I argue that riscv-*-elf should support dynamic linking using ELF, but
riscv-*-none should be oriented towards building monolithic binary
images, as are appropriate for a microcontroller or boot firmware image
where the infrastructure for dynamic linking simply does not exist.

(I also think that RISC-V should use the x86-64 approach of building a
multiarch compiler, but that is probably water under the bridge at this
point. Perhaps GCC may merge riscv32/riscv64 in some future cleanup and
use -march=RV32*/-march=RV64*/-march=RV128* to select a processor base ISA.)


-- Jacob

Khem Raj

unread,
Aug 28, 2017, 9:25:14 PM8/28/17
to jcb6...@gmail.com, Palmer Dabbelt, RISC-V SW Dev
On Mon, Aug 28, 2017 at 5:59 PM, Jacob Bachmeyer <jcb6...@gmail.com> wrote:
> Palmer Dabbelt wrote:
>>
>> * Do we support dynamic linking? Yes, because I don't want to deal with
>> the
>> fallout.
>
>
> Think about this one a bit: You propose a toolchain configuration
> specifically for systems that have no environment, yet want to include
> support for a feature that is inherently dependent on an environment?
>
> I argue that riscv-*-elf should support dynamic linking using ELF, but
> riscv-*-none should be oriented towards building monolithic binary images,
> as are appropriate for a microcontroller or boot firmware image where the
> infrastructure for dynamic linking simply does not exist.

while you can attach any kind of semantic to the tuples. This would break
the general understanding of tuples for gcc toolchains, I would
suggest to stick to the known jargons to reduce the confusion.
dynamic linking requires hosted environments e.g linux, freebsd and so on.
so if we were to use what you propose which OS would it target. generally
-static switch does the right thing across the toolchain to generate static
binaries, just stick to that.


>
> (I also think that RISC-V should use the x86-64 approach of building a
> multiarch compiler, but that is probably water under the bridge at this
> point. Perhaps GCC may merge riscv32/riscv64 in some future cleanup and use
> -march=RV32*/-march=RV64*/-march=RV128* to select a processor base ISA.)

This is a good proposal and gcc does have tentacles to implement
it. There is ppc bi-arch support and mips tri-arch support already in gcc

>
>
> -- Jacob
>
> --
> You received this message because you are subscribed to the Google Groups
> "RISC-V SW Dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sw-dev+un...@groups.riscv.org.
> To post to this group, send email to sw-...@groups.riscv.org.
> Visit this group at
> https://groups.google.com/a/groups.riscv.org/group/sw-dev/.
> To view this discussion on the web visit
> https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/59A4BC6F.9080904%40gmail.com.

Palmer Dabbelt

unread,
Aug 28, 2017, 11:17:49 PM8/28/17
to raj....@gmail.com, jcb6...@gmail.com, sw-...@groups.riscv.org
Replying to both of you here, to try to keep the thread from branching too
much.

On Mon, 28 Aug 2017 18:24:42 PDT (-0700), raj....@gmail.com wrote:
> On Mon, Aug 28, 2017 at 5:59 PM, Jacob Bachmeyer <jcb6...@gmail.com> wrote:
>> Palmer Dabbelt wrote:
>>>
>>> * Do we support dynamic linking? Yes, because I don't want to deal with
>>> the
>>> fallout.
>>
>>
>> Think about this one a bit: You propose a toolchain configuration
>> specifically for systems that have no environment, yet want to include
>> support for a feature that is inherently dependent on an environment?

Well, that's why I brought it up: dynamic linking is probably the wrong thing
to do on embedded systems.

That said, I'm not sure it's correct to disable support for it. We solve this
problem by not building any shared libraries when providing our toolchains for
embedded systems (see riscv-gnu-toolchain), so there's no way for users to
confuse this unless they're doing something tricky.

>> I argue that riscv-*-elf should support dynamic linking using ELF, but
>> riscv-*-none should be oriented towards building monolithic binary images,
>> as are appropriate for a microcontroller or boot firmware image where the
>> infrastructure for dynamic linking simply does not exist.

While I agree that ELF is also probably the wrong thing to emit for embedded
systems (as even static ELFs require some sort of loader), realistically we
just don't have time to support any other binary formats.

Our current flow is to use objcopy post-link to convert to flat binaries,
essentially doing the loading on the host. It's not ideal, but it's
functional. Unless someone steps up to take this on, it's not going to happen
any time soon. I wouldn't be opposed to calling the tuple something like
"riscv*-*-bareelf" or something, as "none" is an awkward name anyway.

> while you can attach any kind of semantic to the tuples. This would break
> the general understanding of tuples for gcc toolchains, I would
> suggest to stick to the known jargons to reduce the confusion.
> dynamic linking requires hosted environments e.g linux, freebsd and so on.
> so if we were to use what you propose which OS would it target. generally
> -static switch does the right thing across the toolchain to generate static
> binaries, just stick to that.

I'm not quite sure which way you're arguing here, but I'd prefer to just leave
in support for dynamic linking. Embedded distros shouldn't be shipping target
shared libraries, so users shouldn't be able to screw it up.

There's no reason your embedded system couldn't just deal with loading shared
objects, you'd just need to embed a loader that executes before you get to any
of that code. I've seen similar systems before, though honestly if you're that
far along you can probably deal with passing "-nostdlib"...

>> (I also think that RISC-V should use the x86-64 approach of building a
>> multiarch compiler, but that is probably water under the bridge at this
>> point. Perhaps GCC may merge riscv32/riscv64 in some future cleanup and use
>> -march=RV32*/-march=RV64*/-march=RV128* to select a processor base ISA.)
>
> This is a good proposal and gcc does have tentacles to implement
> it. There is ppc bi-arch support and mips tri-arch support already in gcc

I agree: in fact, we've supported it for years :). You could replace
riscv32-unknown-* with:

#!/bin/bash
exec "$(echo "$0" | sed s/riscv32/riscv64/g)" -march=rv32imafdc "$@"

This is why we only ship riscv64-* as part of the SiFive binary releases.
Assuming you build a multilib toolchain, the only differences are the default
"-march" and "-mabi" arguments.

Jacob Bachmeyer

unread,
Aug 29, 2017, 12:33:37 AM8/29/17
to Palmer Dabbelt, raj....@gmail.com, sw-...@groups.riscv.org
Palmer Dabbelt wrote:
> Replying to both of you here, to try to keep the thread from branching too
> much.
>
Likewise.
> On Mon, 28 Aug 2017 18:24:42 PDT (-0700), raj....@gmail.com wrote:
>
>> On Mon, Aug 28, 2017 at 5:59 PM, Jacob Bachmeyer <jcb6...@gmail.com> wrote:
>>
>>> Palmer Dabbelt wrote:
>>>
>>>> * Do we support dynamic linking? Yes, because I don't want to deal with
>>>> the
>>>> fallout.
>>>>
>>> Think about this one a bit: You propose a toolchain configuration
>>> specifically for systems that have no environment, yet want to include
>>> support for a feature that is inherently dependent on an environment?
>>>
>
> Well, that's why I brought it up: dynamic linking is probably the wrong thing
> to do on embedded systems.
>
> That said, I'm not sure it's correct to disable support for it. We solve this
> problem by not building any shared libraries when providing our toolchains for
> embedded systems (see riscv-gnu-toolchain), so there's no way for users to
> confuse this unless they're doing something tricky.
>

The problem I see is that support for dynamic linking depends on ELF,
which implies an environment, which conflicts with declaring the
toolchain as "OS: none". This does not conflict with using ELF on the
build machine to store objects, only with the idea that any further
processing will be done at run-time.

>>> I argue that riscv-*-elf should support dynamic linking using ELF, but
>>> riscv-*-none should be oriented towards building monolithic binary images,
>>> as are appropriate for a microcontroller or boot firmware image where the
>>> infrastructure for dynamic linking simply does not exist.
>>>
>
> While I agree that ELF is also probably the wrong thing to emit for embedded
> systems (as even static ELFs require some sort of loader), realistically we
> just don't have time to support any other binary formats.
>
> Our current flow is to use objcopy post-link to convert to flat binaries,
> essentially doing the loading on the host. It's not ideal, but it's
> functional. Unless someone steps up to take this on, it's not going to happen
> any time soon. I wouldn't be opposed to calling the tuple something like
> "riscv*-*-bareelf" or something, as "none" is an awkward name anyway.
>

Last I checked, GNU ld can directly generate any format BFD supports,
which means the linker can directly write a flat binary if the linker
script indicates to do so. The catch is that symbol information is
lost, so this is less useful for debugging than generating an ELF image
with symbol tables and debug info and using objcopy later.

If the toolchain is intended for OS-less microcontrollers and early boot
firmware in larger systems, then "none" is entirely correct.

>> while you can attach any kind of semantic to the tuples. This would break
>> the general understanding of tuples for gcc toolchains, I would
>> suggest to stick to the known jargons to reduce the confusion.
>> dynamic linking requires hosted environments e.g linux, freebsd and so on.
>> so if we were to use what you propose which OS would it target. generally
>> -static switch does the right thing across the toolchain to generate static
>> binaries, just stick to that.
>>

I think that you are agreeing with me here: dynamic linking requires an
environment; the "none" in riscv-*-none indicates a target that has no
environment; therefore, a riscv-*-none toolchain cannot support dynamic
linking.

> I'm not quite sure which way you're arguing here, but I'd prefer to just leave
> in support for dynamic linking. Embedded distros shouldn't be shipping target
> shared libraries, so users shouldn't be able to screw it up.
>
> There's no reason your embedded system couldn't just deal with loading shared
> objects, you'd just need to embed a loader that executes before you get to any
> of that code. I've seen similar systems before, though honestly if you're that
> far along you can probably deal with passing "-nostdlib"...
>

I am suggesting that riscv-*-none should either have "-static" in its
specs or some internal equivalent. The riscv-*-elf toolchain (possibly
with "-nostdlib" if newlib is unwanted for a particular application) is
suitable for other uses, since it implies an ELF environment. The
riscv-*-none toolchain would be specifically intended for "no
environment" and that implies that loading must be done on the build
machine to produce a flat binary. Generating static ELF with all
relocations resolved as appropriate for the target board's memory map
(from the linker script) seems appropriate and a good compromise between
simplicity and debugging support. GDB will want the symbol table, and a
flat binary does not have a symbol table, nor would most embedded users
want debugging symbols taking up space in the final image.

(The riscv-*-linux-gnu and riscv-*-rtems toolchains have specific
support for their respective systems and I expect that other operating
systems will eventually add their own tuples when they are ported to
RISC-V. I doubt OpenBSD will want to use a *-linux-gnu compiler.)

>>> (I also think that RISC-V should use the x86-64 approach of building a
>>> multiarch compiler, but that is probably water under the bridge at this
>>> point. Perhaps GCC may merge riscv32/riscv64 in some future cleanup and use
>>> -march=RV32*/-march=RV64*/-march=RV128* to select a processor base ISA.)
>>>
>> This is a good proposal and gcc does have tentacles to implement
>> it. There is ppc bi-arch support and mips tri-arch support already in gcc
>>
>
> I agree: in fact, we've supported it for years :). You could replace
> riscv32-unknown-* with:
>
> #!/bin/bash
> exec "$(echo "$0" | sed s/riscv32/riscv64/g)" -march=rv32imafdc "$@"
>
> This is why we only ship riscv64-* as part of the SiFive binary releases.
> Assuming you build a multilib toolchain, the only differences are the default
> "-march" and "-mabi" arguments.

For this reason, I suggest merging the CPU type in the tuple to "riscv"
instead of having "riscv32" and "riscv64" that are equivalent in
practice. This still leaves the problem of incompatible ABIs, but
perhaps we could repurpose the now-useless "vendor" field? (If it will
always be "unknown", then it is useless. For a RISC-V implementation to
have its own "vendor" could also be handled as a non-standard
extension.) The compiler would be riscv-generic-* or riscv-standard-*
but binaries compiled as RV32GC would be riscv-32gc-* and so forth. I
suggest putting the ISA width first to reduce the chance of a collision
with an actual vendor name, but using riscv-rv32gc-* is another option
if we do not want a "vendor" that starts with a digit.



-- Jacob

Angelo Bulfone

unread,
Aug 29, 2017, 2:18:47 AM8/29/17
to jcb6...@gmail.com, Palmer Dabbelt, raj....@gmail.com, sw-...@groups.riscv.org
About the elf vs flat binary issue. I'd lean toward elf simply because elf -> flat is a trivial invocation of objcopy, which flat -> elf required me to jump through some hoops. In addition, it's you're concerned about debug symbols, use strip.
That said, I wouldn't mind having flat binaries be an option, I just think it's not as important as elf.

--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
To post to this group, send email to sw-...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.

Liviu Ionescu

unread,
Aug 29, 2017, 3:19:22 AM8/29/17
to Palmer Dabbelt, sw-...@groups.riscv.org

> On 29 Aug 2017, at 02:49, Palmer Dabbelt <pal...@sifive.com> wrote:
>
> We currently have the following toolchain tuples committed upstream in GCC:
>
> * riscv*-*-elf: ...
> * riscv*-*-rtems: ...
> * riscv*-*-linux-gnu: ...
>
> The riscv*-*-elf toolchains ... if you call a C library function from your code that makes a
> system call as part of its implementation, then the compiler will produce a
> binary that has those system calls implemented via the standard RISC-V syscall
> ABI. As a result, these binaries will run in environments that implement this
> ABI: for example, Linux, QEMU's user-mode emulation, or the proxy kernel.
...
> None of this is suitable for bare-metal programming, where users want to know
> everything that's going on in their program.

I'm glad you finally confirmed this, since I've been accused I misunderstood it.


> More specifically:
>
> * Linking libc is sometimes viable, but often times the default newlib has too
> big of a footprint. There's options here (newlib-nano is one solution, as
> are other C libraries), but those are orthogonal to what's going on here.

both newlib and newlib-nano are 'usually' ok. there are cases when some implementation in newlib are 'heavy', but they can be easily overcome, simply add a better implementation for that function in your application.

this is how the projects created by the new Eclipse RISC-V wizard work.

> * We currently only have an implementation of libgloss that follows the default
> syscall ABI, which isn't appropriate when nothing is running to handle the
> traps that will be executed.

that implementation wouldn't be a problem itself, the problem is that you *always* include it in the build.

> * The C runtime files generally aren't wanted: the startup code doesn't make
> much sense because there's nothing to set up an environment, and the shutdown
> code probably shouldn't be run because there's rarely anything to return back
> to.

yes and no. yes, for real applications it is correct, but for testing purposes I heavily use environments like ARM semihosting, where applications get args from the host, return an exit code and leave a file (.txt, .xml, .json, etc) with the test result.

> * The linker script is almost certainly wrong, as it assumes it can just go put
> any section anywhere ... a bunch of wacky
> constrains on their segments in order to run correctly (.text in flash, .data
> in SRAM, for example). This tends to bleed over into the C runtime files as
> well.

that's correct.

> ... so I'm just going to go ahead submit
> another tuple pattern upstream to GCC to alleviate these problems. We're going
> to call the tuple pattern "riscv*-*-none",


the idea to have a bare-metal toolchain is ok.

however it is not clear why the riscv*-*-elf is still needed, since, with some care, you can use the riscv*-*-none with an explicit -lgloss and get the same binaries.

> which means the toolchains will be
> called "riscv32-unknown-none" and "riscv64-unknown-none".

I know you don't like this, but this is a good opportunity to reduce the 32-bits vs 64-bits confusion, and use a unified name, like riscv-*

> Here's the options we have for the tuple, along with the direction I'm leaning
> for each:
>
> * Do we link libc? No, but I'd be OK changing this if people think it's better
> to link libc by default.

yes, link libc

> * Do we link libgcc? Yes, as these are all internal GCC routines that users
> aren't going to be able to implement on their own anyway.

yes

> * Do we link libgloss? No, as that's what started this whole mess in the first
> place.

no

> * Do we link libnosys? No, after some feedback people would rather have their
> empty syscall implementations in some file with their own name on it.

no

> * Do we link crt*.o? No, as these aren't going to work so we shouldn't be
> linking them.

yes. for tests (like semihosting tests), the standard crt*.o may be ok.

and if you do it, the -elf toolchain will be really identical to this one plus the -lgloss option

> * Do we provide a linker script? Yes, as sometimes users can get away with
> just passing argument to GCC that tell it where to target.

yes, same reasons as before.

> * Do we support dynamic linking? Yes, because I don't want to deal with the
> fallout.

yes.

it has no additional costs and no major disadvantages.


regards,

Liviu

Liviu Ionescu

unread,
Aug 29, 2017, 3:20:02 AM8/29/17
to Khem Raj, jcb6...@gmail.com, Palmer Dabbelt, RISC-V SW Dev

> On 29 Aug 2017, at 04:24, Khem Raj <raj....@gmail.com> wrote:
>
>> Perhaps GCC may merge riscv32/riscv64 in some future cleanup and use
>> -march=RV32*/-march=RV64*/-march=RV128* to select a processor base ISA.)
>
> This is a good proposal

+1

riscv-none-gcc would be a better name.


regards,

Liviu



Liviu Ionescu

unread,
Aug 29, 2017, 3:21:20 AM8/29/17
to Palmer Dabbelt, raj....@gmail.com, jcb6...@gmail.com, sw-...@groups.riscv.org

> On 29 Aug 2017, at 06:17, Palmer Dabbelt <pal...@sifive.com> wrote:
>
> Well, that's why I brought it up: dynamic linking is probably the wrong thing
> to do on embedded systems.

although unusual, I would not call dynamic linking "wrong".

> That said, I'm not sure it's correct to disable support for it. We solve this
> problem by not building any shared libraries when providing our toolchains for
> embedded systems (see riscv-gnu-toolchain), so there's no way for users to
> confuse this unless they're doing something tricky.
...
> I'm not quite sure which way you're arguing here, but I'd prefer to just leave
> in support for dynamic linking.

fully agree.

> While I agree that ELF is also probably the wrong thing to emit for embedded
> systems

no, for debugging purposes elf is perfectly ok. how else would you do debugging?



regards,

Liviu


Liviu Ionescu

unread,
Aug 29, 2017, 3:21:43 AM8/29/17
to Angelo Bulfone, jcb6...@gmail.com, Palmer Dabbelt, raj....@gmail.com, sw-...@groups.riscv.org

> On 29 Aug 2017, at 09:18, Angelo Bulfone <mbul...@gmail.com> wrote:
>
> About the elf vs flat binary issue. I'd lean toward elf simply because elf -> flat is a trivial invocation of objcopy, which flat -> elf required me to jump through some hoops. In addition, it's you're concerned about debug symbols, use strip.
> That said, I wouldn't mind having flat binaries be an option, I just think it's not as important as elf.

elf, no question about it. how else would you do debugging without the debugging sections present in elf files?

as for having the binary file too, the GNU MCU Eclipse build plug-in has a check box and a selection for the binary format (hex, etc), it is quite easy to generate both elf and binary.


regards,

Liviu

Liviu Ionescu

unread,
Aug 29, 2017, 3:22:19 AM8/29/17
to jcb6...@gmail.com, Palmer Dabbelt, raj....@gmail.com, sw-...@groups.riscv.org

> On 29 Aug 2017, at 07:33, Jacob Bachmeyer <jcb6...@gmail.com> wrote:
>
> For this reason, I suggest merging the CPU type in the tuple to "riscv" instead of having "riscv32" and "riscv64" that are equivalent in practice.

fully agree. 'riscv-*' is more than enough and reduces confusion.

> repurpose the now-useless "vendor" field? (If it will always be "unknown", then it is useless.

in this context, "unknown" does not bring any information, it is completely useless.

> If the toolchain is intended for OS-less microcontrollers and early boot firmware in larger systems, then "none" is entirely correct.

is intended for **Unix** OS-less microcontrollers, but RTOS configurations are more than welcomed. still, "none" is entirely ok.

so, I reiterate my suggestion, 'riscv-none-gcc' would be a fine name for a bare-metal compiler.

> On 29 Aug 2017, at 07:33, Jacob Bachmeyer <jcb6...@gmail.com> wrote:
>
> The problem I see is that support for dynamic linking depends on ELF, which implies an environment, which conflicts with declaring the toolchain as "OS: none". This does not conflict with using ELF on the build machine to store objects, only with the idea that any further processing will be done at run-time.

please do not prevent the toolchain from generating shared libraries. although shared libraries are not very common in embedded applications, supporting them has no additional costs.

modern bare-metal embedded applications are more than traditional blinky samples; they have RTOSes, flash file systems, network stacks, and sometimes lots of external RAM. I would not exclude a run-time loader able to load shared libraries, so please keep this feature.

> I am suggesting that riscv-*-none should either have "-static" in its specs or some internal equivalent.

no, please don't do this. if you really need it, you can specify it explicitly.


regards,

Liviu

Liviu Ionescu

unread,
Aug 29, 2017, 4:01:47 AM8/29/17
to Palmer Dabbelt, sw-...@groups.riscv.org

> On 29 Aug 2017, at 02:49, Palmer Dabbelt <pal...@sifive.com> wrote:
>
> * riscv{32,64}-unknown-none are the full tuples, which is how we've been naming
> the other toolchains.
>
> While I feel like I'm not going to be able to prevent people from arguing about
> the naming convention here, I'd at least like to respect these constraints when
> you suggest new names.

the full tuple syntax is

<arch>-<vendor>-<os>-<library/abi>-*

but some parts are optional, as you already admit by using only 3 parts.

I think using "none" for <os> is perfectly ok; there is little room for confusion when compared to 'riscv*-*-linux-gnu'; however it will not be as easy when compared to riscv*-*-elf, since both generate elf; my suggestion is to retire the -elf toolchain entirely.

using "riscv" for <arch> is enough, since the compiler supports both 32 and 64-bits.

if you insist on riscv32-* and riscv64-*, what would you do when 128-bits support will be added? add another riscv128-*?

given the multiple ABI variations, all supported by a single toolchain, the <abi> part is not relevant.

the "unknown" name for <vendor> brings little information and only gives a feeling of uncertainty. it is optional, see names like x86_64-linux-gnu-gcc, i686-elf-gcc, etc; I suggest we drop it entirely.


the above rules give us names like 'riscv-none-gcc'; nice, tidy and future proof (when 128 bits will be ready, we'll not have to update our build configurations).

internally you can keep riscv32-*, riscv64-* and riscv128-*, if this helps the implementation, but please also add an alias riscv-*, to be used publicly.


regards,

Liviu


Marko Zec

unread,
Aug 29, 2017, 6:20:56 AM8/29/17
to Liviu Ionescu, Palmer Dabbelt, sw-...@groups.riscv.org
On Tue, 29 Aug 2017 11:01:43 +0300
Liviu Ionescu <i...@livius.net> wrote:
...
> the "unknown" name for <vendor> brings little information and only
> gives a feeling of uncertainty. it is optional, see names like
> x86_64-linux-gnu-gcc, i686-elf-gcc, etc; I suggest we drop it
> entirely.

+1

Marko

Jeremy Herbert

unread,
Aug 29, 2017, 7:40:32 AM8/29/17
to Palmer Dabbelt, sw-...@groups.riscv.org
Everything you wrote sounds great! Your efforts are very much appreciated. I will leave the naming argument to the more pedantic among us ;)

Thanks,
Jeremy

--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
To post to this group, send email to sw-...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.

Bruce Hoult

unread,
Aug 29, 2017, 8:35:06 AM8/29/17
to Palmer Dabbelt, raj....@gmail.com, Jacob Bachmeyer, RISC-V SW Dev
On Tue, Aug 29, 2017 at 6:17 AM, Palmer Dabbelt <pal...@sifive.com> wrote:
While I agree that ELF is also probably the wrong thing to emit for embedded
systems (as even static ELFs require some sort of loader), realistically we
just don't have time to support any other binary formats.

Our current flow is to use objcopy post-link to convert to flat binaries,
essentially doing the loading on the host.  It's not ideal, but it's
functional.

I disagree that generating ELF is not ideal :-)

OpenOCD can read ELF files directly just as easily as a binary image or intel hex or motorola s-record  (and the same for similar tools on other platforms, such as avrdude).

ELF is essential for debugging.

Even where someone needs to use objcopy to extract a binary image or hex or s-record from the ELF file to feed to their flashing/programming/downloading tool,  that is what they are USED to doing and what they expect. No or minimal hassle.

I think the same goes for -nostdlib and -static. It's probably best to default to using a statically linked and -ffunction-sections compiled Newlib (or whatever) for beginners when no extra flags are presented. Advanced users can add what options they need -- and it's best if they are consistent with other systems. If someone wants to implement a dynamic linker on a larger bare metal system then why prevent them?

Alex Bradbury

unread,
Aug 29, 2017, 9:37:47 AM8/29/17
to Palmer Dabbelt, RISC-V SW Dev
On 29 August 2017 at 00:49, Palmer Dabbelt <pal...@sifive.com> wrote:
> Here's the options we have for the tuple, along with the direction I'm leaning
> for each:
>
> * Do we link libc? No, but I'd be OK changing this if people think it's better
> to link libc by default.
> * Do we link libgcc? Yes, as these are all internal GCC routines that users
> aren't going to be able to implement on their own anyway.
> * Do we link libgloss? No, as that's what started this whole mess in the first
> place.
> * Do we link libnosys? No, after some feedback people would rather have their
> empty syscall implementations in some file with their own name on it.
> * Do we link crt*.o? No, as these aren't going to work so we shouldn't be
> linking them.
> * Do we provide a linker script? Yes, as sometimes users can get away with
> just passing argument to GCC that tell it where to target.
> * Do we support dynamic linking? Yes, because I don't want to deal with the
> fallout.
>
> I'd really like to get this matter put to rest, so if you have opinions on what
> should be the default set of options for the "riscv*-*-none" toolchains then
> now is the time to speak up.
>
> The implementation lives here
>
> https://github.com/riscv/riscv-gcc/commit/950f25b4fdd2f2c31cc7250107a579bff202d3d4
>
> It would be great if you could submit your suggestions as patches, but I can
> understand if that's too hard so replying with your suggestions is OK too.

Hi Palmer, thanks for so clearly summarising everything in this email.
For the list of questions above, perhaps someone could comment on what
other targets do? Obviously RISC-V doesn't _have_ to do the same as
others, but if riscv*-*-none toolchains act differently to
{mips,arm,...}*-*-none toolchains, it would be good to ensure they do
so via an explicit decision rather than by accident.

Best,

Alex

Martin Schoeberl

unread,
Aug 29, 2017, 9:42:27 AM8/29/17
to RISC-V SW Dev
Thanks for this detailed post! Lot of good information.

> On 29 Aug, 2017, at 1:49, Palmer Dabbelt <pal...@sifive.com> wrote:
>

A small OT question:

> * We currently only have an implementation of libgloss that follows the default
> syscall ABI, which isn't appropriate when nothing is running to handle the
> traps that will be executed.


When you write “default syscall ABI”, is this default somewhere documented?

I know I can find out in the source, but a document is easier to read.

Cheers,
Martin

Liviu Ionescu

unread,
Aug 29, 2017, 9:42:34 AM8/29/17
to Alex Bradbury, Palmer Dabbelt, RISC-V SW Dev

> On 29 Aug 2017, at 16:37, Alex Bradbury <a...@asbradbury.org> wrote:
>
> perhaps someone could comment on what other targets do?

as far as I know, the arm-none-eabi uses the configuration I suggested in a previous message:

> Do we link libc? No,

yes

> Do we link libgcc? Yes,

yes

> Do we link libgloss? No,

no

> Do we link libnosys? No,

no

> Do we link crt*.o? No,

yes

* Do we provide a linker script? Yes,

yes

* Do we support dynamic linking? Yes,

yes




regards,

Liviu

Richard W.M. Jones

unread,
Aug 29, 2017, 11:20:28 AM8/29/17
to Palmer Dabbelt, sw-...@groups.riscv.org
On Mon, Aug 28, 2017 at 04:49:43PM -0700, Palmer Dabbelt wrote:
> * Do we link libc? No, but I'd be OK changing this if people think it's better
> to link libc by default.

Sorry for the naive question, but what does ‘libc’ mean in this
(embedded) situation, or which libc? Or do you just mean that ‘-lc’
is added by collect2/linker/the linker script and it's up to the end
user to arrange for this to be resolved?

Rich.

--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-p2v converts physical machines to virtual machines. Boot with a
live CD or over the network (PXE) and turn machines into KVM guests.
http://libguestfs.org/virt-v2v

Palmer Dabbelt

unread,
Aug 29, 2017, 12:33:44 PM8/29/17
to z...@fer.hr, i...@livius.net, sw-...@groups.riscv.org
I'd like to reiterate here that we're discussing canonical tuple names only,
specifically to avoid this sort of bikeshedding. If you want to argue about
non-canonical tuple names, then please open another thread (and don't CC me on
it).

Let's try to keep this thread on track.

Palmer Dabbelt

unread,
Aug 29, 2017, 12:33:44 PM8/29/17
to br...@hoult.org, raj....@gmail.com, jcb6...@gmail.com, sw-...@groups.riscv.org
On Tue, 29 Aug 2017 05:35:03 PDT (-0700), br...@hoult.org wrote:
> On Tue, Aug 29, 2017 at 6:17 AM, Palmer Dabbelt <pal...@sifive.com> wrote:
>
>> While I agree that ELF is also probably the wrong thing to emit for
>> embedded
>> systems (as even static ELFs require some sort of loader), realistically we
>> just don't have time to support any other binary formats.
>>
>> Our current flow is to use objcopy post-link to convert to flat binaries,
>> essentially doing the loading on the host. It's not ideal, but it's
>> functional.
>
>
> I disagree that generating ELF is not ideal :-)
>
> OpenOCD can read ELF files directly just as easily as a binary image or
> intel hex or motorola s-record (and the same for similar tools on other
> platforms, such as avrdude).
>
> ELF is essential for debugging.
>
> Even where someone needs to use objcopy to extract a binary image or hex or
> s-record from the ELF file to feed to their
> flashing/programming/downloading tool, that is what they are USED to doing
> and what they expect. No or minimal hassle.

Yep -- this is why I really don't want to abandon ELF. While it'd be simple to
make the toolchain spit out flat binaries, it's going to be hard to get a
single flat binary format that everyone agrees on as there's all these subtle
incompatibilities. ELF is standard, designed to support all the features you
could possibly want, and is simple to convert to flat binaries.

> I think the same goes for -nostdlib and -static. It's probably best to
> default to using a statically linked and -ffunction-sections
> compiled Newlib (or whatever) for beginners when no extra flags are
> presented. Advanced users can add what options they need -- and it's best
> if they are consistent with other systems. If someone wants to implement a
> dynamic linker on a larger bare metal system then why prevent them?

I think you (and maybe a few other people) are conflating two things here:

* Do we support support dynamic linking? We currently do.

* Do we default to dynamic linking? We don't even in the
"riscv*-*-elf" toolchains we ship now, as it's not going to work on most
embedded systems.

The question was "do we allow dynamic linking", not "do we default to dymanic
linking". I think we've all reached the agreement that we support dynamic
linking but don't default to it, just like the "riscv*-*-elf" toolchains do.

Palmer Dabbelt

unread,
Aug 29, 2017, 12:33:45 PM8/29/17
to rjo...@redhat.com, sw-...@groups.riscv.org
On Tue, 29 Aug 2017 08:20:24 PDT (-0700), rjo...@redhat.com wrote:
> On Mon, Aug 28, 2017 at 04:49:43PM -0700, Palmer Dabbelt wrote:
>> * Do we link libc? No, but I'd be OK changing this if people think it's better
>> to link libc by default.
>
> Sorry for the naive question, but what does ‘libc’ mean in this
> (embedded) situation, or which libc? Or do you just mean that ‘-lc’
> is added by collect2/linker/the linker script and it's up to the end
> user to arrange for this to be resolved?

In an ideal world, that would be all that happens. GCC calls this variable
"LIB_SPEC", which lives here for the "riscv*-*-elf" toolchains

https://github.com/riscv/riscv-gcc/blob/riscv-gcc-7/gcc/config/riscv/elf.h#L27

Unfortunately there's a few places in GCC where the tuple is actually tied to
the C library, for example here

https://github.com/riscv/riscv-gcc/blob/riscv-gcc-7/gcc/config.gcc#L2035

or here

https://github.com/riscv/riscv-gcc/blob/riscv-gcc-7/gcc/config.gcc#L2021

This is really an upstream GCC issue and is a mess everywhere, but we could
always add a bunch more autoconf wizardry to fill these out appropriately.
Right now we only have newlib and glibc, so we're safe :).

Palmer Dabbelt

unread,
Aug 29, 2017, 12:38:28 PM8/29/17
to mar...@jopdesign.com, sw-...@groups.riscv.org
On Tue, 29 Aug 2017 06:41:14 PDT (-0700), mar...@jopdesign.com wrote:
> Thanks for this detailed post! Lot of good information.
>
>> On 29 Aug, 2017, at 1:49, Palmer Dabbelt <pal...@sifive.com> wrote:
>>
>
> A small OT question:
>
>> * We currently only have an implementation of libgloss that follows the default
>> syscall ABI, which isn't appropriate when nothing is running to handle the
>> traps that will be executed.
>
>
> When you write “default syscall ABI”, is this default somewhere documented?

It should be here

https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md

but it's not.

> I know I can find out in the source, but a document is easier to read.

It's actually pretty simple: it's exactly the same as the regular call ABI,
except that:

* No floating-point registers are ever used.
* The syscall number goes in a7, so only a0-a6 are available for arguments.
* Control transfer is handled by "ecall" instead of "call".

Right now we just use the syscall numbers from Linux's asm-generic, and we use
the subset that happens to be supported by all the implementations (ie, a mushy
definition). In theory that should all be specified as well, but that's a lot
more work.

Do you have time to write some documentation?

Michael Clark

unread,
Aug 29, 2017, 5:15:43 PM8/29/17
to Liviu Ionescu, Palmer Dabbelt, sw-...@groups.riscv.org
This statement implies that riscv*-*-elf is not a bare-metal toolchain.

It is when passing -nostartfiles -nostdlib -nostdinc

A bare metal toolchain implies no start files or C library, but again this can be achieved simply by passing flags to the riscv*-*-elf “newlib” toolchain.

> however it is not clear why the riscv*-*-elf is still needed, since, with some care, you can use the riscv*-*-none with an explicit -lgloss and get the same binaries.
>
>> which means the toolchains will be
>> called "riscv32-unknown-none" and "riscv64-unknown-none".
>
> I know you don't like this, but this is a good opportunity to reduce the 32-bits vs 64-bits confusion, and use a unified name, like riscv-*
>
>> Here's the options we have for the tuple, along with the direction I'm leaning
>> for each:
>>
>> * Do we link libc? No, but I'd be OK changing this if people think it's better
>> to link libc by default.
>
> yes, link libc

As soon as you link crt and libc you are not strictly bare-metal any more.

bare metal implies implementing _start, and if you implement _start, by nature you are not linking the crt, and the crt is by nature tied to libc.

>> * Do we link libgcc? Yes, as these are all internal GCC routines that users
>> aren't going to be able to implement on their own anyway.
>
> yes
>
>> * Do we link libgloss? No, as that's what started this whole mess in the first
>> place.
>
> no
>
>> * Do we link libnosys? No, after some feedback people would rather have their
>> empty syscall implementations in some file with their own name on it.
>
> no
>
>> * Do we link crt*.o? No, as these aren't going to work so we shouldn't be
>> linking them.
>
> yes. for tests (like semihosting tests), the standard crt*.o may be ok.
>
> and if you do it, the -elf toolchain will be really identical to this one plus the -lgloss option

The newlib syscall stubs can be eliminated simply by passing: -nostdlib -lc

e.g.

$ cat hello.c
#include <stdio.h>

int main()
{
printf("Hello World\n");
}

here we have removed -lgloss by passing -nostdlib -lc

$ riscv64-unknown-elf-gcc hello.c -nostdlib -lc -o hello

sbrkr.c:(.text+0x10): undefined reference to `sbrk'
writer.c:(.text+0x14): undefined reference to `write'
closer.c:(.text+0x10): undefined reference to `close'
lseekr.c:(.text+0x14): undefined reference to `lseek'
readr.c:(.text+0x14): undefined reference to `read'
fstatr.c:(.text+0x12): undefined reference to `fstat'
isattyr.c:(.text+0x10): undefined reference to `isatty’

and here we have substituted -lnosys for -lgloss

$ riscv64-unknown-elf-gcc hello.c -nostdlib -lc -lnosys -o hello

closer.c:(.text+0x15): warning: _close is not implemented and will always fail
fstatr.c:(.text+0x17): warning: _fstat is not implemented and will always fail
isattyr.c:(.text+0x15): warning: _isatty is not implemented and will always fail
lseekr.c:(.text+0x19): warning: _lseek is not implemented and will always fail
readr.c:(.text+0x19): warning: _read is not implemented and will always fail
writer.c:(.text+0x19): warning: _write is not implemented and will always fail

Is there really much point in creating a new toolchain if its all about getting the elf/newlib toolchain to not link libgloss by default?

Also it sounds to me like the toolchain should technically be named:

riscv*-*-newlib

We shouldn’t really have none in the abi/lib position of the tuple if its indeed a “newlib” toolchain. none implies no crt or libc.

I think the term “embedded” toolchain might be more appropriate as bare metal implies implementing _start i.e. no crt or libc, and this is just -nostdinc plus link options.

>> * Do we provide a linker script? Yes, as sometimes users can get away with
>> just passing argument to GCC that tell it where to target.
>
> yes, same reasons as before.
>
>> * Do we support dynamic linking? Yes, because I don't want to deal with the
>> fallout.
>
> yes.
>
> it has no additional costs and no major disadvantages.

There is the cost of fragmentation in link options with two “newlib” embedded toolchains. I can see a case for it if it is a distinct newlib-nano toolchain, assuming this can’t be done within the confines of the existing elf bare metal toolchain using multilib. If this can’t be done as multilib there might be a case for another newlib toolchain configured for newlib-nano e.g.

riscv*-*-nano

none should be reserved for a toolchain that has no libc or crt, just libgcc otherwise it is technically a misnomer as “newlib” should be in the lib/abi suffix for a newlib “embedded” toolchain, not none. I don’t necessarily think we should copy the mistakes from other platforms.

bare metal is the omission of standard includes, the crt and C library and this can be achieved with link options.

Tommy Murphy

unread,
Aug 29, 2017, 5:31:40 PM8/29/17
to RISC-V SW Dev, i...@livius.net, pal...@sifive.com
In my opinion this is a (the?) key question here.
And right now my view is that the answer is "no" for the reasons outlined by Michael.
If others still think that the answer is "yes" can they clearly explain/synopsise the rationale for a third (fourth if we include the aforementioned RTEMS specific toolchain?!?) toolchain?
The existing riscv*-unknown-elf-gcc toolchain is capable of targeting bare metal and many of us are using it to do so.
In my view another toolchain variant just creates more confusion and fragmentation for no obviously good reason.

Angelo Bulfone

unread,
Aug 29, 2017, 5:33:48 PM8/29/17
to Tommy Murphy, RISC-V SW Dev, i...@livius.net, pal...@sifive.com
Just because something can be used for something doesn't mean it should. Bare metal development can be done with a linux toolchain, but there's an entire wiki page detailing why you shouldn't.

--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
To post to this group, send email to sw-...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.

Michael Clark

unread,
Aug 29, 2017, 5:38:42 PM8/29/17
to Angelo Bulfone, Tommy Murphy, RISC-V SW Dev, i...@livius.net, pal...@sifive.com
The newlib/elf toolchain is not strictly a linux toolchain. It differs substantially from linux-gnu as was pointed out in detail by Palmer. The only linuxy part of the newlib toolchain that its libgloss implementation emits linux compatible syscalls. These can be optioned out with linker options.

As Tommy pointed out, and based on Liviu’s requests for libc it boils down to removing -lgloss from the specs file of the elf/newlib toolchain. I don’t think that flag change warrants creating another “newlib” embedded toolchain.
> To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/CAGP_OL7%2BR_5OiGqBkxhP56aUuBfzLuPBey2EC-dG4qzmO29QQg%40mail.gmail.com.

Tommy Murphy

unread,
Aug 29, 2017, 5:44:08 PM8/29/17
to RISC-V SW Dev, tommy_...@hotmail.com, i...@livius.net, pal...@sifive.com
It might be helpful for you to link to the wiki to which you refer for those of us who don't know what you're referring to.
The linux toolchain doesn't bundle/use newlib so obviously (to me anyway) it's not suitable for bare metal.
The riscv*-unknown-elf does use bundle/newlib and IS usable and, arguably, suitable for use with bare metal targets as it stands.
You haven't really addressed my question of clearly laying out the rationale for yet another toolchain.

Liviu Ionescu

unread,
Aug 29, 2017, 5:47:02 PM8/29/17
to Michael Clark, Palmer Dabbelt, sw-...@groups.riscv.org

> On 30 Aug 2017, at 00:15, Michael Clark <michae...@mac.com> wrote:
>
>
> As soon as you link crt and libc you are not strictly bare-metal any more.
>
> bare metal implies implementing _start, and if you implement _start, by nature you are not linking the crt, and the crt is by nature tied to libc.

not necessarily. there are things in libc that can be safely used.

it should be the user call to use it or not.

> Also it sounds to me like the toolchain should technically be named:
>
> riscv*-*-newlib
>
> We shouldn’t really have none in the abi/lib position of the tuple if its indeed a “newlib” toolchain. none implies no crt or libc.

the full tuple syntax is

<arch>-<vendor>-<os>-<library/abi>-*

as such, 'none' is for <os>. I already explained this 2 times.

> ... I can see a case for it if it is a distinct newlib-nano toolchain,

GNU MCU RISC-V GCC, which is only a repack of riscv*-*-elf already includes support for newlib-nano, in parallel with the large newlib.

you have to specify --specs=nano and everything moves to nano (includes and libraries). same as arm-none-eabi.


> none should be reserved for a toolchain that has no libc or crt,

nope. 'none' is practically the antonym for 'linux'. means no 'real' operating system needed to run the application.


regards,

Liviu

Angelo Bulfone

unread,
Aug 29, 2017, 5:48:12 PM8/29/17
to Tommy Murphy, RISC-V SW Dev, i...@livius.net, pal...@sifive.com

--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
To post to this group, send email to sw-...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.

Tommy Murphy

unread,
Aug 29, 2017, 5:56:20 PM8/29/17
to RISC-V SW Dev, tommy_...@hotmail.com, i...@livius.net, pal...@sifive.com
Thanks - I obviously missed that earlier.
But to be honest it looks like a bit of a non sequitur to me in the context of this and related threads.
I am still far from convinced that we need yet another toolchain just to deal with the libgloss/crt0 etc. issues when the existing riscv*-unknown-elf works for bare metal and many of us are using it successfully.

Liviu Ionescu

unread,
Aug 29, 2017, 6:24:20 PM8/29/17
to Michael Clark, Angelo Bulfone, Tommy Murphy, RISC-V SW Dev, pal...@sifive.com

> On 30 Aug 2017, at 00:38, Michael Clark <michae...@mac.com> wrote:
>
> it boils down to removing -lgloss from the specs file of the elf/newlib toolchain

that was my initial request.

due to internal usage of the -elf one in various test suites, Palmer considered this request unacceptable and suggested a new toolchain, which in the end it turns out to be identical with the -elf one, with the -libgloss removed from the specs.

my concern with the -elf toolchain is that, considering it will continue to be used mainly for tests that run on linux-like environments, in time we might get changes that contradict the common uses in embedded environments.

thus I'd prefer a -none toolchain, explicitly intended for embedded environments, hopefully with slimmer chances of surprises.


btw, since embedded and bare-metal configurations have a wide range of meanings, and I have a feeling that on this list many people have different requirements, and different experience, could those who suggest various embedded and bare-metal configurations define their range of interests?


regards,

Liviu


for conformity: my interest is mainly in microcontroller applications that run from flash, have a relatively limited amount of ram (tens to hundreds of kB) and a wide range of peripherals (usb, can, i2c, buttons, displays, radios, etc). from a software point of view the very small devices run in a loop, and the large ones use a RTOS (like µOS++, the project I maintain, http://micro-os-plus.github.io). modern embedded environments also support flash file systems, network stacks, usb, and for this POSIX like IO environments are required, thus the conflict with -libgloss in the current toolchain. as experience, I did various embedded OSes from 8080, Z80, i960, PICs, AVRs, and, recently, all Cortex-M devices. I'm currently not targeting linux loaders, multi-core gpus and generally non-microcontroller usages.

after my initial limited experience with RISC-V, my current feeling is that microcontroller applications are only marginally addressed, the focus being on large linux application devices, or very specific multi-core devices, like gpus. which is a pity.




Martin Schoeberl

unread,
Aug 29, 2017, 7:35:48 PM8/29/17
to RISC-V SW Dev
This is a starting point. What is (or where is) Linux’s asm-generic?

I am fine with a mushy definition and those ecall traps should be fine for a
simulator of a RISC-V processor.

> Do you have time to write some documentation?

Not too much, but I might have a little bit of time. I’m introducing RISC-V in teaching
this semester and this allows for some time to contribute.

Cheers,
Martin

Jacob Bachmeyer

unread,
Aug 29, 2017, 8:07:01 PM8/29/17
to Liviu Ionescu, Angelo Bulfone, Palmer Dabbelt, raj....@gmail.com, sw-...@groups.riscv.org
To be clear, I agree that the linker should default to generating ELF,
since other tools (like GDB) will want that image. But that ELF image
should contain a flat binary -- no relocations, no dynamic linking, just
a "preloaded" binary that already fits the target board's physical
memory map.


-- Jacob

Jacob Bachmeyer

unread,
Aug 29, 2017, 8:20:33 PM8/29/17
to Liviu Ionescu, Palmer Dabbelt, raj....@gmail.com, sw-...@groups.riscv.org
Liviu Ionescu wrote:
>> On 29 Aug 2017, at 07:33, Jacob Bachmeyer <jcb6...@gmail.com> wrote:
>>
>> For this reason, I suggest merging the CPU type in the tuple to "riscv" instead of having "riscv32" and "riscv64" that are equivalent in practice.
>>
>
> fully agree. 'riscv-*' is more than enough and reduces confusion.
>
>
>> repurpose the now-useless "vendor" field? (If it will always be "unknown", then it is useless.
>>
>
> in this context, "unknown" does not bring any information, it is completely useless.
>
>
>> If the toolchain is intended for OS-less microcontrollers and early boot firmware in larger systems, then "none" is entirely correct.
>>
>
> is intended for **Unix** OS-less microcontrollers, but RTOS configurations are more than welcomed. still, "none" is entirely ok.
>
> so, I reiterate my suggestion, 'riscv-none-gcc' would be a fine name for a bare-metal compiler.
>

I was suggesting to reuse the "vendor" field as a "variant" field:
CPU-VARIANT-OS or CPU-VARIANT-KERNEL-OS. This would provide a place to
record various extensions, such that a full RISC-V target could be
something like riscv-rv32ec-none or riscv-rv64gqv-linux-gnu. The same
riscv-standard-none and riscv-standard-linux-gnu compilers would be able
to generate binaries for all standard ISA variants. At some point, if
we can reduce the differences to libraries, we might be able to merge
all of those into a single multiarch multilib "riscv-standard-gcc" for
all standard RISC-V ISA variants on all environments.

>> On 29 Aug 2017, at 07:33, Jacob Bachmeyer <jcb6...@gmail.com> wrote:
>>
>> The problem I see is that support for dynamic linking depends on ELF, which implies an environment, which conflicts with declaring the toolchain as "OS: none". This does not conflict with using ELF on the build machine to store objects, only with the idea that any further processing will be done at run-time.
>>
>
> please do not prevent the toolchain from generating shared libraries. although shared libraries are not very common in embedded applications, supporting them has no additional costs.
>
> modern bare-metal embedded applications are more than traditional blinky samples; they have RTOSes, flash file systems, network stacks, and sometimes lots of external RAM. I would not exclude a run-time loader able to load shared libraries, so please keep this feature.
>

The catch here is that we have another toolchain (riscv-*-elf) that
fully supports dynamic linking, *and* is intended for non-specific ELF
environments. If you want to build shared objects, use riscv-*-elf. If
you want to build truly bare-metal programs, use riscv-*-none. At the
point where you have an RTOS, flash file system, network stack, and a
dynamic loader, for which you are building a shared object, you are not
programming a bare-metal environment anymore. Put another way
"bare-metal" and "loads shared objects" are mutually exclusive.

>> I am suggesting that riscv-*-none should either have "-static" in its specs or some internal equivalent.
>>
>
> no, please don't do this. if you really need it, you can specify it explicitly.
>

If you want dynamic linking, use riscv-*-elf. There is no proposal to
remove dynamic linking from the riscv-*-elf toolchain, only that the new
riscv-*-none toolchain logically cannot support dynamic linking and
should not appear to do so.


-- Jacob

Jacob Bachmeyer

unread,
Aug 29, 2017, 8:29:03 PM8/29/17
to Palmer Dabbelt, br...@hoult.org, raj....@gmail.com, sw-...@groups.riscv.org
Palmer Dabbelt wrote:
> On Tue, 29 Aug 2017 05:35:03 PDT (-0700), br...@hoult.org wrote:
>
>> On Tue, Aug 29, 2017 at 6:17 AM, Palmer Dabbelt <pal...@sifive.com> wrote:
>>
>>
>>> While I agree that ELF is also probably the wrong thing to emit for
>>> embedded
>>> systems (as even static ELFs require some sort of loader), realistically we
>>> just don't have time to support any other binary formats.
>>>
>>> Our current flow is to use objcopy post-link to convert to flat binaries,
>>> essentially doing the loading on the host. It's not ideal, but it's
>>> functional.
>>>
>> I disagree that generating ELF is not ideal :-)
>>
>> OpenOCD can read ELF files directly just as easily as a binary image or
>> intel hex or motorola s-record (and the same for similar tools on other
>> platforms, such as avrdude).
>>
>> ELF is essential for debugging.
>>
>> Even where someone needs to use objcopy to extract a binary image or hex or
>> s-record from the ELF file to feed to their
>> flashing/programming/downloading tool, that is what they are USED to doing
>> and what they expect. No or minimal hassle.
>>
>
> Yep -- this is why I really don't want to abandon ELF. While it'd be simple to
> make the toolchain spit out flat binaries, it's going to be hard to get a
> single flat binary format that everyone agrees on as there's all these subtle
> incompatibilities. ELF is standard, designed to support all the features you
> could possibly want, and is simple to convert to flat binaries.
>

ELF is fine as linker output. I had mentioned that GNU ld *already*
supports writing other formats, but I was not suggesting that we should
change the default, especially not when most other GNU toolchains wrap
their flat binaries in ELF.

>> I think the same goes for -nostdlib and -static. It's probably best to
>> default to using a statically linked and -ffunction-sections
>> compiled Newlib (or whatever) for beginners when no extra flags are
>> presented. Advanced users can add what options they need -- and it's best
>> if they are consistent with other systems. If someone wants to implement a
>> dynamic linker on a larger bare metal system then why prevent them?
>>
>
> I think you (and maybe a few other people) are conflating two things here:
>
> * Do we support support dynamic linking? We currently do.
>
> * Do we default to dynamic linking? We don't even in the
> "riscv*-*-elf" toolchains we ship now, as it's not going to work on most
> embedded systems.
>
> The question was "do we allow dynamic linking", not "do we default to dymanic
> linking". I think we've all reached the agreement that we support dynamic
> linking but don't default to it, just like the "riscv*-*-elf" toolchains do.

If we allow dynamic linking, then what is the difference between
risvc-*-elf and riscv-*-none?

I maintain that we should support dynamic linking in the riscv-*-elf
toolchains (but default to static linking) since "ELF" is enough of an
environment for dynamic linking to possibly make sense. By the same
token, lack of dynamic linking support is logically the major difference
between riscv-*-none and riscv-*-elf, since the former targets an
environment where dynamic linking is not possible. If you can load a
shared object, then you have an environment that goes beyond "bare
metal" and riscv-*-none specifically targets "bare metal" environments.

If riscv-*-none will support ELF dynamic linking, thus assuming an ELF
environment, why have it distinct from riscv-*-elf? Why not just use
riscv-*-elf?


-- Jacob

Liviu Ionescu

unread,
Aug 30, 2017, 1:33:38 AM8/30/17
to jcb6...@gmail.com, Palmer Dabbelt, br...@hoult.org, raj....@gmail.com, sw-...@groups.riscv.org

> On 30 Aug 2017, at 03:28, Jacob Bachmeyer <jcb6...@gmail.com> wrote:
>
> At the point where you have an RTOS, flash file system, network stack, and a dynamic loader, for which you are building a shared object, you are not programming a bare-metal environment anymore.

then we obviously have a different understanding of the subject.

if you stick to your definition then yes, I do not want a truly `bare-metal` environment where I have to write everything from scratch when there are plenty of useful functions in the library (who would want it?); I want a modern IoT environment, which I already have for Cortex-M devices and planned to use for RISC-V too. it is as POSIX compatible as reasonably possible, but it does not use a unix kernel, so libgloss stands in the way.

> ... Why not just use riscv-*-elf?

because it always includes libgloss, which interferes with my POSIX IO sybsystem, used to access character devices (like uarts), files in file systems and network stacks.

> If you can load a shared object, then you have an environment that goes beyond "bare metal" and riscv-*-none specifically targets "bare metal" environments.

I have difficulties to understand what kind of applications you are targeting when you say 'bare-metal' and why do you insist on providing a crippled toolchain? the current risvc-*-elf without libgloss is perfectly fine.

what is your experience in (modern) embedded systems that makes you think this is not ok?

`arm-none-eabi-` does exactly this and the whole world is perfectly happy with it. why do we feel the need to re-innvent the wheel?


regards,

Liviu

Liviu Ionescu

unread,
Aug 30, 2017, 2:07:29 AM8/30/17
to jcb6...@gmail.com, Palmer Dabbelt, br...@hoult.org, raj....@gmail.com, sw-...@groups.riscv.org

> On 30 Aug 2017, at 08:33, Liviu Ionescu <i...@livius.net> wrote:
>
>> At the point where you have an RTOS, flash file system, network stack, and a dynamic loader, for which you are building a shared object, you are not programming a bare-metal environment anymore.
>
> then we obviously have a different understanding of the subject.

to be sure we align our terminology, the short definition of "bare-metal" is that of an environment without an operating system (a traditional one, like Unix):

https://en.wikipedia.org/wiki/Bare_machine

this is exactly what I am targeting, and, for this environment, riscv*-*-elf has the disadvantage of requiring extra juggling to get rid of libgloss, which depends on a linux kernel (and breaks the above definition).


regards,

Liviu




Bruce Hoult

unread,
Aug 30, 2017, 3:31:05 AM8/30/17
to Liviu Ionescu, Jacob Bachmeyer, Palmer Dabbelt, raj....@gmail.com, RISC-V SW Dev
It doesn't depend on a Linux kernel, it depends on having a trap handler that implements a small amount of basic functionality that happens to be compatible with a tiny subset of Linux.

As Michael showed, it is trivial to get rid of libgloss with a couple of command line flags which you can put in your makefile and then forget. Or even in environment variables.

If you want one setup and someone else wants another setup then you're going to have to do *something* different to them. Or, indeed, if you want different things in different projects.

I don't understand why changing the makefile variable for linker flags to get different setups is more onerous than changing the makefile variable for the toolchain name.




regards,

Liviu




--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+unsubscribe@groups.riscv.org.

To post to this group, send email to sw-...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.

Richard Herveille

unread,
Aug 30, 2017, 3:53:34 AM8/30/17
to Liviu Ionescu, Michael Clark, Angelo Bulfone, Tommy Murphy, RISC-V SW Dev, pal...@sifive.com, Richard Herveille

Just because a particular group uses a toolchain for a particular purpose, doesn’t mean everybody else has to.

Maybe the tests should include –libgloss during compilation?

 

I see no need for a new toolchain. Rename riscv[xx]-unkown-elf-gcc to riscv-none-elf-gcc and remove libgloss from the build (yes, that’s what Liviu did). Anybody who wants to use additional libraries should include those during their code build.

I have no preference for the naming. I just don’t think we need another toolchain.

 

Richard

 

 

 

 

Richard Herveille

Managing Director

Phone +31 (45) 405 5681

Cell +31 (6) 5207 2230

richard....@roalogic.com

 

--

You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.

To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.

To post to this group, send email to sw-...@groups.riscv.org.

Liviu Ionescu

unread,
Aug 30, 2017, 3:54:28 AM8/30/17
to Bruce Hoult, Jacob Bachmeyer, Palmer Dabbelt, raj....@gmail.com, RISC-V SW Dev

> On 30 Aug 2017, at 10:31, Bruce Hoult <br...@hoult.org> wrote:
>
> It doesn't depend on a Linux kernel, it depends on having a trap handler that implements a small amount of basic functionality that happens to be compatible with a tiny subset of Linux.

same thing.

> I don't understand why changing the makefile variable for linker flags to get different setups is more onerous than changing the makefile variable for the toolchain name.

because I do not use makefile directly, but managed Eclipse projects, and expecting the user to not forget to reconfigure the linker flags each time a new Eclipse project or build configuration is created is not realistic.

given that in most cases (99.9%?) the same options are required, it is safer to have them as defaults.


regards,

Liviu



Richard Herveille

unread,
Aug 30, 2017, 3:58:20 AM8/30/17
to Liviu Ionescu, Bruce Hoult, Jacob Bachmeyer, Palmer Dabbelt, raj....@gmail.com, RISC-V SW Dev, Richard Herveille

 

I don't understand why changing the makefile variable for linker flags to get different setups is more onerous than changing the makefile variable for the toolchain name.

 

because I do not use makefile directly, but managed Eclipse projects, and expecting the user to not forget to reconfigure the linker flags each time a new Eclipse project or build configuration is created is not realistic.

 

given that in most cases (99.9%?) the same options are required, it is safer to have them as defaults.

 

 

[rih] Playing devil’s advocate here…

You can set de flag to remove libgloss (and anything else you want to remove/add) as defaults in your eclipse plugin.xml. That’s what I do in the eclipse environment I provide.

 

Richard

 

 

 

 

 

regards,

 

Liviu

 

 

 

--

You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.

To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.

To post to this group, send email to sw-...@groups.riscv.org.

Richard Herveille

unread,
Aug 30, 2017, 4:01:23 AM8/30/17
to jcb6...@gmail.com, Liviu Ionescu, Palmer Dabbelt, raj....@gmail.com, sw-...@groups.riscv.org, Richard Herveille

 

I was suggesting to reuse the "vendor" field as a "variant" field:  

CPU-VARIANT-OS or CPU-VARIANT-KERNEL-OS.  This would provide a place to

record various extensions, such that a full RISC-V target could be

something like riscv-rv32ec-none or riscv-rv64gqv-linux-gnu.  The same

riscv-standard-none and riscv-standard-linux-gnu compilers would be able

to generate binaries for all standard ISA variants.  At some point, if

we can reduce the differences to libraries, we might be able to merge

all of those into a single multiarch multilib "riscv-standard-gcc" for

all standard RISC-V ISA variants on all environments.

 

 

[rih] Please no … The –march= and –mabi= options are intended for this.

 

Richard

 

 

 

Liviu Ionescu

unread,
Aug 30, 2017, 4:02:26 AM8/30/17
to Richard Herveille, Bruce Hoult, Jacob Bachmeyer, Palmer Dabbelt, raj....@gmail.com, RISC-V SW Dev

> On 30 Aug 2017, at 10:58, Richard Herveille <richard....@roalogic.com> wrote:
>
> You can set de flag to remove libgloss (and anything else you want to remove/add) as defaults in your eclipse plugin.xml.

my build plug-in is multi-toolchain, the user can select the toolchain from a list (that can be extended by other plug-ins via an extension point), it is not reasonable to use defaults specific to a toolchain in plugin.xml, since they'll be applied to all toolchains.

regards,

Liviu



Liviu Ionescu

unread,
Aug 30, 2017, 4:03:56 AM8/30/17
to Richard Herveille, jcb6...@gmail.com, Palmer Dabbelt, raj....@gmail.com, sw-...@groups.riscv.org

> On 30 Aug 2017, at 11:01, Richard Herveille <richard....@roalogic.com> wrote:
>
> I was suggesting to reuse the "vendor" field as a "variant" field:
> ...
> [rih] Please no … The –march= and –mabi= options are intended for this.

agree.

and it won't convince Palmer anyway. ;-)


regards,

Liviu



Liviu Ionescu

unread,
Aug 30, 2017, 4:17:42 AM8/30/17
to Richard Herveille, Michael Clark, Angelo Bulfone, Tommy Murphy, RISC-V SW Dev, pal...@sifive.com

> On 30 Aug 2017, at 10:53, Richard Herveille <richard....@roalogic.com> wrote:
>
> ... remove libgloss from the build (yes, that’s what Liviu did).

ah, good you reminded me. I already did it. so I'm fine; and my users will also be fine.

I think I gave enough arguments why removing libgloss from the gcc specs would be a safer option, while preserving the other configuration choices as they are now.

if there are others who need it, either make your voice heard so that Palmer provides a satisfactory solution, or simply use my toolchain distribution (which, even for the inclusion of newlib-nano, is anyway more elaborate than the official one).


regards,

Liviu

Cesar Eduardo Barros

unread,
Aug 30, 2017, 8:00:28 AM8/30/17
to Martin Schoeberl, RISC-V SW Dev
Em 29-08-2017 20:35, Martin Schoeberl escreveu:
>
>> On 29 Aug, 2017, at 18:38, Palmer Dabbelt <pal...@sifive.com> wrote:
>>
>> Right now we just use the syscall numbers from Linux's asm-generic, and we use
>> the subset that happens to be supported by all the implementations (ie, a mushy
>> definition). In theory that should all be specified as well, but that's a lot
>> more work.
>
> This is a starting point. What is (or where is) Linux’s asm-generic?

A quick story lesson:

A long time ago, every time Linux was ported to a new architecture, the
architecture-specific code and headers were copy-and-pasted from another
architecture, and then modified to fit the new architecture. This led to
a maze of duplicated headers, all slightly different. Every change or
bugfix to these headers and code had to be duplicated for every
architecture in the kernel, taking care to respect the small differences.

To reduce the duplication, the asm-generic directory was created. It has
that name because architecture-dependent headers on Linux are named
asm/something.h, while architecture-independent headers are named
linux/something.h (on an installed system, they can be found at
/usr/include/asm and /usr/include/linux). The headers which had been
duplicated several times were deduplicated and moved to that directory.

It is recommended that ports of Linux to new architectures use the
asm-generic headers as much as possible, to reduce the work both of
creating the port, and of maintaning it (and the rest of the kernel).
Since RISC-V is a new port, it follows that advice.

As to where it can be found, the part which interests you is at
include/uapi/asm-generic on the Linux kernel source code (it can be
found at /usr/include/asm-generic on an installed system; "uapi" are the
headers visible to user space). For instance, the unistd.h header has
the system call numbers.

That is, unless the RISC-V port has its own asm/unistd.h header (which
it probably doesn't), you should look at the following two headers:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/uapi/asm-generic/unistd.h
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/syscalls.h

To conclude, a couple of articles about asm-generic:

https://lwn.net/Articles/307713/
https://lwn.net/Articles/357803/

--
Cesar Eduardo Barros
ces...@cesarb.eti.br

Liviu Ionescu

unread,
Aug 30, 2017, 8:03:32 AM8/30/17
to Cesar Eduardo Barros, Martin Schoeberl, RISC-V SW Dev

> On 30 Aug 2017, at 15:00, Cesar Eduardo Barros <ces...@cesarb.eti.br> wrote:
>
>> This is a starting point. What is (or where is) Linux’s asm-generic?
>
> A quick story lesson: ...

thank you, but I think this is a bit off-topic.


regards,

Liviu


Palmer Dabbelt

unread,
Aug 30, 2017, 11:15:13 AM8/30/17
to i...@livius.net, ces...@cesarb.eti.br, mar...@jopdesign.com, sw-...@groups.riscv.org
I disagree.

The RISC-V software effort is a massive project, and it will only succeed if we
have a vibrant community behind it. We're never going to get there if we treat
potential contributors with hostility. It's always on-topic to offer to write
documentation for a RISC-V project or specification on this list, and it's
wonderful when a member of the community steps up to help turn a user into
contributor. Stories are always a plus :).

Martin: Hopefully we haven't managed to scare you away from contributing to
RISC-V projects. We're sorely lacking in documentation so we'd really value
some contributions here. Documentation is meant to be consumed by people who
aren't very familiar with a project, so often times it's best written by people
who are in the same boat.

If you have any more questions, feel free to ask!

Liviu Ionescu

unread,
Aug 30, 2017, 2:27:18 PM8/30/17
to Palmer Dabbelt, ces...@cesarb.eti.br, mar...@jopdesign.com, sw-...@groups.riscv.org

> On 30 Aug 2017, at 18:15, Palmer Dabbelt <pal...@sifive.com> wrote:
>
> On Wed, 30 Aug 2017 05:03:28 PDT (-0700), i...@livius.net wrote:
>>
>>> On 30 Aug 2017, at 15:00, Cesar Eduardo Barros <ces...@cesarb.eti.br> wrote:
>>>
>>>> This is a starting point. What is (or where is) Linux’s asm-generic?
>>>
>>> A quick story lesson: ...
>>
>> thank you, but I think this is a bit off-topic.
>
> ... We're sorely lacking in documentation so we'd really value
> some contributions here.

fully agree.

sorry if my comment was scary and turned any contributors out. it was not intended.

regards,

Liviu

Jacob Bachmeyer

unread,
Aug 30, 2017, 10:13:38 PM8/30/17
to Liviu Ionescu, Richard Herveille, Palmer Dabbelt, raj....@gmail.com, sw-...@groups.riscv.org
Liviu Ionescu wrote:
>> On 30 Aug 2017, at 11:01, Richard Herveille <richard....@roalogic.com> wrote:
>>
>> I was suggesting to reuse the "vendor" field as a "variant" field:
>> ...
>> [rih] Please no … The –march= and –mabi= options are intended for this.
>>
>
> agree.
>

I seem to have been unclear: I was suggesting that the /compiler/ be
riscv-standard-*-gcc; one compiler for all variants, using -march= and
-mabi= to select. But some way is needed to indicate /which/
incompatible or partially-compatible arch a program is compiled for. I
suggest using the vendor field for this information, but only having
/one/ standard compiler that can generate any riscv-rv*-* binary. Or
adding a -mtarget= option to the compiler that auto-selects the
appropriate -march= and -mabi= options. I am suggesting fewer
compilers, possibly as few as /one/ GCC configuration that can target
all environments and variants using multilibs.


-- Jacob

Jacob Bachmeyer

unread,
Aug 30, 2017, 10:22:03 PM8/30/17
to Liviu Ionescu, Palmer Dabbelt, br...@hoult.org, raj....@gmail.com, sw-...@groups.riscv.org
Liviu Ionescu wrote:
>> On 30 Aug 2017, at 03:28, Jacob Bachmeyer <jcb6...@gmail.com> wrote:
>>
>> At the point where you have an RTOS, flash file system, network stack, and a dynamic loader, for which you are building a shared object, you are not programming a bare-metal environment anymore.
>>
>
> then we obviously have a different understanding of the subject.
>
> if you stick to your definition then yes, I do not want a truly `bare-metal` environment where I have to write everything from scratch when there are plenty of useful functions in the library (who would want it?); I want a modern IoT environment, which I already have for Cortex-M devices and planned to use for RISC-V too. it is as POSIX compatible as reasonably possible, but it does not use a unix kernel, so libgloss stands in the way.
>

So you want an ELF environment? Then riscv-*-elf is the toolchain you
should be using.

>> ... Why not just use riscv-*-elf?
>>
>
> because it always includes libgloss, which interferes with my POSIX IO sybsystem, used to access character devices (like uarts), files in file systems and network stacks.
>

Then riscv-*-elf, as it currently stands, is broken and should be fixed,
by removing the automatic inclusion of libgloss.

>> If you can load a shared object, then you have an environment that goes beyond "bare metal" and riscv-*-none specifically targets "bare metal" environments.
>>
>
> I have difficulties to understand what kind of applications you are targeting when you say 'bare-metal' and why do you insist on providing a crippled toolchain? the current risvc-*-elf without libgloss is perfectly fine.
>

Small microcontrollers, lacking Ethernet, similar to an AVR or PIC, are
one example. These are applications that do not use IoT environments.
Boot firmware for larger systems is another example.


-- Jacob


Liviu Ionescu

unread,
Aug 31, 2017, 3:50:55 AM8/31/17
to jcb6...@gmail.com, Palmer Dabbelt, br...@hoult.org, raj....@gmail.com, sw-...@groups.riscv.org

> On 31 Aug 2017, at 05:21, Jacob Bachmeyer <jcb6...@gmail.com> wrote:
>
>
> ... So you want an ELF environment? Then riscv-*-elf is the toolchain you should be using.

yes. it is called GNU MCU RISC-V GCC, it has no libgloss, and I am already using it successfully.

>
>>> ... Why not just use riscv-*-elf?
>>>
>>
>> because it always includes libgloss, which interferes with my POSIX IO sybsystem, used to access character devices (like uarts), files in file systems and network stacks.
>>
>
> Then riscv-*-elf, as it currently stands, is broken and should be fixed, by removing the automatic inclusion of libgloss.

fully agree.

>>> If you can load a shared object, then you have an environment that goes beyond "bare metal" and riscv-*-none specifically targets "bare metal" environments.
>>>
>>
>> I have difficulties to understand what kind of applications you are targeting when you say 'bare-metal' and why do you insist on providing a crippled toolchain? the current risvc-*-elf without libgloss is perfectly fine.
>
> Small microcontrollers, lacking Ethernet, similar to an AVR or PIC, are one example. These are applications that do not use IoT environments. Boot firmware for larger systems is another example.

ah, ok, it seems that you target small superloop applications, i.e. do not use a RTOS (I have a manual page trying to define the terminology, http://micro-os-plus.github.io/user-manual/basic-concepts/, if you have any feedback on it I would be grateful). this explains your desire to remove standard libraries and dynamic linking.

I target the 'middle class' applications, slightly more complicated that yours, but not that complicated to require a unix kernel.

given the current Cortex-M4 & M7 devices, with lots of resources, perfectly able to run multi-threaded systems, this class of applications is quite wide and gets wider.

unfortunately, similar RISC-V devices are not yet available, but I'm willing to help make them possible, and also to contribute my development tools and environment (the Eclipse plug-ins, the µOS++ RTOS and xPack tools) to the RISC-V project.


I would be grateful to know if there are others interested in this class of multi-threaded RTOS applications for RISC-V, to possibly form a small working group to develop the tools needed to help writing such applications.


thank you,

Liviu

Tommy Murphy

unread,
Aug 31, 2017, 3:59:16 AM8/31/17
to RISC-V SW Dev, i...@livius.net, richard....@roalogic.com, pal...@sifive.com, raj....@gmail.com, jcb6...@gmail.com
I would love this but have no idea if it is feasible - i.e. to have the ability to build a single toolchain that can target (a) linux user mode (b) linux freestanding (e.g. kernel using -ffreestanding) (c) bare metal (including newlib/newlib nano for some or even all arch/abi multilib tuples) and (d) anything else (e.g. I don't understand why RTEMS ostensibly needs its own toolchain but maybe there is a good reason?).
Right now riscvxx-linux-gnu-gcc caters for (a) and (b), riscvxx-unknown-elf caters for (c) and the aforementioned rtems specific toolchain falls into category (d).

Angelo Bulfone

unread,
Aug 31, 2017, 2:39:34 PM8/31/17
to Tommy Murphy, RISC-V SW Dev, i...@livius.net, richard....@roalogic.com, pal...@sifive.com, raj....@gmail.com, jcb6...@gmail.com
Tommy, that's called LLVM. Because some brilliant guy decided that GCC should be built completely separately for each possible configuration. (OK, it doesn't support linux freestanding or riscv yet. Work is being done to fix those.)

--
You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
To post to this group, send email to sw-...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.

Jacob Bachmeyer

unread,
Aug 31, 2017, 9:26:33 PM8/31/17
to Tommy Murphy, RISC-V SW Dev, i...@livius.net, richard....@roalogic.com, pal...@sifive.com, raj....@gmail.com
As I understand, the quirk that GCC toolchains target a specific
environment is a leftover from the days before actual GNU systems
existed when that actually made sense -- a compiler for Apollo Domain/OS
and a compiler for DEC OSF/1 were very different and relied on different
(non-free) system libraries, so even building cross-compilers could get
interesting if it was possible at all, since the (non-free) libraries
could not be transferred from their native environments. This is also
why libgcc exists: on older systems, certain operations were not
portable, so GCC emits calls into libgcc for those operations. To
provide implementations, libgcc itself was compiled with the system
compiler, rather than GCC.

Of course, on modern platforms like RISC-V, much of this is vestigial
and should be rethought or changed. This is why I am proposing that a
single RISC-V GCC should be able to generate binaries targeting
riscv-VARIANT-ENVIRONMENT for any VARIANT
("rv32e"/"rv32ec"/"rv32ima"/"rv32g"/"rv64i"/"rv64ima"/"rv64gqv"/etc.)
and any ENVIRONMENT, provided that the needed libraries for ENVIRONMENT
are available. I also suggest adopting/extending the existing GNU
toolchain model and putting libraries for riscv-VARIANT-ENVIRONMENT in
/usr/riscv-<VARIANT>-<ENVIRONMENT>/lib by default, with binaries for
same expected to be in /usr/riscv-<VARIANT>-<ENVIRONMENT>/bin.


-- Jacob

Jacob Bachmeyer

unread,
Aug 31, 2017, 10:01:32 PM8/31/17
to Liviu Ionescu, Palmer Dabbelt, br...@hoult.org, raj....@gmail.com, sw-...@groups.riscv.org
Liviu Ionescu wrote:
>> On 31 Aug 2017, at 05:21, Jacob Bachmeyer <jcb6...@gmail.com> wrote:
>>
>>
>>>> If you can load a shared object, then you have an environment that goes beyond "bare metal" and riscv-*-none specifically targets "bare metal" environments.
>>>>
>>>>
>>> I have difficulties to understand what kind of applications you are targeting when you say 'bare-metal' and why do you insist on providing a crippled toolchain? the current risvc-*-elf without libgloss is perfectly fine.
>>>
>> Small microcontrollers, lacking Ethernet, similar to an AVR or PIC, are one example. These are applications that do not use IoT environments. Boot firmware for larger systems is another example.
>>
>
> ah, ok, it seems that you target small superloop applications, i.e. do not use a RTOS (I have a manual page trying to define the terminology, http://micro-os-plus.github.io/user-manual/basic-concepts/, if you have any feedback on it I would be grateful).

Overall, that page seems reasonable enough, although what you call
"superloop" is what I have known as "interrupt-driven" as opposed to
even simpler programs that just execute in an infinite loop polling for
everything and eschew interrupts. (And "simpler" may be a bit of a
misnomer -- I have worked with embedded network stacks that, as far as I
could tell, did not use interrupts at all. Calling that particular mess
"buggy" is an understatement.)

> this explains your desire to remove standard libraries and dynamic linking.
>

For a specialized minimal toolchain different from riscv-*-elf, yes. I
envision that riscv-*-none would be intended for very small, minimal
applications, such as small microcontrollers and early boot firmware for
larger systems. Neither standard libraries nor dynamic linking are
appropriate for either of these.

> I target the 'middle class' applications, slightly more complicated that yours, but not that complicated to require a unix kernel.
>

Which is the "complexity tier" that I expect riscv-*-elf to target. A
riscv-*-none toolchain should not be of direct interest to your
applications.

In summary:
-3- riscv-*-linux-gnu: full GNU/Linux systems

-2- riscv-*-elf: generic embedded ELF environment
-2- riscv-*-rtems: embedded apps; specialized for RTEMS

-1- riscv-*-none: bare metal; static binaries only; also
suitable for early boot firmware



-- Jacob

Liviu Ionescu

unread,
Sep 1, 2017, 2:19:50 AM9/1/17
to jcb6...@gmail.com, Palmer Dabbelt, br...@hoult.org, raj....@gmail.com, sw-...@groups.riscv.org

> On 1 Sep 2017, at 05:01, Jacob Bachmeyer <jcb6...@gmail.com> wrote:
>
> ... what you call "superloop" is what I have known as "interrupt-driven" as opposed to even simpler programs that just execute in an infinite loop polling for everything

yeah, "interrupt-driven" is already from a higher league ;-)

> ... I have worked with embedded network stacks that, as far as I could tell, did not use interrupts at all. Calling that particular mess "buggy" is an understatement.

yes, I remember those times. I also remember devices having a stack only 8 levels deep and RAM organised in 3 banks of 92 bytes each (bytes, not kilobytes!).

>> this explains your desire to remove standard libraries and dynamic linking.
>
> For a specialized minimal toolchain different from riscv-*-elf, yes. I envision that riscv-*-none would be intended for very small, minimal applications, such as small microcontrollers and early boot firmware for larger systems. Neither standard libraries nor dynamic linking are appropriate for either of these.

I'm not sure such a fragmentation is beneficial.

>> I target the 'middle class' applications, slightly more complicated that yours, but not that complicated to require a unix kernel.
>
> Which is the "complexity tier" that I expect riscv-*-elf to target.

I wouldn't mind if it would not mandate for libgloss.

from all respondents, only Michael strongly objects to removing libgloss from riscv-*-elf, which would be the most reasonable solution to this issue.

if the community really has a word when these decisions are made, I think Palmer should consider it.

looking forward for Palmer's solution.

if satisfactory (no libloss or other libraries, no extra command line options, in-line with de-facto standards like arm-none-eabi), I'll obviously use it; otherwise I'll continue to use my fork of riscv-*-elf with libgloss removed, and probably rename it to shorter `riscv-none`.


regards,

Liviu





Jacob Bachmeyer

unread,
Sep 1, 2017, 9:14:35 PM9/1/17
to Liviu Ionescu, Palmer Dabbelt, br...@hoult.org, raj....@gmail.com, sw-...@groups.riscv.org
Liviu Ionescu wrote:
>> On 1 Sep 2017, at 05:01, Jacob Bachmeyer <jcb6...@gmail.com> wrote:
>>
>>
>>
>> ... I have worked with embedded network stacks that, as far as I could tell, did not use interrupts at all. Calling that particular mess "buggy" is an understatement.
>>
>
> yes, I remember those times. I also remember devices having a stack only 8 levels deep and RAM organised in 3 banks of 92 bytes each (bytes, not kilobytes!).
>

Your devices would have had an excuse. The mess I had to work with was
running on an embedded MIPS SoC. (At the time no other stack had a
driver for the oddball Ethernet chip the hardware used, and management
did not want a driver written for an actual RTOS. Penny wise, pound
foolish considering the problems that mess gave us.)

>>> this explains your desire to remove standard libraries and dynamic linking.
>>>
>> For a specialized minimal toolchain different from riscv-*-elf, yes. I envision that riscv-*-none would be intended for very small, minimal applications, such as small microcontrollers and early boot firmware for larger systems. Neither standard libraries nor dynamic linking are appropriate for either of these.
>>
>
> I'm not sure such a fragmentation is beneficial.
>

I am also uncertain that a riscv-*-none toolchain would actually be
useful, but I am adamant that the proper meaning of *-none is just
that: no environment. And that having "no environment" precludes
support for dynamic linking.

>>> I target the 'middle class' applications, slightly more complicated that yours, but not that complicated to require a unix kernel.
>>>
>> Which is the "complexity tier" that I expect riscv-*-elf to target.
>>
>
> I wouldn't mind if it would not mandate for libgloss.
>
> from all respondents, only Michael strongly objects to removing libgloss from riscv-*-elf, which would be the most reasonable solution to this issue.
>
> if the community really has a word when these decisions are made, I think Palmer should consider it.
>

Overall, we seem to have consensus for removing libgloss from
riscv-*-elf with one dissenting. (And the one dissenter seems more
interested in binary translation than bare metal embedded solutions; I
believe that "add '-lgloss' to your LDFLAGS" is the correct answer for
his applications.)


-- Jacob

Michael Clark

unread,
Sep 1, 2017, 9:27:46 PM9/1/17
to Liviu Ionescu, Jacob Bachmeyer, Palmer Dabbelt, Bruce Hoult, raj....@gmail.com, RISC-V SW Dev

> On 1 Sep 2017, at 6:19 PM, Liviu Ionescu <i...@livius.net> wrote:
>
> from all respondents, only Michael strongly objects to removing libgloss from riscv-*-elf, which would be the most reasonable solution to this issue.

I read your replies. You turned neutral and or negative responses into 0.5.

I only objected to removing libgloss without also removing libc and crt for consistency and I outlines the reasons why. I prefer Palmers proposed changes which have already been committed to the riscv-gcc repo. Send a patch or make a pull request :-D

What is the issue again? not having your link options as the default?

newlib libc less libgloss with “very-newlib” specific back-end functions to implement along with default link errors is a very odd default. I’d prefer libnosys over that.

I believe it is a documentation issue. i.e. what linker flags are required to achieve different configurations, including actual bare metal instead of alternative defaults with newlib.


## RISC-V Newlib ELF Toolchain Libraries:

- libgcc - gcc compiler intrinsics
- crt0.o - newlib embedded C runtime
- libc.a - newlib embedded C library (depends on crt)
- libgloss.a - newlib linux system calls
- libnosys.a - newlib no-op system calls


## RISC-V Newlib ELF Toolchain Link options

1. Default: crt. libc, libgloss (binaries work with the riscv-pk and riscv-isa-sim, or in riscv-linux)

riscv-unknown-elf-gcc

2. Alternative default: crt, libc (will fail to link unless libgloss POSIX system call stubs are implemented)

riscv-unknown-elf-gcc -nostdlib -lc

3. libc and libnosys (will link but POSIX calls return -ENOSYS)

riscv-unknown-elf-gcc -nostdlib -lc -lnosys

4. “Default bare metal” linkage (user supplies _start symbol, default text address 0x10000)

riscv-unknown-elf-gcc -nostdlib -nostartfiles

5. “Actual bare metal" linkage (user supplies _start symbol and a linker script)

riscv-unknown-elf-gcc -nostdlib -nostartfiles -Wl,-T,myprog-link.ld

Michael Clark

unread,
Sep 1, 2017, 9:49:48 PM9/1/17
to Liviu Ionescu, Jacob Bachmeyer, Palmer Dabbelt, Bruce Hoult, raj....@gmail.com, RISC-V SW Dev

> On 2 Sep 2017, at 1:27 PM, Michael Clark <michae...@mac.com> wrote:
>
>
>> On 1 Sep 2017, at 6:19 PM, Liviu Ionescu <i...@livius.net> wrote:
>>
>> from all respondents, only Michael strongly objects to removing libgloss from riscv-*-elf, which would be the most reasonable solution to this issue.
>
> I read your replies. You turned neutral and or negative responses into 0.5.
>
> I only objected to removing libgloss without also removing libc and crt for consistency and I outlines the reasons why. I prefer Palmers proposed changes which have already been committed to the riscv-gcc repo. Send a patch or make a pull request :-D

s/outlines/outlined/

> What is the issue again? not having your link options as the default?
>
> newlib libc less libgloss with “very-newlib” specific back-end functions to implement along with default link errors is a very odd default. I’d prefer libnosys over that.
>
> I believe it is a documentation issue. i.e. what linker flags are required to achieve different configurations, including actual bare metal instead of alternative defaults with newlib.

I’m going to start calling these link options “alternative defaults” ;-)

> ## RISC-V Newlib ELF Toolchain Libraries:
>
> - libgcc - gcc compiler intrinsics
> - crt0.o - newlib embedded C runtime
> - libc.a - newlib embedded C library (depends on crt)
> - libgloss.a - newlib linux system calls
> - libnosys.a - newlib no-op system calls
>
>
> ## RISC-V Newlib ELF Toolchain Link options
>
> 1. Default: crt. libc, libgloss (binaries work with the riscv-pk and riscv-isa-sim, or in riscv-linux)
>
> riscv-unknown-elf-gcc
>
> 2. Alternative default: crt, libc (will fail to link unless libgloss POSIX system call stubs are implemented)
>
> riscv-unknown-elf-gcc -nostdlib -lc
>
> 3. libc and libnosys (will link but POSIX calls return -ENOSYS)
>
> riscv-unknown-elf-gcc -nostdlib -lc -lnosys
>
> 4. “Default bare metal” linkage (user supplies _start symbol, default text address 0x10000)
>
> riscv-unknown-elf-gcc -nostdlib -nostartfiles
>
> 5. “Actual bare metal" linkage (user supplies _start symbol and a linker script)
>
> riscv-unknown-elf-gcc -nostdlib -nostartfiles -Wl,-T,myprog-link.ld
>
> --
> You received this message because you are subscribed to the Google Groups "RISC-V SW Dev" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sw-dev+un...@groups.riscv.org.
> To post to this group, send email to sw-...@groups.riscv.org.
> Visit this group at https://groups.google.com/a/groups.riscv.org/group/sw-dev/.
> To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/sw-dev/FA47D435-A4C2-4B1E-A821-AF2EEEAC3DE0%40mac.com.

Jacob Bachmeyer

unread,
Sep 1, 2017, 10:14:05 PM9/1/17
to Michael Clark, Liviu Ionescu, Palmer Dabbelt, Bruce Hoult, raj....@gmail.com, RISC-V SW Dev
Michael Clark wrote:
>> On 1 Sep 2017, at 6:19 PM, Liviu Ionescu <i...@livius.net> wrote:
>>
>> from all respondents, only Michael strongly objects to removing libgloss from riscv-*-elf, which would be the most reasonable solution to this issue.
>>
>
> I read your replies. You turned neutral and or negative responses into 0.5.
>
> I only objected to removing libgloss without also removing libc and crt for consistency and I outlines the reasons why. I prefer Palmers proposed changes which have already been committed to the riscv-gcc repo. Send a patch or make a pull request :-D
>

Some parts of libc do not rely on system calls, sprintf(3) for example.
As such, keeping a static libc in the default link is reasonable,
although I would like to see it selectable with an -m* option of some type.

> What is the issue again? not having your link options as the default?
>

The issue is that certain link options, such as the set of libraries to
use, are additive in nature. It is not possible to portably remove just
one of them, because the standard libraries may have dependencies of
their own.

> newlib libc less libgloss with “very-newlib” specific back-end functions to implement along with default link errors is a very odd default. I’d prefer libnosys over that.
>

I maintain that link errors by default is correct in this case. A
program that uses a system call (perhaps indirectly) in a "bare-metal"
environment without supplying its own implementation is erroneous. Such
an error will be immediately apparent when the link fails. Including
libgloss (or even libnosys) by default is bad because it defers the
failure to run-time. Since libgloss simply does ECALL for every
function, the run-time failure manifests as an unhandled trap, which
usually hangs the hart.

A program that uses system calls in an environment that has no system
cannot run correctly. There is a basic premise that reliable systems
should fail as soon as a failure is inevitable and not defer that
failure until later. Failing at link-time is preferable to failing at
run-time, especially when the run-time failures are
difficult-to-diagnose hangs.

> I believe it is a documentation issue. i.e. what linker flags are required to achieve different configurations, including actual bare metal instead of alternative defaults with newlib.
>
>
> ## RISC-V Newlib ELF Toolchain Libraries:
>
> - libgcc - gcc compiler intrinsics
> - crt0.o - newlib embedded C runtime
> - libc.a - newlib embedded C library (depends on crt)
> - libgloss.a - newlib linux system calls
> - libnosys.a - newlib no-op system calls
>
>
> ## RISC-V Newlib ELF Toolchain Link options
>
> 1. Default: crt. libc, libgloss (binaries work with the riscv-pk and riscv-isa-sim, or in riscv-linux)
>
> riscv-unknown-elf-gcc
>
Or: riscv-unknown-elf-gcc -lgloss
> 2. Alternative default: crt, libc (will fail to link unless libgloss POSIX system call stubs are implemented)
>
> riscv-unknown-elf-gcc -nostdlib -lc
>
Or: riscv-unknown-elf-gcc
(will link just fine as long the application does not use parts of libc
that depend on system calls)
> 3. libc and libnosys (will link but POSIX calls return -ENOSYS)
>
> riscv-unknown-elf-gcc -nostdlib -lc -lnosys
>
Or: riscv-unknown-elf-gcc -lnosys
> 4. “Default bare metal” linkage (user supplies _start symbol, default text address 0x10000)
>
> riscv-unknown-elf-gcc -nostdlib -nostartfiles
>
No change.
> 5. “Actual bare metal" linkage (user supplies _start symbol and a linker script)
>
> riscv-unknown-elf-gcc -nostdlib -nostartfiles -Wl,-T,myprog-link.ld
>
No change.

6. Ordinary application for physical hardware (user supplies main and a
linker script)
...
Or: riscv-unknown-elf-gcc -Wl,-T,myboard.ld

The problem is that you are suggesting that most configurations,
including the ones that will correspond to actual physical hardware
(case 5), will involve passing -nostdlib, which is supposed to be an
option used only in very special cases. Building an image that uses the
"system-less" parts of the C library, like atoi(3), for an M-only
microcontroller with application-as-monitor should NOT require the use
of -nostdlib. Compare AVR-GCC.

Put another way, "-nostdlib -lc" represents either a fundamental
misunderstanding or a workaround for a broken toolchain. Also, all of
your examples that use -nostdlib are subtly broken: you forgot to
include -lgcc. This is why I favor removing libgloss from the default
link instead of expecting people to use -nostdlib. Also, -nostdlib
includes -nostartfiles and is equivalent to "-nodefaultlibs
-nostartfiles" according to the GCC 7.2 manual. Further, GCC can end up
including quite a variety of other libraries into the link
automatically, and this set is NOT fixed. Put simply, expecting routine
use to include -nostdlib is wrong and indicates a broken toolchain. The
toolchain should be fixed. Refusing to fix this breakage will make a
fork inevitable.


-- Jacob

Michael Clark

unread,
Sep 2, 2017, 12:18:30 AM9/2/17
to Jacob Bachmeyer, Liviu Ionescu, Palmer Dabbelt, Bruce Hoult, raj....@gmail.com, RISC-V SW Dev

> On 2 Sep 2017, at 2:14 PM, Jacob Bachmeyer <jcb6...@gmail.com> wrote:
>
> Michael Clark wrote:
>>> On 1 Sep 2017, at 6:19 PM, Liviu Ionescu <i...@livius.net> wrote:
>>>
>>> from all respondents, only Michael strongly objects to removing libgloss from riscv-*-elf, which would be the most reasonable solution to this issue.
>>>
>>
>> I read your replies. You turned neutral and or negative responses into 0.5.
>>
>> I only objected to removing libgloss without also removing libc and crt for consistency and I outlines the reasons why. I prefer Palmers proposed changes which have already been committed to the riscv-gcc repo. Send a patch or make a pull request :-D
>>
>
> Some parts of libc do not rely on system calls, sprintf(3) for example. As such, keeping a static libc in the default link is reasonable, although I would like to see it selectable with an -m* option of some type.

That’s not a very good argument. It’s not a “bare metal" default. It’s another quirky set of defaults for a “newlib” toolchain. Exchanging one set of quirks for another.

I’d like PIE by default so I can easily relocate the runtime image to a different address without TEXTRELS. The libs are built without PIE by default and this makes ASLR harder. I have to build my own toolchain if I want static PIE. It’s not a biggie. I can do this. If the toolchain gets forked a thousand times then RISC-V is doing something right, based on the principles of making forks easy. IMHO that’s a good thing. It makes one consider ones changes so they can be done in a way that suites multiple users, not just ones own defaults.

The result might be patches that support a multiarch multilib toolchain with riscv- prefix (including PIE, non-PIE libs for each C library and associated CRT) that can be used for bare metal, glibc, newlib and musl, rather than simply changing the defaults to ones own defaults. libgcc probably needs PIE and non-PIE versions as some functions use .rodata.
I doubt this will work with the current crt unless there is a loader that sets up a stack point and provides argv, argc, envp. It could be used as a start protocol for the payload of a boot loader however it would need due consideration so that it would work in a nearly bare metal environment. I say nearly because it necessitates some protocol between the load, the crt and main. It would add some symmetry to calls like Linux’s kexec which is used for loading other supervisors. I actually like this idea even though it’s not really possible because everyone has invented their own boot protocols. args, env, auxp with sp set up is actually a nice simple extensible protocol that can be implemented in a few lines.

> The problem is that you are suggesting that most configurations, including the ones that will correspond to actual physical hardware (case 5), will involve passing -nostdlib, which is supposed to be an option used only in very special cases. Building an image that uses the "system-less" parts of the C library, like atoi(3), for an M-only microcontroller with application-as-monitor should NOT require the use of -nostdlib. Compare AVR-GCC.

I use -nostdlib often.

> Put another way, "-nostdlib -lc" represents either a fundamental misunderstanding or a workaround for a broken toolchain. Also, all of your examples that use -nostdlib are subtly broken: you forgot to include -lgcc. This is why I favor removing libgloss from the default link instead of expecting people to use -nostdlib. Also, -nostdlib includes -nostartfiles and is equivalent to "-nodefaultlibs -nostartfiles" according to the GCC 7.2 manual. Further, GCC can end up including quite a variety of other libraries into the link automatically, and this set is NOT fixed. Put simply, expecting routine use to include -nostdlib is wrong and indicates a broken toolchain. The toolchain should be fixed. Refusing to fix this breakage will make a fork inevitable.

There are other omissions too like -ffreestanding which needs to be specified for barest-metal apps so that the compiler doesn’t assume standard functions have standard semantics. Barer-metal. Typical applications need to link several libraries and run configure tests against the compiler to check that their compile and link options work.

I’ve added -lgcc below based on your feedback.



## RISC-V Newlib ELF Toolchain Link options

1. Default: crt. libc, libgloss (binaries work with the riscv-pk and riscv-isa-sim, or in riscv-linux)

riscv-unknown-elf-gcc

2. Alternative default: crt, libc and libgcc (will fail to link unless libgloss POSIX system call stubs are implemented)

riscv-unknown-elf-gcc -nostdlib -lc -lgcc

3. crt, libc, libnosys and libgcc (will link but POSIX calls return -ENOSYS)

riscv-unknown-elf-gcc -nostdlib -lc -lnosys -lgcc

4. “Default bare metal” linkage (user supplies _start symbol, default text address 0x10000)

riscv-unknown-elf-gcc -nostdlib -nostartfiles

Liviu Ionescu

unread,
Sep 2, 2017, 5:22:21 PM9/2/17
to jcb6...@gmail.com, Michael Clark, Palmer Dabbelt, Bruce Hoult, raj....@gmail.com, RISC-V SW Dev

> On 2 Sep 2017, at 05:14, Jacob Bachmeyer <jcb6...@gmail.com> wrote:
>
> ... Put simply, expecting routine use to include -nostdlib is wrong and indicates a broken toolchain. The toolchain should be fixed.

fully agree.

> Refusing to fix this breakage will make a fork inevitable.

I'll wait a few more days, and, if Palmer does not provide a proper solution, I'll probably release 'riscv-none-gcc', with a behaviour similar to 'arm-none-eabi-gcc'.


regards,

Liviu


Reply all
Reply to author
Forward
0 new messages