This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 1/4] Add reading/writing of pe/coff debug directory and codeview records


Add routines for reading and writing of the debug directory entries in a pe/coff
header.

Also add routines for reading and writing a codeview record which may be pointed
to by a debug directory entry.

This tries to match the existing style, but not sure if it succeeds. Not sure
how to handle the variable length pdbfilename the codeview record contains, but
it's not very interesting, so just leave that out for the moment.

bfd/ChangeLog:

2014-01-20  Jon TURNEY  <jon.turney@dronecode.org.uk>

	* peXXigen.c (_bfd_XXi_swap_debugdir_in)
	(_bfd_XXi_swap_debugdir_out, _bfd_XXi_slurp_codeview_record)
	(_bfd_XXi_write_codeview_record): Add functions for reading and
	writing debugdir and codeview records.
	* libpei.h (_bfd_XXi_swap_debugdir_in)
	(_bfd_XXi_swap_debugdir_out, _bfd_XXi_write_codeview_record):
	Add prototypes and macros.

include/coff/ChangeLog:

2014-01-20  Jon TURNEY  <jon.turney@dronecode.org.uk>

	* pe.h (external_IMAGE_DEBUG_DIRECTORY, _CV_INFO_PDB70)
	(_CV_INFO_PDB20): Add structures and constants for debug directory
	and codeview records.
	* internal.h (internal_IMAGE_DEBUG_DIRECTORY, CODEVIEW_INFO):
	Add structures and constants for internal representation of debug
	directory and codeview records.

Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
---
 bfd/libpei.h            | 12 ++++++
 bfd/peXXigen.c          | 99 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/coff/internal.h | 37 ++++++++++++++++++
 include/coff/pe.h       | 37 ++++++++++++++++++
 4 files changed, 185 insertions(+)

diff --git a/bfd/libpei.h b/bfd/libpei.h
index 40026ef..0913184 100644
--- a/bfd/libpei.h
+++ b/bfd/libpei.h
@@ -236,6 +236,9 @@
 #define _bfd_XXi_swap_scnhdr_out			_bfd_pex64i_swap_scnhdr_out
 #define _bfd_XXi_swap_sym_in				_bfd_pex64i_swap_sym_in
 #define _bfd_XXi_swap_sym_out				_bfd_pex64i_swap_sym_out
+#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
 
 #elif defined COFF_WITH_pep
 
@@ -267,6 +270,9 @@
 #define _bfd_XXi_swap_scnhdr_out			_bfd_pepi_swap_scnhdr_out
 #define _bfd_XXi_swap_sym_in				_bfd_pepi_swap_sym_in
 #define _bfd_XXi_swap_sym_out				_bfd_pepi_swap_sym_out
+#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
 
 #else /* !COFF_WITH_pep */
 
@@ -298,6 +304,9 @@
 #define _bfd_XXi_swap_scnhdr_out			_bfd_pei_swap_scnhdr_out
 #define _bfd_XXi_swap_sym_in				_bfd_pei_swap_sym_in
 #define _bfd_XXi_swap_sym_out				_bfd_pei_swap_sym_out
+#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
 
 #endif /* !COFF_WITH_pep */
 
