int _xlate_merge_range(xlate_table_pro table, Elf64_Addr new_address, Elf64_Xword new_range, Elf64_Addr old_address, Elf64_Xword old_range) { int retstatus = XLATE_TB_STATUS_NO_ERROR; Elf64_Addr tr_address; xlate_block consumer_range; Elf64_Xword nindex = 0; Elf64_Xword oindex = 0; Elf64_Xword consumer_tab_new_address; Elf64_Xword last_valid_nindex = new_range - INSTRUCTION_SIZE; Elf64_Xword last_valid_oindex = old_range - INSTRUCTION_SIZE; Elf64_Xword tentative_new_range; Elf64_Xword tentative_old_range; while( oindex < old_range ) { consumer_tab_new_address = old_address + oindex; if(oindex == last_valid_oindex && last_valid_nindex > last_valid_oindex) { /* case nr1 > or1 */ tentative_new_range = last_valid_nindex - last_valid_oindex + INSTRUCTION_SIZE; } else { tentative_new_range = INSTRUCTION_SIZE; } retstatus = xlate_address(table->tb_con_table, XLATE_ADDRESS_INPUT_NEW_ADDRESS, consumer_tab_new_address, &tr_address, &consumer_range); if ( retstatus != XLATE_TB_STATUS_NO_ERROR) { return retstatus; } else { tentative_old_range = INSTRUCTION_SIZE; /* last new instr at end of returned consumer range? */ if(consumer_tab_new_address == (consumer_range.xe_new_address+ consumer_range.xe_new_range- INSTRUCTION_SIZE)) { /* yes.*/ /* is consumer old range > consumer new range? */ if(consumer_range.xe_old_range > consumer_range.xe_new_range) { /* case nr2 < or2 */ tentative_old_range = consumer_range.xe_old_range - consumer_range.xe_new_range + INSTRUCTION_SIZE; } } retstatus = _xlate_add_tentative_new_range(table, new_address + nindex, tentative_new_range, tr_address, tentative_old_range); if(retstatus != XLATE_TB_STATUS_NO_ERROR) { return retstatus; } nindex += tentative_new_range; oindex += tentative_old_range; } } return retstatus; }
int xlate_pro_disk_header(xlate_table_pro table, int standard_or_debug, Elf64_Xword * ototal_memory_req, Elf64_Xword * onum_blocks) { Uword total_memory_req = 0; Uword num_blocks = 0; int retstatus = XLATE_TB_STATUS_NO_ERROR; int tretstatus; if(table->tb_magic != PRO_MAGIC_VAL) { return XLATE_TB_STATUS_INVALID_TABLE; } /* Finish up any tentative output if present */ retstatus = _xlate_add_tentative_new_range(table,0, 0, 0, 0); if(retstatus != XLATE_TB_STATUS_NO_ERROR) { return retstatus; } table->tb_no_new_entries_allowed = 1; table->tb_std_header_returned = 0; table->tb_debug_header_returned = 0; table->tb_reginfoRet = 0; table->tb_header_set_to_std_or_debug = standard_or_debug; if(standard_or_debug == XLATE_PRO_STANDARD_SETUP) { table->tb_header_called_on_std = 1; table->tb_blockRet = table->tb_std_block_head; _xlate_final_update_highwater_addrs(table, table->tb_std_block_tail, &table->tb_std_highwater); /* determine if the output is empty */ if(table->tb_blockRet == 0 && table->tb_regInfoOffset == 0) { xlate_table_con contab = table->tb_con_table; if(contab) { if(contab->xc_hdr.ich_total_reginfo_bytes == 0) { /* No need to look at con_table translation ** bytes since there is no input range to ** merge them with. ** just check con table reginfo. */ *ototal_memory_req = 0; *onum_blocks = 0; return retstatus; } } else { *ototal_memory_req = 0; *onum_blocks = 0; return retstatus; } } } else if (standard_or_debug == XLATE_PRO_DEBUG_SETUP) { table->tb_header_called_on_debug = 1; table->tb_blockRet = table->tb_debug_block_head; /* determine if the output is empty */ if(table->tb_blockRet == 0 && table->tb_regInfoOffset == 0) { *ototal_memory_req = 0; *onum_blocks = 0; return retstatus; } _xlate_final_update_highwater_addrs(table, table->tb_debug_block_tail, &table->tb_debug_highwater); } else { retstatus = XLATE_TB_STATUS_PRO_REQ_INVALID; return retstatus; } /* do an initial call on each to get total size */ for(;;) { Elf64_Xword len; tretstatus = xlate_pro_disk_next_block(table, /*data=*/0, &len); if(tretstatus == XLATE_TB_STATUS_NO_ERROR) { total_memory_req += len; num_blocks += 1; continue; } else if (tretstatus == XLATE_TB_STATUS_ALREADY_DONE) { break; } /* major failure!? */ return tretstatus; } /* now reset for user to call for real. */ table->tb_no_new_entries_allowed = 1; table->tb_std_header_returned = 0; table->tb_debug_header_returned = 0; table->tb_reginfoRet = 0; table->tb_header_set_to_std_or_debug = standard_or_debug; if(standard_or_debug == XLATE_PRO_STANDARD_SETUP) { table->tb_header_called_on_std = 1; table->tb_blockRet = table->tb_std_block_head; } else if (standard_or_debug == XLATE_PRO_DEBUG_SETUP) { table->tb_header_called_on_debug = 1; table->tb_blockRet = table->tb_debug_block_head; } else { retstatus = XLATE_TB_STATUS_PRO_REQ_INVALID; return retstatus; } *ototal_memory_req = total_memory_req; *onum_blocks = num_blocks; return retstatus; }