From: Mark Harmstone <mark@harmstone.com>
To: binutils@sourceware.org
Cc: Mark Harmstone <mark@harmstone.com>
Subject: [PATCH] ld: Write DEBUG_S_LINES entries in PDB file
Date: Sun, 27 Nov 2022 02:38:40 +0000 [thread overview]
Message-ID: <20221127023840.32080-2-mark@harmstone.com> (raw)
In-Reply-To: <20221127023840.32080-1-mark@harmstone.com>
This extracts the DEBUG_S_LINES subsections of the .debug$S section of
the input files, resolves the relocations, and copies them into the
module symbol stream of the PDB.
---
ld/pdb.c | 111 +++++++++++++++++++++++++++-
ld/pdb.h | 1 +
ld/testsuite/ld-pe/pdb.exp | 2 +-
ld/testsuite/ld-pe/pdb3-c13-info1.d | 8 +-
ld/testsuite/ld-pe/pdb3a.s | 88 ++++++++++++++++++++++
5 files changed, 204 insertions(+), 6 deletions(-)
diff --git a/ld/pdb.c b/ld/pdb.c
index 42bb1b3a91b..cfc76004227 100644
--- a/ld/pdb.c
+++ b/ld/pdb.c
@@ -623,7 +623,8 @@ parse_string_table (bfd_byte *data, size_t size,
static bool
handle_debugs_section (asection *s, bfd *mod, struct string_table *strings,
uint8_t **dataptr, uint32_t *sizeptr,
- struct mod_source_files *mod_source)
+ struct mod_source_files *mod_source,
+ bfd *abfd)
{
bfd_byte *data = NULL;
size_t off;
@@ -637,6 +638,59 @@ handle_debugs_section (asection *s, bfd *mod, struct string_table *strings,
if (!data)
return false;
+ /* Resolve relocations. Addresses are stored within the .debug$S section as
+ a .secidx, .secrel32 pair. */
+
+ if (s->flags & SEC_RELOC)
+ {
+ struct internal_reloc *relocs;
+ struct internal_syment *symbols;
+ asection **sectlist;
+ unsigned int syment_count;
+ int sect_num;
+ struct external_syment *ext;
+
+ syment_count = obj_raw_syment_count (mod);
+
+ relocs =
+ _bfd_coff_read_internal_relocs (mod, s, false, NULL, true, NULL);
+
+ symbols = xmalloc (sizeof (struct internal_syment) * syment_count);
+ sectlist = xmalloc (sizeof (asection *) * syment_count);
+
+ ext = (struct external_syment *) (coff_data (mod)->external_syms);
+
+ for (unsigned int i = 0; i < syment_count; i++)
+ {
+ bfd_coff_swap_sym_in (mod, &ext[i], &symbols[i]);
+ }
+
+ sect_num = 1;
+
+ for (asection *sect = mod->sections; sect; sect = sect->next)
+ {
+ for (unsigned int i = 0; i < syment_count; i++)
+ {
+ if (symbols[i].n_scnum == sect_num)
+ sectlist[i] = sect;
+ }
+
+ sect_num++;
+ }
+
+ if (!bfd_coff_relocate_section (abfd, coff_data (abfd)->link_info, mod,
+ s, data, relocs, symbols, sectlist))
+ {
+ free (sectlist);
+ free (symbols);
+ free (data);
+ return false;
+ }
+
+ free (sectlist);
+ free (symbols);
+ }
+
if (bfd_getl32 (data) != CV_SIGNATURE_C13)
{
free (data);
@@ -689,6 +743,32 @@ handle_debugs_section (asection *s, bfd *mod, struct string_table *strings,
string_table = (char *) data + off;
break;
+
+ case DEBUG_S_LINES:
+ {
+ uint16_t sect;
+
+ if (size < sizeof (uint32_t) + sizeof (uint16_t))
+ {
+ free (data);
+ bfd_set_error (bfd_error_bad_value);
+ return false;
+ }
+
+ sect = bfd_getl16 (data + off + sizeof (uint32_t));
+
+ /* Skip GC'd symbols. */
+ if (sect != 0)
+ {
+ c13_size += sizeof (uint32_t) + sizeof (uint32_t) + size;
+
+ if (c13_size % sizeof (uint32_t))
+ c13_size +=
+ sizeof (uint32_t) - (c13_size % sizeof (uint32_t));
+ }
+
+ break;
+ }
}
off += size;
@@ -734,6 +814,28 @@ handle_debugs_section (asection *s, bfd *mod, struct string_table *strings,
bufptr += sizeof (uint32_t) + sizeof (uint32_t) + size;
break;
+
+ case DEBUG_S_LINES:
+ {
+ uint16_t sect;
+
+ sect = bfd_getl16 (data + off + sizeof (uint32_t));
+
+ /* Skip if GC'd. */
+ if (sect != 0)
+ {
+ bfd_putl32 (type, bufptr);
+ bufptr += sizeof (uint32_t);
+
+ bfd_putl32 (size, bufptr);
+ bufptr += sizeof (uint32_t);
+
+ memcpy (bufptr, data + off, size);
+ bufptr += size;
+ }
+
+ break;
+ }
}
off += size;
@@ -770,7 +872,8 @@ static bool
populate_module_stream (bfd *stream, bfd *mod, uint32_t *sym_byte_size,
struct string_table *strings,
uint32_t *c13_info_size,
- struct mod_source_files *mod_source)
+ struct mod_source_files *mod_source,
+ bfd *abfd)
{
uint8_t int_buf[sizeof (uint32_t)];
uint8_t *c13_info = NULL;
@@ -785,7 +888,7 @@ populate_module_stream (bfd *stream, bfd *mod, uint32_t *sym_byte_size,
if (!strcmp (s->name, ".debug$S") && s->size >= sizeof (uint32_t))
{
if (!handle_debugs_section (s, mod, strings, &c13_info,
- c13_info_size, mod_source))
+ c13_info_size, mod_source, abfd))
{
free (c13_info);
free (mod_source->files);
@@ -918,7 +1021,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]))
+ &source->mods[mod_num], abfd))
{
for (unsigned int i = 0; i < source->mod_count; i++)
{
diff --git a/ld/pdb.h b/ld/pdb.h
index e8f673c24a0..bbb106043c4 100644
--- a/ld/pdb.h
+++ b/ld/pdb.h
@@ -155,6 +155,7 @@ struct optional_dbg_header
#define CV_SIGNATURE_C13 4
+#define DEBUG_S_LINES 0xf2
#define DEBUG_S_STRINGTABLE 0xf3
#define DEBUG_S_FILECHKSMS 0xf4
diff --git a/ld/testsuite/ld-pe/pdb.exp b/ld/testsuite/ld-pe/pdb.exp
index 9dab41110ac..2e5f83477aa 100644
--- a/ld/testsuite/ld-pe/pdb.exp
+++ b/ld/testsuite/ld-pe/pdb.exp
@@ -870,7 +870,7 @@ proc test4 { } {
return
}
- if ![ld_link $ld "tmpdir/pdb3.exe" "--pdb=tmpdir/pdb3.pdb tmpdir/pdb3a.o tmpdir/pdb3b.o"] {
+ if ![ld_link $ld "tmpdir/pdb3.exe" "--pdb=tmpdir/pdb3.pdb --gc-sections -e main tmpdir/pdb3a.o tmpdir/pdb3b.o"] {
unsupported "Create PE image with PDB file"
return
}
diff --git a/ld/testsuite/ld-pe/pdb3-c13-info1.d b/ld/testsuite/ld-pe/pdb3-c13-info1.d
index f92062ba4e5..5a4f94861c7 100644
--- a/ld/testsuite/ld-pe/pdb3-c13-info1.d
+++ b/ld/testsuite/ld-pe/pdb3-c13-info1.d
@@ -5,4 +5,10 @@ Contents of section .data:
0000 f4000000 30000000 02000000 10016745 ....0.........gE
0010 2301efcd ab8998ba dcfe1023 45670000 #..........#Eg..
0020 06000000 100198ba dcfe1023 45676745 ...........#EggE
- 0030 2301efcd ab890000 #.......
\ No newline at end of file
+ 0030 2301efcd ab890000 f2000000 58000000 #...........X...
+ 0040 00000000 01000000 14000000 00000000 ................
+ 0050 02000000 1c000000 00000000 01000080 ................
+ 0060 04000000 02000080 18000000 02000000 ................
+ 0070 1c000000 08000000 03000080 0c000000 ................
+ 0080 04000080 00000000 01000000 14000000 ................
+ 0090 10000000 05000080 ........
\ No newline at end of file
diff --git a/ld/testsuite/ld-pe/pdb3a.s b/ld/testsuite/ld-pe/pdb3a.s
index 71795b53a66..1df84a344f6 100644
--- a/ld/testsuite/ld-pe/pdb3a.s
+++ b/ld/testsuite/ld-pe/pdb3a.s
@@ -1,4 +1,5 @@
.equ CV_SIGNATURE_C13, 4
+.equ DEBUG_S_LINES, 0xf2
.equ DEBUG_S_STRINGTABLE, 0xf3
.equ DEBUG_S_FILECHKSMS, 0xf4
.equ CHKSUM_TYPE_MD5, 1
@@ -50,3 +51,90 @@
.chksms_end:
.balign 4
+
+.long DEBUG_S_LINES
+.long .lines_end - .lines_start
+
+.lines_start:
+
+.secrel32 main
+.secidx main
+.short 0 # flags
+.long .main_end - main # length of region
+
+.lines_block1:
+
+.long 0 # file ID 0 (foo)
+.long 2 # no. lines
+.long .lines_block2 - .lines_block1 # length
+
+.long .line1 - main
+.long 0x80000001 # line 1
+.long .line2 - main
+.long 0x80000002 # line 2
+
+.lines_block2:
+
+.long 0x18 # file ID 18 (bar)
+.long 2 # no. lines
+.long .lines_block3 - .lines_block2 # length
+
+.long .line3 - main
+.long 0x80000003 # line 3
+.long .line4 - main
+.long 0x80000004 # line 4
+
+.lines_block3:
+
+.long 0 # file ID 0 (foo)
+.long 1 # no. lines
+.long .lines_end - .lines_block3 # length
+
+.long .line5 - main
+.long 0x80000005 # line 5
+
+.lines_end:
+
+.long DEBUG_S_LINES
+.long .lines_end2 - .lines_start2
+
+.lines_start2:
+
+.secrel32 gcfunc
+.secidx gcfunc
+.short 0 # flags
+.long .gcfunc_end - gcfunc # length of region
+
+.lines_block4:
+
+.long 0 # file ID 0 (foo)
+.long 1 # no. lines
+.long .lines_end2 - .lines_block4 # length
+
+.long .line6 - gcfunc
+.long 0x80000006 # line 6
+
+.lines_end2:
+
+.text
+
+.global main
+main:
+.line1:
+ .long 0x12345678
+.line2:
+ .long 0x12345678
+.line3:
+ .long 0x12345678
+.line4:
+ .long 0x12345678
+.line5:
+ .long 0x12345678
+.main_end:
+
+.section "gcsect"
+
+gcfunc:
+.line6:
+ .long 0x12345678
+.gcfunc_end:
--
2.37.4
next prev parent reply other threads:[~2022-11-27 2:38 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-25 2:53 [PATCH v2] ld: Generate PDB string table Mark Harmstone
2022-11-25 2:54 ` [PATCH] ld: Write DEBUG_S_FILECHKSMS entries in PDBs Mark Harmstone
2022-11-27 2:38 ` [PATCH] ld: Fix segfault in populate_publics_stream Mark Harmstone
2022-11-27 2:38 ` Mark Harmstone [this message]
2022-11-29 0:10 ` [PATCH] ld: Write types into TPI stream of PDB Mark Harmstone
2022-11-29 0:10 ` [PATCH] ld: Write types into IPI " Mark Harmstone
2022-11-29 0:10 ` [PATCH] ld: Parse LF_UDT_SRC_LINE records when creating PDB file Mark Harmstone
2022-12-05 1:53 ` [PATCH] ld: Write globals stream in PDB Mark Harmstone
2022-12-05 1:53 ` [PATCH] ld: Copy other symbols into PDB file Mark Harmstone
2022-12-05 1:53 ` [PATCH] ld: Write linker symbols in PDB Mark Harmstone
2022-12-06 17:07 ` [PATCH] ld: Write globals stream " Nick Clifton
2022-12-06 17:52 ` Mark Harmstone
2022-12-08 11:00 ` Nick Clifton
2022-12-09 1:11 ` Mark Harmstone
2022-11-28 14:54 ` [PATCH] ld: Fix segfault in populate_publics_stream Jan Beulich
2022-11-28 17:53 ` Mark Harmstone
2022-11-29 9:00 ` Jan Beulich
2022-11-29 17:47 ` Mark Harmstone
2022-11-30 7:00 ` Jan Beulich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221127023840.32080-2-mark@harmstone.com \
--to=mark@harmstone.com \
--cc=binutils@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).