Line data Source code
1 : /* Print contents of object file note.
2 : Copyright (C) 2002, 2007, 2009, 2011, 2015, 2016 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 <stdlib.h>
37 : #include <string.h>
38 : #include <libeblP.h>
39 :
40 :
41 : void
42 32 : ebl_object_note (Ebl *ebl, const char *name, uint32_t type,
43 : uint32_t descsz, const char *desc)
44 : {
45 32 : if (! ebl->object_note (name, type, descsz, desc))
46 : {
47 : /* The machine specific function did not know this type. */
48 :
49 32 : if (strcmp ("stapsdt", name) == 0)
50 : {
51 0 : if (type != 3)
52 : {
53 0 : printf (gettext ("unknown SDT version %u\n"), type);
54 : return;
55 : }
56 :
57 : /* Descriptor starts with three addresses, pc, base ref and
58 : semaphore. Then three zero terminated strings provider,
59 : name and arguments. */
60 :
61 : union
62 : {
63 : Elf64_Addr a64[3];
64 : Elf32_Addr a32[3];
65 : } addrs;
66 :
67 0 : size_t addrs_size = gelf_fsize (ebl->elf, ELF_T_ADDR, 3, EV_CURRENT);
68 0 : if (descsz < addrs_size + 3)
69 : {
70 0 : invalid_sdt:
71 0 : printf (gettext ("invalid SDT probe descriptor\n"));
72 : return;
73 : }
74 :
75 0 : Elf_Data src =
76 : {
77 : .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
78 : .d_buf = (void *) desc, .d_size = addrs_size
79 : };
80 :
81 0 : Elf_Data dst =
82 : {
83 : .d_type = ELF_T_ADDR, .d_version = EV_CURRENT,
84 : .d_buf = &addrs, .d_size = addrs_size
85 : };
86 :
87 0 : if (gelf_xlatetom (ebl->elf, &dst, &src,
88 0 : elf_getident (ebl->elf, NULL)[EI_DATA]) == NULL)
89 : {
90 0 : printf ("%s\n", elf_errmsg (-1));
91 : return;
92 : }
93 :
94 0 : const char *provider = desc + addrs_size;
95 0 : const char *pname = memchr (provider, '\0', desc + descsz - provider);
96 0 : if (pname == NULL)
97 : goto invalid_sdt;
98 :
99 0 : ++pname;
100 0 : const char *args = memchr (pname, '\0', desc + descsz - pname);
101 0 : if (args == NULL ||
102 0 : memchr (++args, '\0', desc + descsz - pname) != desc + descsz - 1)
103 : goto invalid_sdt;
104 :
105 : GElf_Addr pc;
106 : GElf_Addr base;
107 : GElf_Addr sem;
108 0 : if (gelf_getclass (ebl->elf) == ELFCLASS32)
109 : {
110 0 : pc = addrs.a32[0];
111 0 : base = addrs.a32[1];
112 0 : sem = addrs.a32[2];
113 : }
114 : else
115 : {
116 0 : pc = addrs.a64[0];
117 0 : base = addrs.a64[1];
118 0 : sem = addrs.a64[2];
119 : }
120 :
121 0 : printf (gettext (" PC: "));
122 0 : printf ("%#" PRIx64 ",", pc);
123 0 : printf (gettext (" Base: "));
124 0 : printf ("%#" PRIx64 ",", base);
125 0 : printf (gettext (" Semaphore: "));
126 0 : printf ("%#" PRIx64 "\n", sem);
127 0 : printf (gettext (" Provider: "));
128 0 : printf ("%s,", provider);
129 0 : printf (gettext (" Name: "));
130 0 : printf ("%s,", pname);
131 0 : printf (gettext (" Args: "));
132 : printf ("'%s'\n", args);
133 : return;
134 : }
135 :
136 32 : switch (type)
137 : {
138 25 : case NT_GNU_BUILD_ID:
139 25 : if (strcmp (name, "GNU") == 0 && descsz > 0)
140 : {
141 50 : printf (gettext (" Build ID: "));
142 : uint_fast32_t i;
143 500 : for (i = 0; i < descsz - 1; ++i)
144 950 : printf ("%02" PRIx8, (uint8_t) desc[i]);
145 25 : printf ("%02" PRIx8 "\n", (uint8_t) desc[i]);
146 : }
147 : break;
148 :
149 0 : case NT_GNU_GOLD_VERSION:
150 0 : if (strcmp (name, "GNU") == 0 && descsz > 0)
151 : /* A non-null terminated version string. */
152 0 : printf (gettext (" Linker version: %.*s\n"),
153 : (int) descsz, desc);
154 : break;
155 :
156 6 : case NT_GNU_ABI_TAG:
157 6 : if (strcmp (name, "GNU") == 0 && descsz >= 8 && descsz % 4 == 0)
158 : {
159 6 : Elf_Data in =
160 : {
161 : .d_version = EV_CURRENT,
162 : .d_type = ELF_T_WORD,
163 : .d_size = descsz,
164 : .d_buf = (void *) desc
165 : };
166 : /* Normally NT_GNU_ABI_TAG is just 4 words (16 bytes). If it
167 : is much (4*) larger dynamically allocate memory to convert. */
168 : #define FIXED_TAG_BYTES 16
169 : uint32_t sbuf[FIXED_TAG_BYTES];
170 : uint32_t *buf;
171 6 : if (unlikely (descsz / 4 > FIXED_TAG_BYTES))
172 : {
173 0 : buf = malloc (descsz);
174 0 : if (unlikely (buf == NULL))
175 0 : return;
176 : }
177 : else
178 : buf = sbuf;
179 6 : Elf_Data out =
180 : {
181 : .d_version = EV_CURRENT,
182 : .d_type = ELF_T_WORD,
183 : .d_size = descsz,
184 : .d_buf = buf
185 : };
186 :
187 6 : if (elf32_xlatetom (&out, &in, ebl->data) != NULL)
188 : {
189 : const char *os;
190 6 : switch (buf[0])
191 : {
192 : case ELF_NOTE_OS_LINUX:
193 : os = "Linux";
194 : break;
195 :
196 0 : case ELF_NOTE_OS_GNU:
197 0 : os = "GNU";
198 0 : break;
199 :
200 0 : case ELF_NOTE_OS_SOLARIS2:
201 0 : os = "Solaris";
202 0 : break;
203 :
204 0 : case ELF_NOTE_OS_FREEBSD:
205 0 : os = "FreeBSD";
206 0 : break;
207 :
208 0 : default:
209 0 : os = "???";
210 0 : break;
211 : }
212 :
213 12 : printf (gettext (" OS: %s, ABI: "), os);
214 24 : for (size_t cnt = 1; cnt < descsz / 4; ++cnt)
215 : {
216 18 : if (cnt > 1)
217 : putchar_unlocked ('.');
218 36 : printf ("%" PRIu32, buf[cnt]);
219 : }
220 : putchar_unlocked ('\n');
221 : }
222 6 : if (descsz / 4 > FIXED_TAG_BYTES)
223 0 : free (buf);
224 6 : break;
225 : }
226 : FALLTHROUGH;
227 :
228 : default:
229 : /* Unknown type. */
230 : break;
231 : }
232 0 : }
233 : }
|