Home | History | Annotate | Download | only in dwarf2
      1 /*
      2  * DWARF2 debugging format - address range table
      3  *
      4  *  Copyright (C) 2006-2007  Peter Johnson
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
     16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
     19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  * POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 #include <util.h>
     28 
     29 #include <libyasm.h>
     30 
     31 #include "dwarf2-dbgfmt.h"
     32 
     33 
     34 static void
     35 dwarf2_append_arange(yasm_section *debug_aranges, /*@only@*/ yasm_expr *start,
     36                      /*@only@*/ yasm_expr *length, unsigned int sizeof_address)
     37 {
     38     yasm_datavalhead dvs;
     39     yasm_bytecode *bc;
     40 
     41     yasm_dvs_initialize(&dvs);
     42     yasm_dvs_append(&dvs, yasm_dv_create_expr(start));
     43     yasm_dvs_append(&dvs, yasm_dv_create_expr(length));
     44     bc = yasm_bc_create_data(&dvs, sizeof_address, 0, NULL, 0);
     45     yasm_bc_finalize(bc, yasm_dwarf2__append_bc(debug_aranges, bc));
     46     yasm_bc_calc_len(bc, NULL, NULL);
     47 }
     48 
     49 typedef struct dwarf2_aranges_info {
     50     yasm_section *debug_aranges;    /* section to which address ranges go */
     51     yasm_object *object;
     52     yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2;
     53 } dwarf2_aranges_info;
     54 
     55 static int
     56 dwarf2_generate_aranges_section(yasm_section *sect, /*@null@*/ void *d)
     57 {
     58     dwarf2_aranges_info *info = (dwarf2_aranges_info *)d;
     59     yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = info->dbgfmt_dwarf2;
     60     /*@null@*/ dwarf2_section_data *dsd;
     61     /*@only@*/ yasm_expr *start, *length;
     62 
     63     dsd = yasm_section_get_data(sect, &yasm_dwarf2__section_data_cb);
     64     if (!dsd)
     65         return 0;       /* no line data for this section */
     66 
     67     /* Create address range descriptor */
     68     start = yasm_expr_create_ident(
     69         yasm_expr_sym(yasm_dwarf2__bc_sym(info->object->symtab,
     70                                           yasm_section_bcs_first(sect))), 0);
     71     length = yasm_expr_create_ident(
     72         yasm_expr_int(yasm_calc_bc_dist(yasm_section_bcs_first(sect),
     73                                         yasm_section_bcs_last(sect))), 0);
     74     dwarf2_append_arange(info->debug_aranges, start, length,
     75                          dbgfmt_dwarf2->sizeof_address);
     76 
     77     return 0;
     78 }
     79 
     80 yasm_section *
     81 yasm_dwarf2__generate_aranges(yasm_object *object, yasm_section *debug_info)
     82 {
     83     yasm_dbgfmt_dwarf2 *dbgfmt_dwarf2 = (yasm_dbgfmt_dwarf2 *)object->dbgfmt;
     84     int new;
     85     yasm_section *debug_aranges;
     86     yasm_bytecode *bc;
     87     dwarf2_head *head;
     88     dwarf2_aranges_info info;
     89 
     90     debug_aranges =
     91         yasm_object_get_general(object, ".debug_aranges",
     92                                 2*dbgfmt_dwarf2->sizeof_address, 0, 0, &new,
     93                                 0);
     94 
     95     /* header */
     96     head = yasm_dwarf2__add_head(dbgfmt_dwarf2, debug_aranges, debug_info, 1,
     97                                  1);
     98 
     99     /* align ranges to 2x address size (range size) */
    100     bc = yasm_bc_create_align(
    101         yasm_expr_create_ident(yasm_expr_int(
    102             yasm_intnum_create_uint(dbgfmt_dwarf2->sizeof_address*2)), 0),
    103         NULL, NULL, NULL, 0);
    104     yasm_bc_finalize(bc, yasm_dwarf2__append_bc(debug_aranges, bc));
    105     yasm_bc_calc_len(bc, NULL, NULL);
    106 
    107     info.debug_aranges = debug_aranges;
    108     info.object = object;
    109     info.dbgfmt_dwarf2 = dbgfmt_dwarf2;
    110 
    111     yasm_object_sections_traverse(object, (void *)&info,
    112                                   dwarf2_generate_aranges_section);
    113 
    114     /* Terminate with empty address range descriptor */
    115     dwarf2_append_arange(debug_aranges,
    116         yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)), 0),
    117         yasm_expr_create_ident(yasm_expr_int(yasm_intnum_create_uint(0)), 0),
    118         dbgfmt_dwarf2->sizeof_address);
    119 
    120     /* mark end of aranges information */
    121     yasm_dwarf2__set_head_end(head, yasm_section_bcs_last(debug_aranges));
    122 
    123     return debug_aranges;
    124 }
    125 
    126