]>
Commit | Line | Data |
---|---|---|
f8aa6628 ER |
1 | --- rpm-4.5/tools/debugedit.c 2008-04-06 23:32:15.000000000 +0300 |
2 | +++ trunk/tools/debugedit.c 2010-01-27 18:57:49.758813670 +0200 | |
62238cf9 | 3 | @@ -1,4 +1,4 @@ |
f8aa6628 ER |
4 | -/* Copyright (C) 2001, 2002, 2003, 2005, 2007 Red Hat, Inc. |
5 | +/* Copyright (C) 2001, 2002, 2003, 2005, 2007, 2009 Red Hat, Inc. | |
62238cf9 | 6 | Written by Alexander Larsson <alexl@redhat.com>, 2002 |
7 | Based on code by Jakub Jelinek <jakub@redhat.com>, 2001. | |
8 | ||
f447d2d7 | 9 | @@ -77,8 +77,9 @@ |
62238cf9 | 10 | int list_file_fd = -1; |
11 | int do_build_id = 0; | |
12 | ||
f8aa6628 ER |
13 | -typedef unsigned int uint_32; |
14 | -typedef unsigned short uint_16; | |
f447d2d7 ER |
15 | +typedef unsigned char rpmuint8_t; |
16 | +typedef unsigned int rpmuint32_t; | |
17 | +typedef unsigned short rpmuint16_t; | |
18 | ||
62238cf9 | 19 | typedef struct |
20 | { | |
f8aa6628 | 21 | @@ -93,7 +90,7 @@ |
62238cf9 | 22 | typedef struct |
23 | { | |
24 | unsigned char *ptr; | |
f8aa6628 ER |
25 | - uint_32 addend; |
26 | + rpmuint32_t addend; | |
62238cf9 | 27 | } REL; |
28 | ||
29 | #define read_uleb128(ptr) ({ \ | |
f8aa6628 | 30 | @@ -112,31 +109,32 @@ |
62238cf9 | 31 | ret; \ |
32 | }) | |
33 | ||
f8aa6628 ER |
34 | -static uint_16 (*do_read_16) (unsigned char *ptr); |
35 | -static uint_32 (*do_read_32) (unsigned char *ptr); | |
36 | +static rpmuint16_t (*do_read_16) (unsigned char *ptr); | |
37 | +static rpmuint32_t (*do_read_32) (unsigned char *ptr); | |
62238cf9 | 38 | static void (*write_32) (unsigned char *ptr, GElf_Addr val); |
39 | ||
40 | static int ptr_size; | |
f8aa6628 | 41 | +static int cu_version; |
62238cf9 | 42 | |
f8aa6628 ER |
43 | -static inline uint_16 |
44 | +static inline rpmuint16_t | |
62238cf9 | 45 | buf_read_ule16 (unsigned char *data) |
46 | { | |
47 | return data[0] | (data[1] << 8); | |
48 | } | |
49 | ||
f8aa6628 ER |
50 | -static inline uint_16 |
51 | +static inline rpmuint16_t | |
62238cf9 | 52 | buf_read_ube16 (unsigned char *data) |
53 | { | |
54 | return data[1] | (data[0] << 8); | |
55 | } | |
56 | ||
f8aa6628 ER |
57 | -static inline uint_32 |
58 | +static inline rpmuint32_t | |
62238cf9 | 59 | buf_read_ule32 (unsigned char *data) |
60 | { | |
61 | return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); | |
62 | } | |
63 | ||
f8aa6628 ER |
64 | -static inline uint_32 |
65 | +static inline rpmuint32_t | |
62238cf9 | 66 | buf_read_ube32 (unsigned char *data) |
67 | { | |
68 | return data[3] | (data[2] << 8) | (data[1] << 16) | (data[0] << 24); | |
f8aa6628 | 69 | @@ -156,7 +154,7 @@ |
62238cf9 | 70 | { |
71 | if (data->d_buf | |
72 | && offset >= data->d_off | |
f8aa6628 ER |
73 | - && offset < data->d_off + data->d_size) |
74 | + && offset < data->d_off + (off_t)data->d_size) | |
62238cf9 | 75 | return (const char *) data->d_buf + (offset - data->d_off); |
76 | } | |
77 | } | |
f8aa6628 | 78 | @@ -168,13 +166,13 @@ |
62238cf9 | 79 | #define read_1(ptr) *ptr++ |
80 | ||
81 | #define read_16(ptr) ({ \ | |
f8aa6628 ER |
82 | - uint_16 ret = do_read_16 (ptr); \ |
83 | + rpmuint16_t ret = do_read_16 (ptr); \ | |
62238cf9 | 84 | ptr += 2; \ |
85 | ret; \ | |
86 | }) | |
87 | ||
88 | #define read_32(ptr) ({ \ | |
f8aa6628 ER |
89 | - uint_32 ret = do_read_32 (ptr); \ |
90 | + rpmuint32_t ret = do_read_32 (ptr); \ | |
62238cf9 | 91 | ptr += 4; \ |
92 | ret; \ | |
93 | }) | |
f8aa6628 | 94 | @@ -183,7 +181,7 @@ |
62238cf9 | 95 | int reltype; |
96 | ||
97 | #define do_read_32_relocated(ptr) ({ \ | |
f8aa6628 ER |
98 | - uint_32 dret = do_read_32 (ptr); \ |
99 | + rpmuint32_t dret = do_read_32 (ptr); \ | |
62238cf9 | 100 | if (relptr) \ |
101 | { \ | |
102 | while (relptr < relend && relptr->ptr < ptr) \ | |
f8aa6628 | 103 | @@ -200,7 +198,7 @@ |
62238cf9 | 104 | }) |
105 | ||
106 | #define read_32_relocated(ptr) ({ \ | |
f8aa6628 ER |
107 | - uint_32 ret = do_read_32_relocated (ptr); \ |
108 | + rpmuint32_t ret = do_read_32_relocated (ptr); \ | |
62238cf9 | 109 | ptr += 4; \ |
110 | ret; \ | |
111 | }) | |
f8aa6628 | 112 | @@ -208,7 +206,7 @@ |
62238cf9 | 113 | static void |
114 | dwarf2_write_le32 (unsigned char *p, GElf_Addr val) | |
115 | { | |
f8aa6628 ER |
116 | - uint_32 v = (uint_32) val; |
117 | + rpmuint32_t v = (rpmuint32_t) val; | |
62238cf9 | 118 | |
119 | p[0] = v; | |
120 | p[1] = v >> 8; | |
f8aa6628 | 121 | @@ -220,7 +218,7 @@ |
62238cf9 | 122 | static void |
123 | dwarf2_write_be32 (unsigned char *p, GElf_Addr val) | |
124 | { | |
f8aa6628 ER |
125 | - uint_32 v = (uint_32) val; |
126 | + rpmuint32_t v = (rpmuint32_t) val; | |
62238cf9 | 127 | |
128 | p[3] = v; | |
129 | p[2] = v >> 8; | |
f8aa6628 | 130 | @@ -242,16 +240,18 @@ |
62238cf9 | 131 | #define DEBUG_LINE 2 |
132 | #define DEBUG_ARANGES 3 | |
133 | #define DEBUG_PUBNAMES 4 | |
f8aa6628 ER |
134 | -#define DEBUG_MACINFO 5 |
135 | -#define DEBUG_LOC 6 | |
136 | -#define DEBUG_STR 7 | |
137 | -#define DEBUG_FRAME 8 | |
138 | -#define DEBUG_RANGES 9 | |
139 | +#define DEBUG_PUBTYPES 5 | |
140 | +#define DEBUG_MACINFO 6 | |
141 | +#define DEBUG_LOC 7 | |
142 | +#define DEBUG_STR 8 | |
143 | +#define DEBUG_FRAME 9 | |
144 | +#define DEBUG_RANGES 10 | |
62238cf9 | 145 | { ".debug_info", NULL, NULL, 0, 0, 0 }, |
146 | { ".debug_abbrev", NULL, NULL, 0, 0, 0 }, | |
147 | { ".debug_line", NULL, NULL, 0, 0, 0 }, | |
148 | { ".debug_aranges", NULL, NULL, 0, 0, 0 }, | |
149 | { ".debug_pubnames", NULL, NULL, 0, 0, 0 }, | |
f8aa6628 | 150 | + { ".debug_pubtypes", NULL, NULL, 0, 0, 0 }, |
62238cf9 | 151 | { ".debug_macinfo", NULL, NULL, 0, 0, 0 }, |
152 | { ".debug_loc", NULL, NULL, 0, 0, 0 }, | |
153 | { ".debug_str", NULL, NULL, 0, 0, 0 }, | |
154 | @@ -331,7 +331,7 @@ | |
155 | } | |
156 | if (*slot != NULL) | |
157 | { | |
f8aa6628 ER |
158 | - error (0, 0, "%s: Duplicate DWARF-2 abbreviation %d", dso->filename, |
159 | + error (0, 0, "%s: Duplicate DWARF abbreviation %d", dso->filename, | |
62238cf9 | 160 | t->entry); |
161 | free (t); | |
162 | htab_delete (h); | |
163 | @@ -351,7 +351,7 @@ | |
164 | form = read_uleb128 (ptr); | |
165 | if (form == 2 || form > DW_FORM_indirect) | |
166 | { | |
f8aa6628 ER |
167 | - error (0, 0, "%s: Unknown DWARF-2 DW_FORM_%d", dso->filename, form); |
168 | + error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename, form); | |
62238cf9 | 169 | htab_delete (h); |
170 | return NULL; | |
171 | } | |
172 | @@ -361,7 +361,7 @@ | |
173 | } | |
174 | if (read_uleb128 (ptr) != 0) | |
175 | { | |
f8aa6628 ER |
176 | - error (0, 0, "%s: DWARF-2 abbreviation does not end with 2 zeros", |
177 | + error (0, 0, "%s: DWARF abbreviation does not end with 2 zeros", | |
62238cf9 | 178 | dso->filename); |
179 | htab_delete (h); | |
180 | return NULL; | |
181 | @@ -468,8 +468,8 @@ | |
182 | has_prefix (const char *str, | |
183 | const char *prefix) | |
184 | { | |
f8aa6628 ER |
185 | - int str_len; |
186 | - int prefix_len; | |
187 | + size_t str_len; | |
188 | + size_t prefix_len; | |
62238cf9 | 189 | |
190 | str_len = strlen (str); | |
191 | prefix_len = strlen (prefix); | |
192 | @@ -481,14 +481,14 @@ | |
193 | } | |
194 | ||
195 | static int | |
f8aa6628 ER |
196 | -edit_dwarf2_line (DSO *dso, uint_32 off, char *comp_dir, int phase) |
197 | +edit_dwarf2_line (DSO *dso, rpmuint32_t off, char *comp_dir, int phase) | |
62238cf9 | 198 | { |
199 | unsigned char *ptr = debug_sections[DEBUG_LINE].data, *dir; | |
200 | unsigned char **dirt; | |
201 | unsigned char *endsec = ptr + debug_sections[DEBUG_LINE].size; | |
202 | unsigned char *endcu, *endprol; | |
203 | unsigned char opcode_base; | |
f8aa6628 ER |
204 | - uint_32 value, dirt_cnt; |
205 | + rpmuint32_t value, dirt_cnt; | |
62238cf9 | 206 | size_t comp_dir_len = strlen (comp_dir); |
207 | size_t abs_file_cnt = 0, abs_dir_cnt = 0; | |
208 | ||
209 | @@ -513,7 +513,7 @@ | |
210 | } | |
211 | ||
212 | value = read_16 (ptr); | |
f8aa6628 ER |
213 | - if (value != 2) |
214 | + if (value != 2 && value != 3) | |
62238cf9 | 215 | { |
216 | error (0, 0, "%s: DWARF version %d unhandled", dso->filename, | |
217 | value); | |
f8aa6628 | 218 | @@ -679,9 +679,12 @@ |
62238cf9 | 219 | if (--shrank == 0) |
220 | error (EXIT_FAILURE, 0, | |
221 | "canonicalization unexpectedly shrank by one character"); | |
f8aa6628 ER |
222 | - memset (ptr, 'X', shrank); |
223 | - ptr += shrank; | |
224 | - *ptr++ = '\0'; | |
225 | + else | |
226 | + { | |
227 | + memset (ptr, 'X', shrank); | |
228 | + ptr += shrank; | |
229 | + *ptr++ = '\0'; | |
230 | + } | |
62238cf9 | 231 | } |
232 | ||
233 | if (abs_dir_cnt + abs_file_cnt != 0) | |
f8aa6628 | 234 | @@ -737,7 +740,7 @@ |
62238cf9 | 235 | edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase) |
236 | { | |
237 | int i; | |
f8aa6628 ER |
238 | - uint_32 list_offs; |
239 | + rpmuint32_t list_offs; | |
62238cf9 | 240 | int found_list_offs; |
241 | char *comp_dir; | |
242 | ||
f8aa6628 | 243 | @@ -746,9 +749,9 @@ |
62238cf9 | 244 | found_list_offs = 0; |
245 | for (i = 0; i < t->nattr; ++i) | |
246 | { | |
f8aa6628 ER |
247 | - uint_32 form = t->attr[i].form; |
248 | - uint_32 len = 0; | |
249 | - int base_len, dest_len; | |
250 | + rpmuint32_t form = t->attr[i].form; | |
251 | + size_t len = 0; | |
252 | + size_t base_len, dest_len; | |
62238cf9 | 253 | |
254 | ||
255 | while (1) | |
f8aa6628 | 256 | @@ -791,7 +794,7 @@ |
62238cf9 | 257 | { |
258 | char *dir; | |
259 | ||
f8aa6628 ER |
260 | - dir = (char *)debug_sections[DEBUG_STR].data |
261 | + dir = (char *) debug_sections[DEBUG_STR].data | |
62238cf9 | 262 | + do_read_32_relocated (ptr); |
263 | ||
264 | free (comp_dir); | |
f8aa6628 | 265 | @@ -821,7 +824,7 @@ |
62238cf9 | 266 | { |
267 | char *name; | |
268 | ||
f8aa6628 ER |
269 | - name = (char *)debug_sections[DEBUG_STR].data |
270 | + name = (char *) debug_sections[DEBUG_STR].data | |
62238cf9 | 271 | + do_read_32_relocated (ptr); |
272 | if (*name == '/' && comp_dir == NULL) | |
273 | { | |
f8aa6628 | 274 | @@ -855,7 +858,12 @@ |
62238cf9 | 275 | |
276 | switch (form) | |
277 | { | |
f8aa6628 ER |
278 | - case DW_FORM_ref_addr: /* ptr_size in DWARF 2, offset in DWARF 3 */ |
279 | + case DW_FORM_ref_addr: | |
280 | + if (cu_version == 2) | |
281 | + ptr += ptr_size; | |
282 | + else | |
283 | + ptr += 4; | |
284 | + break; | |
62238cf9 | 285 | case DW_FORM_addr: |
286 | ptr += ptr_size; | |
287 | break; | |
f8aa6628 | 288 | @@ -907,7 +915,7 @@ |
62238cf9 | 289 | assert (len < UINT_MAX); |
290 | break; | |
291 | default: | |
f8aa6628 ER |
292 | - error (0, 0, "%s: Unknown DWARF-2 DW_FORM_%d", dso->filename, |
293 | + error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename, | |
62238cf9 | 294 | form); |
295 | return NULL; | |
296 | } | |
f8aa6628 | 297 | @@ -918,6 +926,34 @@ |
62238cf9 | 298 | break; |
299 | } | |
300 | } | |
f8aa6628 ER |
301 | + |
302 | + /* Ensure the CU current directory will exist even if only empty. Source | |
303 | + filenames possibly located in its parent directories refer relatively to | |
304 | + it and the debugger (GDB) cannot safely optimize out the missing | |
305 | + CU current dir subdirectories. */ | |
306 | + if (comp_dir && list_file_fd != -1) | |
307 | + { | |
308 | + char *p; | |
309 | + size_t size; | |
310 | + | |
311 | + if (base_dir && has_prefix (comp_dir, base_dir)) | |
312 | + p = comp_dir + strlen (base_dir); | |
313 | + else if (dest_dir && has_prefix (comp_dir, dest_dir)) | |
314 | + p = comp_dir + strlen (dest_dir); | |
315 | + else | |
316 | + p = comp_dir; | |
317 | + | |
318 | + size = strlen (p) + 1; | |
319 | + while (size > 0) | |
320 | + { | |
321 | + ssize_t ret = write (list_file_fd, p, size); | |
322 | + if (ret == -1) | |
323 | + break; | |
324 | + size -= ret; | |
325 | + p += ret; | |
326 | + } | |
327 | + } | |
328 | + | |
62238cf9 | 329 | if (found_list_offs && comp_dir) |
330 | edit_dwarf2_line (dso, list_offs, comp_dir, phase); | |
331 | ||
f8aa6628 | 332 | @@ -1034,7 +1070,7 @@ |
62238cf9 | 333 | if (debug_sections[DEBUG_INFO].data != NULL) |
334 | { | |
335 | unsigned char *ptr, *endcu, *endsec; | |
f8aa6628 ER |
336 | - uint_32 value; |
337 | + rpmuint32_t value; | |
62238cf9 | 338 | htab_t abbrev; |
339 | struct abbrev_tag tag, *t; | |
340 | int phase; | |
f8aa6628 | 341 | @@ -1176,11 +1212,11 @@ |
62238cf9 | 342 | return 1; |
343 | } | |
344 | ||
f8aa6628 ER |
345 | - value = read_16 (ptr); |
346 | - if (value != 2) | |
347 | + cu_version = read_16 (ptr); | |
348 | + if (cu_version != 2 && cu_version != 3) | |
62238cf9 | 349 | { |
350 | error (0, 0, "%s: DWARF version %d unhandled", dso->filename, | |
f8aa6628 ER |
351 | - value); |
352 | + cu_version); | |
62238cf9 | 353 | return 1; |
354 | } | |
355 | ||
f8aa6628 | 356 | @@ -1190,7 +1226,7 @@ |
62238cf9 | 357 | if (debug_sections[DEBUG_ABBREV].data == NULL) |
358 | error (0, 0, "%s: .debug_abbrev not present", dso->filename); | |
359 | else | |
f8aa6628 ER |
360 | - error (0, 0, "%s: DWARF-2 CU abbrev offset too large", |
361 | + error (0, 0, "%s: DWARF CU abbrev offset too large", | |
62238cf9 | 362 | dso->filename); |
363 | return 1; | |
364 | } | |
f8aa6628 | 365 | @@ -1200,14 +1236,14 @@ |
62238cf9 | 366 | ptr_size = read_1 (ptr); |
367 | if (ptr_size != 4 && ptr_size != 8) | |
368 | { | |
f8aa6628 ER |
369 | - error (0, 0, "%s: Invalid DWARF-2 pointer size %d", |
370 | + error (0, 0, "%s: Invalid DWARF pointer size %d", | |
62238cf9 | 371 | dso->filename, ptr_size); |
372 | return 1; | |
373 | } | |
374 | } | |
375 | else if (read_1 (ptr) != ptr_size) | |
376 | { | |
f8aa6628 ER |
377 | - error (0, 0, "%s: DWARF-2 pointer size differs between CUs", |
378 | + error (0, 0, "%s: DWARF pointer size differs between CUs", | |
62238cf9 | 379 | dso->filename); |
380 | return 1; | |
381 | } | |
f8aa6628 | 382 | @@ -1225,7 +1261,7 @@ |
62238cf9 | 383 | t = htab_find_with_hash (abbrev, &tag, tag.entry); |
384 | if (t == NULL) | |
385 | { | |
f8aa6628 ER |
386 | - error (0, 0, "%s: Could not find DWARF-2 abbreviation %d", |
387 | + error (0, 0, "%s: Could not find DWARF abbreviation %d", | |
62238cf9 | 388 | dso->filename, tag.entry); |
389 | htab_delete (abbrev); | |
390 | return 1; | |
f8aa6628 | 391 | @@ -1374,12 +1410,12 @@ |
62238cf9 | 392 | or Elf64 object, only that we are consistent in what bits feed the |
393 | hash so it comes out the same for the same file contents. */ | |
394 | { | |
f8aa6628 ER |
395 | - inline void process (const void *data, size_t size) |
396 | + auto inline void process (const void *data, size_t size); | |
397 | + auto inline void process (const void *data, size_t size) | |
62238cf9 | 398 | { |
399 | memchunk chunk = { .data = (void *) data, .size = size }; | |
400 | hashFunctionContextUpdateMC (&ctx, &chunk); | |
401 | } | |
f8aa6628 | 402 | - |
62238cf9 | 403 | union |
404 | { | |
405 | GElf_Ehdr ehdr; | |
f8aa6628 | 406 | @@ -1439,11 +1475,11 @@ |
62238cf9 | 407 | |
408 | /* Now format the build ID bits in hex to print out. */ | |
409 | { | |
f8aa6628 ER |
410 | - const unsigned char * id = (unsigned char *) build_id->d_buf + build_id_offset; |
411 | + const rpmuint8_t * id = (rpmuint8_t *)build_id->d_buf + build_id_offset; | |
62238cf9 | 412 | char hex[build_id_size * 2 + 1]; |
413 | int n = snprintf (hex, 3, "%02" PRIx8, id[0]); | |
414 | assert (n == 2); | |
f8aa6628 ER |
415 | - for (i = 1; i < build_id_size; ++i) |
416 | + for (i = 1; i < (int)build_id_size; ++i) | |
62238cf9 | 417 | { |
418 | n = snprintf (&hex[i * 2], 3, "%02" PRIx8, id[i]); | |
419 | assert (n == 2); | |
f8aa6628 | 420 | @@ -1466,8 +1502,7 @@ |
62238cf9 | 421 | Elf_Data *build_id = NULL; |
422 | size_t build_id_offset = 0, build_id_size = 0; | |
423 | ||
f8aa6628 ER |
424 | - optCon = poptGetContext("debugedit", argc, (const char **)argv, |
425 | - optionsTable, 0); | |
426 | + optCon = poptGetContext("debugedit", argc, (const char **)argv, optionsTable, 0); | |
62238cf9 | 427 | |
428 | while ((nextopt = poptGetNextOpt (optCon)) > 0 || nextopt == POPT_ERROR_BADOPT) | |
429 | /* do nothing */ ; | |
f8aa6628 | 430 | @@ -1585,7 +1620,8 @@ |
62238cf9 | 431 | Elf_Data src = dst; |
432 | src.d_buf = data->d_buf; | |
433 | assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr)); | |
f8aa6628 ER |
434 | - while ((char *) data->d_buf + data->d_size - (char *) src.d_buf > (int) sizeof nh |
435 | + while ((char *) data->d_buf + data->d_size - | |
436 | + (char *) src.d_buf > (int) sizeof nh | |
62238cf9 | 437 | && elf32_xlatetom (&dst, &src, dso->ehdr.e_ident[EI_DATA])) |
438 | { | |
439 | Elf32_Word len = sizeof nh + nh.n_namesz; | |
f8aa6628 | 440 | @@ -1595,7 +1631,8 @@ |
62238cf9 | 441 | && !memcmp ((char *) src.d_buf + sizeof nh, "GNU", sizeof "GNU")) |
442 | { | |
443 | build_id = data; | |
f8aa6628 ER |
444 | - build_id_offset = (char *) src.d_buf + len - (char *) data->d_buf; |
445 | + build_id_offset = (char *) src.d_buf + len - | |
446 | + (char *) data->d_buf; | |
62238cf9 | 447 | build_id_size = nh.n_descsz; |
448 | break; | |
449 | } |