Array size depending on symbol address

U

usenet

Hello,

I am running my code on an embedded platform without OS. I have defined some
data in a section called .eeprom. The section is defined by the linker
script and starts at address zero. The symbol __eeprom_end is defined by the
linker script as well, and lies at the end of this section. The address of
__eeprom_end is thus equal to the number of bytes in the .eeprom section.

My problem : I want to declare an array in .bss with the same size of this
section. My naive approch was :

extern void *_eeprom;
char eeprom_shadow[(int)&_eeprom_end];

This fails miserably, ofcourse : the compiler doesn't know the address of
__eeprom before the linker is done, so it can not declare the array.

Is there a trick to allocate the memory for this array at compile time ? I'd
rather not use malloc() and friends, since I am working on a platform with a
very small amount of memory, and don't like using dynamic memory here.

Thanks,
 
G

Gordon Burditt

I am running my code on an embedded platform without OS. I have defined some
data in a section called .eeprom. The section is defined by the linker
script and starts at address zero. The symbol __eeprom_end is defined by the
linker script as well, and lies at the end of this section. The address of
__eeprom_end is thus equal to the number of bytes in the .eeprom section.

My problem : I want to declare an array in .bss with the same size of this
section. My naive approch was :

extern void *_eeprom;
char eeprom_shadow[(int)&_eeprom_end];

This fails miserably, ofcourse : the compiler doesn't know the address of
__eeprom before the linker is done, so it can not declare the array.

Is there a trick to allocate the memory for this array at compile time ? I'd
rather not use malloc() and friends, since I am working on a platform with a
very small amount of memory, and don't like using dynamic memory here.

You have a fundamental chicken-or-the-egg problem here. A change
in the size of the array can change the size of the code (because,
for example, instructions can have short or long offsets), which
can change the size of the .eeprom section, which can change the
size of the array, which can change the size of the code AGAIN,
which can change the size of the .eeprom section AGAIN, ad nauseum.

Gordon L. Burditt
 
U

usenet

I am running my code on an embedded platform without OS. I have defined some
data in a section called .eeprom. The section is defined by the linker
script and starts at address zero. The symbol __eeprom_end is defined by the
linker script as well, and lies at the end of this section. The address of
__eeprom_end is thus equal to the number of bytes in the .eeprom section.

My problem : I want to declare an array in .bss with the same size of this
section. My naive approch was :

extern void *_eeprom;
char eeprom_shadow[(int)&_eeprom_end];

This fails miserably, ofcourse : the compiler doesn't know the address of
__eeprom before the linker is done, so it can not declare the array.

Is there a trick to allocate the memory for this array at compile time ? I'd
rather not use malloc() and friends, since I am working on a platform with a
very small amount of memory, and don't like using dynamic memory here.

You have a fundamental chicken-or-the-egg problem here. A change
in the size of the array can change the size of the code (because,
for example, instructions can have short or long offsets), which
can change the size of the .eeprom section, which can change the
size of the array, which can change the size of the code AGAIN,
which can change the size of the .eeprom section AGAIN, ad nauseum.

Gordon L. Burditt

Hi Gordon,

Yes, this would be a problem if my the rest of my code would change anything
to the .eeprom section. This is not the case however, since I specifically
declare some variables with attributes to place them in the .eeprom section,
and no other data will go there. (The rest is in the usual places, .text,
..data, .bss)
 
S

Skarmander

Hello,

I am running my code on an embedded platform without OS. I have defined some
data in a section called .eeprom. The section is defined by the linker
script and starts at address zero. The symbol __eeprom_end is defined by the
linker script as well, and lies at the end of this section. The address of
__eeprom_end is thus equal to the number of bytes in the .eeprom section.

My problem : I want to declare an array in .bss with the same size of this
section. My naive approch was :

extern void *_eeprom;
char eeprom_shadow[(int)&_eeprom_end];

This fails miserably, ofcourse : the compiler doesn't know the address of
__eeprom before the linker is done, so it can not declare the array.

Is there a trick to allocate the memory for this array at compile time ?

Your identifiers are all over each other. Is _eeprom the address of the
section .eeprom? Is _eeprom_end a typo or intended to be the same as
__eeprom_end? What is __eeprom with two underscores?

In any case, as you say, all this information is available at link time.
There is simply no way to turn these symbols or their addresses into
compile-time constants if you don't already have the information available,
and global array sizes must be compile-time constants.

Any reason why you can't have the linker declare a section .eeprom_shadow of
equal size and use the address of that? Indexing would work the same; the
only restriction is that you still don't know the size at compile time, but
that shouldn't be too much of a problem, since you'd have __eeprom_end (or
_eeprom_end) available at runtime.

S.
 
U

usenet

Skarmander said:
Hello,

I am running my code on an embedded platform without OS. I have defined some
data in a section called .eeprom. The section is defined by the linker
script and starts at address zero. The symbol __eeprom_end is defined by the
linker script as well, and lies at the end of this section. The address of
__eeprom_end is thus equal to the number of bytes in the .eeprom section.

My problem : I want to declare an array in .bss with the same size of this
section. My naive approch was :

extern void *_eeprom;
char eeprom_shadow[(int)&_eeprom_end];

This fails miserably, ofcourse : the compiler doesn't know the address of
__eeprom before the linker is done, so it can not declare the array.

Is there a trick to allocate the memory for this array at compile time ?

Your identifiers are all over each other. Is _eeprom the address of the
section .eeprom? Is _eeprom_end a typo or intended to be the same as
__eeprom_end? What is __eeprom with two underscores?

Yes, definitely all over eachother, very confusing, I'm sorry. It should
read '__eeprom_end' everywhere.
Any reason why you can't have the linker declare a section .eeprom_shadow of
equal size and use the address of that? Indexing would work the same; the
only restriction is that you still don't know the size at compile time, but
that shouldn't be too much of a problem, since you'd have __eeprom_end (or
_eeprom_end) available at runtime.

Yes, having the linker create another section should work ofcourse, thanks
for the hint,
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top