[Bug middle-end/89269] RISC-V stack variable as global variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89269 --- Comment #7 from Pharos Team --- Just an additional note to anyone who might have the same problem, I solved it with: /**/ /* Start of text and read-only data area */ /**/ .text : { CREATE_OBJECT_SYMBOLS /* source code is in text section */ pharosStartText = .; KEEP(*(.textStart)) KEEP(*(.textStart.*)) . = ALIGN (0x4); *(.text) *(.text.*) /* read-only data is placed in text */ . = ALIGN (0x10); pharosRodataStart = . ; *(.srodata) *(.srodata.*) *(.rodata) *(.rodata.*) *(.note.gnu.build-id) *(.note.gnu.build-id.*) pharosRodataEnd = .; /* variable to check the end of the text section */ . = ALIGN (0x10); _endtext = .; pharosEndText = .; } > sdram That is, placing *(.srodata) solved it (the constant variable was being placed at .srodata instead of .rodata) Regards, Pharos team
[Bug middle-end/89269] RISC-V stack variable as global variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89269 Pharos Team changed: What|Removed |Added Resolution|INVALID |FIXED --- Comment #6 from Pharos Team --- OK, I think I got it know. I've tried more things and indeed this seems now to be a linker problem. I tried to increase the message length (2 more bytes): void aperiodicThread0_0() { PharosHwQueueSendR sendResult; uint8_t message[] = { 0xda , 0x4f , 0xc2 , 4 , 5 , 6 , 7 , 8 , 9 , 10 }; . . . } and now the generated assembly is: 800013b8: 1101addisp,sp,-32 800013ba: ec06sd ra,24(sp) 800013bc: e822sd s0,16(sp) 800013be: 1000addis0,sp,32 800013c0: 00011797auipc a5,0x11 800013c4: 1c878793addia5,a5,456 # 80012588 800013c8: 6398ld a4,0(a5) 800013ca: fee43023sd a4,-32(s0) 800013ce: 0087d783lhu a5,8(a5) 800013d2: fef41423sh a5,-24(s0) as opposed to initially which was: 800013b8: 1101addisp,sp,-32 800013ba: ec06sd ra,24(sp) 800013bc: e822sd s0,16(sp) 800013be: 1000addis0,sp,32 800013c0: 00bff797auipc a5,0xbff 800013c4: 04078793addia5,a5,64 # 80c00400 800013c8: 639cld a5,0(a5) 800013ca: fef43023sd a5,-32(s0) 800013ce: 00011597auipc a1,0x11 800013d2: 11258593addia1,a1,274 # 800124e0 800013d6: 4501li a0,0 I assuming now that the linker found some 8 bytes free near the partition1BssEnd, instead of placing the data in the rodata section. By the way, the linker script for the text section is: .text : { CREATE_OBJECT_SYMBOLS /* source code is in text section */ pharosStartText = .; *(.textStart) *(.textStart.*) . = ALIGN (0x4); *(.text) *(.text.*) /* read-only data is placed in text */ . = ALIGN (0x10); pharosRodataStart = . ; *(.rodata) *(.rodata.*) *(.note.gnu.build-id) pharosRodataEnd = .; /* variable to check the end of the text section */ . = ALIGN (0x10); _endtext = .; pharosEndText = .; } > sdram and near the partition1BssEnd is: /* data of partition */ .partition1 : { CREATE_OBJECT_SYMBOLS /* address of the partition 1 data section start in RAM */ partition1DataStart = .; . = ALIGN(PARTITION_ALIGNMENT); . = ALIGN(8); partition1Start = .; *(.partition1) *(.partition1.*) /* address of the partition 1 data section end in RAM */ . = ALIGN(8); partition1DataEnd = .; } > sdram AT > sdram = 0xff /* bss of partition 1*/ .partition1Bss (NOLOAD) : { CREATE_OBJECT_SYMBOLS /* address of the partition 1 bss section start in RAM */ . = ALIGN(8); partition1BssStart = .; *(.partition1Bss) *(.partition1Bss.*) /* address of the shared partition 1 section end in RAM */ . = ALIGN(8); partition1BssEnd = .; /* place here the partition data that is NOT to be initialized at all */ partition1UssStart = .; *(.partition1Uss) *(.partition1Uss.*) partition1UssEnd = .; partition1End = .; } > sdram This is indeed one of those bugs that happens one in a million! So in short, from my part, you can close this bug (I noticed that last time you marked it as "fixed", maybe a mistake as you mark it correctly as "invalid" the other times). I'll continue to investigate if this is a binutils issue or if something has to be done on my side (linker script?) Thank you and have a good weekend (rest of it). Pharos team
[Bug middle-end/89269] RISC-V stack variable as global variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89269 Pharos Team changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID |--- --- Comment #4 from Pharos Team --- I continue not to understand your point. Correct me if I'm wrong, it is GCC that generates the assembly instructions to read from partition1BssEnd, where it shouldn't. How can this be a linker problem? Just to make clear, the address 80c00400 belongs is inside the linker script. It is the MMU that is initialized to state that address as invalid (and it is correctly initialized as invalid since this address belongs to another partition).
[Bug middle-end/89269] RISC-V stack variable as global variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89269 Pharos Team changed: What|Removed |Added Status|RESOLVED|UNCONFIRMED Resolution|INVALID |--- --- Comment #2 from Pharos Team --- I'm sorry but your comment is invalid. The following lines: 800013b4: 00bff797auipc a5,0xbff 800013b8: 04c78793addia5,a5,76 #80c00400 800013bc: 639cld a5,0(a5) load to a5 the address of partition1BssEnd and then they "read" the location of partition1BssEnd. Even though there is no "write", the "read" operation is triggering the MMU to raise an error (as it should). For example, compiling the same C code for ARM AARCH64 we get the result: 1448: a9be7bfdstp x29, x30, [sp, #-32]! 144c: 910003fdmov x29, sp PharosHwQueueSendR sendResult; //uint8_t message4[10]; uint8_t message[] = { 1450: 128004a0mov w0, #0xffda // #-38 1454: 390043e0strbw0, [sp, #16] 1458: 528009e0mov w0, #0x4f // #79 145c: 390047e0strbw0, [sp, #17] 1460: 128007a0mov w0, #0xffc2 // #-62 1464: 39004be0strbw0, [sp, #18] 1468: 52800080mov w0, #0x4// #4 146c: 39004fe0strbw0, [sp, #19] 1470: 528000a0mov w0, #0x5// #5 1474: 390053e0strbw0, [sp, #20] 1478: 528000c0mov w0, #0x6// #6 147c: 390057e0strbw0, [sp, #21] 1480: 528000e0mov w0, #0x7// #7 1484: 39005be0strbw0, [sp, #22] 1488: 52800100mov w0, #0x8// #8 148c: 39005fe0strbw0, [sp, #23] That is, everything is placed (correctly) on the stack. I just place the aarch64 example so that we can make sure that the C code is not making any reference at all to partition1BssEnd (I have no idea why on RISC-V it would make such a reference). With this "read" problem I took the liberty to reopen the bug. I truly believe this is a bug and not invalid. Best regards, Pharos team
[Bug c/89269] New: RISC-V stack variable as global variable
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89269 Bug ID: 89269 Summary: RISC-V stack variable as global variable Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: rtos.pharos at outlook dot com Target Milestone: --- Hello all, I'm working on Pharos operating system https://sourceforge.net/projects/rtospharos/ (maybe this information could be useful for debugging the issue). In RISC-V (riscv64-unknown-elf-gcc) version 8.2.0 the following code: void aperiodicThread0_0() { PharosHwQueueSendR sendResult; uint8_t message[] = { 0xda , 0x4f , 0xc2 , 4 , 5 , 6 , 7 , 8 }; . . . } (the important part is the message variable that is declared on the stack) this code compiles into: 800013ac: 1101addisp,sp,-32 800013ae: ec06sd ra,24(sp) 800013b0: e822sd s0,16(sp) 800013b2: 1000addis0,sp,32 PharosHwQueueSendR sendResult; uint8_t message[] = { 800013b4: 00bff797auipc a5,0xbff 800013b8: 04c78793addia5,a5,76 # 80c00400 800013bc: 639cld a5,0(a5) 800013be: fef43023sd a5,-32(s0) 0xda , 0x4f , 0xc2 , 4 , 5 , 6 , 7 , 8 That is, the "message" variable is placed after the partition1BssEnd section (this is defined on the linker script). Even with optimizations (this code was compiled -O0) this should not occur. In short, I am developing an OS with everything defined statically, so that at startup the OS already knows where to place every global variable and we can protect the memory of each partition/process. If variables that should on stack are placed on a global section (not even on the partition that they belong to) that screws up the mechanism. Best regards, Pharos Team