X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2FpeXXigen.c;h=c33c495a0f6a4e4ac741d0b77d7a50a7e1c721a1;hb=708a2ffff5cc2d280968a6b28268d8276d391bb4;hp=ab0da7f53284be96a260fe608f4fda46bed168a2;hpb=ec9bd0a22dd42327ae9943937a96f1e865fb5d46;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c index ab0da7f532..c33c495a0f 100644 --- a/bfd/peXXigen.c +++ b/bfd/peXXigen.c @@ -1,5 +1,5 @@ /* Support for the generic parts of PE/PEI; the common executable parts. - Copyright (C) 1995-2019 Free Software Foundation, Inc. + Copyright (C) 1995-2020 Free Software Foundation, Inc. Written by Cygnus Solutions. This file is part of BFD, the Binary File Descriptor library. @@ -177,25 +177,25 @@ _bfd_XXi_swap_sym_in (bfd * abfd, void * ext1, void * in1) int unused_section_number = 0; asection *sec; flagword flags; + size_t name_len; + char *sec_name; for (sec = abfd->sections; sec; sec = sec->next) if (unused_section_number <= sec->target_index) unused_section_number = sec->target_index + 1; - if (name == namebuf) + name_len = strlen (name) + 1; + sec_name = bfd_alloc (abfd, name_len); + if (sec_name == NULL) { - name = (const char *) bfd_alloc (abfd, strlen (namebuf) + 1); - if (name == NULL) - { - _bfd_error_handler (_("%pB: out of memory creating name for empty section"), - abfd); - return; - } - strcpy ((char *) name, namebuf); + _bfd_error_handler (_("%pB: out of memory creating name " + "for empty section"), abfd); + return; } + memcpy (sec_name, name, name_len); flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD; - sec = bfd_make_section_anyway_with_flags (abfd, name, flags); + sec = bfd_make_section_anyway_with_flags (abfd, sec_name, flags); if (sec == NULL) { _bfd_error_handler (_("%pB: unable to create fake empty section"), @@ -723,6 +723,9 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out) { int rounded = FA (sec->size); + if (rounded == 0) + continue; + /* The first non-zero section filepos is the header size. Sections without contents will have a filepos of 0. */ if (hsize == 0) @@ -863,22 +866,9 @@ _bfd_XXi_only_swap_filehdr_out (bfd * abfd, void * in, void * out) /* This next collection of data are mostly just characters. It appears to be constant within the headers put on NT exes. */ - filehdr_in->pe.dos_message[0] = 0x0eba1f0e; - filehdr_in->pe.dos_message[1] = 0xcd09b400; - filehdr_in->pe.dos_message[2] = 0x4c01b821; - filehdr_in->pe.dos_message[3] = 0x685421cd; - filehdr_in->pe.dos_message[4] = 0x70207369; - filehdr_in->pe.dos_message[5] = 0x72676f72; - filehdr_in->pe.dos_message[6] = 0x63206d61; - filehdr_in->pe.dos_message[7] = 0x6f6e6e61; - filehdr_in->pe.dos_message[8] = 0x65622074; - filehdr_in->pe.dos_message[9] = 0x6e757220; - filehdr_in->pe.dos_message[10] = 0x206e6920; - filehdr_in->pe.dos_message[11] = 0x20534f44; - filehdr_in->pe.dos_message[12] = 0x65646f6d; - filehdr_in->pe.dos_message[13] = 0x0a0d0d2e; - filehdr_in->pe.dos_message[14] = 0x24; - filehdr_in->pe.dos_message[15] = 0x0; + memcpy (filehdr_in->pe.dos_message, pe_data (abfd)->dos_message, + sizeof (filehdr_in->pe.dos_message)); + filehdr_in->pe.nt_signature = IMAGE_NT_SIGNATURE; H_PUT_16 (abfd, filehdr_in->f_magic, filehdr_out->f_magic); @@ -886,10 +876,10 @@ _bfd_XXi_only_swap_filehdr_out (bfd * abfd, void * in, void * out) /* Use a real timestamp by default, unless the no-insert-timestamp option was chosen. */ - if ((pe_data (abfd)->insert_timestamp)) + if ((pe_data (abfd)->timestamp) == -1) H_PUT_32 (abfd, time (0), filehdr_out->f_timdat); else - H_PUT_32 (abfd, 0, filehdr_out->f_timdat); + H_PUT_32 (abfd, pe_data (abfd)->timestamp, filehdr_out->f_timdat); PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr, filehdr_out->f_symptr); @@ -1353,8 +1343,7 @@ pe_print_idata (bfd * abfd, void * vfile) if (!bfd_malloc_and_get_section (abfd, rel_section, &data)) { - if (data != NULL) - free (data); + free (data); return FALSE; } @@ -1362,8 +1351,7 @@ pe_print_idata (bfd * abfd, void * vfile) if (offset >= rel_section->size || offset + 8 > rel_section->size) { - if (data != NULL) - free (data); + free (data); return FALSE; } @@ -1378,8 +1366,7 @@ pe_print_idata (bfd * abfd, void * vfile) /* xgettext:c-format */ _("\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"), start_address, loadable_toc_address, toc_address); - if (data != NULL) - free (data); + free (data); } else { @@ -1399,8 +1386,7 @@ pe_print_idata (bfd * abfd, void * vfile) /* Read the whole section. Some of the fields might be before dataoff. */ if (!bfd_malloc_and_get_section (abfd, section, &data)) { - if (data != NULL) - free (data); + free (data); return FALSE; } @@ -1945,8 +1931,7 @@ pe_print_pdata (bfd * abfd, void * vfile) if (! bfd_malloc_and_get_section (abfd, section, &data)) { - if (data != NULL) - free (data); + free (data); return FALSE; } @@ -2129,8 +2114,7 @@ _bfd_XX_print_ce_compressed_pdata (bfd * abfd, void * vfile) if (! bfd_malloc_and_get_section (abfd, section, &data)) { - if (data != NULL) - free (data); + free (data); return FALSE; } @@ -2245,8 +2229,7 @@ pe_print_reloc (bfd * abfd, void * vfile) if (! bfd_malloc_and_get_section (abfd, section, &data)) { - if (data != NULL) - free (data); + free (data); return FALSE; } @@ -2553,8 +2536,7 @@ rsrc_print_section (bfd * abfd, void * vfile) if (! bfd_malloc_and_get_section (abfd, section, & data)) { - if (data != NULL) - free (data); + free (data); return FALSE; } @@ -2613,7 +2595,7 @@ rsrc_print_section (bfd * abfd, void * vfile) return TRUE; } -#define IMAGE_NUMBEROF_DEBUG_TYPES 12 +#define IMAGE_NUMBEROF_DEBUG_TYPES 17 static char * debug_type_names[IMAGE_NUMBEROF_DEBUG_TYPES] = { @@ -2629,6 +2611,11 @@ static char * debug_type_names[IMAGE_NUMBEROF_DEBUG_TYPES] = "Borland", "Reserved", "CLSID", + "Feature", + "CoffGrp", + "ILTCG", + "MPX", + "Repro", }; static bfd_boolean @@ -2640,7 +2627,7 @@ pe_print_debugdata (bfd * abfd, void * vfile) asection *section; bfd_byte *data = 0; bfd_size_type dataoff; - unsigned int i; + unsigned int i, j; bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress; bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size; @@ -2693,8 +2680,7 @@ pe_print_debugdata (bfd * abfd, void * vfile) /* Read the whole section. */ if (!bfd_malloc_and_get_section (abfd, section, &data)) { - if (data != NULL) - free (data); + free (data); return FALSE; } @@ -2732,8 +2718,8 @@ pe_print_debugdata (bfd * abfd, void * vfile) idd.SizeOfData, cvinfo)) continue; - for (i = 0; i < cvinfo->SignatureLength; i++) - sprintf (&signature[i*2], "%02x", cvinfo->Signature[i] & 0xff); + for (j = 0; j < cvinfo->SignatureLength; j++) + sprintf (&signature[j*2], "%02x", cvinfo->Signature[j] & 0xff); /* xgettext:c-format */ fprintf (file, _("(format %c%c%c%c signature %s age %ld)\n"), @@ -2742,6 +2728,8 @@ pe_print_debugdata (bfd * abfd, void * vfile) } } + free(data); + if (size % sizeof (struct external_IMAGE_DEBUG_DIRECTORY) != 0) fprintf (file, _("The debug directory size is not a multiple of the debug directory entry size\n")); @@ -2749,6 +2737,70 @@ pe_print_debugdata (bfd * abfd, void * vfile) return TRUE; } +static bfd_boolean +pe_is_repro (bfd * abfd) +{ + pe_data_type *pe = pe_data (abfd); + struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr; + asection *section; + bfd_byte *data = 0; + bfd_size_type dataoff; + unsigned int i; + bfd_boolean res = FALSE; + + bfd_vma addr = extra->DataDirectory[PE_DEBUG_DATA].VirtualAddress; + bfd_size_type size = extra->DataDirectory[PE_DEBUG_DATA].Size; + + if (size == 0) + return FALSE; + + addr += extra->ImageBase; + for (section = abfd->sections; section != NULL; section = section->next) + { + if ((addr >= section->vma) && (addr < (section->vma + section->size))) + break; + } + + if ((section == NULL) + || (!(section->flags & SEC_HAS_CONTENTS)) + || (section->size < size)) + { + return FALSE; + } + + dataoff = addr - section->vma; + + if (size > (section->size - dataoff)) + { + return FALSE; + } + + if (!bfd_malloc_and_get_section (abfd, section, &data)) + { + free (data); + return FALSE; + } + + for (i = 0; i < size / sizeof (struct external_IMAGE_DEBUG_DIRECTORY); i++) + { + struct external_IMAGE_DEBUG_DIRECTORY *ext + = &((struct external_IMAGE_DEBUG_DIRECTORY *)(data + dataoff))[i]; + struct internal_IMAGE_DEBUG_DIRECTORY idd; + + _bfd_XXi_swap_debugdir_in (abfd, ext, &idd); + + if (idd.Type == PE_IMAGE_DEBUG_TYPE_REPRO) + { + res = TRUE; + break; + } + } + + free(data); + + return res; +} + /* Print out the program headers. */ bfd_boolean @@ -2780,11 +2832,21 @@ _bfd_XX_print_private_bfd_data_common (bfd * abfd, void * vfile) PF (IMAGE_FILE_BYTES_REVERSED_HI, "big endian"); #undef PF - /* ctime implies '\n'. */ - { - time_t t = pe->coff.timestamp; - fprintf (file, "\nTime/Date\t\t%s", ctime (&t)); - } + /* + If a PE_IMAGE_DEBUG_TYPE_REPRO entry is present in the debug directory, the + timestamp is to be interpreted as the hash of a reproducible build. + */ + if (pe_is_repro (abfd)) + { + fprintf (file, "\nTime/Date\t\t%08lx", pe->coff.timestamp); + fprintf (file, "\t(This is a reproducible build file hash, not a timestamp)\n"); + } + else + { + /* ctime implies '\n'. */ + time_t t = pe->coff.timestamp; + fprintf (file, "\nTime/Date\t\t%s", ctime (&t)); + } #ifndef IMAGE_NT_OPTIONAL_HDR_MAGIC # define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b @@ -2979,6 +3041,8 @@ _bfd_XX_bfd_copy_private_bfd_data_common (bfd * ibfd, bfd * obfd) && ! (pe_data (ibfd)->real_flags & IMAGE_FILE_RELOCS_STRIPPED)) pe_data (obfd)->dont_strip_reloc = 1; + memcpy (ope->dos_message, ipe->dos_message, sizeof (ope->dos_message)); + /* The file offsets contained in the debug directory need rewriting. */ if (ope->pe_opthdr.DataDirectory[PE_DEBUG_DATA].Size != 0) { @@ -3064,7 +3128,7 @@ _bfd_XX_bfd_copy_private_section_data (bfd *ibfd, { if (coff_section_data (obfd, osec) == NULL) { - bfd_size_type amt = sizeof (struct coff_section_tdata); + size_t amt = sizeof (struct coff_section_tdata); osec->used_by_bfd = bfd_zalloc (obfd, amt); if (osec->used_by_bfd == NULL) return FALSE; @@ -3072,7 +3136,7 @@ _bfd_XX_bfd_copy_private_section_data (bfd *ibfd, if (pei_section_data (obfd, osec) == NULL) { - bfd_size_type amt = sizeof (struct pei_section_tdata); + size_t amt = sizeof (struct pei_section_tdata); coff_section_data (obfd, osec)->tdata = bfd_zalloc (obfd, amt); if (coff_section_data (obfd, osec)->tdata == NULL) return FALSE;