+static unsigned int * debug_line_pointer_sizes = NULL;
+static unsigned int num_debug_line_pointer_sizes = 0;
+
+/* Locate and scan the .debug_info section in the file and record the pointer
+ sizes for the compilation units in it. Usually an executable will have
+ just one pointer size, but this is not guaranteed, and so we try not to
+ make any assumptions. Returns zero upon failure, or the number of
+ compilation units upon success. */
+
+static unsigned int
+get_debug_line_pointer_sizes (FILE * file)
+{
+ Elf_Internal_Shdr * section;
+ unsigned char * start;
+ unsigned char * end;
+ unsigned char * begin;
+ unsigned long length;
+ unsigned int num_units;
+ unsigned int unit;
+
+ section = find_section (".debug_info");
+ if (section == NULL)
+ return 0;
+
+ length = section->sh_size;
+ start = get_data (NULL, file, section->sh_offset, section->sh_size,
+ _("extracting pointer sizes from .debug_info section"));
+ if (start == NULL)
+ return 0;
+
+ end = start + section->sh_size;
+ /* First scan the section to get the number of comp units. */
+ for (begin = start, num_units = 0; begin < end; num_units++)
+ {
+ /* Read the first 4 bytes. For a 32-bit DWARF section, this will
+ be the length. For a 64-bit DWARF section, it'll be the escape
+ code 0xffffffff followed by an 8 byte length. */
+ length = byte_get (begin, 4);
+
+ if (length == 0xffffffff)
+ {
+ length = byte_get (begin + 4, 8);
+ begin += length + 12;
+ }
+ else
+ begin += length + 4;
+ }
+
+ if (num_units == 0)
+ {
+ error (_("No comp units in .debug_info section ?"));
+ free (start);
+ return 0;
+ }
+
+ /* Then allocate an array to hold the pointer sizes. */
+ debug_line_pointer_sizes = malloc (num_units * sizeof * debug_line_pointer_sizes);
+ if (debug_line_pointer_sizes == NULL)
+ {
+ error (_("Not enough memory for a pointer size array of %u entries"),
+ num_units);
+ free (start);
+ return 0;
+ }
+
+ /* Populate the array. */
+ for (begin = start, unit = 0; begin < end; unit++)
+ {
+ length = byte_get (begin, 4);
+ if (length == 0xffffffff)
+ {
+ /* For 64-bit DWARF, the 1-byte address_size field is 22 bytes
+ from the start of the section. This is computed as follows:
+
+ unit_length: 12 bytes
+ version: 2 bytes
+ debug_abbrev_offset: 8 bytes
+ -----------------------------
+ Total: 22 bytes */
+
+ debug_line_pointer_sizes [unit] = byte_get (begin + 22, 1);
+ length = byte_get (begin + 4, 8);
+ begin += length + 12;
+ }
+ else
+ {
+ /* For 32-bit DWARF, the 1-byte address_size field is 10 bytes from
+ the start of the section:
+
+ unit_length: 4 bytes
+ version: 2 bytes
+ debug_abbrev_offset: 4 bytes
+ -----------------------------
+ Total: 10 bytes */
+
+ debug_line_pointer_sizes [unit] = byte_get (begin + 10, 1);
+ begin += length + 4;
+ }
+ }
+
+ free (start);
+ num_debug_line_pointer_sizes = num_units;
+ return num_units;
+}