Author Topic: A question on GCC .ld linker script syntax  (Read 8462 times)

0 Members and 1 Guest are viewing this topic.

Offline wek

  • Frequent Contributor
  • **
  • Posts: 495
  • Country: sk
Re: A question on GCC .ld linker script syntax
« Reply #25 on: March 13, 2023, 11:42:52 pm »
Quote
weak...

Somebody said above that library (.a) is only a collection of .o. It is, but the linker does not treat it as such. There are several subtle but important differences, one being that weak symbols from .o are not overriden by symbols from .a.

https://stackoverflow.com/questions/36994557/gnu-ld-weak-declaration-overriding-strong-declaration and links from there.

JW
 
The following users thanked this post: peter-h, newbrain

Offline eutectique

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: be
Re: A question on GCC .ld linker script syntax
« Reply #26 on: March 13, 2023, 11:55:41 pm »
No assembly required-
https://godbolt.org/z/PsnGff93o

In principle, yes, nice trick. Practically, when jumping from bl into the app, it would be good to place memory barriers, invalidate cache (if present), and set up the stack pointer.
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 828
Re: A question on GCC .ld linker script syntax
« Reply #27 on: March 14, 2023, 12:33:07 am »
Quote
it would be good to place memory barriers, invalidate cache (if present), and set up the stack pointer.
Then I guess add some code from the cmsis headers before the goto- __set_MSP, __DMB, etc.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3724
  • Country: gb
  • Doing electronics since the 1960s...
Re: A question on GCC .ld linker script syntax
« Reply #28 on: March 14, 2023, 06:47:17 am »
Yes - this worked also. The "extern" is the key hack

   extern int main();
   main();

This is just a way to show that you are a C expert ;)

                extern uint32_t code_base;
                goto *(&code_base);

I really have no idea what line 2 does. & takes the address of, but why the * ? I've never used function pointers in C. Only in asm. Anyway, can't beat asm; it does exactly what it says on the tin :)

Quote
it would be good to place memory barriers, invalidate cache (if present), and set up the stack pointer.

I do this just before the jmp:

   // Set SP to top of RAM
   asm volatile ("ldr sp, = _estack \n");

Quote
Then I guess add some code from the cmsis headers before the goto- __set_MSP, __DMB, etc.

Why, when this is just one load of code transferring control to another load of code? And it happens before interrupts are enabled, before RTOS starts...

Quote
Somebody said above that library (.a) is only a collection of .o. It is, but the linker does not treat it as such. There are several subtle but important differences, one being that weak symbols from .o are not overriden by symbols from .a.

That's staggering.

But I don't think it is my problem right now. I have weak symbols in a .s file and am trying to override them with a .c (compiled to .o) file. I continue to work on this one. It works in another version of the project and has done so for years, so is somehow very narrowly context dependent.

Still amazed over those KEEP directives. Mostly they are unnecessary BS which people just throw everywhere.

Same with the __libc_init_array stuff apparently. Somebody put it there and everybody just left it. All I see is this in the .map file

Code: [Select]

.preinit_array  0x000000000807095c        0x0
                0x000000000807095c                PROVIDE (__preinit_array_start = .)
 *(.preinit_array*)
                0x000000000807095c                PROVIDE (__preinit_array_end = .)

.init_array     0x000000000807095c        0x8
                0x000000000807095c                PROVIDE (__init_array_start = .)
 *(SORT_BY_NAME(.init_array.*))
 .init_array.00000
                0x000000000807095c        0x4 ../LIBC/LIBCW\libc-weakened.a(lib_a-__call_atexit.o)
 *(.init_array*)
 .init_array    0x0000000008070960        0x4 c:/st/stm32cubeide_1.11.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.win32_1.0.200.202301161003/tools/bin/../lib/gcc/arm-none-eabi/10.3.1/thumb/v7e-m+fp/hard/crtbegin.o
                0x0000000008070964                PROVIDE (__init_array_end = .)

