import sys
import sre
import os

def l(string):
	print >>sys.stderr, ("%s"%string)
	
class DisassGOT:
	header = []
	table = []
	plt = {}
	GOTfields = []
	parent = None
	
	def __init__(self, filename, parent):
		l("Loading GOT")
		self.parent = parent
		self.init(os.popen('objdump -R %s'%filename).readlines())
		l("Processing ASM")
		self.process(os.popen('objdump -S %s'%filename).readlines())
		
	def __str__(self):
		retvar = "\n".join(self.table)
		for i in self.plt:
			retvar += "%s::%s\n"%(i, self.plt.get(i))
		return retvar
	
	def init(self, lines=""):
		while (len(lines) > 0 and sre.match('^[0-9a-fA-F]{7,8}', lines[0]) == None):
			self.header.append(lines.pop(0))
		
		# Strip off leading " " and "0"s from each line
		for LINE in lines:
			LINE = LINE.strip()
			while (len(LINE)>0 and (LINE[0] == " " or LINE[0] == "0")):
				LINE = LINE[1:]
				#l("shrinking")
			
			if (len(LINE) == 0):
				continue
			
			self.table.append(LINE)

			lineparts = LINE.split()
			self.parent.registerLookup(lineparts[0],"PLT::%s"%lineparts[2])
	
	def append(self, lines):
		self.table.append(lines)
		
		
	def process(self, lines):
		self.table.sort()
		
		self.GOTfields = []
		for got in self.table:
			self.GOTfields.append(sre.split("\s+", got))
			
		### Tag PLT with GOT names
		each = 0
		length = len(lines)
		WORKIT = False
		while (each < length):
			try:
				thisline = lines[each].strip()
				thisline.lower().index('jmp')

				if (WORKIT):
					#l("GOT.process: %s" % (thisline))
					for got in self.GOTfields:
						if (sre.search(got[0], thisline) >-1):
							address = sre.split(':', thisline)[0]
							self.plt.setdefault(address, got[2])
							self.parent.registerLookup(address,"GOT::%s"%got[2])
							#("::".join(got))
			except ValueError,e:
				pass
				#l("GOT.process: Error: %s::%s"%(e,thisline))
				
			if (thisline.find("Disassembly of section .plt:") >=0):
				WORKIT = True
				l("STARTING THE PLT SECTION")
			elif (thisline.find("Disassembly of section") >=0 and WORKIT):
				WORKIT = False
				each = length
				l("END PLT")
			
			each += 1
	
	def getGOT(self):
		return self.table
	
	def getPLT(self):
		return self.plt
	
	def getSubName(self,address, clean = False):
		name = ""
		#for i in self.table:
		#	#    print >>sys.stderr, ("%s:%s" % (address,i))
		#	if (sre.search(address, i ) > -1):
		#		name = "GOT::%s"%i[45:-1]
		#l(address)
		pltname = self.plt.get(address,"")
		if (len(pltname) > 0):
			if (not clean): name += "PLT::"
			name += "%s" % pltname
		
		for i in self.GOTfields:
			#    print >>sys.stderr, ("GOT.getSubName: %s:%s" % (address,i))
			if (i[0].find(address) > -1 and len(address) == len(i[0])):
				if (not clean): name += "GOT::"
				name += "%s"%(i[2])

		return name
		
	def printTXT(self, outfile=sys.stdout):
		print >>outfile,("\n\nGOT:")
		for line in self.table:
			print >>outfile,(line.strip())
			
			
