GCC: Access to linker symbol from C file

In my NIOS project I'm trying to access a linker symbol from my C file. I'm using the Altera GCC toolchain. The idea is to find out where the end of my code and R/O memory is in flash so I can use the remainder for storage. I have the following in my .c file:

.C file: extern int __ram_rodata_end; void *p = &__ram_rodata_end;

The .map file shows the symbol __ram_rodata_end like this: 0x01014f20 PROVIDE (__ram_rodata_end, (.))

But the linker gives me the error below. If I use a symbol that's in reach (e.g. __sbss_end) everything works and p points to the end of data. The format in the map file is exactly the same so I know that's not the problem.

Linker error: ../test.c:33: Unable to reach __ram_rodata_end (at 0x01014f20) from the global pointer (at 0x0101ed34) because the offset (-40468) is out of the allowed range, -32678 to 32767.

Here's the assembly code causing the problem: 145 0100 040080D0 addi r2,gp,%gprel(__ram_rodata_end) 146 0104 150680E0 stw r2,24(fp)

Is there an easy way of getting the value of a linker symbol into a C variable? I'm not above using inline assembly with a global or static variable to get the value.

Thanks, Andrew

Reply to
andrew queisser
Loading thread data ...

I haven't used NIOS, but for PowerPC (& I believe, generally), this works:

extern int __ram_rodata_end[];

The trick is to use an array of :In my NIOS project I'm trying to access a linker symbol from my C file. I'm :using the Altera GCC toolchain. The idea is to find out where the end of my :code and R/O memory is in flash so I can use the remainder for storage. I :have the following in my .c file: : :.C file: : extern int __ram_rodata_end; : void *p = &__ram_rodata_end; : :The .map file shows the symbol __ram_rodata_end like this: : 0x01014f20 PROVIDE (__ram_rodata_end, (.)) : :But the linker gives me the error below. If I use a symbol that's in reach :(e.g. __sbss_end) everything works and p points to the end of data. The :format in the map file is exactly the same so I know that's not the problem. : :Linker error: : ../test.c:33: Unable to reach __ram_rodata_end (at 0x01014f20) from the :global pointer (at 0x0101ed34) because the offset (-40468) is out of the :allowed range, -32678 to 32767. : :Here's the assembly code causing the problem: : 145 0100 040080D0 addi r2,gp,%gprel(__ram_rodata_end) : 146 0104 150680E0 stw r2,24(fp) : : :Is there an easy way of getting the value of a linker symbol into a C :variable? I'm not above using inline assembly with a global or static :variable to get the value. : :Thanks, :Andrew :

Reply to
David R Brooks

David,

Thanks very much, that solved the problem.

For anyone who's following this, below is the assembly code used to get the array address and store it in a local variable. There's two operations for the high and low part of the address since immediate moves only allow 16 bit operands. (Interestingly, there's a NIOS opcode 'movia' that does the compiler doesn't generate it.)

145 0100 34008000 movhi r2,%hiadj(__ram_rodata_end) 146 0104 04008010 addi r2,r2,%lo(__ram_rodata_end) 147 0108 150680E0 stw r2,24(fp)

Andrew

Reply to
andrew queisser

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.