Page 1 of 2

gcc packed structs?

Posted: Sun Mar 28, 2004 11:36 pm
by stonedzealot
I'm converting my IDT entries into C structs but because GCC pads all of the struct's members to be integer aligned, it obviously won't work. I remember mr. xsism doing an IDT in C that had a struct in it for an IDT entry but can't find the code or the posts here. I've also heard that GCC ignores __attribute__((packed)) for structs, so how should you write a struct for an IDT without all of the padding?

Re:gcc packed structs?

Posted: Mon Mar 29, 2004 2:36 am
by Pype.Clicker
never heard such a thing about packed ignored... do you have quotes about this ?

Re:gcc packed structs?

Posted: Mon Mar 29, 2004 6:42 am
by stonedzealot
other than Mr. A said so in forum X, no, but I can give an example from my code...

upon defining an idtentry as

struct idtentry
{
short offset015;
short selector;
char alwayszero;
char type;
short offset1631;
} __attribute__((packed))

I set all of the above to solid FFs and the memory I read it into reads

FFFFFFFF
FF00FF00
FFFF0000

so it seems to be short aligned, instead of packed...

Re:gcc packed structs?

Posted: Mon Mar 29, 2004 6:46 am
by Therx
what do you get if you do sizeof(idtentry)

Pete

Re:gcc packed structs?

Posted: Mon Mar 29, 2004 7:32 am
by Pype.Clicker
i tend to use 'bitfields' for such cases :

Code: Select all

struct ia32_gateDescriptor{
  unsigned int offset_lo:16; //!< target offset (bits 0..15)
  unsigned int selector:16;  //!< target segment selector
  int :8;
  unsigned int type:5; //!< gate type
  /*!< \see ia32_descrtype */
  unsigned int dpl:2; //!< requested priviledge level to access
  unsigned int present:1; 
  unsigned int offset_hi:16; //!< target offset (bits 16..31)
}; 
worked quite fine, at least when optimizations are turned on ...

Translating "Kernighan & Ritchie 'Le Langage C -- Norme Ansi' " from French to English:
Bitfields (...) are interpreted as [tt]int[/tt] type which length is given. Adjacent fields in a structure are grouped in memory units depending on the implementation in an implementation-dependant order. When a field following another doesn't fit a partially filled memory unit, it *may* be split between two memory units, or the memory unit *may* be zero-filled

An unnamed field with a 0 width enforces that memory-unit filling so that the next field starts on the next memory unit.
Everything i've seen so far tends to prove that on GCC, for IA-32 platforms, the 'memory unit' is a 32bits word and the order is the 'natural' least-significant bits first.

Re:gcc packed structs?

Posted: Mon Mar 29, 2004 7:36 am
by Candy
Pype.Clicker wrote:

Code: Select all

  int :8;
Is that valid? a piece of padding (?) without name?
Everything i've seen so far tends to prove that on GCC, for IA-32 platforms, the 'memory unit' is a 32bits word and the order is the 'natural' least-significant bits first.
AFAIK, if you make a bitfield of short ints, it should be 16-bit memory units. For chars, 8-bit memory units, for long longs make that 64-bit memory units. Not sure about anything though, but thought it was.

Re:gcc packed structs?

Posted: Mon Mar 29, 2004 7:50 am
by Pype.Clicker
Candy wrote: Is that valid? a piece of padding (?) without name?
absolutely valid.
AFAIK, if you make a bitfield of short ints, it should be 16-bit memory units. For chars, 8-bit memory units, for long longs make that 64-bit memory units. Not sure about anything though, but thought it was.
i don't see anything like that in my book. It says bitfield are of int, signed int or unsigned int ...

Re:gcc packed structs?

Posted: Mon Mar 29, 2004 12:41 pm
by Neo
wangpeng wrote: ... but I can give an example from my code...

upon defining an idtentry as

struct idtentry
{
short offset015;
short selector;
char alwayszero;
char type;
short offset1631;
} __attribute__((packed))
err... sorry if this sounds stupid but there seems to be no semi-colon at the end of the struct. (or is that a typo here)

