|
Lines 30-37
Link Here
|
| 30 |
#include <sys/types.h> |
30 |
#include <sys/types.h> |
| 31 |
#include <stdio.h> |
31 |
#include <stdio.h> |
| 32 |
#include <stdlib.h> |
32 |
#include <stdlib.h> |
|
|
33 |
#include <fcntl.h> |
| 33 |
#include <strings.h> |
34 |
#include <strings.h> |
| 34 |
#include <ctype.h> |
35 |
#include <ctype.h> |
|
|
36 |
#include <unistd.h> |
| 35 |
#include <zlib.h> |
37 |
#include <zlib.h> |
| 36 |
#include <elf.h> |
38 |
#include <elf.h> |
| 37 |
|
39 |
|
|
Lines 52-57
Link Here
|
| 52 |
#define CTF_BUF_CHUNK_SIZE (64 * 1024) |
54 |
#define CTF_BUF_CHUNK_SIZE (64 * 1024) |
| 53 |
#define RES_BUF_CHUNK_SIZE (64 * 1024) |
55 |
#define RES_BUF_CHUNK_SIZE (64 * 1024) |
| 54 |
|
56 |
|
|
|
57 |
#define SPEC_BUF_SIZE 1024 |
| 58 |
#define SPEC_MAX_FIELDS 16 |
| 59 |
|
| 55 |
struct ctf_buf { |
60 |
struct ctf_buf { |
| 56 |
strtab_t ctb_strtab; /* string table */ |
61 |
strtab_t ctb_strtab; /* string table */ |
| 57 |
caddr_t ctb_base; /* pointer to base of buffer */ |
62 |
caddr_t ctb_base; /* pointer to base of buffer */ |
|
Lines 73-79
Link Here
|
| 73 |
#define SWAP_32(x) (x) = BSWAP_32(x) |
78 |
#define SWAP_32(x) (x) = BSWAP_32(x) |
| 74 |
|
79 |
|
| 75 |
static int target_requires_swap; |
80 |
static int target_requires_swap; |
|
|
81 |
static int compactPresentation; |
| 76 |
|
82 |
|
|
|
83 |
/* |
| 84 |
* In order to prevent frequent small-size allocation |
| 85 |
* we keep pre-allocated scratch-pad that should be used for |
| 86 |
* converting host representation to target one |
| 87 |
*/ |
| 88 |
struct ctf_struct_spec { |
| 89 |
size_t size; /* structure size */ |
| 90 |
size_t field_offset[SPEC_MAX_FIELDS]; /* Offsets for fields */ |
| 91 |
char *scratchpad; /* memory area of size bytes */ |
| 92 |
}; |
| 93 |
|
| 94 |
typedef enum { |
| 95 |
CTF_SPEC_STYPE = 0, |
| 96 |
CTF_SPEC_TYPE, |
| 97 |
CTF_SPEC_ARRAY, |
| 98 |
CTF_SPEC_MEMBER, |
| 99 |
CTF_SPEC_LMEMBER, |
| 100 |
CTF_SPEC_ENUM, |
| 101 |
CTF_SPEC_MAX, |
| 102 |
} ctf_spec_type_t; |
| 103 |
|
| 104 |
static const char* ctf_spec_type_name[] = |
| 105 |
{ |
| 106 |
"ctf_stype_t", |
| 107 |
"ctf_type_t", |
| 108 |
"ctf_array_t", |
| 109 |
"ctf_member_t", |
| 110 |
"ctf_lmember_t", |
| 111 |
"ctf_enum_t" |
| 112 |
}; |
| 113 |
|
| 114 |
static struct ctf_struct_spec target_specs[CTF_SPEC_MAX]; |
| 115 |
static uint_t ctf_spec_mask = 0; |
| 116 |
|
| 77 |
/*PRINTFLIKE1*/ |
117 |
/*PRINTFLIKE1*/ |
| 78 |
static void |
118 |
static void |
| 79 |
parseterminate(const char *fmt, ...) |
119 |
parseterminate(const char *fmt, ...) |
|
Lines 142-147
Link Here
|
| 142 |
} |
182 |
} |
| 143 |
} |
183 |
} |
| 144 |
|
184 |
|
|
|
185 |
static void |
| 186 |
ctf_scratchpad_reset(ctf_spec_type_t t) |
| 187 |
{ |
| 188 |
|
| 189 |
bzero(target_specs[t].scratchpad, target_specs[t].size); |
| 190 |
} |
| 191 |
|
| 192 |
static void |
| 193 |
ctf_scratchpad_write(ctf_spec_type_t t, int field, void const *p, size_t n) |
| 194 |
{ |
| 195 |
size_t offset = target_specs[t].field_offset[field]; |
| 196 |
|
| 197 |
if (offset + n > target_specs[t].size) |
| 198 |
terminate("Can't write outside scratchpad, type %s, field %d", |
| 199 |
ctf_spec_type_name[t]); |
| 200 |
|
| 201 |
bcopy(p, target_specs[t].scratchpad + offset, n); |
| 202 |
} |
| 203 |
|
| 204 |
static void |
| 205 |
ctf_scratchpad_flush(ctf_buf_t *b, ctf_spec_type_t t) |
| 206 |
{ |
| 207 |
|
| 208 |
ctf_buf_write(b, target_specs[t].scratchpad, target_specs[t].size); |
| 209 |
} |
| 210 |
|
| 145 |
static int |
211 |
static int |
| 146 |
write_label(void *arg1, void *arg2) |
212 |
write_label(void *arg1, void *arg2) |
| 147 |
{ |
213 |
{ |
|
Lines 167-178
Link Here
|
| 167 |
{ |
233 |
{ |
| 168 |
ushort_t id = (idp ? idp->ii_dtype->t_id : 0); |
234 |
ushort_t id = (idp ? idp->ii_dtype->t_id : 0); |
| 169 |
|
235 |
|
| 170 |
ctf_buf_write(b, &id, sizeof (id)); |
|
|
| 171 |
|
236 |
|
| 172 |
if (target_requires_swap) { |
237 |
if (target_requires_swap) { |
| 173 |
SWAP_16(id); |
238 |
SWAP_16(id); |
| 174 |
} |
239 |
} |
| 175 |
|
240 |
|
|
|
241 |
ctf_buf_write(b, &id, sizeof (id)); |
| 242 |
|
| 176 |
debug(3, "Wrote object %s (%d)\n", (idp ? idp->ii_name : "(null)"), id); |
243 |
debug(3, "Wrote object %s (%d)\n", (idp ? idp->ii_name : "(null)"), id); |
| 177 |
} |
244 |
} |
| 178 |
|
245 |
|
|
Lines 227-232
Link Here
|
| 227 |
debug(3, "Wrote function %s (%d args)\n", idp->ii_name, nargs); |
294 |
debug(3, "Wrote function %s (%d args)\n", idp->ii_name, nargs); |
| 228 |
} |
295 |
} |
| 229 |
|
296 |
|
|
|
297 |
static void |
| 298 |
write_unsized_type_rec(ctf_buf_t *b, ctf_type_t *ctt) |
| 299 |
{ |
| 300 |
ctf_stype_t *cts = (ctf_stype_t *)ctt; |
| 301 |
|
| 302 |
if (target_requires_swap) { |
| 303 |
SWAP_32(cts->ctt_name); |
| 304 |
SWAP_16(cts->ctt_info); |
| 305 |
SWAP_16(cts->ctt_size); |
| 306 |
} |
| 307 |
|
| 308 |
/* XXXCROSS 1 */ |
| 309 |
if (compactPresentation) { |
| 310 |
ctf_scratchpad_reset(CTF_SPEC_STYPE); |
| 311 |
ctf_scratchpad_write(CTF_SPEC_STYPE, 0, |
| 312 |
&cts->ctt_name, sizeof(cts->ctt_name)); |
| 313 |
ctf_scratchpad_write(CTF_SPEC_STYPE, 1, |
| 314 |
&cts->ctt_info, sizeof(cts->ctt_info)); |
| 315 |
ctf_scratchpad_write(CTF_SPEC_STYPE, 2, |
| 316 |
&cts->ctt_size, sizeof(cts->ctt_size)); |
| 317 |
ctf_scratchpad_flush(b, CTF_SPEC_STYPE); |
| 318 |
} else |
| 319 |
ctf_buf_write(b, cts, sizeof (*cts)); |
| 320 |
} |
| 321 |
|
| 230 |
/* |
322 |
/* |
| 231 |
* Depending on the size of the type being described, either a ctf_stype_t (for |
323 |
* Depending on the size of the type being described, either a ctf_stype_t (for |
| 232 |
* types with size < CTF_LSTRUCT_THRESH) or a ctf_type_t (all others) will be |
324 |
* types with size < CTF_LSTRUCT_THRESH) or a ctf_type_t (all others) will be |
|
Lines 247-253
Link Here
|
| 247 |
SWAP_32(ctt->ctt_lsizehi); |
339 |
SWAP_32(ctt->ctt_lsizehi); |
| 248 |
SWAP_32(ctt->ctt_lsizelo); |
340 |
SWAP_32(ctt->ctt_lsizelo); |
| 249 |
} |
341 |
} |
| 250 |
ctf_buf_write(b, ctt, sizeof (*ctt)); |
342 |
/* XXXCROSS 1 */ |
|
|
343 |
if (compactPresentation) { |
| 344 |
ctf_scratchpad_reset(CTF_SPEC_TYPE); |
| 345 |
ctf_scratchpad_write(CTF_SPEC_TYPE, 0, |
| 346 |
&ctt->ctt_name, sizeof(ctt->ctt_name)); |
| 347 |
ctf_scratchpad_write(CTF_SPEC_TYPE, 1, |
| 348 |
&ctt->ctt_info, sizeof(ctt->ctt_info)); |
| 349 |
ctf_scratchpad_write(CTF_SPEC_TYPE, 2, |
| 350 |
&ctt->ctt_size, sizeof(ctt->ctt_size)); |
| 351 |
ctf_scratchpad_write(CTF_SPEC_TYPE, 3, |
| 352 |
&ctt->ctt_lsizehi, sizeof(ctt->ctt_lsizehi)); |
| 353 |
ctf_scratchpad_write(CTF_SPEC_TYPE, 4, |
| 354 |
&ctt->ctt_lsizelo, sizeof(ctt->ctt_lsizelo)); |
| 355 |
ctf_scratchpad_flush(b, CTF_SPEC_TYPE); |
| 356 |
|
| 357 |
} else |
| 358 |
ctf_buf_write(b, ctt, sizeof (*ctt)); |
| 251 |
} else { |
359 |
} else { |
| 252 |
ctf_stype_t *cts = (ctf_stype_t *)ctt; |
360 |
ctf_stype_t *cts = (ctf_stype_t *)ctt; |
| 253 |
|
361 |
|
|
Lines 259-282
Link Here
|
| 259 |
SWAP_16(cts->ctt_size); |
367 |
SWAP_16(cts->ctt_size); |
| 260 |
} |
368 |
} |
| 261 |
|
369 |
|
| 262 |
ctf_buf_write(b, cts, sizeof (*cts)); |
370 |
write_unsized_type_rec(b, ctt); |
| 263 |
} |
371 |
} |
| 264 |
} |
372 |
} |
| 265 |
|
373 |
|
| 266 |
static void |
|
|
| 267 |
write_unsized_type_rec(ctf_buf_t *b, ctf_type_t *ctt) |
| 268 |
{ |
| 269 |
ctf_stype_t *cts = (ctf_stype_t *)ctt; |
| 270 |
|
| 271 |
if (target_requires_swap) { |
| 272 |
SWAP_32(cts->ctt_name); |
| 273 |
SWAP_16(cts->ctt_info); |
| 274 |
SWAP_16(cts->ctt_size); |
| 275 |
} |
| 276 |
|
| 277 |
ctf_buf_write(b, cts, sizeof (*cts)); |
| 278 |
} |
| 279 |
|
| 280 |
static int |
374 |
static int |
| 281 |
write_type(void *arg1, void *arg2) |
375 |
write_type(void *arg1, void *arg2) |
| 282 |
{ |
376 |
{ |
|
Lines 372-378
Link Here
|
| 372 |
SWAP_16(cta.cta_index); |
466 |
SWAP_16(cta.cta_index); |
| 373 |
SWAP_32(cta.cta_nelems); |
467 |
SWAP_32(cta.cta_nelems); |
| 374 |
} |
468 |
} |
| 375 |
ctf_buf_write(b, &cta, sizeof (cta)); |
469 |
/* XXXCROSS 1 */ |
|
|
470 |
if (compactPresentation) { |
| 471 |
ctf_scratchpad_reset(CTF_SPEC_ARRAY); |
| 472 |
ctf_scratchpad_write(CTF_SPEC_ARRAY, 0, |
| 473 |
&cta.cta_contents, sizeof(cta.cta_contents)); |
| 474 |
ctf_scratchpad_write(CTF_SPEC_ARRAY, 1, |
| 475 |
&cta.cta_index, sizeof(cta.cta_index)); |
| 476 |
ctf_scratchpad_write(CTF_SPEC_ARRAY, 2, |
| 477 |
&cta.cta_nelems, sizeof(cta.cta_nelems)); |
| 478 |
ctf_scratchpad_flush(b, CTF_SPEC_ARRAY); |
| 479 |
} |
| 480 |
else |
| 481 |
ctf_buf_write(b, &cta, sizeof (cta)); |
| 482 |
|
| 376 |
break; |
483 |
break; |
| 377 |
|
484 |
|
| 378 |
case STRUCT: |
485 |
case STRUCT: |
|
Lines 406-412
Link Here
|
| 406 |
SWAP_16(ctm.ctm_type); |
513 |
SWAP_16(ctm.ctm_type); |
| 407 |
SWAP_16(ctm.ctm_offset); |
514 |
SWAP_16(ctm.ctm_offset); |
| 408 |
} |
515 |
} |
| 409 |
ctf_buf_write(b, &ctm, sizeof (ctm)); |
516 |
|
|
|
517 |
/* XXXCROSS 1 */ |
| 518 |
if (compactPresentation) { |
| 519 |
ctf_scratchpad_reset(CTF_SPEC_MEMBER); |
| 520 |
ctf_scratchpad_write(CTF_SPEC_MEMBER, 0, |
| 521 |
&ctm.ctm_name, sizeof(ctm.ctm_name)); |
| 522 |
ctf_scratchpad_write(CTF_SPEC_MEMBER, 1, |
| 523 |
&ctm.ctm_type, sizeof(ctm.ctm_type)); |
| 524 |
ctf_scratchpad_write(CTF_SPEC_MEMBER, 2, |
| 525 |
&ctm.ctm_offset, sizeof(ctm.ctm_offset)); |
| 526 |
ctf_scratchpad_flush(b, CTF_SPEC_MEMBER); |
| 527 |
} |
| 528 |
else |
| 529 |
ctf_buf_write(b, &ctm, sizeof (ctm)); |
| 410 |
} |
530 |
} |
| 411 |
} else { |
531 |
} else { |
| 412 |
for (mp = tp->t_members; mp != NULL; mp = mp->ml_next) { |
532 |
for (mp = tp->t_members; mp != NULL; mp = mp->ml_next) { |
|
Lines 428-434
Link Here
|
| 428 |
SWAP_32(ctlm.ctlm_offsetlo); |
548 |
SWAP_32(ctlm.ctlm_offsetlo); |
| 429 |
} |
549 |
} |
| 430 |
|
550 |
|
| 431 |
ctf_buf_write(b, &ctlm, sizeof (ctlm)); |
551 |
/* XXXCROSS 1 */ |
|
|
552 |
if (compactPresentation) { |
| 553 |
ctf_scratchpad_reset(CTF_SPEC_LMEMBER); |
| 554 |
ctf_scratchpad_write(CTF_SPEC_LMEMBER, 0, |
| 555 |
&ctlm.ctlm_name, sizeof(ctlm.ctlm_name)); |
| 556 |
ctf_scratchpad_write(CTF_SPEC_LMEMBER, 1, |
| 557 |
&ctlm.ctlm_type, sizeof(ctlm.ctlm_type)); |
| 558 |
ctf_scratchpad_write(CTF_SPEC_LMEMBER, 2, |
| 559 |
&ctlm.ctlm_offsethi, sizeof(ctlm.ctlm_offsethi)); |
| 560 |
ctf_scratchpad_write(CTF_SPEC_LMEMBER, 3, |
| 561 |
&ctlm.ctlm_offsetlo, sizeof(ctlm.ctlm_offsetlo)); |
| 562 |
ctf_scratchpad_flush(b, CTF_SPEC_LMEMBER); |
| 563 |
} |
| 564 |
else |
| 565 |
ctf_buf_write(b, &ctlm, sizeof (ctlm)); |
| 566 |
|
| 432 |
} |
567 |
} |
| 433 |
} |
568 |
} |
| 434 |
break; |
569 |
break; |
|
Lines 456-462
Link Here
|
| 456 |
SWAP_32(cte.cte_value); |
591 |
SWAP_32(cte.cte_value); |
| 457 |
} |
592 |
} |
| 458 |
|
593 |
|
| 459 |
ctf_buf_write(b, &cte, sizeof (cte)); |
594 |
/* XXXCROSS 1 */ |
|
|
595 |
if (compactPresentation) { |
| 596 |
ctf_scratchpad_reset(CTF_SPEC_ENUM); |
| 597 |
ctf_scratchpad_write(CTF_SPEC_ENUM, 0, |
| 598 |
&cte.cte_name, sizeof(cte.cte_name)); |
| 599 |
ctf_scratchpad_write(CTF_SPEC_ENUM, 1, |
| 600 |
&cte.cte_value, sizeof(cte.cte_value)); |
| 601 |
ctf_scratchpad_flush(b, CTF_SPEC_ENUM); |
| 602 |
|
| 603 |
} |
| 604 |
else |
| 605 |
ctf_buf_write(b, &cte, sizeof (cte)); |
| 460 |
i--; |
606 |
i--; |
| 461 |
} |
607 |
} |
| 462 |
break; |
608 |
break; |
|
Lines 1299-1304
Link Here
|
| 1299 |
return (td); |
1445 |
return (td); |
| 1300 |
} |
1446 |
} |
| 1301 |
|
1447 |
|
|
|
1448 |
static ctf_spec_type_t |
| 1449 |
type_by_name(char *name) |
| 1450 |
{ |
| 1451 |
int i; |
| 1452 |
|
| 1453 |
for (i = 0; i < CTF_SPEC_MAX; i++) { |
| 1454 |
if (streq(ctf_spec_type_name[i], name)) |
| 1455 |
break; |
| 1456 |
} |
| 1457 |
|
| 1458 |
return (i); |
| 1459 |
} |
| 1460 |
|
| 1461 |
static void |
| 1462 |
parse_spec_line(char *line) |
| 1463 |
{ |
| 1464 |
char *ptr; |
| 1465 |
int got_type, got_size; |
| 1466 |
int field; |
| 1467 |
ctf_spec_type_t ctf_type = CTF_SPEC_MAX; |
| 1468 |
|
| 1469 |
field = got_type = got_size = 0; |
| 1470 |
for (ptr = strtok(line, ":"); ptr; ptr = strtok(NULL, ":")) |
| 1471 |
{ |
| 1472 |
if (!got_type) { |
| 1473 |
ctf_type = type_by_name(ptr); |
| 1474 |
if (ctf_type == CTF_SPEC_MAX) |
| 1475 |
terminate("%s: unknown type in spec", ptr); |
| 1476 |
got_type = 1; |
| 1477 |
} else if (!got_size) { |
| 1478 |
target_specs[ctf_type].size = atoi(ptr); |
| 1479 |
got_size = 1; |
| 1480 |
} else |
| 1481 |
target_specs[ctf_type].field_offset[field++] = atoi(ptr); |
| 1482 |
} |
| 1483 |
|
| 1484 |
if (ctf_type == CTF_SPEC_MAX) |
| 1485 |
terminate("internal error\n"); |
| 1486 |
|
| 1487 |
if (target_specs[ctf_type].size == 0) |
| 1488 |
terminate("%s: structure size is zero", ctf_spec_type_name[ctf_type]); |
| 1489 |
|
| 1490 |
target_specs[ctf_type].scratchpad = xcalloc(target_specs[ctf_type].size); |
| 1491 |
|
| 1492 |
debug(3, "Spec: Type %s, size: %d, fields: %d\n", ctf_spec_type_name[ctf_type], |
| 1493 |
target_specs[ctf_type].size, field); |
| 1494 |
|
| 1495 |
return; |
| 1496 |
} |
| 1497 |
|
| 1498 |
int |
| 1499 |
ctf_load_target_spec(char *file) |
| 1500 |
{ |
| 1501 |
int fd; |
| 1502 |
char *buf; |
| 1503 |
int bytes; |
| 1504 |
char *line; |
| 1505 |
int i, j; |
| 1506 |
|
| 1507 |
if ((buf = xcalloc(SPEC_BUF_SIZE)) == NULL) |
| 1508 |
terminate("%s: Cannot allocate buffer for reading spec", file); |
| 1509 |
|
| 1510 |
if ((line = xcalloc(SPEC_BUF_SIZE)) == NULL) |
| 1511 |
terminate("%s: Cannot allocate buffer for reading spec", file); |
| 1512 |
|
| 1513 |
if ((fd = open(file, O_RDONLY)) < 0) |
| 1514 |
terminate("%s: Cannot open for reading", file); |
| 1515 |
|
| 1516 |
j = 0; |
| 1517 |
while ((bytes = read(fd, buf, SPEC_BUF_SIZE)) > 0) { |
| 1518 |
for (i = 0; i < bytes; i++) { |
| 1519 |
if (buf[i] == '\n') { |
| 1520 |
/* |
| 1521 |
* Parse line |
| 1522 |
*/ |
| 1523 |
line[j++] = 0; |
| 1524 |
parse_spec_line(line); |
| 1525 |
|
| 1526 |
/* |
| 1527 |
* Reset line |
| 1528 |
*/ |
| 1529 |
j = 0; |
| 1530 |
bzero(line, SPEC_BUF_SIZE); |
| 1531 |
continue; |
| 1532 |
} |
| 1533 |
|
| 1534 |
if (!isspace(buf[i])) |
| 1535 |
line[j++] = buf[i]; |
| 1536 |
} |
| 1537 |
} |
| 1538 |
|
| 1539 |
compactPresentation = 1; |
| 1540 |
ctf_spec_mask = 1; |
| 1541 |
|
| 1542 |
free(buf); |
| 1543 |
free(line); |
| 1544 |
close(fd); |
| 1545 |
|
| 1546 |
return (0); |
| 1547 |
} |
| 1548 |
|
| 1302 |
static size_t |
1549 |
static size_t |
| 1303 |
decompress_ctf(caddr_t cbuf, size_t cbufsz, caddr_t dbuf, size_t dbufsz) |
1550 |
decompress_ctf(caddr_t cbuf, size_t cbufsz, caddr_t dbuf, size_t dbufsz) |
| 1304 |
{ |
1551 |
{ |