yasm_section * yasm_dwarf2__generate_aranges(yasm_object *object, yasm_section *debug_info) { yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt; int new; yasm_section *debug_aranges; yasm_bytecode *bc; dwarf2_head *head; dwarf2_aranges_info info; debug_aranges = yasm_object_get_general(object, ".debug_aranges", 2*dbgfmt_dwarf2->sizeof_address, 0, 0, &new, 0); /* header */ head = yasm_dwarf2__add_head(dbgfmt_dwarf2, debug_aranges, debug_info, 1, 1); /* align ranges to 2x address size (range size) */ bc = yasm_bc_create_align( yasm_expr_create_ident(yasm_expr_int( yasm_intnum_create_uint(dbgfmt_dwarf2->sizeof_address*2)), 0), NULL, NULL, NULL, 0); yasm_bc_finalize(bc, yasm_dwarf2__append_bc(debug_aranges, bc)); yasm_bc_calc_len(bc, NULL, NULL); info.debug_aranges = debug_aranges; info.object = object; info.dbgfmt_dwarf2 = dbgfmt_dwarf2; yasm_object_sections_traverse(object, (void *)&info, dwarf2_generate_aranges_section); /* Terminate with empty address range descriptor */ dwarf2_append_arange(debug_aranges, yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)), 0), yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)), 0), dbgfmt_dwarf2->sizeof_address); /* mark end of aranges information */ yasm_dwarf2__set_head_end(head, yasm_section_bcs_last(debug_aranges)); return debug_aranges; }
static int dwarf2_generate_aranges_section(yasm_section *sect, /*@null@*/ void *d) { dwarf2_aranges_info *info = (dwarf2_aranges_info *)d; yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2; /*@null@*/ dwarf2_section_data *dsd; /*@only@*/ yasm_expr *start, *length; dsd = yasm_section_get_data(sect, &yasm_dwarf2__section_data_cb); if (!dsd) return 0; /* no line data for this section */ /* Create address range descriptor */ start = yasm_expr_create_ident( yasm_expr_sym(yasm_dwarf2__bc_sym(info->object->symtab, yasm_section_bcs_first(sect))), 0); length = yasm_expr_create_ident( yasm_expr_int(yasm_calc_bc_dist(yasm_section_bcs_first(sect), yasm_section_bcs_last(sect))), 0); dwarf2_append_arange(info->debug_aranges, start, length, dbgfmt_dwarf2->sizeof_address); return 0; }
static int xdf_objfmt_output_section(yasm_section *sect, /*@null@*/ void *d) { /*@null@*/ xdf_objfmt_output_info *info = (xdf_objfmt_output_info *)d; /*@dependent@*/ /*@null@*/ xdf_section_data *xsd; long pos; xdf_reloc *reloc; assert(info != NULL); xsd = yasm_section_get_data(sect, &xdf_section_data_cb); assert(xsd != NULL); if (xsd->flags & XDF_SECT_BSS) { /* Don't output BSS sections. * TODO: Check for non-reserve bytecodes? */ pos = 0; /* position = 0 because it's not in the file */ xsd->size = yasm_bc_next_offset(yasm_section_bcs_last(sect)); } else { pos = ftell(info->f); if (pos == -1) { yasm__fatal(N_("could not get file position on output file")); /*@notreached@*/ return 1; } info->sect = sect; info->xsd = xsd; yasm_section_bcs_traverse(sect, info->errwarns, info, xdf_objfmt_output_bytecode); /* Sanity check final section size */ if (xsd->size != yasm_bc_next_offset(yasm_section_bcs_last(sect))) yasm_internal_error( N_("xdf: section computed size did not match actual size")); } /* Empty? Go on to next section */ if (xsd->size == 0) return 0; xsd->scnptr = (unsigned long)pos; /* No relocations to output? Go on to next section */ if (xsd->nreloc == 0) return 0; pos = ftell(info->f); if (pos == -1) { yasm__fatal(N_("could not get file position on output file")); /*@notreached@*/ return 1; } xsd->relptr = (unsigned long)pos; reloc = (xdf_reloc *)yasm_section_relocs_first(sect); while (reloc) { unsigned char *localbuf = info->buf; /*@null@*/ xdf_symrec_data *xsymd; xsymd = yasm_symrec_get_data(reloc->reloc.sym, &xdf_symrec_data_cb); if (!xsymd) yasm_internal_error( N_("xdf: no symbol data for relocated symbol")); yasm_intnum_get_sized(reloc->reloc.addr, localbuf, 4, 32, 0, 0, 0); localbuf += 4; /* address of relocation */ YASM_WRITE_32_L(localbuf, xsymd->index); /* relocated symbol */ if (reloc->base) { xsymd = yasm_symrec_get_data(reloc->base, &xdf_symrec_data_cb); if (!xsymd) yasm_internal_error( N_("xdf: no symbol data for relocated base symbol")); YASM_WRITE_32_L(localbuf, xsymd->index); /* base symbol */ } else { if (reloc->type == XDF_RELOC_WRT) yasm_internal_error( N_("xdf: no base symbol for WRT relocation")); YASM_WRITE_32_L(localbuf, 0); /* no base symbol */ } YASM_WRITE_8(localbuf, reloc->type); /* type of relocation */ YASM_WRITE_8(localbuf, reloc->size); /* size of relocation */ YASM_WRITE_8(localbuf, reloc->shift); /* relocation shift */ YASM_WRITE_8(localbuf, 0); /* flags */ fwrite(info->buf, 16, 1, info->f); reloc = (xdf_reloc *)yasm_section_reloc_next((yasm_reloc *)reloc); } return 0; }