Re:gcc packed structs?

Posted: Mon Mar 29, 2004 12:45 pm
by Therx
it wouldn't compile with out the ; so it must be a typo

Pete

Re:gcc packed structs?

Posted: Mon Mar 29, 2004 1:05 pm
by Neo
Pete wrote: it wouldn't compile with out the ; so it must be a typo

Pete
No just try this out with "gcc file.c" and execute it (it worked for me in windows)

Code: Select all

#include<stdio.h>
struct ab{
 int a,b,c;
}

main()
{
printf("hello");
}
<edit>
the problem here i think is that the compiler thinks the return type of the function is the struct declared before it. (is this right?)
</edit>

Re:gcc packed structs?

Posted: Mon Mar 29, 2004 1:20 pm
by Candy
Neo wrote: the problem here i think is that the compiler thinks the return type of the function is the struct declared before it. (is this right?)
that's not a problem, that's by design. End all class definitions, type definitions, struct definitions etc. with a semicolon. If you don't know whether one has to be there, place it anyway. Too much doesn't hurt (usually...). Too little does.

Re:gcc packed structs?

Posted: Mon Mar 29, 2004 1:48 pm
by uri
from the gcc manual:

Code: Select all

The packed attribute specifies that a variable or structure field should have the smallest possible alignment--one byte for a variable, and one bit for a field, unless you specify a larger value with the aligned attribute.

Here is a structure in which the field x is packed, so that it immediately follows a:

struct foo
{
  char a;
  int x[2] __attribute__ ((packed));
};
...as I read it, the "attribute" has to be applied to every member variable of the structure. I've written a small test program to confirm this:

Code: Select all

#include <stdio.h>

typedef struct
{
  int a;
  short b;
  char c;
} t1 __attribute__ ((packed));

typedef struct
{
  int a   __attribute__ ((packed));
  short b __attribute__ ((packed));
  char c  __attribute__ ((packed));
} t2;

t1 var1;
t2 var2;


int main(void)
{
  printf("%d\n%d\n", sizeof(var1), sizeof(var2));
  return 0;
}
On my machine (DJGPP, gcc 3.3.1) the output is:

Code: Select all

8
7
...so at least it works for me :)


-uri

Re:gcc packed structs?

Posted: Mon Mar 29, 2004 3:10 pm
by proxy
there is another option which i find to be a lot more intuative :)

use the gcc pragmas like so:

Code: Select all

#pragma pack (push, 1) 
class DescTable {
public:
   uint16 size;
   uint32 offset;
};
#pragma pack(pop)

Code: Select all

sizeof(DescTable)
will yeild 6 in this case, as it should :)

proxy

Re:gcc packed structs?

Posted: Mon Mar 29, 2004 4:06 pm
by stonedzealot
Hi again, all. Sorry I haven't been more participant but I've been busy with other engagements (like finishing high school).

@Neo: Yep, that was a typo, writing it this morning as my carpool drove up, didn't really check for syntax.

@Pype: Interesting, I've never heard of bitfields and they look very nice (I don't like the idea of putting __attribute__((packed)) next to all of the members of the struct, to be honest) , but wouldn't turning on optimizations...well...I wonder, I'll do a little testing.

@uri: I didn't find that in the GCC manual...perhaps I need to take another look. Maybe GCC just...stopped applying the __attribute__s to the entire struct if it's defined at the end?

@proxy: I heard that pragmas were a little unpredicatable when it came to portability between compilers, but again, I dunno firsthand.

Thanks for the suggestions.

Re:gcc packed structs?

Posted: Mon Mar 29, 2004 4:34 pm
by proxy
@proxy: I heard that pragmas were a little unpredicatable when it came to portability between compilers, but again, I dunno firsthand.
well of course they are :), that's the definition of a pragma, a compiler dependant directive...but the __atribute__ stuff will break and simply not compile on non-gcc, the pragmas stand a change of likely being ignored by another compiler..

besides, if this is a toy OS, are you that likely to switch compilers?

proxy