From: Waldemar Kozaczuk <jwkozac...@gmail.com>
Committer: Waldemar Kozaczuk <jwkozac...@gmail.com>
Branch: master

loader.py: enhance to support debugging programs launched with Linux dynamic 
linker

Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com>

---
diff --git a/scripts/loader.py b/scripts/loader.py
--- a/scripts/loader.py
+++ b/scripts/loader.py
@@ -21,6 +21,8 @@
                        format_time)
 from osv import trace, debug
 
+from manifest_common import add_var, expand, unsymlink, read_manifest, defines
+
 virtio_driver_type = gdb.lookup_type('virtio::virtio_driver')
 
 class status_enum_class(object):
@@ -131,33 +133,40 @@ def __init__(self):
         # Load data from usr.manifest in build_dir
         mm_path = os.path.join(build_dir, 'usr.manifest')
         try:
-            self.data = open(mm_path).read().split('\n')
+            _manifest = read_manifest(mm_path)
+            self.guest_to_host_map = list(expand(_manifest))
+            self.guest_to_host_map = [(x, unsymlink(y % defines)) for (x, y) 
in self.guest_to_host_map]
         except IOError:
-            self.data = []
+            self.guest_to_host_map = []
 
     def find(self, path):
         '''Try to locate file with help of usr.manifest'''
-        files = [ff.split(':', 1)[1].strip() for ff in self.data if 
ff.split(':', 1)[0].strip() == path]
+        files = [host for (guest, host) in self.guest_to_host_map if guest == 
path]
         if files:
-            file = files[-1]  # the last line in usr.manifest wins
+            host_file = files[-1]  # the last line in usr.manifest wins
         else:
-            file = ""
-        file = self.resolve_symlink(file)
-        print('manifest.find_file: path=%s, found file=%s' % (path, file))
+            host_file = ""
+        host_file = self.resolve_host_file(host_file)
+        print('manifest.find_file: path=%s, found file=%s' % (path, host_file))
         # usr.manifest contains lines like "%(gccbase)s/lib64/libgcc_s.so.1" 
too.
         # Filter out such cases.
-        if os.path.exists(file):
-            return file
+        if os.path.exists(host_file):
+            return host_file
         else:
             return ""
 
-    def resolve_symlink(self, file):
-        '''If file is a symlink, try to resolve it with help of usr.manifest'''
+    def resolve_host_file(self, file):
         resolved_file = file
+        #Handle symlink
         if file.startswith('->'):
-            path = file[2:]
-            resolved_file = self.find(path)
-            # print('manifest.resolve_symlink: file=%s, resolved_file=%s' % 
(file, resolved_file))
+            resolved_file = self.find(file[2:].strip())
+        else:
+            resolved_file = file
+        #Handle path to build directory
+        if resolved_file.startswith('.'):
+            resolved_file = os.path.join(build_dir, resolved_file[2:])
+        if not resolved_file.startswith('/'):
+            resolved_file = os.path.join(build_dir, resolved_file)
         return resolved_file
 
 manifest = Manifest()
@@ -689,6 +698,7 @@ def __init__(self):
                              gdb.COMMAND_USER, gdb.COMPLETE_NONE)
     def invoke(self, arg, from_tty):
         syminfo_resolver.clear_cache()
+        object_paths = set()
         for obj in 
read_vector(gdb.lookup_global_symbol('elf::program::s_objs').value()):
             base = to_int(obj['_base'])
             obj_path = obj['_pathname']['_M_dataplus']['_M_p'].string()
@@ -697,8 +707,30 @@ def invoke(self, arg, from_tty):
                 print('ERROR: Unable to locate object file for:', obj_path, 
hex(base))
             else:
                 print(path, hex(base))
+                object_paths.add(path)
                 load_elf(path, base)
 
+        for vma in vma_list():
+            start = ulong(vma['_range']['_start'])
+            flags = flagstr(ulong(vma['_flags']))
+            perm = permstr(ulong(vma['_perm']))
+
+            if 'F' in flags:
+                file_vma = vma.cast(gdb.lookup_type('mmu::file_vma').pointer())
+                file_ptr = 
file_vma['_file']['px'].cast(gdb.lookup_type('file').pointer())
+                dentry_ptr = 
file_ptr['f_dentry']['px'].cast(gdb.lookup_type('dentry').pointer())
+                file_path = dentry_ptr['d_path'].string()
+                path = translate(file_path)
+                if not path:
+                    print('ERROR: Unable to locate object file for:', 
file_path, hex(start))
+                elif path not in object_paths:
+                    print(path, hex(start))
+                    try:
+                        load_elf(path, start)
+                        object_paths.add(path)
+                    except gdb.error:
+                        print('ERROR: Not an ELF file', path, hex(start))
+
 class osv_load_elf(gdb.Command):
     def __init__(self):
         gdb.Command.__init__(self, 'osv load-elf',

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/000000000000cc8bd6060c9082bf%40google.com.

Reply via email to