Stackdb
Stackdb is a stackable, multi-target and -level source debugger and memory forensics library.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
binfile_elf.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011, 2012, 2013, 2014 The University of Utah
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #include <stdlib.h>
20 #include <unistd.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <fcntl.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <stdint.h>
27 #include <inttypes.h>
28 #include <assert.h>
29 #include <regex.h>
30 #include <glib.h>
31 
32 #include "config.h"
33 #include "common.h"
34 #include "arch.h"
35 #include "log.h"
36 #include "output.h"
37 #include "list.h"
38 #include "glib_wrapper.h"
39 #include "clfit.h"
40 #include "alist.h"
41 #include "binfile.h"
42 #include "dwdebug.h"
43 #include "dwdebug_priv.h"
44 
45 #include <dwarf.h>
46 #include <gelf.h>
47 #include <elfutils/libebl.h>
48 #include <elfutils/libdw.h>
49 #include <elfutils/libdwfl.h>
50 
51 #include "memory-access.h"
52 
53 
54 static const char *elf_binfile_get_backend_name(void);
55 static struct binfile *elf_binfile_open(char *filename,char *root_prefix,
56  struct binfile_instance *bfinst);
57 static struct binfile *elf_binfile_open_debuginfo(struct binfile *binfile,
58  struct binfile_instance *bfinst,
59  const char *DFPATH[]);
60 static struct binfile_instance *elf_binfile_infer_instance(struct binfile *binfile,
61  ADDR base,
62  GHashTable *config);
63 static int elf_binfile_close(struct binfile *binfile);
64 static void elf_binfile_free(struct binfile *binfile);
65 static void elf_binfile_free_instance(struct binfile_instance *bfi);
66 
68  .get_backend_name = elf_binfile_get_backend_name,
69  .open = elf_binfile_open,
70  .open_debuginfo = elf_binfile_open_debuginfo,
71  .infer_instance = elf_binfile_infer_instance,
72  .close = elf_binfile_close,
73  .free = elf_binfile_free,
74  .free_instance = elf_binfile_free_instance,
75 };
76 
77 static struct arch *elf_get_arch(Elf *elf) {
78  char *eident;
79  GElf_Ehdr ehdr;
80  struct arch *arch;
81 
82  if (!gelf_getehdr(elf,&ehdr)) {
83  verror("cannot read ELF header: %s",elf_errmsg(-1));
84  return NULL;
85  }
86 
87  /* read the ident stuff to get machine, wordsize, and endianness info */
88  if (!(eident = elf_getident(elf,NULL))) {
89  verror("elf_getident: %s\n",elf_errmsg(elf_errno()));
90  return NULL;
91  }
92 
93  if ((uint8_t)eident[EI_DATA] == ELFDATA2LSB) {
94  vdebug(3,LA_DEBUG,LF_DFILE,"little endian\n");
95  }
96  else if ((uint8_t)eident[EI_DATA] == ELFDATA2MSB) {
97  verror("big endian ELF files unsupported; no arch for them\n");
98  return NULL;
99  }
100  else {
101  verror("unknown elf data %d; not big/little endian!\n",
102  (uint8_t)eident[EI_DATA]);
103  return NULL;
104  }
105 
106  if (ehdr.e_machine == EM_386)
107  arch = arch_get(ARCH_X86);
108  else if (ehdr.e_machine == EM_X86_64)
109  arch = arch_get(ARCH_X86_64);
110  else {
111  verror("unsupported elf machine type %d!\n",ehdr.e_machine);
112  return NULL;
113  }
114 
115  return arch;
116 }
117 
118 static const char *elf_binfile_get_backend_name(void) {
119  return "elf";
120 }
121 
122 static int elf_binfile_close(struct binfile *binfile) {
123  struct binfile_elf *bfelf = (struct binfile_elf *)binfile->priv;
124  int had_dwfl = 0;
125 
126  if (bfelf->ebl) {
127  ebl_closebackend(bfelf->ebl);
128  bfelf->ebl = NULL;
129  }
130  if (bfelf->dwfl) {
131  dwfl_end(bfelf->dwfl);
132  bfelf->dwfl = NULL;
133  had_dwfl = 1;
134  }
135  if (bfelf->elf) {
136  if (binfile->image && had_dwfl) {
137  /*
138  * NB: dwfl_end already called elf_end; don't! See
139  * dwarf_load_debuginfo().
140  */
141  bfelf->elf = NULL;
142  }
143  else if (bfelf->elf) {
144  elf_end(bfelf->elf);
145  bfelf->elf = NULL;
146  }
147  }
148  if (binfile->fd > -1) {
149  close(binfile->fd);
150  binfile->fd = -1;
151  }
152  if (binfile->image) {
153  free(binfile->image);
154  binfile->image = NULL;
155  }
156 
157  return 0;
158 }
159 
160 static void elf_binfile_free(struct binfile *binfile) {
161  struct binfile_elf *bfelf = (struct binfile_elf *)binfile->priv;
162  struct binfile_instance *bfi = (struct binfile_instance *)binfile->instance;
163  struct binfile_instance_elf *bfielf = NULL;
164 
165  elf_binfile_close(binfile);
166 
167  if (bfi) {
168  bfielf = (struct binfile_instance_elf *)bfi->priv;
169 
170  if (bfielf) {
171  if (bfielf->section_tab) {
172  free(bfielf->section_tab);
173  bfielf->section_tab = NULL;
174  }
175  if (bfielf->symbol_tab) {
176  free(bfielf->symbol_tab);
177  bfielf->symbol_tab = NULL;
178  }
179  free(bfielf);
180  bfi->priv = NULL;
181  }
182  }
183 
184  if (bfelf->shdrs) {
185  free(bfelf->shdrs);
186  bfelf->shdrs = NULL;
187  }
188  if (bfelf->phdrs) {
189  free(bfelf->phdrs);
190  bfelf->phdrs = NULL;
191  }
192  if (bfelf->buildid) {
193  free(bfelf->buildid);
194  bfelf->buildid = NULL;
195  }
196  if (bfelf->gnu_debuglinkfile) {
197  free(bfelf->gnu_debuglinkfile);
198  bfelf->gnu_debuglinkfile = NULL;
199  }
200 
201  free(binfile->priv);
202 }
203 
204 static void elf_binfile_free_instance(struct binfile_instance *bfi) {
205  struct binfile_instance_elf *bfielf = \
206  (struct binfile_instance_elf *)bfi->priv;
207 
208  if (bfielf) {
209  if (bfielf->shdrs) {
210  free(bfielf->shdrs);
211  bfielf->shdrs = NULL;
212  }
213  if (bfielf->section_tab) {
214  free(bfielf->section_tab);
215  bfielf->section_tab = NULL;
216  }
217  if (bfielf->symbol_tab) {
218  free(bfielf->symbol_tab);
219  bfielf->symbol_tab = NULL;
220  }
221  free(bfielf);
222  bfi->priv = NULL;
223  }
224 }
225 
226 struct binfile *elf_binfile_open_debuginfo(struct binfile *binfile,
227  struct binfile_instance *bfinst,
228  const char *DFPATH[]) {
229  struct binfile_elf *bfelf = (struct binfile_elf *)binfile->priv;
230  char pbuf[PATH_MAX];
231  struct stat stbuf;
232  char *finalfile = NULL;
233  int len;
234  int i;
235  char *filedir;
236  char *tmp;
237 
238  /*
239  * Read the debuginfo info from the given binary and figure out if
240  * we should load from this file, or load from a pointed-to
241  * debugfile.
242  */
243 
244  vdebug(5,LA_DEBUG,LF_DFILE,"ELF info for file %s:\n",binfile->filename);
245  vdebug(5,LA_DEBUG,LF_DFILE," has_debuginfo=%d,buildid='",
246  (int)binfile->has_debuginfo);
247  if (bfelf->buildid) {
248  len = (int)strlen(bfelf->buildid);
249  for (i = 0; i < len; ++i)
250  vdebugc(5,LA_DEBUG,LF_DFILE,"%hhx",bfelf->buildid[i]);
251  }
252  vdebugc(5,LA_DEBUG,LF_DFILE,"'\n");
253  vdebug(5,LA_DEBUG,LF_DFILE," debuglinkfile=%s,debuglinkfilecrc=0x%x\n",
255 
256  if (binfile->has_debuginfo)
257  return binfile;
258 
259  if (bfelf->buildid) {
260  for (i = 0; DFPATH[i]; ++i) {
261  if (binfile->root_prefix)
262  snprintf(pbuf,PATH_MAX,"%s/%s/.build-id/%02hhx/%s.debug",
263  binfile->root_prefix,DFPATH[i],*bfelf->buildid,
264  (char *)(bfelf->buildid+1));
265  else
266  snprintf(pbuf,PATH_MAX,"%s/.build-id/%02hhx/%s.debug",
267  DFPATH[i],*bfelf->buildid,(char *)(bfelf->buildid+1));
268  if (stat(pbuf,&stbuf) == 0) {
269  finalfile = pbuf;
270  break;
271  }
272  }
273  }
274 
275  if (!finalfile && bfelf->gnu_debuglinkfile) {
276  /* Find the containing dir path so we can use it in our search
277  * of the standard debug file dir infrastructure.
278  *
279  * NB: if the binfile is already a file inside root_prefix, to
280  * get the intermediate fildir, we have to strip off the
281  * root_prefix... then add it on again in the loop :-\.
282  */
283  if (binfile->root_prefix
284  && strstr(binfile->filename,binfile->root_prefix)
285  == binfile->filename) {
286  filedir = strdup(binfile->filename + strlen(binfile->root_prefix));
287  }
288  else {
289  filedir = strdup(binfile->filename);
290  }
291  tmp = rindex(filedir,'/');
292  if (tmp)
293  *tmp = '\0';
294  for (i = 0; DFPATH[i]; ++i) {
295  if (binfile->root_prefix)
296  snprintf(pbuf,PATH_MAX,"%s/%s/%s/%s",
297  binfile->root_prefix,DFPATH[i],filedir,
298  bfelf->gnu_debuglinkfile);
299  else
300  snprintf(pbuf,PATH_MAX,"%s/%s/%s",
301  DFPATH[i],filedir,bfelf->gnu_debuglinkfile);
302  if (stat(pbuf,&stbuf) == 0) {
303  finalfile = pbuf;
304  break;
305  }
306  }
307  free(filedir);
308  }
309 
310  if (!finalfile) {
312  "no debuginfo sources associated with %s\n",binfile->filename);
313  errno = ENODATA;
314  return NULL;
315  }
316 
317  /*
318  * Open the file!
319  */
320  return binfile_open__int(finalfile,binfile->root_prefix,bfinst);
321 }
322 
323 static struct binfile_instance *elf_binfile_infer_instance(struct binfile *binfile,
324  ADDR base,
325  GHashTable *config) {
326  struct binfile_elf *bfelf;
327  struct binfile_instance *bfi;
328  struct binfile_instance_elf *bfielf;
329  /*
330  * This is the order the kernel module order lays out sections; see
331  * kernel/module.c:layout_sections . We use their algorithm for
332  * layout too. So, first layout exec&alloc sections that are not
333  * arch-specific (not on the x86 at all); then alloc-only sections
334  * that are not writeable; then alloc&writeable sections that are
335  * not small; then small&alloc sections.
336  *
337  * Of course this layout is
338  */
339 #define ARCH_SHF_X86 0
340  static unsigned long const shfm[][2] = {
341  { SHF_EXECINSTR | SHF_ALLOC, ARCH_SHF_X86 },
342  { SHF_ALLOC, SHF_WRITE | ARCH_SHF_X86 },
343  { SHF_WRITE | SHF_ALLOC, ARCH_SHF_X86 },
344  { ARCH_SHF_X86 | SHF_ALLOC, 0 }
345  };
346  unsigned int fm;
347  unsigned int i;
348  ADDR size = 0;
349  ADDR align;
350  GElf_Shdr *shdr;
351  GElf_Sym sym_mem;
352  GElf_Sym *sym;
353  char *secname;
354  Elf_Scn *scn;
355  Elf_Data *edata;
356  uint8_t *done_sections;
357  char *config_str;
358  int kallsyms = 0;
359  int kallsyms_after_init = 0;
360  int set_module_ronx = 0;
361  int module_unload = 1;
362  int major = 0,minor = 0,patch = 0;
363  char *tmp;
364 
365  if (!(bfelf = (struct binfile_elf *)binfile->priv)) {
366  verror("no ELF info for source binfile %s!\n",binfile->filename);
367  errno = EINVAL;
368  return NULL;
369  }
370 
371  bfi = calloc(1,sizeof(*bfi));
372  bfielf = calloc(1,sizeof(*bfielf));
373 
374  bfi->filename = strdup(binfile->filename);
375  if (binfile->root_prefix)
376  bfi->root_prefix = strdup(binfile->root_prefix);
377  bfi->base = base;
378  bfi->ops = binfile->ops;
379  bfi->priv = bfielf;
380 
381  bfielf->num_sections = bfelf->ehdr.e_shnum;
382  bfielf->section_tab = calloc(bfielf->num_sections,sizeof(ADDR));
383 
384  done_sections = calloc(bfielf->num_sections,sizeof(uint8_t));
385 
386  /*
387  * Some special kernel hacks! Don't load modinfo, and load
388  * symtab/strtab if CONFIG_KALLSYMS was set. Need to tweak the
389  * shdrs to stop modinfo from being alloc'd, and to alloc
390  * symtab/strtab. Also, check to see if we need to align text,
391  * text+ro, text+ro+all onto page boundaries via
392  * CONFIG_DEBUG_SET_MODULE_RONX . Also, if this is a 2.6.32 or
393  * greater kernel, the symtab/strtab stuff gets mapped *after* the
394  * module's init section.
395  */
396  if (config) {
397  if ((tmp = (char *)g_hash_table_lookup(config,"__VERSION_MAJOR")))
398  major = atoi(tmp);
399  if ((tmp = (char *)g_hash_table_lookup(config,"__VERSION_MINOR")))
400  minor = atoi(tmp);
401  if ((tmp = (char *)g_hash_table_lookup(config,"__VERSION_PATCH")))
402  patch = atoi(tmp);
403 
404  config_str = g_hash_table_lookup(config,"CONFIG_KALLSYMS");
405  if (config_str && (*config_str == 'y' || *config_str == 'Y'))
406  kallsyms = 1;
407 
408  if (kallsyms
409  && (major > 2
410  || (major == 2 && minor == 6 && patch >= 32)))
411  kallsyms_after_init = 1;
412 
413  config_str =
414  g_hash_table_lookup(config,"CONFIG_DEBUG_SET_MODULE_RONX");
415  if (config_str
416  && (*config_str == 'y' || *config_str == 'Y'))
417  set_module_ronx = 1;
418 
419  config_str =
420  g_hash_table_lookup(config,"CONFIG_MODULE_UNLOAD");
421  if (config_str
422  && (*config_str == 'n' || *config_str == 'N'))
423  module_unload = 0;
424  }
425 
426  /*
427  * This is very bad of us -- because we edit the cached section
428  * headers in memory, and the underlying ELF descriptor does not
429  * know.
430  *
431  * So, we save a copy in the instance, and edit that copy. Anything
432  * that uses our instance needs to know this. We only use this for
433  * relocatable ELF files that we relocate (and load into memory to
434  * do the relocations on -- so we modify the relocated, in-memory
435  * ELF descriptor in that case. See elf_binfile_open...
436  *
437  * But, for this function, note that we use the edited shdrs!!
438  */
439  bfielf->shdrs = calloc(bfelf->ehdr.e_shnum,sizeof(*bfelf->shdrs));
440  memcpy(bfielf->shdrs,bfelf->shdrs,bfelf->ehdr.e_shnum*sizeof(*bfelf->shdrs));
441 
442 #define __ALIGN(x,a) (((x) + (typeof(x))(a) - 1) & ~((typeof(x))(a) - 1))
443 #define __PAGE_SIZE 0x1000
444 #define __DEBUG_ALIGN (x) __ALIGN((x),__PAGE_SIZE)
445 
446  for (i = 0; i < bfelf->ehdr.e_shnum; ++i) {
447  shdr = &bfielf->shdrs[i];
448  secname = elf_strptr(bfelf->elf,bfelf->shstrndx,shdr->sh_name);
449 
450  if (kallsyms && !kallsyms_after_init
451  && (strcmp(secname,".symtab") == 0
452  || strcmp(secname,".strtab") == 0))
453  bfielf->shdrs[i].sh_flags |= SHF_ALLOC;
454 
455  /*
456  * Per-CPU data is special.
457  */
458  if (strcmp(secname,".data..percpu") == 0)
459  bfielf->shdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
460 
461  /*
462  * Don't load version info, nor modinfo
463  */
464  if (strcmp(secname,"__versions") == 0)
465  bfielf->shdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
466  if (strcmp(secname,".modinfo") == 0)
467  bfielf->shdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
468 
469  /*
470  * Don't load exit sections if CONFIG_MODULE_UNLOAD is n.
471  */
472  if (!module_unload && strncmp(secname,".exit",5) == 0)
473  bfielf->shdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
474  }
475 
476  /*
477  * For now, the default layout is the kernel's layout :). Those are
478  * the only relocatable files we have to handle initially.
479  */
480  for (fm = 0; fm < sizeof(shfm)/(2*sizeof(unsigned long)); ++fm) {
481  for (i = 0; i < bfelf->ehdr.e_shnum; ++i) {
482  shdr = &bfielf->shdrs[i];
483  secname = elf_strptr(bfelf->elf,bfelf->shstrndx,shdr->sh_name);
484 
485  if ((shdr->sh_flags & shfm[fm][0]) != shfm[fm][0]
486  || (shdr->sh_flags & shfm[fm][1])
487  || done_sections[i] != 0
488  || !secname
489  || strncmp(secname,".init",5) == 0)
490  continue;
491 
492  align = shdr->sh_addralign ? shdr->sh_addralign : 1;
493  bfielf->section_tab[i] = __ALIGN(size,align);
494  size = bfielf->section_tab[i] + shdr->sh_size;
495  bfielf->section_tab[i] += base;
496 
498  "section %d (%s) placed at 0x%"PRIxADDR" (0x%"PRIxADDR"+%ld)\n",
499  i,secname,bfielf->section_tab[i],base,
500  bfielf->section_tab[i] - base);
501 
502  done_sections[i] = 1;
503 
504  if (bfi->start < bfi->base)
505  bfi->start = bfielf->section_tab[i];
506  else if (bfielf->section_tab[i] < bfi->start)
507  bfi->start = bfielf->section_tab[i];
508 
509  if (bfielf->section_tab[i] > bfi->end)
510  bfi->end = bfielf->section_tab[i];
511  }
512  if (set_module_ronx) {
513  if (fm == 0 || fm == 1 || fm == 2)
514  size = __ALIGN(size,__PAGE_SIZE);
515  }
516  }
517 
518  for (fm = 0; fm < sizeof(shfm)/(2*sizeof(unsigned long)); ++fm) {
519  for (i = 0; i < bfelf->ehdr.e_shnum; ++i) {
520  shdr = &bfielf->shdrs[i];
521  secname = elf_strptr(bfelf->elf,bfelf->shstrndx,shdr->sh_name);
522 
523  if ((shdr->sh_flags & shfm[fm][0]) != shfm[fm][0]
524  || shdr->sh_flags & shfm[fm][1]
525  || done_sections[i] != 0
526  || !secname || strncmp(secname,".init",5) != 0)
527  continue;
528 
529  align = shdr->sh_addralign ? shdr->sh_addralign : 1;
530  bfielf->section_tab[i] = __ALIGN(size,align);
531  size = bfielf->section_tab[i] + shdr->sh_size;
532  bfielf->section_tab[i] += base;
533 
535  "section %d (%s) placed at 0x%"PRIxADDR" (0x%"PRIxADDR"+%ld)\n",
536  i,secname,bfielf->section_tab[i],base,
537  bfielf->section_tab[i] - base);
538 
539  done_sections[i] = 1;
540 
541  if (bfi->start < bfi->base)
542  bfi->start = bfielf->section_tab[i];
543  else if (bfielf->section_tab[i] < bfi->start)
544  bfi->start = bfielf->section_tab[i];
545 
546  if (bfielf->section_tab[i] > bfi->end)
547  bfi->end = bfielf->section_tab[i];
548  }
549  if (set_module_ronx) {
550  if (fm == 0 || fm == 1 || fm == 2)
551  size = __ALIGN(size,__PAGE_SIZE);
552  }
553  }
554 
555  /*
556  * Now, if we have to put symtab/strtab after module's init stuff,
557  * do that.
558  */
559  if (kallsyms && kallsyms_after_init) {
560  for (i = 0; i < bfelf->ehdr.e_shnum; ++i) {
561  shdr = &bfielf->shdrs[i];
562  secname = elf_strptr(bfelf->elf,bfelf->shstrndx,shdr->sh_name);
563 
564  if (strcmp(secname,".symtab") == 0
565  || strcmp(secname,".strtab") == 0)
566  bfielf->shdrs[i].sh_flags |= SHF_ALLOC;
567  }
568 
569  for (fm = 0; fm < sizeof(shfm)/(2*sizeof(unsigned long)); ++fm) {
570  for (i = 0; i < bfelf->ehdr.e_shnum; ++i) {
571  shdr = &bfielf->shdrs[i];
572  secname = elf_strptr(bfelf->elf,bfelf->shstrndx,shdr->sh_name);
573 
574  if ((shdr->sh_flags & shfm[fm][0]) != shfm[fm][0]
575  || (shdr->sh_flags & shfm[fm][1])
576  || done_sections[i] != 0
577  || !secname
578  || strncmp(secname,".init",5) == 0)
579  continue;
580 
581  align = shdr->sh_addralign ? shdr->sh_addralign : 1;
582  bfielf->section_tab[i] = __ALIGN(size,align);
583  size = bfielf->section_tab[i] + shdr->sh_size;
584  bfielf->section_tab[i] += base;
585 
587  "section %d (%s) placed at 0x%"PRIxADDR" (0x%"PRIxADDR"+%ld)\n",
588  i,secname,bfielf->section_tab[i],base,
589  bfielf->section_tab[i] - base);
590 
591  done_sections[i] = 1;
592 
593  if (bfi->start < bfi->base)
594  bfi->start = bfielf->section_tab[i];
595  else if (bfielf->section_tab[i] < bfi->start)
596  bfi->start = bfielf->section_tab[i];
597 
598  if (bfielf->section_tab[i] > bfi->end)
599  bfi->end = bfielf->section_tab[i];
600  }
601  if (set_module_ronx) {
602  if (fm == 0 || fm == 1 || fm == 2)
603  size = __ALIGN(size,__PAGE_SIZE);
604  }
605  }
606  }
607 
608  free(done_sections);
609 
610  /*
611  * Take a spin over the symtab, and fill in our local entries. We
612  * could also wait until the binfile is opened against the instance,
613  * but I suppose the user might not do that. So do it here... sigh.
614  */
615  for (i = 0; i < bfelf->ehdr.e_shnum; ++i) {
616  shdr = &bfielf->shdrs[i];
617 
618  if (!shdr || shdr->sh_size <= 0 || shdr->sh_type != SHT_SYMTAB)
619  continue;
620 
621  secname = elf_strptr(bfelf->elf,bfelf->shstrndx,shdr->sh_name);
622 
623  if (strcmp(secname,".symtab") != 0)
624  continue;
625 
626  vdebug(2,LA_DEBUG,LF_ELF,"found .symtab section in ELF file %s\n",
627  binfile->filename);
628 
629  scn = elf_getscn(bfelf->elf,i);
630  edata = elf_getdata(scn,NULL);
631  if (!edata || !edata->d_size || !edata->d_buf) {
632  verror("cannot get data for valid section %s in %s: %s (skipping)\n",
633  secname,binfile->filename,elf_errmsg(-1));
634  goto errout;
635  }
636 
637  bfielf->num_symbols = \
638  edata->d_size / (bfelf->class == ELFCLASS32 ? sizeof (Elf32_Sym) \
639  : sizeof (Elf64_Sym));
640  bfielf->symbol_tab = \
641  calloc(bfielf->num_symbols,sizeof(*bfielf->symbol_tab));
642 
644  ".symtab section in ELF file %s has %d symbols\n",
645  binfile->filename,bfielf->num_symbols);
646 
647  /* Load the symtab */
648  for (i = 0; i < bfielf->num_symbols; ++i) {
649  sym = gelf_getsym(edata,i,&sym_mem);
650 
651  if (GELF_ST_TYPE(sym->st_info) == STT_SECTION) {
652  bfielf->symbol_tab[i] = bfielf->section_tab[sym->st_shndx];
653  }
654  else if ((GELF_ST_TYPE(sym->st_info) == STT_OBJECT
655  || GELF_ST_TYPE(sym->st_info) == STT_FUNC)
656  && sym->st_shndx != SHN_UNDEF
657  && sym->st_shndx != SHN_ABS
658  && sym->st_shndx != SHN_COMMON) {
659  bfielf->symbol_tab[i] = bfielf->section_tab[sym->st_shndx]
660  + sym->st_value;
661  }
662  else {
663  continue;
664  }
665  }
666  }
667 
668  errout:
669 
670  return bfi;
671 }
672 
673 static struct binfile *elf_binfile_open(char *filename,char *root_prefix,
674  struct binfile_instance *bfinst) {
675  struct binfile *bf = NULL;
676  struct binfile_elf *bfelf = NULL;
677  Elf_Scn *scn = NULL;
678  GElf_Phdr *phdr;
679  GElf_Shdr *shdr;
680  char *name;
681  Elf_Data *edata;
682  struct array_list *ral;
683  struct array_list *tmp_ral;
684  struct clf_range_data *tmp_crd;
685  struct symbol *tmp_symbol;
686  struct clf_range_data *gcrd;
687  GElf_Sym sym_mem;
688  GElf_Sym *sym;
689  char *symname;
690  unsigned char stt;
691  struct symbol *symbol;
692  unsigned int i, ii;
693  int j,k;
694  Word_t tmpstart = -1;
695  Word_t start = -1;
696  Elf32_Nhdr *nthdr32;
697  Elf64_Nhdr *nthdr64;
698  char *ndata,*nend;
699  struct stat stbuf;
700  int rci, rc;
701  int fdi;
702  GElf_Rel rel;
703  int nrels;
704  Elf_Scn *rstscn;
705  Elf_Data *rstedata;
706  int rsec;
707  int rstsec;
708  GElf_Sym rsym;
709  int rsymidx;
710  int rtype;
711  int rcoffset;
712  GElf_Addr rvalue;
713  struct binfile_instance_elf *bfelfinst = NULL;
714  GElf_Shdr *shdr_new;
715  GElf_Shdr shdr_new_mem;
716  int sec_found;
717  Word_t sec_end;
718  int has_plt = 0;
719  Word_t plt_start = 0;
720  Word_t plt_size = 0;
721  int plt_idx;
722  int plt_entry_size = 0;
723  int len;
724  char *pltsymbuf = NULL;
725  int pltsymbuf_len;
726  GElf_Rela rela;
727  int rstrsec;
728  int dynsymtabsec = -1;
729  int symtabsec = -1;
730  int dynstrtabsec = -1;
731  struct symbol *tsymbol;
732  struct scope *root_scope;
733  GSList *zll = NULL;
734  GSList *t1;
735 
736  /*
737  * Set up our data structures.
738  */
739  bfelf = (struct binfile_elf *)calloc(1,sizeof(*bfelf));
740  if (!bfelf)
741  goto errout;
742  bfelf->dwfl_fd = -1;
743 
744  bf = binfile_create(filename,&elf_binfile_ops,bfelf);
745  if (!bf)
746  goto errout;
747 
748  root_scope = symbol_write_owned_scope(bf->root);
749 
750  if (root_prefix) {
751  bf->root_prefix = strdup(root_prefix);
752  if (strstr(filename,root_prefix) != filename) {
753  vwarn("BUG: filename '%s' does not start with root_prefix '%s'!\n",
754  filename,root_prefix);
755  }
756  }
757 
758  if (bfinst)
759  bfelfinst = (struct binfile_instance_elf *)bfinst->priv;
760 
761  elf_version(EV_CURRENT);
762 
763  /*
764  * First, just open the file and do some sanity checks. If this
765  * doesn't seem like an ELF file, throw an optional warning and
766  * return. If it is an ELF file and we can't read it, or we can't
767  * handle the type, throw an error and return.
768  */
769  if ((bf->fd = open(bf->filename,0,O_RDONLY)) < 0) {
770  vwarnopt(1,LA_DEBUG,LF_ELF,"open %s: %s\n",bf->filename,strerror(errno));
771  goto errout;
772  }
773  else if (!(bfelf->elf = elf_begin(bf->fd,ELF_C_READ,NULL))) {
774  vwarnopt(1,LA_DEBUG,LF_ELF,"elf_begin %s: %s\n",
775  bf->filename,elf_errmsg(elf_errno()));
776  goto errout;
777  }
778  else if (!gelf_getehdr(bfelf->elf,&bfelf->ehdr)) {
779  verror("cannot read ELF header: %s",elf_errmsg(-1));
780  errno = EINVAL;
781  goto errout;
782  }
783  else if (bfelf->ehdr.e_type != ET_EXEC && bfelf->ehdr.e_type != ET_REL
784  && bfelf->ehdr.e_type != ET_DYN) {
785  verror("unreadable ELF type 0x%x\n",bfelf->ehdr.e_type);
786  errno = EINVAL;
787  goto errout;
788  }
789 
790  if (!(bf->arch = elf_get_arch(bfelf->elf))) {
791  verror("could not get arch for %s!\n",bf->filename);
792  goto errout;
793  }
794 
795  if (bfelf->ehdr.e_type == ET_EXEC)
796  bf->type = BINFILE_TYPE_EXEC;
797  else if (bfelf->ehdr.e_type == ET_DYN)
798  bf->type = BINFILE_TYPE_DYN;
799  else if (bfelf->ehdr.e_type == ET_REL)
800  bf->type = BINFILE_TYPE_REL;
801 
802  /*
803  * Load all the ELF metadata we are going to save.
804  */
805  bfelf->ebl = ebl_openbackend(bfelf->elf);
806  if (bfelf->ebl == NULL) {
807  verror("cannot create EBL handle: %s",strerror(errno));
808  goto errout;
809  }
810 
811  bfelf->class = gelf_getclass(bfelf->elf);
812 
813 #if _INT_ELFUTILS_VERSION >= 152
814  if (elf_getshdrstrndx(bfelf->elf,&bfelf->shstrndx) < 0) {
815 #else
816  if (elf_getshstrndx(bfelf->elf,&bfelf->shstrndx) < 0) {
817 #endif
818  verror("cannot get section header string table index\n");
819  goto errout;
820  }
821 
822  /*
823  * Before we use elfutils calls that save pointers into the file or
824  * data gleaned from it, we need to perform relocations if we have @bfinst.
825  */
826  if (bfelf->ehdr.e_type == ET_REL && bfinst) {
827  /* Save the instance! */
828  bf->instance = bfinst;
829  RHOLD(bfinst,bf);
830 
831  /*
832  * Leave the ELF fd intact, and buffer the file into a memory
833  * buffer for relocation.
834  */
835  if (stat(bf->filename,&stbuf)) {
836  verror("stat %s (before relocation): %s\n",
837  bf->filename,strerror(errno));
838  goto errout;
839  }
840  rci = 0;
841  bf->image = malloc(stbuf.st_size);
842  fdi = dup(bf->fd);
843  lseek(fdi,0,SEEK_SET);
844  while (rci < stbuf.st_size) {
845  rc = read(fdi,bf->image+rci,stbuf.st_size - rci);
846  if (rc < 0) {
847  if (errno == EAGAIN || errno == EINTR)
848  continue;
849  else {
850  verror("read(%s): %s\n",bf->filename,strerror(errno));
851  goto errout;
852  }
853  }
854  rci += rc;
855  }
856  close(fdi);
857 
858  /*
859  * Now, while we still have the old ELF descriptor open, go
860  * through all the sections and apply relocations *in the memory
861  * image* we just read.
862  */
864  "relocating ELF file %s in memory...\n",bf->filename);
865 
866  /*
867  * Now load all the section headers and build up a tmp array.
868  */
869  bfelf->shdrs = (GElf_Shdr *)calloc(bfelf->ehdr.e_shnum,sizeof(GElf_Shdr));
870  if (bfelfinst->shdrs) {
871  memcpy(bfelf->shdrs,bfelfinst->shdrs,
872  bfelf->ehdr.e_shnum*sizeof(GElf_Shdr));
873  }
874  else {
875  for (i = 0; i < bfelf->ehdr.e_shnum; ++i) {
876  scn = elf_getscn(bfelf->elf,i);
877  if (!gelf_getshdr(scn,&bfelf->shdrs[i])) {
878  verror("could not load section header for section %d!\n",i);
879  goto errout;
880  }
881  }
882  }
883 
884  for (i = 0; i < bfelf->ehdr.e_shnum; ++i) {
885  shdr = &bfelf->shdrs[i];
886  scn = elf_getscn(bfelf->elf,i);
887  if (!scn) {
888  verror("could not find Elf section for section %d!\n",i);
889  continue;
890  }
891  else if (!shdr || shdr->sh_size <= 0)
892  continue;
893  else if (shdr->sh_type != SHT_REL)
894  continue;
895 
896  edata = elf_getdata(scn,NULL);
897  if (!edata || !edata->d_size || !edata->d_buf) {
898  verror("cannot get data for relocation section %d during"
899  " relocation!\n",
900  i);
901  continue;
902  }
903 
904  /*
905  * Do the relocs.
906  */
907  nrels = shdr->sh_size / shdr->sh_entsize;
908 
909  rsec = shdr->sh_info;
910  rstsec = shdr->sh_link;
911 
912  /*
913  * Grab the symtab section referred to so we can load the syms.
914  */
915  rstscn = elf_getscn(bfelf->elf,rstsec);
916  if (!rstscn) {
917  verror("could not load symtab section %d during relocation!\n",
918  rstsec);
919  continue;
920  }
921  rstedata = elf_getdata(rstscn,NULL);
922  if (!rstedata || !rstedata->d_size || !rstedata->d_buf) {
923  verror("cannot get data for valid symtab section %d during"
924  " relocation!\n",
925  rstsec);
926  continue;
927  }
928 
930  "found %d relocations in %d in ELF file %s\n",
931  nrels,i,bf->filename);
932 
933  /*
934  * Don't realloc sections that are not getting loaded; we
935  * are not a linker that needs to recombine sections.
936  */
937  if (!(bfelf->shdrs[rsec].sh_flags & SHF_ALLOC)) {
939  "skipping reloc section %d for non-alloc section %d\n",
940  i,rsec);
941  continue;
942  }
943 
944  for (j = 0; j < nrels; ++j) {
945  if (!gelf_getrel(edata,j,&rel)) {
946  verror("bad relocation %d in %d; skipping!\n",j,i);
947  continue;
948  }
949  rtype = GELF_R_TYPE(rel.r_info);
950  rsymidx = GELF_R_SYM(rel.r_info);
951  if (!gelf_getsym(rstedata,rsymidx,&rsym)) {
952  verror("could not load sym %d in %d (for %d/%d) during"
953  " relocation; skipping!\n",
954  rsymidx,rstsec,j,i);
955  continue;
956  }
957 
958  if (rsym.st_shndx >= bfelfinst->num_sections) {
959  verror("bad section %d for symbol %d (relocation %d/%d)!\n",
960  rsym.st_shndx,rsymidx,j,i);
961  continue;
962  }
963 
964  /*
965  * The bit of mem we're going to modify is the offset in
966  * the ELF file of the section we're relocating, plus
967  * the r_offset in the relocation.
968  */
969  rcoffset = bfelf->shdrs[rsec].sh_offset + rel.r_offset;
970 
971  if (GELF_ST_TYPE(rsym.st_info) == STT_SECTION) {
972  /*
973  * Don't realloc sections that are not getting
974  * loaded; we are not a linker that needs to
975  * recombine sections.
976  */
977  if (!(bfelf->shdrs[rsym.st_shndx].sh_flags & SHF_ALLOC)) {
979  "skipping reloc for non-alloc section %d\n",
980  rsym.st_shndx);
981  continue;
982  }
983 
984  rvalue = (GElf_Addr)bfelfinst->section_tab[rsym.st_shndx];
985  }
986  else if (GELF_ST_TYPE(rsym.st_info) == STT_OBJECT
987  || GELF_ST_TYPE(rsym.st_info) == STT_FUNC) {
988  rvalue = rsym.st_value \
989  + (GElf_Addr)bfelfinst->section_tab[rsym.st_shndx];
990  }
991  else if (GELF_ST_TYPE(rsym.st_info) == STT_NOTYPE
992  && GELF_ST_BIND(rsym.st_info) == STB_GLOBAL) {
994  "skipping global symbol %d"
995  " (relocation %d/%d); skipping!\n",
996  rsymidx,j,i);
997  }
998  else {
999  verror("unknown symbol type %d for symbol %d"
1000  " (relocation %d/%d); skipping!\n",
1001  GELF_ST_TYPE(rsym.st_info),rsymidx,j,i);
1002  continue;
1003  }
1004 
1005  switch (rtype) {
1006  case R_386_32:
1007  /* Sv + Ad */
1008  if (rcoffset >= stbuf.st_size) {
1010  "relocation offset exceeds file length by %d"
1011  " (symbol %d, relocation %d/%d); skipping\n!",
1012  rcoffset - stbuf.st_size,
1013  rsymidx,j,i);
1014  continue;
1015  }
1016  memcpy(bf->image+rcoffset,&rvalue,bf->arch->wordsize);
1017  break;
1018  case R_386_PC32:
1019  /* Sv + Ad - P (r_offset?) */
1020  rvalue -= rel.r_offset;
1021  if (rcoffset >= stbuf.st_size) {
1023  "relocation offset exceeds file length by %d"
1024  " (symbol %d, relocation %d/%d); skipping\n!",
1025  rcoffset - stbuf.st_size,
1026  rsymidx,j,i);
1027  continue;
1028  }
1029  memcpy(bf->image+rcoffset,&rvalue,bf->arch->wordsize);
1030  break;
1031  default:
1032  verror("cannot handle relocation type %d for symbol %d"
1033  " (relocation %d/%d); skipping\n!",
1034  rtype,rsymidx,j,i);
1035  break;
1036  }
1037  }
1038  }
1039 
1040  free(bfelf->shdrs);
1041 
1042  /*
1043  * Now, close off the old ELF and its fd, and open the new ELF
1044  * against the memory image.
1045  */
1046  elf_end(bfelf->elf);
1047  close(bf->fd);
1048  bf->fd = -1;
1049  bfelf->elf = elf_memory(bf->image,stbuf.st_size);
1050 
1051  /*
1052  * Also, update sh_flags from the instance's headers if they
1053  * exist.
1054  */
1055  if (bfelfinst->shdrs) {
1056  for (i = 0; i < bfelf->ehdr.e_shnum; ++i) {
1057  scn = elf_getscn(bfelf->elf,i);
1058  if (!(shdr_new = gelf_getshdr(scn,&shdr_new_mem))) {
1059  verror("could not load section header for section %d!\n",i);
1060  goto errout;
1061  }
1062 
1063  if (shdr_new->sh_flags != bfelfinst->shdrs[i].sh_flags) {
1064  shdr_new->sh_flags = bfelfinst->shdrs[i].sh_flags;
1065 
1066  if (gelf_update_shdr(scn,shdr_new)) {
1068  "could not update sh_flags for section %d;"
1069  " skipping; debuginfo reloc might be broken!\n",
1070  i);
1071  continue;
1072  }
1073  }
1074  }
1075  }
1076 
1078  "opened relocated ELF file %s in memory\n",bf->filename);
1079  }
1080  else if (bfelf->ehdr.e_type == ET_REL) {
1082  "relocatable file %s, but no program image; not relocating!\n",
1083  bf->filename);
1084  }
1085 
1086  /*
1087  * Save off the program headers, and calculate the base addrs.
1088  *
1089  * Search through all the program headers; for those of type LOAD,
1090  * find the minimum phys addr (and its corresponding virt addr);
1091  * take these addrs to be used in calculating the phys_offset later
1092  * for use in virt<->phys addr translation from debuginfo virt addrs
1093  * to phys machine addrs.
1094  */
1095  if (bfelf->ehdr.e_phnum > 0) {
1096  bfelf->phdrs = (GElf_Phdr *)calloc(bfelf->ehdr.e_phnum,sizeof(GElf_Phdr));
1097  bf->base_phys_addr = ADDRMAX;
1098  bf->base_virt_addr = ADDRMAX;
1099 
1100  for (i = 0; i < bfelf->ehdr.e_phnum; ++i) {
1101  if (!(phdr = gelf_getphdr(bfelf->elf,i,&bfelf->phdrs[i]))) {
1102  vwarn("could not read program header %d\n",(int)i);
1103  continue;
1104  }
1105 
1106  if (phdr->p_type != PT_LOAD)
1107  continue;
1108 
1109  if (phdr->p_vaddr < bf->base_virt_addr) {
1110  bf->base_phys_addr = phdr->p_paddr;
1111  bf->base_virt_addr = phdr->p_vaddr;
1112  }
1113  }
1114 
1115  /*
1116  * If we didn't find anything (weird), make sure to use 0 as our
1117  * base; it's the best we can do, realistically.
1118  */
1119  if (bf->base_phys_addr == ADDRMAX && bf->base_virt_addr == ADDRMAX)
1120  bf->base_phys_addr = bf->base_virt_addr = 0;
1121  }
1122 
1123  /*
1124  * Now load all the section headers and build up a simple array.
1125  */
1126  bfelf->shdrs = (GElf_Shdr *)calloc(bfelf->ehdr.e_shnum,sizeof(GElf_Shdr));
1127  for (i = 0; i < bfelf->ehdr.e_shnum; ++i) {
1128  scn = elf_getscn(bfelf->elf,i);
1129  if (!gelf_getshdr(scn,&bfelf->shdrs[i])) {
1130  verror("could not load section header for section %d!\n",i);
1131  goto errout;
1132  }
1133  }
1134 
1135  /* Scan for various sections. */
1136  for (i = 0; i < bfelf->ehdr.e_shnum; ++i) {
1137  shdr = &bfelf->shdrs[i];
1138  scn = elf_getscn(bfelf->elf,i);
1139 
1140  if (!shdr || shdr->sh_size <= 0)
1141  continue;
1142  if (!scn) {
1143  verror("could not find Elf section for section %d!\n",i);
1144  continue;
1145  }
1146 
1147  name = elf_strptr(bfelf->elf,bfelf->shstrndx,shdr->sh_name);
1148 
1149  if (shdr->sh_type == SHT_STRTAB && strcmp(name,".strtab") == 0) {
1150  if (bf->strtab) {
1151  vwarn("multiple .strtab sections; ignoring after first!\n");
1152  continue;
1153  }
1154 
1156  "found .strtab section in ELF file %s\n",
1157  bf->filename);
1158 
1159  edata = elf_rawdata(scn,NULL);
1160  if (!edata || !edata->d_size || !edata->d_buf) {
1161  verror("cannot get data for valid section %s in %s: %s",
1162  name,bf->filename,elf_errmsg(-1));
1163  goto errout;
1164  }
1165 
1166  //strtabsec = i;
1167  bf->strtablen = edata->d_size;
1168  bf->strtab = malloc(edata->d_size);
1169  memcpy(bf->strtab,edata->d_buf,edata->d_size);
1170  }
1171  else if (shdr->sh_type == SHT_SYMTAB) {
1172  if (symtabsec > -1) {
1173  vwarn("multiple .dynsym sections; ignoring after first!\n");
1174  continue;
1175  }
1176 
1178  "found %s section in ELF file %s\n",name,bf->filename);
1179 
1180  symtabsec = i;
1181  }
1182  else if (shdr->sh_type == SHT_DYNSYM) {
1183  if (dynsymtabsec > -1) {
1184  vwarn("multiple .dynsym sections; ignoring after first!\n");
1185  continue;
1186  }
1187 
1189  "found %s section in ELF file %s\n",name,bf->filename);
1190 
1191  dynsymtabsec = i;
1192 
1193  /*
1194  * Find the strtab for it.
1195  */
1196  dynstrtabsec = shdr->sh_link;
1197  if (dynstrtabsec >= bfelf->ehdr.e_shnum || dynstrtabsec < 1) {
1198  verror("bad sh_link (dynstr sec idx) %d; not using dynsym sec %d!\n",
1199  dynstrtabsec,dynsymtabsec);
1200  dynsymtabsec = -1;
1201  dynstrtabsec = -1;
1202  }
1203 
1204  scn = elf_getscn(bfelf->elf,dynstrtabsec);
1205  if (!scn) {
1206  verror("could not find Elf section for section %d!\n",i);
1207  dynsymtabsec = -1;
1208  dynstrtabsec = -1;
1209  continue;
1210  }
1211  edata = elf_rawdata(scn,NULL);
1212  if (!edata || !edata->d_size || !edata->d_buf) {
1213  verror("cannot get data for valid section %s in %s: %s",
1214  name,bf->filename,elf_errmsg(-1));
1215  goto errout;
1216  }
1217 
1218  bf->dynstrtablen = edata->d_size;
1219  bf->dynstrtab = malloc(edata->d_size);
1220  memcpy(bf->dynstrtab,edata->d_buf,edata->d_size);
1221  }
1222  else if (strcmp(name,".plt") == 0) {
1224  "found %s section (%d); recording\n",
1225  name,shdr->sh_size);
1226  has_plt = 1;
1227  /* Important if we process .rela.plt */
1228  plt_entry_size = shdr->sh_entsize;
1229  plt_start = shdr->sh_addr;
1230  plt_size = shdr->sh_size;
1231  }
1232  else if (strcmp(name,".dynamic") == 0) {
1234  "found %s section (%d); ELF file is dynamic\n",
1235  name,shdr->sh_size);
1236  bf->is_dynamic = 1;
1237  }
1238  else if (strcmp(name,".debug_info") == 0) {
1240  "found %s section (%d)\n",name,shdr->sh_size);
1241  bf->has_debuginfo = 1;
1243  }
1244  else if (!bfelf->buildid && shdr->sh_type == SHT_NOTE) {
1246  "found %s note section (%d)\n",name,shdr->sh_size);
1247  edata = elf_rawdata(scn,NULL);
1248  if (!edata) {
1249  vwarn("cannot get data for valid section '%s': %s",
1250  name,elf_errmsg(-1));
1251  continue;
1252  }
1253 
1254  ndata = edata->d_buf;
1255  nend = ndata + edata->d_size;
1256  while (ndata < nend) {
1257  if (bf->arch->wordsize == 8) {
1258  nthdr64 = (Elf64_Nhdr *)ndata;
1259  /* skip past the header and the name string and its
1260  * padding */
1261  ndata += sizeof(Elf64_Nhdr);
1262  vdebug(5,LA_DEBUG,LF_DFILE,"found note name '%s'\n",ndata);
1263  ndata += nthdr64->n_namesz;
1264  if (nthdr64->n_namesz % 4)
1265  ndata += (4 - nthdr64->n_namesz % 4);
1266  vdebug(5,LA_DEBUG,LF_DFILE,"found note desc '%s'\n",ndata);
1267  /* dig out the build ID */
1268  if (nthdr64->n_type == NT_GNU_BUILD_ID) {
1269  bfelf->buildid = strndup(ndata,nend - ndata);
1270  break;
1271  }
1272  /* skip past the descriptor and padding */
1273  ndata += nthdr64->n_descsz;
1274  if (nthdr64->n_descsz % 4)
1275  ndata += (4 - nthdr64->n_descsz % 4);
1276  }
1277  else {
1278  nthdr32 = (Elf32_Nhdr *)ndata;
1279  /* skip past the header and the name string and its
1280  * padding */
1281  ndata += sizeof(Elf32_Nhdr);
1282  ndata += nthdr32->n_namesz;
1283  if (nthdr32->n_namesz % 4)
1284  ndata += (4 - nthdr32->n_namesz % 4);
1285  /* dig out the build ID */
1286  if (nthdr32->n_type == NT_GNU_BUILD_ID) {
1287  bfelf->buildid = strndup(ndata,nend - ndata);
1288  break;
1289  }
1290  /* skip past the descriptor and padding */
1291  ndata += nthdr32->n_descsz;
1292  if (nthdr32->n_descsz % 4)
1293  ndata += (4 - nthdr32->n_descsz % 4);
1294  }
1295  }
1296  }
1297  else if (strcmp(name,".gnu_debuglink") == 0) {
1298  edata = elf_rawdata(scn,NULL);
1299  if (!edata) {
1300  vwarn("cannot get data for valid section '%s': %s",
1301  name,elf_errmsg(-1));
1302  continue;
1303  }
1304  bfelf->gnu_debuglinkfile = strdup(edata->d_buf);
1305  bfelf->gnu_debuglinkfile_crc = \
1306  *(uint32_t *)(edata->d_buf + edata->d_size - 4);
1307  }
1308  }
1309  if (!bf->is_dynamic)
1310  vdebug(2,LA_DEBUG,LF_ELF,"ELF file is static\n");
1311 
1312  /*
1313  * Infer symbol names in the PLT if there was one by processing the
1314  * relocations for the PLT; those have the symbol names; we generate
1315  * a symbol for each JMP_SLOT relocation, assuming that the GOT and
1316  * PLT are strictly ordered w.r.t. one another, and assuming that a
1317  * PLT has a single "header" entry at its top.
1318  */
1319  pltsymbuf = malloc(128);
1320  pltsymbuf_len = 128;
1321  for (i = 0; i < bfelf->ehdr.e_shnum; ++i) {
1322  shdr = &bfelf->shdrs[i];
1323  scn = elf_getscn(bfelf->elf,i);
1324 
1325  if (!shdr || shdr->sh_size <= 0)
1326  continue;
1327  if (!scn) {
1328  verror("could not find Elf section for section %d!\n",i);
1329  continue;
1330  }
1331 
1332  name = elf_strptr(bfelf->elf,bfelf->shstrndx,shdr->sh_name);
1333 
1334  if (shdr->sh_type != SHT_RELA || strcmp(name,".rela.plt") != 0)
1335  continue;
1336 
1337  if (!has_plt) {
1338  verror("found .rela.plt section, but no .plt in ELF file %s!\n",
1339  bf->filename);
1340  break;
1341  }
1342 
1344  "found .rela.plt section in ELF file %s;"
1345  " generating @plt symbol names\n",
1346  bf->filename);
1347 
1348  edata = elf_rawdata(scn,NULL);
1349  if (!edata || !edata->d_size || !edata->d_buf) {
1350  verror("cannot get data for valid section %s in %s: %s",
1351  name,bf->filename,elf_errmsg(-1));
1352  goto errout;
1353  }
1354 
1355  /*
1356  * Process only the JMP_SLOT relocs.
1357  */
1358  nrels = shdr->sh_size / shdr->sh_entsize;
1359 
1360  rsec = shdr->sh_info;
1361  rstsec = shdr->sh_link;
1362 
1363  rstrsec = bfelf->shdrs[rstsec].sh_link;
1364 
1365  /*
1366  * Grab the symtab section referred to so we can load the syms.
1367  */
1368  rstscn = elf_getscn(bfelf->elf,rstsec);
1369  if (!rstscn) {
1370  verror("could not load symtab section %d during plt relocation!\n",
1371  rstsec);
1372  break;
1373  }
1374  rstedata = elf_getdata(rstscn,NULL);
1375  if (!rstedata || !rstedata->d_size || !rstedata->d_buf) {
1376  verror("cannot get data for valid symtab section %d during"
1377  " plt relocation!\n",
1378  rstsec);
1379  break;
1380  }
1381 
1383  "found %d plt relocations in %d in ELF file %s\n",
1384  nrels,i,bf->filename);
1385 
1386  /* Skip the first plt "header" entry. */
1387  plt_idx = 1;
1388 
1389  for (j = 0; j < nrels; ++j) {
1390  if (!gelf_getrela(edata,j,&rela)) {
1392  "bad relocation %d in %d; skipping!\n",j,i);
1393  continue;
1394  }
1395  rtype = GELF_R_TYPE(rela.r_info);
1396  rsymidx = GELF_R_SYM(rela.r_info);
1397  if (!gelf_getsym(rstedata,rsymidx,&rsym)) {
1399  "could not load sym %d in %d (for %d/%d) during"
1400  " relocation; skipping!\n",
1401  rsymidx,rstsec,j,i);
1402  continue;
1403  }
1404 
1405  if (rtype != R_X86_64_JUMP_SLOT || rtype != R_386_JMP_SLOT) {
1407  "unexpected relocation type %d (not JMP_SLOT) in"
1408  " .rela.plt at idx %d; plt index names may be wrong!\n",
1409  rtype,j);
1410  continue;
1411  }
1412 
1413 
1414  symname = elf_strptr(bfelf->elf,rstrsec,rsym.st_name);
1415  if (!symname) {
1417  "skipping .rela.plt ELF symbol at .rela.plt idx %d;"
1418  " bad symbol strtab idx %d\n",
1419  j,(int)rsym.st_name);
1420  continue;
1421  }
1422 
1423  len = strlen(symname) + sizeof("@plt") + 1;
1424  if (len > pltsymbuf_len) {
1425  pltsymbuf = realloc(pltsymbuf,len);
1426  pltsymbuf_len = len;
1427  }
1428  snprintf(pltsymbuf,len,"%s@plt",symname);
1429 
1431  pltsymbuf,1,
1432  (SMOFFSET)(shdr->sh_addr + j * shdr->sh_entsize),
1433  LOADTYPE_FULL,root_scope);
1434 
1435  if (GELF_ST_BIND(rsym.st_info) == STB_GLOBAL
1436  || GELF_ST_BIND(rsym.st_info) == STB_WEAK)
1437  symbol_set_external(symbol);
1438 
1439  symbol_set_bytesize(symbol,plt_entry_size);
1440  symbol_set_addr(symbol,(ADDR)(plt_start + plt_idx * plt_entry_size));
1441 
1442  symbol_insert_symbol(bf->root,symbol);
1443 
1444  clrange_add(&bf->ranges,symbol_get_addr(symbol),
1445  symbol_get_addr(symbol) + symbol_get_bytesize(symbol),
1446  symbol);
1447 
1449  "added plt index ELF symbol %s at 0x%"PRIxADDR"\n",
1450  symbol->name,symbol->addr);
1451 
1452  ++plt_idx;
1453  }
1454 
1455  break;
1456  }
1457 
1458  /*
1459  * Now process symtab section. If we have an instance, grab the
1460  * symbol locations out of that symtab.
1461  */
1462  if (symtabsec > -1) {
1463  shdr = &bfelf->shdrs[symtabsec];
1464 
1465  name = elf_strptr(bfelf->elf,bfelf->shstrndx,shdr->sh_name);
1466 
1467  vdebug(2,LA_DEBUG,LF_ELF,"processing %s section in ELF file %s\n",
1468  name,bf->filename);
1469 
1470  scn = elf_getscn(bfelf->elf,symtabsec);
1471  edata = elf_getdata(scn,NULL);
1472  if (!edata || !edata->d_size || !edata->d_buf) {
1473  verror("cannot get data for valid section %s in %s: %s",
1474  name,bf->filename,elf_errmsg(-1));
1475  goto errout;
1476  }
1477 
1478  bfelf->num_symbols = \
1479  edata->d_size / (bfelf->class == ELFCLASS32 ? sizeof (Elf32_Sym) \
1480  : sizeof (Elf64_Sym));
1481 
1483  "%s section in ELF file %s has %d symbols\n",
1484  name,bf->filename,bfelf->num_symbols);
1485 
1486  /* Load the symtab */
1487  for (ii = 0; ii < bfelf->num_symbols; ++ii) {
1488  sym = gelf_getsym(edata,ii,&sym_mem);
1489  if (sym->st_name >= bf->strtablen) {
1490  vwarn("skipping ELF symbol with bad name strtab idx %d\n",
1491  (int)sym->st_name);
1492  continue;
1493  }
1494 
1495  stt = GELF_ST_TYPE(sym->st_info);
1496 
1497  /*
1498  * If the symbol type is NOTYPE, check to see which
1499  * section the symbol is in, and try to dynamically
1500  * "set" the type to STT_OBJECT or STT_FUNC. This will
1501  * result in symbols that should not be in the ELF
1502  * symtab, probably, but hopefully it will reduce the
1503  * amount of missing symbols in our ELF symtab.
1504  */
1505  if (stt == STT_NOTYPE && sym->st_shndx < bfelf->ehdr.e_shnum) {
1506  if (bfelf->shdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR)
1507  stt = STT_FUNC;
1508  else if (bfelf->shdrs[sym->st_shndx].sh_flags & SHF_ALLOC)
1509  stt = STT_OBJECT;
1510  }
1511 
1512  if (!(stt == STT_OBJECT || stt == STT_COMMON || stt == STT_TLS
1513  || stt == STT_FUNC
1514 #if defined(STT_GNU_IFUNC)
1515  || stt == STT_GNU_IFUNC
1516 #endif
1517  ))
1518  /* Skip all non-code symbols */
1519  continue;
1520 
1521  /*
1522  * If it is not in a section in our binary, don't save it.
1523  * XXX: we could expose this as an option, BUT since we're
1524  * not a linker we don't really care.
1525  */
1526  if (sym->st_shndx == SHN_UNDEF)
1527  continue;
1528 
1529  /*
1530  * Don't want various meaningless symbols...
1531  */
1532  if (sym->st_shndx == SHN_ABS && stt == STT_OBJECT && sym->st_value == 0)
1533  continue;
1534 
1535  /*
1536  * Either way, don't have symbol_create copy symname; we do
1537  * it here if we need to.
1538  */
1539 #ifdef DWDEBUG_NOUSE_STRTAB
1540  symname = strdup(&bf->strtab[sym->st_name]);
1541 #else
1542  symname = &bf->strtab[sym->st_name];
1543 #endif
1544 
1545  symbol = symbol_create((stt == STT_OBJECT || stt == STT_TLS
1546  || stt == STT_COMMON) \
1549  symname,0,(SMOFFSET)ii,LOADTYPE_FULL,
1550  root_scope);
1551 
1552  if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL
1553  || GELF_ST_BIND(sym->st_info) == STB_WEAK)
1554  symbol->isexternal = 1;
1555 
1556  symbol->size.bytes = sym->st_size;
1557  symbol->size_is_bytes = 1;
1558 
1559  if (bfelfinst && bfelfinst->symbol_tab && ii < bfelfinst->num_symbols)
1560  symbol_set_addr(symbol,bfelfinst->symbol_tab[ii]);
1561  else
1562  symbol_set_addr(symbol,(ADDR)sym->st_value);
1563 
1564  symbol_insert_symbol(bf->root,symbol);
1565 
1566  /*
1567  * Insert into debugfile->addresses IF the hashtable is
1568  * empty (i.e., if we load the symtab first, before the
1569  * debuginfo file), or if there is not anything already
1570  * at this location. We want debuginfo symbols to trump
1571  * ELF symbols in this table.
1572  */
1573  /* XXXXXX
1574  if (g_hash_table_size(debugfile->addresses) == 0
1575  || !g_hash_table_lookup(debugfile->addresses,
1576  (gpointer)symbol->base_addr))
1577  g_hash_table_insert(debugfile->addresses,
1578  (gpointer)symbol->base_addr,
1579  (gpointer)symbol);
1580  */
1581 
1582  if (symbol_get_addr(symbol) != 0) {
1583  if (sym->st_size > 0)
1584  clrange_add(&bf->ranges,symbol_get_addr(symbol),
1585  symbol_get_addr(symbol) + sym->st_size,symbol);
1586  else
1587  zll = g_slist_prepend(zll,symbol);
1588  }
1589  }
1590  }
1591 
1592  /*
1593  * Now process dynsymtab section. Differences from above code:
1594  * don't duplicate symbols (i.e., if symtab had one with same name
1595  * and addr, don't duplicate it); and don't check bf inst (XXX must
1596  * reconsider how that fits with dynsyms, not just "regular" syms).
1597  */
1598  if (dynsymtabsec > -1) {
1599  shdr = &bfelf->shdrs[dynsymtabsec];
1600 
1601  name = elf_strptr(bfelf->elf,bfelf->shstrndx,shdr->sh_name);
1602  vdebug(2,LA_DEBUG,LF_ELF,"processing %s section in ELF file %s\n",
1603  name,bf->filename);
1604 
1605  scn = elf_getscn(bfelf->elf,dynsymtabsec);
1606  edata = elf_getdata(scn,NULL);
1607  if (!edata || !edata->d_size || !edata->d_buf) {
1608  verror("cannot get data for valid section %s in %s: %s",
1609  name,bf->filename,elf_errmsg(-1));
1610  goto errout;
1611  }
1612 
1613  bfelf->num_symbols = \
1614  edata->d_size / (bfelf->class == ELFCLASS32 ? sizeof (Elf32_Sym) \
1615  : sizeof (Elf64_Sym));
1617  "%s section in ELF file %s has %d symbols\n",
1618  name,bf->filename,bfelf->num_symbols);
1619 
1620  /* Load the symtab */
1621  for (ii = 0; ii < bfelf->num_symbols; ++ii) {
1622  sym = gelf_getsym(edata,ii,&sym_mem);
1623  if (sym->st_name >= bf->dynstrtablen) {
1624  vwarn("skipping ELF symbol with bad name strtab idx %d\n",
1625  (int)sym->st_name);
1626  continue;
1627  }
1628 
1629  stt = GELF_ST_TYPE(sym->st_info);
1630 
1631  /*
1632  * If the symbol type is NOTYPE, check to see which
1633  * section the symbol is in, and try to dynamically
1634  * "set" the type to STT_OBJECT or STT_FUNC. This will
1635  * result in symbols that should not be in the ELF
1636  * symtab, probably, but hopefully it will reduce the
1637  * amount of missing symbols in our ELF symtab.
1638  */
1639  if (stt == STT_NOTYPE && sym->st_shndx < bfelf->ehdr.e_shnum) {
1640  if (bfelf->shdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR)
1641  stt = STT_FUNC;
1642  else if (bfelf->shdrs[sym->st_shndx].sh_flags & SHF_ALLOC)
1643  stt = STT_OBJECT;
1644  }
1645 
1646  if (!(stt == STT_OBJECT || stt == STT_COMMON || stt == STT_TLS
1647  || stt == STT_FUNC
1648 #if defined(STT_GNU_IFUNC)
1649  || stt == STT_GNU_IFUNC
1650 #endif
1651  ))
1652  /* Skip all non-code symbols */
1653  continue;
1654 
1655  /*
1656  * If it is not in a section in our binary, don't save it.
1657  * XXX: we could expose this as an option, BUT since we're
1658  * not a linker we don't really care.
1659  */
1660  if (sym->st_shndx == SHN_UNDEF)
1661  continue;
1662 
1663  /*
1664  * Don't want various meaningless symbols...
1665  */
1666  if (sym->st_shndx == SHN_ABS && stt == STT_OBJECT && sym->st_value == 0)
1667  continue;
1668 
1669  /*
1670  * Check symtab; don't duplicate!
1671  */
1672  tsymbol = symbol_get_one_member__int(bf->root,
1673  &bf->dynstrtab[sym->st_name]);
1674  if (tsymbol && symbol_get_addr(tsymbol) == sym->st_value) {
1676  "not creating duplicate dynsym %s (0x%"PRIxADDR")\n",
1677  tsymbol->name,symbol_get_addr(tsymbol));
1678  continue;
1679  }
1680 
1681  /*
1682  * Either way, don't have symbol_create copy symname; we do
1683  * it here if we need to.
1684  */
1685 #ifdef DWDEBUG_NOUSE_STRTAB
1686  symname = strdup(&bf->dynstrtab[sym->st_name]);
1687 #else
1688  symname = &bf->dynstrtab[sym->st_name];
1689 #endif
1690 
1691  symbol = symbol_create((stt == STT_OBJECT || stt == STT_TLS
1692  || stt == STT_COMMON) \
1693  ? SYMBOL_TYPE_VAR : SYMBOL_TYPE_FUNC,
1695  symname,0,(SMOFFSET)ii,LOADTYPE_FULL,
1696  root_scope);
1697 
1698  if (GELF_ST_BIND(sym->st_info) == STB_GLOBAL
1699  || GELF_ST_BIND(sym->st_info) == STB_WEAK)
1700  symbol_set_external(symbol);
1701 
1702  symbol_set_bytesize(symbol,sym->st_size);
1703 
1704  if (sym->st_value > 0)
1705  symbol_set_addr(symbol,(ADDR)sym->st_value);
1706 
1707  symbol_insert_symbol(bf->root,symbol);
1708 
1709  /*
1710  * Insert into debugfile->addresses IF the hashtable is
1711  * empty (i.e., if we load the symtab first, before the
1712  * debuginfo file), or if there is not anything already
1713  * at this location. We want debuginfo symbols to trump
1714  * ELF symbols in this table.
1715  */
1716  /* XXXXXX
1717  if (g_hash_table_size(debugfile->addresses) == 0
1718  || !g_hash_table_lookup(debugfile->addresses,
1719  (gpointer)symbol->base_addr))
1720  g_hash_table_insert(debugfile->addresses,
1721  (gpointer)symbol->base_addr,
1722  (gpointer)symbol);
1723  */
1724 
1725  if (sym->st_value > 0) {
1726  if (sym->st_size > 0)
1727  clrange_add(&bf->ranges,symbol_get_addr(symbol),
1728  symbol_get_addr(symbol) + sym->st_size,symbol);
1729  else
1730  zll = g_slist_prepend(zll,symbol);
1731  }
1732  }
1733  }
1734 
1735  /*
1736  * Add section symbols if they have addresses and sizes.
1737  */
1738  for (i = 0; i < bfelf->ehdr.e_shnum; ++i) {
1739  shdr = &bfelf->shdrs[i];
1740  scn = elf_getscn(bfelf->elf,i);
1741 
1742  if (!shdr || shdr->sh_size <= 0 || shdr->sh_addr <= 0)
1743  continue;
1744  if (!scn) {
1745  verror("could not find Elf section for section %d!\n",i);
1746  continue;
1747  }
1748  if (!(shdr->sh_flags & SHF_ALLOC))
1749  continue;
1750 
1751  name = elf_strptr(bfelf->elf,bfelf->shstrndx,shdr->sh_name);
1752 
1753  if (shdr->sh_flags & SHF_EXECINSTR)
1754  stt = STT_FUNC;
1755  else
1756  stt = STT_OBJECT;
1757 
1758  symbol = symbol_create(stt == STT_OBJECT ? SYMBOL_TYPE_VAR
1759  : SYMBOL_TYPE_FUNC,
1761  name,1,(SMOFFSET)i,LOADTYPE_FULL,root_scope);
1762 
1763  symbol_set_external(symbol);
1764  symbol_set_bytesize(symbol,shdr->sh_size);
1765  symbol_set_addr(symbol,(ADDR)shdr->sh_addr);
1766 
1767  symbol_insert_symbol(bf->root,symbol);
1768 
1769  vdebug(16,LA_DEBUG,LF_ELF,
1770  "created section symbol %s (0x%"PRIxADDR"; %d bytes)\n",
1771  name,(ADDR)shdr->sh_addr,shdr->sh_size);
1772  }
1773 
1774  if (zll) {
1775  /*
1776  * Now go through all the zero-length symbols, and try to update
1777  * their sizes based on the following range's address -- this is
1778  * definitely possibly wrong sometimes. Could be wrong!
1779  *
1780  * The idea is, for any 0-length isexternal (GLOBAL ELF sym)
1781  * function symbol, don't just look for the next symbol; look
1782  * for the next global function symbol (or end of section).
1783  *
1784  * (This strategy is informed by how the Linux kernel does
1785  * its i386 asm files; "functions" are declared global;
1786  * labels are not, so they appear as LOCAL ELF symbols.)
1787  *
1788  * This will hopefully will allow disassembly of non-DWARF
1789  * functions -- since we guess their length here. Could be
1790  * wrong sometimes.
1791  *
1792  * Note that we immediately sort zll in reverse order -- from
1793  * highest start addr to lowest (and we also prefer external
1794  * symbols to non-external symbols).
1795  */
1796 
1797  gint __symbol_sort_addr_desc(gconstpointer a,gconstpointer b) {
1798  struct symbol *sa = (struct symbol *)a;
1799  struct symbol *sb = (struct symbol *)b;
1800 
1801  if (sa->addr > sb->addr)
1802  return -1;
1803  else if (sa->addr == sb->addr)
1804  return 0;
1805  else
1806  return 1;
1807  }
1808 
1809  zll = g_slist_sort(zll,__symbol_sort_addr_desc);
1810 
1811  v_g_slist_foreach(zll,t1,symbol) {
1812  start = symbol_get_addr(symbol);
1813 
1814  vdebug(16,LA_DEBUG,LF_ELF,
1815  "checking end of ELF symbol %s (0x%"PRIxADDR")\n",
1816  symbol_get_name(symbol),start);
1817 
1818  /*
1819  * Find the next nearest start range, such that
1820  * attributes match.
1821  *
1822  * If the 0-length *function* symbol is global, and the
1823  * next symbol is NOT global, we need to try to find the
1824  * next global symbol!
1825  */
1826  if (SYMBOL_IS_FUNC(symbol) && symbol->isexternal) {
1827  gcrd = NULL;
1828  tmpstart = start;
1829  while ((tmp_ral = clrange_find_next_exc(&bf->ranges,
1830  tmpstart))) {
1831  /* Need to find *any* global symbol at this ral,
1832  * so check the whole list!
1833  */
1834  for (k = 0; k < array_list_len(tmp_ral); ++k) {
1835  tmp_crd = (struct clf_range_data *) \
1836  array_list_item(tmp_ral,k);
1837  tmp_symbol = (struct symbol *)CLRANGE_DATA(tmp_crd);
1838  if (tmp_symbol->isexternal) {
1839  gcrd = tmp_crd;
1840  break;
1841  }
1842 
1843  /* Doesn't matter which one; all same. */
1844  tmpstart = CLRANGE_START(tmp_crd);
1845  }
1846 
1847  if (gcrd)
1848  break;
1849  }
1850 
1851  /*
1852  * We need to find the section containing the base
1853  * addr, and make sure whatever next addr we found,
1854  * if any, is still in that section! If it is not
1855  * still in that section (or if we didn't find one),
1856  * use the section end addr.
1857  */
1858  sec_found = 0;
1859  sec_end = 0;
1860  for (ii = 0; ii < bfelf->ehdr.e_shnum; ++ii) {
1861  if (start >= bfelf->shdrs[ii].sh_addr
1862  && start < (bfelf->shdrs[ii].sh_addr
1863  + bfelf->shdrs[ii].sh_size)) {
1864  sec_found = 1;
1865  sec_end = bfelf->shdrs[ii].sh_addr
1866  + bfelf->shdrs[ii].sh_size;
1867  break;
1868  }
1869  }
1870 
1871  if (!sec_found) {
1873  "could not find section containing 0x%"PRIxADDR";"
1874  " not updating 0-length GLOBAL %s!\n",
1875  start,symbol_get_name(symbol));
1876  continue;
1877  }
1878 
1879  if (!gcrd || CLRANGE_START(gcrd) > sec_end) {
1880  if (!gcrd) {
1882  "could not find next global symbol after %s;"
1883  " using section(%d:%d) end 0x%"PRIxADDR"!\n",
1884  symbol_get_name(symbol),
1885  ii,bfelf->shdrs[ii].sh_size,sec_end);
1886  }
1887  else {
1889  "next global symbol after %s was past section"
1890  "(%d:%d); using section end 0x%"PRIxADDR"!\n",
1891  symbol_get_name(symbol),
1892  ii,bfelf->shdrs[ii].sh_size,sec_end);
1893  }
1894 
1895  symbol->size.bytes = sec_end - start;
1896  symbol->size_is_bytes = 1;
1897  symbol->guessed_size = 1;
1898 
1899  clrange_add(&bf->ranges,start,sec_end,symbol);
1900  }
1901  else {
1903  "updating 0-length GLOBAL symbol %s to"
1904  " 0x%"PRIxADDR",0x%"PRIxADDR"\n",
1905  symbol_get_name(symbol),start,CLRANGE_START(gcrd));
1906 
1907  symbol->size.bytes = CLRANGE_START(gcrd) - start;
1908  symbol->size_is_bytes = 1;
1909  symbol->guessed_size = 1;
1910 
1911  clrange_add(&bf->ranges,start,CLRANGE_START(gcrd),symbol);
1912  }
1913  }
1914  else {
1915  tmp_ral = clrange_find_next_exc(&bf->ranges,start);
1916  if (!tmp_ral) {
1918  "could not find a next range after %s;"
1919  " not updating 0-length symbol!\n",
1920  symbol_get_name(symbol));
1921  continue;
1922  }
1923 
1924  /* Just take the first one! */
1925  gcrd = (struct clf_range_data *)array_list_item(tmp_ral,0);
1926 
1927  /*
1928  * We need to find the section containing the base
1929  * addr, and make sure whatever next addr we found,
1930  * if any, is still in that section! If it is not
1931  * still in that section (or if we didn't find one),
1932  * use the section end addr.
1933  */
1934  sec_found = 0;
1935  sec_end = 0;
1936  for (ii = 0; ii < bfelf->ehdr.e_shnum; ++ii) {
1937  if (start >= bfelf->shdrs[ii].sh_addr
1938  && start < (bfelf->shdrs[ii].sh_addr
1939  + bfelf->shdrs[ii].sh_size)) {
1940  sec_found = 1;
1941  sec_end = bfelf->shdrs[ii].sh_addr
1942  + bfelf->shdrs[ii].sh_size;
1943  break;
1944  }
1945  }
1946 
1947  if (!sec_found) {
1949  "could not find section containing 0x%"PRIxADDR";"
1950  " not updating 0-length GLOBAL %s!\n",
1951  start,symbol_get_name(symbol));
1952  continue;
1953  }
1954 
1955  if (CLRANGE_START(gcrd) > sec_end) {
1957  "next global symbol after %s was past section"
1958  "(%d:%d); using section end 0x%"PRIxADDR"!\n",
1959  symbol_get_name(symbol),
1960  ii,bfelf->shdrs[ii].sh_size,sec_end);
1961 
1962  symbol->size.bytes = sec_end - start;
1963  symbol->size_is_bytes = 1;
1964  symbol->guessed_size = 1;
1965 
1966  clrange_add(&bf->ranges,start,sec_end,symbol);
1967  }
1968  else {
1969 
1971  "updating 0-length symbol %s to 0x%"PRIxADDR","
1972  "0x%"PRIxADDR"\n",
1973  symbol_get_name(symbol),start,CLRANGE_START(gcrd));
1974 
1975  symbol->size.bytes = CLRANGE_START(gcrd) - start;
1976  symbol->size_is_bytes = 1;
1977  symbol->guessed_size = 1;
1978 
1979  clrange_add(&bf->ranges,start,CLRANGE_START(gcrd),symbol);
1980  }
1981  }
1982  }
1983 
1984  g_slist_free(zll);
1985  zll = NULL;
1986  }
1987 
1988  {
1989  /*
1990  * NB: make a special header "function" symbol for the plt.
1991  * This is helpful for stuff that wants to disasm the plt -- but
1992  * at the moment we can't disasm for plain code blocks, only for
1993  * symbols.
1994  *
1995  * We basically run the length of this symbol all the way to
1996  * either the end of the PLT, or to the first symbol in the PLT.
1997  */
1998  if (has_plt) {
1999  symbol = symbol_create(SYMBOL_TYPE_FUNC,SYMBOL_SOURCE_ELF,
2000  "_header@plt",0,(SMOFFSET)0,
2001  LOADTYPE_FULL,root_scope);
2002 
2003  symbol_set_external(symbol);
2004  symbol_set_addr(symbol,plt_start);
2005 
2006  ral = clrange_find_next_exc(&bf->ranges,plt_start);
2007  if (!ral) {
2008  symbol_set_bytesize(symbol,plt_size);
2010  "could not find a symbol following the PLT; assuming _header@plt is the whole PLT!\n");
2011  }
2012  else {
2013  /* Just take the first one! */
2014  gcrd = (struct clf_range_data *)array_list_item(ral,0);
2015 
2016  if (CLRANGE_START(gcrd) >= (plt_start + plt_size)) {
2017  symbol_set_bytesize(symbol,plt_size);
2019  "could not find a symbol following the PLT within"
2020  " the PLT; assuming _header@plt is the whole PLT!\n");
2021  }
2022  else {
2023  symbol_set_bytesize(symbol,CLRANGE_START(gcrd) - plt_start);
2024 
2026  "setting _header@plt size to %d bytes.\n",
2027  symbol_get_bytesize(symbol));
2028  }
2029  }
2030 
2031  symbol_insert_symbol(bf->root,symbol);
2032 
2033  clrange_add(&bf->ranges,symbol_get_addr(symbol),
2034  symbol_get_addr(symbol) + symbol_get_bytesize(symbol),
2035  symbol);
2036  }
2037  }
2038 
2039  if (pltsymbuf)
2040  free(pltsymbuf);
2041 #ifdef DWDEBUG_NOUSE_STRTAB
2042  /*
2043  * Only save elf_strtab if we're gonna use it.
2044  */
2045  if (bf->strtab) {
2046  free(bf->strtab);
2047  bf->strtablen = 0;
2048  bf->strtab = NULL;
2049  }
2050  if (bf->dynstrtab) {
2051  free(bf->dynstrtab);
2052  bf->dynstrtablen = 0;
2053  bf->dynstrtab = NULL;
2054  }
2055 #endif
2056 
2057  return bf;
2058 
2059  errout:
2060  if (pltsymbuf)
2061  free(pltsymbuf);
2062  if (bf) {
2063  binfile_close(bf);
2064  binfile_free(bf,1);
2065  }
2066  else if (bfelf) {
2067  free(bfelf);
2068  }
2069 
2070  return NULL;
2071 }
2072 
int symbol_insert_symbol(struct symbol *parent, struct symbol *child)
Definition: debug.c:2758
ADDR base_virt_addr
Definition: binfile.h:286
#define vwarnopt(level, area, flags, format,...)
Definition: log.h:37
Word_t start
Definition: clfit.h:37
struct scope * symbol_write_owned_scope(struct symbol *symbol)
Definition: debug.c:2689
char * filename
Definition: binfile.h:243
void symbol_set_bytesize(struct symbol *s, uint32_t b)
Definition: debug.c:3219
#define symbol_set_external(s)
REFCNT binfile_free(struct binfile *binfile, int force)
Definition: binfile.c:358
union symbol::@7 size
int fd
Definition: binfile.h:214
clrange_t ranges
Definition: binfile.h:279
struct symbol * symbol_create(symbol_type_t symtype, symbol_source_t source, char *name, int name_copy, SMOFFSET offset, load_type_t loadtype, struct scope *scope)
Definition: debug.c:2550
unsigned int guessed_size
Definition: dwdebug_priv.h:839
struct symbol * symbol_get_one_member__int(struct symbol *symbol, char *member)
Definition: debug.c:4123
unsigned int num_symbols
Definition: binfile.h:337
static uint64_t unsigned int i
unsigned int isexternal
Definition: dwdebug_priv.h:839
char * image
Definition: binfile.h:213
binfile_type_t type
Definition: binfile.h:200
Ebl * ebl
Definition: binfile.h:351
#define v_g_slist_foreach(gslhead, gslcur, elm)
Definition: glib_wrapper.h:60
unsigned int strtablen
Definition: binfile.h:224
unsigned int size_is_bytes
Definition: dwdebug_priv.h:839
char * strtab
Definition: binfile.h:225
ADDR addr
Definition: dwdebug_priv.h:916
unsigned int dynstrtablen
Definition: binfile.h:233
int32_t SMOFFSET
Definition: common.h:100
ADDR symbol_get_addr(struct symbol *symbol)
Definition: debug.c:3096
#define fm
uint32_t symbol_get_bytesize(struct symbol *symbol)
Definition: debug.c:3065
Dwfl * dwfl
Definition: binfile.h:352
uint32_t gnu_debuglinkfile_crc
Definition: binfile.h:335
#define verror(format,...)
Definition: log.h:30
#define vwarn(format,...)
Definition: log.h:33
#define ADDRMAX
Definition: common.h:74
void free(void *ptr)
Definition: debugserver.c:207
uint8_t is_dynamic
Definition: binfile.h:202
char * root_prefix
Definition: binfile.h:376
Definition: log.h:124
Definition: log.h:69
int class
Definition: binfile.h:331
struct arch * arch
Definition: binfile.h:216
void * priv
Definition: binfile.h:265
struct symbol * root
Definition: binfile.h:272
size_t shstrndx
Definition: binfile.h:332
const char *(* get_backend_name)(void)
Definition: binfile.h:173
struct binfile * binfile_open__int(char *filename, char *root_prefix, struct binfile_instance *bfinst)
Definition: binfile.c:254
int dwfl_fd
Definition: binfile.h:353
#define CLRANGE_DATA(crd)
Definition: clfit.h:45
char * gnu_debuglinkfile
Definition: binfile.h:334
unsigned int num_symbols
Definition: binfile.h:387
#define __PAGE_SIZE
uint8_t has_debuginfo
Definition: binfile.h:202
#define __ALIGN(x, a)
char * name
Definition: dwdebug_priv.h:788
GElf_Shdr * shdrs
Definition: binfile.h:397
int len
Definition: dumptarget.c:52
#define RHOLD(x, hx)
Definition: common.h:622
void symbol_set_addr(struct symbol *s, ADDR a)
Definition: debug.c:3276
#define ARCH_SHF_X86
#define vdebug(devel, areas, flags, format,...)
Definition: log.h:302
void * realloc(void *ptr, size_t size)
Definition: debugserver.c:221
GElf_Ehdr ehdr
Definition: binfile.h:343
char * buildid
Definition: binfile.h:333
struct binfile * binfile_create(char *filename, struct binfile_ops *bfops, void *priv)
Definition: binfile.c:124
struct binfile_ops * ops
Definition: binfile.h:264
#define vdebugc(devel, areas, flags, format,...)
Definition: log.h:303
#define CLRANGE_START(crd)
Definition: clfit.h:43
unsigned int wordsize
Definition: arch.h:121
void * calloc(size_t nmemb, size_t size)
Definition: debugserver.c:200
Definition: log.h:135
struct arch * arch_get(arch_type_t at)
Definition: arch.c:25
Definition: arch.h:102
struct binfile_ops elf_binfile_ops
Definition: binfile_elf.c:67
struct binfile_ops * ops
Definition: binfile.h:381
uint32_t ADDR
Definition: common.h:64
Definition: arch.h:116
GElf_Shdr * shdrs
Definition: binfile.h:345
GElf_Phdr * phdrs
Definition: binfile.h:344
uint32_t bytes
Definition: dwdebug_priv.h:901
#define PRIxADDR
Definition: common.h:67
struct binfile_instance * instance
Definition: binfile.h:301
char * dynstrtab
Definition: binfile.h:234
int binfile_close(struct binfile *binfile)
Definition: binfile.c:339
char * root_prefix
Definition: binfile.h:321
char * symbol_get_name(struct symbol *symbol)
Definition: debug.c:2587
void * malloc(size_t size)
Definition: debugserver.c:214
Elf * elf
Definition: binfile.h:350
ADDR base_phys_addr
Definition: binfile.h:285
#define SYMBOL_IS_FUNC(sym)
int clrange_add(clrange_t *clf, Word_t start, Word_t end, void *data)
Definition: clfit.c:104
struct array_list * clrange_find_next_exc(clrange_t *clf, Word_t index)
Definition: clfit.c:494
unsigned int num_sections
Definition: binfile.h:386
struct spf_config * config
Definition: spf.c:156
char * filename
Definition: binfile.h:368
debugfile_type_t has_debuginfo_type
Definition: binfile.h:206