@@ -340,6 +349,9 @@ bfd_boolean _bfd_XX_print_private_bfd_data_common (bfd *, void *);
 bfd_boolean _bfd_XX_bfd_copy_private_bfd_data_common (bfd *, bfd *);
 void        _bfd_XX_get_symbol_info (bfd *, asymbol *, symbol_info *);
 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 * abfd, file_ptr where, CODEVIEW_INFO *cvinfo);
 
 /* 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/bfd/peXXigen.c b/bfd/peXXigen.c
index 1da5a9a..270aa86 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -1031,6 +1031,105 @@ _bfd_XXi_swap_scnhdr_out (bfd * abfd, void * in, void * out)
   return ret;
 }
 
+void
+_bfd_XXi_swap_debugdir_in (bfd * abfd, void * ext1, void * in1)
+{
+  struct external_IMAGE_DEBUG_DIRECTORY *ext = (struct external_IMAGE_DEBUG_DIRECTORY *) ext1;
+  struct internal_IMAGE_DEBUG_DIRECTORY *in = (struct internal_IMAGE_DEBUG_DIRECTORY *) in1;
+
+  in->Characteristics = H_GET_32(abfd, ext->Characteristics);
+  in->TimeDateStamp = H_GET_32(abfd, ext->TimeDateStamp);
+  in->MajorVersion = H_GET_16(abfd, ext->MajorVersion);
+  in->MinorVersion = H_GET_16(abfd, ext->MinorVersion);
+  in->Type = H_GET_32(abfd, ext->Type);
+  in->SizeOfData = H_GET_32(abfd, ext->SizeOfData);
+  in->AddressOfRawData = H_GET_32(abfd, ext->AddressOfRawData);
+  in->PointerToRawData = H_GET_32(abfd, ext->PointerToRawData);
+}
+
+unsigned int
+_bfd_XXi_swap_debugdir_out (bfd * abfd, void * inp, void * extp)
+{
+  struct external_IMAGE_DEBUG_DIRECTORY *ext = (struct external_IMAGE_DEBUG_DIRECTORY *) extp;
+  struct internal_IMAGE_DEBUG_DIRECTORY *in = (struct internal_IMAGE_DEBUG_DIRECTORY *) inp;
+
+  H_PUT_32(abfd, in->Characteristics, ext->Characteristics);
+  H_PUT_32(abfd, in->TimeDateStamp, ext->TimeDateStamp);
+  H_PUT_16(abfd, in->MajorVersion, ext->MajorVersion);
+  H_PUT_16(abfd, in->MinorVersion, ext->MinorVersion);
+  H_PUT_32(abfd, in->Type, ext->Type);
+  H_PUT_32(abfd, in->SizeOfData, ext->SizeOfData);
+  H_PUT_32(abfd, in->AddressOfRawData, ext->AddressOfRawData);
+  H_PUT_32(abfd, in->PointerToRawData, ext->PointerToRawData);
+
+  return sizeof(struct external_IMAGE_DEBUG_DIRECTORY);
+}
+
+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)
+    return NULL;
+
+  if (bfd_bread (buffer, 256, abfd) < 4)
+    return NULL;
+
+  /* ensure null termination of filename */
+  buffer[256] = '\0';
+
+  cvinfo->CVSignature = H_GET_32(abfd, buffer);
+  cvinfo->Age = 0;
+
+  if ((cvinfo->CVSignature == CVINFO_PDB70_CVSIGNATURE)
+      && (length > sizeof(CV_INFO_PDB70)))
+    {
+      CV_INFO_PDB70 *cvinfo70 = (CV_INFO_PDB70 *)(buffer);
+
+      cvinfo->Age = H_GET_32(abfd, cvinfo70->Age);
+      memcpy(cvinfo->Signature, cvinfo70->Signature, CV_INFO_SIGNATURE_LENGTH);
+      cvinfo->SignatureLength = CV_INFO_SIGNATURE_LENGTH;
+      // cvinfo->PdbFileName = cvinfo70->PdbFileName;
+
+      return cvinfo;
+    }
+  else if ((cvinfo->CVSignature == CVINFO_PDB20_CVSIGNATURE)
+           && (length > sizeof(CV_INFO_PDB20)))
+    {
+      CV_INFO_PDB20 *cvinfo20 = (CV_INFO_PDB20 *)(buffer);
+      cvinfo->Age = H_GET_32(abfd, cvinfo20->Age);
+      memcpy(cvinfo->Signature, cvinfo20->Signature, 4);
+      cvinfo->SignatureLength = 4;
+      // cvinfo->PdbFileName = cvinfo20->PdbFileName;
+
+      return cvinfo;
+    }
+
+  return NULL;
+}
+
+unsigned int
+_bfd_XXi_write_codeview_record(bfd * abfd, file_ptr where, CODEVIEW_INFO *cvinfo)
+{
+  unsigned int size = sizeof(CV_INFO_PDB70) + 1;
+  char buffer[size];
+
+  if (bfd_seek (abfd, where, SEEK_SET) != 0)
+    return 0;
+
+  CV_INFO_PDB70 *cvinfo70 = (CV_INFO_PDB70 *)buffer;
+  H_PUT_32(abfd, CVINFO_PDB70_CVSIGNATURE, cvinfo70->CvSignature);
+  memcpy(&(cvinfo70->Signature), cvinfo->Signature, CV_INFO_SIGNATURE_LENGTH);
+  H_PUT_32(abfd, cvinfo->Age, cvinfo70->Age);
+  cvinfo70->PdbFileName[0] = '\0';
+
+  if (bfd_bwrite (buffer, size, abfd) != size)
+    return 0;
+
+  return size;
+}
+
 static char * dir_names[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] =
 {
   N_("Export Directory [.edata (or where ever we found it)]"),
diff --git a/include/coff/internal.h b/include/coff/internal.h
index 8b84324..ed0bff8 100644
--- a/include/coff/internal.h
+++ b/include/coff/internal.h
@@ -133,6 +133,43 @@ typedef struct _IMAGE_DATA_DIRECTORY
 /* DataDirectory[15] is currently reserved, so no define. */
 #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES  16
 
+/* Extra structure used in debug directory */
+struct internal_IMAGE_DEBUG_DIRECTORY {
+  unsigned long  Characteristics;
+  unsigned long  TimeDateStamp;
+  unsigned short MajorVersion;
+  unsigned short MinorVersion;
+  unsigned long  Type;
+  unsigned long  SizeOfData;
+  unsigned long  AddressOfRawData;
+  unsigned long  PointerToRawData;
+};
+
+#define PE_IMAGE_DEBUG_TYPE_UNKNOWN          0
+#define PE_IMAGE_DEBUG_TYPE_COFF             1
+#define PE_IMAGE_DEBUG_TYPE_CODEVIEW         2
+#define PE_IMAGE_DEBUG_TYPE_FPO              3
+#define PE_IMAGE_DEBUG_TYPE_MISC             4
+#define PE_IMAGE_DEBUG_TYPE_EXCEPTION        5
+#define PE_IMAGE_DEBUG_TYPE_FIXUP            6
+#define PE_IMAGE_DEBUG_TYPE_OMAP_TO_SRC      7
+#define PE_IMAGE_DEBUG_TYPE_OMAP_FROM_SRC    8
+#define PE_IMAGE_DEBUG_TYPE_BORLAND          9
+#define PE_IMAGE_DEBUG_TYPE_RESERVED10       10
+#define PE_IMAGE_DEBUG_TYPE_CLSID            11
+
+/* Extra structure for a codeview debug record */
+#define CV_INFO_SIGNATURE_LENGTH 16
+
+typedef struct _CODEVIEW_INFO
+{
+  unsigned long CVSignature;
+  char          Signature[CV_INFO_SIGNATURE_LENGTH];
+  unsigned int  SignatureLength;
+  unsigned long Age;
+  // char PdbFileName[];
+} CODEVIEW_INFO;
+
 /* Default image base for NT.  */
 #define NT_EXE_IMAGE_BASE 0x400000
 #define NT_DLL_IMAGE_BASE 0x10000000
diff --git a/include/coff/pe.h b/include/coff/pe.h
index 5e2b37e..c931ea8 100644
--- a/include/coff/pe.h
+++ b/include/coff/pe.h
@@ -506,4 +506,41 @@ struct external_pex64_scope_entry
   (PEX64_OFFSET_TO_SCOPE_COUNT(COUNTOFUNWINDCODES) + \
    PEX64_SCOPE_ENTRY_SIZE * (IDX))
 
+/* Extra structure used in debug directory */
+struct external_IMAGE_DEBUG_DIRECTORY {
+  char Characteristics[4];
+  char TimeDateStamp[4];
+  char MajorVersion[2];
+  char MinorVersion[2];
+  char Type[4];
+  char SizeOfData[4];
+  char AddressOfRawData[4];
+  char PointerToRawData[4];
+};
+
+/* Extra structures used in codeview debug record */
+/* This is not part of the PE specification */
+
+#define CVINFO_PDB70_CVSIGNATURE 0x53445352 // "RSDS"
+#define CVINFO_PDB20_CVSIGNATURE 0x3031424e // "NB10"
+#define CVINFO_CV50_CVSIGNATURE  0x3131424e // "NB11"
+#define CVINFO_CV41_CVSIGNATURE  0x3930424e // âNB09"
+
+typedef struct _CV_INFO_PDB70
+{
+  char CvSignature[4];
+  char Signature[16];
+  char Age[4];
+  char PdbFileName[];
+} CV_INFO_PDB70;
+
+typedef struct _CV_INFO_PDB20
+{
+  char CvHeader[4];
+  char Offset[4];
+  char Signature[4];
+  char Age[4];
+  char PdbFileName[];
+} CV_INFO_PDB20;
+
 #endif /* _PE_H */
-- 
1.8.3.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]