Gentoo Archives: gentoo-commits

From: Fabian Groffen <grobian@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/pax-utils:master commit in: /
Date: Fri, 01 Jan 2021 14:08:27
Message-Id: 1609509982.8a389efbb1b504de7964ab093af1d528da7ebf3b.grobian@gentoo
1 commit: 8a389efbb1b504de7964ab093af1d528da7ebf3b
2 Author: Fabian Groffen <grobian <AT> gentoo <DOT> org>
3 AuthorDate: Fri Jan 1 14:06:22 2021 +0000
4 Commit: Fabian Groffen <grobian <AT> gentoo <DOT> org>
5 CommitDate: Fri Jan 1 14:06:22 2021 +0000
6 URL: https://gitweb.gentoo.org/proj/pax-utils.git/commit/?id=8a389efb
7
8 scanmacho: add support for dumping UUIDs
9
10 Add flag -U/--uuid to dump the object's UUID.
11
12 (This is in particular useful when comparing against TextAPI stubs,
13 .tbd files.)
14
15 Signed-off-by: Fabian Groffen <grobian <AT> gentoo.org>
16
17 macho.h | 6 ++++++
18 scanmacho.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++------
19 2 files changed, 56 insertions(+), 6 deletions(-)
20
21 diff --git a/macho.h b/macho.h
22 index 7457473..79da151 100644
23 --- a/macho.h
24 +++ b/macho.h
25 @@ -258,6 +258,12 @@ struct rpath_command {
26 union lc_str path;
27 };
28
29 +struct uuid_command {
30 + uint32_t cmd;
31 + uint32_t cmdsize;
32 + uint8_t uuid[16];
33 +};
34 +
35 struct fat_header
36 {
37 uint32_t magic;
38
39 diff --git a/scanmacho.c b/scanmacho.c
40 index 71b1593..e2aa485 100644
41 --- a/scanmacho.c
42 +++ b/scanmacho.c
43 @@ -1,12 +1,12 @@
44 /*
45 - * Copyright 2008-2012 Gentoo Foundation
46 + * Copyright 2008-2021 Gentoo Foundation
47 * Distributed under the terms of the GNU General Public License v2
48 *
49 * based on scanelf by:
50 * Copyright 2003-2012 Ned Ludd - <solar@g.o>
51 * Copyright 2004-2012 Mike Frysinger - <vapier@g.o>
52 * for Darwin specific fun:
53 - * 2008-2013 Fabian Groffen - <grobian@g.o>
54 + * 2008-2021 Fabian Groffen - <grobian@g.o>
55 */
56
57 const char argv0[] = "scanmacho";
58 @@ -37,6 +37,7 @@ static char show_rpath = 0;
59 static char show_needed = 0;
60 static char show_interp = 0;
61 static char show_bind = 0;
62 +static char show_uuid = 0;
63 static char show_soname = 0;
64 static char show_banner = 1;
65 static char show_endian = 0;
66 @@ -181,18 +182,54 @@ static char *macho_file_soname(fatobj *fobj, char *found_soname)
67 return NULL;
68 }
69
70 +static char *macho_file_uuid(fatobj *fobj, char *found_uuid)
71 +{
72 + loadcmd *lcmd;
73 + uint32_t lc_uuid;
74 + static char uuid_buf[32 + 4 + 1];
75 +
76 + if (!show_uuid)
77 + return NULL;
78 +
79 + lcmd = firstloadcmd(fobj);
80 + lc_uuid = MGET(fobj->swapped, LC_UUID);
81 +
82 + do {
83 + if (lcmd->lcmd->cmd == lc_uuid) {
84 + struct uuid_command *ucmd = lcmd->data;
85 + unsigned char *uuid;
86 + uuid = (unsigned char *)(ucmd->uuid);
87 + *found_uuid = 1;
88 + free(lcmd);
89 + if (be_wewy_wewy_quiet)
90 + return NULL;
91 + snprintf(uuid_buf, sizeof(uuid_buf),
92 + "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
93 + "%02x%02x%02x%02x%02x%02x",
94 + uuid[0], uuid[1], uuid[2], uuid[3],
95 + uuid[4], uuid[5],
96 + uuid[6], uuid[7],
97 + uuid[8], uuid[9],
98 + uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
99 + return uuid_buf;
100 + }
101 + } while (nextloadcmd(lcmd));
102 +
103 + return NULL;
104 +}
105 +
106 /* scan a macho file and show all the fun stuff */
107 #define prints(str) ({ ssize_t ret = write(fileno(stdout), str, strlen(str)); ret; })
108 static int scanmacho_fatobj(fatobj *fobj)
109 {
110 unsigned long i;
111 char found_rpath, found_needed, found_interp, found_soname,
112 - found_lib, found_file;
113 + found_lib, found_file, found_uuid;
114 static char *out_buffer = NULL;
115 static size_t out_len;
116
117 found_rpath = found_needed = found_interp = found_soname = \
118 - found_lib = found_file = 0;
119 + found_lib = found_file = found_uuid = 0;
120
121 if (be_verbose > 2)
122 printf("%s: scanning file {%s,%s}\n", fobj->filename,
123 @@ -228,6 +265,7 @@ static int scanmacho_fatobj(fatobj *fobj)
124 case 'b': prints("FLAGS "); break;
125 case 'Z': prints("SIZE "); break;
126 case 'S': prints("INSTALLNAME "); break;
127 + case 'U': prints("UUID "); break;
128 case 'N': prints("LIB "); break;
129 case 'a': prints("ARCH "); break;
130 case 'O': prints("PERM "); break;
131 @@ -293,6 +331,7 @@ static int scanmacho_fatobj(fatobj *fobj)
132 case 'i': out = macho_file_interp(fobj, &found_interp); break;
133 case 'b': get_machomhflags(fobj, &out_buffer, &out_len); break;
134 case 'S': out = macho_file_soname(fobj, &found_soname); break;
135 + case 'U': out = macho_file_uuid(fobj, &found_uuid); break;
136 case 'a': out = get_machomtype(fobj); break;
137 case 'Z': snprintf(ubuf, sizeof(ubuf), "%llu", (unsigned long long int)fobj->len); out = ubuf; break;;
138 default: warnf("'%c' has no scan code?", out_format[i]);
139 @@ -532,8 +571,8 @@ static void scanmacho_envpath(void)
140 free(path);
141 }
142
143 -/* usage / invocation handling functions */ /* Free Flags: c d e j k l s t u w x z G H I J K L P Q T U W X Y */
144 -#define PARSE_FLAGS "pRmyArnibSN:gE:M:DO:ZaqvF:f:o:CBhV"
145 +/* usage / invocation handling functions */ /* Free Flags: c d e j k l s t u w x z G H I J K L P Q T W X Y */
146 +#define PARSE_FLAGS "pRmyArnibSUN:gE:M:DO:ZaqvF:f:o:CBhV"
147 #define a_argument required_argument
148 static struct option const long_opts[] = {
149 {"path", no_argument, NULL, 'p'},
150 @@ -546,6 +585,7 @@ static struct option const long_opts[] = {
151 {"interp", no_argument, NULL, 'i'},
152 {"bind", no_argument, NULL, 'b'},
153 {"soname", no_argument, NULL, 'S'},
154 + {"uuid", no_argument, NULL, 'U'},
155 {"lib", a_argument, NULL, 'N'},
156 {"gmatch", no_argument, NULL, 'g'},
157 {"etype", a_argument, NULL, 'E'},
158 @@ -577,6 +617,7 @@ static const char * const opts_help[] = {
159 "Print LC_LOAD_DYLINKER information (ELF: INTERP)",
160 "Print flags from mach_header (ELF: BIND)",
161 "Print LC_ID_DYLIB information (ELF: SONAME)",
162 + "Print LC_UUID information",
163 "Find a specified library",
164 "Use strncmp to match libraries. (use with -N)",
165 "Print only Mach-O files matching mach_header\n"
166 @@ -678,6 +719,7 @@ static int parseargs(int argc, char *argv[])
167 case 'i': show_interp = 1; break;
168 case 'b': show_bind = 1; break;
169 case 'S': show_soname = 1; break;
170 + case 'U': show_uuid = 1; break;
171 case 'q': be_quiet = 1; break;
172 case 'v': be_verbose = (be_verbose % 20) + 1; break;
173 case 'a': show_perms = show_endian = show_bind = 1; break;
174 @@ -717,6 +759,7 @@ static int parseargs(int argc, char *argv[])
175 case 'i': show_interp = 1; break;
176 case 'b': show_bind = 1; break;
177 case 'S': show_soname = 1; break;
178 + case 'U': show_uuid = 1; break;
179 default:
180 err("Invalid format specifier '%c' (byte %i)",
181 out_format[i], i+1);
182 @@ -738,6 +781,7 @@ static int parseargs(int argc, char *argv[])
183 if (show_interp) xstrcat(&out_format, "%i ", &fmt_len);
184 if (show_bind) xstrcat(&out_format, "%b ", &fmt_len);
185 if (show_soname) xstrcat(&out_format, "%S ", &fmt_len);
186 + if (show_uuid) xstrcat(&out_format, "%U ", &fmt_len);
187 if (find_lib) xstrcat(&out_format, "%N ", &fmt_len);
188 if (!be_quiet) xstrcat(&out_format, "%F ", &fmt_len);
189 }