How to pick up a symbol in C code which was defined in a .ld linkfile? - Page 1
Forum section: electronics / general

author: peter-h
author_rank: Super Contributor
timestamp: July 31, 2024, 12:56:37 pm
content: This is weird.In the linkfile I have_build_type = 1;and sure enough in the .map file I see0x0000000000000001 _build_type = 0x1but this codeCode:extern char _build_type;strcat((char *)PAGE_BODY, "<br>Build: ");if ( _build_type == 0 ){strcat((char *)PAGE_BODY, "v0");}else if ( _build_type == 1 ){strcat((char *)PAGE_BODY, "v1");}always sees it as zero. Confirmed by stepping through it.I have also tried int instead of char - doesn't pick up a value at all. I am wondering whether every value in a linkfile is actually implicitly an address, so one can't do this?But then this type of construct worksCode:extern char _s_nonboot_data;extern char _e_nonboot_data;extern char _si_nonboot_data;memcpy(&_s_nonboot_data, &_si_nonboot_data, &_e_nonboot_data - &_s_nonboot_data);and "obviously" 0 and 1 are also valid addresses.Obviously I could have a .h file with a #define in it, etc, but for other reasons I am trying to select a text string based on a symbol defined 0/1 in the linkfile. I can build two different versions of the project which are very similar but have different linkfiles.

author: pcprogrammer
author_rank: Super Contributor
timestamp: July 31, 2024, 01:14:06 pm
content: I have used this in projects of mine and it looks like this:Link fileCode:MY_LINK_VARIABLE = 10;Code fileCode:if(&MY_LINK_VARIABLE == 10){...}else{...}This is with the GNU compiler for ARM.

author: peter-h
author_rank: Super Contributor
timestamp: July 31, 2024, 01:18:31 pm
content: I tried that (my memcpy example above uses it) butMaybe it works with values other than 0but that produces "warning: comparison between pointer and integer".So maybe (char*) 0 or (char*) 1.

author: pcprogrammer
author_rank: Super Contributor
timestamp: July 31, 2024, 01:26:05 pm
content: Ah yes, that is how it is used in my code, for addresses. Maybe there is another way then the & sign to have it be the actual variable instead of the address.Could it be that the variable needs to be in a section part of the link file?

author: peter-h
author_rank: Super Contributor
timestamp: July 31, 2024, 01:34:36 pm
content: I am defining other stuff in the linkfile, and not inside any special section, but they are all memory addresses.Such a simple thing! But this works:Code:extern char _build_type;strcat((char *)PAGE_BODY, "<br>Build: ");if ( &_build_type == (char*) 1 ){strcat((char *)PAGE_BODY, "v1");}else if ( &_build_type == (char*) 2 ){strcat((char *)PAGE_BODY, "v2");}so using 1 or 2, not 0. Odd since addresses can be 0 too, although usually this indicates a cockup (null pointer, etc). Maybe to test for ==0 one should use ==NULL.

author: Nominal Animal
author_rank: Super Contributor
timestamp: July 31, 2024, 03:07:59 pm
content: Quote from: peter-h on July 31, 2024, 12:56:37 pmAs you already realized, in the linker script you can define symboladdresses, not symbolvalues.In C code, you could useextern const char _build_type[];#define BUILD_TYPE ((uintptr_t)(_build_type))since the name of an array decays to a pointer. With this,_build_type == (void *)1andBUILD_TYPE == 1.