diff --git a/linux-ramdump-parser-v2/ramdump.py b/linux-ramdump-parser-v2/ramdump.py
index 34bb0a087028fdd34a29657d8f0ca8865851efca..afc974ca585b7180f3a2a83b6e24c6ed0e1faa33 100644
--- a/linux-ramdump-parser-v2/ramdump.py
+++ b/linux-ramdump-parser-v2/ramdump.py
@@ -1263,13 +1263,33 @@ class RamDump():
         symbols = stream.readlines()
         kaslr = self.get_kaslr_offset()
 
+        # The beginning and ending of kernel image, from vmlinux.lds.S
+        _text = self.address_of('_text')
+        if _text is None:
+            _text = 0
+
+        _end = self.address_of('_end')
+        if _end is None:
+            _end = 0xFFFFFFFFFFFFFFFF
+
         for line in symbols:
             s = line.split(' ')
-            if len(s) == 3:
-                self.lookup_table.append((int(s[0], 16) + kaslr,
-                                         s[2].rstrip()))
+            if len(s) != 3:
+                continue
+
+            entry = (int(s[0], 16) + kaslr, s[2].rstrip())
+
+            # The symbol file contains many artificial symbols which we don't care about.
+            if entry[0] < _text or entry[0] >= _end:
+                continue
+
+            self.lookup_table.append(entry)
         stream.close()
 
+        if not len(self.lookup_table):
+            print_out_str('!!! Unable to retrieve symbols... Exiting')
+            sys.exit(1)
+
     def retrieve_modules(self):
         mod_list = self.address_of('modules')
         next_offset = self.field_offset('struct list_head', 'next')
@@ -1398,36 +1418,49 @@ class RamDump():
             pass
 
     def unwind_lookup(self, addr, symbol_size=0):
-        if (addr is None):
-            return ('(Invalid address)', 0x0)
+        """
+        Returns closest symbols <= addr and either the relative offset
+        or the symbol size.
+
+        The loop constant is:
+        table[low] <= addr <= table[high]
+        """
 
+        table = self.lookup_table
         low = 0
-        high = len(self.lookup_table)
-        # Python now complains about division producing floats
-        mid = (low + high) >> 1
-        premid = 0
+        high = len(self.lookup_table) - 1
 
-        while(not(addr >= self.lookup_table[mid][0] and addr < self.lookup_table[mid + 1][0])):
+        if addr is None or addr < table[low][0] or addr > table[high][0]:
+            return None
 
-            if(addr < self.lookup_table[mid][0]):
-                high = mid - 1
+        while(True):
+            # Python now complains about division producing floats
+            mid = (high + low) >> 1
 
-            if(addr > self.lookup_table[mid][0]):
-                low = mid + 1
+            if mid == low or mid == high:
+                break
 
-            mid = (high + low) >> 1
+            if addr <= table[mid][0]:
+                high = mid
+            elif addr >= table[mid][0]:
+                low = mid
 
-            if(mid == premid):
-                return None
-            if (mid + 1) >= len(self.lookup_table) or mid < 0:
-                return None
+        if addr == table[low][0]:
+            high = low
+        elif addr == table[high][0]:
+            low = high
 
-            premid = mid
+        offset = addr - table[low][0]
+        #how to calculate size for the last symbol?
+        if low == len(self.lookup_table) - 1:
+            size = 0
+        else:
+            size = table[low + 1][0] - table[low][0]
 
         if symbol_size == 0:
-            return (self.lookup_table[mid][1], addr - self.lookup_table[mid][0])
+            return (table[low][1], offset)
         else:
-            return (self.lookup_table[mid][1], self.lookup_table[mid + 1][0] - self.lookup_table[mid][0])
+            return (table[low][1], size)
 
     def read_physical(self, addr, length):
         if self.minidump: