debug_line.c

Go to the documentation of this file.
00001 
00011 #include "config.h"
00012 #include <stdint.h>
00013 #include <stdlib.h>
00014 #include <string.h>
00015 #include <stddef.h>
00016 #include <stdio.h>
00017 #include <bfd.h>
00018 #include <limits.h>
00019 
00020 #include "opjitconv.h"
00021 #include "jitdump.h"
00022 #include "opagent.h"
00023 #include "op_libiberty.h"
00024 #include "op_growable_buffer.h"
00025 
00026 /*
00027  * Terminology comes from the TIS DWARF Debugging Information Format
00028  * version 2.0
00029  */
00030 
00031 typedef uint32_t uword;
00032 typedef uint16_t uhalf;
00033 typedef int32_t  sword;
00034 typedef int16_t  shalf;
00035 typedef uint8_t  ubyte;
00036 typedef int8_t   sbyte;
00037 
00038 /*
00039  * Many of the following enum are incomplete and define only the subset
00040  * of DWARF we use.
00041  */
00042 enum lns_opcode {
00043     DW_LNS_copy=1,
00044     DW_LNS_advance_pc,
00045     DW_LNS_advance_line,
00046     DW_LNS_set_file,
00047     DW_LNS_set_column,
00048     DW_LNS_negate_stmt,
00049     DW_LNS_set_basic_block,
00050     DW_LNS_const_add_pc,
00051     DW_LNS_fixed_advance_pc,
00052 
00053     /* Adding new opcode needs an update of the standard_opcode_length
00054      * array */
00055 
00056     DW_LNS_max_opcode,
00057 };
00058 
00059 enum lne_opcode {
00060     DW_LNE_end_sequence = 1,
00061     DW_LNE_set_address,
00062     DW_LNE_define_file
00063 };
00064 
00065 enum dw_tag {
00066     DW_TAG_compile_unit = 0x11,
00067 };
00068 
00069 enum dw_at {
00070     DW_AT_name = 0x03,
00071     DW_AT_stmt_list = 0x10,
00072     DW_AT_low_pc,
00073     DW_AT_high_pc,
00074     DW_AT_language,
00075     DW_AT_compdir = 0x1b,
00076     DW_AT_producer = 0x25,
00077 };
00078 
00079 enum dw_children {
00080     DW_CHILDREN_no,
00081     DW_CHILDREN_yes
00082 };
00083 
00084 enum dw_form {
00085     DW_FORM_data4 = 0x06,
00086 };
00087 
00088 struct debug_line_header {
00089     // Not counting this field
00090     uword total_length;
00091     // version number (2 currently)
00092     uhalf version;
00093     // relative offset from next field to
00094     // program statement
00095     uword prolog_length;
00096     ubyte minimum_instruction_length;
00097     ubyte default_is_stmt;
00098     // line_base - see DWARF 2 specs
00099     sbyte line_base;
00100     // line_range - see DWARF 2 specs
00101     ubyte line_range;
00102     // number of opcode + 1
00103     ubyte opcode_base;
00104     /* follow the array of opcode args nr: ubytes [nr_opcode_base] */
00105     /* follow the search directories index, zero terminated string
00106      * terminated by an empty string.
00107      */
00108     /* follow an array of { filename, LEB128, LEB128, LEB128 }, first is
00109      * the directory index entry, 0 means current directory, then mtime
00110      * and filesize, last entry is followed by en empty string.
00111      */
00112     /* follow the first program statement */
00113 } __attribute__((packed));
00114 
00115 /* DWARF 2 spec talk only about one possible compilation unit header while
00116  * binutils can handle two flavours of dwarf 2, 32 and 64 bits, this is not
00117  * related to the used arch, an ELF 32 can hold more than 4 Go of debug
00118  * information. For now we handle only DWARF 2 32 bits comp unit. It'll only
00119  * become a problem if we generate more than 4GB of debug information.
00120  */
00121 struct compilation_unit_header {
00122     uword total_length;
00123     uhalf version;
00124     uword debug_abbrev_offset;
00125     ubyte pointer_size;
00126 } __attribute__((packed));
00127 
00128 /* field filled at run time are marked with -1 */
00129 static struct debug_line_header const default_debug_line_header = {
00130     -1,
00131     2,
00132     -1,
00133     1,  /* could be better when min instruction size != 1 */
00134     1,  /* we don't take care about basic block */
00135     -5, /* sensible value for line base ... */
00136     14,     /* ... and line range are guessed statically */
00137     DW_LNS_max_opcode
00138 };
00139 
00140 static ubyte const standard_opcode_length[DW_LNS_max_opcode - 1] =
00141 {
00142     0, 1, 1, 1, 1, 0, 0, 0, 1
00143 };
00144 
00145 /* field filled at run time are marked with -1 */
00146 static struct compilation_unit_header const default_comp_unit_header = {
00147     -1,
00148     2,
00149     0,     /* we reuse the same abbrev entries for all comp unit */
00150     -1
00151 };
00152 
00153 
00154 static void emit_uword(struct growable_buffer * b, uword data)
00155 {
00156     add_data(b, &data, sizeof(uword));
00157 }
00158 
00159 
00160 static void emit_string(struct growable_buffer * b, char const * s)
00161 {
00162     add_data(b, s, strlen(s) + 1);
00163 }
00164 
00165 
00166 static void emit_unsigned_LEB128(struct growable_buffer * b,
00167                  unsigned long data)
00168 {
00169     do {
00170         ubyte cur = data & 0x7F;
00171         data >>= 7;
00172         if (data)
00173             cur |= 0x80;
00174         add_data(b, &cur, 1);
00175     } while (data);
00176 }
00177 
00178 
00179 static void emit_signed_LEB128(struct growable_buffer * b, long data)
00180 {
00181     int more = 1;
00182     int negative = data < 0;
00183     int size = sizeof(long) * CHAR_BIT;
00184     while (more) {
00185         ubyte cur = data & 0x7F;
00186         data >>= 7;
00187         if (negative)
00188             data |= - (1 << (size - 7));
00189         if ((data == 0 && !(cur & 0x40)) ||
00190             (data == -1l && (cur & 0x40)))
00191             more = 0;
00192         else
00193             cur |= 0x80;
00194         add_data(b, &cur, 1);
00195     }
00196 }
00197 
00198 
00199 static void emit_extended_opcode(struct growable_buffer * b, ubyte opcode,
00200                  void * data, size_t data_len)
00201 {
00202     add_data(b, "", 1);
00203     emit_unsigned_LEB128(b, data_len + 1);
00204     add_data(b, &opcode, 1);
00205     add_data(b, data, data_len);
00206 }
00207 
00208 
00209 static void emit_opcode(struct growable_buffer * b, ubyte opcode)
00210 {
00211     add_data(b, &opcode, 1);
00212 }
00213 
00214 
00215 static void emit_opcode_signed(struct growable_buffer * b,
00216                    ubyte opcode, long data)
00217 {
00218     add_data(b, &opcode, 1);
00219     emit_signed_LEB128(b, data);
00220 }
00221 
00222 
00223 static void emit_opcode_unsigned(struct growable_buffer * b, ubyte opcode, 
00224                  unsigned long data)
00225 {
00226     add_data(b, &opcode, 1);
00227     emit_unsigned_LEB128(b, data);
00228 }
00229 
00230 
00231 static void emit_advance_pc(struct growable_buffer * b, unsigned long delta_pc)
00232 {
00233     emit_opcode_unsigned(b, DW_LNS_advance_pc, delta_pc);
00234 }
00235 
00236 
00237 static void emit_advance_lineno(struct growable_buffer * b, long delta_lineno)
00238 {
00239     emit_opcode_signed(b, DW_LNS_advance_line, delta_lineno);
00240 }
00241 
00242 
00243 static void emit_lne_end_of_sequence(struct growable_buffer * b)
00244 {
00245     emit_extended_opcode(b, DW_LNE_end_sequence, NULL, 0);
00246 }
00247 
00248 
00249 static void emit_set_file(struct growable_buffer * b, unsigned long index)
00250 {
00251     emit_opcode_unsigned(b, DW_LNS_set_file, index);
00252 }
00253 
00254 
00255 static void emit_lne_define_filename(struct growable_buffer * b,
00256                      char const * filename)
00257 {
00258     /* emit_extended_opcode() can't be used here, we have additional
00259      * data to output and the len field will be miscalculated. */
00260     add_data(b, "", 1);
00261     /* strlen(filename) + zero terminator + len field + 3 bytes for the dir
00262      * entry, timestamp and filesize */
00263     emit_unsigned_LEB128(b, strlen(filename) + 5);
00264     emit_opcode(b, DW_LNE_define_file);
00265     emit_string(b, filename);
00266     add_data(b, "\0\0\0", 3);
00267 }
00268 
00269 
00270 static void emit_lne_set_address(struct growable_buffer * b,
00271                  void const * address)
00272 {
00273     emit_extended_opcode(b, DW_LNE_set_address, &address, sizeof(address));
00274 }
00275 
00276 
00277 static ubyte get_special_opcode(struct debug_line_info const * line,
00278     unsigned int last_lineno, unsigned long last_vma)
00279 {
00280     unsigned int temp;
00281     unsigned long delta_addr;
00282 
00283     /* See TIS DWARF Debugging Information Format version 2.0 § 6.2.5.1 */
00284 
00285     temp = (line->lineno - last_lineno) -
00286         default_debug_line_header.line_base;
00287     if (temp >= default_debug_line_header.line_range)
00288         return 0;
00289 
00290     delta_addr = (line->vma - last_vma) /
00291         default_debug_line_header.minimum_instruction_length;
00292     /* This is not sufficient to ensure opcode will be in [0-256] but
00293      * sufficient to ensure when summing with the delta lineno we will
00294      * not overflow the unsigned long opcode */
00295     if (delta_addr <= 256 / default_debug_line_header.line_range) {
00296         unsigned long opcode = temp +
00297             (delta_addr * default_debug_line_header.line_range) +
00298             default_debug_line_header.opcode_base;
00299 
00300         return opcode <= 255 ? opcode : 0;
00301     }
00302 
00303     return 0;
00304 }
00305 
00306 
00307 static void emit_lineno_info(struct growable_buffer * b,
00308     struct debug_line_info const * line, size_t nr_entry,
00309     unsigned long code_addr)
00310 {
00311     size_t i;
00312 
00313     /*
00314      * Machine state at start of a statement program
00315      * address = 0
00316      * file    = 1
00317      * line    = 1
00318      * column  = 0
00319      * is_stmt = default_is_stmt as given in the debug_line_header
00320      * basic block = 0
00321      * end sequence = 0
00322      */
00323 
00324     /* start state of the state machine we take care of */
00325     unsigned long last_vma = code_addr;
00326     unsigned int last_lineno = 1;
00327     char const  * cur_filename = NULL;
00328     unsigned long cur_file_index = 0;
00329 
00330     /* FIXME: relocatable address? */
00331     emit_lne_set_address(b, (void const *)code_addr);
00332     emit_advance_lineno(b, line[0].lineno - last_lineno);
00333     last_lineno = line[0].lineno;
00334     emit_lne_define_filename(b, line[0].filename);
00335     cur_filename = line[0].filename;
00336     emit_set_file(b, ++cur_file_index);
00337     emit_opcode(b, DW_LNS_copy);
00338     
00339 
00340     for (i = 0; i < nr_entry; i++) {
00341         int need_copy = 0;
00342         ubyte special_opcode;
00343 
00344         if (!cur_filename || strcmp(cur_filename, line[i].filename)) {
00345             emit_lne_define_filename(b, line[i].filename);
00346             cur_filename = line[i].filename;
00347             emit_set_file(b, ++cur_file_index);
00348             need_copy = 1;
00349         }
00350         if ((special_opcode = get_special_opcode(&line[i],
00351                 last_lineno, last_vma)) != 0) {
00352             last_lineno = line[i].lineno;
00353             last_vma = line[i].vma;
00354             emit_opcode(b, special_opcode);
00355         } else {
00356             if (last_lineno != line[i].lineno) {
00357                 emit_advance_lineno(b,
00358                     line[i].lineno - last_lineno);
00359                 last_lineno = line[i].lineno;
00360                 need_copy = 1;
00361             }
00362             if (last_vma != line[i].vma) {
00363                 emit_advance_pc(b, line[i].vma - last_vma);
00364                 last_vma = line[i].vma;
00365                 need_copy = 1;
00366             }
00367             if (need_copy)
00368                 emit_opcode(b, DW_LNS_copy);
00369         }
00370     }
00371 }
00372 
00373 
00374 static void add_debug_line(struct growable_buffer * b,
00375     struct debug_line_info const * line, size_t nr_entry,
00376     unsigned long code_addr)
00377 {
00378     struct debug_line_header * dbg_header;
00379     size_t old_size;
00380 
00381     old_size = b->size;
00382 
00383     add_data(b, &default_debug_line_header,
00384          sizeof(default_debug_line_header));
00385     add_data(b, &standard_opcode_length,  sizeof(standard_opcode_length));
00386 
00387     // empty directory entry
00388     add_data(b, "", 1);
00389 
00390     // empty filename directory
00391     add_data(b, "", 1);
00392 
00393     dbg_header = b->p + old_size;
00394     dbg_header->prolog_length = (b->size - old_size) -
00395         offsetof(struct debug_line_header, minimum_instruction_length);
00396 
00397     emit_lineno_info(b, line, nr_entry, code_addr);
00398 
00399     emit_lne_end_of_sequence(b);
00400 
00401     dbg_header = b->p + old_size;
00402     dbg_header->total_length = (b->size - old_size) -
00403         offsetof(struct debug_line_header, version);
00404 }
00405 
00406 
00407 static void add_compilation_unit(struct growable_buffer * b,
00408                  size_t offset_debug_line)
00409 {
00410     struct compilation_unit_header * comp_unit_header;
00411 
00412     size_t old_size = b->size;
00413 
00414     add_data(b, &default_comp_unit_header,
00415          sizeof(default_comp_unit_header));
00416 
00417     emit_unsigned_LEB128(b, 1);
00418     emit_uword(b, offset_debug_line);
00419 
00420     comp_unit_header = b->p + old_size;
00421     comp_unit_header->total_length = (b->size - old_size) -
00422         offsetof(struct compilation_unit_header, version);
00423     comp_unit_header->pointer_size = sizeof(void *);
00424 }
00425 
00426 
00427 static void create_debug_abbrev(struct growable_buffer * b)
00428 {
00429     emit_unsigned_LEB128(b, 1);
00430     emit_unsigned_LEB128(b, DW_TAG_compile_unit);
00431     emit_unsigned_LEB128(b, DW_CHILDREN_yes);
00432     emit_unsigned_LEB128(b, DW_AT_stmt_list);
00433     emit_unsigned_LEB128(b, DW_FORM_data4);
00434     emit_unsigned_LEB128(b, 0);
00435 }
00436 
00437 static struct growable_buffer b_line;
00438 static struct growable_buffer b_debug_info;
00439 static struct growable_buffer b_debug_abbrev;
00440 
00441 int init_debug_line_info(bfd * abfd)
00442 {
00443     asection * line_section, * debug_info, * debug_abbrev;
00444     struct jitentry_debug_line * debug_line;
00445 
00446     init_buffer(&b_line);
00447     init_buffer(&b_debug_info);
00448     init_buffer(&b_debug_abbrev);
00449 
00450     for (debug_line = jitentry_debug_line_list;
00451          debug_line;
00452          debug_line = debug_line->next) {
00453         struct jr_code_debug_info const * rec = debug_line->data;
00454         if (rec->nr_entry) {
00455             size_t i;
00456             void const * data = rec + 1;
00457             struct debug_line_info * dbg_line =
00458                 xmalloc(rec->nr_entry *
00459                     sizeof(struct debug_line_info));
00460             for (i = 0; i < rec->nr_entry; ++i) {
00461                 dbg_line[i].vma = *(unsigned long *)data;
00462                 data += sizeof(unsigned long);
00463                 dbg_line[i].lineno = *(unsigned int *)data;
00464                 data += sizeof(unsigned int);
00465                 dbg_line[i].filename = data;
00466                 data += strlen(data) + 1;
00467             }
00468 
00469             add_compilation_unit(&b_debug_info, b_line.size);
00470             add_debug_line(&b_line, dbg_line,
00471                        rec->nr_entry, rec->code_addr);
00472             create_debug_abbrev(&b_debug_abbrev);
00473 
00474             free(dbg_line);
00475         }
00476     }
00477     
00478     line_section = create_section(abfd, ".debug_line", b_line.size, 0,
00479         SEC_HAS_CONTENTS|SEC_READONLY|SEC_DEBUGGING);
00480     if (!line_section)
00481         return -1;
00482 
00483     debug_info = create_section(abfd, ".debug_info", b_debug_info.size, 0,
00484         SEC_HAS_CONTENTS|SEC_READONLY|SEC_DEBUGGING);
00485     if (!debug_info)
00486         return -1;
00487 
00488     debug_abbrev = create_section(abfd, ".debug_abbrev",
00489         b_debug_abbrev.size, 0,
00490         SEC_HAS_CONTENTS|SEC_READONLY|SEC_DEBUGGING);
00491     if (!debug_abbrev)
00492         return -1;
00493 
00494     return 0;
00495 }
00496 
00497 
00498 int finalize_debug_line_info(bfd * abfd)
00499 {
00500     asection * line_section, * debug_info, * debug_abbrev;
00501 
00502     line_section = bfd_get_section_by_name(abfd, ".debug_line");
00503     if (!line_section)
00504         return -1;
00505 
00506     debug_info = bfd_get_section_by_name(abfd, ".debug_info");
00507     if (!debug_info)
00508         return -1;
00509 
00510 
00511     debug_abbrev = bfd_get_section_by_name(abfd, ".debug_abbrev");
00512     if (!debug_abbrev)
00513         return -1;
00514 
00515     fill_section_content(abfd, line_section, b_line.p, 0, b_line.size);
00516     fill_section_content(abfd, debug_info, b_debug_info.p,
00517                  0, b_debug_info.size);
00518     fill_section_content(abfd, debug_abbrev, b_debug_abbrev.p, 0,
00519                  b_debug_abbrev.size);
00520 
00521 
00522     free_buffer(&b_line);
00523     free_buffer(&b_debug_info);
00524     free_buffer(&b_debug_abbrev);
00525 
00526     return 0;
00527 }

Generated on 8 Nov 2012 for Oprofile by  doxygen 1.6.1