[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