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