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_stuff.h"
00044 #include "libdwarfdefs.h"
00045 #include <stdio.h>
00046 #include <stdlib.h>
00047 #include <string.h>
00048 #ifdef HAVE_ELFACCESS_H
00049 #include <elfaccess.h>
00050 #endif
00051 #include "pro_incl.h"
00052 #include "pro_section.h"
00053 #include "pro_line.h"
00054 #include "pro_frame.h"
00055 #include "pro_die.h"
00056 #include "pro_macinfo.h"
00057 #include "pro_types.h"
00058
00059 int
00060 _dwf_pro_generate_ehframe(Dwarf_P_Debug dbg, Dwarf_Error *error)
00061 {
00062 int elfsectno;
00063 int i;
00064 int firsttime = 1;
00065 #ifdef TARG_IA64
00066 int pad;
00067 #endif
00068 Dwarf_P_Cie curcie;
00069 Dwarf_P_Fde curfde;
00070 unsigned char *data;
00071 Dwarf_Signed dsw;
00072 Dwarf_Ubyte Personality_Format;
00073 Dwarf_Unsigned du;
00074 Dwarf_Ubyte db;
00075 long *cie_offs;
00076 unsigned long cie_length;
00077 int cie_no;
00078 int uwordb_size = dbg->de_offset_size;
00079 int extension_size = dbg->de_64bit_extension? 4:0;
00080 int upointer_size = dbg->de_pointer_size;
00081 Dwarf_Unsigned cur_off;
00082
00083
00084 if (generate_fpic_dwarf)
00085 {
00086 upointer_size = 4;
00087 Personality_Format = 0x9b;
00088 } else {
00089 Personality_Format = 0;
00090 }
00091
00092 elfsectno = dbg->de_elf_sects[EH_FRAME];
00093
00094 curcie = dbg->de_eh_frame_cies;
00095 cie_length = 0;
00096 cur_off = 0;
00097 cie_offs = (long *)
00098 _dwarf_p_get_alloc(dbg, sizeof(long)*dbg->de_eh_n_cie);
00099 if (cie_offs == NULL) {
00100 DWARF_P_DBG_ERROR(dbg,DW_DLE_CIE_OFFS_ALLOC,-1);
00101 }
00102
00103 cie_no = 1;
00104 while (curcie) {
00105 char *code_al;
00106 int c_bytes;
00107 char *data_al;
00108 int d_bytes;
00109 int res;
00110 char buff1[ENCODE_SPACE_NEEDED];
00111 char buff2[ENCODE_SPACE_NEEDED];
00112 char buff3[ENCODE_SPACE_NEEDED];
00113 const char *augmentation;
00114 char *augmented_al;
00115 long augmented_fields_length;
00116 int a_bytes;
00117
00118 Dwarf_Unsigned personality = curcie->cie_personality;
00119 int personality_length = personality ? upointer_size : 0;
00120
00121 if (cie_no != 1) {
00122 fprintf (stderr,"Implement multiple CIE's");
00123 abort();
00124 }
00125
00126 res = dbg->de_reloc_name(dbg, EH_FRAME,
00127 extension_size,
00128 0,
00129 #ifdef TARG_IA64
00130 dwarf_drt_none,
00131 #else
00132 dwarf_drt_cie_begin,
00133 #endif
00134 uwordb_size);
00135 if (res != DW_DLV_OK) {
00136 DWARF_P_DBG_ERROR(dbg,DW_DLE_CHUNK_ALLOC,-1);
00137 }
00138
00139 res = dbg->de_reloc_name(dbg, EH_FRAME,
00140 extension_size+uwordb_size,
00141 0,
00142 dwarf_drt_none,
00143 uwordb_size);
00144 if (res != DW_DLV_OK) {
00145 DWARF_P_DBG_ERROR(dbg,DW_DLE_CHUNK_ALLOC,-1);
00146 }
00147 res = _dwarf_pro_encode_leb128_nm(curcie->cie_code_align,
00148 &c_bytes,
00149 buff1,sizeof(buff1));
00150 if (res != DW_DLV_OK) {
00151 DWARF_P_DBG_ERROR(dbg,DW_DLE_CIE_OFFS_ALLOC,-1);
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 res = _dwarf_pro_encode_signed_leb128_nm(curcie->cie_data_align,
00172 &d_bytes,
00173 buff2,sizeof(buff2));
00174 if (res != DW_DLV_OK) {
00175 DWARF_P_DBG_ERROR(dbg,DW_DLE_CIE_OFFS_ALLOC,-1);
00176 }
00177 code_al = buff1;
00178 data_al = buff2;
00179
00180
00181 if (firsttime) {
00182 cie_offs[cie_no-1] = 0 ;
00183 firsttime = 0;
00184 } else {
00185 cie_offs[cie_no-1] = cie_offs[cie_no-2] +
00186 (long)cie_length +
00187 uwordb_size + extension_size;
00188 }
00189 cie_no++;
00190 augmentation = curcie->cie_aug;
00191 if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0
00192 || !strcmp(augmentation, PIC_DW_CIE_AUGMENTER_STRING_V0)
00193
00194 || !strcmp(augmentation,
00195 PIC_NONCPLUS_DW_CIE_AUGMENTER_STRING_V0)
00196 ) {
00197 if (!strcmp(augmentation,
00198 PIC_NONCPLUS_DW_CIE_AUGMENTER_STRING_V0)) {
00199 augmented_fields_length = 1;
00200 Personality_Format = 0x1b;
00201 }
00202 else if (generate_fpic_dwarf)
00203 augmented_fields_length = 7;
00204 else
00205 augmented_fields_length = generate_m64_dwarf ? 10 : 6;
00206 res = _dwarf_pro_encode_leb128_nm(augmented_fields_length,
00207 &a_bytes, buff3,
00208 sizeof(buff3));
00209 augmented_al = buff3;
00210 if (res != DW_DLV_OK) {
00211 DWARF_P_DBG_ERROR(dbg,DW_DLE_CIE_OFFS_ALLOC,-1);
00212 }
00213 cie_length =
00214 uwordb_size +
00215 sizeof(Dwarf_Ubyte) +
00216 strlen(curcie->cie_aug)+1 +
00217 c_bytes +
00218 d_bytes +
00219 sizeof(Dwarf_Ubyte) +
00220 a_bytes +
00221 sizeof(Dwarf_Ubyte) +
00222 personality_length +
00223 sizeof(Dwarf_Ubyte) +
00224 (generate_fpic_dwarf ? sizeof(Dwarf_Ubyte) : 0) +
00225 curcie->cie_inst_bytes;
00226 }
00227 else {
00228 cie_length =
00229 uwordb_size +
00230 sizeof(Dwarf_Ubyte) +
00231 strlen(curcie->cie_aug)+1 +
00232 c_bytes +
00233 d_bytes +
00234 sizeof(Dwarf_Ubyte) +
00235 curcie->cie_inst_bytes;
00236 }
00237 #ifdef TARG_IA64
00238 pad = (int)PADDING(cie_length, upointer_size);
00239 cie_length += pad;
00240 #endif
00241 if (personality) {
00242 res = dbg->de_reloc_name(dbg, EH_FRAME,
00243 extension_size+2*uwordb_size+
00244 3*sizeof(Dwarf_Ubyte)+
00245 (strlen(curcie->cie_aug)+1)+
00246 c_bytes+d_bytes+a_bytes,
00247 personality,
00248 dwarf_drt_data_reloc_by_str_id,
00249 upointer_size);
00250 if (res != DW_DLV_OK) {
00251 DWARF_P_DBG_ERROR(dbg,DW_DLE_CHUNK_ALLOC,-1);
00252 }
00253 }
00254 GET_CHUNK(dbg,elfsectno,data,cie_length+uwordb_size
00255 +extension_size, error);
00256 if (extension_size) {
00257 Dwarf_Unsigned x = DISTINGUISHED_VALUE;
00258 WRITE_UNALIGNED(dbg,(void *)data,
00259 (const void *)&x,
00260 sizeof(x), extension_size);
00261 data += extension_size;
00262
00263 }
00264 du = cie_length;
00265
00266 #ifdef TARG_IA64
00267 WRITE_UNALIGNED(dbg,(void *)data,
00268 (const void *)&du,
00269 sizeof(du), uwordb_size);
00270 #endif
00271
00272 data += uwordb_size;
00273
00274
00275 #ifdef KEY
00276
00277
00278 du = 0x0LL;
00279 #else
00280 du = DW_CIE_ID;
00281 #endif
00282 WRITE_UNALIGNED(dbg,(void *)data, (const void *)&du,
00283 sizeof(du), uwordb_size);
00284 data += uwordb_size;
00285
00286 db = curcie->cie_version;
00287 WRITE_UNALIGNED(dbg,(void *)data, (const void *)&db,
00288 sizeof(db),sizeof(Dwarf_Ubyte));
00289 data += sizeof(Dwarf_Ubyte);
00290 strcpy((char *)data, curcie->cie_aug);
00291 data += strlen(curcie->cie_aug)+1;
00292 memcpy((void *)data, (const void *)code_al, c_bytes);
00293 data += c_bytes;
00294 memcpy((void *)data, (const void *)data_al, d_bytes);
00295 data += d_bytes;
00296 db = curcie->cie_ret_reg;
00297 WRITE_UNALIGNED(dbg,(void *)data, (const void *)&db,
00298 sizeof(db),sizeof(Dwarf_Ubyte));
00299 data += sizeof(Dwarf_Ubyte);
00300
00301 if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0
00302 || !strcmp(augmentation, PIC_DW_CIE_AUGMENTER_STRING_V0)
00303
00304 || !strcmp(augmentation,
00305 PIC_NONCPLUS_DW_CIE_AUGMENTER_STRING_V0)
00306 ) {
00307 memcpy((void *)data, (const void *) augmented_al, a_bytes);
00308 data += a_bytes;
00309 }
00310
00311 if (personality) {
00312
00313
00314
00315
00316 db = Personality_Format;
00317 WRITE_UNALIGNED(dbg, (void *)data, (const void *)&db,
00318 sizeof(db), sizeof(Dwarf_Ubyte));
00319 data += sizeof(Dwarf_Ubyte);
00320
00321 Dwarf_Unsigned p = 0;
00322 WRITE_UNALIGNED(dbg, (void *)data, (const void *)&p,
00323 sizeof(p), upointer_size);
00324 data += upointer_size;
00325
00326 if (generate_fpic_dwarf) {
00327 p = 0x1b;
00328 }
00329
00330 WRITE_UNALIGNED(dbg, (void *)data, (const void *)&p,
00331 sizeof(p), sizeof(Dwarf_Ubyte));
00332 data += sizeof(Dwarf_Ubyte);
00333 }
00334 if (generate_fpic_dwarf) {
00335
00336 Dwarf_Unsigned p = 0x1b;
00337 WRITE_UNALIGNED(dbg, (void *)data, (const void *)&p,
00338 sizeof(p), sizeof(Dwarf_Ubyte));
00339 data += sizeof(Dwarf_Ubyte);
00340 }
00341 memcpy((void *)data, (const void *)curcie->cie_inst, curcie->cie_inst_bytes);
00342 data += curcie->cie_inst_bytes;
00343 #ifdef TARG_IA64
00344 for (i = 0 ; i < pad ; i++) {
00345 *data = DW_CFA_nop;
00346 data++;
00347 }
00348 #endif
00349 curcie = curcie->cie_next;
00350 }
00351
00352 cur_off = cie_offs[cie_no-2] + cie_length + uwordb_size
00353 + extension_size;
00354
00355
00356 curfde = dbg->de_eh_frame_fdes;
00357 while (curfde) {
00358 Dwarf_P_Frame_Pgm curinst;
00359 long fde_length;
00360 #ifdef TARG_IA64
00361 int pad;
00362 #endif
00363 Dwarf_P_Cie cie_ptr;
00364 Dwarf_Word cie_index, index;
00365 int oet_length, afl_length, res;
00366 int v0_augmentation = 0;
00367 int pic_augmentation = 0;
00368 #if 0
00369 unsigned char *fde_start_point;
00370 #endif
00371 unsigned char *fde_start_point;
00372
00373 char afl_buff[ENCODE_SPACE_NEEDED];
00374
00375
00376 cie_ptr = dbg->de_eh_frame_cies;
00377 cie_index = curfde->fde_cie;
00378 index = 1;
00379 while (cie_ptr && index < cie_index) {
00380 cie_ptr = cie_ptr->cie_next;
00381 index++;
00382 }
00383 if (cie_ptr == NULL) {
00384 DWARF_P_DBG_ERROR(dbg,DW_DLE_CIE_NULL,-1);
00385 }
00386
00387 if (strcmp(cie_ptr->cie_aug, DW_CIE_AUGMENTER_STRING_V0) == 0
00388 || !strcmp(cie_ptr->cie_aug, PIC_DW_CIE_AUGMENTER_STRING_V0)
00389 ) {
00390 v0_augmentation = 1;
00391 if (generate_fpic_dwarf || !generate_m64_dwarf)
00392 oet_length = 4;
00393 else
00394 oet_length = 8;
00395
00396 res = _dwarf_pro_encode_leb128_nm(
00397 oet_length,
00398 &afl_length, afl_buff,
00399 sizeof(afl_buff));
00400 if (res != DW_DLV_OK) {
00401 DWARF_P_DBG_ERROR(dbg,DW_DLE_CIE_OFFS_ALLOC,-1);
00402 }
00403
00404 fde_length = curfde->fde_n_bytes +
00405 uwordb_size +
00406 upointer_size +
00407 upointer_size +
00408 afl_length +
00409 oet_length;
00410 }
00411 else if (!strcmp(cie_ptr->cie_aug,
00412 PIC_NONCPLUS_DW_CIE_AUGMENTER_STRING_V0) &&
00413 generate_fpic_dwarf) {
00414
00415
00416 pic_augmentation = 1;
00417 oet_length = 0;
00418
00419 res = _dwarf_pro_encode_leb128_nm(
00420 oet_length,
00421 &afl_length, afl_buff,
00422 sizeof(afl_buff));
00423 if (res != DW_DLV_OK) {
00424 DWARF_P_DBG_ERROR(dbg,DW_DLE_CIE_OFFS_ALLOC,-1);
00425 }
00426
00427 fde_length = curfde->fde_n_bytes +
00428 uwordb_size +
00429 upointer_size +
00430 upointer_size +
00431 afl_length;
00432 }
00433 else {
00434 fde_length = curfde->fde_n_bytes +
00435 uwordb_size +
00436 upointer_size +
00437 upointer_size;
00438 }
00439
00440
00441 res = dbg->de_reloc_name(dbg, EH_FRAME,
00442 cur_off+extension_size,
00443 0,
00444 #ifdef TARG_IA64
00445 dwarf_drt_none,
00446 #else
00447 dwarf_drt_fde_begin,
00448 #endif
00449 uwordb_size);
00450 if (res != DW_DLV_OK) {
00451 DWARF_P_DBG_ERROR(dbg,DW_DLE_CHUNK_ALLOC,-1);
00452 }
00453
00454 res = dbg->de_reloc_pair(dbg, EH_FRAME,
00455 cur_off+extension_size+uwordb_size,
00456 dbg->de_sect_name_idx[EH_FRAME],
00457 0,
00458 dwarf_drt_first_of_length_pair_create_second,
00459 uwordb_size);
00460 if (res != DW_DLV_OK) {
00461 DWARF_P_DBG_ERROR(dbg,DW_DLE_CHUNK_ALLOC,-1);
00462 }
00463
00464
00465 res = dbg->de_reloc_name(dbg,
00466 EH_FRAME,
00467 cur_off+extension_size+2*uwordb_size,
00468 curfde->fde_r_symidx,
00469 dwarf_drt_data_reloc,
00470 upointer_size);
00471 if (res != DW_DLV_OK) {
00472 DWARF_P_DBG_ERROR(dbg,DW_DLE_CHUNK_ALLOC,-1);
00473 }
00474
00475 res = dbg->de_reloc_pair(dbg,
00476
00477 EH_FRAME,
00478 cur_off +extension_size+2*uwordb_size +
00479 upointer_size,
00480 curfde->fde_r_symidx,
00481 curfde->fde_end_symbol,
00482 dwarf_drt_first_of_length_pair,
00483 upointer_size);
00484 if (res != DW_DLV_OK) {
00485 {_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return(0);}
00486 }
00487
00488
00489
00490 if (v0_augmentation &&
00491 curfde->fde_offset_into_exception_tables >= 0) {
00492
00493 res = dbg->de_reloc_name(dbg,
00494 EH_FRAME,
00495
00496
00497
00498 cur_off+2*uwordb_size+
00499 extension_size+2*upointer_size + afl_length,
00500
00501 curfde->fde_exception_table_symbol,
00502 dwarf_drt_segment_rel,
00503 upointer_size);
00504 if (res != DW_DLV_OK) {
00505 DWARF_P_DBG_ERROR(dbg,DW_DLE_CHUNK_ALLOC,-1);
00506 }
00507 }
00508
00509 #ifdef TARG_IA64
00510
00511 pad = (int)PADDING(fde_length, upointer_size);
00512 fde_length += pad;
00513 #endif
00514
00515
00516 GET_CHUNK(dbg,elfsectno,data,fde_length+uwordb_size +
00517 extension_size, error);
00518 #if 0
00519 fde_start_point = data;
00520 #endif
00521 fde_start_point = data;
00522 du = fde_length;
00523 {
00524 if (extension_size) {
00525 Dwarf_Word x = DISTINGUISHED_VALUE;
00526 WRITE_UNALIGNED(dbg,(void *)data,
00527 (const void *)&x,
00528 sizeof(x), extension_size);
00529 data += extension_size;
00530 }
00531
00532 #ifdef TARG_IA64
00533 WRITE_UNALIGNED(dbg,(void *)data,
00534 (const void *)&du,
00535 sizeof(du), uwordb_size);
00536 #endif
00537
00538 data += uwordb_size;
00539
00540
00541 du = cie_offs[curfde->fde_cie-1];
00542 WRITE_UNALIGNED(dbg,(void *)data,
00543 (const void *)&du,
00544 sizeof(du),uwordb_size);
00545 data += uwordb_size;
00546
00547 du = curfde->fde_initloc;
00548 WRITE_UNALIGNED(dbg,(void *)data,
00549 (const void *)&du,
00550 sizeof(du),upointer_size);
00551 data += upointer_size;
00552
00553 if (dbg->de_reloc_pair &&
00554 curfde->fde_end_symbol != 0 &&
00555 curfde->fde_addr_range == 0) {
00556
00557
00558
00559
00560 Dwarf_Unsigned val;
00561
00562
00563
00564
00565 val = curfde->fde_end_symbol_offset -
00566 curfde->fde_initloc;
00567 WRITE_UNALIGNED(dbg,data,
00568 (const void *)&val,
00569 sizeof(val), upointer_size);
00570 data += upointer_size;
00571 } else {
00572
00573 du = curfde->fde_addr_range;
00574 WRITE_UNALIGNED(dbg,(void *)data,
00575 (const void *) &du,
00576 sizeof(du),upointer_size);
00577 data += upointer_size;
00578 }
00579 }
00580
00581 if (v0_augmentation) {
00582
00583 memcpy((void *)data, (const void *)afl_buff, afl_length);
00584 data += afl_length;
00585
00586 dsw = curfde->fde_offset_into_exception_tables;
00587 if (dsw == -1) dsw = 0;
00588 WRITE_UNALIGNED(dbg,(void *)data, (const void *)&dsw,
00589 sizeof(dsw), upointer_size);
00590 data += upointer_size;
00591 }
00592 else if (pic_augmentation) {
00593
00594 memcpy((void *)data, (const void *)afl_buff, afl_length);
00595 data += afl_length;
00596 }
00597 curinst = curfde->fde_inst;
00598 while (curinst) {
00599 db = curinst->dfp_opcode;
00600 WRITE_UNALIGNED(dbg,(void *)data, (const void *)&db,
00601 sizeof(db), sizeof(Dwarf_Ubyte));
00602 data += sizeof(Dwarf_Ubyte);
00603 if (DW_CFA_advance_loc4 == db) {
00604 res = dbg->de_reloc_pair(dbg,
00605 EH_FRAME,
00606 (data-fde_start_point) +
00607 cur_off,
00608 #ifdef TARG_IA64
00609 *(unsigned short *)(&curinst->dfp_args[0]),
00610 *(unsigned short *)(&curinst->dfp_args[2]),
00611 #else
00612 *(Dwarf_Unsigned *)(curinst->dfp_args),
00613 *(Dwarf_Unsigned *)(curinst->dfp_args
00614 + sizeof(Dwarf_Unsigned)),
00615 #endif
00616 dwarf_drt_first_of_length_pair,
00617 uwordb_size);
00618 if (res != DW_DLV_OK) {
00619 {_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); return(0);}
00620 }
00621 }
00622 #if 0
00623 if (curinst->dfp_sym_index) {
00624 int res;
00625 res = dbg->de_reloc_name(dbg,
00626 EH_FRAME,
00627 (data-fde_start_point)
00628 + cur_off+
00629 uwordb_size,
00630 curinst->dfp_sym_index,
00631 dwarf_drt_data_reloc,
00632 upointer_size);
00633 if (res != DW_DLV_OK) {
00634 {_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
00635 return(0);}
00636 }
00637 }
00638 #endif
00639 if (DW_CFA_advance_loc4 == db) {
00640 data[0] = 0;
00641 data[1] = 0;
00642 data[2] = 0;
00643 data[3] = 0;
00644 } else
00645 memcpy((void *)data,
00646 (const void *)curinst->dfp_args,
00647 curinst->dfp_nbytes);
00648 data += curinst->dfp_nbytes;
00649 curinst = curinst->dfp_next;
00650 }
00651 #ifdef TARG_IA64
00652
00653 for (i = 0 ; i < pad ; i++) {
00654 *data = DW_CFA_nop;
00655 data++;
00656 }
00657 #endif
00658 cur_off += fde_length + uwordb_size;
00659 curfde = curfde->fde_next;
00660 }
00661
00662
00663 return (int)dbg->de_n_debug_sect;
00664 }