00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "config.h"
00043 #include "dwarf_incl.h"
00044 #include <stdio.h>
00045 #include <stdlib.h>
00046 #include "dwarf_line.h"
00047 #ifdef HAVE_ALLOCA_H
00048 #include <alloca.h>
00049 #endif
00050 #if ! defined(BUILD_OS_DARWIN)
00051 #include <malloc.h>
00052 #endif
00053
00054 #define MINIMUM_POSSIBLE_PROLOG_LEN 10
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 static int
00065 _dwarf_update_line_sec(Dwarf_Small * line_ptr,
00066 unsigned long remaining_bytes,
00067 int *any_change,
00068 int length_size,
00069 int *err_code, Dwarf_Small ** new_line_ptr);
00070
00071
00072
00073
00074 struct a_line_area {
00075 Dwarf_Addr ala_address;
00076 Dwarf_Unsigned ala_offset;
00077 Dwarf_Unsigned ala_length;
00078 int ala_entry_num;
00079 struct a_line_area *ala_next;
00080 };
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 int
00107 _dwarf_ld_sort_lines(void *orig_buffer,
00108 unsigned long buffer_len,
00109 int is_64_bit, int *any_change, int *err_code)
00110 {
00111
00112 int length_size = 4;
00113 Dwarf_Small *orig_line_ptr;
00114
00115 Dwarf_Small *line_ptr;
00116
00117
00118 Dwarf_Small *new_line_ptr;
00119
00120
00121
00122
00123 unsigned long remaining_bytes = buffer_len;
00124
00125
00126
00127
00128
00129
00130
00131 int sec_res;
00132 int lany_change = 0;
00133 int did_change = 0;
00134
00135 if (is_64_bit)
00136 length_size = 8;
00137
00138 *any_change = 0;
00139 line_ptr = malloc(buffer_len);
00140 if (!line_ptr) {
00141 *err_code = DW_DLE_ALLOC_FAIL;
00142 return DW_DLV_ERROR;
00143 }
00144 orig_line_ptr = line_ptr;
00145 memcpy(line_ptr, orig_buffer, buffer_len);
00146
00147
00148
00149
00150
00151
00152 sec_res = DW_DLV_OK;
00153
00154 for (sec_res = _dwarf_update_line_sec(line_ptr,
00155 remaining_bytes,
00156 &lany_change,
00157 length_size,
00158 err_code,
00159 &new_line_ptr);
00160 (sec_res == DW_DLV_OK) && (remaining_bytes > 0);
00161 sec_res = _dwarf_update_line_sec(line_ptr,
00162 remaining_bytes,
00163 &lany_change,
00164 length_size,
00165 err_code, &new_line_ptr)) {
00166 long bytes_used = new_line_ptr - line_ptr;
00167
00168 line_ptr = new_line_ptr;
00169 remaining_bytes -= bytes_used;
00170 if (lany_change) {
00171 did_change = 1;
00172 }
00173 if (remaining_bytes > 0) {
00174 continue;
00175 }
00176 break;
00177 }
00178 if (sec_res == DW_DLV_ERROR) {
00179 free(orig_line_ptr);
00180 return sec_res;
00181 }
00182
00183
00184
00185 if (did_change) {
00186
00187
00188
00189 memcpy(orig_buffer, orig_line_ptr, buffer_len);
00190 *any_change = 1;
00191 }
00192 free(orig_line_ptr);
00193
00194 return sec_res;
00195 }
00196
00197
00198
00199
00200
00201
00202 static int
00203 cmpr(const void *lin, const void *rin)
00204 {
00205 const struct a_line_area *l = lin;
00206 const struct a_line_area *r = rin;
00207
00208 if (l->ala_address < r->ala_address) {
00209 return -1;
00210 }
00211 if (l->ala_address > r->ala_address) {
00212 return 1;
00213 }
00214 if (l->ala_entry_num < r->ala_entry_num) {
00215 return -1;
00216 }
00217 if (l->ala_entry_num > r->ala_entry_num) {
00218 return 1;
00219 }
00220 return 0;
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 static int
00263 _dwarf_update_line_sec(Dwarf_Small * line_ptr,
00264 unsigned long remaining_bytes,
00265 int *any_change,
00266 int length_size,
00267 int *err_code, Dwarf_Small ** new_line_ptr)
00268 {
00269
00270
00271
00272
00273
00274 Dwarf_Small *line_ptr_end;
00275
00276
00277
00278
00279
00280 Dwarf_Small *check_line_ptr;
00281
00282 Dwarf_Small *orig_line_ptr;
00283
00284
00285 Dwarf_Unsigned total_length;
00286 Dwarf_Half version;
00287 Dwarf_Unsigned prologue_length;
00288 Dwarf_Small minimum_instruction_length;
00289 Dwarf_Small default_is_stmt;
00290 Dwarf_Sbyte line_base;
00291 Dwarf_Small line_range;
00292 Dwarf_Small opcode_base;
00293 struct Dwarf_Debug_s dbg_data;
00294 Dwarf_Debug dbg = &dbg_data;
00295
00296 Dwarf_Small *opcode_length = 0;
00297
00298
00299 Dwarf_Addr address;
00300 Dwarf_Word line;
00301 Dwarf_Bool is_stmt;
00302
00303 struct a_line_area *area_base = 0;
00304 struct a_line_area *area_current = 0;
00305 long area_count = 0;
00306
00307 Dwarf_Addr last_address = 0;
00308 int need_to_sort = 0;
00309
00310 Dwarf_Sword i;
00311 Dwarf_Sword file_entry_count;
00312 Dwarf_Sword include_directories_count;
00313
00314
00315
00316 Dwarf_Small opcode;
00317
00318
00319
00320
00321
00322
00323 Dwarf_Word leb128_num;
00324 Dwarf_Word leb128_length;
00325 Dwarf_Sword advance_line;
00326
00327
00328
00329
00330 Dwarf_Half fixed_advance_pc;
00331
00332
00333 Dwarf_Word instr_length;
00334 Dwarf_Small ext_opcode;
00335
00336
00337
00338 dbg->de_copy_word = memcpy;
00339
00340
00341
00342 *any_change = 0;
00343 orig_line_ptr = line_ptr;
00344 if(remaining_bytes < MINIMUM_POSSIBLE_PROLOG_LEN) {
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 return(DW_DLV_NO_ENTRY);
00355 }
00356
00357 READ_UNALIGNED(dbg, total_length, Dwarf_Unsigned,
00358 line_ptr, length_size);
00359 line_ptr += length_size;
00360 line_ptr_end = line_ptr + total_length;
00361 if (line_ptr_end > line_ptr + remaining_bytes) {
00362 *err_code = DW_DLE_DEBUG_LINE_LENGTH_BAD;
00363 return (DW_DLV_ERROR);
00364 }
00365
00366 *new_line_ptr = line_ptr_end;
00367 READ_UNALIGNED(dbg, version, Dwarf_Half,
00368 line_ptr, sizeof(Dwarf_Half));
00369 line_ptr += sizeof(Dwarf_Half);
00370 if (version != CURRENT_VERSION_STAMP) {
00371 *err_code = DW_DLE_VERSION_STAMP_ERROR;
00372 return (DW_DLV_ERROR);
00373 }
00374
00375 READ_UNALIGNED(dbg, prologue_length, Dwarf_Unsigned,
00376 line_ptr, length_size);
00377 line_ptr += length_size;
00378 check_line_ptr = line_ptr;
00379
00380 minimum_instruction_length = *(Dwarf_Small *) line_ptr;
00381 line_ptr = line_ptr + sizeof(Dwarf_Small);
00382
00383 default_is_stmt = *(Dwarf_Small *) line_ptr;
00384 line_ptr = line_ptr + sizeof(Dwarf_Small);
00385
00386 line_base = *(Dwarf_Sbyte *) line_ptr;
00387 line_ptr = line_ptr + sizeof(Dwarf_Sbyte);
00388
00389 line_range = *(Dwarf_Small *) line_ptr;
00390 line_ptr = line_ptr + sizeof(Dwarf_Small);
00391
00392 opcode_base = *(Dwarf_Small *) line_ptr;
00393 line_ptr = line_ptr + sizeof(Dwarf_Small);
00394
00395 opcode_length = (Dwarf_Small *)
00396 alloca(sizeof(Dwarf_Small) * opcode_base);
00397 for (i = 1; i < opcode_base; i++) {
00398 opcode_length[i] = *(Dwarf_Small *) line_ptr;
00399 line_ptr = line_ptr + sizeof(Dwarf_Small);
00400 }
00401
00402 include_directories_count = 0;
00403 while ((*(char *) line_ptr) != '\0') {
00404 line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
00405 include_directories_count++;
00406 }
00407 line_ptr++;
00408
00409 file_entry_count = 0;
00410 while (*(char *) line_ptr != '\0') {
00411
00412
00413
00414 line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
00415
00416
00417 _dwarf_decode_u_leb128(line_ptr, &leb128_length);
00418 line_ptr = line_ptr + leb128_length;
00419
00420
00421 _dwarf_decode_u_leb128(line_ptr, &leb128_length);
00422 line_ptr = line_ptr + leb128_length;
00423
00424
00425 _dwarf_decode_u_leb128(line_ptr, &leb128_length);
00426 line_ptr = line_ptr + leb128_length;
00427
00428 file_entry_count++;
00429 }
00430 line_ptr++;
00431
00432 if (line_ptr != check_line_ptr + prologue_length) {
00433 *err_code = DW_DLE_LINE_PROLOG_LENGTH_BAD;
00434 return (DW_DLV_ERROR);
00435 }
00436
00437
00438 address = 0;
00439
00440 line = 1;
00441
00442 is_stmt = default_is_stmt;
00443
00444
00445
00446
00447 while (line_ptr < line_ptr_end) {
00448 int type;
00449
00450 Dwarf_Small *stmt_prog_entry_start = line_ptr;
00451
00452 opcode = *(Dwarf_Small *) line_ptr;
00453 line_ptr++;
00454
00455 WHAT_IS_OPCODE(type, opcode, opcode_base,
00456 opcode_length, line_ptr);
00457
00458
00459
00460 if (type == LOP_DISCARD) {
00461
00462 } else if (type == LOP_SPECIAL) {
00463 opcode = opcode - opcode_base;
00464 address = address + minimum_instruction_length *
00465 (opcode / line_range);
00466 line = line + line_base + opcode % line_range;
00467
00468
00469
00470
00471 } else if (type == LOP_STANDARD) {
00472
00473
00474 switch (opcode) {
00475
00476
00477 case DW_LNS_copy:{
00478 if (opcode_length[DW_LNS_copy] != 0) {
00479 *err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
00480 return (DW_DLV_ERROR);
00481 }
00482
00483
00484
00485 break;
00486 }
00487
00488 case DW_LNS_advance_pc:{
00489 Dwarf_Unsigned utmp2;
00490
00491 if (opcode_length[DW_LNS_advance_pc] != 1) {
00492 *err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
00493 return (DW_DLV_ERROR);
00494 }
00495
00496 DECODE_LEB128_UWORD(line_ptr, utmp2)
00497 leb128_num = (Dwarf_Word) utmp2;
00498 address =
00499 address +
00500 minimum_instruction_length * leb128_num;
00501 break;
00502 }
00503
00504 case DW_LNS_advance_line:{
00505 Dwarf_Signed stmp;
00506
00507 if (opcode_length[DW_LNS_advance_line] != 1) {
00508 *err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
00509 return (DW_DLV_ERROR);
00510 }
00511
00512 DECODE_LEB128_SWORD(line_ptr, stmp)
00513 advance_line = (Dwarf_Sword) stmp;
00514 line = line + advance_line;
00515 break;
00516 }
00517
00518 case DW_LNS_set_file:{
00519 Dwarf_Unsigned utmp2;
00520
00521 if (opcode_length[DW_LNS_set_file] != 1) {
00522 *err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
00523 return (DW_DLV_ERROR);
00524 }
00525
00526 DECODE_LEB128_UWORD(line_ptr, utmp2)
00527
00528 break;
00529 }
00530
00531 case DW_LNS_set_column:{
00532 Dwarf_Unsigned utmp2;
00533
00534 if (opcode_length[DW_LNS_set_column] != 1) {
00535 *err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
00536 return (DW_DLV_ERROR);
00537 }
00538
00539 DECODE_LEB128_UWORD(line_ptr, utmp2)
00540
00541 break;
00542 }
00543
00544 case DW_LNS_negate_stmt:{
00545 if (opcode_length[DW_LNS_negate_stmt] != 0) {
00546 *err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
00547 return (DW_DLV_ERROR);
00548 }
00549
00550 is_stmt = !is_stmt;
00551 break;
00552 }
00553
00554 case DW_LNS_set_basic_block:{
00555 if (opcode_length[DW_LNS_set_basic_block] != 0) {
00556 *err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
00557 return (DW_DLV_ERROR);
00558 }
00559
00560
00561 break;
00562 }
00563
00564 case DW_LNS_const_add_pc:{
00565 opcode = MAX_LINE_OP_CODE - opcode_base;
00566 address = address + minimum_instruction_length *
00567 (opcode / line_range);
00568
00569 break;
00570 }
00571
00572 case DW_LNS_fixed_advance_pc:{
00573 if (opcode_length[DW_LNS_fixed_advance_pc] != 1) {
00574 *err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
00575 return (DW_DLV_ERROR);
00576 }
00577
00578 READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
00579 line_ptr, sizeof(Dwarf_Half));
00580 line_ptr += sizeof(Dwarf_Half);
00581 address = address + fixed_advance_pc;
00582 break;
00583 }
00584 }
00585 } else if (type == LOP_EXTENDED) {
00586
00587
00588 Dwarf_Unsigned utmp3;
00589
00590 DECODE_LEB128_UWORD(line_ptr, utmp3)
00591 instr_length = (Dwarf_Word) utmp3;
00592 ext_opcode = *(Dwarf_Small *) line_ptr;
00593 line_ptr++;
00594 switch (ext_opcode) {
00595
00596 case DW_LNE_end_sequence:{
00597
00598
00599 address = 0;
00600
00601 line = 1;
00602
00603 is_stmt = default_is_stmt;
00604
00605
00606
00607 break;
00608 }
00609
00610 case DW_LNE_set_address:{
00611 if (instr_length - 1 == length_size) {
00612 struct a_line_area *area;
00613
00614 READ_UNALIGNED(dbg, address, Dwarf_Addr,
00615 line_ptr, length_size);
00616
00617
00618
00619 if (address < last_address) {
00620 need_to_sort = 1;
00621 }
00622 last_address = address;
00623
00624 area = alloca(sizeof(struct a_line_area));
00625 area->ala_address = address;
00626 area->ala_offset = stmt_prog_entry_start -
00627 orig_line_ptr;
00628 area->ala_entry_num = area_count;
00629 area->ala_next = 0;
00630 area->ala_length = 0;
00631 if (area_current) {
00632 area_current->ala_next = area;
00633 area_current->ala_length =
00634 area->ala_offset -
00635 area_current->ala_offset;
00636 }
00637 ++area_count;
00638 area_current = area;
00639 if (area_base == 0) {
00640 area_base = area;
00641 }
00642
00643 line_ptr += length_size;
00644 } else {
00645 *err_code = DW_DLE_LINE_SET_ADDR_ERROR;
00646 return (DW_DLV_ERROR);
00647 }
00648
00649
00650 break;
00651 }
00652
00653 case DW_LNE_define_file:{
00654
00655 break;
00656 }
00657
00658 default:{
00659 *err_code = DW_DLE_LINE_EXT_OPCODE_BAD;
00660 return (DW_DLV_ERROR);
00661 }
00662 }
00663
00664 }
00665 }
00666
00667
00668 if (!need_to_sort) {
00669 return (DW_DLV_OK);
00670 }
00671
00672
00673
00674 area_current->ala_length = (line_ptr - orig_line_ptr)
00675
00676 -area_current->ala_offset;
00677
00678
00679
00680
00681
00682
00683
00684
00685 {
00686 struct a_line_area *ala_array;
00687 struct a_line_area *local;
00688 long start_len;
00689 Dwarf_Small *new_area;
00690 long i;
00691
00692 ala_array = malloc(area_count * sizeof(struct a_line_area));
00693 if (!ala_array) {
00694 *err_code = DW_DLE_ALLOC_FAIL;
00695 return DW_DLV_ERROR;
00696 }
00697
00698 for (local = area_base, i = 0; local;
00699 local = local->ala_next, ++i) {
00700
00701 ala_array[i] = *local;
00702 }
00703
00704 qsort(ala_array, area_count, sizeof(struct a_line_area), cmpr);
00705
00706
00707
00708 start_len = (check_line_ptr + prologue_length) - orig_line_ptr;
00709 new_area = malloc(remaining_bytes);
00710 if (!new_area) {
00711 free(ala_array);
00712 *err_code = DW_DLE_ALLOC_FAIL;
00713 return DW_DLV_ERROR;
00714 }
00715 memcpy(new_area, orig_line_ptr, start_len);
00716 line_ptr = new_area + start_len;
00717 for (i = 0; i < area_count; ++i) {
00718 memcpy(line_ptr, orig_line_ptr +
00719 ala_array[i].ala_offset, ala_array[i].ala_length);
00720 line_ptr += ala_array[i].ala_length;
00721 }
00722
00723 memcpy(orig_line_ptr, new_area, remaining_bytes);
00724
00725 free(new_area);
00726 free(ala_array);
00727 ala_array = 0;
00728 new_area = 0;
00729 }
00730
00731 *any_change = 1;
00732 return (DW_DLV_OK);
00733 }