.fini_array     0x0000000008070964        0x4
                0x0000000008070964                PROVIDE (__fini_array_start = .)
 *(.fini_array*)
 .fini_array    0x0000000008070964        0x4 c:/st/stm32cubeide_1.11.0/stm32cubeide/plugins/com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.win32_1.0.200.202301161003/tools/bin/../lib/gcc/arm-none-eabi/10.3.1/thumb/v7e-m+fp/hard/crtbegin.o
 *(SORT_BY_NAME(.fini_array.*))
                0x0000000008070968                PROVIDE (__fini_array_end = .)


« Last Edit: March 14, 2023, 07:09:17 am by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6290
  • Country: fi
    • My home page and email address
Re: A question on GCC .ld linker script syntax
« Reply #29 on: March 14, 2023, 07:01:09 am »
Still amazed over those KEEP directives. Mostly they are unnecessary BS which people just throw everywhere.
They only matter when link-time garbage collection is used, i.e. --gc-sections is used.

For library-style code, -ffunction-sections -fdata-sections at compile time (CFLAGS), and -Wl,--gc-sections at link time (LDFLAGS using gcc to link) does omit unneeded functions and data (and is also what generates all those .textsuffix and .datasuffix sections), so that only actually used code and data will be linked to the final binary.  You have to admit it is very useful in some use cases.

It has to be done this way, because ELF linkers operate on sections, and not at the individual symbol level.  (This is what reminds me so much of awk, if we compare ELF sections to awk records.  I can certainly understand why the original implementors wrote it this way, even if I myself would now do it differently.  It does significantly reduce the annoyance factor for myself.)
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3724
  • Country: gb
  • Doing electronics since the 1960s...
Re: A question on GCC .ld linker script syntax
« Reply #30 on: March 14, 2023, 07:11:37 am »
Indeed

Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3724
  • Country: gb
  • Doing electronics since the 1960s...
Re: A question on GCC .ld linker script syntax
« Reply #31 on: March 14, 2023, 07:19:04 am »
I have now realised that wek is exactly right.

The vectors file compiles to a .o but the real ISRs are in a library .a.

Bloody hell.

The simplest way is to get rid of the weaks for ISRs that actually exist. This is all inherited code; I never write stuff like this. Let's face it - the code will not run unless the real function is provided, so all this gives you is a project that compiles and then bombs.
« Last Edit: March 14, 2023, 08:06:28 am by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8184
  • Country: fi
Re: A question on GCC .ld linker script syntax
« Reply #32 on: March 14, 2023, 10:38:32 am »

                extern uint32_t code_base;
                goto *(&code_base);

I really have no idea what line 2 does. & takes the address of, but why the * ? I've never used function pointers in C. Only in asm.

This is not function pointer. This is not even C language. It's a GCC extension, a so-called computed goto.

If you googled "C function pointer", it would be instantly obvious that it does not involve using goto.
 
The following users thanked this post: newbrain

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6290
  • Country: fi
    • My home page and email address
Re: A question on GCC .ld linker script syntax
« Reply #33 on: March 14, 2023, 10:43:40 am »
Yup.  It's also related to the GCC label address extension: &&label is a void pointer you can use with goto (for example, in an expression that chooses between multiple ones), as well as an initializer (either after, or within the same block the label label has been declared).

You can even implement a Duff's Device without a switch() this way; just define an array of void pointers to labels, and then you can do a computed goto, indexing the array.
« Last Edit: March 14, 2023, 10:45:17 am by Nominal Animal »
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3724
  • Country: gb
  • Doing electronics since the 1960s...
Re: A question on GCC .ld linker script syntax
« Reply #34 on: March 14, 2023, 11:48:43 am »
Quote
If you googled "C function pointer", it would be instantly obvious that it does not involve using goto.

You rarely waste an opportunity to tell me that I am intellectually inferior to you :) I don't mind at all, so long as I am learning, but in this case I learnt nothing (I know a goto is not a function pointer) so you need to up your game :) I use a goto occassionally; it is handy for error handling. So I could see this is a form of computed goto. Anyway, asm is best; always works.

