Back to index

cell-binutils  2.17cvs20070401
dwarf.c
Go to the documentation of this file.
00001 /* dwarf.c -- display DWARF contents of a BFD binary file
00002    Copyright 2005, 2006, 2007
00003    Free Software Foundation, Inc.
00004 
00005    This file is part of GNU Binutils.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 2 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program; if not, write to the Free Software
00019    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
00020    02110-1301, USA.  */
00021 
00022 #include <stdio.h>
00023 
00024 #include "dwarf.h"
00025 
00026 #include "bucomm.h"
00027 #include "libiberty.h"
00028 
00029 static int have_frame_base;
00030 static int need_base_address;
00031 
00032 static unsigned int last_pointer_size = 0;
00033 static int warned_about_missing_comp_units = FALSE;
00034 
00035 static unsigned int num_debug_info_entries = 0;
00036 static debug_info *debug_information = NULL;
00037 
00038 dwarf_vma eh_addr_size;
00039 int is_relocatable;
00040 
00041 int do_debug_info;
00042 int do_debug_abbrevs;
00043 int do_debug_lines;
00044 int do_debug_pubnames;
00045 int do_debug_aranges;
00046 int do_debug_ranges;
00047 int do_debug_frames;
00048 int do_debug_frames_interp;
00049 int do_debug_macinfo;
00050 int do_debug_str;
00051 int do_debug_loc;
00052 
00053 dwarf_vma (*byte_get) (unsigned char *, int);
00054 
00055 dwarf_vma
00056 byte_get_little_endian (unsigned char *field, int size)
00057 {
00058   switch (size)
00059     {
00060     case 1:
00061       return *field;
00062 
00063     case 2:
00064       return  ((unsigned int) (field[0]))
00065        |    (((unsigned int) (field[1])) << 8);
00066 
00067     case 4:
00068       return  ((unsigned long) (field[0]))
00069        |    (((unsigned long) (field[1])) << 8)
00070        |    (((unsigned long) (field[2])) << 16)
00071        |    (((unsigned long) (field[3])) << 24);
00072 
00073     case 8:
00074       if (sizeof (dwarf_vma) == 8)
00075        return  ((dwarf_vma) (field[0]))
00076          |    (((dwarf_vma) (field[1])) << 8)
00077          |    (((dwarf_vma) (field[2])) << 16)
00078          |    (((dwarf_vma) (field[3])) << 24)
00079          |    (((dwarf_vma) (field[4])) << 32)
00080          |    (((dwarf_vma) (field[5])) << 40)
00081          |    (((dwarf_vma) (field[6])) << 48)
00082          |    (((dwarf_vma) (field[7])) << 56);
00083       else if (sizeof (dwarf_vma) == 4)
00084        /* We want to extract data from an 8 byte wide field and
00085           place it into a 4 byte wide field.  Since this is a little
00086           endian source we can just use the 4 byte extraction code.  */
00087        return  ((unsigned long) (field[0]))
00088          |    (((unsigned long) (field[1])) << 8)
00089          |    (((unsigned long) (field[2])) << 16)
00090          |    (((unsigned long) (field[3])) << 24);
00091 
00092     default:
00093       error (_("Unhandled data length: %d\n"), size);
00094       abort ();
00095     }
00096 }
00097 
00098 dwarf_vma
00099 byte_get_big_endian (unsigned char *field, int size)
00100 {
00101   switch (size)
00102     {
00103     case 1:
00104       return *field;
00105 
00106     case 2:
00107       return ((unsigned int) (field[1])) | (((int) (field[0])) << 8);
00108 
00109     case 4:
00110       return ((unsigned long) (field[3]))
00111        |   (((unsigned long) (field[2])) << 8)
00112        |   (((unsigned long) (field[1])) << 16)
00113        |   (((unsigned long) (field[0])) << 24);
00114 
00115     case 8:
00116       if (sizeof (dwarf_vma) == 8)
00117        return ((dwarf_vma) (field[7]))
00118          |   (((dwarf_vma) (field[6])) << 8)
00119          |   (((dwarf_vma) (field[5])) << 16)
00120          |   (((dwarf_vma) (field[4])) << 24)
00121          |   (((dwarf_vma) (field[3])) << 32)
00122          |   (((dwarf_vma) (field[2])) << 40)
00123          |   (((dwarf_vma) (field[1])) << 48)
00124          |   (((dwarf_vma) (field[0])) << 56);
00125       else if (sizeof (dwarf_vma) == 4)
00126        {
00127          /* Although we are extracing data from an 8 byte wide field,
00128             we are returning only 4 bytes of data.  */
00129          field += 4;
00130          return ((unsigned long) (field[3]))
00131            |   (((unsigned long) (field[2])) << 8)
00132            |   (((unsigned long) (field[1])) << 16)
00133            |   (((unsigned long) (field[0])) << 24);
00134        }
00135 
00136     default:
00137       error (_("Unhandled data length: %d\n"), size);
00138       abort ();
00139     }
00140 }
00141 
00142 static dwarf_vma
00143 byte_get_signed (unsigned char *field, int size)
00144 {
00145   dwarf_vma x = byte_get (field, size);
00146 
00147   switch (size)
00148     {
00149     case 1:
00150       return (x ^ 0x80) - 0x80;
00151     case 2:
00152       return (x ^ 0x8000) - 0x8000;
00153     case 4:
00154       return (x ^ 0x80000000) - 0x80000000;
00155     case 8:
00156       return x;
00157     default:
00158       abort ();
00159     }
00160 }
00161 
00162 static unsigned long int
00163 read_leb128 (unsigned char *data, unsigned int *length_return, int sign)
00164 {
00165   unsigned long int result = 0;
00166   unsigned int num_read = 0;
00167   unsigned int shift = 0;
00168   unsigned char byte;
00169 
00170   do
00171     {
00172       byte = *data++;
00173       num_read++;
00174 
00175       result |= ((unsigned long int) (byte & 0x7f)) << shift;
00176 
00177       shift += 7;
00178 
00179     }
00180   while (byte & 0x80);
00181 
00182   if (length_return != NULL)
00183     *length_return = num_read;
00184 
00185   if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40))
00186     result |= -1L << shift;
00187 
00188   return result;
00189 }
00190 
00191 typedef struct State_Machine_Registers
00192 {
00193   unsigned long address;
00194   unsigned int file;
00195   unsigned int line;
00196   unsigned int column;
00197   int is_stmt;
00198   int basic_block;
00199   int end_sequence;
00200 /* This variable hold the number of the last entry seen
00201    in the File Table.  */
00202   unsigned int last_file_entry;
00203 } SMR;
00204 
00205 static SMR state_machine_regs;
00206 
00207 static void
00208 reset_state_machine (int is_stmt)
00209 {
00210   state_machine_regs.address = 0;
00211   state_machine_regs.file = 1;
00212   state_machine_regs.line = 1;
00213   state_machine_regs.column = 0;
00214   state_machine_regs.is_stmt = is_stmt;
00215   state_machine_regs.basic_block = 0;
00216   state_machine_regs.end_sequence = 0;
00217   state_machine_regs.last_file_entry = 0;
00218 }
00219 
00220 /* Handled an extend line op.
00221    Returns the number of bytes read.  */
00222 
00223 static int
00224 process_extended_line_op (unsigned char *data, int is_stmt)
00225 {
00226   unsigned char op_code;
00227   unsigned int bytes_read;
00228   unsigned int len;
00229   unsigned char *name;
00230   unsigned long adr;
00231 
00232   len = read_leb128 (data, & bytes_read, 0);
00233   data += bytes_read;
00234 
00235   if (len == 0)
00236     {
00237       warn (_("badly formed extended line op encountered!\n"));
00238       return bytes_read;
00239     }
00240 
00241   len += bytes_read;
00242   op_code = *data++;
00243 
00244   printf (_("  Extended opcode %d: "), op_code);
00245 
00246   switch (op_code)
00247     {
00248     case DW_LNE_end_sequence:
00249       printf (_("End of Sequence\n\n"));
00250       reset_state_machine (is_stmt);
00251       break;
00252 
00253     case DW_LNE_set_address:
00254       adr = byte_get (data, len - bytes_read - 1);
00255       printf (_("set Address to 0x%lx\n"), adr);
00256       state_machine_regs.address = adr;
00257       break;
00258 
00259     case DW_LNE_define_file:
00260       printf (_("  define new File Table entry\n"));
00261       printf (_("  Entry\tDir\tTime\tSize\tName\n"));
00262 
00263       printf (_("   %d\t"), ++state_machine_regs.last_file_entry);
00264       name = data;
00265       data += strlen ((char *) data) + 1;
00266       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
00267       data += bytes_read;
00268       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
00269       data += bytes_read;
00270       printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
00271       printf (_("%s\n\n"), name);
00272       break;
00273 
00274     default:
00275       printf (_("UNKNOWN: length %d\n"), len - bytes_read);
00276       break;
00277     }
00278 
00279   return len;
00280 }
00281 
00282 static const char *
00283 fetch_indirect_string (unsigned long offset)
00284 {
00285   struct dwarf_section *section = &debug_displays [str].section;
00286 
00287   if (section->start == NULL)
00288     return _("<no .debug_str section>");
00289 
00290   /* DWARF sections under Mach-O have non-zero addresses.  */
00291   offset -= section->address;
00292   if (offset > section->size)
00293     {
00294       warn (_("DW_FORM_strp offset too big: %lx\n"), offset);
00295       return _("<offset is too big>");
00296     }
00297 
00298   return (const char *) section->start + offset;
00299 }
00300 
00301 /* FIXME:  There are better and more efficient ways to handle
00302    these structures.  For now though, I just want something that
00303    is simple to implement.  */
00304 typedef struct abbrev_attr
00305 {
00306   unsigned long attribute;
00307   unsigned long form;
00308   struct abbrev_attr *next;
00309 }
00310 abbrev_attr;
00311 
00312 typedef struct abbrev_entry
00313 {
00314   unsigned long entry;
00315   unsigned long tag;
00316   int children;
00317   struct abbrev_attr *first_attr;
00318   struct abbrev_attr *last_attr;
00319   struct abbrev_entry *next;
00320 }
00321 abbrev_entry;
00322 
00323 static abbrev_entry *first_abbrev = NULL;
00324 static abbrev_entry *last_abbrev = NULL;
00325 
00326 static void
00327 free_abbrevs (void)
00328 {
00329   abbrev_entry *abbrev;
00330 
00331   for (abbrev = first_abbrev; abbrev;)
00332     {
00333       abbrev_entry *next = abbrev->next;
00334       abbrev_attr *attr;
00335 
00336       for (attr = abbrev->first_attr; attr;)
00337        {
00338          abbrev_attr *next = attr->next;
00339 
00340          free (attr);
00341          attr = next;
00342        }
00343 
00344       free (abbrev);
00345       abbrev = next;
00346     }
00347 
00348   last_abbrev = first_abbrev = NULL;
00349 }
00350 
00351 static void
00352 add_abbrev (unsigned long number, unsigned long tag, int children)
00353 {
00354   abbrev_entry *entry;
00355 
00356   entry = malloc (sizeof (*entry));
00357 
00358   if (entry == NULL)
00359     /* ugg */
00360     return;
00361 
00362   entry->entry      = number;
00363   entry->tag        = tag;
00364   entry->children   = children;
00365   entry->first_attr = NULL;
00366   entry->last_attr  = NULL;
00367   entry->next       = NULL;
00368 
00369   if (first_abbrev == NULL)
00370     first_abbrev = entry;
00371   else
00372     last_abbrev->next = entry;
00373 
00374   last_abbrev = entry;
00375 }
00376 
00377 static void
00378 add_abbrev_attr (unsigned long attribute, unsigned long form)
00379 {
00380   abbrev_attr *attr;
00381 
00382   attr = malloc (sizeof (*attr));
00383 
00384   if (attr == NULL)
00385     /* ugg */
00386     return;
00387 
00388   attr->attribute = attribute;
00389   attr->form      = form;
00390   attr->next      = NULL;
00391 
00392   if (last_abbrev->first_attr == NULL)
00393     last_abbrev->first_attr = attr;
00394   else
00395     last_abbrev->last_attr->next = attr;
00396 
00397   last_abbrev->last_attr = attr;
00398 }
00399 
00400 /* Processes the (partial) contents of a .debug_abbrev section.
00401    Returns NULL if the end of the section was encountered.
00402    Returns the address after the last byte read if the end of
00403    an abbreviation set was found.  */
00404 
00405 static unsigned char *
00406 process_abbrev_section (unsigned char *start, unsigned char *end)
00407 {
00408   if (first_abbrev != NULL)
00409     return NULL;
00410 
00411   while (start < end)
00412     {
00413       unsigned int bytes_read;
00414       unsigned long entry;
00415       unsigned long tag;
00416       unsigned long attribute;
00417       int children;
00418 
00419       entry = read_leb128 (start, & bytes_read, 0);
00420       start += bytes_read;
00421 
00422       /* A single zero is supposed to end the section according
00423         to the standard.  If there's more, then signal that to
00424         the caller.  */
00425       if (entry == 0)
00426        return start == end ? NULL : start;
00427 
00428       tag = read_leb128 (start, & bytes_read, 0);
00429       start += bytes_read;
00430 
00431       children = *start++;
00432 
00433       add_abbrev (entry, tag, children);
00434 
00435       do
00436        {
00437          unsigned long form;
00438 
00439          attribute = read_leb128 (start, & bytes_read, 0);
00440          start += bytes_read;
00441 
00442          form = read_leb128 (start, & bytes_read, 0);
00443          start += bytes_read;
00444 
00445          if (attribute != 0)
00446            add_abbrev_attr (attribute, form);
00447        }
00448       while (attribute != 0);
00449     }
00450 
00451   return NULL;
00452 }
00453 
00454 static char *
00455 get_TAG_name (unsigned long tag)
00456 {
00457   switch (tag)
00458     {
00459     case DW_TAG_padding:           return "DW_TAG_padding";
00460     case DW_TAG_array_type:        return "DW_TAG_array_type";
00461     case DW_TAG_class_type:        return "DW_TAG_class_type";
00462     case DW_TAG_entry_point:              return "DW_TAG_entry_point";
00463     case DW_TAG_enumeration_type:  return "DW_TAG_enumeration_type";
00464     case DW_TAG_formal_parameter:  return "DW_TAG_formal_parameter";
00465     case DW_TAG_imported_declaration:     return "DW_TAG_imported_declaration";
00466     case DW_TAG_label:                    return "DW_TAG_label";
00467     case DW_TAG_lexical_block:            return "DW_TAG_lexical_block";
00468     case DW_TAG_member:                   return "DW_TAG_member";
00469     case DW_TAG_pointer_type:             return "DW_TAG_pointer_type";
00470     case DW_TAG_reference_type:           return "DW_TAG_reference_type";
00471     case DW_TAG_compile_unit:             return "DW_TAG_compile_unit";
00472     case DW_TAG_string_type:              return "DW_TAG_string_type";
00473     case DW_TAG_structure_type:           return "DW_TAG_structure_type";
00474     case DW_TAG_subroutine_type:   return "DW_TAG_subroutine_type";
00475     case DW_TAG_typedef:           return "DW_TAG_typedef";
00476     case DW_TAG_union_type:        return "DW_TAG_union_type";
00477     case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
00478     case DW_TAG_variant:           return "DW_TAG_variant";
00479     case DW_TAG_common_block:             return "DW_TAG_common_block";
00480     case DW_TAG_common_inclusion:  return "DW_TAG_common_inclusion";
00481     case DW_TAG_inheritance:              return "DW_TAG_inheritance";
00482     case DW_TAG_inlined_subroutine:       return "DW_TAG_inlined_subroutine";
00483     case DW_TAG_module:                   return "DW_TAG_module";
00484     case DW_TAG_ptr_to_member_type:       return "DW_TAG_ptr_to_member_type";
00485     case DW_TAG_set_type:          return "DW_TAG_set_type";
00486     case DW_TAG_subrange_type:            return "DW_TAG_subrange_type";
00487     case DW_TAG_with_stmt:         return "DW_TAG_with_stmt";
00488     case DW_TAG_access_declaration:       return "DW_TAG_access_declaration";
00489     case DW_TAG_base_type:         return "DW_TAG_base_type";
00490     case DW_TAG_catch_block:              return "DW_TAG_catch_block";
00491     case DW_TAG_const_type:        return "DW_TAG_const_type";
00492     case DW_TAG_constant:          return "DW_TAG_constant";
00493     case DW_TAG_enumerator:        return "DW_TAG_enumerator";
00494     case DW_TAG_file_type:         return "DW_TAG_file_type";
00495     case DW_TAG_friend:                   return "DW_TAG_friend";
00496     case DW_TAG_namelist:          return "DW_TAG_namelist";
00497     case DW_TAG_namelist_item:            return "DW_TAG_namelist_item";
00498     case DW_TAG_packed_type:              return "DW_TAG_packed_type";
00499     case DW_TAG_subprogram:        return "DW_TAG_subprogram";
00500     case DW_TAG_template_type_param:      return "DW_TAG_template_type_param";
00501     case DW_TAG_template_value_param:     return "DW_TAG_template_value_param";
00502     case DW_TAG_thrown_type:              return "DW_TAG_thrown_type";
00503     case DW_TAG_try_block:         return "DW_TAG_try_block";
00504     case DW_TAG_variant_part:             return "DW_TAG_variant_part";
00505     case DW_TAG_variable:          return "DW_TAG_variable";
00506     case DW_TAG_volatile_type:            return "DW_TAG_volatile_type";
00507     case DW_TAG_MIPS_loop:         return "DW_TAG_MIPS_loop";
00508     case DW_TAG_format_label:             return "DW_TAG_format_label";
00509     case DW_TAG_function_template: return "DW_TAG_function_template";
00510     case DW_TAG_class_template:           return "DW_TAG_class_template";
00511       /* DWARF 2.1 values.  */
00512     case DW_TAG_dwarf_procedure:   return "DW_TAG_dwarf_procedure";
00513     case DW_TAG_restrict_type:            return "DW_TAG_restrict_type";
00514     case DW_TAG_interface_type:           return "DW_TAG_interface_type";
00515     case DW_TAG_namespace:         return "DW_TAG_namespace";
00516     case DW_TAG_imported_module:   return "DW_TAG_imported_module";
00517     case DW_TAG_unspecified_type:  return "DW_TAG_unspecified_type";
00518     case DW_TAG_partial_unit:             return "DW_TAG_partial_unit";
00519     case DW_TAG_imported_unit:            return "DW_TAG_imported_unit";
00520       /* UPC values.  */
00521     case DW_TAG_upc_shared_type:   return "DW_TAG_upc_shared_type";
00522     case DW_TAG_upc_strict_type:   return "DW_TAG_upc_strict_type";
00523     case DW_TAG_upc_relaxed_type:  return "DW_TAG_upc_relaxed_type";
00524     default:
00525       {
00526        static char buffer[100];
00527 
00528        snprintf (buffer, sizeof (buffer), _("Unknown TAG value: %lx"), tag);
00529        return buffer;
00530       }
00531     }
00532 }
00533 
00534 static char *
00535 get_FORM_name (unsigned long form)
00536 {
00537   switch (form)
00538     {
00539     case DW_FORM_addr:             return "DW_FORM_addr";
00540     case DW_FORM_block2:    return "DW_FORM_block2";
00541     case DW_FORM_block4:    return "DW_FORM_block4";
00542     case DW_FORM_data2:            return "DW_FORM_data2";
00543     case DW_FORM_data4:            return "DW_FORM_data4";
00544     case DW_FORM_data8:            return "DW_FORM_data8";
00545     case DW_FORM_string:    return "DW_FORM_string";
00546     case DW_FORM_block:            return "DW_FORM_block";
00547     case DW_FORM_block1:    return "DW_FORM_block1";
00548     case DW_FORM_data1:            return "DW_FORM_data1";
00549     case DW_FORM_flag:             return "DW_FORM_flag";
00550     case DW_FORM_sdata:            return "DW_FORM_sdata";
00551     case DW_FORM_strp:             return "DW_FORM_strp";
00552     case DW_FORM_udata:            return "DW_FORM_udata";
00553     case DW_FORM_ref_addr:  return "DW_FORM_ref_addr";
00554     case DW_FORM_ref1:             return "DW_FORM_ref1";
00555     case DW_FORM_ref2:             return "DW_FORM_ref2";
00556     case DW_FORM_ref4:             return "DW_FORM_ref4";
00557     case DW_FORM_ref8:             return "DW_FORM_ref8";
00558     case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
00559     case DW_FORM_indirect:  return "DW_FORM_indirect";
00560     default:
00561       {
00562        static char buffer[100];
00563 
00564        snprintf (buffer, sizeof (buffer), _("Unknown FORM value: %lx"), form);
00565        return buffer;
00566       }
00567     }
00568 }
00569 
00570 static unsigned char *
00571 display_block (unsigned char *data, unsigned long length)
00572 {
00573   printf (_(" %lu byte block: "), length);
00574 
00575   while (length --)
00576     printf ("%lx ", (unsigned long) byte_get (data++, 1));
00577 
00578   return data;
00579 }
00580 
00581 static int
00582 decode_location_expression (unsigned char * data,
00583                          unsigned int pointer_size,
00584                          unsigned long length,
00585                          unsigned long cu_offset)
00586 {
00587   unsigned op;
00588   unsigned int bytes_read;
00589   unsigned long uvalue;
00590   unsigned char *end = data + length;
00591   int need_frame_base = 0;
00592 
00593   while (data < end)
00594     {
00595       op = *data++;
00596 
00597       switch (op)
00598        {
00599        case DW_OP_addr:
00600          printf ("DW_OP_addr: %lx",
00601                 (unsigned long) byte_get (data, pointer_size));
00602          data += pointer_size;
00603          break;
00604        case DW_OP_deref:
00605          printf ("DW_OP_deref");
00606          break;
00607        case DW_OP_const1u:
00608          printf ("DW_OP_const1u: %lu", (unsigned long) byte_get (data++, 1));
00609          break;
00610        case DW_OP_const1s:
00611          printf ("DW_OP_const1s: %ld", (long) byte_get_signed (data++, 1));
00612          break;
00613        case DW_OP_const2u:
00614          printf ("DW_OP_const2u: %lu", (unsigned long) byte_get (data, 2));
00615          data += 2;
00616          break;
00617        case DW_OP_const2s:
00618          printf ("DW_OP_const2s: %ld", (long) byte_get_signed (data, 2));
00619          data += 2;
00620          break;
00621        case DW_OP_const4u:
00622          printf ("DW_OP_const4u: %lu", (unsigned long) byte_get (data, 4));
00623          data += 4;
00624          break;
00625        case DW_OP_const4s:
00626          printf ("DW_OP_const4s: %ld", (long) byte_get_signed (data, 4));
00627          data += 4;
00628          break;
00629        case DW_OP_const8u:
00630          printf ("DW_OP_const8u: %lu %lu", (unsigned long) byte_get (data, 4),
00631                 (unsigned long) byte_get (data + 4, 4));
00632          data += 8;
00633          break;
00634        case DW_OP_const8s:
00635          printf ("DW_OP_const8s: %ld %ld", (long) byte_get (data, 4),
00636                 (long) byte_get (data + 4, 4));
00637          data += 8;
00638          break;
00639        case DW_OP_constu:
00640          printf ("DW_OP_constu: %lu", read_leb128 (data, &bytes_read, 0));
00641          data += bytes_read;
00642          break;
00643        case DW_OP_consts:
00644          printf ("DW_OP_consts: %ld", read_leb128 (data, &bytes_read, 1));
00645          data += bytes_read;
00646          break;
00647        case DW_OP_dup:
00648          printf ("DW_OP_dup");
00649          break;
00650        case DW_OP_drop:
00651          printf ("DW_OP_drop");
00652          break;
00653        case DW_OP_over:
00654          printf ("DW_OP_over");
00655          break;
00656        case DW_OP_pick:
00657          printf ("DW_OP_pick: %ld", (unsigned long) byte_get (data++, 1));
00658          break;
00659        case DW_OP_swap:
00660          printf ("DW_OP_swap");
00661          break;
00662        case DW_OP_rot:
00663          printf ("DW_OP_rot");
00664          break;
00665        case DW_OP_xderef:
00666          printf ("DW_OP_xderef");
00667          break;
00668        case DW_OP_abs:
00669          printf ("DW_OP_abs");
00670          break;
00671        case DW_OP_and:
00672          printf ("DW_OP_and");
00673          break;
00674        case DW_OP_div:
00675          printf ("DW_OP_div");
00676          break;
00677        case DW_OP_minus:
00678          printf ("DW_OP_minus");
00679          break;
00680        case DW_OP_mod:
00681          printf ("DW_OP_mod");
00682          break;
00683        case DW_OP_mul:
00684          printf ("DW_OP_mul");
00685          break;
00686        case DW_OP_neg:
00687          printf ("DW_OP_neg");
00688          break;
00689        case DW_OP_not:
00690          printf ("DW_OP_not");
00691          break;
00692        case DW_OP_or:
00693          printf ("DW_OP_or");
00694          break;
00695        case DW_OP_plus:
00696          printf ("DW_OP_plus");
00697          break;
00698        case DW_OP_plus_uconst:
00699          printf ("DW_OP_plus_uconst: %lu",
00700                 read_leb128 (data, &bytes_read, 0));
00701          data += bytes_read;
00702          break;
00703        case DW_OP_shl:
00704          printf ("DW_OP_shl");
00705          break;
00706        case DW_OP_shr:
00707          printf ("DW_OP_shr");
00708          break;
00709        case DW_OP_shra:
00710          printf ("DW_OP_shra");
00711          break;
00712        case DW_OP_xor:
00713          printf ("DW_OP_xor");
00714          break;
00715        case DW_OP_bra:
00716          printf ("DW_OP_bra: %ld", (long) byte_get_signed (data, 2));
00717          data += 2;
00718          break;
00719        case DW_OP_eq:
00720          printf ("DW_OP_eq");
00721          break;
00722        case DW_OP_ge:
00723          printf ("DW_OP_ge");
00724          break;
00725        case DW_OP_gt:
00726          printf ("DW_OP_gt");
00727          break;
00728        case DW_OP_le:
00729          printf ("DW_OP_le");
00730          break;
00731        case DW_OP_lt:
00732          printf ("DW_OP_lt");
00733          break;
00734        case DW_OP_ne:
00735          printf ("DW_OP_ne");
00736          break;
00737        case DW_OP_skip:
00738          printf ("DW_OP_skip: %ld", (long) byte_get_signed (data, 2));
00739          data += 2;
00740          break;
00741 
00742        case DW_OP_lit0:
00743        case DW_OP_lit1:
00744        case DW_OP_lit2:
00745        case DW_OP_lit3:
00746        case DW_OP_lit4:
00747        case DW_OP_lit5:
00748        case DW_OP_lit6:
00749        case DW_OP_lit7:
00750        case DW_OP_lit8:
00751        case DW_OP_lit9:
00752        case DW_OP_lit10:
00753        case DW_OP_lit11:
00754        case DW_OP_lit12:
00755        case DW_OP_lit13:
00756        case DW_OP_lit14:
00757        case DW_OP_lit15:
00758        case DW_OP_lit16:
00759        case DW_OP_lit17:
00760        case DW_OP_lit18:
00761        case DW_OP_lit19:
00762        case DW_OP_lit20:
00763        case DW_OP_lit21:
00764        case DW_OP_lit22:
00765        case DW_OP_lit23:
00766        case DW_OP_lit24:
00767        case DW_OP_lit25:
00768        case DW_OP_lit26:
00769        case DW_OP_lit27:
00770        case DW_OP_lit28:
00771        case DW_OP_lit29:
00772        case DW_OP_lit30:
00773        case DW_OP_lit31:
00774          printf ("DW_OP_lit%d", op - DW_OP_lit0);
00775          break;
00776 
00777        case DW_OP_reg0:
00778        case DW_OP_reg1:
00779        case DW_OP_reg2:
00780        case DW_OP_reg3:
00781        case DW_OP_reg4:
00782        case DW_OP_reg5:
00783        case DW_OP_reg6:
00784        case DW_OP_reg7:
00785        case DW_OP_reg8:
00786        case DW_OP_reg9:
00787        case DW_OP_reg10:
00788        case DW_OP_reg11:
00789        case DW_OP_reg12:
00790        case DW_OP_reg13:
00791        case DW_OP_reg14:
00792        case DW_OP_reg15:
00793        case DW_OP_reg16:
00794        case DW_OP_reg17:
00795        case DW_OP_reg18:
00796        case DW_OP_reg19:
00797        case DW_OP_reg20:
00798        case DW_OP_reg21:
00799        case DW_OP_reg22:
00800        case DW_OP_reg23:
00801        case DW_OP_reg24:
00802        case DW_OP_reg25:
00803        case DW_OP_reg26:
00804        case DW_OP_reg27:
00805        case DW_OP_reg28:
00806        case DW_OP_reg29:
00807        case DW_OP_reg30:
00808        case DW_OP_reg31:
00809          printf ("DW_OP_reg%d", op - DW_OP_reg0);
00810          break;
00811 
00812        case DW_OP_breg0:
00813        case DW_OP_breg1:
00814        case DW_OP_breg2:
00815        case DW_OP_breg3:
00816        case DW_OP_breg4:
00817        case DW_OP_breg5:
00818        case DW_OP_breg6:
00819        case DW_OP_breg7:
00820        case DW_OP_breg8:
00821        case DW_OP_breg9:
00822        case DW_OP_breg10:
00823        case DW_OP_breg11:
00824        case DW_OP_breg12:
00825        case DW_OP_breg13:
00826        case DW_OP_breg14:
00827        case DW_OP_breg15:
00828        case DW_OP_breg16:
00829        case DW_OP_breg17:
00830        case DW_OP_breg18:
00831        case DW_OP_breg19:
00832        case DW_OP_breg20:
00833        case DW_OP_breg21:
00834        case DW_OP_breg22:
00835        case DW_OP_breg23:
00836        case DW_OP_breg24:
00837        case DW_OP_breg25:
00838        case DW_OP_breg26:
00839        case DW_OP_breg27:
00840        case DW_OP_breg28:
00841        case DW_OP_breg29:
00842        case DW_OP_breg30:
00843        case DW_OP_breg31:
00844          printf ("DW_OP_breg%d: %ld", op - DW_OP_breg0,
00845                 read_leb128 (data, &bytes_read, 1));
00846          data += bytes_read;
00847          break;
00848 
00849        case DW_OP_regx:
00850          printf ("DW_OP_regx: %lu", read_leb128 (data, &bytes_read, 0));
00851          data += bytes_read;
00852          break;
00853        case DW_OP_fbreg:
00854          need_frame_base = 1;
00855          printf ("DW_OP_fbreg: %ld", read_leb128 (data, &bytes_read, 1));
00856          data += bytes_read;
00857          break;
00858        case DW_OP_bregx:
00859          uvalue = read_leb128 (data, &bytes_read, 0);
00860          data += bytes_read;
00861          printf ("DW_OP_bregx: %lu %ld", uvalue,
00862                 read_leb128 (data, &bytes_read, 1));
00863          data += bytes_read;
00864          break;
00865        case DW_OP_piece:
00866          printf ("DW_OP_piece: %lu", read_leb128 (data, &bytes_read, 0));
00867          data += bytes_read;
00868          break;
00869        case DW_OP_deref_size:
00870          printf ("DW_OP_deref_size: %ld", (long) byte_get (data++, 1));
00871          break;
00872        case DW_OP_xderef_size:
00873          printf ("DW_OP_xderef_size: %ld", (long) byte_get (data++, 1));
00874          break;
00875        case DW_OP_nop:
00876          printf ("DW_OP_nop");
00877          break;
00878 
00879          /* DWARF 3 extensions.  */
00880        case DW_OP_push_object_address:
00881          printf ("DW_OP_push_object_address");
00882          break;
00883        case DW_OP_call2:
00884          /* XXX: Strictly speaking for 64-bit DWARF3 files
00885             this ought to be an 8-byte wide computation.  */
00886          printf ("DW_OP_call2: <%lx>", (long) byte_get (data, 2) + cu_offset);
00887          data += 2;
00888          break;
00889        case DW_OP_call4:
00890          /* XXX: Strictly speaking for 64-bit DWARF3 files
00891             this ought to be an 8-byte wide computation.  */
00892          printf ("DW_OP_call4: <%lx>", (long) byte_get (data, 4) + cu_offset);
00893          data += 4;
00894          break;
00895        case DW_OP_call_ref:
00896          printf ("DW_OP_call_ref");
00897          break;
00898 
00899          /* GNU extensions.  */
00900        case DW_OP_GNU_push_tls_address:
00901          printf ("DW_OP_GNU_push_tls_address");
00902          break;
00903 
00904        default:
00905          if (op >= DW_OP_lo_user
00906              && op <= DW_OP_hi_user)
00907            printf (_("(User defined location op)"));
00908          else
00909            printf (_("(Unknown location op)"));
00910          /* No way to tell where the next op is, so just bail.  */
00911          return need_frame_base;
00912        }
00913 
00914       /* Separate the ops.  */
00915       if (data < end)
00916        printf ("; ");
00917     }
00918 
00919   return need_frame_base;
00920 }
00921 
00922 static unsigned char *
00923 read_and_display_attr_value (unsigned long attribute,
00924                           unsigned long form,
00925                           unsigned char *data,
00926                           unsigned long cu_offset,
00927                           unsigned long pointer_size,
00928                           unsigned long offset_size,
00929                           int dwarf_version,
00930                           debug_info *debug_info_p,
00931                           int do_loc)
00932 {
00933   unsigned long uvalue = 0;
00934   unsigned char *block_start = NULL;
00935   unsigned int bytes_read;
00936 
00937   switch (form)
00938     {
00939     default:
00940       break;
00941 
00942     case DW_FORM_ref_addr:
00943       if (dwarf_version == 2)
00944        {
00945          uvalue = byte_get (data, pointer_size);
00946          data += pointer_size;
00947        }
00948       else if (dwarf_version == 3)
00949        {
00950          uvalue = byte_get (data, offset_size);
00951          data += offset_size;
00952        }
00953       else
00954        {
00955          error (_("Internal error: DWARF version is not 2 or 3.\n"));
00956        }
00957       break;
00958 
00959     case DW_FORM_addr:
00960       uvalue = byte_get (data, pointer_size);
00961       data += pointer_size;
00962       break;
00963 
00964     case DW_FORM_strp:
00965       uvalue = byte_get (data, offset_size);
00966       data += offset_size;
00967       break;
00968 
00969     case DW_FORM_ref1:
00970     case DW_FORM_flag:
00971     case DW_FORM_data1:
00972       uvalue = byte_get (data++, 1);
00973       break;
00974 
00975     case DW_FORM_ref2:
00976     case DW_FORM_data2:
00977       uvalue = byte_get (data, 2);
00978       data += 2;
00979       break;
00980 
00981     case DW_FORM_ref4:
00982     case DW_FORM_data4:
00983       uvalue = byte_get (data, 4);
00984       data += 4;
00985       break;
00986 
00987     case DW_FORM_sdata:
00988       uvalue = read_leb128 (data, & bytes_read, 1);
00989       data += bytes_read;
00990       break;
00991 
00992     case DW_FORM_ref_udata:
00993     case DW_FORM_udata:
00994       uvalue = read_leb128 (data, & bytes_read, 0);
00995       data += bytes_read;
00996       break;
00997 
00998     case DW_FORM_indirect:
00999       form = read_leb128 (data, & bytes_read, 0);
01000       data += bytes_read;
01001       if (!do_loc)
01002        printf (" %s", get_FORM_name (form));
01003       return read_and_display_attr_value (attribute, form, data,
01004                                      cu_offset, pointer_size,
01005                                      offset_size, dwarf_version,
01006                                      debug_info_p, do_loc);
01007     }
01008 
01009   switch (form)
01010     {
01011     case DW_FORM_ref_addr:
01012       if (!do_loc)
01013        printf (" <#%lx>", uvalue);
01014       break;
01015 
01016     case DW_FORM_ref1:
01017     case DW_FORM_ref2:
01018     case DW_FORM_ref4:
01019     case DW_FORM_ref_udata:
01020       if (!do_loc)
01021        printf (" <%lx>", uvalue + cu_offset);
01022       break;
01023 
01024     case DW_FORM_data4:
01025     case DW_FORM_addr:
01026       if (!do_loc)
01027        printf (" %#lx", uvalue);
01028       break;
01029 
01030     case DW_FORM_flag:
01031     case DW_FORM_data1:
01032     case DW_FORM_data2:
01033     case DW_FORM_sdata:
01034     case DW_FORM_udata:
01035       if (!do_loc)
01036        printf (" %ld", uvalue);
01037       break;
01038 
01039     case DW_FORM_ref8:
01040     case DW_FORM_data8:
01041       if (!do_loc)
01042        {
01043          uvalue = byte_get (data, 4);
01044          printf (" %lx", uvalue);
01045          printf (" %lx", (unsigned long) byte_get (data + 4, 4));
01046        }
01047       if ((do_loc || do_debug_loc || do_debug_ranges)
01048          && num_debug_info_entries == 0)
01049        {
01050          if (sizeof (uvalue) == 8)
01051            uvalue = byte_get (data, 8);
01052          else
01053            error (_("DW_FORM_data8 is unsupported when sizeof (unsigned long) != 8\n"));
01054        }
01055       data += 8;
01056       break;
01057 
01058     case DW_FORM_string:
01059       if (!do_loc)
01060        printf (" %s", data);
01061       data += strlen ((char *) data) + 1;
01062       break;
01063 
01064     case DW_FORM_block:
01065       uvalue = read_leb128 (data, & bytes_read, 0);
01066       block_start = data + bytes_read;
01067       if (do_loc)
01068        data = block_start + uvalue;
01069       else
01070        data = display_block (block_start, uvalue);
01071       break;
01072 
01073     case DW_FORM_block1:
01074       uvalue = byte_get (data, 1);
01075       block_start = data + 1;
01076       if (do_loc)
01077        data = block_start + uvalue;
01078       else
01079        data = display_block (block_start, uvalue);
01080       break;
01081 
01082     case DW_FORM_block2:
01083       uvalue = byte_get (data, 2);
01084       block_start = data + 2;
01085       if (do_loc)
01086        data = block_start + uvalue;
01087       else
01088        data = display_block (block_start, uvalue);
01089       break;
01090 
01091     case DW_FORM_block4:
01092       uvalue = byte_get (data, 4);
01093       block_start = data + 4;
01094       if (do_loc)
01095        data = block_start + uvalue;
01096       else
01097        data = display_block (block_start, uvalue);
01098       break;
01099 
01100     case DW_FORM_strp:
01101       if (!do_loc)
01102        printf (_(" (indirect string, offset: 0x%lx): %s"),
01103               uvalue, fetch_indirect_string (uvalue));
01104       break;
01105 
01106     case DW_FORM_indirect:
01107       /* Handled above.  */
01108       break;
01109 
01110     default:
01111       warn (_("Unrecognized form: %lu\n"), form);
01112       break;
01113     }
01114 
01115   /* For some attributes we can display further information.  */
01116   if ((do_loc || do_debug_loc || do_debug_ranges)
01117       && num_debug_info_entries == 0)
01118     {
01119       switch (attribute)
01120        {
01121        case DW_AT_frame_base:
01122          have_frame_base = 1;
01123        case DW_AT_location:
01124        case DW_AT_data_member_location:
01125        case DW_AT_vtable_elem_location:
01126        case DW_AT_allocated:
01127        case DW_AT_associated:
01128        case DW_AT_data_location:
01129        case DW_AT_stride:
01130        case DW_AT_upper_bound:
01131        case DW_AT_lower_bound:
01132          if (form == DW_FORM_data4 || form == DW_FORM_data8)
01133            {
01134              /* Process location list.  */
01135              unsigned int max = debug_info_p->max_loc_offsets;
01136              unsigned int num = debug_info_p->num_loc_offsets;
01137 
01138              if (max == 0 || num >= max)
01139               {
01140                 max += 1024;
01141                 debug_info_p->loc_offsets
01142                   = xcrealloc (debug_info_p->loc_offsets,
01143                              max, sizeof (*debug_info_p->loc_offsets));
01144                 debug_info_p->have_frame_base
01145                   = xcrealloc (debug_info_p->have_frame_base,
01146                              max, sizeof (*debug_info_p->have_frame_base));
01147                 debug_info_p->max_loc_offsets = max;
01148               }
01149              debug_info_p->loc_offsets [num] = uvalue;
01150              debug_info_p->have_frame_base [num] = have_frame_base;
01151              debug_info_p->num_loc_offsets++;
01152            }
01153          break;
01154        
01155        case DW_AT_low_pc:
01156          if (need_base_address)
01157            debug_info_p->base_address = uvalue;
01158          break;
01159 
01160        case DW_AT_ranges:
01161          if (form == DW_FORM_data4 || form == DW_FORM_data8)
01162            {
01163              /* Process range list.  */
01164              unsigned int max = debug_info_p->max_range_lists;
01165              unsigned int num = debug_info_p->num_range_lists;
01166 
01167              if (max == 0 || num >= max)
01168               {
01169                 max += 1024;
01170                 debug_info_p->range_lists
01171                   = xcrealloc (debug_info_p->range_lists,
01172                              max, sizeof (*debug_info_p->range_lists));
01173                 debug_info_p->max_range_lists = max;
01174               }
01175              debug_info_p->range_lists [num] = uvalue;
01176              debug_info_p->num_range_lists++;
01177            }
01178          break;
01179 
01180        default:
01181          break;
01182        }
01183     }
01184 
01185   if (do_loc)
01186     return data;
01187 
01188   printf ("\t");
01189 
01190   switch (attribute)
01191     {
01192     case DW_AT_inline:
01193       switch (uvalue)
01194        {
01195        case DW_INL_not_inlined:
01196          printf (_("(not inlined)"));
01197          break;
01198        case DW_INL_inlined:
01199          printf (_("(inlined)"));
01200          break;
01201        case DW_INL_declared_not_inlined:
01202          printf (_("(declared as inline but ignored)"));
01203          break;
01204        case DW_INL_declared_inlined:
01205          printf (_("(declared as inline and inlined)"));
01206          break;
01207        default:
01208          printf (_("  (Unknown inline attribute value: %lx)"), uvalue);
01209          break;
01210        }
01211       break;
01212 
01213     case DW_AT_language:
01214       switch (uvalue)
01215        {
01216          /* Ordered by the numeric value of these constants.  */
01217        case DW_LANG_C89:           printf ("(ANSI C)"); break;
01218        case DW_LANG_C:                    printf ("(non-ANSI C)"); break;
01219        case DW_LANG_Ada83:         printf ("(Ada)"); break;
01220        case DW_LANG_C_plus_plus:   printf ("(C++)"); break;
01221        case DW_LANG_Cobol74:              printf ("(Cobol 74)"); break;
01222        case DW_LANG_Cobol85:              printf ("(Cobol 85)"); break;
01223        case DW_LANG_Fortran77:            printf ("(FORTRAN 77)"); break;
01224        case DW_LANG_Fortran90:            printf ("(Fortran 90)"); break;
01225        case DW_LANG_Pascal83:             printf ("(ANSI Pascal)"); break;
01226        case DW_LANG_Modula2:              printf ("(Modula 2)"); break;
01227          /* DWARF 2.1 values.      */
01228        case DW_LANG_Java:          printf ("(Java)"); break;
01229        case DW_LANG_C99:           printf ("(ANSI C99)"); break;
01230        case DW_LANG_Ada95:         printf ("(ADA 95)"); break;
01231        case DW_LANG_Fortran95:            printf ("(Fortran 95)"); break;
01232          /* DWARF 3 values.  */
01233        case DW_LANG_PLI:           printf ("(PLI)"); break;
01234        case DW_LANG_ObjC:          printf ("(Objective C)"); break;
01235        case DW_LANG_ObjC_plus_plus:       printf ("(Objective C++)"); break;
01236        case DW_LANG_UPC:           printf ("(Unified Parallel C)"); break;
01237        case DW_LANG_D:                    printf ("(D)"); break;
01238          /* MIPS extension.  */
01239        case DW_LANG_Mips_Assembler:       printf ("(MIPS assembler)"); break;
01240          /* UPC extension.  */
01241        case DW_LANG_Upc:           printf ("(Unified Parallel C)"); break;
01242        default:
01243          if (uvalue >= DW_LANG_lo_user && uvalue <= DW_LANG_hi_user)
01244            printf ("(implementation defined: %lx)", uvalue);
01245          else
01246            printf ("(Unknown: %lx)", uvalue);
01247          break;
01248        }
01249       break;
01250 
01251     case DW_AT_encoding:
01252       switch (uvalue)
01253        {
01254        case DW_ATE_void:           printf ("(void)"); break;
01255        case DW_ATE_address:        printf ("(machine address)"); break;
01256        case DW_ATE_boolean:        printf ("(boolean)"); break;
01257        case DW_ATE_complex_float:  printf ("(complex float)"); break;
01258        case DW_ATE_float:          printf ("(float)"); break;
01259        case DW_ATE_signed:         printf ("(signed)"); break;
01260        case DW_ATE_signed_char:    printf ("(signed char)"); break;
01261        case DW_ATE_unsigned:              printf ("(unsigned)"); break;
01262        case DW_ATE_unsigned_char:  printf ("(unsigned char)"); break;
01263          /* DWARF 2.1 value.  */
01264        case DW_ATE_imaginary_float:       printf ("(imaginary float)"); break;
01265        case DW_ATE_decimal_float:  printf ("(decimal float)"); break;
01266        default:
01267          if (uvalue >= DW_ATE_lo_user
01268              && uvalue <= DW_ATE_hi_user)
01269            printf ("(user defined type)");
01270          else
01271            printf ("(unknown type)");
01272          break;
01273        }
01274       break;
01275 
01276     case DW_AT_accessibility:
01277       switch (uvalue)
01278        {
01279        case DW_ACCESS_public:             printf ("(public)"); break;
01280        case DW_ACCESS_protected:   printf ("(protected)"); break;
01281        case DW_ACCESS_private:            printf ("(private)"); break;
01282        default:
01283          printf ("(unknown accessibility)");
01284          break;
01285        }
01286       break;
01287 
01288     case DW_AT_visibility:
01289       switch (uvalue)
01290        {
01291        case DW_VIS_local:          printf ("(local)"); break;
01292        case DW_VIS_exported:              printf ("(exported)"); break;
01293        case DW_VIS_qualified:             printf ("(qualified)"); break;
01294        default:                    printf ("(unknown visibility)"); break;
01295        }
01296       break;
01297 
01298     case DW_AT_virtuality:
01299       switch (uvalue)
01300        {
01301        case DW_VIRTUALITY_none:    printf ("(none)"); break;
01302        case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
01303        case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
01304        default:                    printf ("(unknown virtuality)"); break;
01305        }
01306       break;
01307 
01308     case DW_AT_identifier_case:
01309       switch (uvalue)
01310        {
01311        case DW_ID_case_sensitive:  printf ("(case_sensitive)"); break;
01312        case DW_ID_up_case:         printf ("(up_case)"); break;
01313        case DW_ID_down_case:              printf ("(down_case)"); break;
01314        case DW_ID_case_insensitive:       printf ("(case_insensitive)"); break;
01315        default:                    printf ("(unknown case)"); break;
01316        }
01317       break;
01318 
01319     case DW_AT_calling_convention:
01320       switch (uvalue)
01321        {
01322        case DW_CC_normal:   printf ("(normal)"); break;
01323        case DW_CC_program:  printf ("(program)"); break;
01324        case DW_CC_nocall:   printf ("(nocall)"); break;
01325        default:
01326          if (uvalue >= DW_CC_lo_user
01327              && uvalue <= DW_CC_hi_user)
01328            printf ("(user defined)");
01329          else
01330            printf ("(unknown convention)");
01331        }
01332       break;
01333 
01334     case DW_AT_ordering:
01335       switch (uvalue)
01336        {
01337        case -1: printf ("(undefined)"); break;
01338        case 0:  printf ("(row major)"); break;
01339        case 1:  printf ("(column major)"); break;
01340        }
01341       break;
01342 
01343     case DW_AT_frame_base:
01344       have_frame_base = 1;
01345     case DW_AT_location:
01346     case DW_AT_data_member_location:
01347     case DW_AT_vtable_elem_location:
01348     case DW_AT_allocated:
01349     case DW_AT_associated:
01350     case DW_AT_data_location:
01351     case DW_AT_stride:
01352     case DW_AT_upper_bound:
01353     case DW_AT_lower_bound:
01354       if (block_start)
01355        {
01356          int need_frame_base;
01357 
01358          printf ("(");
01359          need_frame_base = decode_location_expression (block_start,
01360                                                  pointer_size,
01361                                                  uvalue,
01362                                                  cu_offset);
01363          printf (")");
01364          if (need_frame_base && !have_frame_base)
01365            printf (_(" [without DW_AT_frame_base]"));
01366        }
01367       else if (form == DW_FORM_data4 || form == DW_FORM_data8)
01368        printf (_("(location list)"));
01369 
01370       break;
01371 
01372     default:
01373       break;
01374     }
01375 
01376   return data;
01377 }
01378 
01379 static char *
01380 get_AT_name (unsigned long attribute)
01381 {
01382   switch (attribute)
01383     {
01384     case DW_AT_sibling:                   return "DW_AT_sibling";
01385     case DW_AT_location:           return "DW_AT_location";
01386     case DW_AT_name:               return "DW_AT_name";
01387     case DW_AT_ordering:           return "DW_AT_ordering";
01388     case DW_AT_subscr_data:        return "DW_AT_subscr_data";
01389     case DW_AT_byte_size:          return "DW_AT_byte_size";
01390     case DW_AT_bit_offset:         return "DW_AT_bit_offset";
01391     case DW_AT_bit_size:           return "DW_AT_bit_size";
01392     case DW_AT_element_list:              return "DW_AT_element_list";
01393     case DW_AT_stmt_list:          return "DW_AT_stmt_list";
01394     case DW_AT_low_pc:                    return "DW_AT_low_pc";
01395     case DW_AT_high_pc:                   return "DW_AT_high_pc";
01396     case DW_AT_language:           return "DW_AT_language";
01397     case DW_AT_member:                    return "DW_AT_member";
01398     case DW_AT_discr:                     return "DW_AT_discr";
01399     case DW_AT_discr_value:        return "DW_AT_discr_value";
01400     case DW_AT_visibility:         return "DW_AT_visibility";
01401     case DW_AT_import:                    return "DW_AT_import";
01402     case DW_AT_string_length:             return "DW_AT_string_length";
01403     case DW_AT_common_reference:   return "DW_AT_common_reference";
01404     case DW_AT_comp_dir:           return "DW_AT_comp_dir";
01405     case DW_AT_const_value:        return "DW_AT_const_value";
01406     case DW_AT_containing_type:           return "DW_AT_containing_type";
01407     case DW_AT_default_value:             return "DW_AT_default_value";
01408     case DW_AT_inline:                    return "DW_AT_inline";
01409     case DW_AT_is_optional:        return "DW_AT_is_optional";
01410     case DW_AT_lower_bound:        return "DW_AT_lower_bound";
01411     case DW_AT_producer:           return "DW_AT_producer";
01412     case DW_AT_prototyped:         return "DW_AT_prototyped";
01413     case DW_AT_return_addr:        return "DW_AT_return_addr";
01414     case DW_AT_start_scope:        return "DW_AT_start_scope";
01415     case DW_AT_stride_size:        return "DW_AT_stride_size";
01416     case DW_AT_upper_bound:        return "DW_AT_upper_bound";
01417     case DW_AT_abstract_origin:           return "DW_AT_abstract_origin";
01418     case DW_AT_accessibility:             return "DW_AT_accessibility";
01419     case DW_AT_address_class:             return "DW_AT_address_class";
01420     case DW_AT_artificial:         return "DW_AT_artificial";
01421     case DW_AT_base_types:         return "DW_AT_base_types";
01422     case DW_AT_calling_convention: return "DW_AT_calling_convention";
01423     case DW_AT_count:                     return "DW_AT_count";
01424     case DW_AT_data_member_location:      return "DW_AT_data_member_location";
01425     case DW_AT_decl_column:        return "DW_AT_decl_column";
01426     case DW_AT_decl_file:          return "DW_AT_decl_file";
01427     case DW_AT_decl_line:          return "DW_AT_decl_line";
01428     case DW_AT_declaration:        return "DW_AT_declaration";
01429     case DW_AT_discr_list:         return "DW_AT_discr_list";
01430     case DW_AT_encoding:           return "DW_AT_encoding";
01431     case DW_AT_external:           return "DW_AT_external";
01432     case DW_AT_frame_base:         return "DW_AT_frame_base";
01433     case DW_AT_friend:                    return "DW_AT_friend";
01434     case DW_AT_identifier_case:           return "DW_AT_identifier_case";
01435     case DW_AT_macro_info:         return "DW_AT_macro_info";
01436     case DW_AT_namelist_items:            return "DW_AT_namelist_items";
01437     case DW_AT_priority:           return "DW_AT_priority";
01438     case DW_AT_segment:                   return "DW_AT_segment";
01439     case DW_AT_specification:             return "DW_AT_specification";
01440     case DW_AT_static_link:        return "DW_AT_static_link";
01441     case DW_AT_type:               return "DW_AT_type";
01442     case DW_AT_use_location:              return "DW_AT_use_location";
01443     case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
01444     case DW_AT_virtuality:         return "DW_AT_virtuality";
01445     case DW_AT_vtable_elem_location:      return "DW_AT_vtable_elem_location";
01446       /* DWARF 2.1 values.  */
01447     case DW_AT_allocated:          return "DW_AT_allocated";
01448     case DW_AT_associated:         return "DW_AT_associated";
01449     case DW_AT_data_location:             return "DW_AT_data_location";
01450     case DW_AT_stride:                    return "DW_AT_stride";
01451     case DW_AT_entry_pc:           return "DW_AT_entry_pc";
01452     case DW_AT_use_UTF8:           return "DW_AT_use_UTF8";
01453     case DW_AT_extension:          return "DW_AT_extension";
01454     case DW_AT_ranges:                    return "DW_AT_ranges";
01455     case DW_AT_trampoline:         return "DW_AT_trampoline";
01456     case DW_AT_call_column:        return "DW_AT_call_column";
01457     case DW_AT_call_file:          return "DW_AT_call_file";
01458     case DW_AT_call_line:          return "DW_AT_call_line";
01459       /* SGI/MIPS extensions.  */
01460     case DW_AT_MIPS_fde:           return "DW_AT_MIPS_fde";
01461     case DW_AT_MIPS_loop_begin:           return "DW_AT_MIPS_loop_begin";
01462     case DW_AT_MIPS_tail_loop_begin:      return "DW_AT_MIPS_tail_loop_begin";
01463     case DW_AT_MIPS_epilog_begin:  return "DW_AT_MIPS_epilog_begin";
01464     case DW_AT_MIPS_loop_unroll_factor: return "DW_AT_MIPS_loop_unroll_factor";
01465     case DW_AT_MIPS_software_pipeline_depth:
01466       return "DW_AT_MIPS_software_pipeline_depth";
01467     case DW_AT_MIPS_linkage_name:  return "DW_AT_MIPS_linkage_name";
01468     case DW_AT_MIPS_stride:        return "DW_AT_MIPS_stride";
01469     case DW_AT_MIPS_abstract_name: return "DW_AT_MIPS_abstract_name";
01470     case DW_AT_MIPS_clone_origin:  return "DW_AT_MIPS_clone_origin";
01471     case DW_AT_MIPS_has_inlines:   return "DW_AT_MIPS_has_inlines";
01472       /* GNU extensions.  */
01473     case DW_AT_sf_names:           return "DW_AT_sf_names";
01474     case DW_AT_src_info:           return "DW_AT_src_info";
01475     case DW_AT_mac_info:           return "DW_AT_mac_info";
01476     case DW_AT_src_coords:         return "DW_AT_src_coords";
01477     case DW_AT_body_begin:         return "DW_AT_body_begin";
01478     case DW_AT_body_end:           return "DW_AT_body_end";
01479     case DW_AT_GNU_vector:         return "DW_AT_GNU_vector";
01480       /* UPC extension.  */
01481     case DW_AT_upc_threads_scaled: return "DW_AT_upc_threads_scaled";
01482     default:
01483       {
01484        static char buffer[100];
01485 
01486        snprintf (buffer, sizeof (buffer), _("Unknown AT value: %lx"),
01487                 attribute);
01488        return buffer;
01489       }
01490     }
01491 }
01492 
01493 static unsigned char *
01494 read_and_display_attr (unsigned long attribute,
01495                      unsigned long form,
01496                      unsigned char *data,
01497                      unsigned long cu_offset,
01498                      unsigned long pointer_size,
01499                      unsigned long offset_size,
01500                      int dwarf_version,
01501                      debug_info *debug_info_p,
01502                      int do_loc)
01503 {
01504   if (!do_loc)
01505     printf ("     %-18s:", get_AT_name (attribute));
01506   data = read_and_display_attr_value (attribute, form, data, cu_offset,
01507                                   pointer_size, offset_size,
01508                                   dwarf_version, debug_info_p,
01509                                   do_loc);
01510   if (!do_loc)
01511     printf ("\n");
01512   return data;
01513 }
01514 
01515 
01516 /* Process the contents of a .debug_info section.  If do_loc is non-zero
01517    then we are scanning for location lists and we do not want to display
01518    anything to the user.  */
01519 
01520 static int
01521 process_debug_info (struct dwarf_section *section, void *file,
01522                   int do_loc)
01523 {
01524   unsigned char *start = section->start;
01525   unsigned char *end = start + section->size;
01526   unsigned char *section_begin;
01527   unsigned int unit;
01528   unsigned int num_units = 0;
01529 
01530   if ((do_loc || do_debug_loc || do_debug_ranges)
01531       && num_debug_info_entries == 0)
01532     {
01533       unsigned long length;
01534 
01535       /* First scan the section to get the number of comp units.  */
01536       for (section_begin = start, num_units = 0; section_begin < end;
01537           num_units ++)
01538        {
01539          /* Read the first 4 bytes.  For a 32-bit DWARF section, this
01540             will be the length.  For a 64-bit DWARF section, it'll be
01541             the escape code 0xffffffff followed by an 8 byte length.  */
01542          length = byte_get (section_begin, 4);
01543 
01544          if (length == 0xffffffff)
01545            {
01546              length = byte_get (section_begin + 4, 8);
01547              section_begin += length + 12;
01548            }
01549          else
01550            section_begin += length + 4;
01551        }
01552 
01553       if (num_units == 0)
01554        {
01555          error (_("No comp units in %s section ?"), section->name);
01556          return 0;
01557        }
01558 
01559       /* Then allocate an array to hold the information.  */
01560       debug_information = cmalloc (num_units,
01561                                sizeof (* debug_information));
01562       if (debug_information == NULL)
01563        {
01564          error (_("Not enough memory for a debug info array of %u entries"),
01565                num_units);
01566          return 0;
01567        }
01568     }
01569 
01570   if (!do_loc)
01571     {
01572       printf (_("The section %s contains:\n\n"), section->name);
01573 
01574       load_debug_section (str, file);
01575     }
01576 
01577   load_debug_section (abbrev, file);
01578   if (debug_displays [abbrev].section.start == NULL)
01579     {
01580       warn (_("Unable to locate %s section!\n"),
01581            debug_displays [abbrev].section.name);
01582       return 0;
01583     }
01584 
01585   for (section_begin = start, unit = 0; start < end; unit++)
01586     {
01587       DWARF2_Internal_CompUnit compunit;
01588       unsigned char *hdrptr;
01589       unsigned char *cu_abbrev_offset_ptr;
01590       unsigned char *tags;
01591       int level;
01592       unsigned long cu_offset;
01593       int offset_size;
01594       int initial_length_size;
01595 
01596       hdrptr = start;
01597 
01598       compunit.cu_length = byte_get (hdrptr, 4);
01599       hdrptr += 4;
01600 
01601       if (compunit.cu_length == 0xffffffff)
01602        {
01603          compunit.cu_length = byte_get (hdrptr, 8);
01604          hdrptr += 8;
01605          offset_size = 8;
01606          initial_length_size = 12;
01607        }
01608       else
01609        {
01610          offset_size = 4;
01611          initial_length_size = 4;
01612        }
01613 
01614       compunit.cu_version = byte_get (hdrptr, 2);
01615       hdrptr += 2;
01616 
01617       cu_offset = start - section_begin;
01618 
01619       cu_abbrev_offset_ptr = hdrptr;
01620       compunit.cu_abbrev_offset = byte_get (hdrptr, offset_size);
01621       hdrptr += offset_size;
01622 
01623       compunit.cu_pointer_size = byte_get (hdrptr, 1);
01624       hdrptr += 1;
01625       if ((do_loc || do_debug_loc || do_debug_ranges)
01626          && num_debug_info_entries == 0)
01627        {
01628          debug_information [unit].cu_offset = cu_offset;
01629          debug_information [unit].pointer_size
01630            = compunit.cu_pointer_size;
01631          debug_information [unit].base_address = 0;
01632          debug_information [unit].loc_offsets = NULL;
01633          debug_information [unit].have_frame_base = NULL;
01634          debug_information [unit].max_loc_offsets = 0;
01635          debug_information [unit].num_loc_offsets = 0;
01636          debug_information [unit].range_lists = NULL;
01637          debug_information [unit].max_range_lists= 0;
01638          debug_information [unit].num_range_lists = 0;
01639        }
01640 
01641       if (!do_loc)
01642        {
01643          printf (_("  Compilation Unit @ offset 0x%lx:\n"), cu_offset);
01644          printf (_("   Length:        %ld\n"), compunit.cu_length);
01645          printf (_("   Version:       %d\n"), compunit.cu_version);
01646          printf (_("   Abbrev Offset: %ld\n"), compunit.cu_abbrev_offset);
01647          printf (_("   Pointer Size:  %d\n"), compunit.cu_pointer_size);
01648        }
01649 
01650       if (cu_offset + compunit.cu_length + initial_length_size
01651          > section->size)
01652        {
01653          warn (_("Debug info is corrupted, length is invalid (section is %lu bytes)\n"),
01654               (unsigned long)section->size);
01655          break;
01656        }
01657       tags = hdrptr;
01658       start += compunit.cu_length + initial_length_size;
01659 
01660       if (compunit.cu_version != 2 && compunit.cu_version != 3)
01661        {
01662          warn (_("Only version 2 and 3 DWARF debug information is currently supported.\n"));
01663          continue;
01664        }
01665 
01666       free_abbrevs ();
01667 
01668       /* Process the abbrevs used by this compilation unit. DWARF
01669         sections under Mach-O have non-zero addresses.  */
01670       if (compunit.cu_abbrev_offset >= debug_displays [abbrev].section.size)
01671        warn (_("Debug info is corrupted, abbrev offset is invalid (section is %lu bytes)\n"),
01672              (unsigned long)debug_displays [abbrev].section.size);
01673       else
01674        process_abbrev_section
01675          ((unsigned char *) debug_displays [abbrev].section.start
01676           + compunit.cu_abbrev_offset - debug_displays [abbrev].section.address,
01677           (unsigned char *) debug_displays [abbrev].section.start
01678           + debug_displays [abbrev].section.size);
01679 
01680       level = 0;
01681       while (tags < start)
01682        {
01683          unsigned int bytes_read;
01684          unsigned long abbrev_number;
01685          abbrev_entry *entry;
01686          abbrev_attr *attr;
01687 
01688          abbrev_number = read_leb128 (tags, & bytes_read, 0);
01689          tags += bytes_read;
01690 
01691          /* A null DIE marks the end of a list of children.  */
01692          if (abbrev_number == 0)
01693            {
01694              --level;
01695              continue;
01696            }
01697 
01698          if (!do_loc)
01699            printf (_(" <%d><%lx>: Abbrev Number: %lu"),
01700                   level,
01701                   (unsigned long) (tags - section_begin
01702                                  - bytes_read),
01703                   abbrev_number);
01704  
01705          /* Scan through the abbreviation list until we reach the
01706             correct entry.  */
01707          for (entry = first_abbrev;
01708               entry && entry->entry != abbrev_number;
01709               entry = entry->next)
01710            continue;
01711 
01712          if (entry == NULL)
01713            {
01714              if (!do_loc)
01715               {
01716                 printf ("\n");
01717                 fflush (stdout);
01718               }
01719              warn (_("Unable to locate entry %lu in the abbreviation table\n"),
01720                   abbrev_number);
01721              return 0;
01722            }
01723 
01724          if (!do_loc)
01725            printf (_(" (%s)\n"), get_TAG_name (entry->tag));
01726  
01727          switch (entry->tag)
01728            {
01729            default:
01730              need_base_address = 0;
01731              break;
01732            case DW_TAG_compile_unit:
01733              need_base_address = 1;
01734              break;
01735            case DW_TAG_entry_point:
01736            case DW_TAG_inlined_subroutine:
01737            case DW_TAG_subprogram:
01738              need_base_address = 0;
01739              /* Assuming that there is no DW_AT_frame_base.  */
01740              have_frame_base = 0;
01741              break;
01742            }
01743 
01744          for (attr = entry->first_attr; attr; attr = attr->next)
01745            {
01746              if (! do_loc)
01747               /* Show the offset from where the tag was extracted.  */
01748               printf ("  <%2lx>", (unsigned long)(tags - section_begin));
01749 
01750              tags = read_and_display_attr (attr->attribute,
01751                                        attr->form,
01752                                        tags, cu_offset,
01753                                        compunit.cu_pointer_size,
01754                                        offset_size,
01755                                        compunit.cu_version,
01756                                        &debug_information [unit],
01757                                        do_loc);
01758            }
01759  
01760          if (entry->children)
01761            ++level;
01762        }
01763     }
01764  
01765   /* Set num_debug_info_entries here so that it can be used to check if
01766      we need to process .debug_loc and .debug_ranges sections.  */
01767   if ((do_loc || do_debug_loc || do_debug_ranges)
01768       && num_debug_info_entries == 0)
01769     num_debug_info_entries = num_units;
01770       
01771   if (!do_loc)
01772     {
01773       printf ("\n");
01774     }
01775  
01776   return 1;
01777 }
01778 
01779 /* Locate and scan the .debug_info section in the file and record the pointer
01780    sizes and offsets for the compilation units in it.  Usually an executable
01781    will have just one pointer size, but this is not guaranteed, and so we try
01782    not to make any assumptions.  Returns zero upon failure, or the number of
01783    compilation units upon success.  */
01784 
01785 static unsigned int
01786 load_debug_info (void * file)
01787 {
01788   /* Reset the last pointer size so that we can issue correct error
01789      messages if we are displaying the contents of more than one section.  */
01790   last_pointer_size = 0;
01791   warned_about_missing_comp_units = FALSE;
01792 
01793   /* If we already have the information there is nothing else to do.  */
01794   if (num_debug_info_entries > 0)
01795     return num_debug_info_entries;
01796 
01797   if (load_debug_section (info, file)
01798       && process_debug_info (&debug_displays [info].section, file, 1))
01799     return num_debug_info_entries;
01800   else
01801     return 0;
01802 }
01803 
01804 static int
01805 display_debug_lines (struct dwarf_section *section, void *file)
01806 {
01807   unsigned char *start = section->start;
01808   unsigned char *data = start;
01809   unsigned char *end = start + section->size;
01810 
01811   printf (_("\nDump of debug contents of section %s:\n\n"),
01812          section->name);
01813 
01814   load_debug_info (file);
01815 
01816   while (data < end)
01817     {
01818       DWARF2_Internal_LineInfo info;
01819       unsigned char *standard_opcodes;
01820       unsigned char *end_of_sequence;
01821       unsigned char *hdrptr;
01822       int initial_length_size;
01823       int offset_size;
01824       int i;
01825 
01826       hdrptr = data;
01827 
01828       /* Check the length of the block.  */
01829       info.li_length = byte_get (hdrptr, 4);
01830       hdrptr += 4;
01831 
01832       if (info.li_length == 0xffffffff)
01833        {
01834          /* This section is 64-bit DWARF 3.  */
01835          info.li_length = byte_get (hdrptr, 8);
01836          hdrptr += 8;
01837          offset_size = 8;
01838          initial_length_size = 12;
01839        }
01840       else
01841        {
01842          offset_size = 4;
01843          initial_length_size = 4;
01844        }
01845 
01846       if (info.li_length + initial_length_size > section->size)
01847        {
01848          warn
01849            (_("The line info appears to be corrupt - the section is too small\n"));
01850          return 0;
01851        }
01852 
01853       /* Check its version number.  */
01854       info.li_version = byte_get (hdrptr, 2);
01855       hdrptr += 2;
01856       if (info.li_version != 2 && info.li_version != 3)
01857        {
01858          warn (_("Only DWARF version 2 and 3 line info is currently supported.\n"));
01859          return 0;
01860        }
01861 
01862       info.li_prologue_length = byte_get (hdrptr, offset_size);
01863       hdrptr += offset_size;
01864       info.li_min_insn_length = byte_get (hdrptr, 1);
01865       hdrptr++;
01866       info.li_default_is_stmt = byte_get (hdrptr, 1);
01867       hdrptr++;
01868       info.li_line_base = byte_get (hdrptr, 1);
01869       hdrptr++;
01870       info.li_line_range = byte_get (hdrptr, 1);
01871       hdrptr++;
01872       info.li_opcode_base = byte_get (hdrptr, 1);
01873       hdrptr++;
01874 
01875       /* Sign extend the line base field.  */
01876       info.li_line_base <<= 24;
01877       info.li_line_base >>= 24;
01878 
01879       printf (_("  Length:                      %ld\n"), info.li_length);
01880       printf (_("  DWARF Version:               %d\n"), info.li_version);
01881       printf (_("  Prologue Length:             %d\n"), info.li_prologue_length);
01882       printf (_("  Minimum Instruction Length:  %d\n"), info.li_min_insn_length);
01883       printf (_("  Initial value of 'is_stmt':  %d\n"), info.li_default_is_stmt);
01884       printf (_("  Line Base:                   %d\n"), info.li_line_base);
01885       printf (_("  Line Range:                  %d\n"), info.li_line_range);
01886       printf (_("  Opcode Base:                 %d\n"), info.li_opcode_base);
01887 
01888       end_of_sequence = data + info.li_length + initial_length_size;
01889 
01890       reset_state_machine (info.li_default_is_stmt);
01891 
01892       /* Display the contents of the Opcodes table.  */
01893       standard_opcodes = hdrptr;
01894 
01895       printf (_("\n Opcodes:\n"));
01896 
01897       for (i = 1; i < info.li_opcode_base; i++)
01898        printf (_("  Opcode %d has %d args\n"), i, standard_opcodes[i - 1]);
01899 
01900       /* Display the contents of the Directory table.  */
01901       data = standard_opcodes + info.li_opcode_base - 1;
01902 
01903       if (*data == 0)
01904        printf (_("\n The Directory Table is empty.\n"));
01905       else
01906        {
01907          printf (_("\n The Directory Table:\n"));
01908 
01909          while (*data != 0)
01910            {
01911              printf (_("  %s\n"), data);
01912 
01913              data += strlen ((char *) data) + 1;
01914            }
01915        }
01916 
01917       /* Skip the NUL at the end of the table.  */
01918       data++;
01919 
01920       /* Display the contents of the File Name table.  */
01921       if (*data == 0)
01922        printf (_("\n The File Name Table is empty.\n"));
01923       else
01924        {
01925          printf (_("\n The File Name Table:\n"));
01926          printf (_("  Entry\tDir\tTime\tSize\tName\n"));
01927 
01928          while (*data != 0)
01929            {
01930              unsigned char *name;
01931              unsigned int bytes_read;
01932 
01933              printf (_("  %d\t"), ++state_machine_regs.last_file_entry);
01934              name = data;
01935 
01936              data += strlen ((char *) data) + 1;
01937 
01938              printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
01939              data += bytes_read;
01940              printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
01941              data += bytes_read;
01942              printf (_("%lu\t"), read_leb128 (data, & bytes_read, 0));
01943              data += bytes_read;
01944              printf (_("%s\n"), name);
01945            }
01946        }
01947 
01948       /* Skip the NUL at the end of the table.  */
01949       data++;
01950 
01951       /* Now display the statements.  */
01952       printf (_("\n Line Number Statements:\n"));
01953 
01954       while (data < end_of_sequence)
01955        {
01956          unsigned char op_code;
01957          int adv;
01958          unsigned long int uladv;
01959          unsigned int bytes_read;
01960 
01961          op_code = *data++;
01962 
01963          if (op_code >= info.li_opcode_base)
01964            {
01965              op_code -= info.li_opcode_base;
01966              uladv = (op_code / info.li_line_range) * info.li_min_insn_length;
01967              state_machine_regs.address += uladv;
01968              printf (_("  Special opcode %d: advance Address by %lu to 0x%lx"),
01969                     op_code, uladv, state_machine_regs.address);
01970              adv = (op_code % info.li_line_range) + info.li_line_base;
01971              state_machine_regs.line += adv;
01972              printf (_(" and Line by %d to %d\n"),
01973                     adv, state_machine_regs.line);
01974            }
01975          else switch (op_code)
01976            {
01977            case DW_LNS_extended_op:
01978              data += process_extended_line_op (data, info.li_default_is_stmt);
01979              break;
01980 
01981            case DW_LNS_copy:
01982              printf (_("  Copy\n"));
01983              break;
01984 
01985            case DW_LNS_advance_pc:
01986              uladv = read_leb128 (data, & bytes_read, 0);
01987              uladv *= info.li_min_insn_length;
01988              data += bytes_read;
01989              state_machine_regs.address += uladv;
01990              printf (_("  Advance PC by %lu to 0x%lx\n"), uladv,
01991                     state_machine_regs.address);
01992              break;
01993 
01994            case DW_LNS_advance_line:
01995              adv = read_leb128 (data, & bytes_read, 1);
01996              data += bytes_read;
01997              state_machine_regs.line += adv;
01998              printf (_("  Advance Line by %d to %d\n"), adv,
01999                     state_machine_regs.line);
02000              break;
02001 
02002            case DW_LNS_set_file:
02003              adv = read_leb128 (data, & bytes_read, 0);
02004              data += bytes_read;
02005              printf (_("  Set File Name to entry %d in the File Name Table\n"),
02006                     adv);
02007              state_machine_regs.file = adv;
02008              break;
02009 
02010            case DW_LNS_set_column:
02011              uladv = read_leb128 (data, & bytes_read, 0);
02012              data += bytes_read;
02013              printf (_("  Set column to %lu\n"), uladv);
02014              state_machine_regs.column = uladv;
02015              break;
02016 
02017            case DW_LNS_negate_stmt:
02018              adv = state_machine_regs.is_stmt;
02019              adv = ! adv;
02020              printf (_("  Set is_stmt to %d\n"), adv);
02021              state_machine_regs.is_stmt = adv;
02022              break;
02023 
02024            case DW_LNS_set_basic_block:
02025              printf (_("  Set basic block\n"));
02026              state_machine_regs.basic_block = 1;
02027              break;
02028 
02029            case DW_LNS_const_add_pc:
02030              uladv = (((255 - info.li_opcode_base) / info.li_line_range)
02031                     * info.li_min_insn_length);
02032              state_machine_regs.address += uladv;
02033              printf (_("  Advance PC by constant %lu to 0x%lx\n"), uladv,
02034                     state_machine_regs.address);
02035              break;
02036 
02037            case DW_LNS_fixed_advance_pc:
02038              uladv = byte_get (data, 2);
02039              data += 2;
02040              state_machine_regs.address += uladv;
02041              printf (_("  Advance PC by fixed size amount %lu to 0x%lx\n"),
02042                     uladv, state_machine_regs.address);
02043              break;
02044 
02045            case DW_LNS_set_prologue_end:
02046              printf (_("  Set prologue_end to true\n"));
02047              break;
02048 
02049            case DW_LNS_set_epilogue_begin:
02050              printf (_("  Set epilogue_begin to true\n"));
02051              break;
02052 
02053            case DW_LNS_set_isa:
02054              uladv = read_leb128 (data, & bytes_read, 0);
02055              data += bytes_read;
02056              printf (_("  Set ISA to %lu\n"), uladv);
02057              break;
02058 
02059            default:
02060              printf (_("  Unknown opcode %d with operands: "), op_code);
02061 
02062              for (i = standard_opcodes[op_code - 1]; i > 0 ; --i)
02063               {
02064                 printf ("0x%lx%s", read_leb128 (data, &bytes_read, 0),
02065                        i == 1 ? "" : ", ");
02066                 data += bytes_read;
02067               }
02068              putchar ('\n');
02069              break;
02070            }
02071        }
02072       putchar ('\n');
02073     }
02074 
02075   return 1;
02076 }
02077 
02078 static int
02079 display_debug_pubnames (struct dwarf_section *section,
02080                      void *file ATTRIBUTE_UNUSED)
02081 {
02082   DWARF2_Internal_PubNames pubnames;
02083   unsigned char *start = section->start;
02084   unsigned char *end = start + section->size;
02085 
02086   printf (_("Contents of the %s section:\n\n"), section->name);
02087 
02088   while (start < end)
02089     {
02090       unsigned char *data;
02091       unsigned long offset;
02092       int offset_size, initial_length_size;
02093 
02094       data = start;
02095 
02096       pubnames.pn_length = byte_get (data, 4);
02097       data += 4;
02098       if (pubnames.pn_length == 0xffffffff)
02099        {
02100          pubnames.pn_length = byte_get (data, 8);
02101          data += 8;
02102          offset_size = 8;
02103          initial_length_size = 12;
02104        }
02105       else
02106        {
02107          offset_size = 4;
02108          initial_length_size = 4;
02109        }
02110 
02111       pubnames.pn_version = byte_get (data, 2);
02112       data += 2;
02113       pubnames.pn_offset = byte_get (data, offset_size);
02114       data += offset_size;
02115       pubnames.pn_size = byte_get (data, offset_size);
02116       data += offset_size;
02117 
02118       start += pubnames.pn_length + initial_length_size;
02119 
02120       if (pubnames.pn_version != 2 && pubnames.pn_version != 3)
02121        {
02122          static int warned = 0;
02123 
02124          if (! warned)
02125            {
02126              warn (_("Only DWARF 2 and 3 pubnames are currently supported\n"));
02127              warned = 1;
02128            }
02129 
02130          continue;
02131        }
02132 
02133       printf (_("  Length:                              %ld\n"),
02134              pubnames.pn_length);
02135       printf (_("  Version:                             %d\n"),
02136              pubnames.pn_version);
02137       printf (_("  Offset into .debug_info section:     %ld\n"),
02138              pubnames.pn_offset);
02139       printf (_("  Size of area in .debug_info section: %ld\n"),
02140              pubnames.pn_size);
02141 
02142       printf (_("\n    Offset\tName\n"));
02143 
02144       do
02145        {
02146          offset = byte_get (data, offset_size);
02147 
02148          if (offset != 0)
02149            {
02150              data += offset_size;
02151              printf ("    %-6ld\t\t%s\n", offset, data);
02152              data += strlen ((char *) data) + 1;
02153            }
02154        }
02155       while (offset != 0);
02156     }
02157 
02158   printf ("\n");
02159   return 1;
02160 }
02161 
02162 static int
02163 display_debug_macinfo (struct dwarf_section *section,
02164                      void *file ATTRIBUTE_UNUSED)
02165 {
02166   unsigned char *start = section->start;
02167   unsigned char *end = start + section->size;
02168   unsigned char *curr = start;
02169   unsigned int bytes_read;
02170   enum dwarf_macinfo_record_type op;
02171 
02172   printf (_("Contents of the %s section:\n\n"), section->name);
02173 
02174   while (curr < end)
02175     {
02176       unsigned int lineno;
02177       const char *string;
02178 
02179       op = *curr;
02180       curr++;
02181 
02182       switch (op)
02183        {
02184        case DW_MACINFO_start_file:
02185          {
02186            unsigned int filenum;
02187 
02188            lineno = read_leb128 (curr, & bytes_read, 0);
02189            curr += bytes_read;
02190            filenum = read_leb128 (curr, & bytes_read, 0);
02191            curr += bytes_read;
02192 
02193            printf (_(" DW_MACINFO_start_file - lineno: %d filenum: %d\n"),
02194                   lineno, filenum);
02195          }
02196          break;
02197 
02198        case DW_MACINFO_end_file:
02199          printf (_(" DW_MACINFO_end_file\n"));
02200          break;
02201 
02202        case DW_MACINFO_define:
02203          lineno = read_leb128 (curr, & bytes_read, 0);
02204          curr += bytes_read;
02205          string = (char *) curr;
02206          curr += strlen (string) + 1;
02207          printf (_(" DW_MACINFO_define - lineno : %d macro : %s\n"),
02208                 lineno, string);
02209          break;
02210 
02211        case DW_MACINFO_undef:
02212          lineno = read_leb128 (curr, & bytes_read, 0);
02213          curr += bytes_read;
02214          string = (char *) curr;
02215          curr += strlen (string) + 1;
02216          printf (_(" DW_MACINFO_undef - lineno : %d macro : %s\n"),
02217                 lineno, string);
02218          break;
02219 
02220        case DW_MACINFO_vendor_ext:
02221          {
02222            unsigned int constant;
02223 
02224            constant = read_leb128 (curr, & bytes_read, 0);
02225            curr += bytes_read;
02226            string = (char *) curr;
02227            curr += strlen (string) + 1;
02228            printf (_(" DW_MACINFO_vendor_ext - constant : %d string : %s\n"),
02229                   constant, string);
02230          }
02231          break;
02232        }
02233     }
02234 
02235   return 1;
02236 }
02237 
02238 static int
02239 display_debug_abbrev (struct dwarf_section *section,
02240                     void *file ATTRIBUTE_UNUSED)
02241 {
02242   abbrev_entry *entry;
02243   unsigned char *start = section->start;
02244   unsigned char *end = start + section->size;
02245 
02246   printf (_("Contents of the %s section:\n\n"), section->name);
02247 
02248   do
02249     {
02250       free_abbrevs ();
02251 
02252       start = process_abbrev_section (start, end);
02253 
02254       if (first_abbrev == NULL)
02255        continue;
02256 
02257       printf (_("  Number TAG\n"));
02258 
02259       for (entry = first_abbrev; entry; entry = entry->next)
02260        {
02261          abbrev_attr *attr;
02262 
02263          printf (_("   %ld      %s    [%s]\n"),
02264                 entry->entry,
02265                 get_TAG_name (entry->tag),
02266                 entry->children ? _("has children") : _("no children"));
02267 
02268          for (attr = entry->first_attr; attr; attr = attr->next)
02269            printf (_("    %-18s %s\n"),
02270                   get_AT_name (attr->attribute),
02271                   get_FORM_name (attr->form));
02272        }
02273     }
02274   while (start);
02275 
02276   printf ("\n");
02277 
02278   return 1;
02279 }
02280 
02281 static int
02282 display_debug_loc (struct dwarf_section *section, void *file)
02283 {
02284   unsigned char *start = section->start;
02285   unsigned char *section_end;
02286   unsigned long bytes;
02287   unsigned char *section_begin = start;
02288   unsigned int num_loc_list = 0;
02289   unsigned long last_offset = 0;
02290   unsigned int first = 0;
02291   unsigned int i;
02292   unsigned int j;
02293   int seen_first_offset = 0;
02294   int use_debug_info = 1;
02295   unsigned char *next;
02296 
02297   bytes = section->size;
02298   section_end = start + bytes;
02299 
02300   if (bytes == 0)
02301     {
02302       printf (_("\nThe %s section is empty.\n"), section->name);
02303       return 0;
02304     }
02305 
02306   load_debug_info (file);
02307 
02308   /* Check the order of location list in .debug_info section. If
02309      offsets of location lists are in the ascending order, we can
02310      use `debug_information' directly.  */
02311   for (i = 0; i < num_debug_info_entries; i++)
02312     {
02313       unsigned int num;
02314 
02315       num = debug_information [i].num_loc_offsets;
02316       num_loc_list += num;
02317 
02318       /* Check if we can use `debug_information' directly.  */
02319       if (use_debug_info && num != 0)
02320        {
02321          if (!seen_first_offset)
02322            {
02323              /* This is the first location list.  */
02324              last_offset = debug_information [i].loc_offsets [0];
02325              first = i;
02326              seen_first_offset = 1;
02327              j = 1;
02328            }
02329          else
02330            j = 0;
02331 
02332          for (; j < num; j++)
02333            {
02334              if (last_offset >
02335                 debug_information [i].loc_offsets [j])
02336               {
02337                 use_debug_info = 0;
02338                 break;
02339               }
02340              last_offset = debug_information [i].loc_offsets [j];
02341            }
02342        }
02343     }
02344 
02345   if (!use_debug_info)
02346     /* FIXME: Should we handle this case?  */
02347     error (_("Location lists in .debug_info section aren't in ascending order!\n"));
02348 
02349   if (!seen_first_offset)
02350     error (_("No location lists in .debug_info section!\n"));
02351 
02352   /* DWARF sections under Mach-O have non-zero addresses.  */
02353   if (debug_information [first].num_loc_offsets > 0
02354       && debug_information [first].loc_offsets [0] != section->address)
02355     warn (_("Location lists in %s section start at 0x%lx\n"),
02356          section->name, debug_information [first].loc_offsets [0]);
02357 
02358   printf (_("Contents of the %s section:\n\n"), section->name);
02359   printf (_("    Offset   Begin    End      Expression\n"));
02360 
02361   seen_first_offset = 0;
02362   for (i = first; i < num_debug_info_entries; i++)
02363     {
02364       unsigned long begin;
02365       unsigned long end;
02366       unsigned short length;
02367       unsigned long offset;
02368       unsigned int pointer_size;
02369       unsigned long cu_offset;
02370       unsigned long base_address;
02371       int need_frame_base;
02372       int has_frame_base;
02373 
02374       pointer_size = debug_information [i].pointer_size;
02375       cu_offset = debug_information [i].cu_offset;
02376 
02377       for (j = 0; j < debug_information [i].num_loc_offsets; j++)
02378        {
02379          has_frame_base = debug_information [i].have_frame_base [j];
02380          /* DWARF sections under Mach-O have non-zero addresses.  */
02381          offset = debug_information [i].loc_offsets [j] - section->address; 
02382          next = section_begin + offset;
02383          base_address = debug_information [i].base_address;
02384 
02385          if (!seen_first_offset)
02386            seen_first_offset = 1;
02387          else
02388            {
02389              if (start < next)
02390               warn (_("There is a hole [0x%lx - 0x%lx] in .debug_loc section.\n"),
02391                     (long)(start - section_begin), (long)(next - section_begin));
02392              else if (start > next)
02393               warn (_("There is an overlap [0x%lx - 0x%lx] in .debug_loc section.\n"),
02394                     (long)(start - section_begin), (long)(next - section_begin));
02395            }
02396          start = next;
02397 
02398          if (offset >= bytes)
02399            {
02400              warn (_("Offset 0x%lx is bigger than .debug_loc section size.\n"),
02401                   offset);
02402              continue;
02403            }
02404 
02405          while (1)
02406            {
02407              if (start + 2 * pointer_size > section_end)
02408               {
02409                 warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
02410                      offset);
02411                 break;
02412               }
02413 
02414              begin = byte_get (start, pointer_size);
02415              start += pointer_size;
02416              end = byte_get (start, pointer_size);
02417              start += pointer_size;
02418 
02419              if (begin == 0 && end == 0)
02420               {
02421                 printf (_("    %8.8lx <End of list>\n"), offset);
02422                 break;
02423               }
02424 
02425              /* Check base address specifiers.  */
02426              if (begin == -1UL && end != -1UL)
02427               {
02428                 base_address = end;
02429                 printf (_("    %8.8lx %8.8lx %8.8lx (base address)\n"),
02430                        offset, begin, end);
02431                 continue;
02432               }
02433 
02434              if (start + 2 > section_end)
02435               {
02436                 warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
02437                      offset);
02438                 break;
02439               }
02440 
02441              length = byte_get (start, 2);
02442              start += 2;
02443 
02444              if (start + length > section_end)
02445               {
02446                 warn (_("Location list starting at offset 0x%lx is not terminated.\n"),
02447                      offset);
02448                 break;
02449               }
02450 
02451              printf ("    %8.8lx %8.8lx %8.8lx (",
02452                     offset, begin + base_address, end + base_address);
02453              need_frame_base = decode_location_expression (start,
02454                                                      pointer_size,
02455                                                      length,
02456                                                      cu_offset);
02457              putchar (')');
02458 
02459              if (need_frame_base && !has_frame_base)
02460               printf (_(" [without DW_AT_frame_base]"));
02461 
02462              if (begin == end)
02463               fputs (_(" (start == end)"), stdout);
02464              else if (begin > end)
02465               fputs (_(" (start > end)"), stdout);
02466 
02467              putchar ('\n');
02468 
02469              start += length;
02470            }
02471        }
02472     }
02473   return 1;
02474 }
02475 
02476 static int
02477 display_debug_str (struct dwarf_section *section,
02478                  void *file ATTRIBUTE_UNUSED)
02479 {
02480   unsigned char *start = section->start;
02481   unsigned long bytes = section->size;
02482   dwarf_vma addr = section->address;
02483 
02484   if (bytes == 0)
02485     {
02486       printf (_("\nThe %s section is empty.\n"), section->name);
02487       return 0;
02488     }
02489 
02490   printf (_("Contents of the %s section:\n\n"), section->name);
02491 
02492   while (bytes)
02493     {
02494       int j;
02495       int k;
02496       int lbytes;
02497 
02498       lbytes = (bytes > 16 ? 16 : bytes);
02499 
02500       printf ("  0x%8.8lx ", (unsigned long) addr);
02501 
02502       for (j = 0; j < 16; j++)
02503        {
02504          if (j < lbytes)
02505            printf ("%2.2x", start[j]);
02506          else
02507            printf ("  ");
02508 
02509          if ((j & 3) == 3)
02510            printf (" ");
02511        }
02512 
02513       for (j = 0; j < lbytes; j++)
02514        {
02515          k = start[j];
02516          if (k >= ' ' && k < 0x80)
02517            printf ("%c", k);
02518          else
02519            printf (".");
02520        }
02521 
02522       putchar ('\n');
02523 
02524       start += lbytes;
02525       addr  += lbytes;
02526       bytes -= lbytes;
02527     }
02528 
02529   putchar ('\n');
02530 
02531   return 1;
02532 }
02533 
02534 static int
02535 display_debug_info (struct dwarf_section *section, void *file)
02536 {
02537   return process_debug_info (section, file, 0);
02538 }
02539 
02540 
02541 static int
02542 display_debug_aranges (struct dwarf_section *section,
02543                      void *file ATTRIBUTE_UNUSED)
02544 {
02545   unsigned char *start = section->start;
02546   unsigned char *end = start + section->size;
02547 
02548   printf (_("The section %s contains:\n\n"), section->name);
02549 
02550   while (start < end)
02551     {
02552       unsigned char *hdrptr;
02553       DWARF2_Internal_ARange arange;
02554       unsigned char *ranges;
02555       unsigned long length;
02556       unsigned long address;
02557       unsigned char address_size;
02558       int excess;
02559       int offset_size;
02560       int initial_length_size;
02561 
02562       hdrptr = start;
02563 
02564       arange.ar_length = byte_get (hdrptr, 4);
02565       hdrptr += 4;
02566 
02567       if (arange.ar_length == 0xffffffff)
02568        {
02569          arange.ar_length = byte_get (hdrptr, 8);
02570          hdrptr += 8;
02571          offset_size = 8;
02572          initial_length_size = 12;
02573        }
02574       else
02575        {
02576          offset_size = 4;
02577          initial_length_size = 4;
02578        }
02579 
02580       arange.ar_version = byte_get (hdrptr, 2);
02581       hdrptr += 2;
02582 
02583       arange.ar_info_offset = byte_get (hdrptr, offset_size);
02584       hdrptr += offset_size;
02585 
02586       arange.ar_pointer_size = byte_get (hdrptr, 1);
02587       hdrptr += 1;
02588 
02589       arange.ar_segment_size = byte_get (hdrptr, 1);
02590       hdrptr += 1;
02591 
02592       if (arange.ar_version != 2 && arange.ar_version != 3)
02593        {
02594          warn (_("Only DWARF 2 and 3 aranges are currently supported.\n"));
02595          break;
02596        }
02597 
02598       printf (_("  Length:                   %ld\n"), arange.ar_length);
02599       printf (_("  Version:                  %d\n"), arange.ar_version);
02600       printf (_("  Offset into .debug_info:  %lx\n"), arange.ar_info_offset);
02601       printf (_("  Pointer Size:             %d\n"), arange.ar_pointer_size);
02602       printf (_("  Segment Size:             %d\n"), arange.ar_segment_size);
02603 
02604       address_size = arange.ar_pointer_size + arange.ar_segment_size;
02605 
02606       /* The DWARF spec does not require that the address size be a power
02607         of two, but we do.  This will have to change if we ever encounter
02608         an uneven architecture.  */
02609       if ((address_size & (address_size - 1)) != 0)
02610        {
02611          warn (_("Pointer size + Segment size is not a power of two.\n"));
02612          break;
02613        }
02614       
02615       if (address_size > 4)
02616        printf (_("\n    Address            Length\n"));
02617       else
02618        printf (_("\n    Address    Length\n"));
02619 
02620       ranges = hdrptr;
02621 
02622       /* Must pad to an alignment boundary that is twice the address size.  */
02623       excess = (hdrptr - start) % (2 * address_size);
02624       if (excess)
02625        ranges += (2 * address_size) - excess;
02626 
02627       start += arange.ar_length + initial_length_size;
02628 
02629       while (ranges + 2 * address_size <= start)
02630        {
02631          address = byte_get (ranges, address_size);
02632 
02633          ranges += address_size;
02634 
02635          length  = byte_get (ranges, address_size);
02636 
02637          ranges += address_size;
02638 
02639          if (address_size > 4)
02640            printf ("    0x%16.16lx 0x%lx\n", address, length);
02641          else
02642            printf ("    0x%8.8lx 0x%lx\n", address, length);       
02643        }
02644     }
02645 
02646   printf ("\n");
02647 
02648   return 1;
02649 }
02650 
02651 static int
02652 display_debug_ranges (struct dwarf_section *section,
02653                     void *file ATTRIBUTE_UNUSED)
02654 {
02655   unsigned char *start = section->start;
02656   unsigned char *section_end;
02657   unsigned long bytes;
02658   unsigned char *section_begin = start;
02659   unsigned int num_range_list = 0;
02660   unsigned long last_offset = 0;
02661   unsigned int first = 0;
02662   unsigned int i;
02663   unsigned int j;
02664   int seen_first_offset = 0;
02665   int use_debug_info = 1;
02666   unsigned char *next;
02667 
02668   bytes = section->size;
02669   section_end = start + bytes;
02670 
02671   if (bytes == 0)
02672     {
02673       printf (_("\nThe %s section is empty.\n"), section->name);
02674       return 0;
02675     }
02676 
02677   load_debug_info (file);
02678 
02679   /* Check the order of range list in .debug_info section. If
02680      offsets of range lists are in the ascending order, we can
02681      use `debug_information' directly.  */
02682   for (i = 0; i < num_debug_info_entries; i++)
02683     {
02684       unsigned int num;
02685 
02686       num = debug_information [i].num_range_lists;
02687       num_range_list += num;
02688 
02689       /* Check if we can use `debug_information' directly.  */
02690       if (use_debug_info && num != 0)
02691        {
02692          if (!seen_first_offset)
02693            {
02694              /* This is the first range list.  */
02695              last_offset = debug_information [i].range_lists [0];
02696              first = i;
02697              seen_first_offset = 1;
02698              j = 1;
02699            }
02700          else
02701            j = 0;
02702 
02703          for (; j < num; j++)
02704            {
02705              if (last_offset >
02706                 debug_information [i].range_lists [j])
02707               {
02708                 use_debug_info = 0;
02709                 break;
02710               }
02711              last_offset = debug_information [i].range_lists [j];
02712            }
02713        }
02714     }
02715 
02716   if (!use_debug_info)
02717     /* FIXME: Should we handle this case?  */
02718     error (_("Range lists in .debug_info section aren't in ascending order!\n"));
02719 
02720   if (!seen_first_offset)
02721     error (_("No range lists in .debug_info section!\n"));
02722 
02723   /* DWARF sections under Mach-O have non-zero addresses.  */
02724   if (debug_information [first].num_range_lists > 0
02725       && debug_information [first].range_lists [0] != section->address)
02726     warn (_("Range lists in %s section start at 0x%lx\n"),
02727          section->name, debug_information [first].range_lists [0]);
02728 
02729   printf (_("Contents of the %s section:\n\n"), section->name);
02730   printf (_("    Offset   Begin    End\n"));
02731 
02732   seen_first_offset = 0;
02733   for (i = first; i < num_debug_info_entries; i++)
02734     {
02735       unsigned long begin;
02736       unsigned long end;
02737       unsigned long offset;
02738       unsigned int pointer_size;
02739       unsigned long base_address;
02740 
02741       pointer_size = debug_information [i].pointer_size;
02742 
02743       for (j = 0; j < debug_information [i].num_range_lists; j++)
02744        {
02745          /* DWARF sections under Mach-O have non-zero addresses.  */
02746          offset = debug_information [i].range_lists [j] - section->address;
02747          next = section_begin + offset;
02748          base_address = debug_information [i].base_address;
02749 
02750          if (!seen_first_offset)
02751            seen_first_offset = 1;
02752          else
02753            {
02754              if (start < next)
02755               warn (_("There is a hole [0x%lx - 0x%lx] in %s section.\n"),
02756                     (long)(start - section_begin),
02757                     (long)(next - section_begin), section->name);
02758              else if (start > next)
02759               warn (_("There is an overlap [0x%lx - 0x%lx] in %s section.\n"),
02760                     (long)(start - section_begin),
02761                     (long)(next - section_begin), section->name);
02762            }
02763          start = next;
02764 
02765          while (1)
02766            {
02767              begin = byte_get (start, pointer_size);
02768              start += pointer_size;
02769              end = byte_get (start, pointer_size);
02770              start += pointer_size;
02771 
02772              if (begin == 0 && end == 0)
02773               {
02774                 printf (_("    %8.8lx <End of list>\n"), offset);
02775                 break;
02776               }
02777 
02778              /* Check base address specifiers.  */
02779              if (begin == -1UL && end != -1UL)
02780               {
02781                 base_address = end;
02782                 printf ("    %8.8lx %8.8lx %8.8lx (base address)\n",
02783                        offset, begin, end);
02784                 continue;
02785               }
02786 
02787              printf ("    %8.8lx %8.8lx %8.8lx",
02788                     offset, begin + base_address, end + base_address);
02789 
02790              if (begin == end)
02791               fputs (_(" (start == end)"), stdout);
02792              else if (begin > end)
02793               fputs (_(" (start > end)"), stdout);
02794 
02795              putchar ('\n');
02796            }
02797        }
02798     }
02799   putchar ('\n');
02800   return 1;
02801 }
02802 
02803 typedef struct Frame_Chunk
02804 {
02805   struct Frame_Chunk *next;
02806   unsigned char *chunk_start;
02807   int ncols;
02808   /* DW_CFA_{undefined,same_value,offset,register,unreferenced}  */
02809   short int *col_type;
02810   int *col_offset;
02811   char *augmentation;
02812   unsigned int code_factor;
02813   int data_factor;
02814   unsigned long pc_begin;
02815   unsigned long pc_range;
02816   int cfa_reg;
02817   int cfa_offset;
02818   int ra;
02819   unsigned char fde_encoding;
02820   unsigned char cfa_exp;
02821 }
02822 Frame_Chunk;
02823 
02824 /* A marker for a col_type that means this column was never referenced
02825    in the frame info.  */
02826 #define DW_CFA_unreferenced (-1)
02827 
02828 static void
02829 frame_need_space (Frame_Chunk *fc, int reg)
02830 {
02831   int prev = fc->ncols;
02832 
02833   if (reg < fc->ncols)
02834     return;
02835 
02836   fc->ncols = reg + 1;
02837   fc->col_type = xcrealloc (fc->col_type, fc->ncols, sizeof (short int));
02838   fc->col_offset = xcrealloc (fc->col_offset, fc->ncols, sizeof (int));
02839 
02840   while (prev < fc->ncols)
02841     {
02842       fc->col_type[prev] = DW_CFA_unreferenced;
02843       fc->col_offset[prev] = 0;
02844       prev++;
02845     }
02846 }
02847 
02848 static void
02849 frame_display_row (Frame_Chunk *fc, int *need_col_headers, int *max_regs)
02850 {
02851   int r;
02852   char tmp[100];
02853 
02854   if (*max_regs < fc->ncols)
02855     *max_regs = fc->ncols;
02856 
02857   if (*need_col_headers)
02858     {
02859       *need_col_headers = 0;
02860 
02861       printf ("   LOC   CFA      ");
02862 
02863       for (r = 0; r < *max_regs; r++)
02864        if (fc->col_type[r] != DW_CFA_unreferenced)
02865          {
02866            if (r == fc->ra)
02867              printf ("ra   ");
02868            else
02869              printf ("r%-4d", r);
02870          }
02871 
02872       printf ("\n");
02873     }
02874 
02875   printf ("%08lx ", fc->pc_begin);
02876   if (fc->cfa_exp)
02877     strcpy (tmp, "exp");
02878   else
02879     sprintf (tmp, "r%d%+d", fc->cfa_reg, fc->cfa_offset);
02880   printf ("%-8s ", tmp);
02881 
02882   for (r = 0; r < fc->ncols; r++)
02883     {
02884       if (fc->col_type[r] != DW_CFA_unreferenced)
02885        {
02886          switch (fc->col_type[r])
02887            {
02888            case DW_CFA_undefined:
02889              strcpy (tmp, "u");
02890              break;
02891            case DW_CFA_same_value:
02892              strcpy (tmp, "s");
02893              break;
02894            case DW_CFA_offset:
02895              sprintf (tmp, "c%+d", fc->col_offset[r]);
02896              break;
02897            case DW_CFA_val_offset:
02898              sprintf (tmp, "v%+d", fc->col_offset[r]);
02899              break;
02900            case DW_CFA_register:
02901              sprintf (tmp, "r%d", fc->col_offset[r]);
02902              break;
02903            case DW_CFA_expression:
02904              strcpy (tmp, "exp");
02905              break;
02906            case DW_CFA_val_expression:
02907              strcpy (tmp, "vexp");
02908              break;
02909            default:
02910              strcpy (tmp, "n/a");
02911              break;
02912            }
02913          printf ("%-5s", tmp);
02914        }
02915     }
02916   printf ("\n");
02917 }
02918 
02919 static int
02920 size_of_encoded_value (int encoding)
02921 {
02922   switch (encoding & 0x7)
02923     {
02924     default:  /* ??? */
02925     case 0:   return eh_addr_size;
02926     case 2:   return 2;
02927     case 3:   return 4;
02928     case 4:   return 8;
02929     }
02930 }
02931 
02932 static dwarf_vma
02933 get_encoded_value (unsigned char *data, int encoding)
02934 {
02935   int size = size_of_encoded_value (encoding);
02936 
02937   if (encoding & DW_EH_PE_signed)
02938     return byte_get_signed (data, size);
02939   else
02940     return byte_get (data, size);
02941 }
02942 
02943 #define GET(N)       byte_get (start, N); start += N
02944 #define LEB() read_leb128 (start, & length_return, 0); start += length_return
02945 #define SLEB()       read_leb128 (start, & length_return, 1); start += length_return
02946 
02947 static int
02948 display_debug_frames (struct dwarf_section *section,
02949                     void *file ATTRIBUTE_UNUSED)
02950 {
02951   unsigned char *start = section->start;
02952   unsigned char *end = start + section->size;
02953   unsigned char *section_start = start;
02954   Frame_Chunk *chunks = 0;
02955   Frame_Chunk *remembered_state = 0;
02956   Frame_Chunk *rs;
02957   int is_eh = strcmp (section->name, ".eh_frame") == 0;
02958   unsigned int length_return;
02959   int max_regs = 0;
02960 
02961   printf (_("The section %s contains:\n"), section->name);
02962 
02963   while (start < end)
02964     {
02965       unsigned char *saved_start;
02966       unsigned char *block_end;
02967       unsigned long length;
02968       unsigned long cie_id;
02969       Frame_Chunk *fc;
02970       Frame_Chunk *cie;
02971       int need_col_headers = 1;
02972       unsigned char *augmentation_data = NULL;
02973       unsigned long augmentation_data_len = 0;
02974       int encoded_ptr_size = eh_addr_size;
02975       int offset_size;
02976       int initial_length_size;
02977 
02978       saved_start = start;
02979       length = byte_get (start, 4); start += 4;
02980 
02981       if (length == 0)
02982        {
02983          printf ("\n%08lx ZERO terminator\n\n",
02984                   (unsigned long)(saved_start - section_start));
02985          continue;
02986        }
02987 
02988       if (length == 0xffffffff)
02989        {
02990          length = byte_get (start, 8);
02991          start += 8;
02992          offset_size = 8;
02993          initial_length_size = 12;
02994        }
02995       else
02996        {
02997          offset_size = 4;
02998          initial_length_size = 4;
02999        }
03000 
03001       block_end = saved_start + length + initial_length_size;
03002       if (block_end > end)
03003        {
03004          warn ("Invalid length %#08lx in FDE at %#08lx\n",
03005               length, (unsigned long)(saved_start - section_start));
03006          block_end = end;
03007        }
03008       cie_id = byte_get (start, offset_size); start += offset_size;
03009 
03010       if (is_eh ? (cie_id == 0) : (cie_id == DW_CIE_ID))
03011        {
03012          int version;
03013 
03014          fc = xmalloc (sizeof (Frame_Chunk));
03015          memset (fc, 0, sizeof (Frame_Chunk));
03016 
03017          fc->next = chunks;
03018          chunks = fc;
03019          fc->chunk_start = saved_start;
03020          fc->ncols = 0;
03021          fc->col_type = xmalloc (sizeof (short int));
03022          fc->col_offset = xmalloc (sizeof (int));
03023          frame_need_space (fc, max_regs-1);
03024 
03025          version = *start++;
03026 
03027          fc->augmentation = (char *) start;
03028          start = (unsigned char *) strchr ((char *) start, '\0') + 1;
03029 
03030          if (fc->augmentation[0] == 'z')
03031            {
03032              fc->code_factor = LEB ();
03033              fc->data_factor = SLEB ();
03034              if (version == 1)
03035               {
03036                 fc->ra = GET (1);
03037               }
03038              else
03039               {
03040                 fc->ra = LEB ();
03041               }
03042              augmentation_data_len = LEB ();
03043              augmentation_data = start;
03044              start += augmentation_data_len;
03045            }
03046          else if (strcmp (fc->augmentation, "eh") == 0)
03047            {
03048              start += eh_addr_size;
03049              fc->code_factor = LEB ();
03050              fc->data_factor = SLEB ();
03051              if (version == 1)
03052               {
03053                 fc->ra = GET (1);
03054               }
03055              else
03056               {
03057                 fc->ra = LEB ();
03058               }
03059            }
03060          else
03061            {
03062              fc->code_factor = LEB ();
03063              fc->data_factor = SLEB ();
03064              if (version == 1)
03065               {
03066                 fc->ra = GET (1);
03067               }
03068              else
03069               {
03070                 fc->ra = LEB ();
03071               }
03072            }
03073          cie = fc;
03074 
03075          if (do_debug_frames_interp)
03076            printf ("\n%08lx %08lx %08lx CIE \"%s\" cf=%d df=%d ra=%d\n",
03077                   (unsigned long)(saved_start - section_start), length, cie_id,
03078                   fc->augmentation, fc->code_factor, fc->data_factor,
03079                   fc->ra);
03080          else
03081            {
03082              printf ("\n%08lx %08lx %08lx CIE\n",
03083                     (unsigned long)(saved_start - section_start), length, cie_id);
03084              printf ("  Version:               %d\n", version);
03085              printf ("  Augmentation:          \"%s\"\n", fc->augmentation);
03086              printf ("  Code alignment factor: %u\n", fc->code_factor);
03087              printf ("  Data alignment factor: %d\n", fc->data_factor);
03088              printf ("  Return address column: %d\n", fc->ra);
03089 
03090              if (augmentation_data_len)
03091               {
03092                 unsigned long i;
03093                 printf ("  Augmentation data:    ");
03094                 for (i = 0; i < augmentation_data_len; ++i)
03095                   printf (" %02x", augmentation_data[i]);
03096                 putchar ('\n');
03097               }
03098              putchar ('\n');
03099            }
03100 
03101          if (augmentation_data_len)
03102            {
03103              unsigned char *p, *q;
03104              p = (unsigned char *) fc->augmentation + 1;
03105              q = augmentation_data;
03106 
03107              while (1)
03108               {
03109                 if (*p == 'L')
03110                   q++;
03111                 else if (*p == 'P')
03112                   q += 1 + size_of_encoded_value (*q);
03113                 else if (*p == 'R')
03114                   fc->fde_encoding = *q++;
03115                 else
03116                   break;
03117                 p++;
03118               }
03119 
03120              if (fc->fde_encoding)
03121               encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
03122            }
03123 
03124          frame_need_space (fc, fc->ra);
03125        }
03126       else
03127        {
03128          unsigned char *look_for;
03129          static Frame_Chunk fde_fc;
03130 
03131          fc = & fde_fc;
03132          memset (fc, 0, sizeof (Frame_Chunk));
03133 
03134          look_for = is_eh ? start - 4 - cie_id : section_start + cie_id;
03135 
03136          for (cie = chunks; cie ; cie = cie->next)
03137            if (cie->chunk_start == look_for)
03138              break;
03139 
03140          if (!cie)
03141            {
03142              warn ("Invalid CIE pointer %#08lx in FDE at %#08lx\n",
03143                   cie_id, (unsigned long)(saved_start - section_start));
03144              fc->ncols = 0;
03145              fc->col_type = xmalloc (sizeof (short int));
03146              fc->col_offset = xmalloc (sizeof (int));
03147              frame_need_space (fc, max_regs - 1);
03148              cie = fc;
03149              fc->augmentation = "";
03150              fc->fde_encoding = 0;
03151            }
03152          else
03153            {
03154              fc->ncols = cie->ncols;
03155              fc->col_type = xcmalloc (fc->ncols, sizeof (short int));
03156              fc->col_offset = xcmalloc (fc->ncols, sizeof (int));
03157              memcpy (fc->col_type, cie->col_type, fc->ncols * sizeof (short int));
03158              memcpy (fc->col_offset, cie->col_offset, fc->ncols * sizeof (int));
03159              fc->augmentation = cie->augmentation;
03160              fc->code_factor = cie->code_factor;
03161              fc->data_factor = cie->data_factor;
03162              fc->cfa_reg = cie->cfa_reg;
03163              fc->cfa_offset = cie->cfa_offset;
03164              fc->ra = cie->ra;
03165              frame_need_space (fc, max_regs-1);
03166              fc->fde_encoding = cie->fde_encoding;
03167            }
03168 
03169          if (fc->fde_encoding)
03170            encoded_ptr_size = size_of_encoded_value (fc->fde_encoding);
03171 
03172          fc->pc_begin = get_encoded_value (start, fc->fde_encoding);
03173          if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
03174              /* Don't adjust for relocatable file since there's
03175                invariably a pcrel reloc here, which we haven't
03176                applied.  */
03177              && !is_relocatable)
03178            fc->pc_begin += section->address + (start - section_start);
03179          start += encoded_ptr_size;
03180          fc->pc_range = byte_get (start, encoded_ptr_size);
03181          start += encoded_ptr_size;
03182 
03183          if (cie->augmentation[0] == 'z')
03184            {
03185              augmentation_data_len = LEB ();
03186              augmentation_data = start;
03187              start += augmentation_data_len;
03188            }
03189 
03190          printf ("\n%08lx %08lx %08lx FDE cie=%08lx pc=%08lx..%08lx\n",
03191                 (unsigned long)(saved_start - section_start), length, cie_id,
03192                 (unsigned long)(cie->chunk_start - section_start),
03193                 fc->pc_begin, fc->pc_begin + fc->pc_range);
03194          if (! do_debug_frames_interp && augmentation_data_len)
03195            {
03196              unsigned long i;
03197 
03198              printf ("  Augmentation data:    ");
03199              for (i = 0; i < augmentation_data_len; ++i)
03200               printf (" %02x", augmentation_data[i]);
03201              putchar ('\n');
03202              putchar ('\n');
03203            }
03204        }
03205 
03206       /* At this point, fc is the current chunk, cie (if any) is set, and
03207         we're about to interpret instructions for the chunk.  */
03208       /* ??? At present we need to do this always, since this sizes the
03209         fc->col_type and fc->col_offset arrays, which we write into always.
03210         We should probably split the interpreted and non-interpreted bits
03211         into two different routines, since there's so much that doesn't
03212         really overlap between them.  */
03213       if (1 || do_debug_frames_interp)
03214        {
03215          /* Start by making a pass over the chunk, allocating storage
03216             and taking note of what registers are used.  */
03217          unsigned char *tmp = start;
03218 
03219          while (start < block_end)
03220            {
03221              unsigned op, opa;
03222              unsigned long reg, tmp;
03223 
03224              op = *start++;
03225              opa = op & 0x3f;
03226              if (op & 0xc0)
03227               op &= 0xc0;
03228 
03229              /* Warning: if you add any more cases to this switch, be
03230                sure to add them to the corresponding switch below.  */
03231              switch (op)
03232               {
03233               case DW_CFA_advance_loc:
03234                 break;
03235               case DW_CFA_offset:
03236                 LEB ();
03237                 frame_need_space (fc, opa);
03238                 fc->col_type[opa] = DW_CFA_undefined;
03239                 break;
03240               case DW_CFA_restore:
03241                 frame_need_space (fc, opa);
03242                 fc->col_type[opa] = DW_CFA_undefined;
03243                 break;
03244               case DW_CFA_set_loc:
03245                 start += encoded_ptr_size;
03246                 break;
03247               case DW_CFA_advance_loc1:
03248                 start += 1;
03249                 break;
03250               case DW_CFA_advance_loc2:
03251                 start += 2;
03252                 break;
03253               case DW_CFA_advance_loc4:
03254                 start += 4;
03255                 break;
03256               case DW_CFA_offset_extended:
03257               case DW_CFA_val_offset:
03258                 reg = LEB (); LEB ();
03259                 frame_need_space (fc, reg);
03260                 fc->col_type[reg] = DW_CFA_undefined;
03261                 break;
03262               case DW_CFA_restore_extended:
03263                 reg = LEB ();
03264                 frame_need_space (fc, reg);
03265                 fc->col_type[reg] = DW_CFA_undefined;
03266                 break;
03267               case DW_CFA_undefined:
03268                 reg = LEB ();
03269                 frame_need_space (fc, reg);
03270                 fc->col_type[reg] = DW_CFA_undefined;
03271                 break;
03272               case DW_CFA_same_value:
03273                 reg = LEB ();
03274                 frame_need_space (fc, reg);
03275                 fc->col_type[reg] = DW_CFA_undefined;
03276                 break;
03277               case DW_CFA_register:
03278                 reg = LEB (); LEB ();
03279                 frame_need_space (fc, reg);
03280                 fc->col_type[reg] = DW_CFA_undefined;
03281                 break;
03282               case DW_CFA_def_cfa:
03283                 LEB (); LEB ();
03284                 break;
03285               case DW_CFA_def_cfa_register:
03286                 LEB ();
03287                 break;
03288               case DW_CFA_def_cfa_offset:
03289                 LEB ();
03290                 break;
03291               case DW_CFA_def_cfa_expression:
03292                 tmp = LEB ();
03293                 start += tmp;
03294                 break;
03295               case DW_CFA_expression:
03296               case DW_CFA_val_expression:
03297                 reg = LEB ();
03298                 tmp = LEB ();
03299                 start += tmp;
03300                 frame_need_space (fc, reg);
03301                 fc->col_type[reg] = DW_CFA_undefined;
03302                 break;
03303               case DW_CFA_offset_extended_sf:
03304               case DW_CFA_val_offset_sf:
03305                 reg = LEB (); SLEB ();
03306                 frame_need_space (fc, reg);
03307                 fc->col_type[reg] = DW_CFA_undefined;
03308                 break;
03309               case DW_CFA_def_cfa_sf:
03310                 LEB (); SLEB ();
03311                 break;
03312               case DW_CFA_def_cfa_offset_sf:
03313                 SLEB ();
03314                 break;
03315               case DW_CFA_MIPS_advance_loc8:
03316                 start += 8;
03317                 break;
03318               case DW_CFA_GNU_args_size:
03319                 LEB ();
03320                 break;
03321               case DW_CFA_GNU_negative_offset_extended:
03322                 reg = LEB (); LEB ();
03323                 frame_need_space (fc, reg);
03324                 fc->col_type[reg] = DW_CFA_undefined;
03325 
03326               default:
03327                 break;
03328               }
03329            }
03330          start = tmp;
03331        }
03332 
03333       /* Now we know what registers are used, make a second pass over
03334         the chunk, this time actually printing out the info.  */
03335 
03336       while (start < block_end)
03337        {
03338          unsigned op, opa;
03339          unsigned long ul, reg, roffs;
03340          long l, ofs;
03341          dwarf_vma vma;
03342 
03343          op = *start++;
03344          opa = op & 0x3f;
03345          if (op & 0xc0)
03346            op &= 0xc0;
03347 
03348          /* Warning: if you add any more cases to this switch, be
03349             sure to add them to the corresponding switch above.  */
03350          switch (op)
03351            {
03352            case DW_CFA_advance_loc:
03353              if (do_debug_frames_interp)
03354               frame_display_row (fc, &need_col_headers, &max_regs);
03355              else
03356               printf ("  DW_CFA_advance_loc: %d to %08lx\n",
03357                      opa * fc->code_factor,
03358                      fc->pc_begin + opa * fc->code_factor);
03359              fc->pc_begin += opa * fc->code_factor;
03360              break;
03361 
03362            case DW_CFA_offset:
03363              roffs = LEB ();
03364              if (! do_debug_frames_interp)
03365               printf ("  DW_CFA_offset: r%d at cfa%+ld\n",
03366                      opa, roffs * fc->data_factor);
03367              fc->col_type[opa] = DW_CFA_offset;
03368              fc->col_offset[opa] = roffs * fc->data_factor;
03369              break;
03370 
03371            case DW_CFA_restore:
03372              if (! do_debug_frames_interp)
03373               printf ("  DW_CFA_restore: r%d\n", opa);
03374              fc->col_type[opa] = cie->col_type[opa];
03375              fc->col_offset[opa] = cie->col_offset[opa];
03376              break;
03377 
03378            case DW_CFA_set_loc:
03379              vma = get_encoded_value (start, fc->fde_encoding);
03380              if ((fc->fde_encoding & 0x70) == DW_EH_PE_pcrel
03381                 && !is_relocatable)
03382               vma += section->address + (start - section_start);
03383              start += encoded_ptr_size;
03384              if (do_debug_frames_interp)
03385               frame_display_row (fc, &need_col_headers, &max_regs);
03386              else
03387               printf ("  DW_CFA_set_loc: %08lx\n", (unsigned long)vma);
03388              fc->pc_begin = vma;
03389              break;
03390 
03391            case DW_CFA_advance_loc1:
03392              ofs = byte_get (start, 1); start += 1;
03393              if (do_debug_frames_interp)
03394               frame_display_row (fc, &need_col_headers, &max_regs);
03395              else
03396               printf ("  DW_CFA_advance_loc1: %ld to %08lx\n",
03397                      ofs * fc->code_factor,
03398                      fc->pc_begin + ofs * fc->code_factor);
03399              fc->pc_begin += ofs * fc->code_factor;
03400              break;
03401 
03402            case DW_CFA_advance_loc2:
03403              ofs = byte_get (start, 2); start += 2;
03404              if (do_debug_frames_interp)
03405               frame_display_row (fc, &need_col_headers, &max_regs);
03406              else
03407               printf ("  DW_CFA_advance_loc2: %ld to %08lx\n",
03408                      ofs * fc->code_factor,
03409                      fc->pc_begin + ofs * fc->code_factor);
03410              fc->pc_begin += ofs * fc->code_factor;
03411              break;
03412 
03413            case DW_CFA_advance_loc4:
03414              ofs = byte_get (start, 4); start += 4;
03415              if (do_debug_frames_interp)
03416               frame_display_row (fc, &need_col_headers, &max_regs);
03417              else
03418               printf ("  DW_CFA_advance_loc4: %ld to %08lx\n",
03419                      ofs * fc->code_factor,
03420                      fc->pc_begin + ofs * fc->code_factor);
03421              fc->pc_begin += ofs * fc->code_factor;
03422              break;
03423 
03424            case DW_CFA_offset_extended:
03425              reg = LEB ();
03426              roffs = LEB ();
03427              if (! do_debug_frames_interp)
03428               printf ("  DW_CFA_offset_extended: r%ld at cfa%+ld\n",
03429                      reg, roffs * fc->data_factor);
03430              fc->col_type[reg] = DW_CFA_offset;
03431              fc->col_offset[reg] = roffs * fc->data_factor;
03432              break;
03433 
03434            case DW_CFA_val_offset:
03435              reg = LEB ();
03436              roffs = LEB ();
03437              if (! do_debug_frames_interp)
03438               printf ("  DW_CFA_val_offset: r%ld at cfa%+ld\n",
03439                      reg, roffs * fc->data_factor);
03440              fc->col_type[reg] = DW_CFA_val_offset;
03441              fc->col_offset[reg] = roffs * fc->data_factor;
03442              break;
03443 
03444            case DW_CFA_restore_extended:
03445              reg = LEB ();
03446              if (! do_debug_frames_interp)
03447               printf ("  DW_CFA_restore_extended: r%ld\n", reg);
03448              fc->col_type[reg] = cie->col_type[reg];
03449              fc->col_offset[reg] = cie->col_offset[reg];
03450              break;
03451 
03452            case DW_CFA_undefined:
03453              reg = LEB ();
03454              if (! do_debug_frames_interp)
03455               printf ("  DW_CFA_undefined: r%ld\n", reg);
03456              fc->col_type[reg] = DW_CFA_undefined;
03457              fc->col_offset[reg] = 0;
03458              break;
03459 
03460            case DW_CFA_same_value:
03461              reg = LEB ();
03462              if (! do_debug_frames_interp)
03463               printf ("  DW_CFA_same_value: r%ld\n", reg);
03464              fc->col_type[reg] = DW_CFA_same_value;
03465              fc->col_offset[reg] = 0;
03466              break;
03467 
03468            case DW_CFA_register:
03469              reg = LEB ();
03470              roffs = LEB ();
03471              if (! do_debug_frames_interp)
03472               printf ("  DW_CFA_register: r%ld in r%ld\n", reg, roffs);
03473              fc->col_type[reg] = DW_CFA_register;
03474              fc->col_offset[reg] = roffs;
03475              break;
03476 
03477            case DW_CFA_remember_state:
03478              if (! do_debug_frames_interp)
03479               printf ("  DW_CFA_remember_state\n");
03480              rs = xmalloc (sizeof (Frame_Chunk));
03481              rs->ncols = fc->ncols;
03482              rs->col_type = xcmalloc (rs->ncols, sizeof (short int));
03483              rs->col_offset = xcmalloc (rs->ncols, sizeof (int));
03484              memcpy (rs->col_type, fc->col_type, rs->ncols);
03485              memcpy (rs->col_offset, fc->col_offset, rs->ncols * sizeof (int));
03486              rs->next = remembered_state;
03487              remembered_state = rs;
03488              break;
03489 
03490            case DW_CFA_restore_state:
03491              if (! do_debug_frames_interp)
03492               printf ("  DW_CFA_restore_state\n");
03493              rs = remembered_state;
03494              if (rs)
03495               {
03496                 remembered_state = rs->next;
03497                 frame_need_space (fc, rs->ncols-1);
03498                 memcpy (fc->col_type, rs->col_type, rs->ncols);
03499                 memcpy (fc->col_offset, rs->col_offset,
03500                        rs->ncols * sizeof (int));
03501                 free (rs->col_type);
03502                 free (rs->col_offset);
03503                 free (rs);
03504               }
03505              else if (do_debug_frames_interp)
03506               printf ("Mismatched DW_CFA_restore_state\n");
03507              break;
03508 
03509            case DW_CFA_def_cfa:
03510              fc->cfa_reg = LEB ();
03511              fc->cfa_offset = LEB ();
03512              fc->cfa_exp = 0;
03513              if (! do_debug_frames_interp)
03514               printf ("  DW_CFA_def_cfa: r%d ofs %d\n",
03515                      fc->cfa_reg, fc->cfa_offset);
03516              break;
03517 
03518            case DW_CFA_def_cfa_register:
03519              fc->cfa_reg = LEB ();
03520              fc->cfa_exp = 0;
03521              if (! do_debug_frames_interp)
03522               printf ("  DW_CFA_def_cfa_reg: r%d\n", fc->cfa_reg);
03523              break;
03524 
03525            case DW_CFA_def_cfa_offset:
03526              fc->cfa_offset = LEB ();
03527              if (! do_debug_frames_interp)
03528               printf ("  DW_CFA_def_cfa_offset: %d\n", fc->cfa_offset);
03529              break;
03530 
03531            case DW_CFA_nop:
03532              if (! do_debug_frames_interp)
03533               printf ("  DW_CFA_nop\n");
03534              break;
03535 
03536            case DW_CFA_def_cfa_expression:
03537              ul = LEB ();
03538              if (! do_debug_frames_interp)
03539               {
03540                 printf ("  DW_CFA_def_cfa_expression (");
03541                 decode_location_expression (start, eh_addr_size, ul, 0);
03542                 printf (")\n");
03543               }
03544              fc->cfa_exp = 1;
03545              start += ul;
03546              break;
03547 
03548            case DW_CFA_expression:
03549              reg = LEB ();
03550              ul = LEB ();
03551              if (! do_debug_frames_interp)
03552               {
03553                 printf ("  DW_CFA_expression: r%ld (", reg);
03554                 decode_location_expression (start, eh_addr_size, ul, 0);
03555                 printf (")\n");
03556               }
03557              fc->col_type[reg] = DW_CFA_expression;
03558              start += ul;
03559              break;
03560 
03561            case DW_CFA_val_expression:
03562              reg = LEB ();
03563              ul = LEB ();
03564              if (! do_debug_frames_interp)
03565               {
03566                 printf ("  DW_CFA_val_expression: r%ld (", reg);
03567                 decode_location_expression (start, eh_addr_size, ul, 0);
03568                 printf (")\n");
03569               }
03570              fc->col_type[reg] = DW_CFA_val_expression;
03571              start += ul;
03572              break;
03573 
03574            case DW_CFA_offset_extended_sf:
03575              reg = LEB ();
03576              l = SLEB ();
03577              frame_need_space (fc, reg);
03578              if (! do_debug_frames_interp)
03579               printf ("  DW_CFA_offset_extended_sf: r%ld at cfa%+ld\n",
03580                      reg, l * fc->data_factor);
03581              fc->col_type[reg] = DW_CFA_offset;
03582              fc->col_offset[reg] = l * fc->data_factor;
03583              break;
03584 
03585            case DW_CFA_val_offset_sf:
03586              reg = LEB ();
03587              l = SLEB ();
03588              frame_need_space (fc, reg);
03589              if (! do_debug_frames_interp)
03590               printf ("  DW_CFA_val_offset_sf: r%ld at cfa%+ld\n",
03591                      reg, l * fc->data_factor);
03592              fc->col_type[reg] = DW_CFA_val_offset;
03593              fc->col_offset[reg] = l * fc->data_factor;
03594              break;
03595 
03596            case DW_CFA_def_cfa_sf:
03597              fc->cfa_reg = LEB ();
03598              fc->cfa_offset = SLEB ();
03599              fc->cfa_offset = fc->cfa_offset * fc->data_factor;
03600              fc->cfa_exp = 0;
03601              if (! do_debug_frames_interp)
03602               printf ("  DW_CFA_def_cfa_sf: r%d ofs %d\n",
03603                      fc->cfa_reg, fc->cfa_offset);
03604              break;
03605 
03606            case DW_CFA_def_cfa_offset_sf:
03607              fc->cfa_offset = SLEB ();
03608              fc->cfa_offset = fc->cfa_offset * fc->data_factor;
03609              if (! do_debug_frames_interp)
03610               printf ("  DW_CFA_def_cfa_offset_sf: %d\n", fc->cfa_offset);
03611              break;
03612 
03613            case DW_CFA_MIPS_advance_loc8:
03614              ofs = byte_get (start, 8); start += 8;
03615              if (do_debug_frames_interp)
03616               frame_display_row (fc, &need_col_headers, &max_regs);
03617              else
03618               printf ("  DW_CFA_MIPS_advance_loc8: %ld to %08lx\n",
03619                      ofs * fc->code_factor,
03620                      fc->pc_begin + ofs * fc->code_factor);
03621              fc->pc_begin += ofs * fc->code_factor;
03622              break;
03623 
03624            case DW_CFA_GNU_window_save:
03625              if (! do_debug_frames_interp)
03626               printf ("  DW_CFA_GNU_window_save\n");
03627              break;
03628 
03629            case DW_CFA_GNU_args_size:
03630              ul = LEB ();
03631              if (! do_debug_frames_interp)
03632               printf ("  DW_CFA_GNU_args_size: %ld\n", ul);
03633              break;
03634 
03635            case DW_CFA_GNU_negative_offset_extended:
03636              reg = LEB ();
03637              l = - LEB ();
03638              frame_need_space (fc, reg);
03639              if (! do_debug_frames_interp)
03640               printf ("  DW_CFA_GNU_negative_offset_extended: r%ld at cfa%+ld\n",
03641                      reg, l * fc->data_factor);
03642              fc->col_type[reg] = DW_CFA_offset;
03643              fc->col_offset[reg] = l * fc->data_factor;
03644              break;
03645 
03646            default:
03647              if (op >= DW_CFA_lo_user && op <= DW_CFA_hi_user)
03648               printf (_("  DW_CFA_??? (User defined call frame op: %#x)\n"), op);
03649              else
03650               warn (_("unsupported or unknown Dwarf Call Frame Instruction number: %#x\n"), op);         
03651              start = block_end;
03652            }
03653        }
03654 
03655       if (do_debug_frames_interp)
03656        frame_display_row (fc, &need_col_headers, &max_regs);
03657 
03658       start = block_end;
03659     }
03660 
03661   printf ("\n");
03662 
03663   return 1;
03664 }
03665 
03666 #undef GET
03667 #undef LEB
03668 #undef SLEB
03669 
03670 static int
03671 display_debug_not_supported (struct dwarf_section *section,
03672                           void *file ATTRIBUTE_UNUSED)
03673 {
03674   printf (_("Displaying the debug contents of section %s is not yet supported.\n"),
03675            section->name);
03676 
03677   return 1;
03678 }
03679 
03680 void *
03681 cmalloc (size_t nmemb, size_t size)
03682 {
03683   /* Check for overflow.  */
03684   if (nmemb >= ~(size_t) 0 / size)
03685     return NULL;
03686   else
03687     return malloc (nmemb * size);
03688 }
03689 
03690 void *
03691 xcmalloc (size_t nmemb, size_t size)
03692 {
03693   /* Check for overflow.  */
03694   if (nmemb >= ~(size_t) 0 / size)
03695     return NULL;
03696   else
03697     return xmalloc (nmemb * size);
03698 }
03699 
03700 void *
03701 xcrealloc (void *ptr, size_t nmemb, size_t size)
03702 {
03703   /* Check for overflow.  */
03704   if (nmemb >= ~(size_t) 0 / size)
03705     return NULL;
03706   else
03707     return xrealloc (ptr, nmemb * size);
03708 }
03709 
03710 void
03711 error (const char *message, ...)
03712 {
03713   va_list args;
03714 
03715   va_start (args, message);
03716   fprintf (stderr, _("%s: Error: "), program_name);
03717   vfprintf (stderr, message, args);
03718   va_end (args);
03719 }
03720 
03721 void
03722 warn (const char *message, ...)
03723 {
03724   va_list args;
03725 
03726   va_start (args, message);
03727   fprintf (stderr, _("%s: Warning: "), program_name);
03728   vfprintf (stderr, message, args);
03729   va_end (args);
03730 }
03731 
03732 void
03733 free_debug_memory (void)
03734 {
03735   enum dwarf_section_display_enum i;
03736 
03737   free_abbrevs ();
03738 
03739   for (i = 0; i < max; i++)
03740     free_debug_section (i);
03741 
03742   if (debug_information)
03743     {
03744       for (i = 0; i < num_debug_info_entries; i++)
03745        {
03746          if (!debug_information [i].max_loc_offsets)
03747            {
03748              free (debug_information [i].loc_offsets);
03749              free (debug_information [i].have_frame_base);
03750            }
03751          if (!debug_information [i].max_range_lists)
03752            free (debug_information [i].range_lists);
03753        }
03754       free (debug_information);
03755       debug_information = NULL;
03756       num_debug_info_entries = 0;
03757     }
03758 
03759 }
03760 
03761 struct dwarf_section_display debug_displays[] =
03762 {
03763   { { ".debug_abbrev",             NULL,  0,     0 },
03764     display_debug_abbrev,          0,     0 },
03765   { { ".debug_aranges",            NULL,  0,     0 },
03766     display_debug_aranges,         0,     0 },
03767   { { ".debug_frame",              NULL,  0,     0 },
03768     display_debug_frames,          1,     0 },
03769   { { ".debug_info",        NULL,  0,     0 },
03770     display_debug_info,                   1,     0 },
03771   { { ".debug_line",        NULL,  0,     0 },
03772     display_debug_lines,           0,     0 },
03773   { { ".debug_pubnames",    NULL,  0,     0 },
03774     display_debug_pubnames,        0,     0 },
03775   { { ".eh_frame",          NULL,  0,     0 },
03776     display_debug_frames,          1,     1 },
03777   { { ".debug_macinfo",            NULL,  0,     0 },
03778     display_debug_macinfo,         0,     0 },
03779   { { ".debug_str",         NULL,  0,     0 },
03780     display_debug_str,                    0,     0 },
03781   { { ".debug_loc",         NULL,  0,     0 },
03782     display_debug_loc,                    0,     0 },
03783   { { ".debug_pubtypes",    NULL,  0,     0 },
03784     display_debug_pubnames,        0,     0 },
03785   { { ".debug_ranges",             NULL,  0,     0 },
03786     display_debug_ranges,          0,     0 },
03787   { { ".debug_static_func", NULL,  0,     0 },
03788     display_debug_not_supported,   0,     0 },
03789   { { ".debug_static_vars", NULL,  0,     0 },
03790     display_debug_not_supported,   0,     0 },
03791   { { ".debug_types",              NULL,  0,     0 },
03792     display_debug_not_supported,   0,     0 },
03793   { { ".debug_weaknames",   NULL,  0,     0 },
03794     display_debug_not_supported,   0,     0 }
03795 };