brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.6 KiB · 25ad600 Raw
160 lines · python
1import gdbremote_testcase2from lldbsuite.test.decorators import *3from lldbsuite.test.lldbtest import *4from lldbsuite.test import lldbutil5 6 7class TestGdbRemoteAuxvSupport(gdbremote_testcase.GdbRemoteTestCaseBase):8    AUXV_SUPPORT_FEATURE_NAME = "qXfer:auxv:read"9 10    def has_auxv_support(self):11        procs = self.prep_debug_monitor_and_inferior()12 13        self.add_qSupported_packets()14        context = self.expect_gdbremote_sequence()15        self.assertIsNotNone(context)16 17        features = self.parse_qSupported_response(context)18        return (19            self.AUXV_SUPPORT_FEATURE_NAME in features20            and features[self.AUXV_SUPPORT_FEATURE_NAME] == "+"21        )22 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")27 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()32 33        context = self.expect_gdbremote_sequence()34        self.assertIsNotNone(context)35 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"])40 41        OFFSET = 042        LENGTH = 0x40043 44        # Grab the auxv data.45        self.reset_test_sequence()46        self.test_sequence.add_log_lines(47            [48                "read packet: $qXfer:auxv:read::{:x},{:x}:#00".format(OFFSET, LENGTH),49                {50                    "direction": "send",51                    "regex": re.compile(52                        r"^\$([^E])(.*)#[0-9a-fA-F]{2}$", re.MULTILINE | re.DOTALL53                    ),54                    "capture": {1: "response_type", 2: "content_raw"},55                },56            ],57            True,58        )59 60        context = self.expect_gdbremote_sequence()61        self.assertIsNotNone(context)62 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")66 67        # Decode binary data.68        content_raw = context.get("content_raw")69        self.assertIsNotNone(content_raw)70        return (word_size, self.decode_gdbremote_binary(content_raw))71 72    @skipIfWindows  # no auxv support.73    @skipIfDarwin74    def test_supports_auxv(self):75        self.build()76        self.set_inferior_startup_launch()77        self.assertTrue(self.has_auxv_support())78 79    @skipIfWindows80    @expectedFailureNetBSD81    def test_auxv_data_is_correct_size(self):82        self.build()83        self.set_inferior_startup_launch()84 85        (word_size, auxv_data) = self.get_raw_auxv_data()86        self.assertIsNotNone(auxv_data)87 88        # Ensure auxv data is a multiple of 2*word_size (there should be two89        # 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)))92 93    @skipIfWindows94    @expectedFailureNetBSD95    def test_auxv_keys_look_valid(self):96        self.build()97        self.set_inferior_startup_launch()98 99        (word_size, auxv_data) = self.get_raw_auxv_data()100        self.assertIsNotNone(auxv_data)101 102        # Grab endian.103        self.reset_test_sequence()104        self.add_process_info_collection_packets()105        context = self.expect_gdbremote_sequence()106        self.assertIsNotNone(context)107 108        process_info = self.parse_process_info_response(context)109        self.assertIsNotNone(process_info)110        endian = process_info.get("endian")111        self.assertIsNotNone(endian)112 113        auxv_dict = self.build_auxv_dict(endian, word_size, auxv_data)114        self.assertIsNotNone(auxv_dict)115 116        # Verify keys look reasonable. While AUX values are most commonly117        # 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.assertGreaterEqual(auxv_key, 1)121            self.assertLessEqual(auxv_key, 2500)122 123    @skipIfWindows124    @expectedFailureNetBSD125    def test_auxv_chunked_reads_work(self):126        self.build()127        self.set_inferior_startup_launch()128 129        # Verify that multiple smaller offset,length reads of auxv data130        # return the same data as a single larger read.131 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)135 136        # Grab endian.137        self.reset_test_sequence()138        self.add_process_info_collection_packets()139        context = self.expect_gdbremote_sequence()140        self.assertIsNotNone(context)141 142        process_info = self.parse_process_info_response(context)143        self.assertIsNotNone(process_info)144        endian = process_info.get("endian")145        self.assertIsNotNone(endian)146 147        auxv_dict = self.build_auxv_dict(endian, word_size, auxv_data)148        self.assertIsNotNone(auxv_dict)149 150        iterated_auxv_data = self.read_binary_data_in_chunks(151            "qXfer:auxv:read::", 2 * word_size152        )153        self.assertIsNotNone(iterated_auxv_data)154 155        auxv_dict_iterated = self.build_auxv_dict(endian, word_size, iterated_auxv_data)156        self.assertIsNotNone(auxv_dict_iterated)157 158        # Verify both types of data collection returned same content.159        self.assertEqual(auxv_dict_iterated, auxv_dict)160