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++
12603 Discussions

How to declare linker symbol in C files

Altera_Forum
Honored Contributor II
2,353 Views

Dear all, 

 

As we known, the generated automatically linker script defined many symbols for use. For example: __bss_start. 

We can use these symbols in source files, for example, in *.S file, we can declare it as follow: 

.globl __bss_start  

But I don't know how to declare it in *.c files. 

I have tried as follow: 

extern char* __bss_start; 

But it seems doesn't work... 

 

Anybody help... 

 

Thanks in advance, 

David
0 Kudos
7 Replies
Altera_Forum
Honored Contributor II
1,344 Views

David, 

 

This works for me. 

 

// declare the external. 

extern unsigned char *__bss_start; 

 

// somewhere in a function. 

printf("%u\n",(unsigned int)&__bss_start); 

 

The print shows my correct start of bss. 

 

Maybe you are trying to access the 'content of' rather than 'address of'. 

 

Banx.
0 Kudos
Altera_Forum
Honored Contributor II
1,344 Views

Thanks very much for your reply... 

 

I am still a little confuse... 

__bss_start is a pointer, it's value equal to the start address of bss section 

why  

printf("%u\n",(unsigned int)&__bss_start); but not 

printf("%u\n",(unsigned int)__bss_start); 

 

Thanks again, 

David
0 Kudos
Altera_Forum
Honored Contributor II
1,344 Views

 

--- Quote Start ---  

originally posted by david_cai@Aug 17 2006, 06:10 AM 

thanks very much for your reply... 

 

    i am still a little confuse... 

    __bss_start is a pointer, it's value equal to the start address of bss section 

    why  

      printf("%u\n",(unsigned int)&__bss_start);    but not 

      printf("%u\n",(unsigned int)__bss_start); 

 

thanks again, 

david 

<div align='right'><{post_snapback}> (index.php?act=findpost&pid=17677) 

--- quote end ---  

 

--- Quote End ---  

 

 

You&#39;ve told the compiler that __bss_start is a pointer, with space allocated elsewhere. But there is no space allocated, so the only way to use your new pointer is to take the address of it, which gives you the value of __bss_start. 

 

I do it this way when the symbol is within range of the global pointer: 

 

extern unsigned char __some_near_symbol; unsigned int NearSymbolAddr; NearSymbolAddr = (unsigned int) &__some_near_symbol; 

 

or if not in range of the global pointer: 

 

extern unsigned char  __some_far_symbol;  // Use to force compiler to not use global pointer. unsigned int FarSymbolAddr; FarSymbolAddr = (unsigned int) __some_far_symbol;
0 Kudos
Altera_Forum
Honored Contributor II
1,344 Views

Thanks very much... 

 

I almost got it... But I&#39;m still confusing that how to understand the symbol in linker script. It seems that we can take it as a variable in source files, but in fact, there is no space allocated, why don&#39;t we take it as a constant and why operator& which will return its address can get its actual value??? 

 

Thanks again, 

david
0 Kudos
Altera_Forum
Honored Contributor II
1,344 Views

David, 

 

__bss_start isn&#39;t a pointer, nor does it hold anything. It&#39;s just a number generated by the linker that states where the bss starts. i.e. __bss_start does not occupy any memory space, it is a label. You could just as easily declare it as a short or a char. 

 

extern char __bss_start; 

 

In this case, if you printf("%d\n", __bss_start); then you will be printing the CONTENTS OF the first byte of bss, which you have fooled the compiler into thinking is a char that actually occupies a memory location. Just as if you had : 

 

char fred; 

 

fred = 42; 

printf("%d\n", fred); 

 

Using the &#39;&&#39; just makes the compiler print the ADDRESS OF (i.e. the value of the label) instead of CONTENTS OF what the label is pointing to. 

 

I hope that helps. 

 

Banx.
0 Kudos
Altera_Forum
Honored Contributor II
1,344 Views

Hi, 

 

I have done a further study, I find that no matter how you declare the __bss_start,such as: 

extern alt_u8 __bss_start; 

extern alt_u8* __bss_start; 

extern alt_u16 __bss_start; 

extern alt_u16* __bss_start; 

extern alt_u32 __bss_start; 

extern alt_u32* __bss_start; 

 

Then  

printf("\nThe value of __bss_start: %d\n", (unsigned int)&__bss_start); 

You&#39;ll get the same answer which equal to the value of __bss_start in linker script. 

 

So I think in order to use symbols defined in linker script, we should declare them with extern keyword, then use operator& to get their value. 

 

Am I right? 

 

Thanks for any reply, 

David
0 Kudos
Altera_Forum
Honored Contributor II
1,344 Views

Yeah, 

 

Since it isn&#39;t really a pointer to anything I guess most folk would say that it should be declared as 

 

extern void* __bss_start; 

 

Banx.
0 Kudos
Reply