Anyway, following wek's tip I have it all running now :) I would have never found that .o - .a conflict, but I just implemented what I was going to do anyway once I found the weaks were not working: delete the weak defs. I also replaced all unused vectors with .word 0:

Code: [Select]
.word  0 /* TIM4_IRQHandler                    TIM4                         */
  .word  0 /* I2C1_EV_IRQHandler                 I2C1 Event                   */
  .word  0 /* I2C1_ER_IRQHandler                 I2C1 Error                   */
  .word  0 /* I2C2_EV_IRQHandler                 I2C2 Event                   */
  .word  0 /* I2C2_ER_IRQHandler                 I2C2 Error                   */
  .word  0 /* SPI1_IRQHandler                    SPI1                         */
  .word  0 /* SPI2_IRQHandler                    SPI2                         */
  .word  USART1_IRQHandler                  /* USART1                       */
  .word  USART2_IRQHandler                  /* USART2                       */
  .word  USART3_IRQHandler                  /* USART3                       */
  .word  0 /* EXTI15_10_IRQHandler               External Line[15:10]s        */
  .word  0 /* RTC_Alarm_IRQHandler               RTC Alarm (A and B) through EXTI Line */
  .word  0 /* OTG_FS_WKUP_IRQHandler             USB OTG FS Wakeup through EXTI line */

so any interrupt enabled but not handled will properly crash the system, but that would happen equally with the weak symbols.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline eutectique

  • Frequent Contributor
  • **
  • Posts: 399
  • Country: be
Re: A question on GCC .ld linker script syntax
« Reply #35 on: March 14, 2023, 12:16:54 pm »
Quote
it would be good to place memory barriers, invalidate cache (if present), and set up the stack pointer.
Then I guess add some code from the cmsis headers before the goto- __set_MSP, __DMB, etc.

Which, in case of gcc, boils down to __ASM volatile ("dmb 0xF":::"memory");

https://github.com/ARM-software/CMSIS_5/blob/develop/CMSIS/Core/Include/cmsis_gcc.h#L286-L289
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8184
  • Country: fi
Re: A question on GCC .ld linker script syntax
« Reply #36 on: March 14, 2023, 01:16:07 pm »
Quote
If you googled "C function pointer", it would be instantly obvious that it does not involve using goto.
You rarely waste an opportunity to tell me that I am intellectually inferior to you

I nearly forgot this time - I had to edit it in!

But I have to say again, there's absolutely nothing wrong with your intelligence. I'm just wondering you have a lot of what we would call sisu here in Finland, basically persistence "to go through a grey rock", another saying I like here. We appreciate that mindset here, doing something the hard way and learn in the process.

But I mean, function pointer syntax can look daunting sometimes, which is why you should just google, without trying to remember all that stuff. I Google "C function pointer" almost every time I need to use it. Not intelligent enough to automatically remember.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3724
  • Country: gb
  • Doing electronics since the 1960s...
Re: A question on GCC .ld linker script syntax
« Reply #37 on: March 14, 2023, 01:29:50 pm »
Quote
Which, in case of gcc, boils down to __ASM volatile ("dmb 0xF":::"memory");

Why would that be needed?

I have seen this stuff in ETH code but it turned out be not required on a 32F417 which has no data cache.

Quote
doing something the hard way and learn in the process.

I do things in a way which I can understand, and which I know I can document (most coders document exactly nothing) and support when a customer has a problem. I've never worked with anyone who had to worry about the last two.
« Last Edit: March 14, 2023, 02:06:59 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 825
  • Country: es
