GCC: Access to linker symbol from C file

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
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, <code 336> (.))

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



Re: GCC: Access to linker symbol from C file
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 indefinite size. This forces GCC to
generate "full-range" addressing code. Of course, you can cast the
symbol as needed when you use it.

"andrew queisser" <andrew.queisser at hp com> wrote:

: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, <code 336> (.))
:
: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
:


Re: GCC: Access to linker symbol from C file
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

Quoted text here. Click to load it



Site Timeline