On 02/19/2015 03:09 PM, Jakub Jelinek wrote:
If you have hw where NULL is mapped and you know your code violates the C/C++ standards by placing objects at that address, simply do use the option that is designed for that purpose.
As I pointed out earlier, though, that won't help you if your program (perhaps implicitly) uses library code that's been built without the magic option.
I thought that declaring an object explicitly placed at address 0 as "volatile" ought to be sufficient to prevent writes to it from being optimized away and replaced with traps, but alas, that is not the case. Also, a structure copy to such a volatile object is implicitly invoking the regular memcpy function without complaining about casting away volatile-ness, as an explicit call would do. I've attached a couple quick test cases and .s output from arm-none-eabi-gcc -O2, using a mainline build from last night.
-Sandra
static int * const x0 = (int *) 0x00000000; static volatile int * const xv = (int *) 0x00000000; static int * const xn = (int *) 0x10000000; void f0 (int *data) { *x0 = *data; } void fv (int *data) { *xv = *data; } void fn (int *data) { *xn = *data; }
.cpu arm7tdmi .fpu softvfp .eabi_attribute 20, 1 .eabi_attribute 21, 1 .eabi_attribute 23, 3 .eabi_attribute 24, 1 .eabi_attribute 25, 1 .eabi_attribute 26, 1 .eabi_attribute 30, 2 .eabi_attribute 34, 0 .eabi_attribute 18, 4 .arm .syntax divided .file "test.c" .text .align 2 .global f0 .type f0, %function f0: @ Function supports interworking. @ Volatile: function does not return. @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. mov r3, #0 str r3, [r3] .inst 0xe7f000f0 .size f0, .-f0 .align 2 .global fv .type fv, %function fv: @ Function supports interworking. @ Volatile: function does not return. @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. mov r3, #0 str r3, [r3] .inst 0xe7f000f0 .size fv, .-fv .align 2 .global fn .type fn, %function fn: @ Function supports interworking. @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. mov r3, #268435456 ldr r2, [r0] str r2, [r3] bx lr .size fn, .-fn .ident "GCC: (GNU) 5.0.0 20150219 (experimental)"
struct big { int a, b; char c [100]; }; static struct big * const x0 = (struct big *) 0x00000000; static volatile struct big * const xv = (struct big *) 0x00000000; static struct big * const xn = (struct big *) 0x10000000; void f0 (struct big *data) { *x0 = *data; } void fv (struct big *data) { *xv = *data; } void fn (struct big *data) { *xn = *data; }
.cpu arm7tdmi .fpu softvfp .eabi_attribute 20, 1 .eabi_attribute 21, 1 .eabi_attribute 23, 3 .eabi_attribute 24, 1 .eabi_attribute 25, 1 .eabi_attribute 26, 1 .eabi_attribute 30, 2 .eabi_attribute 34, 0 .eabi_attribute 18, 4 .arm .syntax divided .file "test2.c" .text .align 2 .global f0 .type f0, %function f0: @ Function supports interworking. @ Volatile: function does not return. @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 mov r1, r0 stmfd sp!, {r4, lr} mov r2, #108 mov r0, #0 bl memcpy .inst 0xe7f000f0 .size f0, .-f0 .align 2 .global fv .type fv, %function fv: @ Function supports interworking. @ Volatile: function does not return. @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 mov r1, r0 stmfd sp!, {r4, lr} mov r2, #108 mov r0, #0 bl memcpy .inst 0xe7f000f0 .size fv, .-fv .align 2 .global fn .type fn, %function fn: @ Function supports interworking. @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 stmfd sp!, {r4, lr} mov r1, r0 mov r2, #108 mov r0, #268435456 bl memcpy ldmfd sp!, {r4, lr} bx lr .size fn, .-fn .ident "GCC: (GNU) 5.0.0 20150219 (experimental)"