Re: Problem linking *without* avr-libc, libm, etc. (SOLVED)

2021-06-22 Thread Ian Molton
On 01/05/2021 01:11, David Kelly wrote:
> Has been a long time for me but Once Upon A Time it wasn’t just a matter
> of “not using functions in the library”. AVR-gcc required primatives
> other than startup code.

It still does - not just on AVR - also on ARM and others.

It was quite amusing when I implemented the "internal" memcpy() - in C -
only to find that the compiler outsmarted me and implemented it as a
call to itself (which obviously crashed the stack).

doh!

So I've "borrowed" a few bits from avr-libc and avr-gcc to allow my
project to build independently of them.

-Ian



Re: Problem linking *without* avr-libc, libm, etc. (SOLVED)

2021-04-30 Thread David Kelly
Has been a long time for me but Once Upon A Time it wasn’t just a matter of 
“not using functions in the library”. AVR-gcc required primatives other than 
startup code. It couldn’t do most operations on longs in-line, called library 
functions with names outside of usual C-space. I remember being concerned about 
using those inside an interrupt service routine. Unrolled my uint32_t in a 
union for ++ or — on the least significant 16, test and repeat in most 
significant if necessary for carry or borrow.

if( ! ++val.low ) ++val.high;

Or:
if( val.low || val.high ) // I like to count down to zero
if( val.low— ) val.high—;

Back then AVR-gcc was not smart enough to do the above automatically. 

I used a lot of uint32_t and uint64_t as counters to mark the passage of time.

--
David Kelly N4HHE, dke...@hiwaay.net

Whom computers would destroy, they must first drive mad.



Re: Problem linking *without* avr-libc, libm, etc. (SOLVED)

2021-04-30 Thread Ian Molton
On 30/04/2021 09:03, David Brown wrote:
> On 29/04/2021 21:43, Ian Molton wrote:
>> Hi,
>>
>> I'm attempting to build my project, which does not use libc, or libm,
>> but I do want to link with libgcc.
>>
>> additionally, I don't want any startup code to be linked - the project
>> is intended to be fully standalone.
>>
> 
> If you don't use any functions from these libraries, nothing from them
> will be linked into your project - it doesn't matter if the linker has them.

It matters a lot is the user does not have avr-libc installed, as the
linker will fail, despite not requiring functions from those libraries.

I also don't want users to inadvertently link with libraries outside the
project.

> (I can't remember the details for the avr, but often "libm" is actually
> empty, and exists only for compatibility - all the maths functions are
> frequently included in the main libc.)

I believe in libgcc, yes. I still wish to link with libgcc, as the
functiosn therein are tied to the compiler being used.

> Sometimes (again, this is from other targets rather than the avr, which
> I have not used for many years) it is useful to provide stubs of
> functions like "exit()" and "atexit()" - just add these as extra empty
> functions in your code.  That will ensure the library versions are not
> used, and they do not pull in any other bits and pieces.

I've found libgcc doesnt appear to contain mem{set,copy,etc.}, but thats
OK, I can place implementations in my project.

What I need, if for avr-gcc to NOT attempt to link with the crt, libc,
or libm.

I've found that when compiling my objects, I can avoid pollution from
outside the compiler with:

avr-gcc -nostdinc -isystem include/

which covers pollution from headers, and when linking, I can use:

avr-gcc -nostdlib -mmcu=$(CPU_MODEL) -T./$(CPU_MODEL).lds
-Wl,--gc-sections -mrelax $(OBJS)

which results in gcc calling the linker with something like (gcc -v output):

collect2 -plugin liblto_plugin.so -plugin-opt=lto-wrapper
 -plugin-opt=-fresolution=/tmp/cc2XFOOT.res
 -mavr6 -Tdata 0x800200
 --relax -o output.elf
 -L.../avr/lib/gcc/avr/10.3.0/avr6
 ...
 ...
 --gc-sections objects.o more_objects.o -T ./atmega2560.lds

Which almost results in what I want, but not quite. It *actually*
results in a failed link, since --nostdlib has prevented linking with
-lgcc -lc and -lm, as well as the crt. This is correct as documented.

What it *looks like* I want to do is add -lgcc to the commanline, which
it actually says to do in the gcc manual, but it makes no difference to
the parameters passed to collect2.

HOLD THE PHONE...

Its working. The problem was that adding -lgcc to the link command has
to be done *after* the objects.

Heres the "before":
$(CC) -v $(LINK_OPTS) -lgcc -o $@ $(OBJS)

And the (working) after:
$(CC) -v $(LINK_OPTS) -o $@ $(OBJS) -lgcc

Thanks for being rubber duckies, folks.

Posting this in case anyone else trips over it. order *matters*.

Plus I can now avoid the (apparently unsupported in 5.4) -nolibc option.
Winner!

-Ian