bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Objdump uses improper method of determining size of $DATA$ sections


From: Steven Konopa
Subject: Objdump uses improper method of determining size of $DATA$ sections
Date: Tue, 3 Oct 2000 16:27:20 -0400 (EDT)

Hello,

For the HP-UX SOM object format, objdump was using an improper method of
determining the size of the $DATA$ sections in object files.  According to the
32-bit PA-RISC Runtime Architecture Document (which can be downloaded in PDF 
format from the HP Developer's Resources website at the following URL:
    http://devresource.hp.com/devresource/Docs/DocLib_Refs.html#archrefs )
on page 55, the fields file_loc_init_value, initialization_length, and
subspace_length are used as follows:

file_loc_init_value:
    
    If initialization_length field is non-zero, the subspace is initialized, 
    and this field contains a byte offset relative to the first byte of the SOM
    header.  In other words, it is a file location of the initialization image.
    
    If initializtion_length is zero then this field contains a 32 bit quantity
    which is used as an initialization pattern for the enitre subspace.  The
    total length of the subspace is defined by the subspace_length field.  This
    is how BSS subspaces are represented.
    
initialization_length:

    This field contains the size in bytes of the initialization area in the
    file.  If this field is zero then the value contained in the field
    file_loc_init_value is used as the initialization pattern for the subspace.
    
    The initialization_length field can also be non-zero, but less than the
    subspace_length field.  In this case, the length of the initialization
    image is given by initialization_length, and the remainder of the subspace,
    up to subspace_length, is initialized with zeros.
    
subspace_length:

    This is the length in bytes of a subspace.  A total length of a space
    will be kept, and if the addition of all subspace_length fields in a space
    is greater than 2^32-1 then it is an error.
    
Thus, it was necessary to pick-up and store the initialization_length field and
check if it contained a non-zero value.  If it did, up to the initialization 
length of the subspace (section) would be dumped from the object file, otherwise
up to the suspace_length would be dumped.  There have been several instances of
object files that only stored up to the initialization_length of the DATA
subspace in the file (but when linked, the entire subspace_length was in the
executable file, with zeros filling out the rest of the subspace - just as 
described in the PA-RISC architecture document).

These changes, which I have put in my own copy will temporarily correct the
problem until a much better implementation can be developed.

In file binutils-2.10/bfd/bfd-in2.h, make the following changes:

At about line 318, insert the following:

#define bfd_section_init_size(bfd, ptr) ((ptr)->initialization_size)

so what used to be:

#define bfd_section_size(bfd, ptr) (bfd_get_section_size_before_reloc(ptr))
#define bfd_section_vma(bfd, ptr) ((ptr)->vma)

will now look like:

#define bfd_section_size(bfd, ptr) (bfd_get_section_size_before_reloc(ptr))
#define bfd_section_init_size(bfd, ptr) ((ptr)->initialization_size)
#define bfd_section_vma(bfd, ptr) ((ptr)->vma)


In the structure sec, which is typedefed to be asection:

At about line 1155, insert the following:


         /* Some back-ends keep a seperate length for the actual initialized
            data in the data section of object files */

   bfd_size_type initialization_size;

so what used to be:

         /* File position of line data       */

   file_ptr line_filepos;

         /* Pointer to data for applications */

   PTR userdata;

will now look like:

         /* File position of line data       */

   file_ptr line_filepos;

         /* Some back-ends keep a seperate length for the actual initialized
            data in the data section of object files */

   bfd_size_type initialization_size;

         /* Pointer to data for applications */

   PTR userdata;

Save changes back to the file binutils-2.10/bfd/bfd-in2.h


In file binutils-2.10/bfd/section.c, make the following changes:

In the large comment that mirrors the layout of the structure sec, which is
typedefed to be asection, at line 434, insert the following:

.        {* Some back-ends keep a seperate length for the actual initialized
.           data in the data section of object files *}
.
.   bfd_size_type initialization_size;
.

so that what used to be:

.        {* File position of line data       *}
.
.   file_ptr line_filepos;
.
.        {* Pointer to data for applications *}
.
.   PTR userdata;

will now look like:

.        {* File position of line data       *}
.
.   file_ptr line_filepos;
.
.        {* Some back-ends keep a seperate length for the actual initialized
.           data in the data section of object files *}
.
.   bfd_size_type initialization_size;
.
.        {* Pointer to data for applications *}
.
.   PTR userdata;


In the define STD_SECTION:

At line 553, change the following:

    /* userdata, contents, lineno, lineno_count */                            \
       0,        0,        0,      0,                                     \

to 

    /* init_size, userdata, contents, lineno, lineno_count */     \
       0,         0,        0,        0,      0,                  \

In the function bfd_make_section_anyway:

At about line 706, insert the following line:

  newsect->initialization_size = 0;

so that what used to be:

  newsect->line_filepos = 0;
  newsect->owner = abfd;

will now look like:

  newsect->line_filepos = 0;
  newsect->initialization_size = 0;
  newsect->owner = abfd;

Save the changes back to the file binutils-2.10/bfd/section.c


In file binutils-2.10/bfd/som.c, make the following changes:


In function setup_sections:

At line 2059, insert the following line:

      subspace_asect->initialization_size = subspace.initialization_length;

so what used to be:

          subspace_asect->_raw_size = subspace.subspace_length;
          subspace_asect->filepos = subspace.file_loc_init_value;

will now look like:

          subspace_asect->_raw_size = subspace.subspace_length;
      subspace_asect->initialization_size = subspace.initialization_length;
          subspace_asect->filepos = subspace.file_loc_init_value;


At line 2072, change:

      if (!save_subspace.file_loc_init_value)
        {
          space_asect->_cooked_size = 0;
          space_asect->_raw_size = 0;
        }

To:

      if (!save_subspace.file_loc_init_value)
        {
          space_asect->_cooked_size = 0;
          space_asect->_raw_size = 0;
      space_asect->initialization_size = 0;
        }

Save the changes back to the file binutils-2.10/bfd/som.c


In file binutils-2.10/binutils/objdump.c, make the following changes:

In function dissassemble_data:

At line 1700, change:

      datasize = bfd_get_section_size_before_reloc (section);
      if (datasize == 0)
        continue;

To:

      /* get the size of the section to disassemble */
      if (bfd_section_init_size (abfd, section) == 0)
          datasize = bfd_get_section_size_before_reloc (section);
      else
          datasize = bfd_section_init_size (abfd, section);

      /* If the size of the section is zero, then there is nothing to
         disassemble, so continue to the next section (if there is one) */
      if (datasize == 0)
        continue;


In function dump_data:

At line 2269, change:

              if (bfd_section_size (abfd, section) == 0)
                continue;
              data = (bfd_byte *) xmalloc ((size_t) bfd_section_size (abfd, 
section));
              datasize = bfd_section_size (abfd, section);


              bfd_get_section_contents (abfd, section, (PTR) data, 0, 
bfd_section_size (abfd, section));
To:

          /* if there is a size set for the initialization length, then use it
             otherwise, use the full section size */
          if (bfd_section_init_size (abfd, section) == 0)
                  datasize = bfd_section_size (abfd, section);
          else
              datasize = bfd_section_init_size (abfd, section);

              if (datasize == 0)
                continue;
              data = (bfd_byte *) xmalloc ((size_t) datasize );


              bfd_get_section_contents (abfd, section, (PTR) data, 0, datasize);


At line 2282, change:

              if (stop_address == (bfd_vma) -1)
                stop = bfd_section_size (abfd, section);

To:

              if (stop_address == (bfd_vma) -1)
                stop = datasize;


At line 2290, change:

                  if (stop > bfd_section_size (abfd, section) / opb)
                    stop = bfd_section_size (abfd, section) / opb;

To:

                  if (stop > datasize / opb)
                    stop = datasize / opb;

Save the changes back to file binutils-2.10/binutils/objdump.c

These are all of the changes necessary to properly determine the size of the
$DATA$ sections in SOM formatted object files.

Thanks

Steven Konopa
CSC
(540) 663-9251
address@hidden




reply via email to

[Prev in Thread] Current Thread [Next in Thread]