🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.help
Article #52198

Re: How to pack fields in struct?

#52198
From: James Tsillas
Date: Mon, 18 Jan 1993 14:52
263 lines
9023 bytes
I'm not sure why this is not part of the standard gcc but there is code
in there to implement #pragma pack(). The following was copied from a
implementation done for another target. Basically you need do:

*** i386.c~     Thu Nov 12 08:29:28 1992
--- i386.c      Mon Jan  4 17:12:54 1993
***************
*** 1832,1834 ****
--- 1832,2006 ----
      }
    RET;
  }
+ 
+ 
+ #ifdef HANDLE_PRAGMA
+ 
+ /* When structure field packing is in effect, this variable is the
+    number of bits to use as the maximum alignment.  When packing is
not
+    in effect, this is zero. */
+ 
+ int maximum_field_alignment = 0;
+ 
+ /* Handle a pragma directive.  HANDLE_PRAGMA conspires to parse the
+    input following #pragma into tokens based on yylex.  TOKEN is the
+    current token, and STRING is its printable form.  */
+ 
+ void
+ handle_pragma_token (string, token)
+      char *string;
+      tree token;
+ {
+   static enum pragma_state
+     {
+       ps_start,
+       ps_done,
+       ps_bad,
+       ps_weak,
+       ps_name,
+       ps_equals,
+       ps_value,
+       ps_pack,
+       ps_left,
+       ps_align,
+       ps_right
+       } state = ps_start, type;
+   static char *name;
+   static char *value;
+   static int align;
+ 
+   if (string == 0)
+     {
+       if (type == ps_pack)
+       {
+         if (state == ps_right)
+           maximum_field_alignment = align * 8;
+         else
+           warning ("ignoring malformed #pragma pack( [ 1 | 2 | 4 ]
)");
+       }
+ #ifdef WEAK_ASM_OP
+       else if (type == ps_weak)
+       {
+         if (state == ps_name || state == ps_value)
+           {
+             fprintf (asm_out_file, "\t%s\t", WEAK_ASM_OP);
+             ASM_OUTPUT_LABELREF (asm_out_file, name);
+             fputc ('\n', asm_out_file);
+             if (state == ps_value)
+               {
+                 fprintf (asm_out_file, "\t%s\t", SET_ASM_OP);
+                 ASM_OUTPUT_LABELREF (asm_out_file, name);
+                 fputc (',', asm_out_file);
+                 ASM_OUTPUT_LABELREF (asm_out_file, value);
+                 fputc ('\n', asm_out_file);
+               }
+           }
+         else if (! (state == ps_done || state == ps_start))
+           warning ("ignoring malformed #pragma weak symbol [=value]");
+       }
+ #endif /* WEAK_ASM_OP */
+ 
+       type = state = ps_start;
+       return;
+     }
+ 
+   switch (state)
+     {
+     case ps_start:
+       if (token && TREE_CODE (token) == IDENTIFIER_NODE)
+       {
+         if (strcmp (IDENTIFIER_POINTER (token), "pack") == 0)
+           type = state = ps_pack;
+ #ifdef WEAK_ASM_OP
+         else if (strcmp (IDENTIFIER_POINTER (token), "weak") == 0)
+           type = state = ps_weak;
+ #endif
+         else
+           type = state = ps_done;
+       }
+       else
+       type = state = ps_done;
+       break;
+ 
+ #ifdef WEAK_ASM_OP
+     case ps_weak:
+       if (token && TREE_CODE (token) == IDENTIFIER_NODE)
+       {
+         name = IDENTIFIER_POINTER (token);
+         state = ps_name;
+       }
+       else
+       state = ps_bad;
+       break;
+ 
+     case ps_name:
+       state = (strcmp (string, "=") ? ps_bad : ps_equals);
+       break;
+ 
+     case ps_equals:
+       if (token && TREE_CODE (token) == IDENTIFIER_NODE)
+       {
+         value = IDENTIFIER_POINTER (token);
+         state = ps_value;
+       }
+       else
+       state = ps_bad;
+       break;
+ 
+     case ps_value:
+       state = ps_bad;
+       break;
+ #endif /* WEAK_ASM_OP */
+ 
+     case ps_pack:
+       if (strcmp (string, "(") == 0)
+       state = ps_left;
+       else
+       state = ps_bad;
+       break;
+ 
+     case ps_left:
+       if (token && TREE_CODE (token) == INTEGER_CST
+         && TREE_INT_CST_HIGH (token) == 0)
+       switch (TREE_INT_CST_LOW (token))
+         {
+         case 1:
+         case 2:
+         case 4:
+           align = TREE_INT_CST_LOW (token);
+           state = ps_align;
+           break;
+ 
+         default:
+           state = ps_bad;
+         }
+       else if (! token && strcmp (string, ")") == 0)
+       {
+         align = 0;
+         state = ps_right;
+       }
+       else
+       state = ps_bad;
+       break;
+ 
+     case ps_align:
+       if (strcmp (string, ")") == 0)
+       state = ps_right;
+       else
+       state = ps_bad;
+       break;
+ 
+     case ps_right:
+       state = ps_bad;
+       break;
+ 
+     case ps_bad:
+     case ps_done:
+       break;
+ 
+     default:
+       abort ();
+     }
+ }
+ #endif /* HANDLE_PRAGMA */
+ 

