-
Notifications
You must be signed in to change notification settings - Fork 24
Description
Hi,
Following issue occurs on a mor1kx but I think it may be a toolchain problem.
When defining a byte array and casting parts of the byte array to a DWORD, the address of the first byte of the DWORD is probably not DWORD aligned (i.e. &byte_array[1] = 0x00000001 ). Normally, this is no problem and the DWORD pointer can be dereferenced correctly (i.e. p_u32 = (uint32_t *)&byte_array[1]; a=*p_u32;). When storing the DWORD pointer in a global structure, this does not work, the program simply hangs up when trying to dereference the pointer stored in the global struct. Please find below a program to show the problem. The program works fine compiled with standard gcc on a Linux machine but hangs up in Modelsim simulation when compiled with or1k-elf-gcc.
I am not sure to which branch of Openrisc development it belongs but it may be a toolchain problem as the dereferencing in general works when using the local struct. Also I am not sure if this is already fixed as I use an older (~1 year) version of mor1kx and toolchain.
Best regards,
Markus
#include <stdint.h>
#include <stdio.h>
//the structure contains a byte pointer and a DWORD pointer
typedef struct
{
uint8_t * p_struct_u8;
uint32_t * p_struct_u32;
} struct_pointers;
//the structure itself as global variable; does not work!
struct_pointers sp; //comment this line and uncomment the local struct definition to work correctly
int main(int argc, char *argv[])
{
//10 byte array
uint8_t v_array_u8 [10] = {1,2,3,4,5,6,7,8,9,10};
//pointer to byte
uint8_t * p_u8;
//pointer to DWORD
uint32_t * p_u32;
// struct_pointers sp; //the structure as local variable does work; uncomment this line and comment the global struct definition to work correctly
//point to first byte (DWORD aligned pointer address)
p_u8 = &v_array_u8[0];
p_u32 = (uint32_t *)&v_array_u8[0];
//store the pointers in the struct
sp.p_struct_u8 = p_u8;
sp.p_struct_u32 = p_u32;
printf("Addresses of pointers without struct DWORD aligned \n\r");
printf("p8: %#010x \n\r", (unsigned int)p_u8);
printf("p32: %#010x \n\r", (unsigned int)p_u32);
printf("Dereferenced pointers without struct \n\r");
printf("*p8: %#010x \n\r", (unsigned int)*p_u8);
printf("*p32: %#010x \n\r", (unsigned int)*p_u32);
printf("Addresses of pointers stored in struct DWORD aligned\n\r");
printf("sp8: %#010x \n\r", (unsigned int)sp.p_struct_u8);
printf("sp32: %#010x \n\r", (unsigned int)sp.p_struct_u32);
printf("Dereferenced pointers from struct \n\r");
printf("*sp8: %#010x \n\r", (unsigned int)*sp.p_struct_u8);
printf("*sp32: %#010x \n\r", (unsigned int)*sp.p_struct_u32);
//point to second byte (not DWORD aligned pointer address)
p_u8 = &v_array_u8[1];
p_u32 = (uint32_t *)&v_array_u8[1];
//store the pointers in the struct
sp.p_struct_u8 = p_u8;
sp.p_struct_u32 = p_u32;
printf("Addresses of pointers without struct not DWORD aligned \n\r");
printf("p8: %#010x \n\r", (unsigned int)p_u8);
printf("p32: %#010x \n\r", (unsigned int)p_u32);
printf("Dereferenced pointers without struct \n\r");
printf("*p8: %#010x \n\r", (unsigned int)*p_u8);
printf("*p32: %#010x \n\r", (unsigned int)*p_u32);
printf("Addresses of pointers stored in struct not DWORD aligned\n\r");
printf("sp8: %#010x \n\r", (unsigned int)sp.p_struct_u8);
printf("sp32: %#010x \n\r", (unsigned int)sp.p_struct_u32);
printf("Dereferenced pointers from struct \n\r");
printf("*sp8: %#010x \n\r", (unsigned int)*sp.p_struct_u8);
printf("*sp32: %#010x \n\r", (unsigned int)*sp.p_struct_u32); //hangs up here when dereferencing non DWORD aligned address
printf("Successfully finished! \n\r");
while(1) {};
}