From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by sourceware.org (Postfix) with ESMTPS id 0036C3830FC3 for ; Fri, 9 Dec 2022 01:52:51 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 0036C3830FC3 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-x32a.google.com with SMTP id h8-20020a1c2108000000b003d1efd60b65so4807057wmh.0 for ; Thu, 08 Dec 2022 17:52:51 -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=pRAAuMLAiugJDkqr7ANyM1yL/z1eD+nWA/B5ZMAoAJA=; b=liFsFV6SzhWLzxLaXqnJz/w5fIr44LzAk5WZCQfPVPjF1CdMWY6fOqZHlEdJCrKLeZ PVSVUXYjBATq7spTqjmaMrTowyg+esvhoanst/GYs2EoKaeA9DHToDVQo0Zok2IUAgyC 2netHHkIAIPQsA0RfdpZnZlSRhovk/fuZsXSlSZlUZXohlQ2blbfFtiUGaeeXXUGc4bw +OPWMNKc2VaWRPtRqK63Q/0vTdosufnYnCw2JcHdk5/AI7S36p+IHIMJhICGP6ctFLXX GAPLgmO0ae+eptI57YIo8gUIPWWe1i0KOOIfiUxvrfHFt7nrHgCxx8zD4gXEcvzMpLD1 Ip+w== 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=pRAAuMLAiugJDkqr7ANyM1yL/z1eD+nWA/B5ZMAoAJA=; b=z0BbiZEPwq5AQHsA5hNnlNtT8I0sDruHTvYVRb1fHzi1R6UPxUoznyFEB5mKlG+EoJ BIIeOgjjn6SJyqVYpv4jc4iNfxYxXAHC8uKHbxenIdIcr2wsELMp/EMCPLsCq79AZWIw YeXcS33FvkvSxk5m/zpzWvuTVW/EAUWVLVjgU9rSp+FtNKIMkgFb8yhXzgD3L1YGKedm JIHhdGFk0wdxsC9j8i6kxpAbtfMQbryHYJGWM7jCtW5kAutqwLN1LPYgt2jo9M9KnDZW 3XBJ0FTeb/qAbt1wpIw4ZdytQ8ibX43MDhpzR8tjHCQpZhSE9DFBDTUQXf61oyoByLPn R7GQ== X-Gm-Message-State: ANoB5pmXIZasQbgHSofxftuKjAIH7R+Fk/M5gjNWT2w2cZNtBUWYwYia 47T98G4YXniDorMDXWbfRnxa82UWOXg= X-Google-Smtp-Source: AA0mqf7/2TRH6+vRXyPxqUOCP6TE2e3s7zGOW9+KljVQJvTbnjdc4QPM9fF46zLv3DihW9lkmUabjg== X-Received: by 2002:a05:600c:3b9c:b0:3d1:e710:98ec with SMTP id n28-20020a05600c3b9c00b003d1e71098ecmr3859467wms.21.1670550770281; Thu, 08 Dec 2022 17:52:50 -0800 (PST) Received: from beren.harmstone.com ([2a02:8010:64ea:0:8eb8:7eff:fe53:9d5f]) by smtp.gmail.com with ESMTPSA id fc18-20020a05600c525200b003d04e4ed873sm7473139wmb.22.2022.12.08.17.52.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 08 Dec 2022 17:52:49 -0800 (PST) Sender: Mark Harmstone From: Mark Harmstone To: binutils@sourceware.org, nickc@redhat.com Cc: Mark Harmstone Subject: [PATCH 07/10] ld: Parse LF_UDT_SRC_LINE records when creating PDB file Date: Fri, 9 Dec 2022 01:52:37 +0000 Message-Id: <20221209015240.6348-7-mark@harmstone.com> X-Mailer: git-send-email 2.37.4 In-Reply-To: <20221209015240.6348-1-mark@harmstone.com> References: <20221209015240.6348-1-mark@harmstone.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-11.2 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: --- ld/pdb.c | 171 +++++++++++++++++++++-- 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, 459 insertions(+), 10 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 69fade50814..53a83fb8d6b 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) { - 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. */ @@ -1118,13 +1125,149 @@ 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; @@ -2075,6 +2218,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; @@ -2104,6 +2251,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) @@ -2129,7 +2278,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; @@ -2186,7 +2336,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); @@ -2212,7 +2363,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; @@ -2236,7 +2387,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); @@ -2370,7 +2521,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