Branch data Line data Source code
1 : : /* Print contents of object file note.
2 : : Copyright (C) 2002, 2007, 2009, 2011 Red Hat, Inc.
3 : : This file is part of elfutils.
4 : : Written by Ulrich Drepper <drepper@redhat.com>, 2002.
5 : :
6 : : This file is free software; you can redistribute it and/or modify
7 : : it under the terms of either
8 : :
9 : : * the GNU Lesser General Public License as published by the Free
10 : : Software Foundation; either version 3 of the License, or (at
11 : : your option) any later version
12 : :
13 : : or
14 : :
15 : : * the GNU General Public License as published by the Free
16 : : Software Foundation; either version 2 of the License, or (at
17 : : your option) any later version
18 : :
19 : : or both in parallel, as here.
20 : :
21 : : elfutils is distributed in the hope that it will be useful, but
22 : : WITHOUT ANY WARRANTY; without even the implied warranty of
23 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 : : General Public License for more details.
25 : :
26 : : You should have received copies of the GNU General Public License and
27 : : the GNU Lesser General Public License along with this program. If
28 : : not, see <http://www.gnu.org/licenses/>. */
29 : :
30 : : #ifdef HAVE_CONFIG_H
31 : : # include <config.h>
32 : : #endif
33 : :
34 : : #include <inttypes.h>
35 : : #include <stdio.h>
36 : : #include <string.h>
37 : : #include <libeblP.h>
38 : :
39 : :
40 : : void
41 : 48 : ebl_object_note (ebl, name, type, descsz, desc)
42 : : Ebl *ebl;
43 : : const char *name;
44 : : uint32_t type;
45 : : uint32_t descsz;
46 : : const char *desc;
47 : : {
48 [ + - ]: 48 : if (! ebl->object_note (name, type, descsz, desc))
49 : : /* The machine specific function did not know this type. */
50 : :
51 [ - + ]: 48 : if (strcmp ("stapsdt", name) == 0)
52 : : {
53 [ # # ]: 0 : if (type != 3)
54 : : {
55 : 0 : printf (gettext ("unknown SDT version %u\n"), type);
56 : : return;
57 : : }
58 : :
59 : : /* Descriptor starts with three addresses, pc, base ref and
60 : : semaphore. Then three zero terminated strings provider,
61 : : name and arguments. */
62 : :
63 : : union
64 : : {
65 : : Elf64_Addr a64[3];
66 : : Elf32_Addr a32[3];
67 : : } addrs;
68 : :
69 : 0 : size_t addrs_size = gelf_fsize (ebl->elf, ELF_T_ADDR, 3, EV_CURRENT);
70 [ # # ]: 0 : if (descsz < addrs_size + 3)
71 : : {
72 : : invalid_sdt:
73 : 0 : printf (gettext ("invalid SDT probe descriptor\n"));
74 : : return;
75 : : }
76 : :
77 : 0 : Elf_Data src =
78 : : {
79 : : .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
80 : : .d_buf = (void *) desc, .d_size = addrs_size
81 : : };
82 : :
83 : 0 : Elf_Data dst =
84 : : {
85 : : .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
86 : : .d_buf = &addrs, .d_size = addrs_size
87 : : };
88 : :
89 [ # # ]: 0 : if (gelf_xlatetom (ebl->elf, &dst, &src,
90 : 0 : elf_getident (ebl->elf, NULL)[EI_DATA]) == NULL)
91 : : {
92 : 0 : printf ("%s\n", elf_errmsg (-1));
93 : : return;
94 : : }
95 : :
96 : 0 : const char *provider = desc + addrs_size;
97 : 0 : const char *pname = memchr (provider, '\0', desc + descsz - provider);
98 [ # # ]: 0 : if (pname == NULL)
99 : : goto invalid_sdt;
100 : :
101 : 0 : ++pname;
102 : 0 : const char *args = memchr (pname, '\0', desc + descsz - pname);
103 [ # # ][ # # ]: 0 : if (args == NULL ||
104 : 0 : memchr (++args, '\0', desc + descsz - pname) != desc + descsz - 1)
105 : : goto invalid_sdt;
106 : :
107 : : GElf_Addr pc;
108 : : GElf_Addr base;
109 : : GElf_Addr sem;
110 [ # # ]: 0 : if (gelf_getclass (ebl->elf) == ELFCLASS32)
111 : : {
112 : 0 : pc = addrs.a32[0];
113 : 0 : base = addrs.a32[1];
114 : 0 : sem = addrs.a32[2];
115 : : }
116 : : else
117 : : {
118 : 0 : pc = addrs.a64[0];
119 : 0 : base = addrs.a64[1];
120 : 0 : sem = addrs.a64[2];
121 : : }
122 : :
123 : 0 : printf (gettext (" PC: "));
124 : 0 : printf ("%#" PRIx64 ",", pc);
125 : 0 : printf (gettext (" Base: "));
126 : 0 : printf ("%#" PRIx64 ",", base);
127 : 0 : printf (gettext (" Semaphore: "));
128 : 0 : printf ("%#" PRIx64 "\n", sem);
129 : 0 : printf (gettext (" Provider: "));
130 : 0 : printf ("%s,", provider);
131 : 0 : printf (gettext (" Name: "));
132 : 0 : printf ("%s,", pname);
133 : 0 : printf (gettext (" Args: "));
134 : 0 : printf ("'%s'\n", args);
135 : : return;
136 : : }
137 : :
138 [ + - + + ]: 48 : switch (type)
139 : : {
140 : : case NT_GNU_BUILD_ID:
141 [ + - ][ + - ]: 35 : if (strcmp (name, "GNU") == 0 && descsz > 0)
[ + - ][ + - ]
[ + - ]
142 : : {
143 : 35 : printf (gettext (" Build ID: "));
144 : : uint_fast32_t i;
145 [ + + ]: 700 : for (i = 0; i < descsz - 1; ++i)
146 : 665 : printf ("%02" PRIx8, (uint8_t) desc[i]);
147 : 35 : printf ("%02" PRIx8 "\n", (uint8_t) desc[i]);
148 : : }
149 : : break;
150 : :
151 : : case NT_GNU_GOLD_VERSION:
152 [ # # ][ # # ]: 0 : if (strcmp (name, "GNU") == 0 && descsz > 0)
[ # # ][ # # ]
[ # # ]
153 : : /* A non-null terminated version string. */
154 : 0 : printf (gettext (" Linker version: %.*s\n"),
155 : : (int) descsz, desc);
156 : : break;
157 : :
158 : : case NT_GNU_ABI_TAG:
159 [ + - ][ + - ]: 12 : if (strcmp (name, "GNU") == 0 && descsz >= 8 && descsz % 4 == 0)
[ + - ][ + - ]
[ + - ][ + - ]
160 : : {
161 : 12 : Elf_Data in =
162 : : {
163 : : .d_version = EV_CURRENT,
164 : : .d_type = ELF_T_WORD,
165 : : .d_size = descsz,
166 : : .d_buf = (void *) desc
167 : : };
168 : 12 : uint32_t buf[descsz / 4];
169 : 24 : Elf_Data out =
170 : : {
171 : : .d_version = EV_CURRENT,
172 : : .d_type = ELF_T_WORD,
173 : : .d_size = descsz,
174 : 12 : .d_buf = buf
175 : : };
176 : :
177 [ + - ]: 12 : if (elf32_xlatetom (&out, &in, ebl->data) != NULL)
178 : : {
179 : : const char *os;
180 [ - - - - : 12 : switch (buf[0])
+ ]
181 : : {
182 : : case ELF_NOTE_OS_LINUX:
183 : : os = "Linux";
184 : : break;
185 : :
186 : : case ELF_NOTE_OS_GNU:
187 : 0 : os = "GNU";
188 : 0 : break;
189 : :
190 : : case ELF_NOTE_OS_SOLARIS2:
191 : 0 : os = "Solaris";
192 : 0 : break;
193 : :
194 : : case ELF_NOTE_OS_FREEBSD:
195 : 0 : os = "FreeBSD";
196 : 0 : break;
197 : :
198 : : default:
199 : 0 : os = "???";
200 : 0 : break;
201 : : }
202 : :
203 : 12 : printf (gettext (" OS: %s, ABI: "), os);
204 [ + + ]: 48 : for (size_t cnt = 1; cnt < descsz / 4; ++cnt)
205 : : {
206 [ + + ]: 36 : if (cnt > 1)
207 : : putchar_unlocked ('.');
208 : 36 : printf ("%" PRIu32, buf[cnt]);
209 : : }
210 : : putchar_unlocked ('\n');
211 : : }
212 : : break;
213 : : }
214 : : /* FALLTHROUGH */
215 : :
216 : : default:
217 : : /* Unknown type. */
218 : : break;
219 : : }
220 : : }
|