void check_eofpage(char *s, unsigned offset, char *p, int size) { unsigned long last_page, should_be_zero; if (offset + size <= (file_size & ~page_mask)) return; /* * we landed in the last page of the file * test to make sure the VM system provided 0's * beyond the true end of the file mapping * (as required by mmap def in 1996 posix 1003.1) */ last_page = ((unsigned long)p + (offset & page_mask) + size) & ~page_mask; for (should_be_zero = last_page + (file_size & page_mask); should_be_zero < last_page + page_size; should_be_zero++) if (*(char *)should_be_zero) { prt("Mapped %s: non-zero data past EOF (0x%llx) page offset 0x%x is 0x%04x\n", s, file_size - 1, should_be_zero & page_mask, short_at(should_be_zero)); report_failure(205); } }
void check_buffers(unsigned offset, unsigned size) { unsigned char c, t; unsigned i = 0; unsigned n = 0; unsigned op = 0; unsigned bad = 0; if (memcmp(good_buf + offset, temp_buf, size) != 0) { prt("READ BAD DATA: offset = 0x%x, size = 0x%x, fname = %s\n", offset, size, iname); prt("OFFSET\tGOOD\tBAD\tRANGE\n"); while (size > 0) { c = good_buf[offset]; t = temp_buf[i]; if (c != t) { if (n < 16) { bad = short_at(&temp_buf[i]); prt("0x%5x\t0x%04x\t0x%04x", offset, short_at(&good_buf[offset]), bad); op = temp_buf[offset & 1 ? i+1 : i]; prt("\t0x%5x\n", n); if (op) prt("operation# (mod 256) for " "the bad data may be %u\n", ((unsigned)op & 0xff)); else prt("operation# (mod 256) for " "the bad data unknown, check" " HOLE and EXTEND ops\n"); } n++; badoff = offset; } offset++; i++; size--; } report_failure(110); } }
// The current instruction of "c" is a jump; one of its offset starts // at "offset" and is a short if "isShort" is "TRUE", // and an integer otherwise. If the jump crosses "breakPC", change // the span of the jump by "delta". void Relocator::change_jump(int bci, int offset, bool is_short, int break_bci, int delta) { int bci_delta = (is_short) ? short_at(offset) : int_at(offset); int targ = bci + bci_delta; if ((bci <= break_bci && targ > break_bci) || (bci > break_bci && targ <= break_bci)) { int new_delta; if (bci_delta > 0) new_delta = bci_delta + delta; else new_delta = bci_delta - delta; if (is_short && ((new_delta > MAX_SHORT) || new_delta < MIN_SHORT)) { push_jump_widen(bci, delta, new_delta); } else if (is_short) { short_at_put(offset, new_delta); } else { int_at_put(offset, new_delta); } } }
// handle jump_widen instruction. Called be ChangeJumpWiden class bool Relocator::handle_jump_widen(int bci, int delta) { int ilen = rc_instr_len(bci); Bytecodes::Code bc = code_at(bci); switch (bc) { case Bytecodes::_ifeq: case Bytecodes::_ifne: case Bytecodes::_iflt: case Bytecodes::_ifge: case Bytecodes::_ifgt: case Bytecodes::_ifle: case Bytecodes::_if_icmpeq: case Bytecodes::_if_icmpne: case Bytecodes::_if_icmplt: case Bytecodes::_if_icmpge: case Bytecodes::_if_icmpgt: case Bytecodes::_if_icmple: case Bytecodes::_if_acmpeq: case Bytecodes::_if_acmpne: case Bytecodes::_ifnull: case Bytecodes::_ifnonnull: { const int goto_length = Bytecodes::length_for(Bytecodes::_goto); // If 'if' points to the next bytecode after goto, it's already handled. // it shouldn't be. assert (short_at(bci+1) != ilen+goto_length, "if relocation already handled"); assert(ilen == 3, "check length"); // Convert to 0 if <cond> goto 6 // 3 _goto 11 // 6 _goto_w <wide delta offset> // 11 <else code> const int goto_w_length = Bytecodes::length_for(Bytecodes::_goto_w); const int add_bci = goto_length + goto_w_length; if (!relocate_code(bci, 3, /*delta*/add_bci)) return false; // if bytecode points to goto_w instruction short_at_put(bci + 1, ilen + goto_length); int cbci = bci + ilen; // goto around code_at_put(cbci, Bytecodes::_goto); short_at_put(cbci + 1, add_bci); // goto_w <wide delta> cbci = cbci + goto_length; code_at_put(cbci, Bytecodes::_goto_w); if (delta > 0) { delta += 2; // goto_w is 2 bytes more than "if" code } else { delta -= ilen+goto_length; // branch starts at goto_w offset } int_at_put(cbci + 1, delta); break; } case Bytecodes::_goto: case Bytecodes::_jsr: assert(ilen == 3, "check length"); if (!relocate_code(bci, 3, 2)) return false; if (bc == Bytecodes::_goto) code_at_put(bci, Bytecodes::_goto_w); else code_at_put(bci, Bytecodes::_jsr_w); // If it's a forward jump, add 2 for the widening. if (delta > 0) delta += 2; int_at_put(bci + 1, delta); break; default: ShouldNotReachHere(); } return true; }
jushort line_number(int index) { GUARANTEE(((index * 2) + 1) < length(), "line number table line_num index out of bounds"); return is_compressed() ? ubyte_at((index * 2) + 1) : short_at((index * 2) + 1); }