Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
12589 Discussions

pointer out of range link error

Altera_Forum
Honored Contributor II
1,977 Views

I have some code running from SDRAM that references an on chip RAM. In porting from NIOS to NIOS II I'm getting the link error 

global pointer relative address out of range 

 

I saw a topic that suggested NIOS II 1.01 would solve a similar error for an STL problem but that was an access back to the text section. Is this the same problem?  

 

Dan
0 Kudos
8 Replies
Altera_Forum
Honored Contributor II
978 Views

I found some more information on this and it looks like the problem is not with the address per se but with the fact that I'm trying to use a symbol provided by the linker script to access it.  

 

The linker script "generated.x" has a section for my internal memory and within that it has some PROVIDE directives. It seems that I can't access these symbols generated by the PROVIDE from within my code. These are symbols that have the form _alt_partition_MEMORY_NAME_start and _alt_partition_MEMORY_NAME_end. I can access some other PROVIDE symbols like edata.  

 

The ones that start with alt_ seem to be the problem. Is this a result of having no program data to go into the section?  

 

I can use a define from system.h for my immeadiate problem but this has got my curiosity up and I'm likely to need access to some of these linker generated symbols in the future. Any help appreciated. 

 

Dan
0 Kudos
Altera_Forum
Honored Contributor II
978 Views

I think the problem may be to do with the way you are declaring the C externs which you are using to access the data. Please post the C code you used, particularly if the suggestion below doesn't solve your problem. 

 

I'm guessing your code looks a bit like this: 

extern char _alt_partition_MEMORY_NAME_start; printf("%X\n", &_alt_partition_MEMORY_NAME_start); 

That's declaring a one byte symbol. gcc will assume, because the symbol is small, that it will be in section sdata or sbss and use gp relative addressing to get to it. 

 

You need to do something like this: 

extern char _alt_partition_MEMORY_NAME_start; printf("%X\n", _alt_partition_MEMORY_NAME_start); 

This declares a symbol of undefined length. gcc won't make any asusmptions about where it is and will use hi/lo addressing to operate on the symbol. 

 

Alternatively, you could use __attribute__ ((section ("section"))) to tell GCC which section the symbol will be in, but this is probably not needed in this case.
0 Kudos
Altera_Forum
Honored Contributor II
978 Views

Your first sugestion did the trick (use [])!  

 

One thing I noticed is that when I run readelf with -s I don't see the symbol I'm referencing. I see others like __bss_start  

 

Here is the linker script portion that declares my symbol: 

.cpu_memory_data : 

PROVIDE (_alt_partition_cpu_memory_data_start = ABSOLUTE(.)); 

*(.cpu_memory_data) 

. = ALIGN(32 / 8); 

PROVIDE (_alt_partition_cpu_memory_data_end = ABSOLUTE(.)); 

} > cpu_memory_data 

 

Here is the output of nios2-elf-readelf -s 

re/ssec/Debug 

[SOPC Builder]$ nios2-elf-readelf.exe -s project.elf | grep partition 

373: 11000000 0 NOTYPE GLOBAL DEFAULT ABS _alt_partition_cpu_memory 

1617: 11000000 0 NOTYPE GLOBAL DEFAULT ABS _alt_partition_cpu_memory 

 

I am referencing these symbols in the code: 

extern char _alt_partition_cpu_memory_data_start[]; 

extern char _alt_partition_cpu_memory_data_end[];  

printf("start:%p end:%p\n", _alt_partition_cpu_memory_data_start, _alt_partition_cpu_memory_data_end); 

which works.  

 

Should this symbol show up in the readelf output?  

 

Thanks, 

Dan
0 Kudos
Altera_Forum
Honored Contributor II
978 Views

I'm facing the same problem and still struggling to solve this problem. 

obj/nulldriver.o(.text+0x18): global pointer relative address out of range 

 

Is there any solution to this problem besides the one mentioned above? 

 

thanks in advance http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/wink.gif
0 Kudos
Altera_Forum
Honored Contributor II
978 Views

> Is there any solution to this problem besides the one mentioned above? 

 

I&#39;m curious to know if the -G0 compiler option solves the problem ... at least 

as a temporary work around ... it should keep data out of .sdata/.sbss. 

 

BTW: that&#39;s the numeral "zero" 

 

Regards, 

--Scott
0 Kudos
Altera_Forum
Honored Contributor II
978 Views

yes, it does solve the problem  

 

Thanks for the great advice!
0 Kudos
Altera_Forum
Honored Contributor II
978 Views

> yes, it does solve the problem 

 

Great! I&#39;ll use this myself then ... when/if I encounter the problem. 

 

Just note that it will affect performance since full addresses will 

be loaded for what was previously small (gp relative) data -- which 

I believe defaults to variables of 8 bytes or less (when -Gn is not 

specified). 

 

I guess mileage will vary depending on the application ;-) 

 

Regads, 

--Scott
0 Kudos
Altera_Forum
Honored Contributor II
978 Views

Hello, 

 

 

after almost 12 years I've got a similar problem!! 

 

 

I am using Quartus 14.1sp1 and a NIOS II gen2. 

 

I get the following error while trying to compile my application (working in Quartus 7.1, NIOS II classic): 

 

 

obj/default/lpc_lib.o: in function `lsp_to_freq': 

lpc_lib.c:649: warning: unable to reach (null) (at 0x800476b8) from the global pointer (at 0x8003f5d8) because the offset (32992) is out of the allowed range, -32678 to 32767. 

 

collect2: error: ld returned 1 exit status 

make: *** [rio_audio_codec.elf] error 1 

 

 

I tried to define all the extern variables with the "[]" at the end (as suggested above), but the problem is still present. 

 

 

I tried also to use the -G0 flag in the application, but the problem was not solved. 

 

Should I also specify the same flag for the BSP ? If so, how? 

 

 

Anyway I'd like to solve the problem definetely (without using the -G0), also because I need to reach some performance. 

 

 

Any hint is more than appreciated, 

thanks on advance
0 Kudos
Reply