ctf_loader: One more attempt at handling packed enums

With this a "make allyesconfig" on a 2.6.29-rc8 Linux kernel build left 16
cases flagged by ctfdwdiff, 8 unique ones, out of 6209 single-cu (compile unit)
.o files.

But what this clearly shows is that we really need to detect if a struct is
packed, and wether it is naturally packed or if __attribute__ packed was used,
that way we will have more clues as to if a enum is packed or if the whole
struct where it is used as a type for a/several member(s) is packed.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Arnaldo Carvalho de Melo 2009-03-22 15:02:33 -03:00
parent c1d567f047
commit 23df52c620
3 changed files with 34 additions and 20 deletions

View File

@ -800,24 +800,30 @@ static int class__fixup_ctf_bitfields(struct tag *self, struct cu *cu)
pos->bitfield_size = 0;
pos->byte_offset = pos->bit_offset / 8;
if (type->tag != DW_TAG_base_type &&
!tag__is_enumeration(type)) {
uint16_t type_bit_size;
size_t integral_bit_size;
switch (type->tag) {
case DW_TAG_enumeration_type:
type_bit_size = tag__type(type)->size;
/* Best we can do to check if this is a packed enum */
if (is_power_of_2(type_bit_size))
integral_bit_size = roundup(type_bit_size, 8);
else
integral_bit_size = sizeof(int) * 8;
break;
case DW_TAG_base_type: {
struct base_type *bt = tag__base_type(type);
type_bit_size = bt->bit_size;
integral_bit_size = base_type__name_to_size(bt, cu);
}
break;
default:
pos->byte_size = tag__size(type, cu);
pos->bit_size = pos->byte_size * 8;
continue;
}
uint16_t type_bit_size;
size_t integral_bit_size;
if (tag__is_enumeration(type)) {
type_bit_size = tag__type(type)->size;
integral_bit_size = sizeof(int) * 8; /* FIXME: always this size? */
} else {
struct base_type *bt = tag__base_type(type);
type_bit_size = bt->bit_size;
integral_bit_size = base_type__name_to_size(bt, cu);
}
/*
* XXX: integral_bit_size can be zero if base_type__name_to_size doesn't
* know about the base_type name, so one has to add there when

20
dutil.h
View File

@ -1,12 +1,15 @@
#ifndef _DUTIL_H_
#define _DUTIL_H_ 1
/*
Copyright (C) 2007 Arnaldo Carvalho de Melo <acme@redhat.com>
This program is free software; you can redistribute it and/or modify it
under the terms of version 2 of the GNU General Public License as
published by the Free Software Foundation.
*/
* Copyright (C) 2007..2009 Arnaldo Carvalho de Melo <acme@redhat.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* Some functions came from the Linux Kernel sources, copyrighted by a
* cast of dozens, please see the Linux Kernel git history for details.
*/
#include <stdbool.h>
#include <stddef.h>
@ -21,6 +24,11 @@
#define roundup(x,y) ((((x) + ((y) - 1)) / (y)) * (y))
static inline __attribute__((const)) bool is_power_of_2(unsigned long n)
{
return (n != 0 && ((n & (n - 1)) == 0));
}
/* We need define two variables, argp_program_version_hook and
argp_program_bug_address, in all programs. argp.h declares these
variables as non-const (which is correct in general). But we can

View File

@ -41,7 +41,7 @@ static void emit_tag(struct tag *self, uint32_t tag_id, struct cu *cu)
putchar('\n');
lexblock__fprintf(&fn->lexblock, cu, fn, 0, stdout);
}
puts("\n");
printf(" size: %zd\n\n", tag__size(self, cu));
}
static int cu__emit_tags(struct cu *self, void *cookie __unused)