GCC: Access to linker symbol from C file

Jun 09, 2005 2 Replies

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


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 :

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

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required