getsentry / pdb

A parser for Microsoft PDB (Program Database) debugging information
https://docs.rs/pdb/
Apache License 2.0
367 stars 68 forks source link

ImageSectionHeader virtual_size is wrongly named physical_address #121

Closed mstange closed 2 years ago

mstange commented 2 years ago

ImageSectionHeader currently has a physical_address member. This appears to be the wrong name for that field. Instead, that field should be called virtual_size.

Compare the following outputs:

Microsoft (R) Debugging Information Dumper  Version 14.00.23611
Copyright (C) Microsoft Corporation.  All rights reserved.

[...]

SECTION HEADER #1
.textbss name
   10000 virtual size
    1000 virtual address
       0 size of raw data
       0 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
E00000A0 flags
         Code
         Uninitialized Data
         (no align specified)
         Execute Read Write

SECTION HEADER #2
   .text name
   1C572 virtual size
   11000 virtual address
   1C600 size of raw data
     400 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
60000020 flags
         Code
         (no align specified)
         Execute Read

SECTION HEADER #3
  .rdata name
    4C64 virtual size
   2E000 virtual address
    4E00 size of raw data
   1CA00 file pointer to raw data
       0 file pointer to relocation table
       0 file pointer to line numbers
       0 number of relocations
       0 number of line numbers
40000040 flags
         Initialized Data
         (no align specified)
         Read Only
&sections = [
    ImageSectionHeader {
        name(): ".textbss",
        physical_address: 0x10000,
        virtual_address: 0x1000,
        size_of_raw_data: 0,
        pointer_to_raw_data: 0x0,
        pointer_to_relocations: 0x0,
        pointer_to_line_numbers: 0x0,
        number_of_relocations: 0,
        number_of_line_numbers: 0,
        characteristics: 0xe00000a0,
    },
    ImageSectionHeader {
        name(): ".text",
        physical_address: 0x1c572,
        virtual_address: 0x11000,
        size_of_raw_data: 116224,
        pointer_to_raw_data: 0x400,
        pointer_to_relocations: 0x0,
        pointer_to_line_numbers: 0x0,
        number_of_relocations: 0,
        number_of_line_numbers: 0,
        characteristics: 0x60000020,
    },
    ImageSectionHeader {
        name(): ".rdata",
        physical_address: 0x4c64,
        virtual_address: 0x2e000,
        size_of_raw_data: 19968,
        pointer_to_raw_data: 0x1ca00,
        pointer_to_relocations: 0x0,
        pointer_to_line_numbers: 0x0,
        number_of_relocations: 0,
        number_of_line_numbers: 0,
        characteristics: 0x40000040,
    },
jan-auer commented 2 years ago

Thanks, great catch. In IMAGE_SECTION_HEADER, it's defined as a union of virtual size and physical address, but pdbdump and other tools have it hardcoded to "virtual size". The reason for this is hinted at in this stackexchange answer:

This field has different meanings, in EXEs or OBJs. In an EXE, it holds the actual size of the code or data. This is the size before rounding up to the nearest file alignment multiple. The
SizeOfRawData field (seems a bit of a misnomer) later on in the
structure holds the rounded up value. The Borland linker reverses
the meaning of these two fields and appears to be correct. For OBJ
files, this field indicates the physical address of the section. The
first section starts at address 0. To find the physical address in
an OBJ file of the next section, add the SizeOfRawData value to the
physical address of the current section.