import subprocess
import re

import disasm
import file.file
import file.map

class objdump (disasm.disasm):
	"The objdump-based disassembler"
	# This disassembler engine calls objdump as the backend.

	# Sweep the whole map and disassemble code segments
	def sweep(self):
		map = self.file.map
		p = Popen(["objdump", "-fd", self.file.name], stdout=PIPE).communicate()[0]
		base = 0
		lastend = 0
		lastseg = None

		for line in p.readline():
			# start address 0x08048be0
			if (m = re.compile(r"^start address (.*)").match(line)):
				base = int(m.group(1), 16)

			#  8048d15:       c7 44 24 04 01 00 00    movl   $0x1,0x4(%esp)
			elif (m = re.compile(r"^ ([0-9a-f]+):       (.{21})   (.*)").match(line)):
				# Instruction
				ofs = int(m.group(1), 16) - base

				# Fill gap with data
				assert(ofs >= lastend + 1)
				if (ofs > lastend + 1):
					map.new_segment(file.map.seg_data(map, lastend + 1, ofs - lastend - 1))

				# Find out length
				bytes = m.group(2)
				len = (len(bytes) - len(bytes.strip()) + 1) / 3

				txt = m.group(3)

				lastseg = file.map.seg_code(map, ofs, len, txt)
				lastend = ofs + len - 1

			#  8048d1c:       00
			elif (m = re.compile(r"^ ([0-9a-f]+):       (.{3,21})$").match(line)):
				# Instruction continuation
				ofs = int(m.group(1), 16) - base
				assert(ofs == lastend + 1)

				# Find out length
				bytes = m.group(2)
				len = (len(bytes) - len(bytes.strip()) + 1) / 3

				lastseg.len += len
				lastend += len


		# Trailing data
		if (lastend < self.file.size):
			map.new_segment(file.map.seg_data(map, lastend + 1, self.file.size - lastend))
