1 /* Copyright (C) 2001, 2002, 2003, 2005, 2007, 2009, 2010 Red Hat, Inc.
2 Written by Alexander Larsson <alexl@redhat.com>, 2002
3 Based on code by Jakub Jelinek <jakub@redhat.com>, 2001.
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software Foundation,
17 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19
20 /* Needed for libelf */
21 #define _FILE_OFFSET_BITS 64
22
23 #include <assert.h>
24 #if defined(__linux__)
25 #include <byteswap.h>
26 #include <endian.h>
27 #endif
28 #include <errno.h>
29 #if !defined(__FreeBSD__) && !defined(__DragonFly__)
30 #include <error.h>
31 #else
32 #include <err.h>
33 #define error(x, y, format, args...) errx(1, format, ## args)
34 #endif
35 #include <limits.h>
36 #include <string.h>
37 #include <stdlib.h>
38 #include <stdint.h>
39 #include <unistd.h>
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 #include <fcntl.h>
43 #include <popt.h>
44
45 #include <gelf.h>
46 #include <sys/elf_common.h>
47 #include "dwarf.h"
48 #include "hashtab.h"
49
50 #define DW_TAG_partial_unit 0x3c
51 #define DW_FORM_sec_offset 0x17
52 #define DW_FORM_exprloc 0x18
53 #define DW_FORM_flag_present 0x19
54 #define DW_FORM_ref_sig8 0x20
55
56 #if !defined(R_390_32)
57 #define R_390_32 0x04
58 #endif
59 #if !defined(R_IA64_SECREL32LSB)
60 #define R_IA64_SECREL32LSB 0x65
61 #endif
62
63 char *base_dir = NULL;
64 char *dest_dir = NULL;
65 char *list_file = NULL;
66 int win_path = 0;
67 int list_file_fd = -1;
68 int use_newline = 0;
69 int list_only_files = 0;
70 FILE *debug_fd;
71 int be_quiet = 0;
72
73 typedef struct
74 {
75 Elf *elf;
76 GElf_Ehdr ehdr;
77 Elf_Scn **scn;
78 const char *filename;
79 int lastscn;
80 GElf_Shdr shdr[0];
81 } DSO;
82
83 typedef struct
84 {
85 unsigned char *ptr;
86 uint32_t addend;
87 } REL;
88
89 #define read_uleb128(ptr) ({ \
90 unsigned int ret = 0; \
91 unsigned int c; \
92 int shift = 0; \
93 do \
94 { \
95 c = *ptr++; \
96 ret |= (c & 0x7f) << shift; \
97 shift += 7; \
98 } while (c & 0x80); \
99 \
100 if (shift >= 35) \
101 ret = UINT_MAX; \
102 ret; \
103 })
104
105 static uint16_t (*do_read_16) (unsigned char *ptr);
106 static uint32_t (*do_read_32) (unsigned char *ptr);
107 static void (*write_32) (unsigned char *ptr, GElf_Addr val);
108
109 static int ptr_size;
110 static int cu_version;
111
112 static inline uint16_t
buf_read_ule16(unsigned char * data)113 buf_read_ule16 (unsigned char *data)
114 {
115 return data[0] | (data[1] << 8);
116 }
117
118 static inline uint16_t
buf_read_ube16(unsigned char * data)119 buf_read_ube16 (unsigned char *data)
120 {
121 return data[1] | (data[0] << 8);
122 }
123
124 static inline uint32_t
buf_read_ule32(unsigned char * data)125 buf_read_ule32 (unsigned char *data)
126 {
127 return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
128 }
129
130 static inline uint32_t
buf_read_ube32(unsigned char * data)131 buf_read_ube32 (unsigned char *data)
132 {
133 return data[3] | (data[2] << 8) | (data[1] << 16) | (data[0] << 24);
134 }
135
136 static const char *
strptr(DSO * dso,int sec,off_t offset)137 strptr (DSO *dso, int sec, off_t offset)
138 {
139 Elf_Scn *scn;
140 Elf_Data *data;
141
142 scn = dso->scn[sec];
143 if (offset >= 0 && (GElf_Addr) offset < dso->shdr[sec].sh_size)
144 {
145 data = NULL;
146 while ((data = elf_getdata (scn, data)) != NULL)
147 {
148 if (data->d_buf
149 && offset >= data->d_off
150 && offset < data->d_off + data->d_size)
151 return (const char *) data->d_buf + (offset - data->d_off);
152 }
153 }
154
155 return NULL;
156 }
157
158
159 #define read_1(ptr) *ptr++
160
161 #define read_16(ptr) ({ \
162 uint16_t ret = do_read_16 (ptr); \
163 ptr += 2; \
164 ret; \
165 })
166
167 #define read_32(ptr) ({ \
168 uint32_t ret = do_read_32 (ptr); \
169 ptr += 4; \
170 ret; \
171 })
172
173 REL *relptr, *relend;
174 int reltype;
175
176 #define do_read_32_relocated(ptr) ({ \
177 uint32_t dret = do_read_32 (ptr); \
178 if (relptr) \
179 { \
180 while (relptr < relend && relptr->ptr < ptr) \
181 ++relptr; \
182 if (relptr < relend && relptr->ptr == ptr) \
183 { \
184 if (reltype == SHT_REL) \
185 dret += relptr->addend; \
186 else \
187 dret = relptr->addend; \
188 } \
189 } \
190 dret; \
191 })
192
193 #define read_32_relocated(ptr) ({ \
194 uint32_t ret = do_read_32_relocated (ptr); \
195 ptr += 4; \
196 ret; \
197 })
198
199 static void
dwarf2_write_le32(unsigned char * p,GElf_Addr val)200 dwarf2_write_le32 (unsigned char *p, GElf_Addr val)
201 {
202 uint32_t v = (uint32_t) val;
203
204 p[0] = v;
205 p[1] = v >> 8;
206 p[2] = v >> 16;
207 p[3] = v >> 24;
208 }
209
210
211 static void
dwarf2_write_be32(unsigned char * p,GElf_Addr val)212 dwarf2_write_be32 (unsigned char *p, GElf_Addr val)
213 {
214 uint32_t v = (uint32_t) val;
215
216 p[3] = v;
217 p[2] = v >> 8;
218 p[1] = v >> 16;
219 p[0] = v >> 24;
220 }
221
222 static struct
223 {
224 const char *name;
225 unsigned char *data;
226 Elf_Data *elf_data;
227 size_t size;
228 int sec, relsec;
229 } debug_sections[] =
230 {
231 #define DEBUG_INFO 0
232 #define DEBUG_ABBREV 1
233 #define DEBUG_LINE 2
234 #define DEBUG_ARANGES 3
235 #define DEBUG_PUBNAMES 4
236 #define DEBUG_PUBTYPES 5
237 #define DEBUG_MACINFO 6
238 #define DEBUG_LOC 7
239 #define DEBUG_STR 8
240 #define DEBUG_FRAME 9
241 #define DEBUG_RANGES 10
242 #define DEBUG_TYPES 11
243 #define DEBUG_MACRO 12
244 #define DEBUG_GDB_SCRIPT 13
245 #define DEBUG_SYMTAB 14
246
247 { ".debug_info", NULL, NULL, 0, 0, 0 },
248 { ".debug_abbrev", NULL, NULL, 0, 0, 0 },
249 { ".debug_line", NULL, NULL, 0, 0, 0 },
250 { ".debug_aranges", NULL, NULL, 0, 0, 0 },
251 { ".debug_pubnames", NULL, NULL, 0, 0, 0 },
252 { ".debug_pubtypes", NULL, NULL, 0, 0, 0 },
253 { ".debug_macinfo", NULL, NULL, 0, 0, 0 },
254 { ".debug_loc", NULL, NULL, 0, 0, 0 },
255 { ".debug_str", NULL, NULL, 0, 0, 0 },
256 { ".debug_frame", NULL, NULL, 0, 0, 0 },
257 { ".debug_ranges", NULL, NULL, 0, 0, 0 },
258 { ".debug_types", NULL, NULL, 0, 0, 0 },
259 { ".debug_macro", NULL, NULL, 0, 0, 0 },
260 { ".debug_gdb_scripts", NULL, NULL, 0, 0, 0 },
261 { ".symtab", NULL, NULL, 0, 0, 0 },
262 { NULL, NULL, NULL, 0, 0, 0 }
263 };
264
265 struct abbrev_attr
266 {
267 unsigned int attr;
268 unsigned int form;
269 };
270
271 struct abbrev_tag
272 {
273 unsigned int entry;
274 unsigned int tag;
275 int nattr;
276 struct abbrev_attr attr[0];
277 };
278
279 static hashval_t
abbrev_hash(const void * p)280 abbrev_hash (const void *p)
281 {
282 struct abbrev_tag *t = (struct abbrev_tag *)p;
283
284 return t->entry;
285 }
286
287 static int
abbrev_eq(const void * p,const void * q)288 abbrev_eq (const void *p, const void *q)
289 {
290 struct abbrev_tag *t1 = (struct abbrev_tag *)p;
291 struct abbrev_tag *t2 = (struct abbrev_tag *)q;
292
293 return t1->entry == t2->entry;
294 }
295
296 static void
abbrev_del(void * p)297 abbrev_del (void *p)
298 {
299 free (p);
300 }
301
302 static htab_t
read_abbrev(DSO * dso,unsigned char * ptr)303 read_abbrev (DSO *dso, unsigned char *ptr)
304 {
305 htab_t h = htab_try_create (50, abbrev_hash, abbrev_eq, abbrev_del);
306 unsigned int attr, form;
307 struct abbrev_tag *t;
308 int size;
309 void **slot;
310
311 if (h == NULL)
312 {
313 no_memory:
314 error (0, ENOMEM, "%s: Could not read .debug_abbrev", dso->filename);
315 if (h)
316 htab_delete (h);
317 return NULL;
318 }
319
320 while ((attr = read_uleb128 (ptr)) != 0)
321 {
322 size = 10;
323 t = malloc (sizeof (*t) + size * sizeof (struct abbrev_attr));
324 if (t == NULL)
325 goto no_memory;
326 t->entry = attr;
327 t->nattr = 0;
328 slot = htab_find_slot (h, t, INSERT);
329 if (slot == NULL)
330 {
331 free (t);
332 goto no_memory;
333 }
334 if (*slot != NULL)
335 {
336 error (0, 0, "%s: Duplicate DWARF abbreviation %d", dso->filename,
337 t->entry);
338 free (t);
339 htab_delete (h);
340 return NULL;
341 }
342 t->tag = read_uleb128 (ptr);
343 ++ptr; /* skip children flag. */
344 while ((attr = read_uleb128 (ptr)) != 0)
345 {
346 if (t->nattr == size)
347 {
348 size += 10;
349 t = realloc (t, sizeof (*t) + size * sizeof (struct abbrev_attr));
350 if (t == NULL)
351 goto no_memory;
352 }
353 form = read_uleb128 (ptr);
354 if (form == 2
355 || (form > DW_FORM_flag_present && form != DW_FORM_ref_sig8))
356 {
357 error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename, form);
358 htab_delete (h);
359 return NULL;
360 }
361
362 t->attr[t->nattr].attr = attr;
363 t->attr[t->nattr++].form = form;
364 }
365 if (read_uleb128 (ptr) != 0)
366 {
367 error (0, 0, "%s: DWARF abbreviation does not end with 2 zeros",
368 dso->filename);
369 htab_delete (h);
370 return NULL;
371 }
372 *slot = t;
373 }
374
375 return h;
376 }
377
378 #define IS_DIR_SEPARATOR(c) ((c)=='/')
379
380 static char *
canonicalize_path(const char * s,char * d)381 canonicalize_path (const char *s, char *d)
382 {
383 char *rv = d;
384 char *droot;
385
386 if (IS_DIR_SEPARATOR (*s))
387 {
388 *d++ = *s++;
389 if (IS_DIR_SEPARATOR (*s) && !IS_DIR_SEPARATOR (s[1]))
390 {
391 /* Special case for "//foo" meaning a Posix namespace
392 escape. */
393 *d++ = *s++;
394 }
395 while (IS_DIR_SEPARATOR (*s))
396 s++;
397 }
398 droot = d;
399
400 while (*s)
401 {
402 /* At this point, we're always at the beginning of a path
403 segment. */
404
405 if (s[0] == '.' && (s[1] == 0 || IS_DIR_SEPARATOR (s[1])))
406 {
407 s++;
408 if (*s)
409 while (IS_DIR_SEPARATOR (*s))
410 ++s;
411 }
412
413 else if (s[0] == '.' && s[1] == '.'
414 && (s[2] == 0 || IS_DIR_SEPARATOR (s[2])))
415 {
416 char *pre = d - 1; /* includes slash */
417 while (droot < pre && IS_DIR_SEPARATOR (*pre))
418 pre--;
419 if (droot <= pre && ! IS_DIR_SEPARATOR (*pre))
420 {
421 while (droot < pre && ! IS_DIR_SEPARATOR (*pre))
422 pre--;
423 /* pre now points to the slash */
424 if (droot < pre)
425 pre++;
426 if (pre + 3 == d && pre[0] == '.' && pre[1] == '.')
427 {
428 *d++ = *s++;
429 *d++ = *s++;
430 }
431 else
432 {
433 d = pre;
434 s += 2;
435 if (*s)
436 while (IS_DIR_SEPARATOR (*s))
437 s++;
438 }
439 }
440 else
441 {
442 *d++ = *s++;
443 *d++ = *s++;
444 }
445 }
446 else
447 {
448 while (*s && ! IS_DIR_SEPARATOR (*s))
449 *d++ = *s++;
450 }
451
452 if (IS_DIR_SEPARATOR (*s))
453 {
454 *d++ = *s++;
455 while (IS_DIR_SEPARATOR (*s))
456 s++;
457 }
458 }
459 while (droot < d && IS_DIR_SEPARATOR (d[-1]))
460 --d;
461 if (d == rv)
462 *d++ = '.';
463 *d = 0;
464
465 return rv;
466 }
467
468 static int
has_prefix(const char * str,const char * prefix)469 has_prefix (const char *str,
470 const char *prefix)
471 {
472 size_t str_len;
473 size_t prefix_len;
474
475 str_len = strlen (str);
476 prefix_len = strlen (prefix);
477
478 if (str_len < prefix_len)
479 return 0;
480
481 return strncmp (str, prefix, prefix_len) == 0;
482 }
483
484 static int dirty_elf;
485 static void
dirty_section(unsigned int sec)486 dirty_section (unsigned int sec)
487 {
488 elf_flagdata (debug_sections[sec].elf_data, ELF_C_SET, ELF_F_DIRTY);
489 dirty_elf = 1;
490 }
491
make_win_path(char * path)492 void make_win_path(char * path)
493 {
494 int k = 0;
495 while (path[k] != '\0')
496 {
497 if (path[k] == '/') path[k] = '\\';
498 k++;
499 }
500 }
501
502 #define LST_FILE 0
503 #define LST_DIR 1
504
505 static int
append_list_file(char * p,int type)506 append_list_file(char *p, int type)
507 {
508 size_t size = strlen (p) + 1;
509 ssize_t ret;
510
511 if (list_only_files != 0 && type != LST_FILE)
512 return (0);
513 ret = 0;
514 if (use_newline != 0)
515 p[size - 1] = '\n';
516 while (size > 0)
517 {
518 ret = write (list_file_fd, p, size);
519 if (ret == -1)
520 break;
521 size -= ret;
522 p += ret;
523 }
524 if (use_newline != 0)
525 p[size - 1] = '\0';
526 return (ret < 0 ? -1 : 0);
527 }
528
529 static int
edit_dwarf2_line(DSO * dso,uint32_t off,char * comp_dir,int phase)530 edit_dwarf2_line (DSO *dso, uint32_t off, char *comp_dir, int phase)
531 {
532 unsigned char *ptr = debug_sections[DEBUG_LINE].data, *dir;
533 unsigned char **dirt;
534 unsigned char *endsec = ptr + debug_sections[DEBUG_LINE].size;
535 unsigned char *endcu, *endprol;
536 unsigned char opcode_base;
537 uint32_t value, dirt_cnt;
538 size_t comp_dir_len = strlen (comp_dir);
539 size_t abs_file_cnt = 0, abs_dir_cnt = 0;
540
541 if (phase != 0)
542 return 0;
543
544 /* XXX: RhBug:929365, should we error out instead of ignoring? */
545 if (ptr == NULL)
546 return 0;
547
548 ptr += off;
549
550 /*
551 * unit_length
552 *
553 * The size in bytes of the line number information for this
554 * compilation unit, not including the unit_length field itself.
555 */
556
557 endcu = ptr + 4;
558 endcu += read_32 (ptr);
559 if (endcu == ptr + 0xffffffff)
560 {
561 error (0, 0, "%s: 64-bit DWARF not supported", dso->filename);
562 return 1;
563 }
564
565 if (endcu > endsec)
566 {
567 error (0, 0, "%s: .debug_line CU does not fit into section",
568 dso->filename);
569 return 1;
570 }
571
572 /*
573 * version
574 *
575 * A version number. This number is specific to the line number
576 * information and is independent of the DWARF version number.
577 */
578
579 value = read_16 (ptr);
580 if (value != 2 && value != 3 && value != 4)
581 {
582 error (0, 0, "%s: DWARF version %d unhandled", dso->filename,
583 value);
584 return 1;
585 }
586
587 /*
588 * header_length
589 *
590 * The number of bytes following the header_length field to the
591 * beginning of the first byte of the line number program itself.
592 * In the 32-bit DWARF format, this is a 4-byte unsigned length;
593 * in the 64-bit DWARF format, this field is an 8-byte unsigned
594 * length (see Section 7.4).
595 */
596
597 endprol = ptr + 4;
598 endprol += read_32 (ptr);
599 if (endprol > endcu)
600 {
601 error (0, 0, "%s: .debug_line CU prologue does not fit into CU",
602 dso->filename);
603 return 1;
604 }
605
606 opcode_base = ptr[4 + (value >= 4)];
607 ptr = dir = ptr + 4 + (value >= 4) + opcode_base;
608
609 /*
610 * include_directories (sequence of path names)
611 *
612 * Entries in this sequence describe each path that was searched
613 * for included source files in this compilation.
614 *
615 * The last entry is followed by a single null byte.
616 */
617
618 /* dir table: */
619 value = 1;
620 while (*ptr != 0)
621 {
622 ptr = (unsigned char *) strchr ((char *)ptr, 0) + 1;
623 ++value;
624 }
625
626 dirt = (unsigned char **) alloca (value * sizeof (unsigned char *));
627 dirt[0] = (unsigned char *) ".";
628 dirt_cnt = 1;
629 ptr = dir;
630 while (*ptr != 0)
631 {
632 dirt[dirt_cnt++] = ptr;
633 ptr = (unsigned char *) strchr ((char *)ptr, 0) + 1;
634 }
635 ptr++;
636
637 /* file table: */
638 while (*ptr != 0)
639 {
640 char *s, *file;
641 size_t file_len, dir_len;
642
643 file = (char *) ptr;
644 ptr = (unsigned char *) strchr ((char *)ptr, 0) + 1;
645 value = read_uleb128 (ptr);
646
647 if (value >= dirt_cnt)
648 {
649 error (0, 0, "%s: Wrong directory table index %u",
650 dso->filename, value);
651 return 1;
652 }
653
654 /* GCC emits those it seems sometimes */
655 if (strcmp(file, "<built-in>") == 0)
656 goto skip;
657
658 file_len = strlen (file);
659 dir_len = strlen ((char *)dirt[value]);
660 s = malloc (comp_dir_len + 1 + file_len + 1 + dir_len + 1);
661 if (s == NULL)
662 {
663 error (0, ENOMEM, "%s: Reading file table", dso->filename);
664 return 1;
665 }
666
667 if (*file == '/')
668 {
669 memcpy (s, file, file_len + 1);
670 if (dest_dir && has_prefix (file, base_dir))
671 ++abs_file_cnt;
672 }
673 else if (*dirt[value] == '/')
674 {
675 memcpy (s, dirt[value], dir_len);
676 s[dir_len] = '/';
677 memcpy (s + dir_len + 1, file, file_len + 1);
678 }
679 else
680 {
681 char *p = s;
682 if (comp_dir_len != 0)
683 {
684 memcpy (s, comp_dir, comp_dir_len);
685 s[comp_dir_len] = '/';
686 p += comp_dir_len + 1;
687 }
688 memcpy (p, dirt[value], dir_len);
689 p[dir_len] = '/';
690 memcpy (p + dir_len + 1, file, file_len + 1);
691 }
692
693 fprintf(debug_fd, "@@@@linedirt[%d] %s\n", value, dirt[value]);
694
695 canonicalize_path (s, s);
696
697 if (list_file_fd != -1)
698 {
699 char *p = NULL;
700 if (base_dir == NULL)
701 p = s;
702 else if (has_prefix (s, base_dir))
703 p = s + strlen (base_dir);
704 else if (has_prefix (s, dest_dir))
705 p = s + strlen (dest_dir);
706
707 if (p)
708 {
709 append_list_file(p, LST_FILE);
710 }
711 }
712
713 if (win_path)
714 make_win_path(s);
715
716 free (s);
717
718 skip:
719 read_uleb128 (ptr);
720 read_uleb128 (ptr);
721 }
722 ++ptr;
723
724 if (dest_dir)
725 {
726 unsigned char *srcptr, *buf = NULL;
727 size_t base_len = strlen (base_dir);
728 size_t dest_len = strlen (dest_dir);
729 size_t shrank = 0;
730
731 if (dest_len == base_len)
732 abs_file_cnt = 0;
733
734 if (abs_file_cnt)
735 {
736 srcptr = buf = malloc (ptr - dir);
737 memcpy (srcptr, dir, ptr - dir);
738 ptr = dir;
739 }
740 else
741 ptr = srcptr = dir;
742
743 while (*srcptr != 0)
744 {
745 size_t len = strlen ((char *)srcptr) + 1;
746 const unsigned char *readptr = srcptr;
747
748 char *orig = strdup ((const char *) srcptr);
749
750 fprintf(debug_fd, "####linesrcptr %s\n", srcptr);
751
752 if (*srcptr == '/' && has_prefix ((char *)srcptr, base_dir))
753 {
754 if (dest_len < base_len)
755 ++abs_dir_cnt;
756 memcpy (ptr, dest_dir, dest_len);
757 ptr += dest_len;
758 readptr += base_len;
759 }
760
761 srcptr += len;
762
763 shrank += srcptr - readptr;
764
765 canonicalize_path ((char *)readptr, (char *)ptr);
766
767 if (win_path)
768 make_win_path((char *)ptr);
769
770 len = strlen ((char *)ptr) + 1;
771 shrank -= len;
772 ptr += len;
773
774 if (memcmp (orig, ptr - len, len))
775 dirty_section (DEBUG_STR);
776 free (orig);
777 }
778
779 if (shrank > 0)
780 {
781 if (--shrank == 0)
782 error (EXIT_FAILURE, 0,
783 "canonicalization unexpectedly shrank by one character");
784 else
785 {
786 memset (ptr, 'X', shrank);
787 ptr += shrank;
788 *ptr++ = '\0';
789 }
790 }
791
792 if (abs_dir_cnt + abs_file_cnt != 0)
793 {
794 size_t len = (abs_dir_cnt + abs_file_cnt) * (base_len - dest_len);
795
796 if (len == 1)
797 error (EXIT_FAILURE, 0, "-b arg has to be either the same length as -d arg, or more than 1 char longer");
798 memset (ptr, 'X', len - 1);
799 ptr += len - 1;
800 *ptr++ = '\0';
801 }
802 *ptr++ = '\0';
803 ++srcptr;
804
805 while (*srcptr != 0)
806 {
807 size_t len = strlen ((char *)srcptr) + 1;
808
809 fprintf(debug_fd, "@@@@line srcptr %s\n", srcptr);
810
811 if (*srcptr == '/' && has_prefix ((char *)srcptr, base_dir))
812 {
813 memcpy (ptr, dest_dir, dest_len);
814 if (dest_len < base_len)
815 {
816 memmove (ptr + dest_len, srcptr + base_len,
817 len - base_len);
818 ptr += dest_len - base_len;
819 }
820 dirty_section (DEBUG_STR);
821 }
822 else if (ptr != srcptr)
823 memmove (ptr, srcptr, len);
824
825 srcptr += len;
826 ptr += len;
827 dir = srcptr;
828
829 read_uleb128 (srcptr);
830 read_uleb128 (srcptr);
831 read_uleb128 (srcptr);
832
833 if (ptr != dir)
834 memmove (ptr, dir, srcptr - dir);
835 ptr += srcptr - dir;
836 }
837
838 *ptr = '\0';
839
840 free (buf);
841 }
842 return 0;
843 }
844
845 static unsigned char *
edit_attributes(DSO * dso,unsigned char * ptr,struct abbrev_tag * t,int phase)846 edit_attributes (DSO *dso, unsigned char *ptr, struct abbrev_tag *t, int phase)
847 {
848 int i;
849 uint32_t list_offs;
850 int found_list_offs;
851 char *comp_dir;
852
853 comp_dir = NULL;
854 list_offs = 0;
855 found_list_offs = 0;
856 for (i = 0; i < t->nattr; ++i)
857 {
858 uint32_t form = t->attr[i].form;
859 size_t len = 0;
860 size_t base_len, dest_len;
861
862 while (1)
863 {
864 if (t->attr[i].attr == DW_AT_stmt_list)
865 {
866 if (form == DW_FORM_data4
867 || form == DW_FORM_sec_offset)
868 {
869 list_offs = do_read_32_relocated (ptr);
870 found_list_offs = 1;
871 }
872 }
873
874 if (t->attr[i].attr == DW_AT_comp_dir)
875 {
876 if (form == DW_FORM_string)
877 {
878 free (comp_dir);
879 comp_dir = strdup ((char *)ptr);
880
881 fprintf(debug_fd, "####1comp_dir %s\n", comp_dir);
882
883 if (phase == 1 && dest_dir && has_prefix ((char *)ptr, base_dir))
884 {
885 base_len = strlen (base_dir);
886 dest_len = strlen (dest_dir);
887
888 fprintf(debug_fd, "####1updating base from %s to %s\n", base_dir, dest_dir);
889
890 memcpy (ptr, dest_dir, dest_len);
891 if (dest_len < base_len)
892 {
893 if (win_path)
894 memset(ptr + dest_len, '\\',
895 base_len - dest_len);
896 else
897 memset(ptr + dest_len, '/',
898 base_len - dest_len);
899
900 }
901 dirty_section (DEBUG_INFO);
902 }
903 }
904 else if (form == DW_FORM_strp &&
905 debug_sections[DEBUG_STR].data)
906 {
907 char *dir;
908
909 dir = (char *) debug_sections[DEBUG_STR].data
910 + do_read_32_relocated (ptr);
911
912 free (comp_dir);
913 comp_dir = strdup (dir);
914
915 fprintf(debug_fd, "####2comp_dir %s\n", comp_dir);
916
917 if (phase == 1 && dest_dir && has_prefix (dir, base_dir))
918 {
919 base_len = strlen (base_dir);
920 dest_len = strlen (dest_dir);
921
922 fprintf(debug_fd, "####2updating base from %s to %s\n", base_dir, dest_dir);
923
924 memcpy (dir, dest_dir, dest_len);
925 if (dest_len < base_len)
926 {
927 memmove (dir + dest_len, dir + base_len,
928 strlen (dir + base_len) + 1);
929 }
930 dirty_section (DEBUG_STR);
931 }
932 }
933 }
934 else if ((t->tag == DW_TAG_compile_unit
935 || t->tag == DW_TAG_partial_unit)
936 && t->attr[i].attr == DW_AT_name)
937 {
938 char *name;
939
940 if (form == DW_FORM_strp && debug_sections[DEBUG_STR].data)
941 {
942 name = (char *) debug_sections[DEBUG_STR].data
943 + do_read_32_relocated (ptr);
944 }
945 else if (form == DW_FORM_string && debug_sections[DEBUG_INFO].data)
946 {
947 name = (char *)(ptr);
948 }
949
950 fprintf(debug_fd, "====name %s\n", name);
951
952 /*
953 * If the compile unit has full path from root '/',
954 * and the compilation directory is still null,
955 * then we construct a compilation directory string.
956 */
957
958 if (*name == '/' && comp_dir == NULL)
959 {
960 /*
961 * The strrchr() function shall locate the last
962 * occurrence of c (converted to a char) in the
963 * string pointed to by s. The terminating null
964 * byte is considered to be part of the string.
965 *
966 * Upon successful completion, strrchr() shall
967 * return a pointer to the byte or a null pointer
968 * if c does not occur in the string.
969 */
970
971 char *enddir = strrchr (name, '/');
972
973 /*
974 * The compilation directory is constructed by
975 * removing the file name from the compile unit
976 * name attribute.
977 */
978
979 if (enddir != name)
980 {
981 comp_dir = malloc (enddir - name + 1);
982 memcpy (comp_dir, name, enddir - name);
983 comp_dir [enddir - name] = '\0';
984 }
985 else
986 comp_dir = strdup ("/");
987 }
988
989 if (phase == 1 && dest_dir && has_prefix (name, base_dir))
990 {
991 base_len = strlen (base_dir);
992 dest_len = strlen (dest_dir);
993
994 fprintf(debug_fd, "====updating base from %s to %s\n", base_dir, dest_dir);
995
996 memcpy (name, dest_dir, dest_len);
997
998 if (form == DW_FORM_strp)
999 {
1000 if (dest_len < base_len)
1001 {
1002 memmove (name + dest_len, name + base_len,
1003 strlen (name + base_len) + 1);
1004 }
1005
1006 dirty_section (DEBUG_STR);
1007 }
1008 else
1009 {
1010 if (dest_len < base_len)
1011 {
1012 if (win_path)
1013 memset(name + dest_len, '\\',
1014 base_len - dest_len);
1015 else
1016 memset(name + dest_len, '/',
1017 base_len - dest_len);
1018 }
1019
1020 dirty_section (DEBUG_INFO);
1021 }
1022
1023 if (win_path)
1024 make_win_path((char *)name);
1025
1026 }
1027
1028 }
1029
1030 switch (form)
1031 {
1032 case DW_FORM_ref_addr:
1033 if (cu_version == 2)
1034 ptr += ptr_size;
1035 else
1036 ptr += 4;
1037 break;
1038 case DW_FORM_flag_present:
1039 break;
1040 case DW_FORM_addr:
1041 ptr += ptr_size;
1042 break;
1043 case DW_FORM_ref1:
1044 case DW_FORM_flag:
1045 case DW_FORM_data1:
1046 ++ptr;
1047 break;
1048 case DW_FORM_ref2:
1049 case DW_FORM_data2:
1050 ptr += 2;
1051 break;
1052 case DW_FORM_ref4:
1053 case DW_FORM_data4:
1054 case DW_FORM_sec_offset:
1055 ptr += 4;
1056 break;
1057 case DW_FORM_ref8:
1058 case DW_FORM_data8:
1059 case DW_FORM_ref_sig8:
1060 ptr += 8;
1061 break;
1062 case DW_FORM_sdata:
1063 case DW_FORM_ref_udata:
1064 case DW_FORM_udata:
1065 read_uleb128 (ptr);
1066 break;
1067 case DW_FORM_strp:
1068 ptr += 4;
1069 break;
1070 case DW_FORM_string:
1071 ptr = (unsigned char *) strchr ((char *)ptr, '\0') + 1;
1072 break;
1073 case DW_FORM_indirect:
1074 form = read_uleb128 (ptr);
1075 continue;
1076 case DW_FORM_block1:
1077 len = *ptr++;
1078 break;
1079 case DW_FORM_block2:
1080 len = read_16 (ptr);
1081 form = DW_FORM_block1;
1082 break;
1083 case DW_FORM_block4:
1084 len = read_32 (ptr);
1085 form = DW_FORM_block1;
1086 break;
1087 case DW_FORM_block:
1088 case DW_FORM_exprloc:
1089 len = read_uleb128 (ptr);
1090 form = DW_FORM_block1;
1091 assert (len < UINT_MAX);
1092 break;
1093 default:
1094 error (0, 0, "%s: Unknown DWARF DW_FORM_%d", dso->filename,
1095 form);
1096 return NULL;
1097 }
1098
1099 if (form == DW_FORM_block1)
1100 ptr += len;
1101
1102 break;
1103 }
1104 }
1105
1106 /* Ensure the CU current directory will exist even if only empty. Source
1107 filenames possibly located in its parent directories refer relatively to
1108 it and the debugger (GDB) cannot safely optimize out the missing
1109 CU current dir subdirectories. */
1110 if (comp_dir && list_file_fd != -1)
1111 {
1112 char *p;
1113
1114 if (base_dir && has_prefix (comp_dir, base_dir))
1115 p = comp_dir + strlen (base_dir);
1116 else if (dest_dir && has_prefix (comp_dir, dest_dir))
1117 p = comp_dir + strlen (dest_dir);
1118 else
1119 p = comp_dir;
1120
1121 append_list_file(p, LST_DIR);
1122 }
1123
1124 if (found_list_offs && comp_dir)
1125 edit_dwarf2_line (dso, list_offs, comp_dir, phase);
1126
1127 free (comp_dir);
1128
1129 return ptr;
1130 }
1131
1132 static int
rel_cmp(const void * a,const void * b)1133 rel_cmp (const void *a, const void *b)
1134 {
1135 REL *rela = (REL *) a, *relb = (REL *) b;
1136
1137 if (rela->ptr < relb->ptr)
1138 return -1;
1139
1140 if (rela->ptr > relb->ptr)
1141 return 1;
1142
1143 return 0;
1144 }
1145
1146 static void
edit_symtab(DSO * dso,Elf_Data * data)1147 edit_symtab (DSO *dso, Elf_Data *data)
1148 {
1149 GElf_Sym sym;
1150 GElf_Shdr shdr;
1151 unsigned long stridx = -1;
1152 int i;
1153 char *s;
1154 int sec = debug_sections[DEBUG_SYMTAB].sec;
1155 Elf_Data *strtab_data;
1156 gelf_getshdr(dso->scn[sec], &shdr);
1157
1158 stridx = shdr.sh_link;
1159
1160 strtab_data = elf_getdata(dso->scn[stridx], NULL);
1161
1162 i = 0;
1163 while (gelf_getsym(data, i++, &sym) != NULL)
1164 {
1165 s = elf_strptr(dso->elf, stridx, sym.st_name);
1166
1167 if (GELF_ST_TYPE(sym.st_info) == STT_FILE)
1168 {
1169 fprintf(debug_fd, "file %s\n", s);
1170
1171 if (dest_dir && has_prefix (s, base_dir))
1172 {
1173 int base_len = strlen (base_dir);
1174 int dest_len = strlen (dest_dir);
1175
1176 fprintf(debug_fd, "!!!!updating symbol file base from %s to %s\n", base_dir, dest_dir);
1177
1178 memcpy (s, dest_dir, dest_len);
1179 if (dest_len < base_len)
1180 {
1181 memmove (s + dest_len, s + base_len,
1182 strlen (s + base_len) + 1);
1183 }
1184
1185 make_win_path(s);
1186
1187 elf_flagdata (strtab_data, ELF_C_SET, ELF_F_DIRTY);
1188 }
1189 }
1190 else
1191 {
1192 fprintf(debug_fd, "symbol %s\n", s);
1193 }
1194 }
1195 }
1196
1197 static int
edit_dwarf2(DSO * dso)1198 edit_dwarf2 (DSO *dso)
1199 {
1200 Elf_Data *data;
1201 Elf_Scn *scn;
1202 int i, j;
1203
1204 for (i = 0; debug_sections[i].name; ++i)
1205 {
1206 debug_sections[i].data = NULL;
1207 debug_sections[i].size = 0;
1208 debug_sections[i].sec = 0;
1209 debug_sections[i].relsec = 0;
1210 }
1211 ptr_size = 0;
1212
1213 /* Record .debug_* sections into debug_sections[] array */
1214
1215 for (i = 1; i < dso->ehdr.e_shnum; ++i)
1216 if (! (dso->shdr[i].sh_flags & (SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR))
1217 && dso->shdr[i].sh_size)
1218 {
1219 /*
1220 * .debug_* sections do not have the following features:
1221 *
1222 * SHF.ALLOC - Section occupies memory during execution
1223 * SHF.WRITE - Section whose contents should be writable in execution
1224 * SHF.EXECINSTR - Section contains executable machine instructions
1225 */
1226
1227 const char *name = strptr (dso, dso->ehdr.e_shstrndx,
1228 dso->shdr[i].sh_name);
1229
1230 if (strncmp (name, ".debug_", sizeof (".debug_") - 1) == 0)
1231 {
1232 for (j = 0; debug_sections[j].name; ++j)
1233 if (strcmp (name, debug_sections[j].name) == 0)
1234 {
1235 if (debug_sections[j].data)
1236 {
1237 error (0, 0, "%s: Found two copies of %s section",
1238 dso->filename, name);
1239 return 1;
1240 }
1241
1242 scn = dso->scn[i];
1243 data = elf_getdata (scn, NULL);
1244 assert (data != NULL && data->d_buf != NULL);
1245 assert (elf_getdata (scn, data) == NULL);
1246 assert (data->d_off == 0);
1247 assert (data->d_size == dso->shdr[i].sh_size);
1248 debug_sections[j].data = data->d_buf;
1249 debug_sections[j].elf_data = data;
1250 debug_sections[j].size = data->d_size;
1251 debug_sections[j].sec = i;
1252 break;
1253 }
1254
1255 if (debug_sections[j].name == NULL)
1256 {
1257 error (0, 0, "%s: Unknown debugging section %s",
1258 dso->filename, name);
1259 }
1260 }
1261 else if (dso->ehdr.e_type == ET_REL /* Relocatable file */
1262 && ((dso->shdr[i].sh_type == SHT_REL /* Relocation entries without explicit addends */
1263 && strncmp (name, ".rel.debug_",
1264 sizeof (".rel.debug_") - 1) == 0)
1265 || (dso->shdr[i].sh_type == SHT_RELA /* Relocation entries with explicit addends */
1266 && strncmp (name, ".rela.debug_",
1267 sizeof (".rela.debug_") - 1) == 0)))
1268 {
1269 for (j = 0; debug_sections[j].name; ++j)
1270 if (strcmp (name + sizeof (".rel") - 1
1271 + (dso->shdr[i].sh_type == SHT_RELA),
1272 debug_sections[j].name) == 0)
1273 {
1274 debug_sections[j].relsec = i;
1275
1276 fprintf(debug_fd, "Relocation section %d name %s\n", i, name);
1277
1278 break;
1279 }
1280 }
1281 else if (strncmp (name, ".symtab", sizeof (".symtab") - 1) == 0)
1282 {
1283 fprintf(debug_fd, "########.symtab sec %d\n", i);
1284 scn = dso->scn[i];
1285 data = elf_getdata (scn, NULL);
1286 debug_sections[DEBUG_SYMTAB].data = data->d_buf;
1287 debug_sections[DEBUG_SYMTAB].elf_data = data;
1288 debug_sections[DEBUG_SYMTAB].size = data->d_size;
1289 debug_sections[DEBUG_SYMTAB].sec = i;
1290
1291 edit_symtab(dso, data);
1292 }
1293 }
1294
1295 /* Get buffer reading functions according to endian mode */
1296
1297 if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
1298 {
1299 do_read_16 = buf_read_ule16;
1300 do_read_32 = buf_read_ule32;
1301 write_32 = dwarf2_write_le32;
1302 }
1303 else if (dso->ehdr.e_ident[EI_DATA] == ELFDATA2MSB)
1304 {
1305 do_read_16 = buf_read_ube16;
1306 do_read_32 = buf_read_ube32;
1307 write_32 = dwarf2_write_be32;
1308 }
1309 else
1310 {
1311 error (0, 0, "%s: Wrong ELF data enconding", dso->filename);
1312 return 1;
1313 }
1314
1315 /* Edit .debug_info section */
1316
1317 if (debug_sections[DEBUG_INFO].data != NULL)
1318 {
1319 unsigned char *ptr, *endcu, *endsec;
1320 uint32_t value;
1321 htab_t abbrev;
1322 struct abbrev_tag tag, *t;
1323 int phase;
1324 REL *relbuf = NULL;
1325
1326 /* Handle Relocation entries */
1327
1328 if (debug_sections[DEBUG_INFO].relsec)
1329 {
1330 int ndx, maxndx;
1331 GElf_Rel rel;
1332 GElf_Rela rela;
1333 GElf_Sym sym;
1334 GElf_Addr base = dso->shdr[debug_sections[DEBUG_INFO].sec].sh_addr;
1335 Elf_Data *symdata = NULL;
1336 int rtype;
1337
1338 i = debug_sections[DEBUG_INFO].relsec;
1339 scn = dso->scn[i];
1340 data = elf_getdata (scn, NULL);
1341 assert (data != NULL && data->d_buf != NULL);
1342 assert (elf_getdata (scn, data) == NULL);
1343 assert (data->d_off == 0);
1344 assert (data->d_size == dso->shdr[i].sh_size);
1345 maxndx = dso->shdr[i].sh_size / dso->shdr[i].sh_entsize;
1346 relbuf = malloc (maxndx * sizeof (REL));
1347 reltype = dso->shdr[i].sh_type;
1348 if (relbuf == NULL)
1349 error (1, errno, "%s: Could not allocate memory", dso->filename);
1350
1351 symdata = elf_getdata (dso->scn[dso->shdr[i].sh_link], NULL);
1352 assert (symdata != NULL && symdata->d_buf != NULL);
1353 assert (elf_getdata (dso->scn[dso->shdr[i].sh_link], symdata)
1354 == NULL);
1355 assert (symdata->d_off == 0);
1356 assert (symdata->d_size
1357 == dso->shdr[dso->shdr[i].sh_link].sh_size);
1358
1359 for (ndx = 0, relend = relbuf; ndx < maxndx; ++ndx)
1360 {
1361 if (dso->shdr[i].sh_type == SHT_REL)
1362 {
1363 gelf_getrel (data, ndx, &rel);
1364 rela.r_offset = rel.r_offset;
1365 rela.r_info = rel.r_info;
1366 rela.r_addend = 0;
1367 }
1368 else
1369 gelf_getrela (data, ndx, &rela);
1370 gelf_getsym (symdata, ELF64_R_SYM (rela.r_info), &sym);
1371 /* Relocations against section symbols are uninteresting
1372 in REL. */
1373 if (dso->shdr[i].sh_type == SHT_REL && sym.st_value == 0)
1374 continue;
1375 /* Only consider relocations against .debug_str, .debug_line
1376 and .debug_abbrev. */
1377 if (sym.st_shndx != debug_sections[DEBUG_STR].sec
1378 && sym.st_shndx != debug_sections[DEBUG_LINE].sec
1379 && sym.st_shndx != debug_sections[DEBUG_ABBREV].sec)
1380 continue;
1381 rela.r_addend += sym.st_value;
1382 rtype = ELF64_R_TYPE (rela.r_info);
1383 switch (dso->ehdr.e_machine)
1384 {
1385 #ifndef __DragonFly__
1386 case EM_SPARC:
1387 case EM_SPARC32PLUS:
1388 case EM_SPARCV9:
1389 if (rtype != R_SPARC_32 && rtype != R_SPARC_UA32)
1390 goto fail;
1391 break;
1392 case EM_386:
1393 if (rtype != R_386_32)
1394 goto fail;
1395 break;
1396 case EM_PPC:
1397 case EM_PPC64:
1398 if (rtype != R_PPC_ADDR32 && rtype != R_PPC_UADDR32)
1399 goto fail;
1400 break;
1401 #endif
1402 case EM_S390:
1403 if (rtype != R_390_32)
1404 goto fail;
1405 break;
1406 case EM_IA_64:
1407 if (rtype != R_IA64_SECREL32LSB)
1408 goto fail;
1409 break;
1410 case EM_X86_64:
1411 if (rtype != R_X86_64_32)
1412 goto fail;
1413 break;
1414 default:
1415 fail:
1416 error (1, 0, "%s: Unhandled relocation %d in .debug_info section",
1417 dso->filename, rtype);
1418 }
1419 relend->ptr = debug_sections[DEBUG_INFO].data
1420 + (rela.r_offset - base);
1421 relend->addend = rela.r_addend;
1422 ++relend;
1423 }
1424 if (relbuf == relend)
1425 {
1426 free (relbuf);
1427 relbuf = NULL;
1428 relend = NULL;
1429 }
1430 else
1431 qsort (relbuf, relend - relbuf, sizeof (REL), rel_cmp);
1432 }
1433
1434 for (phase = 0; phase < 2; phase++)
1435 {
1436 fprintf(debug_fd, "@@@###@@@phase %d@@@###@@@\n", phase);
1437
1438 ptr = debug_sections[DEBUG_INFO].data;
1439 relptr = relbuf;
1440 endsec = ptr + debug_sections[DEBUG_INFO].size;
1441
1442 /* Parse the .debug_info data buffer */
1443
1444 while (ptr < endsec)
1445 {
1446 /* The .debug_info should be at least 11 bytes */
1447
1448 if (ptr + 11 > endsec)
1449 {
1450 error (0, 0, "%s: .debug_info CU header too small",
1451 dso->filename);
1452 return 1;
1453 }
1454
1455 endcu = ptr + 4;
1456 endcu += read_32 (ptr); /* Length - 32 bits */
1457 if (endcu == ptr + 0xffffffff)
1458 {
1459 error (0, 0, "%s: 64-bit DWARF not supported", dso->filename);
1460 return 1;
1461 }
1462
1463 if (endcu > endsec)
1464 {
1465 error (0, 0, "%s: .debug_info too small", dso->filename);
1466 return 1;
1467 }
1468
1469 cu_version = read_16 (ptr); /* Version - 16 bits */
1470 if (cu_version != 2 && cu_version != 3 && cu_version != 4)
1471 {
1472 error (0, 0, "%s: DWARF version %d unhandled", dso->filename,
1473 cu_version);
1474 return 1;
1475 }
1476
1477 value = read_32_relocated (ptr); /* Abbrev Offset - 32 bits */
1478 if (value >= debug_sections[DEBUG_ABBREV].size)
1479 {
1480 if (debug_sections[DEBUG_ABBREV].data == NULL)
1481 error (0, 0, "%s: .debug_abbrev not present", dso->filename);
1482 else
1483 error (0, 0, "%s: DWARF CU abbrev offset too large",
1484 dso->filename);
1485 return 1;
1486 }
1487
1488 if (ptr_size == 0)
1489 {
1490 ptr_size = read_1 (ptr); /* Pointer Size - 8 bits */
1491 if (ptr_size != 4 && ptr_size != 8)
1492 {
1493 error (0, 0, "%s: Invalid DWARF pointer size %d",
1494 dso->filename, ptr_size);
1495 return 1;
1496 }
1497 }
1498 else if (read_1 (ptr) != ptr_size) /* Pointer Size - 8 bits */
1499 {
1500 error (0, 0, "%s: DWARF pointer size differs between CUs",
1501 dso->filename);
1502 return 1;
1503 }
1504
1505 /* Read from .debug_abbrev section at Abbrev Offset */
1506
1507 abbrev = read_abbrev (dso,
1508 debug_sections[DEBUG_ABBREV].data + value);
1509 if (abbrev == NULL)
1510 return 1;
1511
1512 while (ptr < endcu)
1513 {
1514 tag.entry = read_uleb128 (ptr);
1515 if (tag.entry == 0)
1516 continue;
1517 t = htab_find_with_hash (abbrev, &tag, tag.entry);
1518 if (t == NULL)
1519 {
1520 error (0, 0, "%s: Could not find DWARF abbreviation %d",
1521 dso->filename, tag.entry);
1522 htab_delete (abbrev);
1523 return 1;
1524 }
1525
1526 ptr = edit_attributes (dso, ptr, t, phase);
1527 if (ptr == NULL)
1528 break;
1529 }
1530
1531 htab_delete (abbrev);
1532 }
1533 }
1534 free (relbuf);
1535 }
1536
1537 return 0;
1538 }
1539
1540 static struct poptOption optionsTable[] =
1541 {
1542 {
1543 "base-dir", 'b', POPT_ARG_STRING, &base_dir, 0,
1544 "base build directory of objects", NULL
1545 },
1546 {
1547 "dest-dir", 'd', POPT_ARG_STRING, &dest_dir, 0,
1548 "directory to rewrite base-dir into", NULL
1549 },
1550 {
1551 "list-file", 'l', POPT_ARG_STRING, &list_file, 0,
1552 "file where to put list of source and header file names", NULL
1553 },
1554 {
1555 "win-path", 'w', POPT_ARG_NONE, &win_path, 0,
1556 "change the path delimiter to be Windows compatible", NULL
1557 },
1558 {
1559 "use-newline", 'n', POPT_ARG_NONE, &use_newline, 0,
1560 "separate strings in the list file with \\n, not \\0", NULL
1561 },
1562 {
1563 "files-only", 'f', POPT_ARG_NONE, &list_only_files, 0,
1564 "do not include directories into the list file", NULL
1565 },
1566 {
1567 "quiet", 'q', POPT_ARG_NONE, &be_quiet, 0,
1568 "quiet mode, do not write anything to standard output", NULL
1569 },
1570 POPT_AUTOHELP
1571 { NULL, 0, 0, NULL, 0, NULL, NULL }
1572 };
1573
1574 static DSO *
fdopen_dso(int fd,const char * name,int readonly)1575 fdopen_dso (int fd, const char *name, int readonly)
1576 {
1577 Elf *elf = NULL;
1578 GElf_Ehdr ehdr;
1579 int i;
1580 DSO *dso = NULL;
1581
1582 elf = elf_begin (fd, (readonly == 0) ? ELF_C_RDWR : ELF_C_READ, NULL);
1583 if (elf == NULL)
1584 {
1585 error (0, 0, "cannot open ELF file: %s", elf_errmsg (-1));
1586 goto error_out;
1587 }
1588
1589 if (elf_kind (elf) != ELF_K_ELF)
1590 {
1591 error (0, 0, "\"%s\" is not an ELF file", name);
1592 goto error_out;
1593 }
1594
1595 if (gelf_getehdr (elf, &ehdr) == NULL)
1596 {
1597 error (0, 0, "cannot get the ELF header: %s",
1598 elf_errmsg (-1));
1599 goto error_out;
1600 }
1601
1602 if (ehdr.e_type != ET_DYN && ehdr.e_type != ET_EXEC && ehdr.e_type != ET_REL)
1603 {
1604 error (0, 0, "\"%s\" is not a shared library", name);
1605 goto error_out;
1606 }
1607
1608 /* Allocate DSO structure. Leave place for additional 20 new section
1609 headers. */
1610 dso = (DSO *)
1611 malloc (sizeof(DSO) + (ehdr.e_shnum + 20) * sizeof(GElf_Shdr)
1612 + (ehdr.e_shnum + 20) * sizeof(Elf_Scn *));
1613 if (!dso)
1614 {
1615 error (0, ENOMEM, "Could not open DSO");
1616 goto error_out;
1617 }
1618
1619 elf_flagelf (elf, ELF_C_SET, ELF_F_LAYOUT);
1620
1621 memset (dso, 0, sizeof(DSO));
1622 dso->elf = elf;
1623 dso->ehdr = ehdr;
1624 dso->scn = (Elf_Scn **) &dso->shdr[ehdr.e_shnum + 20];
1625
1626 for (i = 0; i < ehdr.e_shnum; ++i)
1627 {
1628 dso->scn[i] = elf_getscn (elf, i);
1629 gelf_getshdr (dso->scn[i], dso->shdr + i);
1630 }
1631
1632 dso->filename = (const char *) strdup (name);
1633 return dso;
1634
1635 error_out:
1636 if (dso)
1637 {
1638 free ((char *) dso->filename);
1639 free (dso);
1640 }
1641 if (elf)
1642 elf_end (elf);
1643 if (fd != -1)
1644 close (fd);
1645 return NULL;
1646 }
1647
1648 int
main(int argc,char * argv[])1649 main (int argc, char *argv[])
1650 {
1651 DSO *dso;
1652 int fd, i, readonly;
1653 const char *file;
1654 poptContext optCon; /* context for parsing command-line options */
1655 int nextopt;
1656 const char **args;
1657 struct stat stat_buf;
1658 char *p;
1659
1660 debug_fd = stdout;
1661 optCon = poptGetContext("debugedit", argc, (const char **)argv, optionsTable, 0);
1662
1663 while ((nextopt = poptGetNextOpt (optCon)) > 0 || nextopt == POPT_ERROR_BADOPT)
1664 /* do nothing */ ;
1665
1666 if (nextopt != -1)
1667 {
1668 fprintf (stderr, "Error on option %s: %s.\nRun '%s --help' to see a full list of available command line options.\n",
1669 poptBadOption (optCon, 0),
1670 poptStrerror (nextopt),
1671 argv[0]);
1672 exit (1);
1673 }
1674
1675 args = poptGetArgs (optCon);
1676 if (args == NULL || args[0] == NULL || args[1] != NULL)
1677 {
1678 poptPrintHelp(optCon, stdout, 0);
1679 exit (1);
1680 }
1681
1682 if (be_quiet != 0)
1683 {
1684 debug_fd = fopen("/dev/null", "w");
1685 if (debug_fd == NULL)
1686 {
1687 fprintf (stderr, "Can't open /dev/null\n");
1688 exit (1);
1689 }
1690 }
1691
1692 if (dest_dir != NULL)
1693 {
1694 if (base_dir == NULL)
1695 {
1696 fprintf (stderr, "You must specify a base dir if you specify a dest dir\n");
1697 exit (1);
1698 }
1699 if (strlen (dest_dir) > strlen (base_dir))
1700 {
1701 fprintf (stderr, "Dest dir longer than base dir is not supported\n");
1702 exit (1);
1703 }
1704 }
1705
1706 if (dest_dir == NULL && base_dir == NULL && win_path == 0)
1707 {
1708 readonly = 1;
1709 }
1710 else
1711 {
1712 readonly = 0;
1713 }
1714
1715 /* Make sure there are trailing slashes in dirs */
1716
1717 if (base_dir != NULL && base_dir[strlen (base_dir)-1] != '/')
1718 {
1719 p = malloc (strlen (base_dir) + 2);
1720 strcpy (p, base_dir);
1721 strcat (p, "/");
1722 free (base_dir);
1723 base_dir = p;
1724 }
1725
1726 if (dest_dir != NULL && dest_dir[strlen (dest_dir)-1] != '/')
1727 {
1728 p = malloc (strlen (dest_dir) + 2);
1729 strcpy (p, dest_dir);
1730 if (win_path)
1731 strcat (p, "\\");
1732 else
1733 strcat (p, "/");
1734 free (dest_dir);
1735 dest_dir = p;
1736 }
1737
1738 if (list_file != NULL)
1739 {
1740 list_file_fd = open (list_file, O_WRONLY|O_CREAT|O_APPEND, 0644);
1741 }
1742
1743 file = args[0];
1744
1745 if (elf_version(EV_CURRENT) == EV_NONE)
1746 {
1747 fprintf (stderr, "library out of date\n");
1748 exit (1);
1749 }
1750
1751 if (stat(file, &stat_buf) < 0)
1752 {
1753 fprintf (stderr, "Failed to open input file '%s': %s\n", file, strerror(errno));
1754 exit (1);
1755 }
1756
1757 /* Make sure we can read and write */
1758
1759 if (readonly == 0)
1760 chmod (file, stat_buf.st_mode | S_IRUSR | S_IWUSR);
1761
1762 fd = open (file, (readonly == 0) ? O_RDWR : O_RDONLY);
1763 if (fd < 0)
1764 {
1765 fprintf (stderr, "Failed to open input file '%s': %s\n", file, strerror(errno));
1766 exit (1);
1767 }
1768
1769 dso = fdopen_dso (fd, file, readonly);
1770 if (dso == NULL)
1771 exit (1);
1772
1773 for (i = 1; i < dso->ehdr.e_shnum; i++)
1774 {
1775 const char *name;
1776 name = strptr (dso, dso->ehdr.e_shstrndx, dso->shdr[i].sh_name);
1777
1778 fprintf (debug_fd, "sh:%d, sh_type: %d, sh_name: %s\n", i, dso->shdr[i].sh_type, name);
1779
1780 switch (dso->shdr[i].sh_type)
1781 {
1782 case SHT_PROGBITS:
1783
1784 /* TODO: Handle stabs */
1785 if (strcmp (name, ".stab") == 0)
1786 {
1787 fprintf (stderr, "Stabs debuginfo not supported: %s\n", file);
1788 break;
1789 }
1790
1791 if (strcmp (name, ".debug_info") == 0)
1792 edit_dwarf2 (dso);
1793
1794 break;
1795 default:
1796 break;
1797 }
1798 }
1799
1800 if (readonly == 0 && elf_update (dso->elf, ELF_C_WRITE) < 0)
1801 {
1802 fprintf (stderr, "Failed to write file: %s\n", elf_errmsg (elf_errno()));
1803 exit (1);
1804 }
1805
1806 if (elf_end (dso->elf) < 0)
1807 {
1808 fprintf (stderr, "elf_end failed: %s\n", elf_errmsg (elf_errno()));
1809 exit (1);
1810 }
1811
1812 close (fd);
1813
1814 /* Restore old access rights */
1815 if (readonly == 0)
1816 chmod (file, stat_buf.st_mode);
1817
1818 poptFreeContext (optCon);
1819
1820 return 0;
1821 }
1822