Home | History | Annotate | Download | only in libdw
      1 /* Get public symbol information.
      2    Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
      3    Written by Ulrich Drepper <drepper (at) redhat.com>, 2002.
      4 
      5    This program is Open Source software; you can redistribute it and/or
      6    modify it under the terms of the Open Software License version 1.0 as
      7    published by the Open Source Initiative.
      8 
      9    You should have received a copy of the Open Software License along
     10    with this program; if not, you may obtain a copy of the Open Software
     11    License version 1.0 from http://www.opensource.org/licenses/osl.php or
     12    by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
     13    3001 King Ranch Road, Ukiah, CA 95482.   */
     14 
     15 #ifdef HAVE_CONFIG_H
     16 # include <config.h>
     17 #endif
     18 
     19 #include <dwarf.h>
     20 #include <string.h>
     21 
     22 #include <libdwP.h>
     23 
     24 
     25 ptrdiff_t
     26 dwarf_getmacros (die, callback, arg, offset)
     27      Dwarf_Die *die;
     28      int (*callback) (Dwarf_Macro *, void *);
     29      void *arg;
     30      ptrdiff_t offset;
     31 {
     32   /* Get the appropriate attribute.  */
     33   Dwarf_Attribute attr;
     34   if (dwarf_attr (die, DW_AT_macro_info, &attr) == NULL)
     35     return -1;
     36 
     37   /* Offset into the .debug_macinfo section.  */
     38   Dwarf_Word macoff;
     39   if (dwarf_formudata (&attr, &macoff) != 0)
     40     return -1;
     41 
     42   const unsigned char *readp
     43     = die->cu->dbg->sectiondata[IDX_debug_macinfo]->d_buf + offset;
     44   const unsigned char *readendp
     45     = readp + die->cu->dbg->sectiondata[IDX_debug_macinfo]->d_size;
     46 
     47   if (readp == readendp)
     48     return 0;
     49 
     50   if (*readp != DW_MACINFO_start_file)
     51     goto invalid;
     52 
     53   while (readp < readendp)
     54     {
     55       unsigned int opcode = *readp++;
     56       unsigned int u128;
     57       unsigned int u128_2 = 0;
     58       const char *str = NULL;
     59       const unsigned char *endp;
     60 
     61       switch (opcode)
     62 	{
     63 	case DW_MACINFO_define:
     64 	case DW_MACINFO_undef:
     65 	case DW_MACINFO_vendor_ext:
     66 	  /*  For the first two opcodes the parameters are
     67 	        line, string
     68 	      For the latter
     69 	        number, string.
     70 	      We can treat these cases together.  */
     71 	  get_uleb128 (u128, readp);
     72 
     73 	  endp = memchr (readp, '\0', readendp - readp);
     74 	  if (endp == NULL)
     75 	    goto invalid;
     76 
     77 	  str = (char *) readp;
     78 	  readp = endp + 1;
     79 	  break;
     80 
     81 	case DW_MACINFO_start_file:
     82 	  /* The two parameters are line and file index.  */
     83 	  get_uleb128 (u128, readp);
     84 	  get_uleb128 (u128_2, readp);
     85 	  break;
     86 
     87 	case DW_MACINFO_end_file:
     88 	  /* Nothing more to do.  */
     89 	  return 0;
     90 
     91 	default:
     92 	  goto invalid;
     93 	}
     94 
     95       Dwarf_Macro mac;
     96       mac.opcode = opcode;
     97       mac.param1 = u128;
     98       if (str == NULL)
     99 	mac.param2.u = u128_2;
    100       else
    101 	mac.param2.s = str;
    102 
    103       if (callback (&mac, arg) != DWARF_CB_OK)
    104 	return (readp
    105 		- ((unsigned char *) die->cu->dbg->sectiondata[IDX_debug_macinfo]->d_buf
    106 		   + offset));
    107     }
    108 
    109   /* If we come here the termination of the data for the CU is not
    110      present.  */
    111  invalid:
    112   __libdw_seterrno (DWARF_E_INVALID_DWARF);
    113   return -1;
    114 }
    115