dwarf_getmacros.c revision f3df61f7514b4c217b4bf16a62c93493bb1fef56
1b5f6f51ebcac183818061bf53427a3e7808ef10dsewardj/* Get macro information.
2e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   Copyright (C) 2002, 2003, 2004, 2005 Red Hat, Inc.
3e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   This file is part of Red Hat elfutils.
4e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   Written by Ulrich Drepper <drepper@redhat.com>, 2002.
57fd15d674f18757167305947732057099e175914njn
67fd15d674f18757167305947732057099e175914njn   Red Hat elfutils is free software; you can redistribute it and/or modify
77fd15d674f18757167305947732057099e175914njn   it under the terms of the GNU General Public License as published by the
87fd15d674f18757167305947732057099e175914njn   Free Software Foundation; version 2 of the License.
9e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
10e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   Red Hat elfutils is distributed in the hope that it will be useful, but
11e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   WITHOUT ANY WARRANTY; without even the implied warranty of
12b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13b9c427c63a278cc612ae0ec573be7bb1abaa447fnjn   General Public License for more details.
14de4a1d01951937632098a6cda45859afa587a06fsewardj
150f157ddb404bcde7815a1c5bf2d7e41c114f3d73sewardj   You should have received a copy of the GNU General Public License along
16e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   with Red Hat elfutils; if not, write to the Free Software Foundation,
17e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
18e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
19e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   In addition, as a special exception, Red Hat, Inc. gives You the
20e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   additional right to link the code of Red Hat elfutils with code licensed
21e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   under any Open Source Initiative certified open source license
22e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   (http://www.opensource.org/licenses/index.php) which requires the
23e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   distribution of source code with any binary distribution and to
24e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   distribute linked combinations of the two.  Non-GPL Code permitted under
25e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   this exception must only link to the code of Red Hat elfutils through
26e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   those well defined interfaces identified in the file named EXCEPTION
27e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   found in the source code files (the "Approved Interfaces").  The files
28de4a1d01951937632098a6cda45859afa587a06fsewardj   of Non-GPL Code may instantiate templates or use macros or inline
29e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   functions from the Approved Interfaces without causing the resulting
30e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   work to be covered by the GNU General Public License.  Only Red Hat,
31de4a1d01951937632098a6cda45859afa587a06fsewardj   Inc. may make changes or additions to the list of Approved Interfaces.
32e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   Red Hat's grant of this exception is conditioned upon your not adding
33e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   any new exceptions.  If you wish to add a new Approved Interface or
34e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   exception, please contact Red Hat.  You must obey the GNU General Public
35de4a1d01951937632098a6cda45859afa587a06fsewardj   License in all respects for all of the Red Hat elfutils code and other
36e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   code used in conjunction with Red Hat elfutils except the Non-GPL Code
37e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   covered by this exception.  If you modify this file, you may extend this
38e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   exception to your version of the file, but you are not obligated to do
39e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   so.  If you do not wish to provide this exception without modification,
40e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   you must delete this exception statement from your version and license
41e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   this file solely under the GPL without exception.
42e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
43e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   Red Hat elfutils is an included package of the Open Invention Network.
44e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   An included package of the Open Invention Network is a package for which
45e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   Open Invention Network licensees cross-license their patents.  No patent
46e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   license is granted, either expressly or impliedly, by designation as an
47de4a1d01951937632098a6cda45859afa587a06fsewardj   included package.  Should you wish to participate in the Open Invention
48e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   Network licensing program, please visit www.openinventionnetwork.com
49e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn   <http://www.openinventionnetwork.com>.  */
50e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
51e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#ifdef HAVE_CONFIG_H
52e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn# include <config.h>
53e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#endif
54e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn
55e49d8e7dfd3a9c96feb9935b5920973dfc0b170anjn#include <dwarf.h>
56de4a1d01951937632098a6cda45859afa587a06fsewardj#include <string.h>
57de4a1d01951937632098a6cda45859afa587a06fsewardj
58de4a1d01951937632098a6cda45859afa587a06fsewardj#include <libdwP.h>
5930d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
6030d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
6130d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjnptrdiff_t
6230d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjndwarf_getmacros (die, callback, arg, offset)
6330d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn     Dwarf_Die *die;
6430d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn     int (*callback) (Dwarf_Macro *, void *);
6530d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn     void *arg;
6630d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn     ptrdiff_t offset;
670ec07f32bbbb209d749b9974408e6f025ad40b31sewardj{
6830d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn  /* Get the appropriate attribute.  */
6930d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn  Dwarf_Attribute attr;
7030d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn  if (INTUSE(dwarf_attr) (die, DW_AT_macro_info, &attr) == NULL)
7130d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn    return -1;
7230d76c6abc3e7d338b1ca81256fa3ce93eccc09fnjn
73de4a1d01951937632098a6cda45859afa587a06fsewardj  /* Offset into the .debug_macinfo section.  */
74de4a1d01951937632098a6cda45859afa587a06fsewardj  Dwarf_Word macoff;
75de4a1d01951937632098a6cda45859afa587a06fsewardj  if (INTUSE(dwarf_formudata) (&attr, &macoff) != 0)
767104416748e90239b97560f5d727da107e3e08a9sewardj    return -1;
777104416748e90239b97560f5d727da107e3e08a9sewardj
787104416748e90239b97560f5d727da107e3e08a9sewardj  Elf_Data *d = die->cu->dbg->sectiondata[IDX_debug_macinfo];
797104416748e90239b97560f5d727da107e3e08a9sewardj  if (unlikely (d == NULL) || unlikely (d->d_buf == NULL))
807104416748e90239b97560f5d727da107e3e08a9sewardj    {
817104416748e90239b97560f5d727da107e3e08a9sewardj      __libdw_seterrno (DWARF_E_NO_ENTRY);
820fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj      return -1;
830fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj    }
840fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj
850fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj  const unsigned char *macdata = d->d_buf + macoff;
860fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj  const unsigned char *readp =  macdata + offset;
870fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj  const unsigned char *readendp = d->d_buf + d->d_size;
880fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj
890fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj  if (readp == readendp)
900fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj    return 0;
910fe1d4c134ba889ff5e0a3b1b4dc8f36e610ca97sewardj
92bd830b45bf40e077fb5c0ea6333a416971c253cdsewardj  while (readp < readendp)
937104416748e90239b97560f5d727da107e3e08a9sewardj    {
947104416748e90239b97560f5d727da107e3e08a9sewardj      unsigned int opcode = *readp++;
9539de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge      unsigned int u128;
9639de4b473801ab10a48e356cddc863212dd28cd1fitzhardinge      unsigned int u128_2 = 0;
973dd0a912e48a4884ee51ab3afe41856c165185canjn      const char *str = NULL;
983dd0a912e48a4884ee51ab3afe41856c165185canjn      const unsigned char *endp;
993dd0a912e48a4884ee51ab3afe41856c165185canjn
1003dd0a912e48a4884ee51ab3afe41856c165185canjn      switch (opcode)
101f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj	{
1020ec07f32bbbb209d749b9974408e6f025ad40b31sewardj	case DW_MACINFO_define:
1030ec07f32bbbb209d749b9974408e6f025ad40b31sewardj	case DW_MACINFO_undef:
1040ec07f32bbbb209d749b9974408e6f025ad40b31sewardj	case DW_MACINFO_vendor_ext:
1050ec07f32bbbb209d749b9974408e6f025ad40b31sewardj	  /*  For the first two opcodes the parameters are
10659570ffbe31930ab4d678754daaeec0715117a3dsewardj	        line, string
10759570ffbe31930ab4d678754daaeec0715117a3dsewardj	      For the latter
10859570ffbe31930ab4d678754daaeec0715117a3dsewardj	        number, string.
10959570ffbe31930ab4d678754daaeec0715117a3dsewardj	      We can treat these cases together.  */
11059570ffbe31930ab4d678754daaeec0715117a3dsewardj	  get_uleb128 (u128, readp);
1117af3230a91de23a737946c1b4649b2f826672bf6sewardj
1127af3230a91de23a737946c1b4649b2f826672bf6sewardj	  endp = memchr (readp, '\0', readendp - readp);
1137f489813d200fb614a0856fca05e2f9ebf66dd48bart	  if (endp == NULL)
114aaaf21d21f5803b6b1a0fc558bb8db0fcb83a7a0bart	    goto invalid;
115f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
116f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj	  str = (char *) readp;
117f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj	  readp = endp + 1;
118f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj	  break;
11959570ffbe31930ab4d678754daaeec0715117a3dsewardj
120f0c1250e324f6684757c6a15545366447ef1d64fsewardj	case DW_MACINFO_start_file:
121b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj	  /* The two parameters are line and file index.  */
1225db15403e889d4db339b342bc2a824ef0bfaa654sewardj	  get_uleb128 (u128, readp);
1234df0bfc0614379192c780c944415dc420d9cfe8epetarj	  get_uleb128 (u128_2, readp);
124b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj	  break;
125f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
1266e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj	case DW_MACINFO_end_file:
127f76d27a697a7b0bf3b84490baf60623fc96a23afnjn	  /* No parameters for this one.  */
128f76d27a697a7b0bf3b84490baf60623fc96a23afnjn	  u128 = 0;
129f76d27a697a7b0bf3b84490baf60623fc96a23afnjn	  break;
130c913c8e1a75c78cd653fec8076c07ee4bfb56824sewardj
131c913c8e1a75c78cd653fec8076c07ee4bfb56824sewardj	case 0:
1326e9de463ef677f093e9f24f126e1b11c28cf59fdsewardj	  /* Nothing more to do.  */
1337f489813d200fb614a0856fca05e2f9ebf66dd48bart	  return 0;
134c913c8e1a75c78cd653fec8076c07ee4bfb56824sewardj
135c913c8e1a75c78cd653fec8076c07ee4bfb56824sewardj	default:
136aaaf21d21f5803b6b1a0fc558bb8db0fcb83a7a0bart	  goto invalid;
13759570ffbe31930ab4d678754daaeec0715117a3dsewardj	}
138f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj
13959570ffbe31930ab4d678754daaeec0715117a3dsewardj      Dwarf_Macro mac;
140f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      mac.opcode = opcode;
14159570ffbe31930ab4d678754daaeec0715117a3dsewardj      mac.param1 = u128;
142f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      if (str == NULL)
14359570ffbe31930ab4d678754daaeec0715117a3dsewardj	mac.param2.u = u128_2;
144f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj      else
145f0c1250e324f6684757c6a15545366447ef1d64fsewardj	mac.param2.s = str;
14659570ffbe31930ab4d678754daaeec0715117a3dsewardj
147f0c1250e324f6684757c6a15545366447ef1d64fsewardj      if (callback (&mac, arg) != DWARF_CB_OK)
148f0c1250e324f6684757c6a15545366447ef1d64fsewardj	return readp - macdata;
149b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj    }
150b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj
151f0c1250e324f6684757c6a15545366447ef1d64fsewardj  /* If we come here the termination of the data for the CU is not
1524df0bfc0614379192c780c944415dc420d9cfe8epetarj     present.  */
153f0c1250e324f6684757c6a15545366447ef1d64fsewardj invalid:
1545db15403e889d4db339b342bc2a824ef0bfaa654sewardj  __libdw_seterrno (DWARF_E_INVALID_DWARF);
155f76d27a697a7b0bf3b84490baf60623fc96a23afnjn  return -1;
156f5c1a7f5a80a9268b181bf6b73e865eb10688b85sewardj}
1570ec07f32bbbb209d749b9974408e6f025ad40b31sewardj