1cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng/* Get macro information.
2cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
3cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   This file is part of Red Hat elfutils.
4441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
5441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
6cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Red Hat elfutils is free software; you can redistribute it and/or modify
7cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   it under the terms of the GNU General Public License as published by the
8cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Free Software Foundation; version 2 of the License.
9cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
10cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Red Hat elfutils is distributed in the hope that it will be useful, but
11cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   WITHOUT ANY WARRANTY; without even the implied warranty of
12cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   General Public License for more details.
14cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
15cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   You should have received a copy of the GNU General Public License along
16cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   with Red Hat elfutils; if not, write to the Free Software Foundation,
17cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
18cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
19cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   In addition, as a special exception, Red Hat, Inc. gives You the
20cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   additional right to link the code of Red Hat elfutils with code licensed
21cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   under any Open Source Initiative certified open source license
22cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   (http://www.opensource.org/licenses/index.php) which requires the
23cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   distribution of source code with any binary distribution and to
24cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   distribute linked combinations of the two.  Non-GPL Code permitted under
25cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   this exception must only link to the code of Red Hat elfutils through
26cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   those well defined interfaces identified in the file named EXCEPTION
27cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   found in the source code files (the "Approved Interfaces").  The files
28cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   of Non-GPL Code may instantiate templates or use macros or inline
29cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   functions from the Approved Interfaces without causing the resulting
30cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   work to be covered by the GNU General Public License.  Only Red Hat,
31cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Inc. may make changes or additions to the list of Approved Interfaces.
32cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Red Hat's grant of this exception is conditioned upon your not adding
33cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   any new exceptions.  If you wish to add a new Approved Interface or
34cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   exception, please contact Red Hat.  You must obey the GNU General Public
35cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   License in all respects for all of the Red Hat elfutils code and other
36cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   code used in conjunction with Red Hat elfutils except the Non-GPL Code
37cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   covered by this exception.  If you modify this file, you may extend this
38cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   exception to your version of the file, but you are not obligated to do
39cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   so.  If you do not wish to provide this exception without modification,
40cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   you must delete this exception statement from your version and license
41cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   this file solely under the GPL without exception.
42cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
43cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Red Hat elfutils is an included package of the Open Invention Network.
44cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   An included package of the Open Invention Network is a package for which
45cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Open Invention Network licensees cross-license their patents.  No patent
46cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   license is granted, either expressly or impliedly, by designation as an
47cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   included package.  Should you wish to participate in the Open Invention
48cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   Network licensing program, please visit www.openinventionnetwork.com
49cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng   <http://www.openinventionnetwork.com>.  */
50441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
51441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#ifdef HAVE_CONFIG_H
52441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project# include <config.h>
53441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#endif
54441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
55441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <dwarf.h>
56441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <string.h>
57441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
58441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <libdwP.h>
59441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
60441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
61441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectptrdiff_t
62441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectdwarf_getmacros (die, callback, arg, offset)
63441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     Dwarf_Die *die;
64441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     int (*callback) (Dwarf_Macro *, void *);
65441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     void *arg;
66441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     ptrdiff_t offset;
67441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{
68441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Get the appropriate attribute.  */
69441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  Dwarf_Attribute attr;
70cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (INTUSE(dwarf_attr) (die, DW_AT_macro_info, &attr) == NULL)
71441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    return -1;
72441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
73441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* Offset into the .debug_macinfo section.  */
74441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  Dwarf_Word macoff;
75cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng  if (INTUSE(dwarf_formudata) (&attr, &macoff) != 0)
76441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    return -1;
77441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
78441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  const unsigned char *readp
79441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    = die->cu->dbg->sectiondata[IDX_debug_macinfo]->d_buf + offset;
80441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  const unsigned char *readendp
81441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    = readp + die->cu->dbg->sectiondata[IDX_debug_macinfo]->d_size;
82441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
83441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (readp == readendp)
84441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    return 0;
85441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
86441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  if (*readp != DW_MACINFO_start_file)
87441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    goto invalid;
88441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
89441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  while (readp < readendp)
90441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    {
91441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      unsigned int opcode = *readp++;
92441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      unsigned int u128;
93441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      unsigned int u128_2 = 0;
94441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      const char *str = NULL;
95441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      const unsigned char *endp;
96441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
97441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      switch (opcode)
98441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	{
99441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	case DW_MACINFO_define:
100441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	case DW_MACINFO_undef:
101441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	case DW_MACINFO_vendor_ext:
102441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  /*  For the first two opcodes the parameters are
103441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	        line, string
104441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      For the latter
105441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	        number, string.
106441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	      We can treat these cases together.  */
107441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  get_uleb128 (u128, readp);
108441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
109441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  endp = memchr (readp, '\0', readendp - readp);
110441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  if (endp == NULL)
111441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	    goto invalid;
112441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
113441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  str = (char *) readp;
114441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  readp = endp + 1;
115441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  break;
116441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
117441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	case DW_MACINFO_start_file:
118441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  /* The two parameters are line and file index.  */
119441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  get_uleb128 (u128, readp);
120441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  get_uleb128 (u128_2, readp);
121441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  break;
122441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
123441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	case DW_MACINFO_end_file:
124cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  /* No parameters for this one.  */
125cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  u128 = 0;
126cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	  break;
127cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng
128cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng	case 0:
129441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  /* Nothing more to do.  */
130441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  return 0;
131441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
132441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	default:
133441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	  goto invalid;
134441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	}
135441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
136441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      Dwarf_Macro mac;
137441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      mac.opcode = opcode;
138441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      mac.param1 = u128;
139441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (str == NULL)
140441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	mac.param2.u = u128_2;
141441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      else
142441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	mac.param2.s = str;
143441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
144441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project      if (callback (&mac, arg) != DWARF_CB_OK)
145441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project	return (readp
146441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		- ((unsigned char *) die->cu->dbg->sectiondata[IDX_debug_macinfo]->d_buf
147441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project		   + offset));
148441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project    }
149441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project
150441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  /* If we come here the termination of the data for the CU is not
151441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project     present.  */
152441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project invalid:
153441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  __libdw_seterrno (DWARF_E_INVALID_DWARF);
154441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project  return -1;
155441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project}
156