From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x332.google.com (mail-wm1-x332.google.com [IPv6:2a00:1450:4864:20::332]) by sourceware.org (Postfix) with ESMTPS id 5623F385841C for ; Tue, 29 Nov 2022 00:10:25 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5623F385841C Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=harmstone.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-wm1-x332.google.com with SMTP id ay14-20020a05600c1e0e00b003cf6ab34b61so13071284wmb.2 for ; Mon, 28 Nov 2022 16:10:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:from:to:cc:subject:date :message-id:reply-to; bh=JRLtSz4BH7YUeuiZg8yi+NjieIMPojesLDZWIcLY1ZE=; b=onbvAIb3QVa4+px+s+sz/kiw0iwFNyorZDzgvTDicM4rx3cWCpQWrKco+GTV9fb9LY jXrtoWBnlR+k6b9h1dhPt0E3+xuv4pqX59n8Ixcqo+o7zujRQnHGvr2+oJCCM/V8+4Lh K8Be6MnCUf15YpvTKIl51XcUpLPQpXYDOdnv7oIjGp7s6l+CsRHwjdUj6DzAQlF/b/fu b2CxXnI42Bc3xM1sCJ22cJ88ACO/092ndym43S9nDdXPf3cA9pQ8hBpD+KXX3a2wLXED MsB3qQohrcaPiOuCjaWRHDSyqTpusX008swqpRu2ctH1bqNtH5i8ZqPgutAY53OuLFAs RkHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:sender:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=JRLtSz4BH7YUeuiZg8yi+NjieIMPojesLDZWIcLY1ZE=; b=SGg9UpV69M4SDjRxOzw2UsGVJw8VGB/K/ssUOrTBIgPe3rbcY8v54GF2Nc+I+hVslJ Fb8esu1maVz3Y+4RKyiqvssbaZcpxifdLnIaDiCK6gIIsMdI8o0JcbhEXQ4OeGB/s8x2 zZgcjTJhm7NF6V0QzgURwoGha6k037RPh5UUNmgoxfXEOp7uTvg5H9/5gwYLxWsFiHJl ODOlzxvItp3m3qJWrDjn4ukSbZmE7y4xJ46eJ/nrd8SiksFsoQt4OfogKyCuQvpJS02W BViZwtlrKLl4f5Aljr4gJ2vnE8qQ3ZYmHV+p2WhSuIpgHFom2qm/j03OSUQWcbKucEtt VXeg== X-Gm-Message-State: ANoB5pmzaC1gAu38mSskL82CTplnZJCm76MUV55LzI4U1Vfcjs1hPWqq d9/KOKmOHgFJQH0k1KCMYrkh6yNQ9v8= X-Google-Smtp-Source: AA0mqf7EeW/Uq46nGlBBwqatGJnS3KlwxXL6xjxpqI0niGDsFD5zGJgBmqwMWLybw/Hvpl0ym68K2A== X-Received: by 2002:a1c:4b12:0:b0:3cf:90de:7724 with SMTP id y18-20020a1c4b12000000b003cf90de7724mr42972402wma.18.1669680623659; Mon, 28 Nov 2022 16:10:23 -0800 (PST) Received: from beren.harmstone.com ([2a02:8010:64ea:0:8eb8:7eff:fe53:9d5f]) by smtp.gmail.com with ESMTPSA id r11-20020a05600c35cb00b003a84375d0d1sm57570wmq.44.2022.11.28.16.10.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Nov 2022 16:10:23 -0800 (PST) Sender: Mark Harmstone From: Mark Harmstone To: binutils@sourceware.org Cc: Mark Harmstone Subject: [PATCH] ld: Parse LF_UDT_SRC_LINE records when creating PDB file Date: Tue, 29 Nov 2022 00:10:15 +0000 Message-Id: <20221129001015.21775-3-mark@harmstone.com> X-Mailer: git-send-email 2.37.4 In-Reply-To: <20221129001015.21775-1-mark@harmstone.com> References: <20221127023840.32080-2-mark@harmstone.com> <20221129001015.21775-1-mark@harmstone.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,GIT_PATCH_0,HEADER_FROM_DIFFERENT_DOMAINS,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: This covers the special case of the LF_UDT_SRC_LINE records, which get rewritten as LF_UDT_MOD_SRC_LINE records, adding the module number. So if a struct is defined in multiple translation units, the PDB will record the source file, the line number, and the first module in which the struct is defined. --- ld/pdb.c | 174 +++++++++++++++++++++-- ld/pdb.h | 23 +++ ld/testsuite/ld-pe/pdb-types3-hashlist.d | 5 + ld/testsuite/ld-pe/pdb-types3-skiplist.d | 5 + ld/testsuite/ld-pe/pdb-types3-typelist.d | 7 + ld/testsuite/ld-pe/pdb-types3a.s | 57 ++++++++ ld/testsuite/ld-pe/pdb-types3b.s | 68 +++++++++ ld/testsuite/ld-pe/pdb.exp | 133 +++++++++++++++++ 8 files changed, 461 insertions(+), 11 deletions(-) create mode 100644 ld/testsuite/ld-pe/pdb-types3-hashlist.d create mode 100644 ld/testsuite/ld-pe/pdb-types3-skiplist.d create mode 100644 ld/testsuite/ld-pe/pdb-types3-typelist.d create mode 100644 ld/testsuite/ld-pe/pdb-types3a.s create mode 100644 ld/testsuite/ld-pe/pdb-types3b.s diff --git a/ld/pdb.c b/ld/pdb.c index 6584ccd9911..6326e018666 100644 --- a/ld/pdb.c +++ b/ld/pdb.c @@ -76,6 +76,7 @@ struct type_entry struct type_entry *next; uint32_t index; uint32_t cv_hash; + bool has_udt_src_line; uint8_t data[]; }; @@ -708,19 +709,19 @@ copy_filechksms (uint8_t *data, uint32_t size, char *string_table, return true; } -/* Add a string to the strings table, if it's not already there. */ -static void +/* Add a string to the strings table, if it's not already there. Returns its + offset within the string table. */ +static uint32_t add_string (char *str, size_t len, struct string_table *strings) { uint32_t hash = calc_hash (str, len); + struct string *s; void **slot; slot = htab_find_slot_with_hash (strings->hashmap, str, hash, INSERT); - if (slot && !*slot) + if (!*slot) { - struct string *s; - *slot = xmalloc (offsetof (struct string, s) + len); s = (struct string *) *slot; @@ -741,6 +742,12 @@ add_string (char *str, size_t len, struct string_table *strings) strings->strings_len += len + 1; } + else + { + s = (struct string *) *slot; + } + + return s->offset; } /* Return the hash of an entry in the string table. */ @@ -1092,13 +1099,150 @@ is_name_anonymous (char *name, size_t len) return false; } +/* Handle LF_UDT_SRC_LINE type entries, which are a special case. These + give the source file and line number for each user-defined type that is + declared. We parse these and emit instead an LF_UDT_MOD_SRC_LINE entry, + which also includes the module number. */ +static bool +handle_udt_src_line (uint8_t *data, uint16_t size, struct type_entry **map, + uint32_t type_num, uint32_t num_types, + struct types *ids, uint16_t mod_num, + struct string_table *strings) +{ + struct lf_udt_src_line *usl = (struct lf_udt_src_line *) data; + uint32_t orig_type, source_file_type; + void **slot; + hashval_t hash; + struct type_entry *e, *type_e, *str_e; + struct lf_udt_mod_src_line *umsl; + struct lf_string_id *str; + uint32_t source_file_offset; + + if (size < sizeof (struct lf_udt_src_line)) + { + einfo (_("%P: warning: truncated CodeView type record" + " LF_UDT_SRC_LINE\n")); + return false; + } + + /* Check if LF_UDT_MOD_SRC_LINE already present for type, and return. */ + + orig_type = bfd_getl32 (&usl->type); + + if (orig_type < TPI_FIRST_INDEX || + orig_type >= TPI_FIRST_INDEX + num_types || + !map[orig_type - TPI_FIRST_INDEX]) + { + einfo (_("%P: warning: CodeView type record LF_UDT_SRC_LINE" + " referred to unknown type %v\n"), orig_type); + return false; + } + + type_e = map[orig_type - TPI_FIRST_INDEX]; + + /* Skip if type already declared in other module. */ + if (type_e->has_udt_src_line) + return true; + + if (!remap_type (&usl->type, map, type_num, num_types)) + return false; + + /* Extract string from source_file_type. */ + + source_file_type = bfd_getl32 (&usl->source_file_type); + + if (source_file_type < TPI_FIRST_INDEX || + source_file_type >= TPI_FIRST_INDEX + num_types || + !map[source_file_type - TPI_FIRST_INDEX]) + { + einfo (_("%P: warning: CodeView type record LF_UDT_SRC_LINE" + " referred to unknown string %v\n"), source_file_type); + return false; + } + + str_e = map[source_file_type - TPI_FIRST_INDEX]; + + if (bfd_getl16 (str_e->data + sizeof (uint16_t)) != LF_STRING_ID) + { + einfo (_("%P: warning: CodeView type record LF_UDT_SRC_LINE" + " pointed to unexpected record type\n")); + return false; + } + + str = (struct lf_string_id *) str_e->data; + + /* Add string to string table. */ + + source_file_offset = add_string (str->string, strlen (str->string), + strings); + + /* Add LF_UDT_MOD_SRC_LINE entry. */ + + size = sizeof (struct lf_udt_mod_src_line); + + e = xmalloc (offsetof (struct type_entry, data) + size); + + e->next = NULL; + e->index = ids->num_types; + e->has_udt_src_line = false; + + /* LF_UDT_MOD_SRC_LINE use calc_hash on the type number, rather than + the crc32 used for type hashes elsewhere. */ + e->cv_hash = calc_hash ((char *) &usl->type, sizeof (uint32_t)); + + type_e->has_udt_src_line = true; + + umsl = (struct lf_udt_mod_src_line *) e->data; + + bfd_putl16 (size - sizeof (uint16_t), &umsl->size); + bfd_putl16 (LF_UDT_MOD_SRC_LINE, &umsl->kind); + memcpy (&umsl->type, &usl->type, sizeof (uint32_t)); + bfd_putl32 (source_file_offset, + &umsl->source_file_string); + memcpy (&umsl->line_no, &usl->line_no, sizeof (uint16_t)); + bfd_putl16 (mod_num + 1, &umsl->module_no); + + hash = iterative_hash (e->data, size, 0); + + slot = htab_find_slot_with_hash (ids->hashmap, data, hash, INSERT); + if (!slot) + { + free (e); + return false; + } + + if (*slot) + { + free (e); + einfo (_("%P: warning: duplicate CodeView type record " + "LF_UDT_MOD_SRC_LINE\n")); + return false; + } + + *slot = e; + + if (ids->last) + ids->last->next = e; + else + ids->first = e; + + ids->last = e; + + map[type_num] = e; + + ids->num_types++; + + return true; +} + /* Parse a type definition in the .debug$T section. We remap the numbers of any referenced types, and if the type is not a duplicate of one already seen add it to types (for TPI types) or ids (for IPI types). */ static bool handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num, uint32_t num_types, struct types *types, - struct types *ids) + struct types *ids, uint16_t mod_num, + struct string_table *strings) { uint16_t size, type; void **slot; @@ -2069,6 +2213,10 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num, break; } + case LF_UDT_SRC_LINE: + return handle_udt_src_line (data, size, map, type_num, num_types, + ids, mod_num, strings); + default: einfo (_("%P: warning: unrecognized CodeView type %v\n"), type); return false; @@ -2098,6 +2246,8 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num, else e->cv_hash = crc32 (data, size); + e->has_udt_src_line = false; + memcpy (e->data, data, size); if (t->last) @@ -2123,7 +2273,8 @@ handle_type (uint8_t *data, struct type_entry **map, uint32_t type_num, found to handle_type. */ static bool handle_debugt_section (asection *s, bfd *mod, struct types *types, - struct types *ids) + struct types *ids, uint16_t mod_num, + struct string_table *strings) { bfd_byte *data = NULL; size_t off; @@ -2180,7 +2331,8 @@ handle_debugt_section (asection *s, bfd *mod, struct types *types, size = bfd_getl16 (data + off); - if (!handle_type (data + off, map, type_num, num_types, types, ids)) + if (!handle_type (data + off, map, type_num, num_types, types, ids, + mod_num, strings)) { free (data); free (map); @@ -2206,7 +2358,7 @@ populate_module_stream (bfd *stream, bfd *mod, uint32_t *sym_byte_size, uint32_t *c13_info_size, struct mod_source_files *mod_source, bfd *abfd, struct types *types, - struct types *ids) + struct types *ids, uint16_t mod_num) { uint8_t int_buf[sizeof (uint32_t)]; uint8_t *c13_info = NULL; @@ -2230,7 +2382,7 @@ populate_module_stream (bfd *stream, bfd *mod, uint32_t *sym_byte_size, } else if (!strcmp (s->name, ".debug$T") && s->size >= sizeof (uint32_t)) { - if (!handle_debugt_section (s, mod, types, ids)) + if (!handle_debugt_section (s, mod, types, ids, mod_num, strings)) { free (c13_info); free (mod_source->files); @@ -2365,7 +2517,7 @@ create_module_info_substream (bfd *abfd, bfd *pdb, void **data, if (!populate_module_stream (stream, in, &sym_byte_size, strings, &c13_info_size, &source->mods[mod_num], abfd, - types, ids)) + types, ids, mod_num)) { for (unsigned int i = 0; i < source->mod_count; i++) { diff --git a/ld/pdb.h b/ld/pdb.h index 7d87a3fef07..668f3e168fd 100644 --- a/ld/pdb.h +++ b/ld/pdb.h @@ -59,6 +59,8 @@ #define LF_BUILDINFO 0x1603 #define LF_SUBSTR_LIST 0x1604 #define LF_STRING_ID 0x1605 +#define LF_UDT_SRC_LINE 0x1606 +#define LF_UDT_MOD_SRC_LINE 0x1607 #define LF_CHAR 0x8000 #define LF_SHORT 0x8001 @@ -517,6 +519,27 @@ struct lf_mfunc_id char name[]; } ATTRIBUTE_PACKED; +/* lfUdtSrcLine in cvinfo.h */ +struct lf_udt_src_line +{ + uint16_t size; + uint16_t kind; + uint32_t type; + uint32_t source_file_type; + uint32_t line_no; +} ATTRIBUTE_PACKED; + +/* lfUdtModSrcLine in cvinfo.h */ +struct lf_udt_mod_src_line +{ + uint16_t size; + uint16_t kind; + uint32_t type; + uint32_t source_file_string; + uint32_t line_no; + uint16_t module_no; +} ATTRIBUTE_PACKED; + extern bool create_pdb_file (bfd *, const char *, const unsigned char *); #endif diff --git a/ld/testsuite/ld-pe/pdb-types3-hashlist.d b/ld/testsuite/ld-pe/pdb-types3-hashlist.d new file mode 100644 index 00000000000..4a3775be42a --- /dev/null +++ b/ld/testsuite/ld-pe/pdb-types3-hashlist.d @@ -0,0 +1,5 @@ + +*: file format binary + +Contents of section .data: + 0000 d4d90000 0c1c0000 * \ No newline at end of file diff --git a/ld/testsuite/ld-pe/pdb-types3-skiplist.d b/ld/testsuite/ld-pe/pdb-types3-skiplist.d new file mode 100644 index 00000000000..52c10fa501d --- /dev/null +++ b/ld/testsuite/ld-pe/pdb-types3-skiplist.d @@ -0,0 +1,5 @@ + +*: file format binary + +Contents of section .data: + 0000 00100000 00000000 * \ No newline at end of file diff --git a/ld/testsuite/ld-pe/pdb-types3-typelist.d b/ld/testsuite/ld-pe/pdb-types3-typelist.d new file mode 100644 index 00000000000..d6ffaadb246 --- /dev/null +++ b/ld/testsuite/ld-pe/pdb-types3-typelist.d @@ -0,0 +1,7 @@ + +*: file format binary + +Contents of section .data: + 0000 0e000516 00000000 666f6f2e 6800f2f1 ........foo.h... + 0010 10000716 01100000 01000000 2a000000 ............*... + 0020 0100 .. \ No newline at end of file diff --git a/ld/testsuite/ld-pe/pdb-types3a.s b/ld/testsuite/ld-pe/pdb-types3a.s new file mode 100644 index 00000000000..def001e52f7 --- /dev/null +++ b/ld/testsuite/ld-pe/pdb-types3a.s @@ -0,0 +1,57 @@ +.equ CV_SIGNATURE_C13, 4 +.equ T_INT4, 0x0074 + +.equ LF_FIELDLIST, 0x1203 +.equ LF_STRUCTURE, 0x1505 +.equ LF_MEMBER, 0x150d +.equ LF_STRING_ID, 0x1605 +.equ LF_UDT_SRC_LINE, 0x1606 + +.section ".debug$T", "rn" + +.long CV_SIGNATURE_C13 + +# Type 1000, fieldlist for struct foo +.fieldlist1: +.short .struct1 - .fieldlist1 - 2 +.short LF_FIELDLIST +.short LF_MEMBER +.short 3 # public +.long T_INT4 +.short 0 # offset +.asciz "num" +.byte 0xf2 # padding +.byte 0xf1 # padding + +# Type 1001, struct foo +.struct1: +.short .string1 - .struct1 - 2 +.short LF_STRUCTURE +.short 1 # no. members +.short 0 # property +.long 0x1000 # field list +.long 0 # type derived from +.long 0 # type of vshape table +.short 4 # size +.asciz "foo" # name +.byte 0xf2 # padding +.byte 0xf1 # padding + +# Type 1002, string "foo" +.string1: +.short .udtsrcline1 - .string1 - 2 +.short LF_STRING_ID +.long 0 # sub-string +.asciz "foo.h" +.byte 0xf2 +.byte 0xf1 + +# Type 1003, UDT source line for type 1001 +.udtsrcline1: +.short .types_end - .udtsrcline1 - 2 +.short LF_UDT_SRC_LINE +.long 0x1001 +.long 0x1002 # source file string +.long 42 # line no. + +.types_end: diff --git a/ld/testsuite/ld-pe/pdb-types3b.s b/ld/testsuite/ld-pe/pdb-types3b.s new file mode 100644 index 00000000000..a22234e221f --- /dev/null +++ b/ld/testsuite/ld-pe/pdb-types3b.s @@ -0,0 +1,68 @@ +.equ CV_SIGNATURE_C13, 4 + +.equ T_LONG, 0x0012 +.equ T_INT4, 0x0074 + +.equ LF_MODIFIER, 0x1001 +.equ LF_FIELDLIST, 0x1203 +.equ LF_STRUCTURE, 0x1505 +.equ LF_MEMBER, 0x150d +.equ LF_STRING_ID, 0x1605 +.equ LF_UDT_SRC_LINE, 0x1606 + +.section ".debug$T", "rn" + +.long CV_SIGNATURE_C13 + +# Type 1000, const long +.mod1: +.short .fieldlist1 - .mod1 - 2 +.short LF_MODIFIER +.long T_LONG +.short 1 # const +.short 0 # padding + +# Type 1001, fieldlist for struct foo +.fieldlist1: +.short .struct1 - .fieldlist1 - 2 +.short LF_FIELDLIST +.short LF_MEMBER +.short 3 # public +.long T_INT4 +.short 0 # offset +.asciz "num" +.byte 0xf2 # padding +.byte 0xf1 # padding + +# Type 1002, struct foo +.struct1: +.short .string1 - .struct1 - 2 +.short LF_STRUCTURE +.short 1 # no. members +.short 0 # property +.long 0x1001 # field list +.long 0 # type derived from +.long 0 # type of vshape table +.short 4 # size +.asciz "foo" # name +.byte 0xf2 # padding +.byte 0xf1 # padding + +# Type 1003, string "foo" +.string1: +.short .udtsrcline1 - .string1 - 2 +.short LF_STRING_ID +.long 0 # sub-string +.asciz "foo.h" +.byte 0xf2 +.byte 0xf1 + +# Type 1004, UDT source line for type 1002 +.udtsrcline1: +.short .types_end - .udtsrcline1 - 2 +.short LF_UDT_SRC_LINE +.long 0x1002 +.long 0x1003 # source file string +.long 42 # line no. + +.types_end: diff --git a/ld/testsuite/ld-pe/pdb.exp b/ld/testsuite/ld-pe/pdb.exp index 9753216f544..1a5416890d1 100644 --- a/ld/testsuite/ld-pe/pdb.exp +++ b/ld/testsuite/ld-pe/pdb.exp @@ -1319,9 +1319,142 @@ proc test6 { } { } } +proc test7 { } { + global as + global ar + global ld + global objdump + global srcdir + global subdir + + if ![ld_assemble $as $srcdir/$subdir/pdb-types3a.s tmpdir/pdb-types3a.o] { + unsupported "Build pdb-types3a.o" + return + } + + if ![ld_assemble $as $srcdir/$subdir/pdb-types3b.s tmpdir/pdb-types3b.o] { + unsupported "Build pdb-types3b.o" + return + } + + if ![ld_link $ld "tmpdir/pdb-types3.exe" "--pdb=tmpdir/pdb-types3.pdb tmpdir/pdb-types3a.o tmpdir/pdb-types3b.o"] { + unsupported "Create PE image with PDB file" + return + } + + set exec_output [run_host_cmd "$ar" "x --output tmpdir tmpdir/pdb-types3.pdb 0004"] + + if ![string match "" $exec_output] { + fail "Could not extract IPI stream" + return + } else { + pass "Extracted IPI stream" + } + + set fi [open tmpdir/0004] + fconfigure $fi -translation binary + + seek $fi 16 current + + set data [read $fi 4] + binary scan $data i type_list_size + + set data [read $fi 2] + binary scan $data s hash_stream_index + + seek $fi 10 current + + set data [read $fi 4] + binary scan $data i hash_list_offset + + set data [read $fi 4] + binary scan $data i hash_list_size + + set data [read $fi 4] + binary scan $data i skip_list_offset + + set data [read $fi 4] + binary scan $data i skip_list_size + + seek $fi 8 current + + set type_list [read $fi $type_list_size] + + close $fi + + set fi [open tmpdir/pdb-types3-typelist w] + fconfigure $fi -translation binary + puts -nonewline $fi $type_list + close $fi + + # check type list + + set exp [file_contents "$srcdir/$subdir/pdb-types3-typelist.d"] + set got [run_host_cmd "$objdump" "-s --target=binary tmpdir/pdb-types3-typelist"] + if ![string match $exp $got] { + fail "Incorrect type list in IPI stream." + } else { + pass "Correct type list in IPI stream." + } + + # extract hash list and skip list + + set index_str [format "%04x" $hash_stream_index] + + set exec_output [run_host_cmd "$ar" "x --output tmpdir tmpdir/pdb-types3.pdb $index_str"] + + if ![string match "" $exec_output] { + fail "Could not extract IPI hash stream." + } else { + pass "Extracted IPI hash stream." + } + + set fi [open tmpdir/$index_str] + fconfigure $fi -translation binary + + seek $fi $hash_list_offset + set hash_list [read $fi $hash_list_size] + + seek $fi $skip_list_offset + set skip_list [read $fi $skip_list_size] + + close $fi + + # check hash list + + set fi [open tmpdir/pdb-types3-hashlist w] + fconfigure $fi -translation binary + puts -nonewline $fi $hash_list + close $fi + + set exp [file_contents "$srcdir/$subdir/pdb-types3-hashlist.d"] + set got [run_host_cmd "$objdump" "-s --target=binary tmpdir/pdb-types3-hashlist"] + if ![string match $exp $got] { + fail "Incorrect hash list in IPI stream." + } else { + pass "Correct hash list in IPI stream." + } + + # check skip list + + set fi [open tmpdir/pdb-types3-skiplist w] + fconfigure $fi -translation binary + puts -nonewline $fi $skip_list + close $fi + + set exp [file_contents "$srcdir/$subdir/pdb-types3-skiplist.d"] + set got [run_host_cmd "$objdump" "-s --target=binary tmpdir/pdb-types3-skiplist"] + if ![string match $exp $got] { + fail "Incorrect skip list in IPI stream." + } else { + pass "Correct skip list in IPI stream." + } +} + test1 test2 test3 test4 test5 test6 +test7 -- 2.37.4