Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}