* @brief Dumps global variables and constants as gas assembler.
* @author Christian Wuerdig, Matthias Braun
* @date 04.11.2005
- * @version $Id$
*/
#include "config.h"
#include "be_t.h"
#include "beemitter.h"
-#include "be_dbgout.h"
+#include "bedwarf.h"
/** by default, we generate assembler code for the Linux gas */
object_file_format_t be_gas_object_file_format = OBJECT_FILE_FORMAT_ELF;
case GAS_SECTION_DEBUG_ABBREV: name = "section __DWARF,__debug_abbrev,regular,debug"; break;
case GAS_SECTION_DEBUG_LINE: name = "section __DWARF,__debug_line,regular,debug"; break;
case GAS_SECTION_DEBUG_PUBNAMES: name = "section __DWARF,__debug_pubnames,regular,debug"; break;
+ case GAS_SECTION_DEBUG_FRAME: name = "section __DWARF,__debug_frame,regular,debug"; break;
default: panic("unsupported scetion type 0x%X", section);
}
be_emit_irprintf("\t.%s\n", name);
case GAS_SECTION_CSTRING: name = "section __TEXT,__const_coal,coalesced"; break;
default: panic("unsupported scetion type 0x%X", section);
}
+ } else if (flags & GAS_SECTION_FLAG_TLS) {
+ panic("thread local storage not supported on macho (section 0x%X)", section);
} else {
- panic("unsupported section type 0x%X\n", section);
+ panic("unsupported section type 0x%X", section);
}
}
"debug_abbrev",
"debug_line",
"debug_pubnames"
+ "debug_frame",
};
if (current_section == section && !(section & GAS_SECTION_FLAG_COMDAT))
{ "debug_abbrev", "progbits", "" },
{ "debug_line", "progbits", "" },
{ "debug_pubnames", "progbits", "" },
+ { "debug_frame", "progbits", "" },
};
if (be_gas_object_file_format == OBJECT_FILE_FORMAT_MACH_O) {
}
}
-void be_gas_emit_function_prolog(const ir_entity *entity, unsigned po2alignment)
+void be_gas_emit_function_prolog(const ir_entity *entity, unsigned po2alignment, const parameter_dbg_info_t *parameter_infos)
{
be_gas_section_t section;
- be_dbg_method_begin(entity);
+ be_dwarf_method_before(entity, parameter_infos);
section = determine_section(NULL, entity);
emit_section(section, entity);
/* write the begin line (makes the life easier for scripts parsing the
* assembler) */
- be_emit_write_line();
be_emit_cstring("# -- Begin ");
be_gas_emit_entity(entity);
be_emit_char('\n');
be_gas_emit_entity(entity);
be_emit_cstring(":\n");
be_emit_write_line();
+
+ be_dwarf_method_begin();
}
void be_gas_emit_function_epilog(const ir_entity *entity)
{
+ be_dwarf_method_end();
+
if (be_gas_object_file_format == OBJECT_FILE_FORMAT_ELF) {
be_emit_cstring("\t.size\t");
be_gas_emit_entity(entity);
be_emit_char('\n');
be_emit_write_line();
- be_dbg_method_end();
-
be_emit_char('\n');
be_emit_write_line();
}
} v;
} normal_or_bitfield;
-static int is_type_variable_size(ir_type *type)
-{
- (void) type;
- /* TODO */
- return 0;
-}
-
static size_t get_initializer_size(const ir_initializer_t *initializer,
ir_type *type)
{
case IR_INITIALIZER_NULL:
return get_type_size_bytes(type);
case IR_INITIALIZER_COMPOUND:
- if (!is_type_variable_size(type)) {
- return get_type_size_bytes(type);
+ if (is_Array_type(type)) {
+ if (is_array_variable_size(type)) {
+ ir_type *element_type = get_array_element_type(type);
+ unsigned element_size = get_type_size_bytes(element_type);
+ unsigned element_align
+ = get_type_alignment_bytes(element_type);
+ unsigned misalign = element_size % element_align;
+ size_t n_inits
+ = get_initializer_compound_n_entries(initializer);
+ element_size += element_align - misalign;
+ return n_inits * element_size;
+ } else {
+ return get_type_size_bytes(type);
+ }
} else {
- size_t n_entries
- = get_initializer_compound_n_entries(initializer);
- size_t i;
- unsigned initializer_size = get_type_size_bytes(type);
- for (i = 0; i < n_entries; ++i) {
- ir_entity *entity = get_compound_member(type, i);
- ir_type *type = get_entity_type(entity);
-
- const ir_initializer_t *sub_initializer
- = get_initializer_compound_value(initializer, i);
-
- unsigned offset = get_entity_offset(entity);
- unsigned size = get_initializer_size(sub_initializer, type);
-
- if (offset + size > initializer_size) {
- initializer_size = offset + size;
- }
+ assert(is_compound_type(type));
+ size_t size = get_type_size_bytes(type);
+ if (is_compound_variable_size(type)) {
+ /* last initializer has to be an array of variable size */
+ size_t l = get_initializer_compound_n_entries(initializer)-1;
+ const ir_initializer_t *last
+ = get_initializer_compound_value(initializer, l);
+ const ir_entity *last_ent = get_compound_member(type, l);
+ ir_type *last_type = get_entity_type(last_ent);
+ assert(is_array_variable_size(last_type));
+ size += get_initializer_size(last, last_type);
}
- return initializer_size;
+ return size;
}
}
void be_gas_emit_entity(const ir_entity *entity)
{
- if (entity->type == firm_code_type) {
+ if (entity->type == get_code_type()) {
ir_label_t label = get_entity_label(entity);
be_emit_irprintf("%s_%lu", be_gas_get_private_prefix(), label);
return;
void be_gas_emit_block_name(const ir_node *block)
{
- if (has_Block_entity(block)) {
- ir_entity *entity = get_Block_entity(block);
+ ir_entity *entity = get_Block_entity(block);
+ if (entity != NULL) {
be_gas_emit_entity(entity);
} else {
be_emit_irprintf("%s%ld", be_gas_get_private_prefix(), get_irn_node_nr(block));
ir_linkage linkage = get_entity_linkage(entity);
/* block labels are already emittet in the code */
- if (type == firm_code_type)
+ if (type == get_code_type())
return;
/* we already emitted all methods. Except for the trampolines which
return;
}
- be_dbg_variable(entity);
+ be_dwarf_variable(entity);
if (section == GAS_SECTION_BSS) {
switch (visibility) {
void be_gas_begin_compilation_unit(const be_main_env_t *env)
{
- be_dbg_open();
- be_dbg_unit_begin(env->cup_name);
- be_dbg_types();
+ be_dwarf_open();
+ be_dwarf_unit_begin(env->cup_name);
emit_global_asms();
}
{
emit_global_decls(env);
- be_dbg_unit_end();
- be_dbg_close();
+ be_dwarf_unit_end();
+ be_dwarf_close();
}