/*******************************************************************************
 * Copyright (c) 2009, 2010 Nokia 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:
 * Nokia - Initial API and implementation
 *******************************************************************************/
package org.eclipse.cdt.debug.edc.x86;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.cdt.debug.edc.MemoryUtils;
import org.eclipse.cdt.debug.edc.services.IEDCExecutionDMC;
import org.eclipse.cdt.debug.edc.services.IEDCMemory;
import org.eclipse.cdt.debug.edc.services.IEDCModuleDMContext;
import org.eclipse.cdt.debug.edc.services.IEDCModules;
import org.eclipse.cdt.debug.edc.services.Registers;
import org.eclipse.cdt.debug.edc.services.Stack;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.utils.Addr64;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.debug.core.model.MemoryByte;

public class X86Stack extends Stack {

	static class X86PreservedRegisters {

		// the values of registers stored in this frame
		// note: only integer variables tracked
		BigInteger registers[] = new BigInteger[8];
		
		public Map<Integer, BigInteger> getPreservedRegisters() {
			Map<Integer, BigInteger> map = new HashMap<Integer, BigInteger>();
			for (int i = 0; i < registers.length; i++) {
				if (registers[i] != null)
					map.put(i, registers[i]);
			}
			return map;
		}
	}

	public X86Stack(DsfSession session) {
		super(session, new String[] { X86Stack.class.getName() });
	}

	/**
	 * Analyze the stack frame and try to decide what the base address (EBP or ESP),
	 * return address, and preserved registers are.
	 * 
	 * If we are at the beginning of a function, the PUSH %EBP / MOV %ESP,%EBP
	 * instructions are a clue as to where the return address and previous base address have
	 * been placed.  
	 * 
	 * We may also have a jump into a DLL (a jmp *0xNNNN address) which is not yet a new
	 * stack frame.
	 * 
	 * Otherwise, we assume that the current value of EBP is the base
	 * address.  (TODO: optimized code might use EBP as a variable, so if it is far enough
	 * out of range of ESP, we must quit here.)  
	 * @throws CoreException 
	 * @throws NumberFormatException 
	 */
	@Override
	protected List<EdcStackFrame> computeStackFrames(IEDCExecutionDMC context, int startIndex, int endIndex) throws NumberFormatException, CoreException {

		ArrayList<EdcStackFrame> frames = new ArrayList<EdcStackFrame>();

		IEDCModules modules = getService(IEDCModules.class);
		IEDCMemory memoryService = getService(IEDCMemory.class);
		Registers registersService = getService(Registers.class);


		long eipValue = Long.valueOf(registersService.getRegisterValue(context, "EIP"), 16);
		long espValue = Long.valueOf(registersService.getRegisterValue(context, "ESP"), 16);
		long ebpValue = Long.valueOf(registersService.getRegisterValue(context, "EBP"), 16);
		
		long baseAddress = ebpValue;
		long instructionAddress = eipValue;
		long returnAddress = 0;
		long previousBaseAddress = 0;
		long previousPtrToBaseAddress = 0;

		while (true) {
			int level = frames.size();
			
			HashMap<String, Object> properties = new HashMap<String, Object>();
			
			IEDCModuleDMContext module = modules.getModuleByAddress(context.getSymbolDMContext(), new Addr64(Long
					.toString(instructionAddress)));
			
			boolean isFramePushed = true;
			boolean detected = false;
			X86PreservedRegisters preserved = new X86PreservedRegisters();
			
			ArrayList<MemoryByte> memBuffer = new ArrayList<MemoryByte>();
			IStatus memGetStatus = memoryService.getMemory(context, new Addr64(Long.toString(eipValue)), memBuffer, 4,
					1);
			
			boolean validRead = memGetStatus.isOK();
			if (validRead) {
				// check each byte
				for (int i = 0; i < memBuffer.size(); i++) {
					if (memBuffer.get(i) == null || !memBuffer.get(i).isReadable()) {
						validRead = false;
						break;
					}
				}
			}

			if (validRead) {
				byte op1 = memBuffer.get(0).getValue();
				byte op2 = memBuffer.size() > 1 ? memBuffer.get(1).getValue() : 0;
				
				if (level == 0) {
					// the current instruction is special because it may be
					// before the frame has been established
					if (op1 == 0x55) {
						// push %ebp -- only return address is on stack; base address is still %ebp
						detected = true;
						isFramePushed = false;
						
						previousBaseAddress = ebpValue;
						returnAddress = readAddress(context, memoryService, espValue);
					}
					else if (op1 == (byte) 0x89 && op2 == (byte) 0xe5) {
						// mov %esp, %ebp -- only return address and ebp are on stack; base address is still %ebp
						detected = true;
						isFramePushed = false;
						
						previousBaseAddress = ebpValue;
						returnAddress = readAddress(context, memoryService, espValue + 4);
					}
					else if (op1 == (byte) 0xff && op2 == (byte) 0x25) {
						// jmp *0xNNNNN -- likely we're in an __imp_xxx thunk, and the new frame is not pushed
						detected = true;
						isFramePushed = false;
						
						previousBaseAddress = ebpValue;
						returnAddress = readAddress(context, memoryService, espValue);
					}
				}
				if (!detected) {
					// assume we're inside the function already
					preserved.registers[X86Registers.EBP] = BigInteger.valueOf(level == 0 ? ebpValue : previousPtrToBaseAddress);
					
					previousPtrToBaseAddress = baseAddress;
					previousBaseAddress = readAddress(context, memoryService, baseAddress);
					returnAddress = readAddress(context, memoryService, baseAddress + 4);
				}
			}
		
			properties = new HashMap<String, Object>();
			properties.put(StackFrameDMC.LEVEL_INDEX, level);
			properties.put(StackFrameDMC.BASE_ADDR, Long.valueOf(baseAddress));
			properties.put(StackFrameDMC.INSTRUCTION_PTR_ADDR, Long.valueOf(instructionAddress));
			if (module != null) properties.put(StackFrameDMC.MODULE_NAME, module.getName());
			if (level == 0) properties.put(StackFrameDMC.IN_PROLOGUE, !isFramePushed);
			properties.put(StackFrameDMC.PRESERVED_REGISTERS, preserved.getPreservedRegisters());
			frames.add(new EdcStackFrame(properties));
			
			// avoid recursive loop
			if (level > 0 && baseAddress == previousBaseAddress) {
				properties.put(StackFrameDMC.ROOT_FRAME, true);
				break;
			}
			
			baseAddress = previousBaseAddress;
			instructionAddress = returnAddress;
			
			// Bail out when we hit the top of the stack frame
			if (baseAddress == 0) {
				properties.put(StackFrameDMC.ROOT_FRAME, true);
				break;
			}
		}
	
		return frames;
	}

	private long readAddress(IEDCExecutionDMC context, IEDCMemory memoryService, long addr) {
		ArrayList<MemoryByte> memBuffer = new ArrayList<MemoryByte>();
		IStatus status = memoryService.getMemory(context, new Addr64(Long.toString(addr)), memBuffer, 4, 1);
		if (!status.isOK())
			return 0;

		// check each byte
		for (int i = 0; i < memBuffer.size(); i++) {
			if (memBuffer.get(i) == null || !memBuffer.get(i).isReadable())
				return 0;
		}

		return MemoryUtils.convertByteArrayToUnsignedLong(
				memBuffer.subList(0, 4).toArray(new MemoryByte[4]), MemoryUtils.LITTLE_ENDIAN)
				.longValue();
	}

}
