X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ir%2Fbe%2Fbedwarf.c;h=0c11b4fb785fbdd3f0fabe3bfbdf6c967cf4d726;hb=34e3b8d50bce639e760da7233524a4db85c80290;hp=b8fb7ec9646b2f7d698469caf1a0268185aee218;hpb=f17b937ecb4b49c240848a63a4c20dbfe8d36d96;p=libfirm diff --git a/ir/be/bedwarf.c b/ir/be/bedwarf.c index b8fb7ec96..0c11b4fb7 100644 --- a/ir/be/bedwarf.c +++ b/ir/be/bedwarf.c @@ -1,20 +1,6 @@ /* - * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved. - * * This file is part of libFirm. - * - * This file may be distributed and/or modified under the terms of the - * GNU General Public License version 2 as published by the Free Software - * Foundation and appearing in the file LICENSE.GPL included in the - * packaging of this file. - * - * Licensees holding valid libFirm Professional Edition licenses may use - * this file in accordance with the libFirm Commercial License. - * Agreement provided with the Software. - * - * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE. + * Copyright (C) 2012 University of Karlsruhe. */ /** @@ -28,7 +14,9 @@ #include #include +#include "bearch.h" #include "bedwarf_t.h" +#include "error.h" #include "obst.h" #include "irprog.h" #include "irgraph.h" @@ -48,6 +36,7 @@ #include "beemitter.h" #include "dbginfo.h" #include "begnuas.h" +#include "typerep.h" enum { LEVEL_NONE, @@ -63,12 +52,25 @@ static int debug_level = LEVEL_NONE; * here */ typedef enum custom_abbrevs { - abbrev_void_pointer_type = 100, + abbrev_void_subprogram = 1, + abbrev_subprogram, + abbrev_formal_parameter, abbrev_unnamed_formal_parameter, abbrev_formal_parameter_no_location, - abbrev_void_subroutine_type, - abbrev_void_subprogram, + abbrev_variable, + abbrev_compile_unit, + abbrev_base_type, + abbrev_pointer_type, + abbrev_void_pointer_type, + abbrev_array_type, + abbrev_subrange_type, + abbrev_structure_type, + abbrev_union_type, + abbrev_class_type, + abbrev_member, abbrev_bitfield_member, + abbrev_subroutine_type, + abbrev_void_subroutine_type, } custom_abbrevs; /** @@ -90,12 +92,12 @@ typedef struct dwarf_t { static dwarf_t env; static dwarf_source_language language; -static const char *comp_dir; +static char *comp_dir; static unsigned insert_file(const char *filename) { unsigned num; - void *entry = pmap_get(env.file_map, filename); + void *entry = pmap_get(void, env.file_map, filename); if (entry != NULL) { return PTR_TO_INT(entry); } @@ -158,13 +160,6 @@ static unsigned get_sleb128_size(long value) return size; } -static void emit_string(const char *string) -{ - /* TODO: quote special chars */ - be_emit_irprintf("\t.asciz \"%s\"\n", string); - be_emit_write_line(); -} - static void emit_ref(const ir_entity *entity) { be_emit_cstring("\t.long "); @@ -220,7 +215,8 @@ static void register_attribute(dwarf_attribute attribute, dwarf_form form) emit_uleb128(form); } -static void begin_abbrev(unsigned code, dwarf_tag tag, dw_children children) +static void begin_abbrev(custom_abbrevs code, dwarf_tag tag, + dw_children children) { emit_uleb128(code); emit_uleb128(tag); @@ -265,12 +261,12 @@ static void emit_line_info(void) emit_uleb128(1); /* include directory list */ - emit_string("/foo/bar"); + be_gas_emit_cstring("/foo/bar"); emit_int8(0); /* file list */ for (i = 0; i < ARR_LEN(env.file_list); ++i) { - emit_string(env.file_list[i]); + be_gas_emit_cstring(env.file_list[i]); emit_uleb128(1); /* directory */ emit_uleb128(0); /* modification time */ emit_uleb128(0); /* file length */ @@ -303,7 +299,7 @@ static void emit_pubnames(void) be_emit_irprintf("\t.long %sE%ld - %sinfo_begin\n", be_gas_get_private_prefix(), get_entity_nr(entity), be_gas_get_private_prefix()); - emit_string(get_entity_name(entity)); + be_gas_emit_cstring(get_entity_name(entity)); } emit_int32(0); @@ -392,7 +388,7 @@ static void emit_type_address(const ir_type *type) static void emit_subprogram_abbrev(void) { - begin_abbrev(DW_TAG_subprogram, DW_TAG_subprogram, DW_CHILDREN_yes); + begin_abbrev(abbrev_subprogram, DW_TAG_subprogram, DW_CHILDREN_yes); register_attribute(DW_AT_name, DW_FORM_string); register_dbginfo_attributes(); register_attribute(DW_AT_type, DW_FORM_ref4); @@ -415,7 +411,7 @@ static void emit_subprogram_abbrev(void) register_attribute(DW_AT_frame_base, DW_FORM_block1); end_abbrev(); - begin_abbrev(DW_TAG_formal_parameter, DW_TAG_formal_parameter, + begin_abbrev(abbrev_formal_parameter, DW_TAG_formal_parameter, DW_CHILDREN_no); register_attribute(DW_AT_name, DW_FORM_string); register_dbginfo_attributes(); @@ -452,9 +448,8 @@ static void emit_function_parameters(const ir_entity *entity, ir_type *param_type = get_method_param_type(type, i); if (infos != NULL && infos[i].entity != NULL) { - const ir_entity *entity = infos[i].entity; - long offset = get_entity_offset(entity); - emit_uleb128(DW_TAG_formal_parameter); + long const offset = get_entity_offset(infos[i].entity); + emit_uleb128(abbrev_formal_parameter); emit_string_printf("arg%u", (unsigned)i); emit_dbginfo(dbgi); emit_type_address(param_type); @@ -479,8 +474,6 @@ void be_dwarf_method_before(const ir_entity *entity, size_t n_params = get_method_n_params(type); size_t i; - (void)parameter_infos; - be_gas_emit_switch_section(GAS_SECTION_DEBUG_INFO); if (n_ress > 0) { @@ -493,8 +486,8 @@ void be_dwarf_method_before(const ir_entity *entity, } emit_entity_label(entity); - emit_uleb128(n_ress == 0 ? abbrev_void_subprogram : DW_TAG_subprogram); - emit_string(get_entity_ld_name(entity)); + emit_uleb128(n_ress == 0 ? abbrev_void_subprogram : abbrev_subprogram); + be_gas_emit_cstring(get_entity_ld_name(entity)); emit_dbginfo(get_entity_dbg_info(entity)); if (n_ress > 0) { ir_type *res = get_method_res_type(type, 0); @@ -541,7 +534,7 @@ void be_dwarf_method_end(void) static void emit_base_type_abbrev(void) { - begin_abbrev(DW_TAG_base_type, DW_TAG_base_type, DW_CHILDREN_no); + begin_abbrev(abbrev_base_type, DW_TAG_base_type, DW_CHILDREN_no); register_attribute(DW_AT_encoding, DW_FORM_data1); register_attribute(DW_AT_byte_size, DW_FORM_data1); register_attribute(DW_AT_name, DW_FORM_string); @@ -561,7 +554,7 @@ static void emit_base_type(const ir_type *type) ir_print_type(buf, sizeof(buf), type); emit_type_label(type); - emit_uleb128(DW_TAG_base_type); + emit_uleb128(abbrev_base_type); if (mode_is_int(mode)) { /* bool hack */ if (strcmp(buf, "_Bool")==0 || strcmp(buf, "bool")==0) { @@ -577,12 +570,12 @@ static void emit_base_type(const ir_type *type) panic("mode not implemented yet"); } emit_int8(get_mode_size_bytes(mode)); - emit_string(buf); + be_gas_emit_cstring(buf); } static void emit_pointer_type_abbrev(void) { - begin_abbrev(DW_TAG_pointer_type, DW_TAG_pointer_type, DW_CHILDREN_no); + begin_abbrev(abbrev_pointer_type, DW_TAG_pointer_type, DW_CHILDREN_no); register_attribute(DW_AT_type, DW_FORM_ref4); register_attribute(DW_AT_byte_size, DW_FORM_data1); end_abbrev(); @@ -603,7 +596,7 @@ static void emit_pointer_type(const ir_type *type) emit_type(points_to); emit_type_label(type); - emit_uleb128(DW_TAG_pointer_type); + emit_uleb128(abbrev_pointer_type); emit_type_address(points_to); } else { emit_type_label(type); @@ -614,11 +607,11 @@ static void emit_pointer_type(const ir_type *type) static void emit_array_type_abbrev(void) { - begin_abbrev(DW_TAG_array_type, DW_TAG_array_type, DW_CHILDREN_yes); + begin_abbrev(abbrev_array_type, DW_TAG_array_type, DW_CHILDREN_yes); register_attribute(DW_AT_type, DW_FORM_ref4); end_abbrev(); - begin_abbrev(DW_TAG_subrange_type, DW_TAG_subrange_type, DW_CHILDREN_no); + begin_abbrev(abbrev_subrange_type, DW_TAG_subrange_type, DW_CHILDREN_no); register_attribute(DW_AT_upper_bound, DW_FORM_udata); end_abbrev(); } @@ -628,17 +621,17 @@ static void emit_array_type(const ir_type *type) ir_type *element_type = get_array_element_type(type); if (get_array_n_dimensions(type) != 1) - panic("dwarf: multidimensional arrays no supported yet"); + panic("multidimensional arrays no supported yet"); emit_type(element_type); emit_type_label(type); - emit_uleb128(DW_TAG_array_type); + emit_uleb128(abbrev_array_type); emit_type_address(element_type); if (has_array_upper_bound(type, 0)) { int bound = get_array_upper_bound_int(type, 0); - emit_uleb128(DW_TAG_subrange_type); + emit_uleb128(abbrev_subrange_type); emit_uleb128(bound); } @@ -647,22 +640,22 @@ static void emit_array_type(const ir_type *type) static void emit_compound_type_abbrev(void) { - begin_abbrev(DW_TAG_structure_type, DW_TAG_structure_type, DW_CHILDREN_yes); + begin_abbrev(abbrev_structure_type, DW_TAG_structure_type, DW_CHILDREN_yes); register_attribute(DW_AT_byte_size, DW_FORM_udata); // TODO register_dbginfo_attributes(); end_abbrev(); - begin_abbrev(DW_TAG_union_type, DW_TAG_union_type, DW_CHILDREN_yes); + begin_abbrev(abbrev_union_type, DW_TAG_union_type, DW_CHILDREN_yes); register_attribute(DW_AT_byte_size, DW_FORM_udata); // TODO register_dbginfo_attributes(); end_abbrev(); - begin_abbrev(DW_TAG_class_type, DW_TAG_class_type, DW_CHILDREN_yes); + begin_abbrev(abbrev_class_type, DW_TAG_class_type, DW_CHILDREN_yes); register_attribute(DW_AT_byte_size, DW_FORM_udata); // TODO register_dbginfo_attributes(); end_abbrev(); - begin_abbrev(DW_TAG_member, DW_TAG_member, DW_CHILDREN_no); + begin_abbrev(abbrev_member, DW_TAG_member, DW_CHILDREN_no); register_attribute(DW_AT_type, DW_FORM_ref4); register_attribute(DW_AT_name, DW_FORM_string); register_dbginfo_attributes(); @@ -704,12 +697,12 @@ static void emit_compound_type(const ir_type *type) emit_type_label(type); if (is_Struct_type(type)) { - emit_uleb128(DW_TAG_structure_type); + emit_uleb128(abbrev_structure_type); } else if (is_Union_type(type)) { - emit_uleb128(DW_TAG_union_type); + emit_uleb128(abbrev_union_type); } else { assert(is_Class_type(type)); - emit_uleb128(DW_TAG_class_type); + emit_uleb128(abbrev_class_type); } emit_uleb128(get_type_size_bytes(type)); for (i = 0; i < n_members; ++i) { @@ -733,11 +726,11 @@ static void emit_compound_type(const ir_type *type) emit_uleb128(bit_offset); member_type = base; } else { - emit_uleb128(DW_TAG_member); + emit_uleb128(abbrev_member); } emit_type_address(member_type); - emit_string(get_entity_name(member)); + be_gas_emit_cstring(get_entity_name(member)); emit_dbginfo(get_entity_dbg_info(member)); assert(offset >= 0); emit_int8(1 + get_uleb128_size(offset)); @@ -749,7 +742,7 @@ static void emit_compound_type(const ir_type *type) static void emit_subroutine_type_abbrev(void) { - begin_abbrev(DW_TAG_subroutine_type, + begin_abbrev(abbrev_subroutine_type, DW_TAG_subroutine_type, DW_CHILDREN_yes); register_attribute(DW_AT_prototyped, DW_FORM_flag); register_attribute(DW_AT_type, DW_FORM_ref4); @@ -781,7 +774,7 @@ static void emit_subroutine_type(const ir_type *type) } emit_type_label(type); - emit_uleb128(n_ress == 0 ? abbrev_void_subroutine_type : DW_TAG_subroutine_type); + emit_uleb128(n_ress == 0 ? abbrev_void_subroutine_type : abbrev_subroutine_type); emit_int8(1); /* prototyped */ if (n_ress > 0) { /* dwarf only supports 1 return type */ @@ -799,7 +792,7 @@ static void emit_subroutine_type(const ir_type *type) static void emit_type(ir_type *type) { - if (pset_new_insert(&env.emitted_types, type)) + if (!pset_new_insert(&env.emitted_types, type)) return; switch (get_type_tpop_code(type)) { @@ -811,7 +804,7 @@ static void emit_type(ir_type *type) case tpo_union: emit_compound_type(type); break; case tpo_method: emit_subroutine_type(type); break; default: - panic("bedwarf: type %+F not implemented yet", type); + panic("type %+F not implemented yet", type); } } @@ -826,7 +819,7 @@ static void emit_op_addr(const ir_entity *entity) static void emit_variable_abbrev(void) { - begin_abbrev(DW_TAG_variable, DW_TAG_variable, DW_CHILDREN_no); + begin_abbrev(abbrev_variable, DW_TAG_variable, DW_CHILDREN_no); register_attribute(DW_AT_name, DW_FORM_string); register_attribute(DW_AT_type, DW_FORM_ref4); register_attribute(DW_AT_external, DW_FORM_flag); @@ -851,8 +844,8 @@ void be_dwarf_variable(const ir_entity *entity) emit_type(type); emit_entity_label(entity); - emit_uleb128(DW_TAG_variable); - emit_string(get_entity_ld_name(entity)); + emit_uleb128(abbrev_variable); + be_gas_emit_cstring(get_entity_ld_name(entity)); emit_type_address(type); emit_int8(is_extern_entity(entity)); emit_dbginfo(get_entity_dbg_info(entity)); @@ -865,7 +858,7 @@ void be_dwarf_variable(const ir_entity *entity) static void emit_compile_unit_abbrev(void) { - begin_abbrev(DW_TAG_compile_unit, DW_TAG_compile_unit, DW_CHILDREN_yes); + begin_abbrev(abbrev_compile_unit, DW_TAG_compile_unit, DW_CHILDREN_yes); register_attribute(DW_AT_stmt_list, DW_FORM_data4); register_attribute(DW_AT_producer, DW_FORM_string); register_attribute(DW_AT_name, DW_FORM_string); @@ -904,24 +897,25 @@ void be_dwarf_unit_begin(const char *filename) emit_label("info_section_begin"); emit_label("info_begin"); + const backend_params *be_params = be_get_backend_param(); + /* length of compilation unit info */ emit_size("compile_unit_begin", "compile_unit_end"); emit_label("compile_unit_begin"); emit_int16(3); /* dwarf version */ emit_address("abbrev_begin"); - emit_int8(4); /* pointer size, TODO: query backend */ + emit_int8(be_params->machine_size / 8); /* pointer size */ /* compile_unit die */ - emit_uleb128(DW_TAG_compile_unit); + emit_uleb128(abbrev_compile_unit); emit_address("line_section_begin"); emit_string_printf("libFirm (%u.%u %s)", ir_get_version_major(), - ir_get_version_minor(), - ir_get_version_revision()); - emit_string(filename); + ir_get_version_minor(), ir_get_version_revision()); + be_gas_emit_cstring(filename); if (language != 0) emit_int16(language); if (comp_dir != NULL) - emit_string(comp_dir); + be_gas_emit_cstring(comp_dir); /* tell gas to emit cfi in debug_frame * TODO: if we produce exception handling code then this should be @@ -975,7 +969,8 @@ void be_dwarf_set_source_language(dwarf_source_language new_language) void be_dwarf_set_compilation_directory(const char *new_comp_dir) { - comp_dir = new_comp_dir; + xfree(comp_dir); + comp_dir = xstrdup(new_comp_dir); } BE_REGISTER_MODULE_CONSTRUCTOR(be_init_dwarf)