From 05351ece16e5203717dd21a6fc1ad2e6ff87c203 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 6 May 2007 14:50:28 -0300 Subject: [PATCH] [LIB]: Move the __emit functions to a separate library, libdwarves_emit To isolate functionality only used in utilities such as ctracer. Signed-off-by: Arnaldo Carvalho de Melo --- CMakeLists.txt | 10 +- MANIFEST | 2 + ctracer.c | 1 + dwarves.c | 307 ++--------------------------------------- dwarves.h | 12 +- dwarves_emit.c | 307 +++++++++++++++++++++++++++++++++++++++++ dwarves_emit.h | 29 ++++ rpm/SPECS/dwarves.spec | 3 + 8 files changed, 363 insertions(+), 308 deletions(-) create mode 100644 dwarves_emit.c create mode 100644 dwarves_emit.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f09c51..62330cf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,13 +32,18 @@ add_library(dwarves SHARED ${dwarves_LIB_SRCS}) set_target_properties(dwarves PROPERTIES VERSION 1.0.0 SOVERSION 1) target_link_libraries(dwarves ${DWARF_LIBRARIES}) +set(dwarves_emit_LIB_SRCS dwarves_emit.c) +add_library(dwarves_emit SHARED ${dwarves_emit_LIB_SRCS}) +set_target_properties(dwarves_emit PROPERTIES VERSION 1.0.0 SOVERSION 1) +target_link_libraries(dwarves_emit ${DWARF_LIBRARIES} dwarves) + set(codiff_SRCS codiff.c) add_executable(codiff ${codiff_SRCS}) target_link_libraries(codiff dwarves) set(ctracer_SRCS ctracer.c) add_executable(ctracer ${ctracer_SRCS}) -target_link_libraries(ctracer dwarves) +target_link_libraries(ctracer dwarves dwarves_emit) set(dtagnames_SRCS dtagnames.c) add_executable(dtagnames ${dtagnames_SRCS}) @@ -68,7 +73,8 @@ install(TARGETS codiff ctracer dtagnames pahole pdwtags pfunct pglobal prefcnt RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) install(TARGETS dwarves LIBRARY DESTINATION ${LIB_INSTALL_DIR}) -install(FILES dwarves.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include) +install(TARGETS dwarves dwarves_emit LIBRARY DESTINATION ${LIB_INSTALL_DIR}) +install(FILES dwarves.h dwarves_emit.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include) install(FILES ostra/ostra-cg DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) install(FILES ostra/python/ostra.py DESTINATION ${LIB_INSTALL_DIR}/ctracer/python) install(FILES lib/Makefile lib/ctracer_jprobe.c diff --git a/MANIFEST b/MANIFEST index 67044b5..dfccc27 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,5 +1,7 @@ dwarves.c dwarves.h +dwarves_emit.c +dwarves_emit.h cmake/modules/FindDWARF.cmake CMakeLists.txt codiff.c diff --git a/ctracer.c b/ctracer.c index 12486f6..424d2bf 100644 --- a/ctracer.c +++ b/ctracer.c @@ -15,6 +15,7 @@ #include #include +#include "dwarves_emit.h" #include "dwarves.h" /* diff --git a/dwarves.c b/dwarves.c index 8ffc3a2..b2ba0d2 100644 --- a/dwarves.c +++ b/dwarves.c @@ -311,7 +311,7 @@ static void __tag__type_not_found(const struct tag *self, const char *fn) #define tag__type_not_found(self) __tag__type_not_found(self, __func__) -static size_t tag__fprintf_decl_info(const struct tag *self, FILE *fp) +size_t tag__fprintf_decl_info(const struct tag *self, FILE *fp) { return fprintf(fp, "/* <%llx> %s:%u */\n", (unsigned long long)self->id, @@ -379,8 +379,8 @@ static struct type *type__new(Dwarf_Die *die) return self; } -static size_t typedef__fprintf(const struct tag *tag_self, const struct cu *cu, - FILE *fp) +size_t typedef__fprintf(const struct tag *tag_self, const struct cu *cu, + FILE *fp) { const struct type *self = tag__type(tag_self); const struct tag *type = cu__find_tag_by_id(cu, tag_self->type); @@ -430,8 +430,8 @@ static size_t typedef__fprintf(const struct tag *tag_self, const struct cu *cu, tag__name(type, cu, bf, sizeof(bf)), self->name); } -static size_t enumeration__fprintf(const struct tag *tag_self, - const struct conf_fprintf *conf, FILE *fp) +size_t enumeration__fprintf(const struct tag *tag_self, + const struct conf_fprintf *conf, FILE *fp) { const struct type *self = tag__type(tag_self); struct enumerator *pos; @@ -668,46 +668,6 @@ struct cu *cus__find_cu_by_name(const struct cus *self, const char *name) return NULL; } -struct type *cus__find_definition(const struct cus *self, const char *name) -{ - struct type *pos; - - if (name == NULL) - return NULL; - - list_for_each_entry(pos, self->definitions, node) - if (pos->name != NULL && strcmp(pos->name, name) == 0) - return pos; - - return NULL; -} - -struct type *cus__find_fwd_decl(const struct cus *self, const char *name) -{ - struct type *pos; - - list_for_each_entry(pos, self->fwd_decls, node) - if (strcmp(pos->name, name) == 0) - return pos; - - return NULL; -} - -static void cus__add_definition(struct cus *self, struct type *type) -{ - type->definition_emitted = 1; - if (!list_empty(&type->node)) - list_del(&type->node); - list_add_tail(&type->node, self->definitions); -} - -static void cus__add_fwd_decl(struct cus *self, struct type *type) -{ - type->fwd_decl_emitted = 1; - if (list_empty(&type->node)) - list_add_tail(&type->node, self->fwd_decls); -} - struct tag *cu__find_function_by_name(const struct cu *self, const char *name) { struct tag *pos; @@ -1847,9 +1807,7 @@ size_t ftype__fprintf(const struct ftype *self, const struct cu *cu, const char *name, const int inlined, const int is_pointer, int type_spacing, FILE *fp) { - struct parameter *pos; struct tag *type = cu__find_tag_by_id(cu, self->tag.type); - int first_parm = 1; char sbf[128]; const char *stype = tag__name(type, cu, sbf, sizeof(sbf)); size_t printed = fprintf(fp, "%s%-*s %s%s%s%s", @@ -2685,7 +2643,7 @@ size_t class__fprintf(const struct class *self, const struct cu *cu, list_for_each_entry(pos, &tself->members, tag.node) { struct tag *type; - if (pos->offset != last_offset) + if ((int)pos->offset != last_offset) printed += class__fprintf_cacheline_boundary(last_cacheline, sum, sum_holes, @@ -2696,7 +2654,7 @@ size_t class__fprintf(const struct class *self, const struct cu *cu, if (last_offset != -1) { const ssize_t cc_last_size = pos->offset - last_offset; - if (pos->offset < last_offset) { + if ((int)pos->offset < last_offset) { if (!newline++) { fputc('\n', fp); ++printed; @@ -2809,7 +2767,7 @@ size_t class__fprintf(const struct class *self, const struct cu *cu, * check for bitfields, accounting for only the biggest * of the byte_size in the fields in each bitfield set. */ - if (last_offset != pos->offset || + if (last_offset != (int)pos->offset || pos->bit_size == 0 || last_bit_size == 0) { last_size = size; sum += last_size; @@ -3612,255 +3570,6 @@ struct cus *cus__new(struct list_head *definitions, return self; } -static int cus__emit_enumeration_definitions(struct cus *self, struct tag *tag, - const struct conf_fprintf *conf, - FILE *fp) -{ - struct type *etype = tag__type(tag); - - /* Have we already emitted this in this CU? */ - if (etype->definition_emitted) - return 0; - - /* Ok, lets look at the previous CUs: */ - if (cus__find_definition(self, etype->name) != NULL) { - /* - * Yes, so lets mark it visited on this CU too, - * to speed up the lookup. - */ - etype->definition_emitted = 1; - return 0; - } - - enumeration__fprintf(tag, conf, fp); - fputs(";", fp); - cus__add_definition(self, etype); - return 1; -} - -static int cus__emit_tag_definitions(struct cus *self, struct cu *cu, - struct tag *tag, FILE *fp); - -static int cus__emit_typedef_definitions(struct cus *self, struct cu *cu, - struct tag *tdef, FILE *fp) -{ - struct type *def = tag__type(tdef); - struct tag *type, *ptr_type; - int is_pointer = 0; - - /* Have we already emitted this in this CU? */ - if (def->definition_emitted) - return 0; - - /* Ok, lets look at the previous CUs: */ - if (cus__find_definition(self, def->name) != NULL) { - /* - * Yes, so lets mark it visited on this CU too, - * to speed up the lookup. - */ - def->definition_emitted = 1; - return 0; - } - - type = cu__find_tag_by_id(cu, tdef->type); - - switch (type->tag) { - case DW_TAG_array_type: - cus__emit_tag_definitions(self, cu, type, fp); - break; - case DW_TAG_typedef: - cus__emit_typedef_definitions(self, cu, type, fp); - break; - case DW_TAG_pointer_type: - ptr_type = cu__find_tag_by_id(cu, type->type); - if (ptr_type->tag != DW_TAG_subroutine_type) - break; - type = ptr_type; - is_pointer = 1; - /* Fall thru */ - case DW_TAG_subroutine_type: - cus__emit_ftype_definitions(self, cu, tag__ftype(type), fp); - break; - case DW_TAG_enumeration_type: { - const struct type *ctype = tag__type(type); - struct conf_fprintf conf = { - .suffix = NULL, - }; - - tag__fprintf_decl_info(type, fp); - if (ctype->name == NULL) { - fputs("typedef ", fp); - conf.suffix = def->name; - cus__emit_enumeration_definitions(self, type, &conf, fp); - goto out; - } else - cus__emit_enumeration_definitions(self, type, &conf, fp); - } - break; - case DW_TAG_structure_type: - case DW_TAG_union_type: { - const struct type *ctype = tag__type(type); - - if (ctype->name == NULL) { - if (cus__emit_type_definitions(self, cu, type, fp)) - type__emit(type, cu, "typedef", def->name, fp); - goto out; - } else if (cus__emit_type_definitions(self, cu, type, fp)) - type__emit(type, cu, NULL, NULL, fp); - } - } - - /* - * Recheck if the typedef was emitted, as there are cases, like - * wait_queue_t in the Linux kernel, that is against struct - * __wait_queue, that has a wait_queue_func_t member, a function - * typedef that has as one of its parameters a... wait_queue_t, that - * will thus be emitted before the function typedef, making a no go to - * redefine the typedef after struct __wait_queue. - */ - if (!def->definition_emitted) { - typedef__fprintf(tdef, cu, fp); - fputs(";\n", fp); - } -out: - cus__add_definition(self, def); - return 1; -} - -int cus__emit_fwd_decl(struct cus *self, struct type *ctype, FILE *fp) -{ - /* Have we already emitted this in this CU? */ - if (ctype->fwd_decl_emitted) - return 0; - - /* Ok, lets look at the previous CUs: */ - if (cus__find_fwd_decl(self, ctype->name) != NULL) { - /* - * Yes, so lets mark it visited on this CU too, - * to speed up the lookup. - */ - ctype->fwd_decl_emitted = 1; - return 0; - } - - fprintf(fp, "%s %s;\n", - ctype->tag.tag == DW_TAG_union_type ? "union" : "struct", - ctype->name); - cus__add_fwd_decl(self, ctype); - return 1; -} - -static int cus__emit_tag_definitions(struct cus *self, struct cu *cu, - struct tag *tag, FILE *fp) -{ - struct tag *type = cu__find_tag_by_id(cu, tag->type); - int pointer = 0; - - if (type == NULL) - return 0; -next_indirection: - switch (type->tag) { - case DW_TAG_pointer_type: - case DW_TAG_reference_type: - pointer = 1; - /* Fall thru */ - case DW_TAG_array_type: - case DW_TAG_const_type: - case DW_TAG_volatile_type: - type = cu__find_tag_by_id(cu, type->type); - if (type == NULL) - return 0; - goto next_indirection; - case DW_TAG_typedef: - return cus__emit_typedef_definitions(self, cu, type, fp); - case DW_TAG_enumeration_type: - if (tag__type(type)->name != NULL) { - tag__fprintf_decl_info(type, fp); - return cus__emit_enumeration_definitions(self, type, - NULL, fp); - } - break; - case DW_TAG_structure_type: - case DW_TAG_union_type: - if (pointer) - return cus__emit_fwd_decl(self, tag__type(type), fp); - if (cus__emit_type_definitions(self, cu, type, fp)) - type__emit(type, cu, NULL, NULL, fp); - return 1; - case DW_TAG_subroutine_type: - return cus__emit_ftype_definitions(self, cu, - tag__ftype(type), fp); - } - - return 0; -} - -int cus__emit_ftype_definitions(struct cus *self, struct cu *cu, - struct ftype *ftype, FILE *fp) -{ - struct parameter *pos; - /* First check the function return type */ - int printed = cus__emit_tag_definitions(self, cu, &ftype->tag, fp); - - /* Then its parameters */ - list_for_each_entry(pos, &ftype->parms, tag.node) - if (cus__emit_tag_definitions(self, cu, &pos->tag, fp)) - printed = 1; - - if (printed) - fputc('\n', fp); - return printed; -} - -int cus__emit_type_definitions(struct cus *self, struct cu *cu, - struct tag *tag, FILE *fp) -{ - struct type *ctype = tag__type(tag); - struct class_member *pos; - int printed = 0; - - if (ctype->definition_emitted) - return 0; - - /* Ok, lets look at the previous CUs: */ - if (cus__find_definition(self, ctype->name) != NULL) { - ctype->definition_emitted = 1; - return 0; - } - - cus__add_definition(self, ctype); - - list_for_each_entry(pos, &ctype->members, tag.node) - if (cus__emit_tag_definitions(self, cu, &pos->tag, fp)) - printed = 1; - - if (printed) - fputc('\n', fp); - return 1; -} - -void type__emit(struct tag *tag_self, struct cu *cu, - const char *prefix, const char *suffix, FILE *fp) -{ - struct type *ctype = tag__type(tag_self); - - if (tag_self->tag == DW_TAG_structure_type) - class__find_holes(tag__class(tag_self), cu); - - if (ctype->name != NULL || suffix != NULL || prefix != NULL) { - struct conf_fprintf conf = { - .prefix = prefix, - .suffix = suffix, - .emit_stats = 1, - }; - tag__fprintf(tag_self, cu, &conf, fp); - - if (tag_self->tag != DW_TAG_structure_type) - fputc(';', fp); - fputc('\n', fp); - } -} - void dwarves__init(size_t user_cacheline_size) { if (user_cacheline_size == 0) { diff --git a/dwarves.h b/dwarves.h index 8f4d67b..25229c6 100644 --- a/dwarves.h +++ b/dwarves.h @@ -282,6 +282,11 @@ extern struct class *class__reorganize(struct class *self, const int verbose, FILE *fp); extern size_t class__fprintf(const struct class *self, const struct cu *cu, const struct conf_fprintf *conf, FILE *fp); +extern size_t enumeration__fprintf(const struct tag *tag_self, + const struct conf_fprintf *conf, FILE *fp); +extern size_t typedef__fprintf(const struct tag *tag_self, const struct cu *cu, + FILE *fp); +extern size_t tag__fprintf_decl_info(const struct tag *self, FILE *fp); extern size_t tag__fprintf(const struct tag *self, const struct cu *cu, const struct conf_fprintf *conf, FILE *fp); @@ -312,13 +317,6 @@ extern struct tag *cus__find_struct_by_name(const struct cus *self, extern struct tag *cus__find_function_by_name(const struct cus *self, struct cu **cu, const char *name); -extern int cus__emit_ftype_definitions(struct cus *self, struct cu *cu, - struct ftype *ftype, FILE *fp); -extern int cus__emit_type_definitions(struct cus *self, struct cu *cu, - struct tag *tag, FILE *fp); -extern int cus__emit_fwd_decl(struct cus *self, struct type *ctype, FILE *fp); -extern void type__emit(struct tag *tag_self, struct cu *cu, - const char *prefix, const char *suffix, FILE *fp); extern struct tag *cu__find_tag_by_id(const struct cu *self, const Dwarf_Off id); diff --git a/dwarves_emit.c b/dwarves_emit.c new file mode 100644 index 0000000..3ff2b88 --- /dev/null +++ b/dwarves_emit.c @@ -0,0 +1,307 @@ +/* + Copyright (C) 2006 Mandriva Conectiva S.A. + Copyright (C) 2006 Arnaldo Carvalho de Melo + Copyright (C) 2007 Red Hat Inc. + Copyright (C) 2007 Arnaldo Carvalho de Melo + + 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. +*/ + +#include + +#include "list.h" +#include "dwarves_emit.h" +#include "dwarves.h" + +static void cus__add_definition(struct cus *self, struct type *type) +{ + type->definition_emitted = 1; + if (!list_empty(&type->node)) + list_del(&type->node); + list_add_tail(&type->node, self->definitions); +} + +static void cus__add_fwd_decl(struct cus *self, struct type *type) +{ + type->fwd_decl_emitted = 1; + if (list_empty(&type->node)) + list_add_tail(&type->node, self->fwd_decls); +} + +static struct type *cus__find_definition(const struct cus *self, + const char *name) +{ + struct type *pos; + + if (name == NULL) + return NULL; + + list_for_each_entry(pos, self->definitions, node) + if (pos->name != NULL && strcmp(pos->name, name) == 0) + return pos; + + return NULL; +} + +static struct type *cus__find_fwd_decl(const struct cus *self, + const char *name) +{ + struct type *pos; + + list_for_each_entry(pos, self->fwd_decls, node) + if (strcmp(pos->name, name) == 0) + return pos; + + return NULL; +} + +static int cus__emit_enumeration_definitions(struct cus *self, struct tag *tag, + const struct conf_fprintf *conf, + FILE *fp) +{ + struct type *etype = tag__type(tag); + + /* Have we already emitted this in this CU? */ + if (etype->definition_emitted) + return 0; + + /* Ok, lets look at the previous CUs: */ + if (cus__find_definition(self, etype->name) != NULL) { + /* + * Yes, so lets mark it visited on this CU too, + * to speed up the lookup. + */ + etype->definition_emitted = 1; + return 0; + } + + enumeration__fprintf(tag, conf, fp); + fputs(";", fp); + cus__add_definition(self, etype); + return 1; +} + +static int cus__emit_tag_definitions(struct cus *self, struct cu *cu, + struct tag *tag, FILE *fp); + +static int cus__emit_typedef_definitions(struct cus *self, struct cu *cu, + struct tag *tdef, FILE *fp) +{ + struct type *def = tag__type(tdef); + struct tag *type, *ptr_type; + int is_pointer = 0; + + /* Have we already emitted this in this CU? */ + if (def->definition_emitted) + return 0; + + /* Ok, lets look at the previous CUs: */ + if (cus__find_definition(self, def->name) != NULL) { + /* + * Yes, so lets mark it visited on this CU too, + * to speed up the lookup. + */ + def->definition_emitted = 1; + return 0; + } + + type = cu__find_tag_by_id(cu, tdef->type); + + switch (type->tag) { + case DW_TAG_array_type: + cus__emit_tag_definitions(self, cu, type, fp); + break; + case DW_TAG_typedef: + cus__emit_typedef_definitions(self, cu, type, fp); + break; + case DW_TAG_pointer_type: + ptr_type = cu__find_tag_by_id(cu, type->type); + if (ptr_type->tag != DW_TAG_subroutine_type) + break; + type = ptr_type; + is_pointer = 1; + /* Fall thru */ + case DW_TAG_subroutine_type: + cus__emit_ftype_definitions(self, cu, tag__ftype(type), fp); + break; + case DW_TAG_enumeration_type: { + const struct type *ctype = tag__type(type); + struct conf_fprintf conf = { + .suffix = NULL, + }; + + tag__fprintf_decl_info(type, fp); + if (ctype->name == NULL) { + fputs("typedef ", fp); + conf.suffix = def->name; + cus__emit_enumeration_definitions(self, type, &conf, fp); + goto out; + } else + cus__emit_enumeration_definitions(self, type, &conf, fp); + } + break; + case DW_TAG_structure_type: + case DW_TAG_union_type: { + const struct type *ctype = tag__type(type); + + if (ctype->name == NULL) { + if (cus__emit_type_definitions(self, cu, type, fp)) + type__emit(type, cu, "typedef", def->name, fp); + goto out; + } else if (cus__emit_type_definitions(self, cu, type, fp)) + type__emit(type, cu, NULL, NULL, fp); + } + } + + /* + * Recheck if the typedef was emitted, as there are cases, like + * wait_queue_t in the Linux kernel, that is against struct + * __wait_queue, that has a wait_queue_func_t member, a function + * typedef that has as one of its parameters a... wait_queue_t, that + * will thus be emitted before the function typedef, making a no go to + * redefine the typedef after struct __wait_queue. + */ + if (!def->definition_emitted) { + typedef__fprintf(tdef, cu, fp); + fputs(";\n", fp); + } +out: + cus__add_definition(self, def); + return 1; +} + +int cus__emit_fwd_decl(struct cus *self, struct type *ctype, FILE *fp) +{ + /* Have we already emitted this in this CU? */ + if (ctype->fwd_decl_emitted) + return 0; + + /* Ok, lets look at the previous CUs: */ + if (cus__find_fwd_decl(self, ctype->name) != NULL) { + /* + * Yes, so lets mark it visited on this CU too, + * to speed up the lookup. + */ + ctype->fwd_decl_emitted = 1; + return 0; + } + + fprintf(fp, "%s %s;\n", + ctype->tag.tag == DW_TAG_union_type ? "union" : "struct", + ctype->name); + cus__add_fwd_decl(self, ctype); + return 1; +} + +static int cus__emit_tag_definitions(struct cus *self, struct cu *cu, + struct tag *tag, FILE *fp) +{ + struct tag *type = cu__find_tag_by_id(cu, tag->type); + int pointer = 0; + + if (type == NULL) + return 0; +next_indirection: + switch (type->tag) { + case DW_TAG_pointer_type: + case DW_TAG_reference_type: + pointer = 1; + /* Fall thru */ + case DW_TAG_array_type: + case DW_TAG_const_type: + case DW_TAG_volatile_type: + type = cu__find_tag_by_id(cu, type->type); + if (type == NULL) + return 0; + goto next_indirection; + case DW_TAG_typedef: + return cus__emit_typedef_definitions(self, cu, type, fp); + case DW_TAG_enumeration_type: + if (tag__type(type)->name != NULL) { + tag__fprintf_decl_info(type, fp); + return cus__emit_enumeration_definitions(self, type, + NULL, fp); + } + break; + case DW_TAG_structure_type: + case DW_TAG_union_type: + if (pointer) + return cus__emit_fwd_decl(self, tag__type(type), fp); + if (cus__emit_type_definitions(self, cu, type, fp)) + type__emit(type, cu, NULL, NULL, fp); + return 1; + case DW_TAG_subroutine_type: + return cus__emit_ftype_definitions(self, cu, + tag__ftype(type), fp); + } + + return 0; +} + +int cus__emit_ftype_definitions(struct cus *self, struct cu *cu, + struct ftype *ftype, FILE *fp) +{ + struct parameter *pos; + /* First check the function return type */ + int printed = cus__emit_tag_definitions(self, cu, &ftype->tag, fp); + + /* Then its parameters */ + list_for_each_entry(pos, &ftype->parms, tag.node) + if (cus__emit_tag_definitions(self, cu, &pos->tag, fp)) + printed = 1; + + if (printed) + fputc('\n', fp); + return printed; +} + +int cus__emit_type_definitions(struct cus *self, struct cu *cu, + struct tag *tag, FILE *fp) +{ + struct type *ctype = tag__type(tag); + struct class_member *pos; + int printed = 0; + + if (ctype->definition_emitted) + return 0; + + /* Ok, lets look at the previous CUs: */ + if (cus__find_definition(self, ctype->name) != NULL) { + ctype->definition_emitted = 1; + return 0; + } + + cus__add_definition(self, ctype); + + list_for_each_entry(pos, &ctype->members, tag.node) + if (cus__emit_tag_definitions(self, cu, &pos->tag, fp)) + printed = 1; + + if (printed) + fputc('\n', fp); + return 1; +} + +void type__emit(struct tag *tag_self, struct cu *cu, + const char *prefix, const char *suffix, FILE *fp) +{ + struct type *ctype = tag__type(tag_self); + + if (tag_self->tag == DW_TAG_structure_type) + class__find_holes(tag__class(tag_self), cu); + + if (ctype->name != NULL || suffix != NULL || prefix != NULL) { + struct conf_fprintf conf = { + .prefix = prefix, + .suffix = suffix, + .emit_stats = 1, + }; + tag__fprintf(tag_self, cu, &conf, fp); + + if (tag_self->tag != DW_TAG_structure_type) + fputc(';', fp); + fputc('\n', fp); + } +} diff --git a/dwarves_emit.h b/dwarves_emit.h new file mode 100644 index 0000000..5377f94 --- /dev/null +++ b/dwarves_emit.h @@ -0,0 +1,29 @@ +#ifndef _DWARVES_EMIT_H_ +#define _DWARVES_EMIT_H_ 1 +/* + Copyright (C) 2006 Mandriva Conectiva S.A. + Copyright (C) 2006 Arnaldo Carvalho de Melo + Copyright (C) 2007 Arnaldo Carvalho de Melo + + 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. +*/ + +#include + +struct cus; +struct cu; +struct ftype; +struct tag; +struct type; + +extern int cus__emit_ftype_definitions(struct cus *self, struct cu *cu, + struct ftype *ftype, FILE *fp); +extern int cus__emit_type_definitions(struct cus *self, struct cu *cu, + struct tag *tag, FILE *fp); +extern int cus__emit_fwd_decl(struct cus *self, struct type *ctype, FILE *fp); +extern void type__emit(struct tag *tag_self, struct cu *cu, + const char *prefix, const char *suffix, FILE *fp); + +#endif /* _DWARVES_EMIT_H_ */ diff --git a/rpm/SPECS/dwarves.spec b/rpm/SPECS/dwarves.spec index f5af110..d14628c 100644 --- a/rpm/SPECS/dwarves.spec +++ b/rpm/SPECS/dwarves.spec @@ -86,12 +86,15 @@ rm -rf %{buildroot} %files -n %{libname}%{libver} %defattr(0644,root,root,0755) %{_libdir}/%{libname}.so.* +%{_libdir}/%{libname}_emit.so.* %files -n %{libname}%{libver}-devel %defattr(0644,root,root,0755) %doc MANIFEST README %{_includedir}/dwarves.h +%{_includedir}/dwarves_emit.h %{_libdir}/%{libname}.so +%{_libdir}/%{libname}_emit.so %changelog * Tue Apr 3 2007 Arnaldo Carvalho de Melo