When does __do_copy_data get inserted

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

When does __do_copy_data get inserted

Dylan McKay-2
Hello all,

I maintain the AVR LLVM backend, for which downstream users typically use avr-gcc to link, so they get the CRT, startup routines, and libgcc.

I've noticed that AVR-GCC does not insert the __do_copy_data function for LLVM generated executables, but it does for GCC generated ones.

In case reads have not heard of this function, it is one of a few small routines which copies all variables from the .data, .rodata, and .bss in program memory into RAM during startup.

When does AVR-GCC insert __do_copy_data? How do I need to tune the output of LLVM in order to trigger GCC's insertion of this function?

I've looked at the GCC source and as far as I can tell, the logic is based in 'avr_asm_named_section' in 'gcc/config/avr/avr.c'. The code I can see just looks at the section names, sees if it can find sections prefixed with '.rodata', '.data', or '.bss'.

The LLVM backend is correctly placing my global variable into a section prefixed with '.data', but linking with avr-gcc still does not include __do_copy_data.

I have attached the output of 'objdump -t' for my reference LLVM and GCC program. They are not identical, but they both read from a global variable named 'FOO'.



_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list

blink.gcc.o.objdump (792 bytes) Download Attachment
blink.llvm.o.objdump (12K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: When does __do_copy_data get inserted

Erik Christiansen-2
Reply-To: [hidden email]

On 25.08.17 02:24, Dylan McKay wrote:
>
> When does AVR-GCC insert __do_copy_data? How do I need to tune the output
> of LLVM in order to trigger GCC's insertion of this function?

In the absence of a reply from a maintainer, I'll at least give you the
courtesy of a reply, FWIW. I'm not familiar with gcc internals, but have
in the past run:

$ avr-gcc -dumpspecs | grep 'crt[0-9]'

to elicit e.g. %{mmcu=atmega16:crtm16.o%s} , when chasing which crt was
going to be used. Unfortunately, even a grep for just "crt" finds
nothing in avr-gcc (GCC) 4.7.2, which is still the latest I have here.

So the old logic is probably not there any more, but the object file
does reveal that the code was linked in, and avr-gcc was only inserting
a function call.

> I've looked at the GCC source and as far as I can tell, the logic is based
> in 'avr_asm_named_section' in 'gcc/config/avr/avr.c'. The code I can see
> just looks at the section names, sees if it can find sections prefixed with
> '.rodata', '.data', or '.bss'.
>
> The LLVM backend is correctly placing my global variable into a section
> prefixed with '.data', but linking with avr-gcc still does not include
> __do_copy_data.
>
> I have attached the output of 'objdump -t' for my reference LLVM and GCC
> program. They are not identical, but they both read from a global variable
> named 'FOO'.

ISTM that the first problem is that avr-gcc has inserted the necessary
__do_copy_data call, but LLVM has not. At link time (whether avr-ld is
invoked directly or through avr-gcc), the correct crtxx.o will need to
be supplied on the avr-ld command line, for the undefined __do_copy_data
to be satisfied correctly. Well, that's my user-grade supposition, anyway.

Erik


_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

Re: When does __do_copy_data get inserted

Senthil Kumar
In reply to this post by Dylan McKay-2
Hi,

  The part you're missing is the avr_need_copy_data_p global. It's set to false by default, and is set to true inside hooks that gcc calls whenever it needs to put something in data related sections. The avr_file_end hook function checks the variable and emits a reference to a global "__do_copy_data" only if avr_need_copy_data_p is true. The reference then causes the linker to pull in the implementation of __do_coy_data from libgcc.a(_copy_data.o).

  The compiler uses the same trick to decide whether to pull in code to clear bss or not - see avr_need_clear_bss_p.

  In both cases, the idea is to avoid linking in the copy/clearing code if it's unnecessary (no initialized/zero initialized globals).

  Hope this helps.

Regards
Senthil

On Thu, Aug 24, 2017 at 7:54 PM, Dylan McKay <[hidden email]> wrote:
Hello all,

I maintain the AVR LLVM backend, for which downstream users typically use avr-gcc to link, so they get the CRT, startup routines, and libgcc.

I've noticed that AVR-GCC does not insert the __do_copy_data function for LLVM generated executables, but it does for GCC generated ones.

In case reads have not heard of this function, it is one of a few small routines which copies all variables from the .data, .rodata, and .bss in program memory into RAM during startup.

When does AVR-GCC insert __do_copy_data? How do I need to tune the output of LLVM in order to trigger GCC's insertion of this function?

I've looked at the GCC source and as far as I can tell, the logic is based in 'avr_asm_named_section' in 'gcc/config/avr/avr.c'. The code I can see just looks at the section names, sees if it can find sections prefixed with '.rodata', '.data', or '.bss'.

The LLVM backend is correctly placing my global variable into a section prefixed with '.data', but linking with avr-gcc still does not include __do_copy_data.

I have attached the output of 'objdump -t' for my reference LLVM and GCC program. They are not identical, but they both read from a global variable named 'FOO'.



_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list



_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
Reply | Threaded
Open this post in threaded view
|

Re: When does __do_copy_data get inserted

Dylan McKay-2
I've figured it out, thanks for all the help guys!

On Sat, Sep 2, 2017 at 7:15 PM, Senthil Kumar <[hidden email]> wrote:
Hi,

  The part you're missing is the avr_need_copy_data_p global. It's set to false by default, and is set to true inside hooks that gcc calls whenever it needs to put something in data related sections. The avr_file_end hook function checks the variable and emits a reference to a global "__do_copy_data" only if avr_need_copy_data_p is true. The reference then causes the linker to pull in the implementation of __do_coy_data from libgcc.a(_copy_data.o).

  The compiler uses the same trick to decide whether to pull in code to clear bss or not - see avr_need_clear_bss_p.

  In both cases, the idea is to avoid linking in the copy/clearing code if it's unnecessary (no initialized/zero initialized globals).

  Hope this helps.

Regards
Senthil

On Thu, Aug 24, 2017 at 7:54 PM, Dylan McKay <[hidden email]> wrote:
Hello all,

I maintain the AVR LLVM backend, for which downstream users typically use avr-gcc to link, so they get the CRT, startup routines, and libgcc.

I've noticed that AVR-GCC does not insert the __do_copy_data function for LLVM generated executables, but it does for GCC generated ones.

In case reads have not heard of this function, it is one of a few small routines which copies all variables from the .data, .rodata, and .bss in program memory into RAM during startup.

When does AVR-GCC insert __do_copy_data? How do I need to tune the output of LLVM in order to trigger GCC's insertion of this function?

I've looked at the GCC source and as far as I can tell, the logic is based in 'avr_asm_named_section' in 'gcc/config/avr/avr.c'. The code I can see just looks at the section names, sees if it can find sections prefixed with '.rodata', '.data', or '.bss'.

The LLVM backend is correctly placing my global variable into a section prefixed with '.data', but linking with avr-gcc still does not include __do_copy_data.

I have attached the output of 'objdump -t' for my reference LLVM and GCC program. They are not identical, but they both read from a global variable named 'FOO'.



_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list




_______________________________________________
AVR-GCC-list mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list