1 /* Get public symbol information.
2 Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
3 Written by Ulrich Drepper <drepper@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
dwarf_getmacros(die,callback,arg,offset)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