[PATCH v2 16/16] packed: add support for __packed struct

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Currently, the attribute 'packed' is ignored
---
 parse.c                       |  5 ++++-
 symbol.c                      | 12 +++++++++---
 symbol.h                      |  1 +
 validation/packed-bitfield0.c |  1 -
 validation/packed-bitfield1.c |  1 -
 validation/packed-bitfield2.c |  1 -
 validation/packed-bitfield5.c |  1 -
 validation/packed-deref0.c    |  1 -
 validation/packed-struct.c    |  1 -
 9 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/parse.c b/parse.c
index 0fd2bb473a47..42e48620bd5e 100644
--- a/parse.c
+++ b/parse.c
@@ -764,6 +764,7 @@ static struct token *struct_union_enum_specifier(enum type type,
 	attr.ctype.base_type = sym;
 	token = handle_attributes(token, &attr);
 	apply_ctype(token->pos, &sym->ctype, &attr.ctype);
+	sym->packed = attr.packed;
 
 	// Mark the structure as needing re-examination
 	sym->examined = 0;
@@ -1088,8 +1089,10 @@ static struct token *ignore_attribute(struct token *token, struct symbol *attr,
 
 static struct token *attribute_packed(struct token *token, struct symbol *attr, struct decl_state *ctx)
 {
-	if (!ctx->ctype.alignment)
+	if (!ctx->ctype.alignment) {
 		ctx->ctype.alignment = 1;
+		ctx->packed = 1;
+	}
 	return token;
 }
 
diff --git a/symbol.c b/symbol.c
index 1a083fb8432c..aa02c8c5ad80 100644
--- a/symbol.c
+++ b/symbol.c
@@ -88,6 +88,7 @@ struct struct_union_info {
 	unsigned long bit_size;
 	int align_size;
 	char has_flex_array;
+	bool packed;
 	struct symbol *flex_array;
 };
 
@@ -120,6 +121,7 @@ static int bitfield_base_size(struct symbol *sym)
 static void lay_out_struct(struct symbol *sym, struct struct_union_info *info)
 {
 	unsigned long bit_size, align_bit_mask;
+	unsigned long alignment;
 	int base_size;
 
 	bit_size = info->bit_size;
@@ -136,7 +138,8 @@ static void lay_out_struct(struct symbol *sym, struct struct_union_info *info)
 		info->flex_array = sym;
 	}
 
-	align_bit_mask = bytes_to_bits(sym->ctype.alignment) - 1;
+	alignment = info->packed ? 1 : sym->ctype.alignment;
+	align_bit_mask = bytes_to_bits(alignment) - 1;
 
 	/*
 	 * Bitfields have some very special rules..
@@ -147,7 +150,7 @@ static void lay_out_struct(struct symbol *sym, struct struct_union_info *info)
 		// Zero-width fields just fill up the unit.
 		int width = base_size ? : (bit_offset ? room : 0);
 
-		if (width > room) {
+		if (width > room && !info->packed) {
 			bit_size = (bit_size + align_bit_mask) & ~align_bit_mask;
 			bit_offset = 0;
 		}
@@ -157,6 +160,8 @@ static void lay_out_struct(struct symbol *sym, struct struct_union_info *info)
 		info->bit_size = bit_size + width;
 		// warning (sym->pos, "bitfield: offset=%d:%d  size=:%d", sym->offset, sym->bit_offset, width);
 
+		if (info->packed && sym->type == SYM_NODE)
+			sym->packed = 1;
 		return;
 	}
 
@@ -173,6 +178,7 @@ static void lay_out_struct(struct symbol *sym, struct struct_union_info *info)
 static struct symbol * examine_struct_union_type(struct symbol *sym, int advance)
 {
 	struct struct_union_info info = {
+		.packed = sym->packed,
 		.max_align = 1,
 		.bit_size = 0,
 		.align_size = 1
@@ -191,7 +197,7 @@ static struct symbol * examine_struct_union_type(struct symbol *sym, int advance
 			sparse_error(info.flex_array->pos, "flexible array member '%s' is not last", show_ident(info.flex_array->ident));
 		examine_symbol_type(member);
 
-		if (member->ctype.alignment > info.max_align) {
+		if (member->ctype.alignment > info.max_align && !sym->packed) {
 			// Unnamed bitfields do not affect alignment.
 			if (member->ident || !is_bitfield_type(member))
 				info.max_align = member->ctype.alignment;
diff --git a/symbol.h b/symbol.h
index 866d57522f49..15b21452c934 100644
--- a/symbol.h
+++ b/symbol.h
@@ -112,6 +112,7 @@ struct decl_state {
 	unsigned char prefer_abstract;
 	unsigned char autotype;
 	unsigned char forced;
+	unsigned char packed;
 };
 
 struct pseudo;
diff --git a/validation/packed-bitfield0.c b/validation/packed-bitfield0.c
index 907500dedbf0..6d92fb2862eb 100644
--- a/validation/packed-bitfield0.c
+++ b/validation/packed-bitfield0.c
@@ -63,5 +63,4 @@ int main(void)
 
 /*
  * check-name: packed-bitfield0
- * check-known-to-fail
  */
diff --git a/validation/packed-bitfield1.c b/validation/packed-bitfield1.c
index 208a3dc5127c..b7b575ce6922 100644
--- a/validation/packed-bitfield1.c
+++ b/validation/packed-bitfield1.c
@@ -24,5 +24,4 @@ static int foo(struct s *ptr)
 
 /*
  * check-name: packed-bitfield1
- * check-known-to-fail
  */
diff --git a/validation/packed-bitfield2.c b/validation/packed-bitfield2.c
index 4587ebec5c90..244204c2dd35 100644
--- a/validation/packed-bitfield2.c
+++ b/validation/packed-bitfield2.c
@@ -12,5 +12,4 @@ _Static_assert(sizeof(struct bf2) == 8);
 
 /*
  * check-name: packed-bitfield2
- * check-known-to-fail
  */
diff --git a/validation/packed-bitfield5.c b/validation/packed-bitfield5.c
index 8f44d4c2c277..87dbf9c221a1 100644
--- a/validation/packed-bitfield5.c
+++ b/validation/packed-bitfield5.c
@@ -17,5 +17,4 @@ static int ld(struct s *s)
 /*
  * check-name: packed-bitfield5
  * check-description: is check_access() OK with 'overlapping' packed bitfields?
- * check-known-to-fail
  */
diff --git a/validation/packed-deref0.c b/validation/packed-deref0.c
index 865ad68a4f37..d48ad1ac7505 100644
--- a/validation/packed-deref0.c
+++ b/validation/packed-deref0.c
@@ -20,5 +20,4 @@ static void bar(obj_t o)
 
 /*
  * check-name: packed-deref0
- * check-known-to-fail
  */
diff --git a/validation/packed-struct.c b/validation/packed-struct.c
index 5039be4d0b45..253750063ffd 100644
--- a/validation/packed-struct.c
+++ b/validation/packed-struct.c
@@ -29,5 +29,4 @@ _Static_assert(   sizeof(struct c) == 6, "size struct");
 
 /*
  * check-name: packed-struct
- * check-known-to-fail
  */
-- 
2.29.2




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux