Print this page
10138 smatch fixes for usr/src/cmd/sgs
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/sgs/libelf/common/ar.c
+++ new/usr/src/cmd/sgs/libelf/common/ar.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
21 21
22 22 /*
23 23 * Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 26 /*
27 27 * Copyright (c) 1988 AT&T
28 28 * All Rights Reserved
29 29 */
30 30
31 +/*
32 + * Copyright (c) 2018, Joyent, Inc.
33 + */
34 +
31 35 #include <ar.h>
32 36 #include <stdlib.h>
33 37 #include <memory.h>
34 38 #include <errno.h>
35 39 #include <libelf.h>
36 40 #include "decl.h"
37 41 #include "msg.h"
38 42 #include "member.h"
39 43
40 44 #define MANGLE '\177'
41 45
42 46
43 47 /*
44 48 * Archive processing
45 49 * When processing an archive member, two things can happen
46 50 * that are a little tricky.
47 51 *
48 52 * Sliding
49 53 * Sliding support is left in for backward compatibility and for
50 54 * support of Archives produced on other systems. The bundled
51 55 * ar(1) produces archives with all members on a 4 byte boundry,
52 56 * so current archives should need no sliding.
53 57 *
54 58 * Archive members that are only 2-byte aligned within the file will
55 59 * be slid. To reuse the file's memory image, the library slides an
56 60 * archive member into its header to align the bytes. This means
57 61 * the header must be disposable.
58 62 *
59 63 * Header reuse
60 64 * Because the library can trample the header, it must be preserved to
61 65 * avoid restrictions on archive member reuse. That is, if the member
62 66 * header changes, the library may see garbage the next time it looks
63 67 * at the header. After extracting the original header, the library
64 68 * appends it to the parents `ed_memlist' list, thus future lookups first
65 69 * check this list to determine if a member has previously been processed
66 70 * and whether sliding occured.
67 71 */
68 72
69 73
70 74 /*
71 75 * Size check
72 76 * If the header is too small, the following generates a negative
73 77 * subscript for x.x and fails to compile.
74 78 *
75 79 * The check is based on sizeof (Elf64) because that's always going
76 80 * to be at least as big as Elf32.
77 81 */
78 82
79 83 struct x
80 84 {
81 85 char x[sizeof (struct ar_hdr) - 3 * sizeof (Elf64) - 1];
82 86 };
83 87
84 88
85 89
86 90 static const char fmag[] = ARFMAG;
87 91
88 92
89 93 /*
90 94 * Convert a string starting at 'p' and ending at 'end' into
91 95 * an integer. Base is the base of the number being converted
92 96 * (either 8 or 10).
93 97 *
94 98 * Returns the converted integer of the string being scaned.
95 99 */
96 100 unsigned long
97 101 _elf_number(char *p, char *end, int base)
98 102 {
99 103 register unsigned c;
100 104 register unsigned long n = 0;
101 105
102 106 while (p < end) {
103 107 if ((c = *p - '0') >= base) {
104 108 while (*p++ == ' ')
105 109 if (p >= end)
106 110 return (n);
107 111 return (0);
108 112 }
109 113 n *= base;
110 114 n += c;
111 115 ++p;
112 116 }
113 117 return (n);
114 118 }
115 119
116 120
117 121 /*
118 122 * Convert ar_hdr to Member
119 123 * Converts ascii file representation to the binary memory values.
120 124 */
121 125 Member *
122 126 _elf_armem(Elf *elf, char *file, size_t fsz)
123 127 {
124 128 register struct ar_hdr *f = (struct ar_hdr *)file;
125 129 register Member *m;
126 130 register Memlist *l, * ol;
127 131 register Memident *i;
128 132
129 133 if (fsz < sizeof (struct ar_hdr)) {
130 134 _elf_seterr(EFMT_ARHDRSZ, 0);
131 135 return (0);
132 136 }
133 137
134 138 /*
135 139 * Determine in this member has already been processed
136 140 */
137 141 for (l = elf->ed_memlist, ol = l; l; ol = l, l = l->m_next)
138 142 for (i = (Memident *)(l + 1); i < l->m_free; i++)
139 143 if (i->m_offset == file)
140 144 return (i->m_member);
141 145
142 146 if (f->ar_fmag[0] != fmag[0] || f->ar_fmag[1] != fmag[1]) {
143 147 _elf_seterr(EFMT_ARFMAG, 0);
144 148 return (0);
145 149 }
146 150
147 151 /*
148 152 * Allocate a new member structure and assign it to the next free
↓ open down ↓ |
108 lines elided |
↑ open up ↑ |
149 153 * free memlist ident.
150 154 */
151 155 if ((m = (Member *)malloc(sizeof (Member))) == 0) {
152 156 _elf_seterr(EMEM_ARMEM, errno);
153 157 return (0);
154 158 }
155 159 if ((elf->ed_memlist == 0) || (ol->m_free == ol->m_end)) {
156 160 if ((l = (Memlist *)malloc(sizeof (Memlist) +
157 161 (sizeof (Memident) * MEMIDENTNO))) == 0) {
158 162 _elf_seterr(EMEM_ARMEM, errno);
163 + free(m);
159 164 return (0);
160 165 }
161 166 l->m_next = 0;
162 167 l->m_free = (Memident *)(l + 1);
163 168 l->m_end = (Memident *)((uintptr_t)l->m_free +
164 169 (sizeof (Memident) * MEMIDENTNO));
165 170
166 171 if (elf->ed_memlist == 0)
167 172 elf->ed_memlist = l;
168 173 else
169 174 ol->m_next = l;
170 175 ol = l;
171 176 }
172 177 ol->m_free->m_offset = file;
173 178 ol->m_free->m_member = m;
174 179 ol->m_free++;
175 180
176 181 m->m_err = 0;
177 182 (void) memcpy(m->m_name, f->ar_name, ARSZ(ar_name));
178 183 m->m_name[ARSZ(ar_name)] = '\0';
179 184 m->m_hdr.ar_name = m->m_name;
180 185 (void) memcpy(m->m_raw, f->ar_name, ARSZ(ar_name));
181 186 m->m_raw[ARSZ(ar_name)] = '\0';
182 187 m->m_hdr.ar_rawname = m->m_raw;
183 188 m->m_slide = 0;
184 189
185 190 /*
186 191 * Classify file name.
187 192 * If a name error occurs, delay until getarhdr().
188 193 */
189 194
190 195 if (f->ar_name[0] != '/') { /* regular name */
191 196 register char *p;
192 197
193 198 p = &m->m_name[sizeof (m->m_name)];
194 199 while (*--p != '/')
195 200 if (p <= m->m_name)
196 201 break;
197 202 *p = '\0';
198 203 } else if (f->ar_name[1] >= '0' && f->ar_name[1] <= '9') { /* strtab */
199 204 register unsigned long j;
200 205
201 206 j = _elf_number(&f->ar_name[1],
202 207 &f->ar_name[ARSZ(ar_name)], 10);
203 208 if (j < elf->ed_arstrsz)
204 209 m->m_hdr.ar_name = elf->ed_arstr + j;
205 210 else {
206 211 m->m_hdr.ar_name = 0;
207 212 /*LINTED*/ /* MSG_INTL(EFMT_ARSTRNM) */
208 213 m->m_err = (int)EFMT_ARSTRNM;
209 214 }
210 215 } else if (f->ar_name[1] == ' ') /* "/" */
211 216 m->m_name[1] = '\0';
212 217 else if (f->ar_name[1] == '/' && f->ar_name[2] == ' ') /* "//" */
213 218 m->m_name[2] = '\0';
214 219 else if (f->ar_name[1] == 'S' && f->ar_name[2] == 'Y' &&
215 220 f->ar_name[3] == 'M' && f->ar_name[4] == '6' &&
216 221 f->ar_name[5] == '4' && f->ar_name[6] == '/' &&
217 222 f->ar_name[7] == ' ') /* "/SYM64/" */
218 223 m->m_name[7] = '\0';
219 224 else { /* "/?" */
220 225 m->m_hdr.ar_name = 0;
221 226 /*LINTED*/ /* MSG_INTL(EFMT_ARUNKNM) */
222 227 m->m_err = (int)EFMT_ARUNKNM;
223 228 }
224 229
225 230 m->m_hdr.ar_date = (time_t)_elf_number(f->ar_date,
226 231 &f->ar_date[ARSZ(ar_date)], 10);
227 232 /* LINTED */
228 233 m->m_hdr.ar_uid = (uid_t)_elf_number(f->ar_uid,
229 234 &f->ar_uid[ARSZ(ar_uid)], 10);
230 235 /* LINTED */
231 236 m->m_hdr.ar_gid = (gid_t)_elf_number(f->ar_gid,
232 237 &f->ar_gid[ARSZ(ar_gid)], 10);
233 238 /* LINTED */
234 239 m->m_hdr.ar_mode = (mode_t)_elf_number(f->ar_mode,
235 240 &f->ar_mode[ARSZ(ar_mode)], 8);
236 241 m->m_hdr.ar_size = (off_t)_elf_number(f->ar_size,
237 242 &f->ar_size[ARSZ(ar_size)], 10);
238 243
239 244 return (m);
240 245 }
241 246
242 247
243 248 /*
244 249 * Initial archive processing
245 250 * An archive may have two special members.
246 251 *
247 252 * A symbol table, named / or /SYM64/, must be first if it is present.
248 253 * Both forms use the same layout differing in the width of the
249 254 * integer type used (32 or 64-bit respectively).
250 255 *
251 256 * A long name string table, named //, must precede all "normal"
252 257 * members. This string table is used to hold the names of archive
253 258 * members with names that are longer than 15 characters. It should not
254 259 * be confused with the string table found at the end of the symbol
255 260 * table, which is used to hold symbol names.
256 261 *
257 262 * This code "peeks" at headers but doesn't change them.
258 263 * Later processing wants original headers.
259 264 *
260 265 * String table is converted, changing '/' name terminators
261 266 * to nulls. The last byte in the string table, which should
262 267 * be '\n', is set to nil, guaranteeing null termination. That
263 268 * byte should be '\n', but this code doesn't check.
264 269 *
265 270 * The symbol table conversion is delayed until needed.
266 271 */
267 272 void
268 273 _elf_arinit(Elf * elf)
269 274 {
270 275 char *base = elf->ed_ident;
271 276 register char *end = base + elf->ed_fsz;
272 277 register struct ar_hdr *a;
273 278 register char *hdr = base + SARMAG;
274 279 register char *mem;
275 280 int j;
276 281 size_t sz = SARMAG;
277 282
278 283 elf->ed_status = ES_COOKED;
279 284 elf->ed_nextoff = SARMAG;
280 285 for (j = 0; j < 2; ++j) { /* 2 special members */
281 286 unsigned long n;
282 287
283 288 if (((end - hdr) < sizeof (struct ar_hdr)) ||
284 289 (_elf_vm(elf, (size_t)(SARMAG),
285 290 sizeof (struct ar_hdr)) != OK_YES))
286 291 return;
287 292
288 293 a = (struct ar_hdr *)hdr;
289 294 mem = (char *)a + sizeof (struct ar_hdr);
290 295 n = _elf_number(a->ar_size, &a->ar_size[ARSZ(ar_size)], 10);
291 296 if ((end - mem < n) || (a->ar_name[0] != '/') ||
292 297 ((sz = n) != n)) {
293 298 return;
294 299 }
295 300
296 301 hdr = mem + sz;
297 302 if (a->ar_name[1] == ' ') { /* 32-bit symbol table */
298 303 elf->ed_arsym = mem;
299 304 elf->ed_arsymsz = sz;
300 305 elf->ed_arsymoff = (char *)a - base;
301 306 } else if (a->ar_name[1] == '/' && a->ar_name[2] == ' ') {
302 307 /* Long name string table */
303 308 int k;
304 309
305 310 if (_elf_vm(elf, (size_t)(mem - elf->ed_ident),
306 311 sz) != OK_YES)
307 312 return;
308 313 if (elf->ed_vm == 0) {
309 314 char *nmem;
310 315 if ((nmem = malloc(sz)) == 0) {
311 316 _elf_seterr(EMEM_ARSTR, errno);
312 317 return;
313 318 }
314 319 (void) memcpy(nmem, mem, sz);
315 320 elf->ed_myflags |= EDF_ASTRALLOC;
316 321 mem = nmem;
317 322 }
318 323
319 324 elf->ed_arstr = mem;
320 325 elf->ed_arstrsz = sz;
321 326 elf->ed_arstroff = (char *)a - base;
322 327 for (k = 0; k < sz; k++) {
323 328 if (*mem == '/')
324 329 *mem = '\0';
325 330 ++mem;
326 331 }
327 332 *(mem - 1) = '\0';
328 333 } else if (a->ar_name[1] == 'S' && a->ar_name[2] == 'Y' &&
329 334 a->ar_name[3] == 'M' && a->ar_name[4] == '6' &&
330 335 a->ar_name[5] == '4' && a->ar_name[6] == '/' &&
331 336 a->ar_name[7] == ' ') {
332 337 /* 64-bit symbol table */
333 338 elf->ed_arsym = mem;
334 339 elf->ed_arsymsz = sz;
335 340 elf->ed_arsymoff = (char *)a - base;
336 341 elf->ed_myflags |= EDF_ARSYM64;
337 342 } else {
338 343 return;
339 344 }
340 345 hdr += sz & 1;
341 346 }
342 347 }
↓ open down ↓ |
174 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX