1 /* Test program for dwfl_report_offline_memory.
2 Copyright (C) 2022 Google LLC
3 This file is part of elfutils.
4
5 This file 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 3 of the License, or
8 (at your option) any later version.
9
10 elfutils is distributed in the hope that it will be useful, but
11 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, see <http://www.gnu.org/licenses/>. */
17
18 #include <config.h>
19
20 #include <assert.h>
21 #include <errno.h>
22 #include <error.h>
23 #include <fcntl.h>
24 #include <locale.h>
25 #include <stdio.h>
26 #include <stdio_ext.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30
31 #include ELFUTILS_HEADER(dwfl)
32 #include ELFUTILS_HEADER(elf)
33 #include <gelf.h>
34
35
36 static const Dwfl_Callbacks offline_callbacks =
37 {
38 .find_debuginfo = INTUSE(dwfl_standard_find_debuginfo),
39 .section_address = INTUSE(dwfl_offline_section_address),
40 };
41
42 static int
count_modules(Dwfl_Module * mod,void ** userdata,const char * name,Dwarf_Addr base,void * arg)43 count_modules (Dwfl_Module *mod __attribute__ ((unused)),
44 void **userdata __attribute__ ((unused)),
45 const char *name __attribute__ ((unused)),
46 Dwarf_Addr base __attribute__ ((unused)), void *arg)
47 {
48 unsigned long long *counter = arg;
49 ++(*counter);
50 return DWARF_CB_OK;
51 }
52
53 static int
count_sections(Elf * elf)54 count_sections (Elf *elf)
55 {
56 int result = 0;
57 Elf_Scn *section = NULL;
58 GElf_Shdr header;
59 while ((section = elf_nextscn (elf, section)) != NULL)
60 {
61 assert (gelf_getshdr (section, &header) != NULL);
62 result += 1;
63 }
64 return result;
65 }
66
67 int
main(int argc,char ** argv)68 main (int argc, char **argv)
69 {
70 /* We use no threads here which can interfere with handling a stream. */
71 (void) __fsetlocking (stdout, FSETLOCKING_BYCALLER);
72
73 /* Set locale. */
74 (void) setlocale (LC_ALL, "");
75
76 if (argc != 4)
77 error (-1, 0,
78 "usage: dwfl_report_offline_memory [filename] "
79 "[expected number of modules] "
80 "[expected number of sections]");
81
82 const char *fname = argv[1];
83 int fd = open (fname, O_RDONLY);
84 if (fd < 0)
85 error (-1, 0, "can't open file %s: %s", fname, strerror (errno));
86 off_t size = lseek (fd, 0, SEEK_END);
87 if (size < 0)
88 error (-1, 0, "can't lseek file %s: %s", fname, strerror (errno));
89 lseek (fd, 0, SEEK_SET);
90 char *data = malloc (size);
91 if (data == NULL)
92 error (-1, 0, "can't malloc: %s", strerror (errno));
93 ssize_t bytes_read = read (fd, data, size);
94 assert (bytes_read == size);
95 close (fd);
96
97 Dwfl *dwfl = dwfl_begin (&offline_callbacks);
98 assert (dwfl != NULL);
99
100 Dwfl_Module *mod;
101
102 /* Check error handling by suppling zero data */
103 mod = dwfl_report_offline_memory(dwfl, argv[1], argv[1], NULL, 0);
104 assert(mod == NULL);
105
106 mod = dwfl_report_offline_memory(dwfl, argv[1], argv[1], data, size);
107 assert (mod != NULL);
108 dwfl_report_end (dwfl, NULL, NULL);
109
110 unsigned long long number_of_modules = 0;
111 ptrdiff_t offset =
112 dwfl_getmodules (dwfl, &count_modules, &number_of_modules, 0);
113 if (offset < 0)
114 error (1, 0, "dwfl_getmodules: %s", dwfl_errmsg (-1));
115 assert (offset == 0);
116
117 char *endptr;
118 unsigned long long expected_number_of_modules =
119 strtoull (argv[2], &endptr, 0);
120 assert (endptr && !*endptr);
121 assert (number_of_modules == expected_number_of_modules);
122
123 GElf_Addr loadbase = 0;
124 Elf *elf = dwfl_module_getelf (mod, &loadbase);
125 int number_of_sections = count_sections (elf);
126 int expected_number_of_sections = atoi (argv[3]);
127 assert (number_of_sections == expected_number_of_sections);
128
129 dwfl_end (dwfl);
130 free (data);
131
132 return 0;
133 }
134