Re: A question on GCC .ld linker script syntax
« Reply #38 on: March 14, 2023, 02:48:31 pm »
Why invalidating cache/DMBing before a normal flash-to-flash jump? There should be no difference from any local jump/call in this case (unlike i.e. jumping to code freshly loaded to RAM when cache can contain stale data (reason to invalidate) or some reordered RAM store isn't completed yet (reason to DMB)).
There is possible problem of slightly different kind: setting the MSP says goodbye to all stack-based local vars, so it would be better to place it in the same __asm() with the final jump to be sure that no stack var content was used i.e. as a jump target.

peter-h, sorry for my exUSSR straightness, but there is a difference between "I've tried to read the manual on subj A but parts B and C are not clear to me" and "I'm too busy to read first few lines of the first google result" or "the manual has 1000 pages, let someone other read it for me".
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3724
  • Country: gb
  • Doing electronics since the 1960s...
Re: A question on GCC .ld linker script syntax
« Reply #39 on: March 14, 2023, 03:39:44 pm »
Quote
Why invalidating cache/DMBing before a normal flash-to-flash jump? There should be no difference from any local jump/call in this case (unlike i.e. jumping to code freshly loaded to RAM when cache can contain stale data (reason to invalidate) or some reordered RAM store isn't completed yet (reason to DMB)).
There is possible problem of slightly different kind: setting the MSP says goodbye to all stack-based local vars, so it would be better to place it in the same __asm() with the final jump to be sure that no stack var content was used i.e. as a jump target.

Sure. That jmp is however always flash to flash, and AFAICT the assembler produced by GCC contains loads of jumps. Well, on a quick look I can't see any right now...

At the jmp point I am chucking away all stack based variables. There should be none anyway. A bit dirty but I can't see a problem; this is a one-way path. Nothing is returning.

Quote
sorry for my exUSSR straightness, but there is a difference between "I've tried to read the manual on subj A but parts B and C are not clear to me" and "I'm too busy to read first few lines of the first google result" or "the manual has 1000 pages, let someone other read it for me".

I don't think I have ever said that. I have often commented on the 2000 page RM which, even if you find the right section, is incredibly obtuse. It is more like an encyclopedia. I think asking a specific question is ok. This is not like the ST forum where 90% of the posts are from somebody who bought a ST devkit and says "HELP - the LED is not flashing".

I do spend many hours googling (that's how most code is written today) but much of the material is simply wrong, impossible for me to understand, doesn't work, and most hits lead to unsolved problems.

Also note that I post the finished solutions. Almost nobody does that, because most people are coding in their employer's time and won't post any working code. I think that's one of the biggest problems in this area. It is also why there is so much crap on github.

I am from the Iron Curtain area too :)
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 828
Re: A question on GCC .ld linker script syntax
« Reply #40 on: March 14, 2023, 03:53:20 pm »
Quote
Which, in case of gcc, boils down to __ASM volatile ("dmb 0xF":::"memory");
Much code in the cmsis header is inline asm, just pointing out that it may already have been done for you with no need to do it yourself. I think in most cases I would rather use a version from cmsis rather than create my own which does the same thing.

https://godbolt.org/z/5We9d8aqP
Don't even need to make sure bit0 is set, as the goto will do that for you. The attributes are not necessary, but the noinline may make one feel better that this code will stay together as a group.
« Last Edit: March 14, 2023, 04:16:48 pm by cv007 »
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3724
  • Country: gb
  • Doing electronics since the 1960s...
Re: A question on GCC .ld linker script syntax
« Reply #41 on: March 14, 2023, 04:22:13 pm »
What is the difference between these two

Code: [Select]
MSR msp, r3

asm volatile ("ldr sp, = _estack \n");

Remember this is before ints are enabled and before RTOS is started.

I am trying to stick to the simplest way to do stuff.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 828
Re: A question on GCC .ld linker script syntax
« Reply #42 on: March 14, 2023, 04:56:29 pm »
Quote
I am trying to stick to the simplest way to do stuff.
Then maybe just use the cmsis headers to do some of these things. Loading sp like you did is not possible for the M0 for example (ldr restrictions), and if it is an ok instruction (in your case) you still are not choosing which stack pointer is being set. They provided instructions to handle these type of things, and already have higher level inline functions you can use such as __set_MSP. I doubt one could come up with something simpler.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3724
  • Country: gb
  • Doing electronics since the 1960s...
Re: A question on GCC .ld linker script syntax
« Reply #43 on: March 14, 2023, 05:15:21 pm »
On M4, what is called "sp" is the MSP (Main Stack Pointer) which is used during startup and during main(). Interrupts are also using this stack.

PSP (Process Stack Pointer) is used by the process/tasks, only once the RTOS is started.

For example here https://vivonomicon.com/2018/04/20/bare-metal-stm32-programming-part-2-making-it-to-main/

Code: [Select]
LDR  r0, =_estack
MOV  sp, r0

and STM themselves, in their 32F407/417 startupxxx.s, use

Code: [Select]
ldr   sp, =_estack
Looking at the cmsis macros, they still do just the one thing:

Code: [Select]

/**
  \brief   Set Main Stack Pointer
  \details Assigns the given value to the Main Stack Pointer (MSP).
  \param [in]    topOfMainStack  Main Stack Pointer value to set
 */
__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : );
}
« Last Edit: March 14, 2023, 05:17:29 pm by peter-h »
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 828
Re: A question on GCC .ld linker script syntax
« Reply #44 on: March 14, 2023, 06:13:40 pm »
Quote
For example here
They are using a M0+ so cannot directly load sp and need to go through an r0-r7 register. If you have an M4 you can ldr sp as you have shown as there is no r0-r7 restriction. Better than either it seems to me is to just use the cmsis function and be done. No need to figure out what mcu you have, what stack pointer is the target of your value, what registers to use if needed, inline asm syntax, plus it will work the same when you switch to some other cortex-m. What is the downside of using the provided inline function?
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3724
  • Country: gb
  • Doing electronics since the 1960s...
Re: A question on GCC .ld linker script syntax
« Reply #45 on: March 14, 2023, 06:43:05 pm »
I am more concerned if I am doing something wrong, or not doing something I should be doing.

Does a "long jump" have some special requirements?

I agree re generic code but the end result is still a specific CPU, with a ton of software which is totally non generic. For example the GPIO pin to peripheral mapping is totally specific to the project. It is possible to use a 32F437 instead of a 32F417 and change nothing (well, a couple of tiny details like internal measurement of the RTC battery differ). Or a 407 if you rebuild to use software crypto. But in general a product is specific in so many ways that if you changed the CPU you would need to go over every single line of source.
Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 828
Re: A question on GCC .ld linker script syntax
« Reply #46 on: March 14, 2023, 10:14:47 pm »
Quote
I agree re generic code but the end result is still a specific CPU, with a ton of software which is totally non generic.
Of course, but creating your own inline asm to set the stack, in whatever manner you choose, just because the cmsis version works for all cortex-m and all compilers doesn't make sense.

Quote
Does a "long jump" have some special requirements?
Its a 32bit mcu with 32bit registers and a 32bit address space, so define 'long'.
 

Online peter-hTopic starter

  • Super Contributor
  • ***
  • Posts: 3724
  • Country: gb
  • Doing electronics since the 1960s...
Re: A question on GCC .ld linker script syntax
« Reply #47 on: March 14, 2023, 11:04:24 pm »
Quote
so define 'long'.

Do you recognise the long call attrib?

Code: [Select]

// === At this point, interrupts and DMA must still be disabled ====
// Execute loader. Reboots afterwards.

extern char _loader_start;
extern char _loader_end;
extern char _loader_loadaddr;
extern char _loader_bss_start;
extern char _loader_bss_end;

// Copy loader code to RAM. This also sets up its initialised data.
B_memcpy(&_loader_start, &_loader_loadaddr, &_loader_end - &_loader_start);

// Clear loader's BSS and COMMON
B_memset(&_loader_bss_start, 0, &_loader_bss_end - &_loader_bss_start);

// See comments in loader.c for why the long call.

extern void loader_entry() __attribute__((long_call));
loader_entry();

