[Bug c/16894] New: far/section attributes on function parameters, typedefs, and literals
whitis at freelabs dot com
gcc-bugzilla@gcc.gnu.org
Fri Aug 6 08:23:00 GMT 2004
These bugs concern gcc's failure to accept memory space attributes (near, far,
and section) in several places:
- On parameters to functions
- on typedefs
- on string literals
gcc only takes near and far keywords on functions and severely
restricts use of data.
On many commercial compilers, one would just declare functions
like
printf(const char far *fmt, ....)
And the compler pass in a far address and would let compiler helper
functions do the work of retreiving the data. But on gcc variants,
this not only doesn't work but the obvious workarounds don't work either.
This applies particularly to the various 8 and 16 bit ports of gcc that are
mainly used for embedded use:
- 8086 16 bit address, 16 bit segment
- 8051 Harvard architecture
Synthetic 24/32 bit pointers used on commercial compiler
which, when used with compiler helper functions, allow
pointers that can point into either code space or data.
In addition, bank switching is used on some systems.
- 68HC11/12
Bank switching.
I am filling this as a bug against the main gcc since many gcc forks
have the same problem.
However, the near/far issues also apply to newer 64 bit processors. It would
be very wasteful to compile most applications with 64 bit pointers. Even for
some applications that have large data, it might be best to mix 32 and 64 bit
pointers if you have a few large data structures and the rest fall with
32 bit space (have to copy data before passing to 32 bit functions, though).
The 9S12DP256 single chip micro (68HC12 family) has the following memory
layout:
0000-03FFF Ram and registers
4000-7FFFF Fixed EEPROM
8000-BFFFF Window into 256K of bank switched EEPROM
C000-CFFFF Fixed EEPROM
Now, I am trying to port an application that has a lot of "const" data. It
won't fit comfortably in ram or the fixed windows (or will displace
things that really need to be there. In this particular case, memory
pressure can be relieved by moving two classes of const data into
bank switched memory:
- printf() format strings
= a single type of structure that describes a user settable parameter.
Other compilers have much better support for the near/far keyword. All 8086
compilers I have ever used, for example, allowed pointers, typedefs,
pointers passed to functions, etc. to by declared as "far".
#define far __attribute__((far))
#define FIXED_BANK0 __asttribute((section("fixed0")))
#define BANK30 __attribute((section("bank30")))
#define BAKK31 __attribute((section("bank31")))
char far *foo; // pointer to far data
char bank31 * bank 30 foo2;
// Pointer stored in bank 30 pointing to data in bank 31
void yyyprintf(char BANK30 *fmt, ...);
// Pass in 16 bit pointer only valid for bank30
char BANK30 fmt1[] = "hello, world");
yyyprintf(fmt1);
yyyprintf(BANK30 "hello, world\n");
in a pointer to the wrong section it won't
#define xxxprintf(fmt,...) emstdio_printf(copy_format(fmt), ##__VA_ARGS__);
// function itself must to be loaded in non-bank-switched section
// If you leave off tha attribute it will compile ok and might
// even work but there is no type checking so you could pass
// a pointer to the wrong bank.
FIXED_BANK char *copy_format(char __attribute__((section("bank30") *fmt)
{
static buf[256]; //in non-bank-switched-section
// switch banks
// In case relocation gets confused about high order bits and gives
// the lower 16 bits of linear address or the offset from the beginning
// of the bank instead of the address where data appears in bank window
fmt &= 0x3FFF;
fmt &= 0x8000;
memcpy(buf,fmt,sizeof(buf));
// restore bank
return(buf);
}
const char zot30[] __attribute__((section("bank30"))) = "Put me in Bank30\n";
void foo300()
{
xxxprintf("hello, world\n");
xxxprintf("hello, world %d\n",1);
xxxprintf("hello, world %d %d\n",1,2);
}
There should also be a __attribute__((section("void"))) or similar that
will mix with any other section, to be used similarly to void pointers
where you know what you are doing.
It would be nice to have a directive that allowed data to be placed
in specific sections by default
#pragma gcc section rodata bank30
// data the compiler would otherwise put in rodata goes in bank30
// instead.
#pragma gcc section text bank31
#pragma gcc section bss bank32
#pragma gcc section data bank33
Or better yet
pragma "gcc section text bank30" {
// all code here is affected
}
Yeah, I know what you can do in linker scripts. It is a poor substitute.
And the compiler should generate code to use compiler helper functions
to access far data on systems where the processor itself can't handle
them.
--
Summary: far/section attributes on function parameters, typedefs,
and literals
Product: gcc
Version: 3.2.2
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: whitis at freelabs dot com
CC: gcc-bugs at gcc dot gnu dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16894
More information about the Gcc-bugs
mailing list