and add this to your machine .h:

/* Biggest alignment that any structure field can require on this
   machine, in bits.  If packing is in effect, this can be smaller than
   normal.  */

#define BIGGEST_FIELD_ALIGNMENT \
  (maximum_field_alignment ? maximum_field_alignment : 32)

extern int maximum_field_alignment;


/* Code to handle #pragma directives.  The interface is a bit messy,
   but there's no simpler way to do this while still using yylex.  */
#define HANDLE_PRAGMA(FILE)                                     \
  do {                                                          \
    while (c == ' ' || c == '\t')                               \
      c = getc (FILE);                                          \
    if (c == '\n' || c == EOF)                                  \
      {                                                         \
        handle_pragma_token (0, 0);                             \
        return c;                                               \
      }                                                         \
    ungetc (c, FILE);                                           \
    switch (yylex ())                                           \
      {                                                         \
      case IDENTIFIER:                                          \
      case TYPENAME:                                            \
      case STRING:                                              \
      case CONSTANT:                                            \
        handle_pragma_token (token_buffer, yylval.ttype);       \
        break;                                                  \
      default:                                                  \
        handle_pragma_token (token_buffer, 0);                  \
      }                                                         \
    if (nextchar >= 0)                                          \
      c = nextchar, nextchar = -1;                              \
    else                                                        \
      c = getc (FILE);                                          \
  } while (1)

Now I hope this doesn't break anything else in the 386 back end but we
have been using since 2.2.1 without any problems. No guarrantees.

-Jim.

re:
--
In article <C10y0y.G3n@aplcenmp.apl.jhu.edu> akbloom@aplcenmp.apl.jhu.edu (Keith Bloom) writes:

   Newsgroups: gnu.gcc.help
   Path: random.ccs.northeastern.edu!lynx!noc.near.net!uunet!haven.umd.edu!darwin.sura.net!aplcen.apl.jhu.edu!aplcenmp!akbloom
   From: akbloom@aplcenmp.apl.jhu.edu (Keith Bloom)
   Keywords: alignment
   Organization: The Johns Hopkins University
   Date: Mon, 18 Jan 1993 00:43:45 GMT
   Lines: 12


   I recently started to use gcc 2.2.2 under SCO Unix 3.2.  I need to
   pack structs; i.e., force alignment of fields on next available byte,
   rather than next multiple of two or four bytes.  After searching the
   man page and the gcc.info* files, and trying the __attribute__
   ((aligned(n))) syntax, BIGGEST_ALIGNMENT, and BIGGEST_FIELD_ALIGNMENT
   without success, I've been unable to find any facility in gcc to do
   this.  Would someone please help me out?


   Thanks,
   Keith
--
	***  James Tsillas  jtsilla@damon.ccs.northeastern.edu   ***
	***      Work: (508)898-2800, Home: (617)641-0513        ***
	***        "He is after me. Jim is after him."           ***
	***            - Hop on Pop, Dr. Seuss                   ***
Technical Details
Message-ID: <JTSILLA.93Jan18095238@damon.ccs.northeastern.edu>
Path: arc1-ca.pugleaf.net!sparky!uunet!noc.near.net!lynx!random.ccs.northeastern.edu!news
References: <C10y0y.G3n@aplcenmp.apl.jhu.edu>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 11318c,9731048cf1b76736
X-Google-Attributes: gid11318c,public
X-Google-ArrivalTime: 1993-01-19 02:17:06 PST
Newsgroups: gnu.gcc.help
Path: arc1-ca.pugleaf.net!sparky!uunet!noc.near.net!lynx!random.ccs.northeastern.edu!news
From: jtsilla@damon.ccs.northeastern.edu (James Tsillas)
Subject: Re: How to pack fields in struct?
In-Reply-To: akbloom@aplcenmp.apl.jhu.edu's message of Mon, 18 Jan 1993 00: 43:45 GMT
Message-ID: <JTSILLA.93Jan18095238@damon.ccs.northeastern.edu>
Sender: news@random.ccs.northeastern.edu
Nntp-Posting-Host: damon.ccs.northeastern.edu
Organization: Northeastern University, Boston, MA
References: <C10y0y.G3n@aplcenmp.apl.jhu.edu>
Date: Mon, 18 Jan 1993 14:52:38 GMT
Lines: 263