We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
qemu local_path bug
### Description

It seems like some commands e.g. plt, got tries to use ELF file's content as path.

### Steps to reproduce

```
$ qemu-arm -g 23946 ./target
$ gdb-multiarch ./target
(gdb) target remote :23946
(gdb) plt # or
(gdb) got
```

### My setup

Ubuntu 18.04, branch c6473ba (master)

### Analysis (and temporary patch)

plt/got command uses `get_elf_info` at [elf.py](https://github.com/pwndbg/pwndbg/blob/dev/pwndbg/elf.py#L95), which uses get_file at file.py.

It seems like the path itself should be used in [file.py L36](https://github.com/pwndbg/pwndbg/blob/c6473ba7aea797f7b4d2251febf419382564d3f8/pwndbg/file.py#L36):

https://github.com/pwndbg/pwndbg/blob/203f10710e8a9a195a7bade59661ed7f3e3e641c/pwndbg/file.py#L35-L36

to
```py
    if pwndbg.qemu.root() and recurse:
        return os.path.join(pwndbg.qemu.binfmt_root, path)
```

I'm not sure if it's ok in all cases, since I think relative path should be also searched, but it works on plt/got case since absolute path is used (e.g. if path is 'a/b', I'm not sure if binfmt_root + '/a/b' and 'a/b' shoud be searched.)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pwndbg/file.py`
Content:
```
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3 """
4 Retrieve files from the debuggee's filesystem.  Useful when
5 debugging a remote process over SSH or similar, where e.g.
6 /proc/FOO/maps is needed from the remote system.
7 """
8 from __future__ import absolute_import
9 from __future__ import division
10 from __future__ import print_function
11 from __future__ import unicode_literals
12 
13 import binascii
14 import errno as _errno
15 import os
16 import subprocess
17 import tempfile
18 
19 import gdb
20 
21 import pwndbg.qemu
22 import pwndbg.remote
23 
24 
25 def get_file(path, recurse=1):
26     """
27     Downloads the specified file from the system where the current process is
28     being debugged.
29 
30     Returns:
31         The local path to the file
32     """
33     local_path = path
34 
35     if pwndbg.qemu.root() and recurse:
36         return get(os.path.join(pwndbg.qemu.binfmt_root, path), 0)
37     elif pwndbg.remote.is_remote() and not pwndbg.qemu.is_qemu():
38         local_path = tempfile.mktemp()
39         error      = None
40         try:
41             error = gdb.execute('remote get "%s" "%s"' % (path, local_path),
42                                  to_string=True)
43         except gdb.error as e:
44             error = e
45 
46         if error:
47             raise OSError("Could not download remote file %r:\n" \
48                             "Error: %s" % (path, error))
49 
50     return local_path
51 
52 def get(path, recurse=1):
53     """
54     Retrieves the contents of the specified file on the system
55     where the current process is being debugged.
56 
57     Returns:
58         A byte array, or None.
59     """
60     local_path = get_file(path, recurse)
61 
62     try:
63         with open(local_path,'rb') as f:
64             return f.read()
65     except:
66         return b''
67 
68 def readlink(path):
69     """readlink(path) -> str
70 
71     Read the link specified by 'path' on the system being debugged.
72 
73     Handles local, qemu-usermode, and remote debugging cases.
74     """
75     is_qemu = pwndbg.qemu.is_qemu_usermode()
76 
77     if is_qemu:
78         if not os.path.exists(path):
79             path = os.path.join(pwndbg.qemu.root(), path)
80 
81     if is_qemu or not pwndbg.remote.is_remote():
82         try:
83             return os.readlink(path)
84         except Exception:
85             return ''
86 
87     #
88     # Hurray unexposed packets!
89     #
90     # The 'vFile:readlink:' packet does exactly what it sounds like,
91     # but there is no API exposed to do this and there is also no
92     # command exposed... so we have to send the packet manually.
93     #
94     cmd = 'maintenance packet vFile:readlink:%s'
95 
96     # The path must be uppercase hex-encoded and NULL-terminated.
97     path += '\x00'
98     path = binascii.hexlify(path.encode())
99     path = path.upper()
100     path = path.decode()
101 
102     result = gdb.execute(cmd % path, from_tty=False, to_string=True)
103 
104     """
105     sending: "vFile:readlink:2F70726F632F3130303839302F66642F3000"
106     received: "Fc;pipe:[98420]"
107 
108     sending: "vFile:readlink:2F70726F632F3130303839302F66642F333300"
109     received: "F-1,2"
110     """
111 
112     _, data = result.split('\n', 1)
113 
114     # Sanity check
115     expected = 'received: "F'
116     if not data.startswith(expected):
117         return ''
118 
119     # Negative values are errors
120     data = data[len(expected):]
121     if data[0] == '-':
122         return ''
123 
124     # If non-negative, there will be a hex-encoded length followed
125     # by a semicolon.
126     n, data = data.split(';', 1)
127 
128     n = int(n, 16)
129     if n < 0:
130         return ''
131 
132     # The result is quoted by GDB, strip the quote and newline.
133     # I have no idea how well it handles other crazy stuff.
134     ending = '"\n'
135     data = data[:-len(ending)]
136 
137     return data
138
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pwndbg/file.py b/pwndbg/file.py
--- a/pwndbg/file.py
+++ b/pwndbg/file.py
@@ -33,7 +33,7 @@
     local_path = path
 
     if pwndbg.qemu.root() and recurse:
-        return get(os.path.join(pwndbg.qemu.binfmt_root, path), 0)
+        return os.path.join(pwndbg.qemu.binfmt_root, path)
     elif pwndbg.remote.is_remote() and not pwndbg.qemu.is_qemu():
         local_path = tempfile.mktemp()
         error      = None

{"golden_diff": "diff --git a/pwndbg/file.py b/pwndbg/file.py\n--- a/pwndbg/file.py\n+++ b/pwndbg/file.py\n@@ -33,7 +33,7 @@\n     local_path = path\n \n     if pwndbg.qemu.root() and recurse:\n-        return get(os.path.join(pwndbg.qemu.binfmt_root, path), 0)\n+        return os.path.join(pwndbg.qemu.binfmt_root, path)\n     elif pwndbg.remote.is_remote() and not pwndbg.qemu.is_qemu():\n         local_path = tempfile.mktemp()\n         error      = None\n", "issue": "qemu local_path bug\n### Description\r\n\r\nIt seems like some commands e.g. plt, got tries to use ELF file's content as path.\r\n\r\n### Steps to reproduce\r\n\r\n```\r\n$ qemu-arm -g 23946 ./target\r\n$ gdb-multiarch ./target\r\n(gdb) target remote :23946\r\n(gdb) plt # or\r\n(gdb) got\r\n```\r\n\r\n### My setup\r\n\r\nUbuntu 18.04, branch c6473ba (master)\r\n\r\n### Analysis (and temporary patch)\r\n\r\nplt/got command uses `get_elf_info` at [elf.py](https://github.com/pwndbg/pwndbg/blob/dev/pwndbg/elf.py#L95), which uses get_file at file.py.\r\n\r\nIt seems like the path itself should be used in [file.py L36](https://github.com/pwndbg/pwndbg/blob/c6473ba7aea797f7b4d2251febf419382564d3f8/pwndbg/file.py#L36):\r\n\r\nhttps://github.com/pwndbg/pwndbg/blob/203f10710e8a9a195a7bade59661ed7f3e3e641c/pwndbg/file.py#L35-L36\r\n\r\nto\r\n```py\r\n    if pwndbg.qemu.root() and recurse:\r\n        return os.path.join(pwndbg.qemu.binfmt_root, path)\r\n```\r\n\r\nI'm not sure if it's ok in all cases, since I think relative path should be also searched, but it works on plt/got case since absolute path is used (e.g. if path is 'a/b', I'm not sure if binfmt_root + '/a/b' and 'a/b' shoud be searched.)\n", "before_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\"\"\"\nRetrieve files from the debuggee's filesystem.  Useful when\ndebugging a remote process over SSH or similar, where e.g.\n/proc/FOO/maps is needed from the remote system.\n\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\n\nimport binascii\nimport errno as _errno\nimport os\nimport subprocess\nimport tempfile\n\nimport gdb\n\nimport pwndbg.qemu\nimport pwndbg.remote\n\n\ndef get_file(path, recurse=1):\n    \"\"\"\n    Downloads the specified file from the system where the current process is\n    being debugged.\n\n    Returns:\n        The local path to the file\n    \"\"\"\n    local_path = path\n\n    if pwndbg.qemu.root() and recurse:\n        return get(os.path.join(pwndbg.qemu.binfmt_root, path), 0)\n    elif pwndbg.remote.is_remote() and not pwndbg.qemu.is_qemu():\n        local_path = tempfile.mktemp()\n        error      = None\n        try:\n            error = gdb.execute('remote get \"%s\" \"%s\"' % (path, local_path),\n                                 to_string=True)\n        except gdb.error as e:\n            error = e\n\n        if error:\n            raise OSError(\"Could not download remote file %r:\\n\" \\\n                            \"Error: %s\" % (path, error))\n\n    return local_path\n\ndef get(path, recurse=1):\n    \"\"\"\n    Retrieves the contents of the specified file on the system\n    where the current process is being debugged.\n\n    Returns:\n        A byte array, or None.\n    \"\"\"\n    local_path = get_file(path, recurse)\n\n    try:\n        with open(local_path,'rb') as f:\n            return f.read()\n    except:\n        return b''\n\ndef readlink(path):\n    \"\"\"readlink(path) -> str\n\n    Read the link specified by 'path' on the system being debugged.\n\n    Handles local, qemu-usermode, and remote debugging cases.\n    \"\"\"\n    is_qemu = pwndbg.qemu.is_qemu_usermode()\n\n    if is_qemu:\n        if not os.path.exists(path):\n            path = os.path.join(pwndbg.qemu.root(), path)\n\n    if is_qemu or not pwndbg.remote.is_remote():\n        try:\n            return os.readlink(path)\n        except Exception:\n            return ''\n\n    #\n    # Hurray unexposed packets!\n    #\n    # The 'vFile:readlink:' packet does exactly what it sounds like,\n    # but there is no API exposed to do this and there is also no\n    # command exposed... so we have to send the packet manually.\n    #\n    cmd = 'maintenance packet vFile:readlink:%s'\n\n    # The path must be uppercase hex-encoded and NULL-terminated.\n    path += '\\x00'\n    path = binascii.hexlify(path.encode())\n    path = path.upper()\n    path = path.decode()\n\n    result = gdb.execute(cmd % path, from_tty=False, to_string=True)\n\n    \"\"\"\n    sending: \"vFile:readlink:2F70726F632F3130303839302F66642F3000\"\n    received: \"Fc;pipe:[98420]\"\n\n    sending: \"vFile:readlink:2F70726F632F3130303839302F66642F333300\"\n    received: \"F-1,2\"\n    \"\"\"\n\n    _, data = result.split('\\n', 1)\n\n    # Sanity check\n    expected = 'received: \"F'\n    if not data.startswith(expected):\n        return ''\n\n    # Negative values are errors\n    data = data[len(expected):]\n    if data[0] == '-':\n        return ''\n\n    # If non-negative, there will be a hex-encoded length followed\n    # by a semicolon.\n    n, data = data.split(';', 1)\n\n    n = int(n, 16)\n    if n < 0:\n        return ''\n\n    # The result is quoted by GDB, strip the quote and newline.\n    # I have no idea how well it handles other crazy stuff.\n    ending = '\"\\n'\n    data = data[:-len(ending)]\n\n    return data\n", "path": "pwndbg/file.py"}], "after_files": [{"content": "#!/usr/bin/env python\n# -*- coding: utf-8 -*-\n\"\"\"\nRetrieve files from the debuggee's filesystem.  Useful when\ndebugging a remote process over SSH or similar, where e.g.\n/proc/FOO/maps is needed from the remote system.\n\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\nfrom __future__ import unicode_literals\n\nimport binascii\nimport errno as _errno\nimport os\nimport subprocess\nimport tempfile\n\nimport gdb\n\nimport pwndbg.qemu\nimport pwndbg.remote\n\n\ndef get_file(path, recurse=1):\n    \"\"\"\n    Downloads the specified file from the system where the current process is\n    being debugged.\n\n    Returns:\n        The local path to the file\n    \"\"\"\n    local_path = path\n\n    if pwndbg.qemu.root() and recurse:\n        return os.path.join(pwndbg.qemu.binfmt_root, path)\n    elif pwndbg.remote.is_remote() and not pwndbg.qemu.is_qemu():\n        local_path = tempfile.mktemp()\n        error      = None\n        try:\n            error = gdb.execute('remote get \"%s\" \"%s\"' % (path, local_path),\n                                 to_string=True)\n        except gdb.error as e:\n            error = e\n\n        if error:\n            raise OSError(\"Could not download remote file %r:\\n\" \\\n                            \"Error: %s\" % (path, error))\n\n    return local_path\n\ndef get(path, recurse=1):\n    \"\"\"\n    Retrieves the contents of the specified file on the system\n    where the current process is being debugged.\n\n    Returns:\n        A byte array, or None.\n    \"\"\"\n    local_path = get_file(path, recurse)\n\n    try:\n        with open(local_path,'rb') as f:\n            return f.read()\n    except:\n        return b''\n\ndef readlink(path):\n    \"\"\"readlink(path) -> str\n\n    Read the link specified by 'path' on the system being debugged.\n\n    Handles local, qemu-usermode, and remote debugging cases.\n    \"\"\"\n    is_qemu = pwndbg.qemu.is_qemu_usermode()\n\n    if is_qemu:\n        if not os.path.exists(path):\n            path = os.path.join(pwndbg.qemu.root(), path)\n\n    if is_qemu or not pwndbg.remote.is_remote():\n        try:\n            return os.readlink(path)\n        except Exception:\n            return ''\n\n    #\n    # Hurray unexposed packets!\n    #\n    # The 'vFile:readlink:' packet does exactly what it sounds like,\n    # but there is no API exposed to do this and there is also no\n    # command exposed... so we have to send the packet manually.\n    #\n    cmd = 'maintenance packet vFile:readlink:%s'\n\n    # The path must be uppercase hex-encoded and NULL-terminated.\n    path += '\\x00'\n    path = binascii.hexlify(path.encode())\n    path = path.upper()\n    path = path.decode()\n\n    result = gdb.execute(cmd % path, from_tty=False, to_string=True)\n\n    \"\"\"\n    sending: \"vFile:readlink:2F70726F632F3130303839302F66642F3000\"\n    received: \"Fc;pipe:[98420]\"\n\n    sending: \"vFile:readlink:2F70726F632F3130303839302F66642F333300\"\n    received: \"F-1,2\"\n    \"\"\"\n\n    _, data = result.split('\\n', 1)\n\n    # Sanity check\n    expected = 'received: \"F'\n    if not data.startswith(expected):\n        return ''\n\n    # Negative values are errors\n    data = data[len(expected):]\n    if data[0] == '-':\n        return ''\n\n    # If non-negative, there will be a hex-encoded length followed\n    # by a semicolon.\n    n, data = data.split(';', 1)\n\n    n = int(n, 16)\n    if n < 0:\n        return ''\n\n    # The result is quoted by GDB, strip the quote and newline.\n    # I have no idea how well it handles other crazy stuff.\n    ending = '\"\\n'\n    data = data[:-len(ending)]\n\n    return data\n", "path": "pwndbg/file.py"}]}