From 9bf6cbf6dd88777719c5757922aff0190ec46539 Mon Sep 17 00:00:00 2001 From: Joshua Lang Date: Wed, 14 Dec 2016 23:05:00 -0800 Subject: Set CodeView pdb path/name to base name The CodeView pdb path/name field is empty leading windows minidumps to have empty module paths for the binary. This patch sets the path to the base name of the binary. Bug: 33668347 Change-Id: I4138998239b07b54cc36dc2d2e3484c4b63f5435 --- binutils-2.25/bfd/libpei.h | 4 ++++ binutils-2.25/bfd/peXXigen.c | 40 +++++++++++++++++++++++------------ binutils-2.25/include/coff/internal.h | 2 +- binutils-2.25/ld/emultempl/pe.em | 12 +++++++---- binutils-2.25/ld/emultempl/pep.em | 11 ++++++---- 5 files changed, 47 insertions(+), 22 deletions(-) diff --git a/binutils-2.25/bfd/libpei.h b/binutils-2.25/bfd/libpei.h index ffcafded..10090f74 100644 --- a/binutils-2.25/bfd/libpei.h +++ b/binutils-2.25/bfd/libpei.h @@ -238,6 +238,7 @@ #define _bfd_XXi_swap_debugdir_in _bfd_pex64i_swap_debugdir_in #define _bfd_XXi_swap_debugdir_out _bfd_pex64i_swap_debugdir_out #define _bfd_XXi_write_codeview_record _bfd_pex64i_write_codeview_record +#define _bfd_XXi_get_codeview_pdb_name _bfd_pex64i_get_codeview_pdb_name #elif defined COFF_WITH_pep @@ -272,6 +273,7 @@ #define _bfd_XXi_swap_debugdir_in _bfd_pepi_swap_debugdir_in #define _bfd_XXi_swap_debugdir_out _bfd_pepi_swap_debugdir_out #define _bfd_XXi_write_codeview_record _bfd_pepi_write_codeview_record +#define _bfd_XXi_get_codeview_pdb_name _bfd_pepi_get_codeview_pdb_name #else /* !COFF_WITH_pep */ @@ -306,6 +308,7 @@ #define _bfd_XXi_swap_debugdir_in _bfd_pei_swap_debugdir_in #define _bfd_XXi_swap_debugdir_out _bfd_pei_swap_debugdir_out #define _bfd_XXi_write_codeview_record _bfd_pei_write_codeview_record +#define _bfd_XXi_get_codeview_pdb_name _bfd_pei_get_codeview_pdb_name #endif /* !COFF_WITH_pep */ @@ -351,6 +354,7 @@ bfd_boolean _bfd_XXi_final_link_postscript (bfd *, struct coff_final_link_info * void _bfd_XXi_swap_debugdir_in (bfd *, void *, void *); unsigned _bfd_XXi_swap_debugdir_out (bfd *, void *, void *); unsigned _bfd_XXi_write_codeview_record (bfd *, file_ptr, CODEVIEW_INFO *); +const char* _bfd_XXi_get_codeview_pdb_name (bfd *); /* The following are needed only for ONE of pe or pei, but don't otherwise vary; peicode.h fixes up ifdefs but we provide the diff --git a/binutils-2.25/bfd/peXXigen.c b/binutils-2.25/bfd/peXXigen.c index dae32f66..70223404 100644 --- a/binutils-2.25/bfd/peXXigen.c +++ b/binutils-2.25/bfd/peXXigen.c @@ -1138,19 +1138,31 @@ _bfd_XXi_swap_debugdir_out (bfd * abfd, void * inp, void * extp) return sizeof (struct external_IMAGE_DEBUG_DIRECTORY); } +const char * +_bfd_XXi_get_codeview_pdb_name (bfd * abfd) +{ + char * filename_ptr = bfd_get_filename(abfd); + char * last_dir_separator = strrchr(filename_ptr, '/'); + if (last_dir_separator != NULL) { + filename_ptr = last_dir_separator+1; + } + return filename_ptr; +} + static CODEVIEW_INFO * _bfd_XXi_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length, CODEVIEW_INFO *cvinfo) { - char buffer[256+1]; - if (bfd_seek (abfd, where, SEEK_SET) != 0) + char buffer [length]; + + if (!cvinfo) return NULL; - if (bfd_bread (buffer, 256, abfd) < 4) + if (bfd_seek (abfd, where, SEEK_SET) != 0) return NULL; - /* Ensure null termination of filename. */ - buffer[256] = '\0'; + if (bfd_bread (buffer, length, abfd) < 4) + return NULL; cvinfo->CVSignature = H_GET_32(abfd, buffer); cvinfo->Age = 0; @@ -1171,7 +1183,7 @@ _bfd_XXi_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length memcpy (&(cvinfo->Signature[8]), &(cvinfo70->Signature[8]), 8); cvinfo->SignatureLength = CV_INFO_SIGNATURE_LENGTH; - // cvinfo->PdbFileName = cvinfo70->PdbFileName; + strcpy(cvinfo->PdbFileName, cvinfo70->PdbFileName); return cvinfo; } @@ -1193,7 +1205,9 @@ _bfd_XXi_slurp_codeview_record (bfd * abfd, file_ptr where, unsigned long length unsigned int _bfd_XXi_write_codeview_record (bfd * abfd, file_ptr where, CODEVIEW_INFO *cvinfo) { - unsigned int size = sizeof (CV_INFO_PDB70) + 1; + const char * filename_ptr = _bfd_XXi_get_codeview_pdb_name(abfd); + unsigned int filename_size = strlen(filename_ptr); + unsigned int size = sizeof (CV_INFO_PDB70) + filename_size + 1; CV_INFO_PDB70 *cvinfo70; char buffer[size]; @@ -1211,7 +1225,7 @@ _bfd_XXi_write_codeview_record (bfd * abfd, file_ptr where, CODEVIEW_INFO *cvinf memcpy (&(cvinfo70->Signature[8]), &(cvinfo->Signature[8]), 8); H_PUT_32 (abfd, cvinfo->Age, cvinfo70->Age); - cvinfo70->PdbFileName[0] = '\0'; + strcpy(cvinfo70->PdbFileName, filename_ptr); if (bfd_bwrite (buffer, size, abfd) != size) return 0; @@ -2655,8 +2669,8 @@ pe_print_debugdata (bfd * abfd, void * vfile) if (idd.Type == PE_IMAGE_DEBUG_TYPE_CODEVIEW) { char signature[CV_INFO_SIGNATURE_LENGTH * 2 + 1]; - char buffer[256 + 1]; - CODEVIEW_INFO *cvinfo = (CODEVIEW_INFO *) buffer; + char buffer [idd.SizeOfData]; + CODEVIEW_INFO * cvinfo = (CODEVIEW_INFO *) buffer; /* The debug entry doesn't have to have to be in a section, in which case AddressOfRawData is 0, so always use PointerToRawData. */ @@ -2667,9 +2681,9 @@ pe_print_debugdata (bfd * abfd, void * vfile) for (i = 0; i < cvinfo->SignatureLength; i++) sprintf (&signature[i*2], "%02x", cvinfo->Signature[i] & 0xff); - fprintf (file, "(format %c%c%c%c signature %s age %ld)\n", - buffer[0], buffer[1], buffer[2], buffer[3], - signature, cvinfo->Age); + fprintf (file, "(format %c%c%c%c signature %s age %ld pdb %s)\n", + buffer[0], buffer[1], buffer[2], buffer[3], + signature, cvinfo->Age, cvinfo->PdbFileName); } } diff --git a/binutils-2.25/include/coff/internal.h b/binutils-2.25/include/coff/internal.h index 47e85d9f..2fd0264e 100644 --- a/binutils-2.25/include/coff/internal.h +++ b/binutils-2.25/include/coff/internal.h @@ -167,7 +167,7 @@ typedef struct _CODEVIEW_INFO char Signature[CV_INFO_SIGNATURE_LENGTH]; unsigned int SignatureLength; unsigned long Age; - // char PdbFileName[]; + char PdbFileName[]; } CODEVIEW_INFO; /* Default image base for NT. */ diff --git a/binutils-2.25/ld/emultempl/pe.em b/binutils-2.25/ld/emultempl/pe.em index 979cc8b8..f0ecbcfd 100644 --- a/binutils-2.25/ld/emultempl/pe.em +++ b/binutils-2.25/ld/emultempl/pe.em @@ -1324,6 +1324,9 @@ write_build_id (bfd *abfd) return TRUE; } + const char * pdb_name = _bfd_XXi_get_codeview_pdb_name (abfd); + unsigned int pdb_name_length = strlen(pdb_name); + if (t->build_id.sec->contents == NULL) t->build_id.sec->contents = (unsigned char *) xmalloc (t->build_id.sec->size); contents = t->build_id.sec->contents; @@ -1342,7 +1345,7 @@ write_build_id (bfd *abfd) idd.MajorVersion = 0; idd.MinorVersion = 0; idd.Type = PE_IMAGE_DEBUG_TYPE_CODEVIEW; - idd.SizeOfData = sizeof (CV_INFO_PDB70) + 1; + idd.SizeOfData = sizeof (CV_INFO_PDB70) + pdb_name_length + 1; idd.AddressOfRawData = asec->vma - ib + link_order->offset + sizeof (struct external_IMAGE_DEBUG_DIRECTORY); idd.PointerToRawData = asec->filepos + link_order->offset @@ -1406,12 +1409,13 @@ setup_build_id (bfd *ibfd) t->build_id.style = emit_build_id; t->build_id.sec = s; - /* Section is a fixed size: + /* Section is a variable size: One IMAGE_DEBUG_DIRECTORY entry, of type IMAGE_DEBUG_TYPE_CODEVIEW, pointing at a CV_INFO_PDB70 record containing the build-id, with a - null byte for PdbFileName. */ + null terminated string for PdbFileName. */ + s->size = sizeof (struct external_IMAGE_DEBUG_DIRECTORY) - + sizeof (CV_INFO_PDB70) + 1; + + sizeof (CV_INFO_PDB70) + strlen(_bfd_XXi_get_codeview_pdb_name(link_info.output_bfd)) + 1; return TRUE; } diff --git a/binutils-2.25/ld/emultempl/pep.em b/binutils-2.25/ld/emultempl/pep.em index b24a6082..100d4ef4 100644 --- a/binutils-2.25/ld/emultempl/pep.em +++ b/binutils-2.25/ld/emultempl/pep.em @@ -1288,6 +1288,9 @@ write_build_id (bfd *abfd) return TRUE; } + const char * pdb_name = _bfd_XXi_get_codeview_pdb_name (abfd); + unsigned int pdb_name_length = strlen(pdb_name); + if (t->build_id.sec->contents == NULL) t->build_id.sec->contents = (unsigned char *) xmalloc (t->build_id.sec->size); contents = t->build_id.sec->contents; @@ -1306,7 +1309,7 @@ write_build_id (bfd *abfd) idd.MajorVersion = 0; idd.MinorVersion = 0; idd.Type = PE_IMAGE_DEBUG_TYPE_CODEVIEW; - idd.SizeOfData = sizeof (CV_INFO_PDB70) + 1; + idd.SizeOfData = sizeof (CV_INFO_PDB70) + pdb_name_length + 1; idd.AddressOfRawData = asec->vma - ib + link_order->offset + sizeof (struct external_IMAGE_DEBUG_DIRECTORY); idd.PointerToRawData = asec->filepos + link_order->offset @@ -1370,12 +1373,12 @@ setup_build_id (bfd *ibfd) t->build_id.style = emit_build_id; t->build_id.sec = s; - /* Section is a fixed size: + /* Section is a variable size: One IMAGE_DEBUG_DIRECTORY entry, of type IMAGE_DEBUG_TYPE_CODEVIEW, pointing at a CV_INFO_PDB70 record containing the build-id, with a - null byte for PdbFileName. */ + null terminated string for PdbFileName. */ s->size = sizeof (struct external_IMAGE_DEBUG_DIRECTORY) - + sizeof (CV_INFO_PDB70) + 1; + + sizeof (CV_INFO_PDB70) + strlen(_bfd_XXi_get_codeview_pdb_name(link_info.output_bfd)) + 1; return TRUE; } -- cgit v1.2.3