// never get here (loader always reboots)
for (;;);

The comment referred to is

 * ALSO ANY FUNCTIONS CALLED FROM THE BOOT LOADER, AND WHICH ARE NOT IN LOADER.C (WHICH ARE
 * IN THE BOOT BLOCK) NEED THE LONG CALL ATTRIBUTE IN THEIR PROTOTYPE IN B_MAIN.H. It is not clear
 * why this is required and it may just be that debugging works properly. Otherwise, for long calls
 * or jumps the linker adds "veneer code" which needs switching to asm code mode to step through.

There was a thread on the veneer code...

I still have a bit of trouble which I suspect is due to BSS not getting zeroed, or somewhich should be zeroed not getting loaded into BSS. I checked the BSS area for being zeroed by looking at memory, when the memset func is running...

In this code

Code: [Select]

void KDE_get_date_time(char *datetime)
{

RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};

HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);

int i = (sDate.WeekDay - 1) * 3;

sprintf(datetime, "%c%c%c %02d%02d20%02d %02d%02d%02d DOY=%03d",
d_o_w[i],d_o_w[i+1],d_o_w[i+2],sDate.Date, sDate.Month, sDate.Year,
sTime.Hours, sTime.Minutes, sTime.Seconds, day_of_year(sDate.Date, sDate.Month-1, sDate.Year+100));

}

how would you expect those two structs to be zeroed? I would think that if they were static they would be in BSS. But I think there is special code at the start of that function, which might be a string in BSS which gets copied, or perhaps a "memset"? The sprintf() runs for ever. OK; I know it should be an snprintf() but that isn't my code, and it isn't supposed to go off the end.

Z80 Z180 Z280 Z8 S8 8031 8051 H8/300 H8/500 80x86 90S1200 32F417
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 828
Re: A question on GCC .ld linker script syntax
« Reply #48 on: March 14, 2023, 11:49:02 pm »
Quote
NEED THE LONG CALL ATTRIBUTE IN THEIR PROTOTYPE
I don't get that advanced, but I assume there can be cases where the compiler emits a BL instruction where the address cannot be reached (BL limitation, address not known to the compiler at compile time, the linker will fill in, and is out of BL range). The long_call attribute I presume will make the compiler end up using BLX instead whether required or not. Or something.

edit- I guess those that use ram functions will know all about this. It would appear the gcc compiler treats all symbols as BL reachable, so the linker is required to fix up things like making executable code located in data/ram reachable by creating extra code to bridge from BL reachable to BL unreachable.

You can try out various things in the online compiler. It makes for a good playground.
https://godbolt.org/z/sx6K75TGq
(added the goto for fun- the compiler makes no assumptions about the target address when using, obviously not useful when passing arguments, or when you need to return)

Quote
how would you expect those two structs to be zeroed?
Like any other local var. The compiler may put it on the stack and zero it out, or it may optimize the code where there is no need to use the stack or to zero it out. A local non-static var is not using bss in any case.
« Last Edit: March 15, 2023, 06:09:45 am by cv007 »
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8184
  • Country: fi
Re: A question on GCC .ld linker script syntax
« Reply #49 on: March 15, 2023, 06:06:19 am »
Code: [Select]
sprintf(datetime, "%c%c%c %02d%02d20%02d %02d%02d%02d DOY=%03d",
d_o_w[i],d_o_w[i+1],d_o_w[i+2],sDate.Date, sDate.Month, sDate.Year,
sTime.Hours, sTime.Minutes, sTime.Seconds, day_of_year(sDate.Date, sDate.Month-1, sDate.Year+100));

}

That code does not use %s in the format string. IMO, there is nothing in this code which is looking for a terminating zero. It should not "run forever". Initial state of datetime is irrelevant, as are all the input values here; %c or %d cannot "crash", there are no invalid values for them.

Something else is going on; maybe look with a debugger where the code is actually stuck. Maybe you are in a hardfault handler or something.
 
The following users thanked this post: peter-h


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf