We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
stdin dependent symbolic execution is broken by gcc 11.2
<!--
*Disclaimer:
The angr suite is maintained by a small team of volunteers.
While we cannot guarantee any timeliness for fixes and enhancements, we will do our best.
For more real-time help with angr, from us and the community, join our [Slack.](https://angr.io/invite/)*
-->
---

**Describe the bug.**

<!--
Please include a clear and concise description of what the bug is.
-->

When working with binaries compiled with gcc 11.2 symbolic execution always takes only one path as if the stdin which they should depend on wasn't symbolic at all.

**Environment Information.**
<!--
Many common issues are caused by problems with the local Python environment.
Before submitting, double-check that your versions of all modules in the angr suite (angr, cle, pyvex, ...) are up to date.
Please include the output of `python -m angr.misc.bug_report` here.
-->
Tested on arch linux and fedora, freshly installed angr environment from pip (angr 9.1.11752)


**To Reproduce.**

<!--
Please include *both a script to reproduce the crash, and attach the binary used, if possible*
-->
Compile this test code with gcc:
```c
#include <stdio.h>
int main() {
    int a;
    scanf("%d", &a);
    if(a == 0)
        printf("do this\n");
    else
        printf("do that\n");
    return 0;
}
```
The angr script:
```py
import angr, claripy

p = angr.Project('test')

entry = p.factory.entry_state()
simgr = p.factory.simgr(entry)

simgr.run()

import IPython
IPython.embed()
```
When complied with gcc 11.1:
```
In [1]: simgr
Out[1]: <SimulationManager with 2 deadended>
```
When compiled with gcc 11.2:
```
In [1]: simgr
Out[1]: <SimulationManager with all stashes empty (1 errored)>
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `angr/procedures/glibc/__libc_start_main.py`
Content:
```
1 
2 import logging
3 
4 import angr
5 
6 l = logging.getLogger(name=__name__)
7 
8 ######################################
9 # __libc_start_main
10 ######################################
11 class __libc_start_main(angr.SimProcedure):
12     #pylint:disable=arguments-differ,unused-argument,attribute-defined-outside-init
13 
14     ADDS_EXITS = True
15     NO_RET = True
16     local_vars = ('main', 'argc', 'argv', 'init', 'fini')
17 
18     def _initialize_b_loc_table(self):
19         """
20         Initialize ptable for ctype
21 
22         See __ctype_b_loc.c in libc implementation
23         """
24         malloc = angr.SIM_PROCEDURES['libc']['malloc']
25         table = self.inline_call(malloc, 768).ret_expr
26         table_ptr = self.inline_call(malloc, self.state.arch.bytes).ret_expr
27 
28         for pos, c in enumerate(self.state.libc.LOCALE_ARRAY):
29             # Each entry is 2 bytes
30             self.state.memory.store(table + (pos*2),
31                                     self.state.solver.BVV(c, 16),
32                                     inspect=False,
33                                     disable_actions=True,
34                                     )
35         # Offset for negative chars
36         # 256 because 2 bytes each, -128 * 2
37         table += 256
38         self.state.memory.store(table_ptr,
39                                 table,
40                                 size=self.state.arch.bytes,
41                                 endness=self.state.arch.memory_endness,
42                                 inspect=False,
43                                 disable_actions=True,
44                                 )
45 
46         self.state.libc.ctype_b_loc_table_ptr = table_ptr
47 
48     def _initialize_tolower_loc_table(self):
49         """
50         Initialize ptable for ctype
51 
52         See __ctype_tolower_loc.c in libc implementation
53         """
54         malloc = angr.SIM_PROCEDURES['libc']['malloc']
55         # 384 entries, 4 bytes each
56         table = self.inline_call(malloc, 384*4).ret_expr
57         table_ptr = self.inline_call(malloc, self.state.arch.bytes).ret_expr
58 
59         for pos, c in enumerate(self.state.libc.TOLOWER_LOC_ARRAY):
60             self.state.memory.store(table + (pos * 4),
61                                     self.state.solver.BVV(c, 32),
62                                     endness=self.state.arch.memory_endness,
63                                     inspect=False,
64                                     disable_actions=True,
65                                     )
66 
67         # Offset for negative chars: -128 index (4 bytes per index)
68         table += (128 * 4)
69         self.state.memory.store(table_ptr,
70                                 table,
71                                 size=self.state.arch.bytes,
72                                 endness=self.state.arch.memory_endness,
73                                 inspect=False,
74                                 disable_actions=True,
75                                 )
76 
77         self.state.libc.ctype_tolower_loc_table_ptr = table_ptr
78 
79     def _initialize_toupper_loc_table(self):
80         """
81         Initialize ptable for ctype
82 
83         See __ctype_toupper_loc.c in libc implementation
84         """
85         malloc = angr.SIM_PROCEDURES['libc']['malloc']
86         # 384 entries, 4 bytes each
87         table = self.inline_call(malloc, 384*4).ret_expr
88         table_ptr = self.inline_call(malloc, self.state.arch.bytes).ret_expr
89 
90         for pos, c in enumerate(self.state.libc.TOUPPER_LOC_ARRAY):
91             self.state.memory.store(table + (pos * 4),
92                                     self.state.solver.BVV(c, 32),
93                                     endness=self.state.arch.memory_endness,
94                                     inspect=False,
95                                     disable_actions=True,
96                                     )
97 
98         # Offset for negative chars: -128 index (4 bytes per index)
99         table += (128 * 4)
100         self.state.memory.store(table_ptr,
101                                 table,
102                                 size=self.state.arch.bytes,
103                                 endness=self.state.arch.memory_endness,
104                                 inspect=False,
105                                 disable_actions=True,
106                                 )
107 
108         self.state.libc.ctype_toupper_loc_table_ptr = table_ptr
109 
110     def _initialize_ctype_table(self):
111         self._initialize_b_loc_table()
112         self._initialize_tolower_loc_table()
113         self._initialize_toupper_loc_table()
114 
115     def _initialize_errno(self):
116         malloc = angr.SIM_PROCEDURES['libc']['malloc']
117         errno_loc = self.inline_call(malloc, self.state.arch.bytes).ret_expr
118 
119         self.state.libc.errno_location = errno_loc
120         self.state.memory.store(errno_loc, self.state.solver.BVV(0, self.state.arch.bits))
121 
122     @property
123     def envp(self):
124         return self.argv + (self.argc+1)*self.state.arch.bytes
125 
126     def run(self, main, argc, argv, init, fini):
127         # TODO: handle symbolic and static modes
128 
129         self._initialize_ctype_table()
130         self._initialize_errno()
131 
132         self.main, self.argc, self.argv, self.init, self.fini = self._extract_args(self.state, main, argc, argv, init,
133                                                                                    fini)
134 
135         # TODO: __cxa_atexit calls for various at-exit needs
136 
137         self.call(self.init, (self.argc[31:0], self.argv, self.envp), 'after_init',
138             prototype = 'int main(int argc, char **argv, char **envp)')
139 
140     def after_init(self, main, argc, argv, init, fini, exit_addr=0):
141         self.call(self.main, (self.argc[31:0], self.argv, self.envp), 'after_main',
142             prototype='int main(int argc, char **argv, char **envp)')
143 
144     def after_main(self, main, argc, argv, init, fini, exit_addr=0):
145         self.exit(0)
146 
147     def static_exits(self, blocks, cfg=None, **kwargs):
148         # Execute those blocks with a blank state, and then dump the arguments
149         blank_state = angr.SimState(project=self.project, mode="fastpath", cle_memory_backer=self.project.loader.memory,
150                                     add_options={angr.options.SYMBOL_FILL_UNCONSTRAINED_MEMORY,
151                                                  angr.options.SYMBOL_FILL_UNCONSTRAINED_REGISTERS})
152         # set up the stack pointer
153         blank_state.regs.sp = 0x7ffffff0
154 
155         # special handling for x86 PIE GCC binaries
156         #
157         # 08049C70 xor     ebp, ebp
158         # 08049C72 pop     esi
159         # 08049C73 mov     ecx, esp
160         # 08049C75 and     esp, 0FFFFFFF0h
161         # 08049C78 push    eax
162         # 08049C79 push    esp             ; stack_end
163         # 08049C7A push    edx             ; rtld_fini
164         # 08049C7B call    sub_8049CA3      // this is the get_pc function
165         #  // first block starts here
166         # 08049C80 add     ebx, (offset off_806B000 - $)
167         # 08049C86 lea     eax, (nullsub_2 - 806B000h)[ebx]
168         # 08049C8C push    eax             ; fini
169         # 08049C8D lea     eax, (sub_805F530 - 806B000h)[ebx]
170         # 08049C93 push    eax             ; init
171         # 08049C94 push    ecx             ; ubp_av
172         # 08049C95 push    esi             ; argc
173         # 08049C96 mov     eax, offset main
174         # 08049C9C push    eax             ; main
175         # 08049C9D call    ___libc_start_main
176         if cfg is not None and self.arch.name == "X86":
177             first_block = blocks[0]
178             first_node = cfg.model.get_any_node(first_block.addr)
179             if first_node is not None:
180                 caller_nodes = cfg.model.get_predecessors(first_node, excluding_fakeret=False)
181                 if len(caller_nodes) == 1:
182                     caller_node = caller_nodes[0]
183                     succ_and_jks = caller_node.successors_and_jumpkinds()
184                     if len(succ_and_jks) == 1 and succ_and_jks[0][1] == 'Ijk_Call':
185                         # get_pc
186                         getpc_func = cfg.functions.get_by_addr(succ_and_jks[0][0].addr)
187                         if getpc_func is not None and 'get_pc' in getpc_func.info:
188                             # GCC-generated x86-pie binary confirmed.
189                             # initialize the specified register with the block address
190                             get_pc_reg = getpc_func.info['get_pc']
191                             setattr(blank_state.regs, "_" + get_pc_reg, first_block.addr)
192 
193         # Execute each block
194         state = blank_state
195         for b in blocks:
196             irsb = self.project.factory.default_engine.process(state, irsb=b, force_addr=b.addr)
197             if irsb.successors:
198                 state = irsb.successors[0]
199             else:
200                 break
201 
202         cc = angr.DEFAULT_CC[self.arch.name](self.arch)
203         ty = angr.sim_type.parse_signature('void x(void*, void*, void*, void*, void*)').with_arch(self.arch)
204         args = cc.get_args(state, ty)
205         main, _, _, init, fini = self._extract_args(blank_state, *args)
206 
207         all_exits = [
208             {'address': init, 'jumpkind': 'Ijk_Call', 'namehint': 'init'},
209             {'address': main, 'jumpkind': 'Ijk_Call', 'namehint': 'main'},
210             {'address': fini, 'jumpkind': 'Ijk_Call', 'namehint': 'fini'},
211         ]
212 
213         return all_exits
214 
215     @staticmethod
216     def _extract_args(state, main, argc, argv, init, fini):
217         """
218         Extract arguments and set them to
219 
220         :param angr.sim_state.SimState state: The program state.
221         :param main: An argument to __libc_start_main.
222         :param argc: An argument to __libc_start_main.
223         :param argv: An argument to __libc_start_main.
224         :param init: An argument to __libc_start_main.
225         :param fini: An argument to __libc_start_main.
226         :return: A tuple of five elements: (main, argc, argv, init, fini)
227         :rtype: tuple
228         """
229 
230         main_ = main
231         argc_ = argc
232         argv_ = argv
233         init_ = init
234         fini_ = fini
235 
236         if state.arch.name == "PPC32":
237             # for some dumb reason, PPC passes arguments to libc_start_main in some completely absurd way
238             argv_ = argc_
239             argc_ = main_
240             main_ = state.mem[state.regs.r8 + 4:].int.resolved
241             init_ = state.mem[state.regs.r8 + 8:].int.resolved
242             fini_ = state.mem[state.regs.r8 + 12:].int.resolved
243 
244         elif state.arch.name == "PPC64":
245             main_ = state.mem[state.regs.r8 + 8:].long.resolved
246             init_ = state.mem[state.regs.r8 + 16:].long.resolved
247             fini_ = state.mem[state.regs.r8 + 24:].long.resolved
248 
249         return main_, argc_, argv_, init_, fini_
250
```
--- 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/angr/procedures/glibc/__libc_start_main.py b/angr/procedures/glibc/__libc_start_main.py
--- a/angr/procedures/glibc/__libc_start_main.py
+++ b/angr/procedures/glibc/__libc_start_main.py
@@ -134,8 +134,11 @@
 
         # TODO: __cxa_atexit calls for various at-exit needs
 
-        self.call(self.init, (self.argc[31:0], self.argv, self.envp), 'after_init',
-            prototype = 'int main(int argc, char **argv, char **envp)')
+        if not self.state.solver.is_true(self.init == 0):
+            self.call(self.init, (self.argc[31:0], self.argv, self.envp), 'after_init',
+                prototype = 'int main(int argc, char **argv, char **envp)')
+        else:
+            self.after_init(main, argc, argv, init, fini)
 
     def after_init(self, main, argc, argv, init, fini, exit_addr=0):
         self.call(self.main, (self.argc[31:0], self.argv, self.envp), 'after_main',

{"golden_diff": "diff --git a/angr/procedures/glibc/__libc_start_main.py b/angr/procedures/glibc/__libc_start_main.py\n--- a/angr/procedures/glibc/__libc_start_main.py\n+++ b/angr/procedures/glibc/__libc_start_main.py\n@@ -134,8 +134,11 @@\n \n         # TODO: __cxa_atexit calls for various at-exit needs\n \n-        self.call(self.init, (self.argc[31:0], self.argv, self.envp), 'after_init',\n-            prototype = 'int main(int argc, char **argv, char **envp)')\n+        if not self.state.solver.is_true(self.init == 0):\n+            self.call(self.init, (self.argc[31:0], self.argv, self.envp), 'after_init',\n+                prototype = 'int main(int argc, char **argv, char **envp)')\n+        else:\n+            self.after_init(main, argc, argv, init, fini)\n \n     def after_init(self, main, argc, argv, init, fini, exit_addr=0):\n         self.call(self.main, (self.argc[31:0], self.argv, self.envp), 'after_main',\n", "issue": "stdin dependent symbolic execution is broken by gcc 11.2\n<!--\r\n*Disclaimer:\r\nThe angr suite is maintained by a small team of volunteers.\r\nWhile we cannot guarantee any timeliness for fixes and enhancements, we will do our best.\r\nFor more real-time help with angr, from us and the community, join our [Slack.](https://angr.io/invite/)*\r\n-->\r\n---\r\n\r\n**Describe the bug.**\r\n\r\n<!--\r\nPlease include a clear and concise description of what the bug is.\r\n-->\r\n\r\nWhen working with binaries compiled with gcc 11.2 symbolic execution always takes only one path as if the stdin which they should depend on wasn't symbolic at all.\r\n\r\n**Environment Information.**\r\n<!--\r\nMany common issues are caused by problems with the local Python environment.\r\nBefore submitting, double-check that your versions of all modules in the angr suite (angr, cle, pyvex, ...) are up to date.\r\nPlease include the output of `python -m angr.misc.bug_report` here.\r\n-->\r\nTested on arch linux and fedora, freshly installed angr environment from pip (angr 9.1.11752)\r\n\r\n\r\n**To Reproduce.**\r\n\r\n<!--\r\nPlease include *both a script to reproduce the crash, and attach the binary used, if possible*\r\n-->\r\nCompile this test code with gcc:\r\n```c\r\n#include <stdio.h>\r\nint main() {\r\n    int a;\r\n    scanf(\"%d\", &a);\r\n    if(a == 0)\r\n        printf(\"do this\\n\");\r\n    else\r\n        printf(\"do that\\n\");\r\n    return 0;\r\n}\r\n```\r\nThe angr script:\r\n```py\r\nimport angr, claripy\r\n\r\np = angr.Project('test')\r\n\r\nentry = p.factory.entry_state()\r\nsimgr = p.factory.simgr(entry)\r\n\r\nsimgr.run()\r\n\r\nimport IPython\r\nIPython.embed()\r\n```\r\nWhen complied with gcc 11.1:\r\n```\r\nIn [1]: simgr\r\nOut[1]: <SimulationManager with 2 deadended>\r\n```\r\nWhen compiled with gcc 11.2:\r\n```\r\nIn [1]: simgr\r\nOut[1]: <SimulationManager with all stashes empty (1 errored)>\r\n```\r\n\n", "before_files": [{"content": "\nimport logging\n\nimport angr\n\nl = logging.getLogger(name=__name__)\n\n######################################\n# __libc_start_main\n######################################\nclass __libc_start_main(angr.SimProcedure):\n    #pylint:disable=arguments-differ,unused-argument,attribute-defined-outside-init\n\n    ADDS_EXITS = True\n    NO_RET = True\n    local_vars = ('main', 'argc', 'argv', 'init', 'fini')\n\n    def _initialize_b_loc_table(self):\n        \"\"\"\n        Initialize ptable for ctype\n\n        See __ctype_b_loc.c in libc implementation\n        \"\"\"\n        malloc = angr.SIM_PROCEDURES['libc']['malloc']\n        table = self.inline_call(malloc, 768).ret_expr\n        table_ptr = self.inline_call(malloc, self.state.arch.bytes).ret_expr\n\n        for pos, c in enumerate(self.state.libc.LOCALE_ARRAY):\n            # Each entry is 2 bytes\n            self.state.memory.store(table + (pos*2),\n                                    self.state.solver.BVV(c, 16),\n                                    inspect=False,\n                                    disable_actions=True,\n                                    )\n        # Offset for negative chars\n        # 256 because 2 bytes each, -128 * 2\n        table += 256\n        self.state.memory.store(table_ptr,\n                                table,\n                                size=self.state.arch.bytes,\n                                endness=self.state.arch.memory_endness,\n                                inspect=False,\n                                disable_actions=True,\n                                )\n\n        self.state.libc.ctype_b_loc_table_ptr = table_ptr\n\n    def _initialize_tolower_loc_table(self):\n        \"\"\"\n        Initialize ptable for ctype\n\n        See __ctype_tolower_loc.c in libc implementation\n        \"\"\"\n        malloc = angr.SIM_PROCEDURES['libc']['malloc']\n        # 384 entries, 4 bytes each\n        table = self.inline_call(malloc, 384*4).ret_expr\n        table_ptr = self.inline_call(malloc, self.state.arch.bytes).ret_expr\n\n        for pos, c in enumerate(self.state.libc.TOLOWER_LOC_ARRAY):\n            self.state.memory.store(table + (pos * 4),\n                                    self.state.solver.BVV(c, 32),\n                                    endness=self.state.arch.memory_endness,\n                                    inspect=False,\n                                    disable_actions=True,\n                                    )\n\n        # Offset for negative chars: -128 index (4 bytes per index)\n        table += (128 * 4)\n        self.state.memory.store(table_ptr,\n                                table,\n                                size=self.state.arch.bytes,\n                                endness=self.state.arch.memory_endness,\n                                inspect=False,\n                                disable_actions=True,\n                                )\n\n        self.state.libc.ctype_tolower_loc_table_ptr = table_ptr\n\n    def _initialize_toupper_loc_table(self):\n        \"\"\"\n        Initialize ptable for ctype\n\n        See __ctype_toupper_loc.c in libc implementation\n        \"\"\"\n        malloc = angr.SIM_PROCEDURES['libc']['malloc']\n        # 384 entries, 4 bytes each\n        table = self.inline_call(malloc, 384*4).ret_expr\n        table_ptr = self.inline_call(malloc, self.state.arch.bytes).ret_expr\n\n        for pos, c in enumerate(self.state.libc.TOUPPER_LOC_ARRAY):\n            self.state.memory.store(table + (pos * 4),\n                                    self.state.solver.BVV(c, 32),\n                                    endness=self.state.arch.memory_endness,\n                                    inspect=False,\n                                    disable_actions=True,\n                                    )\n\n        # Offset for negative chars: -128 index (4 bytes per index)\n        table += (128 * 4)\n        self.state.memory.store(table_ptr,\n                                table,\n                                size=self.state.arch.bytes,\n                                endness=self.state.arch.memory_endness,\n                                inspect=False,\n                                disable_actions=True,\n                                )\n\n        self.state.libc.ctype_toupper_loc_table_ptr = table_ptr\n\n    def _initialize_ctype_table(self):\n        self._initialize_b_loc_table()\n        self._initialize_tolower_loc_table()\n        self._initialize_toupper_loc_table()\n\n    def _initialize_errno(self):\n        malloc = angr.SIM_PROCEDURES['libc']['malloc']\n        errno_loc = self.inline_call(malloc, self.state.arch.bytes).ret_expr\n\n        self.state.libc.errno_location = errno_loc\n        self.state.memory.store(errno_loc, self.state.solver.BVV(0, self.state.arch.bits))\n\n    @property\n    def envp(self):\n        return self.argv + (self.argc+1)*self.state.arch.bytes\n\n    def run(self, main, argc, argv, init, fini):\n        # TODO: handle symbolic and static modes\n\n        self._initialize_ctype_table()\n        self._initialize_errno()\n\n        self.main, self.argc, self.argv, self.init, self.fini = self._extract_args(self.state, main, argc, argv, init,\n                                                                                   fini)\n\n        # TODO: __cxa_atexit calls for various at-exit needs\n\n        self.call(self.init, (self.argc[31:0], self.argv, self.envp), 'after_init',\n            prototype = 'int main(int argc, char **argv, char **envp)')\n\n    def after_init(self, main, argc, argv, init, fini, exit_addr=0):\n        self.call(self.main, (self.argc[31:0], self.argv, self.envp), 'after_main',\n            prototype='int main(int argc, char **argv, char **envp)')\n\n    def after_main(self, main, argc, argv, init, fini, exit_addr=0):\n        self.exit(0)\n\n    def static_exits(self, blocks, cfg=None, **kwargs):\n        # Execute those blocks with a blank state, and then dump the arguments\n        blank_state = angr.SimState(project=self.project, mode=\"fastpath\", cle_memory_backer=self.project.loader.memory,\n                                    add_options={angr.options.SYMBOL_FILL_UNCONSTRAINED_MEMORY,\n                                                 angr.options.SYMBOL_FILL_UNCONSTRAINED_REGISTERS})\n        # set up the stack pointer\n        blank_state.regs.sp = 0x7ffffff0\n\n        # special handling for x86 PIE GCC binaries\n        #\n        # 08049C70 xor     ebp, ebp\n        # 08049C72 pop     esi\n        # 08049C73 mov     ecx, esp\n        # 08049C75 and     esp, 0FFFFFFF0h\n        # 08049C78 push    eax\n        # 08049C79 push    esp             ; stack_end\n        # 08049C7A push    edx             ; rtld_fini\n        # 08049C7B call    sub_8049CA3      // this is the get_pc function\n        #  // first block starts here\n        # 08049C80 add     ebx, (offset off_806B000 - $)\n        # 08049C86 lea     eax, (nullsub_2 - 806B000h)[ebx]\n        # 08049C8C push    eax             ; fini\n        # 08049C8D lea     eax, (sub_805F530 - 806B000h)[ebx]\n        # 08049C93 push    eax             ; init\n        # 08049C94 push    ecx             ; ubp_av\n        # 08049C95 push    esi             ; argc\n        # 08049C96 mov     eax, offset main\n        # 08049C9C push    eax             ; main\n        # 08049C9D call    ___libc_start_main\n        if cfg is not None and self.arch.name == \"X86\":\n            first_block = blocks[0]\n            first_node = cfg.model.get_any_node(first_block.addr)\n            if first_node is not None:\n                caller_nodes = cfg.model.get_predecessors(first_node, excluding_fakeret=False)\n                if len(caller_nodes) == 1:\n                    caller_node = caller_nodes[0]\n                    succ_and_jks = caller_node.successors_and_jumpkinds()\n                    if len(succ_and_jks) == 1 and succ_and_jks[0][1] == 'Ijk_Call':\n                        # get_pc\n                        getpc_func = cfg.functions.get_by_addr(succ_and_jks[0][0].addr)\n                        if getpc_func is not None and 'get_pc' in getpc_func.info:\n                            # GCC-generated x86-pie binary confirmed.\n                            # initialize the specified register with the block address\n                            get_pc_reg = getpc_func.info['get_pc']\n                            setattr(blank_state.regs, \"_\" + get_pc_reg, first_block.addr)\n\n        # Execute each block\n        state = blank_state\n        for b in blocks:\n            irsb = self.project.factory.default_engine.process(state, irsb=b, force_addr=b.addr)\n            if irsb.successors:\n                state = irsb.successors[0]\n            else:\n                break\n\n        cc = angr.DEFAULT_CC[self.arch.name](self.arch)\n        ty = angr.sim_type.parse_signature('void x(void*, void*, void*, void*, void*)').with_arch(self.arch)\n        args = cc.get_args(state, ty)\n        main, _, _, init, fini = self._extract_args(blank_state, *args)\n\n        all_exits = [\n            {'address': init, 'jumpkind': 'Ijk_Call', 'namehint': 'init'},\n            {'address': main, 'jumpkind': 'Ijk_Call', 'namehint': 'main'},\n            {'address': fini, 'jumpkind': 'Ijk_Call', 'namehint': 'fini'},\n        ]\n\n        return all_exits\n\n    @staticmethod\n    def _extract_args(state, main, argc, argv, init, fini):\n        \"\"\"\n        Extract arguments and set them to\n\n        :param angr.sim_state.SimState state: The program state.\n        :param main: An argument to __libc_start_main.\n        :param argc: An argument to __libc_start_main.\n        :param argv: An argument to __libc_start_main.\n        :param init: An argument to __libc_start_main.\n        :param fini: An argument to __libc_start_main.\n        :return: A tuple of five elements: (main, argc, argv, init, fini)\n        :rtype: tuple\n        \"\"\"\n\n        main_ = main\n        argc_ = argc\n        argv_ = argv\n        init_ = init\n        fini_ = fini\n\n        if state.arch.name == \"PPC32\":\n            # for some dumb reason, PPC passes arguments to libc_start_main in some completely absurd way\n            argv_ = argc_\n            argc_ = main_\n            main_ = state.mem[state.regs.r8 + 4:].int.resolved\n            init_ = state.mem[state.regs.r8 + 8:].int.resolved\n            fini_ = state.mem[state.regs.r8 + 12:].int.resolved\n\n        elif state.arch.name == \"PPC64\":\n            main_ = state.mem[state.regs.r8 + 8:].long.resolved\n            init_ = state.mem[state.regs.r8 + 16:].long.resolved\n            fini_ = state.mem[state.regs.r8 + 24:].long.resolved\n\n        return main_, argc_, argv_, init_, fini_\n", "path": "angr/procedures/glibc/__libc_start_main.py"}], "after_files": [{"content": "\nimport logging\n\nimport angr\n\nl = logging.getLogger(name=__name__)\n\n######################################\n# __libc_start_main\n######################################\nclass __libc_start_main(angr.SimProcedure):\n    #pylint:disable=arguments-differ,unused-argument,attribute-defined-outside-init\n\n    ADDS_EXITS = True\n    NO_RET = True\n    local_vars = ('main', 'argc', 'argv', 'init', 'fini')\n\n    def _initialize_b_loc_table(self):\n        \"\"\"\n        Initialize ptable for ctype\n\n        See __ctype_b_loc.c in libc implementation\n        \"\"\"\n        malloc = angr.SIM_PROCEDURES['libc']['malloc']\n        table = self.inline_call(malloc, 768).ret_expr\n        table_ptr = self.inline_call(malloc, self.state.arch.bytes).ret_expr\n\n        for pos, c in enumerate(self.state.libc.LOCALE_ARRAY):\n            # Each entry is 2 bytes\n            self.state.memory.store(table + (pos*2),\n                                    self.state.solver.BVV(c, 16),\n                                    inspect=False,\n                                    disable_actions=True,\n                                    )\n        # Offset for negative chars\n        # 256 because 2 bytes each, -128 * 2\n        table += 256\n        self.state.memory.store(table_ptr,\n                                table,\n                                size=self.state.arch.bytes,\n                                endness=self.state.arch.memory_endness,\n                                inspect=False,\n                                disable_actions=True,\n                                )\n\n        self.state.libc.ctype_b_loc_table_ptr = table_ptr\n\n    def _initialize_tolower_loc_table(self):\n        \"\"\"\n        Initialize ptable for ctype\n\n        See __ctype_tolower_loc.c in libc implementation\n        \"\"\"\n        malloc = angr.SIM_PROCEDURES['libc']['malloc']\n        # 384 entries, 4 bytes each\n        table = self.inline_call(malloc, 384*4).ret_expr\n        table_ptr = self.inline_call(malloc, self.state.arch.bytes).ret_expr\n\n        for pos, c in enumerate(self.state.libc.TOLOWER_LOC_ARRAY):\n            self.state.memory.store(table + (pos * 4),\n                                    self.state.solver.BVV(c, 32),\n                                    endness=self.state.arch.memory_endness,\n                                    inspect=False,\n                                    disable_actions=True,\n                                    )\n\n        # Offset for negative chars: -128 index (4 bytes per index)\n        table += (128 * 4)\n        self.state.memory.store(table_ptr,\n                                table,\n                                size=self.state.arch.bytes,\n                                endness=self.state.arch.memory_endness,\n                                inspect=False,\n                                disable_actions=True,\n                                )\n\n        self.state.libc.ctype_tolower_loc_table_ptr = table_ptr\n\n    def _initialize_toupper_loc_table(self):\n        \"\"\"\n        Initialize ptable for ctype\n\n        See __ctype_toupper_loc.c in libc implementation\n        \"\"\"\n        malloc = angr.SIM_PROCEDURES['libc']['malloc']\n        # 384 entries, 4 bytes each\n        table = self.inline_call(malloc, 384*4).ret_expr\n        table_ptr = self.inline_call(malloc, self.state.arch.bytes).ret_expr\n\n        for pos, c in enumerate(self.state.libc.TOUPPER_LOC_ARRAY):\n            self.state.memory.store(table + (pos * 4),\n                                    self.state.solver.BVV(c, 32),\n                                    endness=self.state.arch.memory_endness,\n                                    inspect=False,\n                                    disable_actions=True,\n                                    )\n\n        # Offset for negative chars: -128 index (4 bytes per index)\n        table += (128 * 4)\n        self.state.memory.store(table_ptr,\n                                table,\n                                size=self.state.arch.bytes,\n                                endness=self.state.arch.memory_endness,\n                                inspect=False,\n                                disable_actions=True,\n                                )\n\n        self.state.libc.ctype_toupper_loc_table_ptr = table_ptr\n\n    def _initialize_ctype_table(self):\n        self._initialize_b_loc_table()\n        self._initialize_tolower_loc_table()\n        self._initialize_toupper_loc_table()\n\n    def _initialize_errno(self):\n        malloc = angr.SIM_PROCEDURES['libc']['malloc']\n        errno_loc = self.inline_call(malloc, self.state.arch.bytes).ret_expr\n\n        self.state.libc.errno_location = errno_loc\n        self.state.memory.store(errno_loc, self.state.solver.BVV(0, self.state.arch.bits))\n\n    @property\n    def envp(self):\n        return self.argv + (self.argc+1)*self.state.arch.bytes\n\n    def run(self, main, argc, argv, init, fini):\n        # TODO: handle symbolic and static modes\n\n        self._initialize_ctype_table()\n        self._initialize_errno()\n\n        self.main, self.argc, self.argv, self.init, self.fini = self._extract_args(self.state, main, argc, argv, init,\n                                                                                   fini)\n\n        # TODO: __cxa_atexit calls for various at-exit needs\n\n        if not self.state.solver.is_true(self.init == 0):\n            self.call(self.init, (self.argc[31:0], self.argv, self.envp), 'after_init',\n                prototype = 'int main(int argc, char **argv, char **envp)')\n        else:\n            self.after_init(main, argc, argv, init, fini)\n\n    def after_init(self, main, argc, argv, init, fini, exit_addr=0):\n        self.call(self.main, (self.argc[31:0], self.argv, self.envp), 'after_main',\n            prototype='int main(int argc, char **argv, char **envp)')\n\n    def after_main(self, main, argc, argv, init, fini, exit_addr=0):\n        self.exit(0)\n\n    def static_exits(self, blocks, cfg=None, **kwargs):\n        # Execute those blocks with a blank state, and then dump the arguments\n        blank_state = angr.SimState(project=self.project, mode=\"fastpath\", cle_memory_backer=self.project.loader.memory,\n                                    add_options={angr.options.SYMBOL_FILL_UNCONSTRAINED_MEMORY,\n                                                 angr.options.SYMBOL_FILL_UNCONSTRAINED_REGISTERS})\n        # set up the stack pointer\n        blank_state.regs.sp = 0x7ffffff0\n\n        # special handling for x86 PIE GCC binaries\n        #\n        # 08049C70 xor     ebp, ebp\n        # 08049C72 pop     esi\n        # 08049C73 mov     ecx, esp\n        # 08049C75 and     esp, 0FFFFFFF0h\n        # 08049C78 push    eax\n        # 08049C79 push    esp             ; stack_end\n        # 08049C7A push    edx             ; rtld_fini\n        # 08049C7B call    sub_8049CA3      // this is the get_pc function\n        #  // first block starts here\n        # 08049C80 add     ebx, (offset off_806B000 - $)\n        # 08049C86 lea     eax, (nullsub_2 - 806B000h)[ebx]\n        # 08049C8C push    eax             ; fini\n        # 08049C8D lea     eax, (sub_805F530 - 806B000h)[ebx]\n        # 08049C93 push    eax             ; init\n        # 08049C94 push    ecx             ; ubp_av\n        # 08049C95 push    esi             ; argc\n        # 08049C96 mov     eax, offset main\n        # 08049C9C push    eax             ; main\n        # 08049C9D call    ___libc_start_main\n        if cfg is not None and self.arch.name == \"X86\":\n            first_block = blocks[0]\n            first_node = cfg.model.get_any_node(first_block.addr)\n            if first_node is not None:\n                caller_nodes = cfg.model.get_predecessors(first_node, excluding_fakeret=False)\n                if len(caller_nodes) == 1:\n                    caller_node = caller_nodes[0]\n                    succ_and_jks = caller_node.successors_and_jumpkinds()\n                    if len(succ_and_jks) == 1 and succ_and_jks[0][1] == 'Ijk_Call':\n                        # get_pc\n                        getpc_func = cfg.functions.get_by_addr(succ_and_jks[0][0].addr)\n                        if getpc_func is not None and 'get_pc' in getpc_func.info:\n                            # GCC-generated x86-pie binary confirmed.\n                            # initialize the specified register with the block address\n                            get_pc_reg = getpc_func.info['get_pc']\n                            setattr(blank_state.regs, \"_\" + get_pc_reg, first_block.addr)\n\n        # Execute each block\n        state = blank_state\n        for b in blocks:\n            irsb = self.project.factory.default_engine.process(state, irsb=b, force_addr=b.addr)\n            if irsb.successors:\n                state = irsb.successors[0]\n            else:\n                break\n\n        cc = angr.DEFAULT_CC[self.arch.name](self.arch)\n        ty = angr.sim_type.parse_signature('void x(void*, void*, void*, void*, void*)').with_arch(self.arch)\n        args = cc.get_args(state, ty)\n        main, _, _, init, fini = self._extract_args(blank_state, *args)\n\n        all_exits = [\n            {'address': init, 'jumpkind': 'Ijk_Call', 'namehint': 'init'},\n            {'address': main, 'jumpkind': 'Ijk_Call', 'namehint': 'main'},\n            {'address': fini, 'jumpkind': 'Ijk_Call', 'namehint': 'fini'},\n        ]\n\n        return all_exits\n\n    @staticmethod\n    def _extract_args(state, main, argc, argv, init, fini):\n        \"\"\"\n        Extract arguments and set them to\n\n        :param angr.sim_state.SimState state: The program state.\n        :param main: An argument to __libc_start_main.\n        :param argc: An argument to __libc_start_main.\n        :param argv: An argument to __libc_start_main.\n        :param init: An argument to __libc_start_main.\n        :param fini: An argument to __libc_start_main.\n        :return: A tuple of five elements: (main, argc, argv, init, fini)\n        :rtype: tuple\n        \"\"\"\n\n        main_ = main\n        argc_ = argc\n        argv_ = argv\n        init_ = init\n        fini_ = fini\n\n        if state.arch.name == \"PPC32\":\n            # for some dumb reason, PPC passes arguments to libc_start_main in some completely absurd way\n            argv_ = argc_\n            argc_ = main_\n            main_ = state.mem[state.regs.r8 + 4:].int.resolved\n            init_ = state.mem[state.regs.r8 + 8:].int.resolved\n            fini_ = state.mem[state.regs.r8 + 12:].int.resolved\n\n        elif state.arch.name == \"PPC64\":\n            main_ = state.mem[state.regs.r8 + 8:].long.resolved\n            init_ = state.mem[state.regs.r8 + 16:].long.resolved\n            fini_ = state.mem[state.regs.r8 + 24:].long.resolved\n\n        return main_, argc_, argv_, init_, fini_\n", "path": "angr/procedures/glibc/__libc_start_main.py"}]}