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.
IIRC the x86 (16bit edition) supports these attributes on those places so these are all target problems.
Maybe we should close this. If someone is interested on this, they should fill bugs against specific targets.
4 years old, no activity, unconfirmed. Please fill bugs for specific targets with testcases so the target maintainers are aware of this issue.