mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-05 15:15:42 +00:00
ld: Write DEBUG_S_LINES entries in PDB file
This commit is contained in:
committed by
Alan Modra
parent
8b182dc3c6
commit
598c1ae610
111
ld/pdb.c
111
ld/pdb.c
@@ -624,7 +624,8 @@ parse_string_table (bfd_byte *data, size_t size,
|
|||||||
static bool
|
static bool
|
||||||
handle_debugs_section (asection *s, bfd *mod, struct string_table *strings,
|
handle_debugs_section (asection *s, bfd *mod, struct string_table *strings,
|
||||||
uint8_t **dataptr, uint32_t *sizeptr,
|
uint8_t **dataptr, uint32_t *sizeptr,
|
||||||
struct mod_source_files *mod_source)
|
struct mod_source_files *mod_source,
|
||||||
|
bfd *abfd)
|
||||||
{
|
{
|
||||||
bfd_byte *data = NULL;
|
bfd_byte *data = NULL;
|
||||||
size_t off;
|
size_t off;
|
||||||
@@ -638,6 +639,59 @@ handle_debugs_section (asection *s, bfd *mod, struct string_table *strings,
|
|||||||
if (!data)
|
if (!data)
|
||||||
return false;
|
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)
|
if (bfd_getl32 (data) != CV_SIGNATURE_C13)
|
||||||
{
|
{
|
||||||
free (data);
|
free (data);
|
||||||
@@ -690,6 +744,32 @@ handle_debugs_section (asection *s, bfd *mod, struct string_table *strings,
|
|||||||
string_table = (char *) data + off;
|
string_table = (char *) data + off;
|
||||||
|
|
||||||
break;
|
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;
|
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;
|
bufptr += sizeof (uint32_t) + sizeof (uint32_t) + size;
|
||||||
|
|
||||||
break;
|
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;
|
off += size;
|
||||||
@@ -770,7 +872,8 @@ static bool
|
|||||||
populate_module_stream (bfd *stream, bfd *mod, uint32_t *sym_byte_size,
|
populate_module_stream (bfd *stream, bfd *mod, uint32_t *sym_byte_size,
|
||||||
struct string_table *strings,
|
struct string_table *strings,
|
||||||
uint32_t *c13_info_size,
|
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 int_buf[sizeof (uint32_t)];
|
||||||
uint8_t *c13_info = NULL;
|
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 (!strcmp (s->name, ".debug$S") && s->size >= sizeof (uint32_t))
|
||||||
{
|
{
|
||||||
if (!handle_debugs_section (s, mod, strings, &c13_info,
|
if (!handle_debugs_section (s, mod, strings, &c13_info,
|
||||||
c13_info_size, mod_source))
|
c13_info_size, mod_source, abfd))
|
||||||
{
|
{
|
||||||
free (c13_info);
|
free (c13_info);
|
||||||
free (mod_source->files);
|
free (mod_source->files);
|
||||||
@@ -917,7 +1020,7 @@ create_module_info_substream (bfd *abfd, bfd *pdb, void **data,
|
|||||||
|
|
||||||
if (!populate_module_stream (stream, in, &sym_byte_size,
|
if (!populate_module_stream (stream, in, &sym_byte_size,
|
||||||
strings, &c13_info_size,
|
strings, &c13_info_size,
|
||||||
&source->mods[mod_num]))
|
&source->mods[mod_num], abfd))
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < source->mod_count; i++)
|
for (unsigned int i = 0; i < source->mod_count; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
1
ld/pdb.h
1
ld/pdb.h
@@ -155,6 +155,7 @@ struct optional_dbg_header
|
|||||||
|
|
||||||
#define CV_SIGNATURE_C13 4
|
#define CV_SIGNATURE_C13 4
|
||||||
|
|
||||||
|
#define DEBUG_S_LINES 0xf2
|
||||||
#define DEBUG_S_STRINGTABLE 0xf3
|
#define DEBUG_S_STRINGTABLE 0xf3
|
||||||
#define DEBUG_S_FILECHKSMS 0xf4
|
#define DEBUG_S_FILECHKSMS 0xf4
|
||||||
|
|
||||||
|
|||||||
@@ -870,7 +870,7 @@ proc test4 { } {
|
|||||||
return
|
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"
|
unsupported "Create PE image with PDB file"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,4 +5,10 @@ Contents of section .data:
|
|||||||
0000 f4000000 30000000 02000000 10016745 ....0.........gE
|
0000 f4000000 30000000 02000000 10016745 ....0.........gE
|
||||||
0010 2301efcd ab8998ba dcfe1023 45670000 #..........#Eg..
|
0010 2301efcd ab8998ba dcfe1023 45670000 #..........#Eg..
|
||||||
0020 06000000 100198ba dcfe1023 45676745 ...........#EggE
|
0020 06000000 100198ba dcfe1023 45676745 ...........#EggE
|
||||||
0030 2301efcd ab890000 #.......
|
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 ........
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
.equ CV_SIGNATURE_C13, 4
|
.equ CV_SIGNATURE_C13, 4
|
||||||
|
.equ DEBUG_S_LINES, 0xf2
|
||||||
.equ DEBUG_S_STRINGTABLE, 0xf3
|
.equ DEBUG_S_STRINGTABLE, 0xf3
|
||||||
.equ DEBUG_S_FILECHKSMS, 0xf4
|
.equ DEBUG_S_FILECHKSMS, 0xf4
|
||||||
.equ CHKSUM_TYPE_MD5, 1
|
.equ CHKSUM_TYPE_MD5, 1
|
||||||
@@ -50,3 +51,90 @@
|
|||||||
.chksms_end:
|
.chksms_end:
|
||||||
|
|
||||||
.balign 4
|
.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:
|
||||||
|
|||||||
Reference in New Issue
Block a user