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
00028
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
00040
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
00054
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
00090 uword total_length;
00091
00092 uhalf version;
00093
00094
00095 uword prolog_length;
00096 ubyte minimum_instruction_length;
00097 ubyte default_is_stmt;
00098
00099 sbyte line_base;
00100
00101 ubyte line_range;
00102
00103 ubyte opcode_base;
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 } __attribute__((packed));
00114
00115
00116
00117
00118
00119
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
00129 static struct debug_line_header const default_debug_line_header = {
00130 -1,
00131 2,
00132 -1,
00133 1,
00134 1,
00135 -5,
00136 14,
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
00146 static struct compilation_unit_header const default_comp_unit_header = {
00147 -1,
00148 2,
00149 0,
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
00259
00260 add_data(b, "", 1);
00261
00262
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
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
00293
00294
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
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
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
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
00388 add_data(b, "", 1);
00389
00390
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 }