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
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 #include "xlateincl.h"
00084
00085 static struct xlate_block_s zero_xlate_block;
00086
00087 static void __inline set_memodata_valid(
00088 struct memo_s *memodata,
00089 xlate_block *xbp,
00090 Uword entryct,
00091 Uword entrymax,
00092 int isNewAddress,
00093 int restart,
00094 uniform_block_hdr * blk_hdr)
00095 {
00096 memodata->mm_is_valid =1;
00097 memodata->mm_block =*xbp;
00098 memodata->mm_entryct =entryct;
00099 memodata->mm_entrymax =entrymax;
00100 memodata->mm_is_new_address =isNewAddress;
00101 memodata->mm_ublock_index =blk_hdr->ub_block_index;
00102 if(!restart) {
00103 memodata->mm_low_new_addr = blk_hdr->ub_low_new_addr;
00104 memodata->mm_high_new_addr = blk_hdr->ub_high_new_addr;
00105 memodata->mm_low_old_addr = blk_hdr->ub_low_old_addr;
00106 memodata->mm_high_old_addr = blk_hdr->ub_high_old_addr;
00107 }
00108 }
00109
00110
00111
00112
00113
00114
00115
00116 static int __inline _xlate_found_address(Elf64_Addr addr_in,
00117 int isNewAddress, xlate_block *blkp)
00118 {
00119 if(isNewAddress) {
00120 if(addr_in < blkp->xe_new_address) {
00121 return -1;
00122 }
00123 if(addr_in >= (blkp->xe_new_address+
00124 blkp->xe_new_range)) {
00125 return 1;
00126 }
00127 return 0;
00128 }
00129
00130
00131 if(addr_in < blkp->xe_old_address) {
00132 return -1;
00133 }
00134 if(addr_in >= (blkp->xe_old_address+
00135 blkp->xe_old_range)) {
00136 return 1;
00137 }
00138 return 0;
00139 }
00140
00141
00142
00143
00144
00145
00146
00147 static int __inline
00148 _xlate_ck_in_range_and_calc_out_addr(
00149 Elf64_Addr addr_in,
00150 int isNewAddress,
00151 xlate_block *xbp,
00152 Elf64_Addr * addr_out)
00153 {
00154 if(_xlate_found_address(addr_in,isNewAddress,xbp) != 0) {
00155 return 0;
00156 }
00157
00158
00159 if(isNewAddress) {
00160
00161 *addr_out = _xlate_get_out_from_ranges(addr_in,
00162 xbp->xe_new_address,
00163 xbp->xe_old_address,xbp->xe_old_range);
00164 } else {
00165 *addr_out = _xlate_get_out_from_ranges(addr_in,
00166 xbp->xe_old_address,
00167 xbp->xe_new_address,xbp->xe_new_range);
00168 }
00169 return 1;
00170 }
00171
00172
00173
00174
00175
00176
00177 static int
00178 _xlate_binary_search_xlate_block_table(
00179 xlate_block * xbp,
00180
00181 Uword entryct,
00182 Uword entrymax,
00183 int isNewAddress,
00184 Elf64_Addr addr_in,
00185 Uword *outindex)
00186 {
00187 Uword low = entryct;
00188 Uword high = entrymax-1;
00189 Uword probe;
00190 int v;
00191
00192 if(low > high) {
00193 return 0;
00194 }
00195 while(high-low> 1) {
00196
00197 probe = (high+low)/2;
00198 v =_xlate_found_address(addr_in,isNewAddress,xbp+probe);
00199 if(v == 0) {
00200 *outindex = probe;
00201 return 1;
00202 }
00203 if(v < 0) {
00204
00205 high = probe;
00206 } else {
00207
00208 low = probe;
00209 }
00210 }
00211
00212
00213
00214
00215 v =_xlate_found_address(addr_in,isNewAddress,xbp+low);
00216 if(0 == v) {
00217 *outindex = low;
00218 return 1;
00219 } else if ( v < 0) {
00220
00221 return 0;
00222 }
00223 if(0 ==_xlate_found_address(addr_in,isNewAddress,xbp+high)) {
00224 *outindex = high;
00225 return 1;
00226 }
00227 return 0;
00228 }
00229
00230
00231
00232
00233
00234
00235
00236
00237 Elf64_Addr
00238 _xlate_get_out_from_ranges(Elf64_Addr addr_in,
00239 Elf64_Addr base_addr1,
00240 Elf64_Addr base_addr2,
00241 Elf64_Xword range2)
00242 {
00243 Elf64_Xword addrincr = addr_in - base_addr1;
00244 Elf64_Addr final_addr;
00245
00246 if(addrincr >= range2) {
00247
00248 addrincr = range2 - INSTRUCTION_SIZE;
00249 }
00250 final_addr = base_addr2 + addrincr;
00251 return final_addr;
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281 static int
00282 _xlate_expand_block_v1_ps(xlate_table_con tab,
00283 uniform_block_hdr *blk_hdr)
00284 {
00285 int retstatus = XLATE_TB_STATUS_NO_ERROR;
00286 char *startpt;
00287 char *endpt;
00288 Uword entrymax;
00289 Uword entryct = 0;
00290 __uint32_t uval = 0;
00291 __int32_t sval = 0;
00292 int len;
00293 xlate_block lblock = zero_xlate_block;
00294 xlate_block *xbp = 0;
00295
00296 startpt = blk_hdr->ub_data_bytes;
00297 endpt = blk_hdr->ub_data_end;
00298 entrymax = blk_hdr->ub_entrycount-1;
00299
00300 len = _leb128_unsigned_decode32(startpt,&uval);
00301 startpt += len;
00302 len = _leb128_signed_decode32(startpt,&sval);
00303 startpt += len;
00304
00305 lblock.xe_new_address = blk_hdr->ub_first_new_addr;
00306 lblock.xe_old_address = blk_hdr->ub_first_old_addr;
00307 uval = 0;
00308 sval = 0;
00309
00310
00311
00312
00313
00314 blk_hdr->ub_expanded_entries = calloc(entrymax,sizeof(xlate_block));
00315 if(blk_hdr->ub_expanded_entries == 0) {
00316 return XLATE_TB_STATUS_ALLOC_FAIL;
00317 }
00318 xbp = blk_hdr->ub_expanded_entries;
00319
00320
00321 for( ; entryct < entrymax && startpt < endpt; ) {
00322
00323 lblock.xe_new_address += uval;
00324 lblock.xe_old_address += sval;
00325
00326 len = _leb128_unsigned_decode32(startpt,&uval);
00327 startpt += len;
00328 len = _leb128_signed_decode32(startpt,&sval);
00329 startpt += len;
00330 ++entryct;
00331 uval <<=2;
00332 sval <<=2;
00333
00334 lblock.xe_new_range = uval;
00335 lblock.xe_old_range = uval;
00336
00337 *xbp = lblock;
00338
00339 }
00340
00341
00342
00343
00344
00345 blk_hdr->ub_v1_entrycount = entryct;
00346
00347
00348
00349 return retstatus;
00350 }
00351 int
00352 _xlate_get_range_from_block_v1_ps(xlate_table_con tab,
00353 int isNewAddress,
00354 Elf64_Addr addr_in,
00355 int restart,
00356 uniform_block_hdr *blk_hdr,
00357 Elf64_Addr* addr_out,
00358 xlate_block *range_out)
00359 {
00360 int retstatus = XLATE_TB_STATUS_NO_ERROR;
00361 Uword entrymax;
00362 Uword entryct = 0;
00363 Elf64_Addr our_out_addr;
00364 struct memo_s *memodata;
00365 xlate_block *xbp = 0;
00366
00367 if(blk_hdr->ub_expanded_entries == 0) {
00368 retstatus = _xlate_expand_block_v1_ps(tab,
00369 blk_hdr);
00370 if(retstatus != XLATE_TB_STATUS_NO_ERROR) {
00371 return retstatus;
00372 }
00373 }
00374 #ifndef TURN_OFF_MEMO
00375 if(isNewAddress) {
00376 memodata = &tab->xc_memo_new;
00377 } else {
00378 memodata = &tab->xc_memo_old;
00379 }
00380 if(restart) {
00381 entryct = memodata->mm_entryct;
00382 entrymax = memodata->mm_entrymax;
00383 } else {
00384 #endif
00385 entrymax = blk_hdr->ub_v1_entrycount;
00386 #ifndef TURN_OFF_MEMO
00387 }
00388 memodata->mm_is_valid = 0;
00389 #endif
00390
00391
00392 xbp = blk_hdr->ub_expanded_entries;
00393
00394
00395
00396
00397
00398
00399 if(isNewAddress && (entryct < entrymax)) {
00400 Uword newindex;
00401 int res;
00402 res = _xlate_binary_search_xlate_block_table(xbp,entryct,entrymax,
00403 isNewAddress,addr_in,&newindex);
00404 if(!res) {
00405 return XLATE_TB_STATUS_NO_SUCH_ADDR_IN_TABLE;
00406 }
00407
00408
00409 entryct = newindex;
00410 }
00411
00412 xbp += entryct;
00413
00414
00415
00416
00417
00418 for( ; entryct < entrymax ; ++entryct, ++xbp ) {
00419 int res = _xlate_ck_in_range_and_calc_out_addr(addr_in,
00420 isNewAddress,
00421 xbp,&our_out_addr);
00422 if(!res) {
00423 continue;
00424 }
00425
00426
00427
00428 *addr_out = our_out_addr;
00429 if(range_out) {
00430 *range_out = *xbp;
00431 }
00432
00433 #ifndef TURN_OFF_MEMO
00434
00435 set_memodata_valid(memodata,xbp,entryct,entrymax,isNewAddress,
00436 restart,blk_hdr);
00437 #endif
00438 return retstatus;
00439
00440 }
00441
00442 return XLATE_TB_STATUS_NO_SUCH_ADDR_IN_TABLE;
00443
00444 }
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 static int
00456 _xlate_expand_block_v1_po(xlate_table_con tab,
00457 uniform_block_hdr *blk_hdr)
00458 {
00459 int retstatus = XLATE_TB_STATUS_NO_ERROR;
00460 char *startpt;
00461 char *endpt;
00462 Uword entrymax;
00463 Uword entryct = 0;
00464 __uint32_t uval = 0;
00465 __uint32_t uval2 = 0;
00466 int len;
00467 xlate_block lblock = zero_xlate_block;
00468 Elf64_Addr low_old_addr = INITIAL_LOW_ADDR;
00469 Elf64_Addr high_old_addr = 0;
00470 xlate_block *xbp;
00471
00472 startpt = blk_hdr->ub_data_bytes;
00473 endpt = blk_hdr->ub_data_end;
00474 entrymax = blk_hdr->ub_entrycount-1;
00475
00476 len = _leb128_unsigned_decode32(startpt,&uval);
00477 startpt += len;
00478 len = _leb128_unsigned_decode32(startpt,&uval);
00479 startpt += len;
00480 lblock.xe_new_address = blk_hdr->ub_first_new_addr;
00481 lblock.xe_old_address = blk_hdr->ub_first_old_addr;
00482 uval = 0;
00483 uval2 = 0;
00484
00485 blk_hdr->ub_expanded_entries = calloc(entrymax,sizeof(xlate_block));
00486 if(blk_hdr->ub_expanded_entries == 0) {
00487 return XLATE_TB_STATUS_ALLOC_FAIL;
00488 }
00489 xbp = blk_hdr->ub_expanded_entries;
00490
00491
00492
00493
00494 for( ; entryct < entrymax && startpt < endpt; ++xbp) {
00495
00496 lblock.xe_new_address += uval;
00497 lblock.xe_old_address += uval2;
00498
00499 len = _leb128_unsigned_decode32(startpt,&uval);
00500 startpt += len;
00501 len = _leb128_unsigned_decode32(startpt,&uval2);
00502 startpt += len;
00503 ++entryct;
00504 uval <<=2;
00505 uval2 <<=2;
00506
00507 lblock.xe_new_range = uval;
00508 lblock.xe_old_range = uval2;
00509 if(low_old_addr > lblock.xe_old_address) {
00510 low_old_addr = lblock.xe_old_address;
00511 }
00512 if(high_old_addr <
00513 (lblock.xe_old_address + lblock.xe_old_range)) {
00514 high_old_addr = lblock.xe_old_address +
00515 lblock.xe_old_range;
00516 }
00517
00518
00519 *xbp = lblock;
00520 }
00521
00522
00523
00524
00525
00526 blk_hdr->ub_v1_entrycount = entryct;
00527
00528 if(high_old_addr > blk_hdr->ub_high_old_addr) {
00529 blk_hdr->ub_high_old_addr = high_old_addr;
00530 }
00531 if(low_old_addr < blk_hdr->ub_low_old_addr) {
00532 blk_hdr->ub_low_old_addr = low_old_addr;
00533 }
00534
00535 return retstatus;
00536 }
00537 int
00538 _xlate_get_range_from_block_v1_po(xlate_table_con tab,
00539 int isNewAddress,
00540 Elf64_Addr addr_in,
00541 int restart,
00542 uniform_block_hdr *blk_hdr,
00543 Elf64_Addr* addr_out,
00544 xlate_block *range_out)
00545 {
00546 int retstatus = XLATE_TB_STATUS_NO_ERROR;
00547 Uword entrymax;
00548 Uword entryct = 0;
00549 xlate_block lblock = zero_xlate_block;
00550 Elf64_Addr our_out_addr;
00551 struct memo_s *memodata;
00552 xlate_block *xbp;
00553 int res;
00554 Uword newindex;
00555
00556
00557
00558 if(blk_hdr->ub_expanded_entries == 0) {
00559 retstatus = _xlate_expand_block_v1_po(tab,
00560 blk_hdr);
00561 if(retstatus != XLATE_TB_STATUS_NO_ERROR) {
00562 return retstatus;
00563 }
00564
00565 }
00566
00567 #ifndef TURN_OFF_MEMO
00568 if(isNewAddress) {
00569 memodata = &tab->xc_memo_new;
00570 } else {
00571 memodata = &tab->xc_memo_old;
00572 }
00573 if(restart) {
00574 entryct = memodata->mm_entryct;
00575 entrymax = memodata->mm_entrymax;
00576 } else {
00577 #endif
00578 entrymax = blk_hdr->ub_v1_entrycount;
00579 ++entryct;
00580 #ifndef TURN_OFF_MEMO
00581 }
00582 memodata->mm_is_valid = 0;
00583 #endif
00584
00585 xbp = blk_hdr->ub_expanded_entries;
00586
00587
00588
00589
00590 if(entryct < entrymax) {
00591 res = _xlate_binary_search_xlate_block_table(xbp,
00592 entryct,entrymax,isNewAddress,addr_in,&newindex);
00593 if(!res) {
00594 return XLATE_TB_STATUS_NO_SUCH_ADDR_IN_TABLE;
00595 }
00596 entryct = newindex;
00597 }
00598
00599
00600
00601
00602
00603
00604 xbp += entryct;
00605 for( ; entryct < entrymax ; ++xbp,++entryct) {
00606 int res = _xlate_ck_in_range_and_calc_out_addr(addr_in,
00607 isNewAddress,
00608 xbp,&our_out_addr);
00609 if(!res) {
00610 continue;
00611 }
00612
00613
00614
00615 *addr_out = our_out_addr;
00616 if(range_out) {
00617 *range_out = *xbp;
00618 }
00619
00620 #ifndef TURN_OFF_MEMO
00621 set_memodata_valid(memodata,xbp,entryct,entrymax,isNewAddress,
00622 restart,blk_hdr);
00623 #endif
00624 return retstatus;
00625
00626 }
00627
00628
00629
00630
00631
00632 if(!restart) {
00633
00634
00635
00636 if(isNewAddress) {
00637 if(addr_in < blk_hdr->ub_high_new_addr) {
00638
00639 lblock.xe_new_range =
00640 blk_hdr->ub_high_new_addr -lblock.xe_new_address;
00641 lblock.xe_old_range =
00642 blk_hdr->ub_high_old_addr -lblock.xe_old_address;
00643 if(range_out) {
00644 *range_out = lblock;
00645 }
00646 return retstatus;
00647 } else {
00648 }
00649 } else {
00650 if(addr_in < blk_hdr->ub_high_old_addr) {
00651
00652 lblock.xe_new_range =
00653 blk_hdr->ub_high_new_addr -lblock.xe_new_address;
00654 lblock.xe_old_range =
00655 blk_hdr->ub_high_old_addr -lblock.xe_old_address;
00656 if(range_out) {
00657 *range_out = lblock;
00658 }
00659 return retstatus;
00660 } else {
00661 }
00662 }
00663
00664
00665 }
00666 return XLATE_TB_STATUS_NO_SUCH_ADDR_IN_TABLE;
00667
00668 }
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 int
00683 _xlate_get_range_from_block_v1_ge(xlate_table_con tab,
00684 int isNewAddress,
00685 Elf64_Addr addr_in,
00686 int restart,
00687 uniform_block_hdr *blk_hdr,
00688 Elf64_Addr* addr_out,
00689 xlate_block *range_out)
00690 {
00691 int retstatus = XLATE_TB_STATUS_NOT_YET_IMPLEMENT;
00692
00693 return retstatus;
00694 }
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707 static int
00708 _xlate_expand_block_v2_32_ps(xlate_table_con tab,
00709 uniform_block_hdr *blk_hdr)
00710 {
00711 int retstatus = XLATE_TB_STATUS_NO_ERROR;
00712 char *startpt;
00713 char *endpt ;
00714 Uword entrymax;
00715 Uword entryct = 0;
00716 __uint32_t uval = 0;
00717 __int32_t sval = 0;
00718 int len;
00719 xlate_block *xbp = 0;
00720 xlate_block lblock = zero_xlate_block;
00721
00722
00723 startpt = blk_hdr->ub_data_bytes;
00724 endpt = blk_hdr->ub_data_end;
00725 entrymax = blk_hdr->ub_entrycount;
00726
00727 blk_hdr->ub_expanded_entries = calloc(entrymax,sizeof(xlate_block));
00728 if(blk_hdr->ub_expanded_entries == 0) {
00729 return XLATE_TB_STATUS_ALLOC_FAIL;
00730 }
00731 xbp = blk_hdr->ub_expanded_entries;
00732 lblock.xe_new_address = blk_hdr->ub_first_new_addr;
00733 lblock.xe_old_address = blk_hdr->ub_first_old_addr;
00734
00735
00736 for( ; entryct < entrymax && startpt < endpt; ++xbp) {
00737
00738 lblock.xe_new_address += uval;
00739
00740 len = _leb128_unsigned_decode32(startpt,&uval);
00741 startpt += len;
00742 len = _leb128_signed_decode32(startpt,&sval);
00743 startpt += len;
00744 ++entryct;
00745 uval <<=2;
00746 sval <<=2;
00747
00748 lblock.xe_new_range = uval;
00749 lblock.xe_old_range = uval;
00750 lblock.xe_old_address += sval;
00751
00752
00753
00754 *xbp = lblock;
00755 }
00756 return retstatus;
00757 }
00758
00759 int
00760 _xlate_get_range_from_block_v2_32_ps(xlate_table_con tab,
00761 int isNewAddress,
00762 Elf64_Addr addr_in,
00763 int restart,
00764 uniform_block_hdr *blk_hdr,
00765 Elf64_Addr* addr_out,
00766 xlate_block *range_out)
00767 {
00768 int retstatus = XLATE_TB_STATUS_NO_ERROR;
00769 Uword entrymax;
00770 Uword entryct = 0;
00771 Elf64_Addr our_out_addr;
00772 struct memo_s *memodata;
00773 xlate_block *xbp;
00774
00775
00776 if(blk_hdr->ub_expanded_entries == 0) {
00777 retstatus = _xlate_expand_block_v2_32_ps(tab,
00778 blk_hdr);
00779 if(retstatus != XLATE_TB_STATUS_NO_ERROR) {
00780 return retstatus;
00781 }
00782
00783 }
00784
00785 #ifndef TURN_OFF_MEMO
00786 if(isNewAddress) {
00787 memodata = &tab->xc_memo_new;
00788 } else {
00789 memodata = &tab->xc_memo_old;
00790 }
00791 if(restart) {
00792 entryct = memodata->mm_entryct;
00793 entrymax = memodata->mm_entrymax;
00794 } else {
00795 #endif
00796 entrymax = blk_hdr->ub_entrycount;
00797 #ifndef TURN_OFF_MEMO
00798 }
00799 memodata->mm_is_valid = 0;
00800 #endif
00801
00802 xbp = blk_hdr->ub_expanded_entries;
00803 if(isNewAddress) {
00804 Uword newindex;
00805 int res;
00806 res = _xlate_binary_search_xlate_block_table(xbp,entryct,entrymax,
00807 isNewAddress,addr_in,&newindex);
00808 if(!res) {
00809 return XLATE_TB_STATUS_NO_SUCH_ADDR_IN_TABLE;
00810 }
00811
00812
00813 entryct = newindex;
00814 }
00815 xbp += entryct;
00816
00817 for( ; entryct < entrymax ; ++xbp,++entryct) {
00818 int res = _xlate_ck_in_range_and_calc_out_addr(addr_in,
00819 isNewAddress,
00820 xbp,&our_out_addr);
00821 if(!res) {
00822 continue;
00823 }
00824
00825
00826 *addr_out = our_out_addr;
00827 if(range_out) {
00828 *range_out = *xbp;
00829 }
00830
00831 #ifndef TURN_OFF_MEMO
00832 set_memodata_valid(memodata,xbp,entryct,entrymax,isNewAddress,
00833 restart,blk_hdr);
00834 #endif
00835 return retstatus;
00836
00837 }
00838 return XLATE_TB_STATUS_NO_SUCH_ADDR_IN_TABLE;
00839
00840 }
00841
00842
00843
00844
00845
00846
00847
00848
00849 static int
00850 _xlate_expand_block_v2_32_po(xlate_table_con tab,
00851 uniform_block_hdr *blk_hdr)
00852 {
00853 int retstatus = XLATE_TB_STATUS_NO_ERROR;
00854 char *startpt;
00855 char *endpt;
00856 Uword entrymax;
00857 Uword entryct = 0;
00858 __uint32_t uval = 0;
00859 __uint32_t uval2 = 0;
00860 int len;
00861 xlate_block lblock = zero_xlate_block;
00862 xlate_block *xbp;
00863
00864 startpt = blk_hdr->ub_data_bytes;
00865 endpt = blk_hdr->ub_data_end;
00866 entrymax = blk_hdr->ub_entrycount;
00867
00868 blk_hdr->ub_expanded_entries = calloc(entrymax,sizeof(xlate_block));
00869 if(blk_hdr->ub_expanded_entries == 0) {
00870 return XLATE_TB_STATUS_ALLOC_FAIL;
00871 }
00872
00873 xbp = blk_hdr->ub_expanded_entries;
00874
00875 lblock.xe_new_address = blk_hdr->ub_first_new_addr;
00876 lblock.xe_old_address = blk_hdr->ub_first_old_addr;
00877 for( ; entryct < entrymax && startpt < endpt; ++xbp) {
00878
00879 lblock.xe_new_address += uval;
00880 lblock.xe_old_address += uval2;
00881
00882 len = _leb128_unsigned_decode32(startpt,&uval);
00883 startpt += len;
00884 len = _leb128_unsigned_decode32(startpt,&uval2);
00885 startpt += len;
00886 ++entryct;
00887 uval <<=2;
00888 uval2 <<=2;
00889
00890 lblock.xe_new_range = uval;
00891 lblock.xe_old_range = uval2;
00892
00893
00894 *xbp = lblock;
00895 }
00896 return retstatus;
00897 }
00898 int
00899 _xlate_get_range_from_block_v2_32_po(xlate_table_con tab,
00900 int isNewAddress,
00901 Elf64_Addr addr_in,
00902 int restart,
00903 uniform_block_hdr *blk_hdr,
00904 Elf64_Addr* addr_out,
00905 xlate_block *range_out)
00906 {
00907 int retstatus = XLATE_TB_STATUS_NO_ERROR;
00908 Uword entrymax;
00909 Uword entryct = 0;
00910 Elf64_Addr our_out_addr;
00911 struct memo_s *memodata;
00912 Uword newindex;
00913 int res;
00914 xlate_block *xbp;
00915
00916 if( blk_hdr->ub_expanded_entries == 0) {
00917 retstatus = _xlate_expand_block_v2_32_po( tab,
00918 blk_hdr);
00919 if(retstatus != XLATE_TB_STATUS_NO_ERROR) {
00920 return retstatus;
00921 }
00922 }
00923
00924 #ifndef TURN_OFF_MEMO
00925 if(isNewAddress) {
00926 memodata = &tab->xc_memo_new;
00927 } else {
00928 memodata = &tab->xc_memo_old;
00929 }
00930 if(restart) {
00931 entryct = memodata->mm_entryct;
00932 entrymax = memodata->mm_entrymax;
00933 } else {
00934 #endif
00935 entrymax = blk_hdr->ub_entrycount;
00936 #ifndef TURN_OFF_MEMO
00937 }
00938 memodata->mm_is_valid = 0;
00939 #endif
00940 xbp = blk_hdr->ub_expanded_entries;
00941
00942
00943
00944
00945 res = _xlate_binary_search_xlate_block_table(xbp,
00946 entryct,entrymax,isNewAddress,addr_in,&newindex);
00947 if(!res) {
00948 return XLATE_TB_STATUS_NO_SUCH_ADDR_IN_TABLE;
00949 }
00950
00951
00952
00953
00954
00955 xbp += entryct;
00956 for( ; entryct < entrymax ; ++xbp, ++entryct) {
00957 int res = _xlate_ck_in_range_and_calc_out_addr(addr_in,
00958 isNewAddress,
00959 xbp,&our_out_addr);
00960 if(!res) {
00961 continue;
00962 }
00963
00964
00965
00966 *addr_out = our_out_addr;
00967 if(range_out) {
00968 *range_out = *xbp;
00969 }
00970
00971 #ifndef TURN_OFF_MEMO
00972 set_memodata_valid(memodata,xbp,entryct,entrymax,isNewAddress,
00973 restart,blk_hdr);
00974 #endif
00975 return retstatus;
00976
00977 }
00978
00979 return XLATE_TB_STATUS_NO_SUCH_ADDR_IN_TABLE;
00980
00981 }
00982
00983
00984
00985
00986
00987
00988
00989
00990 static int
00991 _xlate_expand_block_v2_32_ge(xlate_table_con tab,
00992 uniform_block_hdr *blk_hdr)
00993 {
00994
00995 int retstatus = XLATE_TB_STATUS_NO_ERROR;
00996 char *startpt;
00997 char *endpt ;
00998 Uword entrymax;
00999 Uword entryct = 0;
01000 __uint32_t uval = 0;
01001 __int32_t sval = 0;
01002 __int32_t sval2 = 0;
01003 int len;
01004 xlate_block lblock = zero_xlate_block;
01005 xlate_block *xbp;
01006 startpt = blk_hdr->ub_data_bytes;
01007 endpt = blk_hdr->ub_data_end;
01008 entrymax = blk_hdr->ub_entrycount;
01009
01010 blk_hdr->ub_expanded_entries = calloc(entrymax,sizeof(xlate_block));
01011 if(blk_hdr->ub_expanded_entries == 0) {
01012 return XLATE_TB_STATUS_ALLOC_FAIL;
01013 }
01014
01015 xbp = blk_hdr->ub_expanded_entries;
01016
01017 lblock.xe_new_address = blk_hdr->ub_first_new_addr;
01018 lblock.xe_old_address = blk_hdr->ub_first_old_addr;
01019
01020 for( ; entryct < entrymax && startpt < endpt; ++xbp) {
01021
01022 lblock.xe_new_address += uval;
01023
01024
01025 len = _leb128_unsigned_decode32(startpt,&uval);
01026 startpt += len;
01027
01028 len = _leb128_signed_decode32(startpt,&sval2);
01029 startpt += len;
01030
01031 len = _leb128_signed_decode32(startpt,&sval);
01032 startpt += len;
01033 ++entryct;
01034 uval <<=2;
01035 sval2 <<=2;
01036 sval <<=2;
01037
01038 lblock.xe_old_address += sval2;
01039 lblock.xe_new_range = uval;
01040
01041 lblock.xe_old_range = uval -sval;
01042
01043
01044
01045 *xbp = lblock;
01046
01047 }
01048 return retstatus;
01049 }
01050 int
01051 _xlate_get_range_from_block_v2_32_ge(xlate_table_con tab,
01052 int isNewAddress,
01053 Elf64_Addr addr_in,
01054 int restart,
01055 uniform_block_hdr *blk_hdr,
01056 Elf64_Addr* addr_out,
01057 xlate_block *range_out)
01058 {
01059
01060 int retstatus = XLATE_TB_STATUS_NO_ERROR;
01061 Uword entrymax;
01062 Uword entryct = 0;
01063 Elf64_Addr our_out_addr;
01064 struct memo_s *memodata;
01065 xlate_block *xbp;
01066
01067 if( blk_hdr->ub_expanded_entries == 0) {
01068 retstatus = _xlate_expand_block_v2_32_ge( tab,
01069 blk_hdr);
01070 if(retstatus != XLATE_TB_STATUS_NO_ERROR) {
01071 return retstatus;
01072 }
01073 }
01074
01075 #ifndef TURN_OFF_MEMO
01076 if(isNewAddress) {
01077 memodata = &tab->xc_memo_new;
01078 } else {
01079 memodata = &tab->xc_memo_old;
01080 }
01081 if(restart) {
01082 entryct = memodata->mm_entryct;
01083 entrymax = memodata->mm_entrymax;
01084 } else {
01085 #endif
01086 entrymax = blk_hdr->ub_entrycount;
01087 #ifndef TURN_OFF_MEMO
01088 }
01089 memodata->mm_is_valid = 0;
01090 #endif
01091
01092 xbp = blk_hdr->ub_expanded_entries;
01093 if(isNewAddress) {
01094 Uword newindex;
01095 int res;
01096 res = _xlate_binary_search_xlate_block_table(xbp,
01097 entryct,entrymax,isNewAddress,addr_in,&newindex);
01098 if(!res) {
01099 return XLATE_TB_STATUS_NO_SUCH_ADDR_IN_TABLE;
01100 }
01101 entryct = newindex;
01102 }
01103 xbp += entryct;
01104
01105 for( ; entryct < entrymax ; ++xbp,++entryct) {
01106 int res = _xlate_ck_in_range_and_calc_out_addr(addr_in,
01107 isNewAddress,
01108 xbp,&our_out_addr);
01109 if(!res) {
01110 continue;
01111 }
01112
01113
01114
01115 *addr_out = our_out_addr;
01116 if(range_out) {
01117 *range_out = *xbp;
01118 }
01119
01120 #ifndef TURN_OFF_MEMO
01121 set_memodata_valid(memodata,xbp,entryct,entrymax,isNewAddress,
01122 restart,blk_hdr);
01123 #endif
01124 return retstatus;
01125
01126 }
01127 return XLATE_TB_STATUS_NO_SUCH_ADDR_IN_TABLE;
01128
01129 }
01130
01131
01132
01133
01134
01135
01136
01137 static int
01138 _xlate_expand_block_v2_64_ps(xlate_table_con tab,
01139 uniform_block_hdr *blk_hdr)
01140 {
01141 int retstatus = XLATE_TB_STATUS_NO_ERROR;
01142 char *startpt;
01143 char *endpt ;
01144 Uword entrymax;
01145 Uword entryct = 0;
01146 __uint64_t uval = 0;
01147 __int64_t sval = 0;
01148 xlate_block lblock = zero_xlate_block;
01149 xlate_block *xbp;
01150 int len;
01151
01152 startpt = blk_hdr->ub_data_bytes;
01153 endpt = blk_hdr->ub_data_end;
01154 entrymax = blk_hdr->ub_entrycount;
01155
01156 blk_hdr->ub_expanded_entries = calloc(entrymax,sizeof(xlate_block));
01157 if(blk_hdr->ub_expanded_entries == 0) {
01158 return XLATE_TB_STATUS_ALLOC_FAIL;
01159 }
01160
01161 xbp = blk_hdr->ub_expanded_entries;
01162 lblock.xe_new_address = blk_hdr->ub_first_new_addr;
01163 lblock.xe_old_address = blk_hdr->ub_first_old_addr;
01164
01165 for( ; entryct < entrymax && startpt < endpt; ++xbp) {
01166
01167 lblock.xe_new_address += uval;
01168
01169 len = _leb128_unsigned_decode64(startpt,&uval);
01170 startpt += len;
01171 len = _leb128_signed_decode64(startpt,&sval);
01172 startpt += len;
01173 ++entryct;
01174 uval <<=2;
01175 sval <<=2;
01176
01177 lblock.xe_new_range = uval;
01178 lblock.xe_old_range = uval;
01179 lblock.xe_old_address += sval;
01180
01181
01182 *xbp = lblock;
01183 }
01184
01185 return retstatus;
01186
01187 }
01188 int
01189 _xlate_get_range_from_block_v2_64_ps(xlate_table_con tab,
01190 int isNewAddress,
01191 Elf64_Addr addr_in,
01192 int restart,
01193 uniform_block_hdr *blk_hdr,
01194 Elf64_Addr* addr_out,
01195 xlate_block *range_out)
01196 {
01197 int retstatus = XLATE_TB_STATUS_NO_ERROR;
01198 Uword entrymax;
01199 Uword entryct = 0;
01200 Elf64_Addr our_out_addr;
01201 struct memo_s *memodata;
01202 xlate_block *xbp;
01203
01204
01205 if( blk_hdr->ub_expanded_entries == 0) {
01206 retstatus = _xlate_expand_block_v2_64_ps( tab,
01207 blk_hdr);
01208 if(retstatus != XLATE_TB_STATUS_NO_ERROR) {
01209 return retstatus;
01210 }
01211 }
01212
01213
01214 #ifndef TURN_OFF_MEMO
01215 if(isNewAddress) {
01216 memodata = &tab->xc_memo_new;
01217 } else {
01218 memodata = &tab->xc_memo_old;
01219 }
01220 if(restart) {
01221 entryct = memodata->mm_entryct;
01222 entrymax = memodata->mm_entrymax;
01223 } else {
01224 #endif
01225 entrymax = blk_hdr->ub_entrycount;
01226 #ifndef TURN_OFF_MEMO
01227 }
01228 memodata->mm_is_valid = 0;
01229 #endif
01230 xbp = blk_hdr->ub_expanded_entries;
01231 if(isNewAddress) {
01232 Uword newindex;
01233 int res;
01234 res = _xlate_binary_search_xlate_block_table(xbp, entryct,
01235 entrymax,isNewAddress,addr_in,&newindex);
01236 if(!res) {
01237 return XLATE_TB_STATUS_NO_SUCH_ADDR_IN_TABLE;
01238 }
01239 entryct = newindex;
01240 }
01241 xbp += entryct;
01242
01243 for( ; entryct < entrymax ;++xbp,++entryct) {
01244 int res = _xlate_ck_in_range_and_calc_out_addr(addr_in,
01245 isNewAddress,
01246 xbp,&our_out_addr);
01247 if(!res) {
01248 continue;
01249 }
01250
01251
01252 *addr_out = our_out_addr;
01253 if(range_out) {
01254 *range_out = *xbp;
01255 }
01256
01257 #ifndef TURN_OFF_MEMO
01258 set_memodata_valid(memodata,xbp,entryct,entrymax,isNewAddress,
01259 restart,blk_hdr);
01260 #endif
01261 return retstatus;
01262
01263 }
01264 return XLATE_TB_STATUS_NO_SUCH_ADDR_IN_TABLE;
01265
01266 }
01267
01268
01269
01270
01271
01272
01273
01274
01275 static int
01276 _xlate_expand_block_v2_64_po(xlate_table_con tab,
01277 uniform_block_hdr *blk_hdr)
01278 {
01279 int retstatus = XLATE_TB_STATUS_NO_ERROR;
01280 char *startpt;
01281 char *endpt ;
01282 Uword entrymax;
01283 Uword entryct = 0;
01284 __uint64_t uval = 0;
01285 __uint64_t uval2 = 0;
01286 int len;
01287 xlate_block lblock = zero_xlate_block;
01288 xlate_block *xbp;
01289
01290 startpt = blk_hdr->ub_data_bytes;
01291 endpt = blk_hdr->ub_data_end;
01292 entrymax = blk_hdr->ub_entrycount;
01293
01294 blk_hdr->ub_expanded_entries = calloc(entrymax,sizeof(xlate_block));
01295 if(blk_hdr->ub_expanded_entries == 0) {
01296 return XLATE_TB_STATUS_ALLOC_FAIL;
01297 }
01298
01299 xbp = blk_hdr->ub_expanded_entries;
01300
01301 lblock.xe_new_address = blk_hdr->ub_first_new_addr;
01302 lblock.xe_old_address = blk_hdr->ub_first_old_addr;
01303
01304 for( ; entryct < entrymax && startpt < endpt; ++xbp) {
01305
01306 lblock.xe_new_address += uval;
01307 lblock.xe_old_address += uval2;
01308
01309 len = _leb128_unsigned_decode64(startpt,&uval);
01310 startpt += len;
01311 len = _leb128_unsigned_decode64(startpt,&uval2);
01312 startpt += len;
01313 ++entryct;
01314 uval <<=2;
01315 uval2 <<=2;
01316
01317 lblock.xe_new_range = uval;
01318 lblock.xe_old_range = uval2;
01319
01320 *xbp = lblock;
01321
01322 }
01323 return retstatus;
01324 }
01325 int
01326 _xlate_get_range_from_block_v2_64_po(xlate_table_con tab,
01327 int isNewAddress,
01328 Elf64_Addr addr_in,
01329 int restart,
01330 uniform_block_hdr *blk_hdr,
01331 Elf64_Addr* addr_out,
01332 xlate_block *range_out)
01333 {
01334 int retstatus = XLATE_TB_STATUS_NO_ERROR;
01335 Uword entrymax;
01336 Uword entryct = 0;
01337 Elf64_Addr our_out_addr;
01338 struct memo_s *memodata;
01339 Uword newindex;
01340 xlate_block *xbp;
01341 int res;
01342
01343 if( blk_hdr->ub_expanded_entries == 0) {
01344 retstatus = _xlate_expand_block_v2_64_po( tab,
01345 blk_hdr);
01346 if(retstatus != XLATE_TB_STATUS_NO_ERROR) {
01347 return retstatus;
01348 }
01349 }
01350 if(isNewAddress) {
01351 memodata = &tab->xc_memo_new;
01352 } else {
01353 memodata = &tab->xc_memo_old;
01354 }
01355 #ifndef TURN_OFF_MEMO
01356 if(restart) {
01357 entryct = memodata->mm_entryct;
01358 entrymax = memodata->mm_entrymax;
01359 } else {
01360 #endif
01361 entrymax = blk_hdr->ub_entrycount;
01362 #ifndef TURN_OFF_MEMO
01363 }
01364 memodata->mm_is_valid = 0;
01365 #endif
01366 xbp = blk_hdr->ub_expanded_entries;
01367
01368
01369
01370
01371
01372 res = _xlate_binary_search_xlate_block_table(xbp,
01373 entryct,entrymax,isNewAddress,addr_in,&newindex);
01374 if(!res) {
01375 return XLATE_TB_STATUS_NO_SUCH_ADDR_IN_TABLE;
01376 }
01377 entryct = newindex;
01378
01379
01380
01381
01382 xbp += entryct;
01383 for( ; entryct < entrymax ; ++xbp,++entryct) {
01384 int res = _xlate_ck_in_range_and_calc_out_addr(addr_in,
01385 isNewAddress,
01386 xbp,&our_out_addr);
01387 if(!res) {
01388 continue;
01389 }
01390
01391
01392 *addr_out = our_out_addr;
01393 if(range_out) {
01394 *range_out = *xbp;
01395 }
01396
01397 #ifndef TURN_OFF_MEMO
01398 set_memodata_valid(memodata,xbp,entryct,entrymax,isNewAddress,
01399 restart,blk_hdr);
01400 #endif
01401 return retstatus;
01402
01403 }
01404
01405 return XLATE_TB_STATUS_NO_SUCH_ADDR_IN_TABLE;
01406
01407 }
01408
01409
01410
01411 static int
01412 _xlate_expand_block_v2_64_ge(xlate_table_con tab,
01413 uniform_block_hdr *blk_hdr)
01414 {
01415 int retstatus = XLATE_TB_STATUS_NO_ERROR;
01416 char *startpt;
01417 char *endpt ;
01418 Uword entrymax;
01419 Uword entryct = 0;
01420 __uint64_t uval = 0;
01421 __int64_t sval = 0;
01422 __int64_t sval2 = 0;
01423 int len;
01424 xlate_block lblock = zero_xlate_block;
01425 xlate_block *xbp;
01426
01427 startpt = blk_hdr->ub_data_bytes;
01428 endpt = blk_hdr->ub_data_end;
01429 entrymax = blk_hdr->ub_entrycount;
01430
01431 blk_hdr->ub_expanded_entries = calloc(entrymax,sizeof(xlate_block));
01432 if(blk_hdr->ub_expanded_entries == 0) {
01433 return XLATE_TB_STATUS_ALLOC_FAIL;
01434 }
01435 xbp = blk_hdr->ub_expanded_entries;
01436 lblock.xe_new_address = blk_hdr->ub_first_new_addr;
01437 lblock.xe_old_address = blk_hdr->ub_first_old_addr;
01438 for( ; entryct < entrymax && startpt < endpt;++xbp) {
01439
01440 lblock.xe_new_address += uval;
01441
01442
01443 len = _leb128_unsigned_decode64(startpt,&uval);
01444 startpt += len;
01445
01446 len = _leb128_signed_decode64(startpt,&sval2);
01447 startpt += len;
01448
01449 len = _leb128_signed_decode64(startpt,&sval);
01450 startpt += len;
01451 ++entryct;
01452 uval <<=2;
01453 sval2 <<=2;
01454 sval <<=2;
01455
01456 lblock.xe_old_address += sval2;
01457 lblock.xe_new_range = uval;
01458
01459 lblock.xe_old_range = uval - sval;
01460
01461
01462 *xbp = lblock;
01463 }
01464
01465 return retstatus;
01466 }
01467
01468
01469 int
01470 _xlate_get_range_from_block_v2_64_ge(xlate_table_con tab,
01471 int isNewAddress,
01472 Elf64_Addr addr_in,
01473 int restart,
01474 uniform_block_hdr *blk_hdr,
01475 Elf64_Addr* addr_out,
01476 xlate_block *range_out)
01477 {
01478
01479 int retstatus = XLATE_TB_STATUS_NO_ERROR;
01480 Uword entrymax;
01481 Uword entryct = 0;
01482 Elf64_Addr our_out_addr;
01483 xlate_block *xbp;
01484 struct memo_s *memodata;
01485
01486 if( blk_hdr->ub_expanded_entries == 0) {
01487 retstatus = _xlate_expand_block_v2_64_ge( tab,
01488 blk_hdr);
01489 if(retstatus != XLATE_TB_STATUS_NO_ERROR) {
01490 return retstatus;
01491 }
01492 }
01493 #ifndef TURN_OFF_MEMO
01494 if(isNewAddress) {
01495 memodata = &tab->xc_memo_new;
01496 } else {
01497 memodata = &tab->xc_memo_old;
01498 }
01499 if(restart) {
01500 entrymax = memodata->mm_entrymax;
01501 entryct = memodata->mm_entryct;
01502 } else {
01503 #endif
01504 entrymax = blk_hdr->ub_entrycount;
01505 #ifndef TURN_OFF_MEMO
01506 }
01507 memodata->mm_is_valid = 0;
01508 #endif
01509 xbp = blk_hdr->ub_expanded_entries;
01510 if(isNewAddress) {
01511 Uword newindex;
01512 int res;
01513 res = _xlate_binary_search_xlate_block_table(xbp, entryct,
01514 entrymax,isNewAddress,addr_in,&newindex);
01515 if(!res) {
01516 return XLATE_TB_STATUS_NO_SUCH_ADDR_IN_TABLE;
01517 }
01518 entryct = newindex;
01519 }
01520
01521 xbp += entryct;
01522
01523 for( ; entryct < entrymax ; ++xbp,++entryct) {
01524
01525 int res = _xlate_ck_in_range_and_calc_out_addr(addr_in,
01526 isNewAddress,
01527 xbp,&our_out_addr);
01528 if(!res) {
01529 continue;
01530 }
01531
01532
01533 *addr_out = our_out_addr;
01534 if(range_out) {
01535 *range_out = *xbp;
01536 }
01537
01538 #ifndef TURN_OFF_MEMO
01539 set_memodata_valid(memodata,xbp,entryct,entrymax,isNewAddress,
01540 restart,blk_hdr);
01541 #endif
01542 return retstatus;
01543
01544 }
01545 return XLATE_TB_STATUS_NO_SUCH_ADDR_IN_TABLE;
01546
01547 }