diff options
author | Dima Kogan <dima@secretsauce.net> | 2014-04-23 00:02:34 -0700 |
---|---|---|
committer | Chanho Park <chanho61.park@samsung.com> | 2014-08-22 20:38:25 +0900 |
commit | 600771876d503cc648fbcf9078d3c439779fd9eb (patch) | |
tree | 75d2f6efa0e8e7b57d698d6edd95e6763779e685 | |
parent | 8b526570440a2a1a8eff9c9991bf5ba103f829e4 (diff) | |
download | ltrace-600771876d503cc648fbcf9078d3c439779fd9eb.tar.gz ltrace-600771876d503cc648fbcf9078d3c439779fd9eb.tar.bz2 ltrace-600771876d503cc648fbcf9078d3c439779fd9eb.zip |
enums are no longer assumed to have type 'int'
-rw-r--r-- | dwarf_prototypes.c | 58 |
1 files changed, 40 insertions, 18 deletions
diff --git a/dwarf_prototypes.c b/dwarf_prototypes.c index 936d94f..0ab05b8 100644 --- a/dwarf_prototypes.c +++ b/dwarf_prototypes.c @@ -192,6 +192,30 @@ static bool get_die_numeric(uint64_t* result, #undef PROCESS_NUMERIC } +static bool get_integer_base_type( enum arg_type* type, int byte_size, bool is_signed ) +{ + switch (byte_size) { + case sizeof(char): + *type = ARGTYPE_CHAR; + return true; + + case sizeof(short): + *type = is_signed ? ARGTYPE_SHORT : ARGTYPE_USHORT; + return true; + + case sizeof(int): + *type = is_signed ? ARGTYPE_INT : ARGTYPE_UINT; + return true; + + case sizeof(long): + *type = is_signed ? ARGTYPE_LONG : ARGTYPE_ULONG; + return true; + + default: + return false; + } +} + static enum arg_type get_base_type(Dwarf_Die* die) { int64_t encoding; @@ -214,23 +238,12 @@ static enum arg_type get_base_type(Dwarf_Die* die) bool is_signed = (encoding == DW_ATE_signed); - switch (byte_size) { - case sizeof(char): - return ARGTYPE_CHAR; - - case sizeof(short): - return is_signed ? ARGTYPE_SHORT : ARGTYPE_USHORT; - - case sizeof(int): - return is_signed ? ARGTYPE_INT : ARGTYPE_UINT; - - case sizeof(long): - return is_signed ? ARGTYPE_LONG : ARGTYPE_ULONG; - - default: - complain(die, ""); - exit(1); + enum arg_type type; + if(!get_integer_base_type(&type, (int)byte_size, is_signed)) { + complain(die, "Unknown integer base type. Using 'void'"); + return ARGTYPE_VOID; } + return type; } if (encoding == DW_ATE_float) { @@ -289,7 +302,16 @@ static int dwarf_die_eq(const void* a, const void* b) static bool get_enum(struct arg_type_info* enum_info, Dwarf_Die* parent) { - enum_info->type = ARGTYPE_INT; + uint64_t byte_size; + if (!get_die_numeric(&byte_size, parent, DW_AT_byte_size)) { + // No byte size given, assume 'int' + enum_info->type = ARGTYPE_INT; + } else { + if(!get_integer_base_type(&enum_info->type, (int)byte_size, true)) { + complain(parent, "Unknown integer base type. Using 'int'"); + enum_info->type = ARGTYPE_INT; + } + } struct enum_lens *lens = calloc(1, sizeof(struct enum_lens)); if (lens == NULL) { @@ -336,7 +358,7 @@ static bool get_enum(struct arg_type_info* enum_info, Dwarf_Die* parent) return false; } - value_init_detached(value, NULL, type_get_simple( ARGTYPE_INT ), 0); + value_init_detached(value, NULL, type_get_simple( enum_info->type ), 0); uint64_t enum_value; if (!get_die_numeric(&enum_value, &die, DW_AT_const_value)) { complain(&die, "Couldn't get enum value"); |