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



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

2021-04-30 Thread Ian Molton
On 30/04/2021 10:52, dva...@internode.on.net wrote:
> 
> Still dabbling a little with AVR once in a while, I add -nostartfiles to
> Ian's -nostdlib, to avoid startup code.

Aha, yes, that one went astray during my attempt to debug this :)

 As my most recent dabble is
> -mmcu=attiny2313, with only 1k instructions, any extraneous code bytes
> would quickly be noticed.

Indeed so!
> And for libgcc, my makefile remembers better than I, a choice to use
> avr-gcc, not just avr-ld for linking on a project which needed libgcc.
> That residual choice in the attiny2313 project confirms David's reminder
> that stuff is only linked if you use it.

* if its present on the system :)

I've solved it anyhow - see my other post :) Thanks,

-Ian



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

2021-04-30 Thread dvalin

On 30.04.21 10: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.

Still dabbling a little with AVR once in a while, I add -nostartfiles
to
Ian's -nostdlib, to avoid startup code. As my most recent dabble is
-mmcu=attiny2313, with only 1k instructions, any extraneous code bytes
would quickly be noticed.

As for libm, I've always had to -lm that explicitly when needed.

And for libgcc, my makefile remembers better than I, a choice to use
avr-gcc, not just avr-ld for linking on a project which needed libgcc.
That residual choice in the attiny2313 project confirms David's
reminder
that stuff is only linked if you use it.

Erik

makefile:
=
# vim:noexpandtab list foldmethod=manual

INC_DIR=include
OBJDIR=obj

CC = avr-gcc
CFLAGS = -g -O2 -nostartfiles -nostdlib -mmcu=attiny2313
-DMCU=attiny2313
AS = /usr/local/avr/bin/avr-as
ASFLAGS = -gstabs -mmcu=attiny2313
LD = /usr/local/avr/bin/avr-ld

# Let avr-gcc link, so it can find libgcc.a:
LDFLAGS = -Wl,-M

.SUFFIXES :
.SUFFIXES : .c .h .o .s .S

%.o: %.c
   $(CC) -c $(CFLAGS) -o $(OBJDIR)/$@ $<

%.o: %.s
   $(AS) -I$(INC_DIR) $(ASFLAGS) -o $(OBJDIR)/$@ $<

%.o: %.S
   $(CC) -c -I$(INC_DIR) -x assembler-with-cpp $(CFLAGS)
-Wa,-alms=$(OBJDIR)/$@.lst -o $(OBJDIR)/$@ $<

dimmer:  init.o os.o timer.o lamps.o eeprom.o serial.o comms.o
  ( cd $(OBJDIR) ; $(CC) $(LDFLAGS) $(CFLAGS) -o $@.elf $^ >
map )
  avr-objcopy -O srec obj/dimmer.elf -S -R .eeprom
--gap-fill=0xff obj/flash.srec
  avr-objcopy -O ihex obj/dimmer.elf -S -j .eeprom
--gap-fill=0xff obj/eeprom.ihex
  avr-objdump -D obj/$@.elf > obj/dimmer.dump

load:  avrdude -P /dev/ttyUSB0 -p t2313 -c stk500 -e -U
flash:w:obj/flash.srec 
   
-U eeprom:w:obj/eeprom.ihex



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

2021-04-30 Thread David Brown
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.

(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.)

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.



Problem linking *without* avr-libc, libm, etc.

2021-04-29 Thread Ian Molton
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.

I've had some success with gcc 10, but I need this to work on gcc 5.4.0
as well.

I'm compiling my objects as normal, with the following cflags:

 -mmcu=atmega2560 -O3 -g \
 -Wall -Wextra -Wshadow -Wundef -Wpadded \
 -MMD -nostdinc -isystem include/ \
 -fno-common -ffunction-sections -fno-builtin-vprintf

and attempting to link them thusly:

gcc-avr -mmcu=atmega2560 -Tmylds.lds -Wl,--gc-sections -mrelax -nostdlib
-o out.elf 

I've found that avr-gcc 5.4 does not recognise -nolibc, which would (on
the face of it) appear to do what I want.

How can I do this? I'm pulling my hair out...

I've tried invoking LD directly, but it doesnt recognise
-mmcu=atmega2560 - I assume I have to specify -mavr6, but thats a pain,
since I have no obvious way to autodetect the architecture in my
buildscripts.

I have managed to get things to work, using the (abbreviated slightly)
following:

/home/ian/x-tools/avr/libexec/gcc/avr/10.3.0/collect2
-plugin ... liblto_plugin.so
-plugin-opt=...lto-wrapper
-plugin-opt=-fresolution=/tmp/ccXJW1Nw.res
-mavr6 -Tdata 0x800200 --relax
-o out.elf
-L (several times over, various paths)
--gc-sections
 ...all_the_objects.o...
--start-group -lgcc --end-group -T mylds.lds

So the question is, what magic do I need to pass to GCC in my linking
step in order to get it to produce that linker commandline?

Thanks in advance,

-Ian