summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDima Kogan <dima@secretsauce.net>2014-04-23 15:54:49 -0700
committerChanho Park <chanho61.park@samsung.com>2014-08-22 20:38:25 +0900
commit76c720d508ffff78fc3c68dccdb64be95ce5418a (patch)
tree087977b0b939b5ad94e7502e28461b9f58c0e8d1
parentfad4037112d06df8d0323d93cb9e2898c442bb3b (diff)
downloadltrace-76c720d508ffff78fc3c68dccdb64be95ce5418a.tar.gz
ltrace-76c720d508ffff78fc3c68dccdb64be95ce5418a.tar.bz2
ltrace-76c720d508ffff78fc3c68dccdb64be95ce5418a.zip
types defined in .conf files now take precedence over DWARF types
-rw-r--r--dwarf_prototypes.c43
1 files changed, 29 insertions, 14 deletions
diff --git a/dwarf_prototypes.c b/dwarf_prototypes.c
index cc60c2b..2960da3 100644
--- a/dwarf_prototypes.c
+++ b/dwarf_prototypes.c
@@ -49,7 +49,7 @@
static struct dict type_hash;
-static bool get_type(struct arg_type_info** info, Dwarf_Die* type_die);
+static bool get_type(struct arg_type_info** info, Dwarf_Die* type_die, struct protolib* plib);
#if 0
@@ -381,7 +381,7 @@ static bool get_enum(struct arg_type_info* enum_info, Dwarf_Die* parent)
return true;
}
-static bool get_array(struct arg_type_info* array_info, Dwarf_Die* parent)
+static bool get_array(struct arg_type_info* array_info, Dwarf_Die* parent, struct protolib* plib)
{
Dwarf_Die type_die;
if (!get_type_die(&type_die, parent)) {
@@ -390,7 +390,7 @@ static bool get_array(struct arg_type_info* array_info, Dwarf_Die* parent)
}
struct arg_type_info* info;
- if (!get_type(&info, &type_die)) {
+ if (!get_type(&info, &type_die, plib)) {
complain(parent, "Couldn't figure out array's type");
return false;
}
@@ -461,7 +461,7 @@ static bool get_array(struct arg_type_info* array_info, Dwarf_Die* parent)
return true;
}
-static bool get_structure(struct arg_type_info* struct_info, Dwarf_Die* parent)
+static bool get_structure(struct arg_type_info* struct_info, Dwarf_Die* parent, struct protolib* plib)
{
type_init_struct(struct_info);
@@ -486,7 +486,7 @@ static bool get_structure(struct arg_type_info* struct_info, Dwarf_Die* parent)
}
struct arg_type_info* member_info = NULL;
- if (!get_type(&member_info, &type_die)) {
+ if (!get_type(&member_info, &type_die, plib)) {
complain(&die, "Couldn't parse type from DWARF data");
return false;
}
@@ -500,7 +500,7 @@ static bool get_structure(struct arg_type_info* struct_info, Dwarf_Die* parent)
// Reads the type in the die into the given structure
// Returns true on sucess
-static bool get_type(struct arg_type_info** info, Dwarf_Die* type_die)
+static bool get_type(struct arg_type_info** info, Dwarf_Die* type_die, struct protolib* plib)
{
Dwarf_Off die_offset = dwarf_dieoffset(type_die);
struct arg_type_info** found_type = dict_find(&type_hash, &die_offset);
@@ -510,6 +510,21 @@ static bool get_type(struct arg_type_info** info, Dwarf_Die* type_die)
return true;
}
+ const char* type_name = dwarf_diename(type_die);
+ if (type_name != NULL) {
+
+ struct named_type* already_defined_type =
+ protolib_lookup_type(plib, type_name, false);
+
+ if (already_defined_type != NULL) {
+ complain(type_die,
+ "Type '%s' defined in a .conf file. Using that instead of DWARF",
+ type_name);
+ *info = already_defined_type->info;
+ return true;
+ }
+ }
+
Dwarf_Die next_die;
switch (dwarf_tag(type_die)) {
@@ -547,7 +562,7 @@ static bool get_type(struct arg_type_info** info, Dwarf_Die* type_die)
complain(type_die, "Storing pointer type: %p", *info);
dict_insert(&type_hash, &die_offset, info);
- return get_type(&(*info)->u.ptr_info.info, &next_die);
+ return get_type(&(*info)->u.ptr_info.info, &next_die, plib);
case DW_TAG_structure_type:
*info = calloc(1, sizeof(struct arg_type_info));
@@ -558,7 +573,7 @@ static bool get_type(struct arg_type_info** info, Dwarf_Die* type_die)
complain(type_die, "Storing struct type: %p", *info);
dict_insert(&type_hash, &die_offset, info);
- return get_structure(*info, type_die);
+ return get_structure(*info, type_die, plib);
case DW_TAG_typedef:
@@ -568,7 +583,7 @@ static bool get_type(struct arg_type_info** info, Dwarf_Die* type_die)
bool res = true;
if (get_type_die(&next_die, type_die)) {
complain(type_die, "Storing const/typedef type: %p", *info);
- res = get_type(info, &next_die);
+ res = get_type(info, &next_die, plib);
} else {
// no type. Use 'void'. Normally I'd think this is bogus, but stdio
// typedefs something to void
@@ -602,7 +617,7 @@ static bool get_type(struct arg_type_info** info, Dwarf_Die* type_die)
complain(type_die, "Storing array: %p", *info);
dict_insert(&type_hash, &die_offset, info);
- return get_array(*info, type_die);
+ return get_array(*info, type_die, plib);
case DW_TAG_union_type:
*info = type_get_simple(ARGTYPE_VOID);
@@ -617,7 +632,7 @@ static bool get_type(struct arg_type_info** info, Dwarf_Die* type_die)
return false;
}
-static bool get_prototype(struct prototype* proto, Dwarf_Die* subroutine)
+static bool get_prototype(struct prototype* proto, Dwarf_Die* subroutine, struct protolib* plib)
{
// First, look at the return type. This is stored in a DW_AT_type tag in the
// subroutine DIE. If there is no such tag, this function returns void
@@ -633,7 +648,7 @@ static bool get_prototype(struct prototype* proto, Dwarf_Die* subroutine)
}
proto->own_return_info = 0;
- if (!get_type(&proto->return_info, &return_type_die)) {
+ if (!get_type(&proto->return_info, &return_type_die, plib)) {
complain(subroutine, "Couldn't get return type");
return false;
}
@@ -659,7 +674,7 @@ static bool get_prototype(struct prototype* proto, Dwarf_Die* subroutine)
}
struct arg_type_info* arg_type_info = NULL;
- if (!get_type(&arg_type_info, &type_die)) {
+ if (!get_type(&arg_type_info, &type_die, plib)) {
complain(&arg_die, "Couldn't parse arg type from DWARF data");
return false;
}
@@ -725,7 +740,7 @@ static bool import_subprogram(struct protolib* plib, struct library* lib,
}
prototype_init(proto);
- if (!get_prototype(proto, die)) {
+ if (!get_prototype(proto, die, plib)) {
complain(die, "couldn't get prototype");
return false;
}