1 import gdbremote_testcase
2 from lldbsuite
.test
.decorators
import *
3 from lldbsuite
.test
.lldbtest
import *
4 from lldbsuite
.test
import lldbutil
7 class TestGdbRemoteAuxvSupport(gdbremote_testcase
.GdbRemoteTestCaseBase
):
8 AUXV_SUPPORT_FEATURE_NAME
= "qXfer:auxv:read"
10 def has_auxv_support(self
):
11 procs
= self
.prep_debug_monitor_and_inferior()
13 self
.add_qSupported_packets()
14 context
= self
.expect_gdbremote_sequence()
15 self
.assertIsNotNone(context
)
17 features
= self
.parse_qSupported_response(context
)
19 self
.AUXV_SUPPORT_FEATURE_NAME
in features
20 and features
[self
.AUXV_SUPPORT_FEATURE_NAME
] == "+"
23 def get_raw_auxv_data(self
):
24 # Start up llgs and inferior, and check for auxv support.
25 if not self
.has_auxv_support():
26 self
.skipTest("auxv data not supported")
28 # Grab pointer size for target. We'll assume that is equivalent to an unsigned long on the target.
29 # Auxv is specified in terms of pairs of unsigned longs.
30 self
.reset_test_sequence()
31 self
.add_process_info_collection_packets()
33 context
= self
.expect_gdbremote_sequence()
34 self
.assertIsNotNone(context
)
36 proc_info
= self
.parse_process_info_response(context
)
37 self
.assertIsNotNone(proc_info
)
38 self
.assertIn("ptrsize", proc_info
)
39 word_size
= int(proc_info
["ptrsize"])
45 self
.reset_test_sequence()
46 self
.test_sequence
.add_log_lines(
48 "read packet: $qXfer:auxv:read::{:x},{:x}:#00".format(OFFSET
, LENGTH
),
52 r
"^\$([^E])(.*)#[0-9a-fA-F]{2}$", re
.MULTILINE | re
.DOTALL
54 "capture": {1: "response_type", 2: "content_raw"},
60 context
= self
.expect_gdbremote_sequence()
61 self
.assertIsNotNone(context
)
63 # Ensure we end up with all auxv data in one packet.
64 # FIXME don't assume it all comes back in one packet.
65 self
.assertEqual(context
.get("response_type"), "l")
68 content_raw
= context
.get("content_raw")
69 self
.assertIsNotNone(content_raw
)
70 return (word_size
, self
.decode_gdbremote_binary(content_raw
))
72 @skipIfWindows # no auxv support.
74 def test_supports_auxv(self
):
76 self
.set_inferior_startup_launch()
77 self
.assertTrue(self
.has_auxv_support())
80 @expectedFailureNetBSD
81 def test_auxv_data_is_correct_size(self
):
83 self
.set_inferior_startup_launch()
85 (word_size
, auxv_data
) = self
.get_raw_auxv_data()
86 self
.assertIsNotNone(auxv_data
)
88 # Ensure auxv data is a multiple of 2*word_size (there should be two
89 # unsigned long fields per auxv entry).
90 self
.assertEqual(len(auxv_data
) % (2 * word_size
), 0)
91 self
.trace("auxv contains {} entries".format(len(auxv_data
) / (2 * word_size
)))
94 @expectedFailureNetBSD
95 def test_auxv_keys_look_valid(self
):
97 self
.set_inferior_startup_launch()
99 (word_size
, auxv_data
) = self
.get_raw_auxv_data()
100 self
.assertIsNotNone(auxv_data
)
103 self
.reset_test_sequence()
104 self
.add_process_info_collection_packets()
105 context
= self
.expect_gdbremote_sequence()
106 self
.assertIsNotNone(context
)
108 process_info
= self
.parse_process_info_response(context
)
109 self
.assertIsNotNone(process_info
)
110 endian
= process_info
.get("endian")
111 self
.assertIsNotNone(endian
)
113 auxv_dict
= self
.build_auxv_dict(endian
, word_size
, auxv_data
)
114 self
.assertIsNotNone(auxv_dict
)
116 # Verify keys look reasonable. While AUX values are most commonly
117 # small (usually smaller than 50), they can sometimes be larger.
118 self
.trace("auxv dict: {}".format(auxv_dict
))
119 for auxv_key
in auxv_dict
:
120 self
.assertTrue(auxv_key
>= 1)
121 self
.assertTrue(auxv_key
<= 2500)
124 @expectedFailureNetBSD
125 def test_auxv_chunked_reads_work(self
):
127 self
.set_inferior_startup_launch()
129 # Verify that multiple smaller offset,length reads of auxv data
130 # return the same data as a single larger read.
132 # Grab the auxv data with a single large read here.
133 (word_size
, auxv_data
) = self
.get_raw_auxv_data()
134 self
.assertIsNotNone(auxv_data
)
137 self
.reset_test_sequence()
138 self
.add_process_info_collection_packets()
139 context
= self
.expect_gdbremote_sequence()
140 self
.assertIsNotNone(context
)
142 process_info
= self
.parse_process_info_response(context
)
143 self
.assertIsNotNone(process_info
)
144 endian
= process_info
.get("endian")
145 self
.assertIsNotNone(endian
)
147 auxv_dict
= self
.build_auxv_dict(endian
, word_size
, auxv_data
)
148 self
.assertIsNotNone(auxv_dict
)
150 iterated_auxv_data
= self
.read_binary_data_in_chunks(
151 "qXfer:auxv:read::", 2 * word_size
153 self
.assertIsNotNone(iterated_auxv_data
)
155 auxv_dict_iterated
= self
.build_auxv_dict(endian
, word_size
, iterated_auxv_data
)
156 self
.assertIsNotNone(auxv_dict_iterated
)
158 # Verify both types of data collection returned same content.
159 self
.assertEqual(auxv_dict_iterated
, auxv_dict
)