mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-16 19:03:22 +00:00
143 lines
5.6 KiB
C++
143 lines
5.6 KiB
C++
/*
|
||
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
|
||
* Copyright (c) 2019 SAP SE. All rights reserved.
|
||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||
*
|
||
* This code is free software; you can redistribute it and/or modify it
|
||
* under the terms of the GNU General Public License version 2 only, as
|
||
* published by the Free Software Foundation.
|
||
*
|
||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||
* version 2 for more details (a copy is included in the LICENSE file that
|
||
* accompanied this code).
|
||
*
|
||
* You should have received a copy of the GNU General Public License version
|
||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||
*
|
||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||
* or visit www.oracle.com if you need additional information or have any
|
||
* questions.
|
||
*
|
||
*/
|
||
|
||
#include "asm/assembler.inline.hpp"
|
||
#include "asm/macroAssembler.hpp"
|
||
#include "code/codeCache.hpp"
|
||
#include "compiler/disassembler.hpp"
|
||
#include "gc/shared/collectedHeap.hpp"
|
||
#include "gc/shared/cardTableBarrierSet.hpp"
|
||
#include "oops/oop.inline.hpp"
|
||
#include "runtime/handles.inline.hpp"
|
||
#include "runtime/stubCodeGenerator.hpp"
|
||
#include "runtime/stubRoutines.hpp"
|
||
#include "utilities/align.hpp"
|
||
|
||
// This method does plain instruction decoding, no frills.
|
||
// It may be called before the binutils disassembler kicks in
|
||
// to handle special cases the binutils disassembler does not.
|
||
// Instruction address, comments, and the like have to be output by caller.
|
||
address Disassembler::decode_instruction0(address here, outputStream * st, address virtual_begin) {
|
||
if (is_abstract()) {
|
||
// The disassembler library was not loaded (yet),
|
||
// use AbstractDisassembler's decode-method.
|
||
return decode_instruction_abstract(here, st, Assembler::instr_len(here), Assembler::instr_maxlen());
|
||
}
|
||
|
||
// Currently, "special decoding" doesn't work when decoding error files.
|
||
// When decoding an instruction from a hs_err file, the given
|
||
// instruction address 'start' points to the instruction's virtual address
|
||
// which is not equal to the address where the instruction is located.
|
||
// Therefore, we will either crash or decode garbage.
|
||
if (is_decode_error_file()) {
|
||
return here;
|
||
}
|
||
|
||
//---< Decode some well-known "instructions" >---
|
||
|
||
address next;
|
||
uint16_t instruction_2bytes = *(uint16_t*)here;
|
||
|
||
if (Assembler::is_z_nop((long)instruction_2bytes)) {
|
||
#if 1
|
||
st->print("nop "); // fill up to operand column, leads to better code comment alignment
|
||
next = here + 2;
|
||
#else
|
||
// Compact disassembler output. Does not work the easy way.
|
||
// Currently unusable, search does not terminate, risk of crash.
|
||
// TODO: rework required.
|
||
// Terminate search loop when reaching CodeEntryAlignment-aligned offset
|
||
// or, at the latest, when reaching the next page boundary.
|
||
int n_nops = 0;
|
||
while(is_same_page(here, here+2*n_nops) && Assembler::is_z_nop((long)instruction_2bytes)) {
|
||
n_nops++;
|
||
instruction_2bytes = *(uint16_t*)(here+2*n_nops);
|
||
}
|
||
if (n_nops <= 4) { // do not group few subsequent nops
|
||
st->print("nop "); // fill up to operand column, leads to better code comment alignment
|
||
next = here + 2;
|
||
} else {
|
||
st->print("nop count=%d", n_nops);
|
||
next = here + 2*n_nops;
|
||
}
|
||
#endif
|
||
} else if (Assembler::is_z_sync((long)instruction_2bytes)) {
|
||
// Specific names. Make use of lightweight sync.
|
||
st->print("sync ");
|
||
if (Assembler::is_z_sync_full((long)instruction_2bytes) ) st->print("heavyweight");
|
||
if (Assembler::is_z_sync_light((long)instruction_2bytes)) st->print("lightweight");
|
||
next = here + 2;
|
||
} else if (instruction_2bytes == 0x0000) {
|
||
#if 1
|
||
st->print("illtrap .nodata");
|
||
next = here + 2;
|
||
#else
|
||
// Compact disassembler output. Does not work the easy way.
|
||
// Currently unusable, search does not terminate, risk of crash.
|
||
// TODO: rework required.
|
||
// Terminate search loop when reaching CodeEntryAlignment-aligned offset
|
||
// or, at the latest, when reaching the next page boundary.
|
||
int n_traps = 0;
|
||
while(is_same_page(here, here+2*n_nops) && (instruction_2bytes == 0x0000)) {
|
||
n_traps++;
|
||
instruction_2bytes = *(uint16_t*)(here+2*n_traps);
|
||
}
|
||
if (n_traps <= 4) { // do not group few subsequent illtraps
|
||
st->print("illtrap .nodata");
|
||
next = here + 2;
|
||
} else {
|
||
st->print("illtrap .nodata count=%d", n_traps);
|
||
next = here + 2*n_traps;
|
||
}
|
||
#endif
|
||
} else if ((instruction_2bytes & 0xff00) == 0x0000) {
|
||
st->print("illtrap .data 0x%2.2x", instruction_2bytes & 0x00ff);
|
||
next = here + 2;
|
||
} else {
|
||
next = here;
|
||
}
|
||
return next;
|
||
}
|
||
|
||
// Print annotations (value of loaded constant)
|
||
void Disassembler::annotate(address here, outputStream* st) {
|
||
// Currently, annotation doesn't work when decoding error files.
|
||
// When decoding an instruction from a hs_err file, the given
|
||
// instruction address 'start' points to the instruction's virtual address
|
||
// which is not equal to the address where the instruction is located.
|
||
// Therefore, we will either crash or decode garbage.
|
||
if (is_decode_error_file()) {
|
||
return;
|
||
}
|
||
|
||
if (MacroAssembler::is_load_const(here)) {
|
||
long value = MacroAssembler::get_const(here);
|
||
const int tsize = 8;
|
||
|
||
st->fill_to(60);
|
||
st->print(";const %p | %ld | %23.15e", (void *)value, value, (double)value);
|
||
}
|
||
}
|