static int first_nibble_is_6(RAnal* anal, RAnalOp* op, ut16 code){ if (IS_MOV_REGS(code)) { op->type = R_ANAL_OP_TYPE_MOV; op->src[0] = anal_fill_ai_rg (anal, GET_SOURCE_REG(code)); op->dst = anal_fill_ai_rg (anal, GET_TARGET_REG(code)); } else if (IS_MOVB_REGREF_TO_REG(code)) { op->type = R_ANAL_OP_TYPE_LOAD; op->src[0] = anal_fill_reg_ref (anal, GET_SOURCE_REG(code), BYTE_SIZE); op->dst = anal_fill_ai_rg (anal, GET_TARGET_REG(code)); } else if (IS_MOVW_REGREF_TO_REG(code)) { op->type = R_ANAL_OP_TYPE_LOAD; op->src[0] = anal_fill_reg_ref (anal, GET_SOURCE_REG(code), WORD_SIZE); op->dst = anal_fill_ai_rg (anal, GET_TARGET_REG(code)); } else if (IS_MOVL_REGREF_TO_REG(code)) { op->type = R_ANAL_OP_TYPE_LOAD; op->src[0] = anal_fill_reg_ref (anal, GET_SOURCE_REG(code), LONG_SIZE); op->dst = anal_fill_ai_rg (anal, GET_TARGET_REG(code)); } else if (IS_EXT(code)) { //ext{s,u}.{b,w} instructs. todo : more detail ? op->type = R_ANAL_OP_TYPE_MOV; op->src[0] = anal_fill_ai_rg (anal, GET_SOURCE_REG(code)); op->dst = anal_fill_ai_rg (anal, GET_TARGET_REG(code)); } else if (IS_MOVB_POP(code) || IS_MOVW_POP(code) || IS_MOVL_POP(code)) { /* 0110nnnnmmmm0100 mov.b @<REG_M>+,<REG_N>*/ /* 0110nnnnmmmm0101 mov.w @<REG_M>+,<REG_N>*/ /* 0110nnnnmmmm0110 mov.l @<REG_M>+,<REG_N>*/ op->type = R_ANAL_OP_TYPE_POP; op->dst = anal_fill_ai_rg (anal, GET_TARGET_REG(code)); //todo : op->src for pop = ? } else if (IS_NEG(code)) { //todo: neg and negc details op->type = R_ANAL_OP_TYPE_UNK; /* 0110nnnnmmmm1010 negc*/ /* 0110nnnnmmmm1010 neg */ op->src[0] = anal_fill_ai_rg (anal, GET_SOURCE_REG(code)); op->dst = anal_fill_ai_rg (anal, GET_TARGET_REG(code)); } else if (IS_NOT(code)) { //todo : details? op->type = R_ANAL_OP_TYPE_NOT; op->src[0] = anal_fill_ai_rg (anal, GET_SOURCE_REG(code)); op->dst = anal_fill_ai_rg (anal, GET_TARGET_REG(code)); } else if (IS_SWAP(code)) { /* 0110nnnnmmmm1000 swap.b <REG_M>,<REG_N>*/ /* 0110nnnnmmmm1001 swap.w <REG_M>,<REG_N>*/ op->type = R_ANAL_OP_TYPE_MOV; //todo : details } return op->size; }
/* **************************************************************** * Lê as partições do volume e atualiza a "disktb" * **************************************************************** */ DISKTB * disktb_create_partitions (DISKTB *base_up) { DISKTB *up, *slot_up = NODISKTB; const DISKTB *end_up; dev_t dev; BHEAD *bp; const PARTTB *reg_pp, *log_pp; daddr_t log_offset, ext_begin, ext_end; int reg_index, log_index, minor_index = 1; int slot_sz, dec; HDINFO hdinfo; char area[BLSZ]; /* * A partição global do volume acabou de ser criada * * ("base_up" é idêntico a "next_disktb") * * Lê o Bloco 0 do volume e extrai a tabela de partições */ up = base_up; dev = up->p_dev; bp = bread (dev, 0, 0); if (bp->b_flags & B_ERROR) { block_put (bp); return (NODISKTB); } if (*(ushort *)(bp->b_addr + MAGIC_OFF) != 0xAA55) printf ("%s: O bloco 0 NÃO contém a assinatura \"0x55AA\"\n", up->p_name); memmove (area, bp->b_addr, BLSZ); block_put (bp); bp = NOBHEAD; /* * Tenta obter a geometria do volume */ geo_get_parttb_geo (up->p_name, area, &hdinfo, up->p_size); /* * Completa a entrada para o volume inteiro */ /*** up->p_name = ...; ***/ /*** up->p_offset = 0; ***/ /*** up->p_size = ...; ***/ /*** up->p_type = 0; ***/ /*** up->p_flags = 0; ***/ /*** up->p_lock = 0; ***/ /*** up->p_blshift = ...; ***/ /*** up->p_dev = ...; ***/ /*** up->p_unit = ...; ***/ /*** up->p_target = ...; ***/ up->p_head = hdinfo.h_head; up->p_sect = hdinfo.h_sect; up->p_cyl = hdinfo.h_cyl; /*** up->p_nopen = 0; ***/ /*** up->p_sb = NOSB; ***/ /*** up->p_inode = NOINODE; ***/ up++; /* * Processa todas as partições */ for (reg_pp = (PARTTB *)(area + PARTB_OFF), reg_index = 1; reg_index <= NPART; reg_index++, reg_pp++) { if (reg_pp->pt_size == 0) continue; /* Encontrou uma partição regular/estendida válida */ if (up >= end_disktb - 1) { printf ("%s: DISKTB cheia\n", base_up->p_name); break; } sprintf (up->p_name, "%s%d", base_up->p_name, reg_index); up->p_offset = reg_pp->pt_offset; up->p_size = reg_pp->pt_size; up->p_type = reg_pp->pt_type; up->p_flags = (reg_pp->pt_active == 0x80) ? DISK_ACTIVE : 0; /*** up->p_lock = 0; ***/ up->p_blshift = base_up->p_blshift; up->p_dev = dev + minor_index++; /* incrementa o MINOR */ up->p_unit = base_up->p_unit; up->p_target = base_up->p_target; up->p_head = hdinfo.h_head; up->p_sect = hdinfo.h_sect; up->p_cyl = hdinfo.h_cyl; /*** up->p_nopen = 0; ***/ /*** up->p_sb = NOSB; ***/ /*** up->p_inode = NOINODE; ***/ up++; if (!IS_EXT (reg_pp->pt_type)) continue; /* * Temos uma partição estendida */ ext_begin = reg_pp->pt_offset; ext_end = reg_pp->pt_offset + reg_pp->pt_size; log_offset = ext_begin; /* * Percorre a cadeia de partições lógicas */ for (log_index = 0; /* abaixo */; log_index++) { if (log_offset < ext_begin || log_offset >= ext_end) { printf ( "%s: Deslocamento %d inválido na partição estendida %d\n", base_up->p_name, log_offset, reg_index ); break; } if (bp != NOBHEAD) block_put (bp); bp = bread (dev, log_offset, 0); if (bp->b_flags & B_ERROR) { block_put (bp); bp = NOBHEAD; break; } if (*(ushort *)(bp->b_addr + MAGIC_OFF) != 0xAA55) { printf ( "%s: O bloco %d da partição estendida %d " "NÃO contém a assinatura \"0x55AA\"\n", base_up->p_name, log_offset, reg_index ); } log_pp = (PARTTB *)(bp->b_addr + PARTB_OFF); if (log_pp[0].pt_size == 0) /* Primeiro método de EOF */ break; /* Encontrou uma partição lógica válida */ if (up >= end_disktb - 1) { printf ("%s: DISKTB cheia\n", base_up->p_name); goto out; } sprintf (up->p_name, "%s%d%c", base_up->p_name, reg_index, 'a' + log_index); up->p_offset = log_offset + log_pp->pt_offset; up->p_size = log_pp->pt_size; up->p_type = log_pp->pt_type; up->p_flags = (log_pp->pt_active == 0x80) ? DISK_ACTIVE : 0; /*** up->p_lock = 0; ***/ up->p_blshift = base_up->p_blshift; up->p_dev = dev + minor_index++; /* incrementa o MINOR */ up->p_unit = base_up->p_unit; up->p_target = base_up->p_target; up->p_head = hdinfo.h_head; up->p_sect = hdinfo.h_sect; up->p_cyl = hdinfo.h_cyl; /*** up->p_nopen = 0; ***/ /*** up->p_sb = NOSB; ***/ /*** up->p_inode = NOINODE; ***/ up++; /* * Procura a partição seguinte */ if (log_pp[1].pt_size == 0) /* Segundo método de EOF */ break; log_offset = ext_begin + log_pp[1].pt_offset; } /* end for (cadeia de partições lógicas) */ } /* end for (partições regulares/estendeidas) */ out: if (bp != NOBHEAD) block_put (bp); /* * Atualiza o final da "disktb" */ next_disktb = up; up->p_name[0] = '\0'; /* * Neste ponto, "minor_index" contém o número de entradas total * * Procura um grupo de "minor_index" entradas vagas contíguas */ for (slot_sz = 0, up = disktb; /* abaixo */; up++) { if (up >= base_up) return (base_up); if (up->p_name[0] != '*') { slot_sz = 0; continue; } if (slot_sz++ == 0) slot_up = up; if (slot_sz >= minor_index) break; } /* * Encontrou um grupo adequado */ memmove (slot_up, base_up, minor_index * sizeof (DISKTB)); dec = base_up - slot_up; for (up = slot_up, end_up = up + minor_index; up < end_up; up++) up->p_dev -= dec; /* Supondo que o MINOR esteja na parte baixa */ memclr (base_up, minor_index * sizeof (DISKTB)); next_disktb = base_up; return (slot_up); } /* end disktb_create_partitions */
/* **************************************************************** * Le as partições do volume e atualiza a "disktb" * **************************************************************** */ int disktb_open_entries (dev_t dev, const SCSI *sp) { DISKTB *up; BHEAD *bp; const PARTTB *reg_pp; HDINFO hdinfo; int reg_index; /* * Obtém a partição inicial do dispositivo */ if ((up = disktb_get_first_entry (dev)) == NODISKTB) return (-1); /* * Le o Bloco 0 do volume */ bp = bread (up->p_dev, 0, 0); if (bp->b_flags & B_ERROR) { block_put (bp); return (-1); } if (*(ushort *)(bp->b_addr + MAGIC_OFF) != 0xAA55) { printf ( "%s: O bloco 0 NÃO contém a assinatura \"0x55AA\"\n", up->p_name ); } /* * Tenta obter a geometria do disco */ geo_get_parttb_geo (up->p_name, bp->b_addr, &hdinfo, sp->scsi_disksz); /* * Processa (por enquanto) somente a primeira partição regular */ for ( reg_index = 0, reg_pp = (PARTTB *)(bp->b_addr + PARTB_OFF); /* abaixo */; reg_index++, reg_pp++ ) { if (reg_index >= NPART) { printf ( "%s: Volume NÃO tem partição regular\n", up->p_name ); u.u_error = ENXIO; block_put (bp); return (-1); } if (reg_pp->pt_size == 0) continue; if (!IS_EXT (reg_pp->pt_type)) break; printf ( "%s: Partição ESTENDIDA ignorada\n", up->p_name ); } /* * Completa a entrada do disco inteiro */ /*** up->p_offset = ...; ***/ up->p_size = sp->scsi_disksz; /*** up->p_type = 0; ***/ /*** up->p_flags = 0; ***/ /*** up->p_lock = 0; ***/ up->p_blshift = sp->scsi_blshift; /*** up->p_dev = ...; ***/ /*** up->p_unit = ...; ***/ /*** up->p_target = ...; ***/ up->p_head = hdinfo.h_head; up->p_sect = hdinfo.h_sect; up->p_cyl = hdinfo.h_cyl; /*** up->p_nopen = 0; ***/ /* * Prepara a entrada da partição regular */ up++; up->p_offset = reg_pp->pt_offset; up->p_size = reg_pp->pt_size; up->p_type = reg_pp->pt_type; up->p_flags = (reg_pp->pt_active == 0x80) ? DISK_ACTIVE : 0; /*** up->p_lock = 0; ***/ up->p_blshift = sp->scsi_blshift; /*** up->p_dev = ...; ***/ /*** up->p_unit = ...; ***/ /*** up->p_target = ...; ***/ up->p_head = hdinfo.h_head; up->p_sect = hdinfo.h_sect; up->p_cyl = hdinfo.h_cyl; /*** up->p_nopen = 0; ***/ block_put (bp); return (0); } /* end disktb_open_entries */