Equivalent macro for "__attribute__" in Visual studio

Hi Experts,

I am working on porting device driver from linux to windows. During the porting efforts I could see attributes macro used. I want to know equivalent macro to achieve it in Visual studio with WDK build environment.

#pragma pack, we could not generate #pragma commands from a macro. Expecting your valuable inputs.

Regards,
Suresh.S

The __pragma() keyword provides a way to put #pragma directives in macros.

See https://msdn.microsoft.com/en-GB/library/d9x1s805.aspx

I am working on porting device driver from linux to windows. During the
porting efforts I could see attributes macro used. I want to know
equivalent macro to achieve it in Visual studio with WDK build
environment.

#pragma pack, we could not generate #pragma commands from a macro.
Expecting your valuable inputs.

Hi David,

Thanks for your valuable input, please see my below input and give me suggestion.

define PACKED_ALIGN attribute((aligned(8),packed)) // gcc compiler

struct csr_config {
u32 major_ver;
u32 minor_ver;
u64 request;
u64 response;
u16 extent_rsp;
u16 extent_req;
u32 entries;
struct pmmu_cntx mmu_cntx;
u64 noname : 55;
u64 fast_spin : 1;
u64 link_connect : 1;
u64 enable_f_smp : 1;
u64 cb_exact : 1;
u64 big_endian : 1;
u64 clean_state : 1;
enum csr_atomic_op atomic_support :2;
u64 pages : 1;
} PACKED_ALIGN; /* struct csr_config [48 byte] */

In linux the size of csr_config is - 48 bytes. When trying with windows visual studio it is -80 bytes. How to achieve the alignment and pack in visual studio 2013 with WDK.
I tried #pragma pack(push,1) and still i am not getting 48 bytes size.

Regards,
Suresh.S

> define PACKED_ALIGN attribute((aligned(8),packed)) // gcc

compiler

struct csr_config {
u32 major_ver;
u32 minor_ver;
u64 request;
u64 response;
u16 extent_rsp;
u16 extent_req;
u32 entries;
struct pmmu_cntx mmu_cntx;
u64 noname : 55;
u64 fast_spin : 1;
u64 link_connect : 1;
u64 enable_f_smp : 1;
u64 cb_exact : 1;
u64 big_endian : 1;
u64 clean_state : 1;
enum csr_atomic_op atomic_support :2;
u64 pages : 1;
} PACKED_ALIGN; /* struct csr_config [48 byte] */

In linux the size of csr_config is - 48 bytes. When trying with windows
visual studio it is -80 bytes. How to achieve the alignment and pack in
visual studio 2013 with WDK.
I tried #pragma pack(push,1) and still i am not getting 48 bytes size.

Regards,
Suresh.S

It’s not clear what sizeof(struct pmmu_cntx) is, although the p suggests it contains a pointer type, so on a 64-bit system that would be 8, bringing the total up to 40 bytes assuming pack(1) or pack(2).

This would leave the remaining 8 bytes you are looking for to be the bit-field types which follow.

The question of using bit fields and packing was discussed on this list last week; rather than repeat the advice given there, I suggest you look at it for yourself, perhaps starting with https://www.osronline.com/showthread.cfm?link=275955#T8

Making the following changes to your source gives me a size of 48 bytes.

//Probably your types
typedef unsigned int u32;
typedef unsigned __int64 u64;
typedef unsigned short u16;

//Disable packing
#pragma pack(push, r1, 1)

//I’m assuming this since it was not specified
struct pmmu_cntx
{
u64 v;
};

struct csr_config
{
u32 major_ver;
u32 minor_ver;
u64 request;
u64 response;
u16 extent_rsp;
u16 extent_req;
u32 entries;

struct pmmu_cntx mmu_cntx;

u64 noname : 55;
u64 fast_spin : 1;
u64 link_connect : 1;
u64 enable_f_smp : 1;
u64 cb_exact : 1;
u64 big_endian : 1;
u64 clean_state : 1;

//enum csr_atomic_op atomic_support :2;
u64 atomic_support : 2;

u64 pages : 1;
};

