These two symbols are declared in object files to indicate whether .data needs to be copied from flash or .bss needs to be cleared. They are supported on avr-gcc and reduce firmware size a bit, which is especially important on very small chips.
I checked the behavior of avr-gcc and matched it as well as possible. From my investigation, it seems to work as follows:
__do_copy_data is set when the compiler finds a data symbol:
- without a section name
- with a section name starting with ".data" or ".gnu.linkonce.d"
- with a section name starting with ".rodata" or ".gnu.linkonce.r" and flash and RAM are in the same address space
__do_clear_bss is set when the compiler finds a data symbol:
- without a section name
- with a section name that starts with .bss
Simply checking whether the calculated section name starts with ".data", ".rodata" or ".bss" should result in the same behavior.
This was an incorrect test: constant globals are actually stored in .rodata which is allocated in RAM. Making it a global makes it a .bss value.