xref: /dflybsd-src/contrib/binutils-2.34/libctf/ctf-subr.c (revision b52ef7118d1621abed722c5bbbd542210290ecef)
1*fae548d3Szrj /* Simple subrs.
2*fae548d3Szrj    Copyright (C) 2019-2020 Free Software Foundation, Inc.
3*fae548d3Szrj 
4*fae548d3Szrj    This file is part of libctf.
5*fae548d3Szrj 
6*fae548d3Szrj    libctf is free software; you can redistribute it and/or modify it under
7*fae548d3Szrj    the terms of the GNU General Public License as published by the Free
8*fae548d3Szrj    Software Foundation; either version 3, or (at your option) any later
9*fae548d3Szrj    version.
10*fae548d3Szrj 
11*fae548d3Szrj    This program is distributed in the hope that it will be useful, but
12*fae548d3Szrj    WITHOUT ANY WARRANTY; without even the implied warranty of
13*fae548d3Szrj    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14*fae548d3Szrj    See the GNU General Public License for more details.
15*fae548d3Szrj 
16*fae548d3Szrj    You should have received a copy of the GNU General Public License
17*fae548d3Szrj    along with this program; see the file COPYING.  If not see
18*fae548d3Szrj    <http://www.gnu.org/licenses/>.  */
19*fae548d3Szrj 
20*fae548d3Szrj #include <ctf-impl.h>
21*fae548d3Szrj #ifdef HAVE_MMAP
22*fae548d3Szrj #include <sys/mman.h>
23*fae548d3Szrj #endif
24*fae548d3Szrj #include <sys/types.h>
25*fae548d3Szrj #include <stdarg.h>
26*fae548d3Szrj #include <string.h>
27*fae548d3Szrj #include <unistd.h>
28*fae548d3Szrj 
29*fae548d3Szrj int _libctf_version = CTF_VERSION;	      /* Library client version.  */
30*fae548d3Szrj int _libctf_debug = 0;			      /* Debugging messages enabled.  */
31*fae548d3Szrj 
32*fae548d3Szrj /* Private, read-only mmap from a file, with fallback to copying.
33*fae548d3Szrj 
34*fae548d3Szrj    No handling of page-offset issues at all: the caller must allow for that. */
35*fae548d3Szrj 
36*fae548d3Szrj _libctf_malloc_ void *
ctf_mmap(size_t length,size_t offset,int fd)37*fae548d3Szrj ctf_mmap (size_t length, size_t offset, int fd)
38*fae548d3Szrj {
39*fae548d3Szrj   void *data;
40*fae548d3Szrj 
41*fae548d3Szrj #ifdef HAVE_MMAP
42*fae548d3Szrj   data = mmap (NULL, length, PROT_READ, MAP_PRIVATE, fd, offset);
43*fae548d3Szrj   if (data == MAP_FAILED)
44*fae548d3Szrj     data = NULL;
45*fae548d3Szrj #else
46*fae548d3Szrj   if ((data = malloc (length)) != NULL)
47*fae548d3Szrj     {
48*fae548d3Szrj       if (ctf_pread (fd, data, length, offset) <= 0)
49*fae548d3Szrj 	{
50*fae548d3Szrj 	  free (data);
51*fae548d3Szrj 	  data = NULL;
52*fae548d3Szrj 	}
53*fae548d3Szrj     }
54*fae548d3Szrj #endif
55*fae548d3Szrj   return data;
56*fae548d3Szrj }
57*fae548d3Szrj 
58*fae548d3Szrj void
ctf_munmap(void * buf,size_t length _libctf_unused_)59*fae548d3Szrj ctf_munmap (void *buf, size_t length _libctf_unused_)
60*fae548d3Szrj {
61*fae548d3Szrj #ifdef HAVE_MMAP
62*fae548d3Szrj   (void) munmap (buf, length);
63*fae548d3Szrj #else
64*fae548d3Szrj   free (buf);
65*fae548d3Szrj #endif
66*fae548d3Szrj }
67*fae548d3Szrj 
68*fae548d3Szrj ssize_t
ctf_pread(int fd,void * buf,ssize_t count,off_t offset)69*fae548d3Szrj ctf_pread (int fd, void *buf, ssize_t count, off_t offset)
70*fae548d3Szrj {
71*fae548d3Szrj   ssize_t len;
72*fae548d3Szrj   size_t acc = 0;
73*fae548d3Szrj   char *data = (char *) buf;
74*fae548d3Szrj 
75*fae548d3Szrj #ifdef HAVE_PREAD
76*fae548d3Szrj   while (count > 0)
77*fae548d3Szrj     {
78*fae548d3Szrj       errno = 0;
79*fae548d3Szrj       if (((len = pread (fd, data, count, offset)) < 0) &&
80*fae548d3Szrj 	  errno != EINTR)
81*fae548d3Szrj 	  return len;
82*fae548d3Szrj       if (errno == EINTR)
83*fae548d3Szrj 	continue;
84*fae548d3Szrj 
85*fae548d3Szrj       acc += len;
86*fae548d3Szrj       if (len == 0)				/* EOF.  */
87*fae548d3Szrj 	return acc;
88*fae548d3Szrj 
89*fae548d3Szrj       count -= len;
90*fae548d3Szrj       offset += len;
91*fae548d3Szrj       data += len;
92*fae548d3Szrj     }
93*fae548d3Szrj   return acc;
94*fae548d3Szrj #else
95*fae548d3Szrj   off_t orig_off;
96*fae548d3Szrj 
97*fae548d3Szrj   if ((orig_off = lseek (fd, 0, SEEK_CUR)) < 0)
98*fae548d3Szrj     return -1;
99*fae548d3Szrj   if ((lseek (fd, offset, SEEK_SET)) < 0)
100*fae548d3Szrj     return -1;
101*fae548d3Szrj 
102*fae548d3Szrj   while (count > 0)
103*fae548d3Szrj     {
104*fae548d3Szrj       errno = 0;
105*fae548d3Szrj       if (((len = read (fd, data, count)) < 0) &&
106*fae548d3Szrj 	  errno != EINTR)
107*fae548d3Szrj 	  return len;
108*fae548d3Szrj       if (errno == EINTR)
109*fae548d3Szrj 	continue;
110*fae548d3Szrj 
111*fae548d3Szrj       acc += len;
112*fae548d3Szrj       if (len == 0)				/* EOF.  */
113*fae548d3Szrj 	break;
114*fae548d3Szrj 
115*fae548d3Szrj       count -= len;
116*fae548d3Szrj       data += len;
117*fae548d3Szrj     }
118*fae548d3Szrj   if ((lseek (fd, orig_off, SEEK_SET)) < 0)
119*fae548d3Szrj     return -1;					/* offset is smashed.  */
120*fae548d3Szrj #endif
121*fae548d3Szrj 
122*fae548d3Szrj   return acc;
123*fae548d3Szrj }
124*fae548d3Szrj 
125*fae548d3Szrj const char *
ctf_strerror(int err)126*fae548d3Szrj ctf_strerror (int err)
127*fae548d3Szrj {
128*fae548d3Szrj   return (const char *) (strerror (err));
129*fae548d3Szrj }
130*fae548d3Szrj 
131*fae548d3Szrj /* Set the CTF library client version to the specified version.  If version is
132*fae548d3Szrj    zero, we just return the default library version number.  */
133*fae548d3Szrj int
ctf_version(int version)134*fae548d3Szrj ctf_version (int version)
135*fae548d3Szrj {
136*fae548d3Szrj   if (version < 0)
137*fae548d3Szrj     {
138*fae548d3Szrj       errno = EINVAL;
139*fae548d3Szrj       return -1;
140*fae548d3Szrj     }
141*fae548d3Szrj 
142*fae548d3Szrj   if (version > 0)
143*fae548d3Szrj     {
144*fae548d3Szrj       /*  Dynamic version switching is not presently supported. */
145*fae548d3Szrj       if (version != CTF_VERSION)
146*fae548d3Szrj 	{
147*fae548d3Szrj 	  errno = ENOTSUP;
148*fae548d3Szrj 	  return -1;
149*fae548d3Szrj 	}
150*fae548d3Szrj       ctf_dprintf ("ctf_version: client using version %d\n", version);
151*fae548d3Szrj       _libctf_version = version;
152*fae548d3Szrj     }
153*fae548d3Szrj 
154*fae548d3Szrj   return _libctf_version;
155*fae548d3Szrj }
156*fae548d3Szrj 
157*fae548d3Szrj void
libctf_init_debug(void)158*fae548d3Szrj libctf_init_debug (void)
159*fae548d3Szrj {
160*fae548d3Szrj   static int inited;
161*fae548d3Szrj   if (!inited)
162*fae548d3Szrj     {
163*fae548d3Szrj       _libctf_debug = getenv ("LIBCTF_DEBUG") != NULL;
164*fae548d3Szrj       inited = 1;
165*fae548d3Szrj     }
166*fae548d3Szrj }
167*fae548d3Szrj 
ctf_setdebug(int debug)168*fae548d3Szrj void ctf_setdebug (int debug)
169*fae548d3Szrj {
170*fae548d3Szrj   /* Ensure that libctf_init_debug() has been called, so that we don't get our
171*fae548d3Szrj      debugging-on-or-off smashed by the next call.  */
172*fae548d3Szrj 
173*fae548d3Szrj   libctf_init_debug();
174*fae548d3Szrj   _libctf_debug = debug;
175*fae548d3Szrj   ctf_dprintf ("CTF debugging set to %i\n", debug);
176*fae548d3Szrj }
177*fae548d3Szrj 
ctf_getdebug(void)178*fae548d3Szrj int ctf_getdebug (void)
179*fae548d3Szrj {
180*fae548d3Szrj   return _libctf_debug;
181*fae548d3Szrj }
182*fae548d3Szrj 
183*fae548d3Szrj _libctf_printflike_ (1, 2)
ctf_dprintf(const char * format,...)184*fae548d3Szrj void ctf_dprintf (const char *format, ...)
185*fae548d3Szrj {
186*fae548d3Szrj   if (_libctf_debug)
187*fae548d3Szrj     {
188*fae548d3Szrj       va_list alist;
189*fae548d3Szrj 
190*fae548d3Szrj       va_start (alist, format);
191*fae548d3Szrj       fflush (stdout);
192*fae548d3Szrj       (void) fputs ("libctf DEBUG: ", stderr);
193*fae548d3Szrj       (void) vfprintf (stderr, format, alist);
194*fae548d3Szrj       va_end (alist);
195*fae548d3Szrj     }
196*fae548d3Szrj }
197