#pragma pack(pop, r1)

int main()
{
unsigned long long x = sizeof(csr_config);
}

Hi Jason,

Thanks for your support,
Please find the structure of pmmu_cntx.

struct pmmu_cntx {
u64 table_level : 3;
u64 wr_access : 1;
enum page_size page_size :4;
enum mmu_translation translation_type :3;
u64 th : 1;
u64 table_ptr : 40;
u64 ro : 1;
u64 tph : 2;
u64 ns : 1;
u64 st : 8;
}PACKED_ALIGNED; /* struct mmu_cntx [8 byte] */

This structure pmmu_cntx size is 8 byte in GCC compiler, but in visual studio it is 20 bytes. After i added your changes still i am getting 60 bytes for csr_config. could you please explain and let me know how i can achieve it.

Regards,
Suresh.S

//Probably your types
typedef unsigned int u32;
typedef unsigned __int64 u64;
typedef unsigned short u16;

//Disable packing
#pragma pack(push, r1, 1)

struct pmmu_cntx
{
u64 table_level : 3;
u64 wr_access : 1;

u64 page_size : 4;
//enum page_size page_size :4;

u64 translation_type : 3;
//enum mmu_translation translation_type :3;

u64 th : 1;
u64 table_ptr :40;
u64 ro : 1;
u64 tph : 2;
u64 ns : 1;
u64 st : 8;
};/* struct mmu_cntx [8 byte] */

struct csr_config
{
u32 major_ver;
u32 minor_ver;
u64 request;
u64 response;
u16 extent_rsp;
u16 extent_req;
u32 entries;

struct pmmu_cntx mmu_cntx;

u64 noname : 55;
u64 fast_spin : 1;
u64 link_connect : 1;
u64 enable_f_smp : 1;
u64 cb_exact : 1;
u64 big_endian : 1;
u64 clean_state : 1;

//enum csr_atomic_op atomic_support :2;
u64 atomic_support : 2;

u64 pages : 1;
};

This will give you 48 bytes. If you want to know why read the link David posted.
J

xxxxx@gmail.com wrote:

Thanks for your support,
Please find the structure of pmmu_cntx.

struct pmmu_cntx {
u64 table_level : 3;
u64 wr_access : 1;
enum page_size page_size :4;
enum mmu_translation translation_type :3;
u64 th : 1;
u64 table_ptr : 40;
u64 ro : 1;
u64 tph : 2;
u64 ns : 1;
u64 st : 8;
}PACKED_ALIGNED; /* struct mmu_cntx [8 byte] */

This structure pmmu_cntx size is 8 byte in GCC compiler, but in visual studio it is 20 bytes. After i added your changes still i am getting 60 bytes for csr_config. could you please explain and let me know how i can achieve it.

You have now had two different people explain this to you. In fact, I
explained this EXACT example. Are you unable to understand the answer?

The C standard does not allow “enum” in a bitfield. Thus, the behavior
is not defined in the spec, and you cannot predict what a compiler will
do. Visual C++ happens to choose difference packing rules than GCC, and
it is entirely allowed to do that.

If you need perfect packing, then you CANNOT use “enums” in a bitfield.
It’s just that simple. Replace the “enum” with u64.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

xxxxx@gmail.com wrote:

struct csr_config {

u64 big_endian : 1;
u64 clean_state : 1;
enum csr_atomic_op atomic_support :2;
u64 pages : 1;
} PACKED_ALIGN; /* struct csr_config [48 byte] */

In linux the size of csr_config is - 48 bytes. When trying with windows visual studio it is -80 bytes. How to achieve the alignment and pack in visual studio 2013 with WDK.
I tried #pragma pack(push,1) and still i am not getting 48 bytes size.

Right, because as I said, Visual C++ uses different packing rules for
the “enum”, and that’s not controlled by pragmas. Use “u64” and it will
work.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.