/*******************************************************************************
* Copyright (c) 2000, 2009 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* QNX Software Systems - Initial API and implementation
* Ericsson - Modified for DSF Reference Implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service.command.output;
import java.util.ArrayList;
import java.util.List;
/**
* The parsed output of the data-disassemble command. The output format is
* determined by the mode field on the request.
*
* -data-disassemble -s $pc -e "$pc + 20" -- 0
* ^done,asm_insns=[
* {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"},
* {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"},
* {address="0x000107c8",func-name="main",offset="12",inst="or %o2, 0x140, %o1\t! 0x11940 <_lib_version+8>"},
* {address="0x000107cc",func-name="main",offset="16",inst="sethi %hi(0x11800), %o2"},
* {address="0x000107d0",func-name="main",offset="20",inst="or %o2, 0x168, %o4\t! 0x11968 <_lib_version+48>"}]
*
* -data-disassemble -f basics.c -l 32 -- 0
* ^done,asm_insns=[
* {address="0x000107bc",func-name="main",offset="0",inst="save %sp, -112, %sp"},
* {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"},
* {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"},
* [...]
* {address="0x0001081c",func-name="main",offset="96",inst="ret "},
* {address="0x00010820",func-name="main",offset="100",inst="restore "}]
*
* -data-disassemble -f basics.c -l 32 -n 3 -- 1
* ^done,asm_insns=[
* src_and_asm_line={line="31",file="/dir1/dir2/basics.c",line_asm_insn=[
* {address="0x000107bc",func-name="main",offset="0",inst="save %sp, -112, %sp"}]},
* src_and_asm_line={line="32",file="/dir1/dir2/basics.c",line_asm_insn=[
* {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"},
* {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"}]}]
*
*/
public class MIDataDisassembleInfo extends MIInfo {
// The parsed information
private boolean mixed;
private MIMixedInstruction[] mixedCode;
private MIInstruction[] assemblyCode;
public MIDataDisassembleInfo(MIOutput record) {
super(record);
mixed = false;
parse();
}
public boolean isMixed() {
return mixed;
}
public MIInstruction[] getMIAssemblyCode() {
return assemblyCode;
}
public MIMixedInstruction[] getMIMixedCode() {
return mixedCode;
}
/**
* Find the relevant tag in the output record ("asm_insns") and then
* parse its value.
*/
private void parse() {
List<MIInstruction> asmList = new ArrayList<MIInstruction>();
List<MIMixedInstruction> srcList = new ArrayList<MIMixedInstruction>();
if (isDone()) {
MIOutput out = getMIOutput();
MIResultRecord rr = out.getMIResultRecord();
if (rr != null) {
MIResult[] results = rr.getMIResults();
// Technically, there should be only one field (asm_insns), but just in case...
for (int i = 0; i < results.length; i++) {
String var = results[i].getVariable();
if (var.equals("asm_insns")) { //$NON-NLS-1$
MIValue value = results[i].getMIValue();
if (value instanceof MIList) {
parseResult((MIList) value, srcList, asmList);
}
}
}
}
}
assemblyCode = asmList.toArray(new MIInstruction[asmList.size()]);
mixedCode = srcList.toArray(new MIMixedInstruction[srcList.size()]);
}
/**
* Parse the back-end result. Depending on the requested mode
* ("-- 0" or "-- 1" on the request), the result has one of the
* following forms:
*
* [1] Mode == 0 (assembly instructions only)
* {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"},
* {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"},
* ...,
* {address="0x00010820",func-name="main",offset="100",inst="restore "}
*
* [2] Mode == 1 (Mixed source and assembly code)
* src_and_asm_line={
* line="31",file="/dir1/dir2/basics.c",
* line_asm_insn=[
* {address="0x000107c0",func-name="main",offset="4",inst="mov 2, %o0"},
* {address="0x000107c4",func-name="main",offset="8",inst="sethi %hi(0x11800), %o2"},
* ...,
* {address="0x00010820",func-name="main",offset="100",inst="restore "}
* ]
* },
* ...,
* src_and_asm_line={
* line="31",file="/dir1/dir2/basics.c",
* line_asm_insn=[
* ...,
* ]
* }
*/
private void parseResult(MIList list,
List<MIMixedInstruction> srcList, List<MIInstruction> asmList) {
// Mixed mode (with source)
MIResult[] results = list.getMIResults();
if (results != null && results.length > 0) {
for (int i = 0; i < results.length; i++) {
String var = results[i].getVariable();
if (var.equals("src_and_asm_line")) { //$NON-NLS-1$
MIValue value = results[i].getMIValue();
if (value instanceof MITuple) {
srcList.add(new MIMixedInstruction((MITuple) value));
}
}
}
mixed = true;
}
// Non-mixed mode
MIValue[] values = list.getMIValues();
if (values != null && values.length > 0) {
for (int i = 0; i < values.length; i++) {
if (values[i] instanceof MITuple) {
asmList.add(new MIInstruction((MITuple) values[i]));
}
}
mixed = false;
}
}
}