ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/src/trunk/usr.sbin/kldxref/kldxref.c
(Generate patch)

Comparing trunk/usr.sbin/kldxref/kldxref.c (file contents):
Revision 10728 by laffer1, Fri Dec 20 23:33:19 2013 UTC vs.
Revision 10729 by laffer1, Sat Jun 9 21:59:22 2018 UTC

# Line 1 | Line 1
1 + /* $MidnightBSD$ */
2   /*
3   * Copyright (c) 2000, Boris Popov
4   * All rights reserved.
# Line 29 | Line 30
30   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31   * SUCH DAMAGE.
32   *
33 < * $FreeBSD: src/usr.sbin/kldxref/kldxref.c,v 1.14 2006/08/05 18:22:11 imp Exp $
33 > * $FreeBSD: stable/10/usr.sbin/kldxref/kldxref.c 298494 2016-04-22 21:43:44Z emaste $
34   */
35  
36   #include <sys/types.h>
# Line 42 | Line 43
43   #include <sys/stat.h>
44   #include <sys/module.h>
45   #define FREEBSD_ELF
45 #include <link.h>
46   #include <err.h>
47   #include <fts.h>
48   #include <string.h>
# Line 54 | Line 54
54  
55   #include "ef.h"
56  
57 < #define MAXRECSIZE      1024
57 > #define MAXRECSIZE      8192
58   #define check(val)      if ((error = (val)) != 0) break
59  
60 < #ifndef min
61 < #define min(a,b)        (((a)<(b)) ? (a) : (b))
62 < #endif
60 > static int dflag;       /* do not create a hint file, only write on stdout */
61 > static int verbose;
62  
63 < struct mod_info {
65 <        char*   mi_name;
66 <        int     mi_ver;
67 <        SLIST_ENTRY(mod_info) mi_next;
68 < };
63 > static FILE *fxref;     /* current hints file */
64  
70 #ifdef notnow
71 struct kld_info {
72        char*   k_filename;
73        SLIST_HEAD(mod_list_head, mod_info) k_modules;
74        SLIST_ENTRY(kld_info) k_next;
75 };
76
77 SLIST_HEAD(kld_list_head, kld_info) kldlist;
78 #endif
79
80 static int dflag, verbose;
81
82 FILE *fxref;
83
65   static const char *xref_file = "linker.hints";
66  
67 + /*
68 + * A record is stored in the static buffer recbuf before going to disk.
69 + */
70   static char recbuf[MAXRECSIZE];
71 < static int recpos, reccnt;
71 > static int recpos;      /* current write position */
72 > static int reccnt;      /* total record written to this file so far */
73  
89 FILE *maketempfile(char *, const char *);
90 static void usage(void);
91
74   static void
75   intalign(void)
76   {
# Line 105 | Line 87 | record_start(void)
87   static int
88   record_end(void)
89   {
90 <        if (dflag || recpos == 0)
90 >        if (recpos == 0)
91                  return 0;
92          reccnt++;
93          intalign();
# Line 123 | Line 105 | record_buf(const void *buf, int size)
105          return 0;
106   }
107  
108 + /*
109 + * An int is stored in host order and aligned
110 + */
111   static int
112   record_int(int val)
113   {
# Line 130 | Line 115 | record_int(int val)
115          return record_buf(&val, sizeof(val));
116   }
117  
118 + /*
119 + * A string is stored as 1-byte length plus data, no padding
120 + */
121   static int
134 record_byte(u_char val)
135 {
136        return record_buf(&val, sizeof(val));
137 }
138
139 static int
122   record_string(const char *str)
123   {
124 <        int len = strlen(str);
125 <        int error;
126 <
124 >        int len, error;
125 >        u_char val;
126 >        
127          if (dflag)
128                  return 0;
129 <        error = record_byte(len);
129 >        val = len = strlen(str);
130 >        if (len > 255)
131 >                errx(1, "string %s too long", str);
132 >        error = record_buf(&val, sizeof(val));
133          if (error)
134                  return error;
135          return record_buf(str, len);
# Line 170 | Line 155 | parse_entry(struct mod_metadata *md, const char *cval,
155                  break;
156          case MDT_VERSION:
157                  check(EF_SEG_READ(ef, data, sizeof(mdv), &mdv));
158 <                record_int(MDT_VERSION);
159 <                record_string(cval);
160 <                record_int(mdv.mv_version);
161 <                record_string(kldname);
162 <                if (!dflag)
163 <                        break;
164 <                printf("  interface %s.%d\n", cval, mdv.mv_version);
158 >                if (dflag) {
159 >                        printf("  interface %s.%d\n", cval, mdv.mv_version);
160 >                } else {
161 >                        record_int(MDT_VERSION);
162 >                        record_string(cval);
163 >                        record_int(mdv.mv_version);
164 >                        record_string(kldname);
165 >                }
166                  break;
167          case MDT_MODULE:
168 <                record_int(MDT_MODULE);
169 <                record_string(cval);
170 <                record_string(kldname);
171 <                if (!dflag)
172 <                        break;
173 <                printf("  module %s\n", cval);
168 >                if (dflag) {
169 >                        printf("  module %s\n", cval);
170 >                } else {
171 >                        record_int(MDT_MODULE);
172 >                        record_string(cval);
173 >                        record_string(kldname);
174 >                }
175                  break;
176 +        case MDT_PNP_INFO:
177 +                if (dflag) {
178 +                        printf("  pnp info for bus %s\n", cval);
179 +                }
180          default:
181                  warnx("unknown metadata record %d in file %s", md->md_type, kldname);
182          }
# Line 199 | Line 190 | read_kld(char *filename, char *kldname)
190   {
191          struct mod_metadata md;
192          struct elf_file ef;
202 /*      struct kld_info *kip;
203        struct mod_info *mip;*/
193          void **p, **orgp;
194          int error, eftype, nmlen;
195          long start, finish, entries;
# Line 224 | Line 213 | read_kld(char *filename, char *kldname)
213          }
214          if (!dflag) {
215                  cp = strrchr(kldname, '.');
216 <                nmlen = cp ? min(MAXMODNAME, cp - kldname) :
217 <                    min(MAXMODNAME, strlen(kldname));
216 >                nmlen = (cp != NULL) ? cp - kldname : (int)strlen(kldname);
217 >                if (nmlen > MAXMODNAME)
218 >                        nmlen = MAXMODNAME;
219                  strlcpy(kldmodname, kldname, nmlen);
220   /*              fprintf(fxref, "%s:%s:%d\n", kldmodname, kldname, 0);*/
221          }
# Line 252 | Line 242 | read_kld(char *filename, char *kldname)
242          return error;
243   }
244  
245 < FILE *
245 > /*
246 > * Create a temp file in directory root, make sure we don't
247 > * overflow the buffer for the destination name
248 > */
249 > static FILE *
250   maketempfile(char *dest, const char *root)
251   {
252          char *p;
253 <        int fd;
253 >        int n, fd;
254  
255 <        strlcpy(dest, root, MAXPATHLEN);
255 >        p = strrchr(root, '/');
256 >        n = p != NULL ? p - root + 1 : 0;
257 >        if (snprintf(dest, MAXPATHLEN, "%.*slhint.XXXXXX", n, root) >=
258 >            MAXPATHLEN) {
259 >                errno = ENAMETOOLONG;
260 >                return NULL;
261 >        }
262  
263        if ((p = strrchr(dest, '/')) != 0)
264                p++;
265        else
266                p = dest;
267        strcpy(p, "lhint.XXXXXX");
263          fd = mkstemp(dest);
264 <        return ((fd == -1) ? NULL : fdopen(fd, "w+"));
264 >        if (fd < 0)
265 >                return NULL;
266 >        fchmod(fd, 0644);       /* nothing secret in the file */
267 >        return fdopen(fd, "w+");
268   }
269  
270   static char xrefname[MAXPATHLEN], tempname[MAXPATHLEN];
271  
272 + static void
273 + usage(void)
274 + {
275 +
276 +        fprintf(stderr, "%s\n",
277 +            "usage: kldxref [-Rdv] [-f hintsfile] path ..."
278 +        );
279 +        exit(1);
280 + }
281 +
282 + static int
283 + compare(const FTSENT *const *a, const FTSENT *const *b)
284 + {
285 +        if ((*a)->fts_info == FTS_D && (*b)->fts_info != FTS_D)
286 +                return 1;
287 +        if ((*a)->fts_info != FTS_D && (*b)->fts_info == FTS_D)
288 +                return -1;
289 +        return strcmp((*a)->fts_name, (*b)->fts_name);
290 + }
291 +
292   int
293   main(int argc, char *argv[])
294   {
# Line 280 | Line 298 | main(int argc, char *argv[])
298          struct stat sb;
299  
300          fts_options = FTS_PHYSICAL;
283 /*      SLIST_INIT(&kldlist);*/
301  
302          while ((opt = getopt(argc, argv, "Rdf:v")) != -1) {
303                  switch (opt) {
304 <                case 'd':
304 >                case 'd':       /* no hint file, only print on stdout */
305                          dflag = 1;
306                          break;
307 <                case 'f':
307 >                case 'f':       /* use this name instead of linker.hints */
308                          xref_file = optarg;
309                          break;
310                  case 'v':
311                          verbose++;
312                          break;
313 <                case 'R':
313 >                case 'R':       /* recurse on directories */
314                          fts_options |= FTS_COMFOLLOW;
315                          break;
316                  default:
# Line 313 | Line 330 | main(int argc, char *argv[])
330                  err(1, "%s", argv[0]);
331          }
332  
333 <        ftsp = fts_open(argv, fts_options, 0);
333 >        ftsp = fts_open(argv, fts_options, compare);
334          if (ftsp == NULL)
335                  exit(1);
336  
337          for (;;) {
338                  p = fts_read(ftsp);
339 <                if ((p == NULL || p->fts_info == FTS_D) && !dflag && fxref) {
339 >                if ((p == NULL || p->fts_info == FTS_D) && fxref) {
340 >                        /* close and rename the current hint file */
341                          fclose(fxref);
342                          fxref = NULL;
343                          if (reccnt) {
344                                  rename(tempname, xrefname);
345                          } else {
346 +                                /* didn't find any entry, ignore this file */
347                                  unlink(tempname);
348                                  unlink(xrefname);
349                          }
350                  }
351                  if (p == NULL)
352                          break;
353 <                if (p && p->fts_info == FTS_D && !dflag) {
353 >                if (p->fts_info == FTS_D && !dflag) {
354 >                        /* visiting a new directory, create a new hint file */
355                          snprintf(xrefname, sizeof(xrefname), "%s/%s",
356                              ftsp->fts_path, xref_file);
357                          fxref = maketempfile(tempname, ftsp->fts_path);
# Line 341 | Line 361 | main(int argc, char *argv[])
361                          fwrite(&ival, sizeof(ival), 1, fxref);
362                          reccnt = 0;
363                  }
364 +                /* skip non-files and separate debug files */
365                  if (p->fts_info != FTS_F)
366                          continue;
367 +                if (p->fts_namelen >= 6 &&
368 +                    strcmp(p->fts_name + p->fts_namelen - 6, ".debug") == 0)
369 +                        continue;
370                  if (p->fts_namelen >= 8 &&
371                      strcmp(p->fts_name + p->fts_namelen - 8, ".symbols") == 0)
372                          continue;
# Line 350 | Line 374 | main(int argc, char *argv[])
374          }
375          fts_close(ftsp);
376          return 0;
353 }
354
355 static void
356 usage(void)
357 {
358
359        fprintf(stderr, "%s\n",
360            "usage: kldxref [-Rdv] [-f hintsfile] path ..."
361        );
362        exit(1);
377   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines