Deleted Added
full compact
ctf_create.c (178526) ctf_create.c (254744)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *

--- 10 unchanged lines hidden (view full) ---

19 *
20 * CDDL HEADER END
21 */
22
23/*
24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *

--- 10 unchanged lines hidden (view full) ---

19 *
20 * CDDL HEADER END
21 */
22
23/*
24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
26 */
27/*
28 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
29 */
27
30
28#pragma ident "%Z%%M% %I% %E% SMI"
29
30#include <sys/sysmacros.h>
31#include <sys/param.h>
32#include <sys/mman.h>
33#include <ctf_impl.h>
31#include <sys/sysmacros.h>
32#include <sys/param.h>
33#include <sys/mman.h>
34#include <ctf_impl.h>
35#include <sys/debug.h>
34
35/*
36 * This static string is used as the template for initially populating a
37 * dynamic container's string table. We always store \0 in the first byte,
38 * and we use the generic string "PARENT" to mark this container's parent
39 * if one is associated with the container using ctf_import().
40 */
41static const char _CTF_STRTAB_TEMPLATE[] = "\0PARENT";

--- 120 unchanged lines hidden (view full) ---

162 bcopy(dmd->dmd_name, s, len);
163 s += len;
164 }
165
166 return (s);
167}
168
169/*
36
37/*
38 * This static string is used as the template for initially populating a
39 * dynamic container's string table. We always store \0 in the first byte,
40 * and we use the generic string "PARENT" to mark this container's parent
41 * if one is associated with the container using ctf_import().
42 */
43static const char _CTF_STRTAB_TEMPLATE[] = "\0PARENT";

--- 120 unchanged lines hidden (view full) ---

164 bcopy(dmd->dmd_name, s, len);
165 s += len;
166 }
167
168 return (s);
169}
170
171/*
172 * Only types of dyanmic CTF containers contain reference counts. These
173 * containers are marked RD/WR. Because of that we basically make this a no-op
174 * for compatability with non-dynamic CTF sections. This is also a no-op for
175 * types which are not dynamic types. It is the responsibility of the caller to
176 * make sure it is a valid type. We help that caller out on debug builds.
177 *
178 * Note that the reference counts are not maintained for types that are not
179 * within this container. In other words if we have a type in a parent, that
180 * will not have its reference count increased. On the flip side, the parent
181 * will not be allowed to remove dynamic types if it has children.
182 */
183static void
184ctf_ref_inc(ctf_file_t *fp, ctf_id_t tid)
185{
186 ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, tid);
187
188 if (dtd == NULL)
189 return;
190
191 if (!(fp->ctf_flags & LCTF_RDWR))
192 return;
193
194 dtd->dtd_ref++;
195}
196
197/*
198 * Just as with ctf_ref_inc, this is a no-op on non-writeable containers and the
199 * caller should ensure that this is already a valid type.
200 */
201static void
202ctf_ref_dec(ctf_file_t *fp, ctf_id_t tid)
203{
204 ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, tid);
205
206 if (dtd == NULL)
207 return;
208
209 if (!(fp->ctf_flags & LCTF_RDWR))
210 return;
211
212 ASSERT(dtd->dtd_ref >= 1);
213 dtd->dtd_ref--;
214}
215
216/*
170 * If the specified CTF container is writable and has been modified, reload
171 * this container with the updated type definitions. In order to make this
172 * code and the rest of libctf as simple as possible, we perform updates by
173 * taking the dynamic type definitions and creating an in-memory CTF file
174 * containing the definitions, and then call ctf_bufopen() on it. This not
175 * only leverages ctf_bufopen(), but also avoids having to bifurcate the rest
176 * of the library code with different lookup paths for static and dynamic
177 * type definitions. We are therefore optimizing greatly for lookup over
178 * update, which we assume will be an uncommon operation. We perform one
179 * extra trick here for the benefit of callers and to keep our code simple:
180 * ctf_bufopen() will return a new ctf_file_t, but we want to keep the fp
181 * constant for the caller, so after ctf_bufopen() returns, we use bcopy to
182 * swap the interior of the old and new ctf_file_t's, and then free the old.
217 * If the specified CTF container is writable and has been modified, reload
218 * this container with the updated type definitions. In order to make this
219 * code and the rest of libctf as simple as possible, we perform updates by
220 * taking the dynamic type definitions and creating an in-memory CTF file
221 * containing the definitions, and then call ctf_bufopen() on it. This not
222 * only leverages ctf_bufopen(), but also avoids having to bifurcate the rest
223 * of the library code with different lookup paths for static and dynamic
224 * type definitions. We are therefore optimizing greatly for lookup over
225 * update, which we assume will be an uncommon operation. We perform one
226 * extra trick here for the benefit of callers and to keep our code simple:
227 * ctf_bufopen() will return a new ctf_file_t, but we want to keep the fp
228 * constant for the caller, so after ctf_bufopen() returns, we use bcopy to
229 * swap the interior of the old and new ctf_file_t's, and then free the old.
230 *
231 * Note that the lists of dynamic types stays around and the resulting container
232 * is still writeable. Furthermore, the reference counts that are on the dtd's
233 * are still valid.
183 */
184int
185ctf_update(ctf_file_t *fp)
186{
187 ctf_file_t ofp, *nfp;
188 ctf_header_t hdr;
189 ctf_dtdef_t *dtd;
190 ctf_sect_t cts;

--- 236 unchanged lines hidden (view full) ---

427
428void
429ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd)
430{
431 ulong_t h = dtd->dtd_type & (fp->ctf_dthashlen - 1);
432 ctf_dtdef_t *p, **q = &fp->ctf_dthash[h];
433 ctf_dmdef_t *dmd, *nmd;
434 size_t len;
234 */
235int
236ctf_update(ctf_file_t *fp)
237{
238 ctf_file_t ofp, *nfp;
239 ctf_header_t hdr;
240 ctf_dtdef_t *dtd;
241 ctf_sect_t cts;

--- 236 unchanged lines hidden (view full) ---

478
479void
480ctf_dtd_delete(ctf_file_t *fp, ctf_dtdef_t *dtd)
481{
482 ulong_t h = dtd->dtd_type & (fp->ctf_dthashlen - 1);
483 ctf_dtdef_t *p, **q = &fp->ctf_dthash[h];
484 ctf_dmdef_t *dmd, *nmd;
485 size_t len;
486 int kind, i;
435
436 for (p = *q; p != NULL; p = p->dtd_hash) {
437 if (p != dtd)
438 q = &p->dtd_hash;
439 else
440 break;
441 }
442
443 if (p != NULL)
444 *q = p->dtd_hash;
445
487
488 for (p = *q; p != NULL; p = p->dtd_hash) {
489 if (p != dtd)
490 q = &p->dtd_hash;
491 else
492 break;
493 }
494
495 if (p != NULL)
496 *q = p->dtd_hash;
497
446 switch (CTF_INFO_KIND(dtd->dtd_data.ctt_info)) {
498 kind = CTF_INFO_KIND(dtd->dtd_data.ctt_info);
499 switch (kind) {
447 case CTF_K_STRUCT:
448 case CTF_K_UNION:
449 case CTF_K_ENUM:
450 for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
451 dmd != NULL; dmd = nmd) {
452 if (dmd->dmd_name != NULL) {
453 len = strlen(dmd->dmd_name) + 1;
454 ctf_free(dmd->dmd_name, len);
455 fp->ctf_dtstrlen -= len;
456 }
500 case CTF_K_STRUCT:
501 case CTF_K_UNION:
502 case CTF_K_ENUM:
503 for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
504 dmd != NULL; dmd = nmd) {
505 if (dmd->dmd_name != NULL) {
506 len = strlen(dmd->dmd_name) + 1;
507 ctf_free(dmd->dmd_name, len);
508 fp->ctf_dtstrlen -= len;
509 }
510 if (kind != CTF_K_ENUM)
511 ctf_ref_dec(fp, dmd->dmd_type);
457 nmd = ctf_list_next(dmd);
458 ctf_free(dmd, sizeof (ctf_dmdef_t));
459 }
460 break;
461 case CTF_K_FUNCTION:
512 nmd = ctf_list_next(dmd);
513 ctf_free(dmd, sizeof (ctf_dmdef_t));
514 }
515 break;
516 case CTF_K_FUNCTION:
517 ctf_ref_dec(fp, dtd->dtd_data.ctt_type);
518 for (i = 0; i < CTF_INFO_VLEN(dtd->dtd_data.ctt_info); i++)
519 if (dtd->dtd_u.dtu_argv[i] != 0)
520 ctf_ref_dec(fp, dtd->dtd_u.dtu_argv[i]);
462 ctf_free(dtd->dtd_u.dtu_argv, sizeof (ctf_id_t) *
463 CTF_INFO_VLEN(dtd->dtd_data.ctt_info));
464 break;
521 ctf_free(dtd->dtd_u.dtu_argv, sizeof (ctf_id_t) *
522 CTF_INFO_VLEN(dtd->dtd_data.ctt_info));
523 break;
524 case CTF_K_ARRAY:
525 ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_contents);
526 ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_index);
527 break;
528 case CTF_K_TYPEDEF:
529 ctf_ref_dec(fp, dtd->dtd_data.ctt_type);
530 break;
531 case CTF_K_POINTER:
532 case CTF_K_VOLATILE:
533 case CTF_K_CONST:
534 case CTF_K_RESTRICT:
535 ctf_ref_dec(fp, dtd->dtd_data.ctt_type);
536 break;
465 }
466
467 if (dtd->dtd_name) {
468 len = strlen(dtd->dtd_name) + 1;
469 ctf_free(dtd->dtd_name, len);
470 fp->ctf_dtstrlen -= len;
471 }
472

--- 17 unchanged lines hidden (view full) ---

490
491 return (dtd);
492}
493
494/*
495 * Discard all of the dynamic type definitions that have been added to the
496 * container since the last call to ctf_update(). We locate such types by
497 * scanning the list and deleting elements that have type IDs greater than
537 }
538
539 if (dtd->dtd_name) {
540 len = strlen(dtd->dtd_name) + 1;
541 ctf_free(dtd->dtd_name, len);
542 fp->ctf_dtstrlen -= len;
543 }
544

--- 17 unchanged lines hidden (view full) ---

562
563 return (dtd);
564}
565
566/*
567 * Discard all of the dynamic type definitions that have been added to the
568 * container since the last call to ctf_update(). We locate such types by
569 * scanning the list and deleting elements that have type IDs greater than
498 * ctf_dtoldid, which is set by ctf_update(), above.
570 * ctf_dtoldid, which is set by ctf_update(), above. Note that to work properly
571 * with our reference counting schemes, we must delete the dynamic list in
572 * reverse.
499 */
500int
501ctf_discard(ctf_file_t *fp)
502{
503 ctf_dtdef_t *dtd, *ntd;
504
505 if (!(fp->ctf_flags & LCTF_RDWR))
506 return (ctf_set_errno(fp, ECTF_RDONLY));
507
508 if (!(fp->ctf_flags & LCTF_DIRTY))
509 return (0); /* no update required */
510
573 */
574int
575ctf_discard(ctf_file_t *fp)
576{
577 ctf_dtdef_t *dtd, *ntd;
578
579 if (!(fp->ctf_flags & LCTF_RDWR))
580 return (ctf_set_errno(fp, ECTF_RDONLY));
581
582 if (!(fp->ctf_flags & LCTF_DIRTY))
583 return (0); /* no update required */
584
511 for (dtd = ctf_list_next(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
585 for (dtd = ctf_list_prev(&fp->ctf_dtdefs); dtd != NULL; dtd = ntd) {
512 if (dtd->dtd_type <= fp->ctf_dtoldid)
513 continue; /* skip types that have been committed */
514
586 if (dtd->dtd_type <= fp->ctf_dtoldid)
587 continue; /* skip types that have been committed */
588
515 ntd = ctf_list_next(dtd);
589 ntd = ctf_list_prev(dtd);
516 ctf_dtd_delete(fp, dtd);
517 }
518
519 fp->ctf_dtnextid = fp->ctf_dtoldid + 1;
520 fp->ctf_flags &= ~LCTF_DIRTY;
521
522 return (0);
523}

--- 85 unchanged lines hidden (view full) ---

609 ctf_id_t type;
610
611 if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE)
612 return (ctf_set_errno(fp, EINVAL));
613
614 if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR)
615 return (CTF_ERR); /* errno is set for us */
616
590 ctf_dtd_delete(fp, dtd);
591 }
592
593 fp->ctf_dtnextid = fp->ctf_dtoldid + 1;
594 fp->ctf_flags &= ~LCTF_DIRTY;
595
596 return (0);
597}

--- 85 unchanged lines hidden (view full) ---

683 ctf_id_t type;
684
685 if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE)
686 return (ctf_set_errno(fp, EINVAL));
687
688 if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR)
689 return (CTF_ERR); /* errno is set for us */
690
691 ctf_ref_inc(fp, ref);
692
617 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, 0);
618 dtd->dtd_data.ctt_type = (ushort_t)ref;
619
620 return (type);
621}
622
623ctf_id_t
624ctf_add_integer(ctf_file_t *fp, uint_t flag,

--- 15 unchanged lines hidden (view full) ---

640 return (ctf_add_reftype(fp, flag, ref, CTF_K_POINTER));
641}
642
643ctf_id_t
644ctf_add_array(ctf_file_t *fp, uint_t flag, const ctf_arinfo_t *arp)
645{
646 ctf_dtdef_t *dtd;
647 ctf_id_t type;
693 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, flag, 0);
694 dtd->dtd_data.ctt_type = (ushort_t)ref;
695
696 return (type);
697}
698
699ctf_id_t
700ctf_add_integer(ctf_file_t *fp, uint_t flag,

--- 15 unchanged lines hidden (view full) ---

716 return (ctf_add_reftype(fp, flag, ref, CTF_K_POINTER));
717}
718
719ctf_id_t
720ctf_add_array(ctf_file_t *fp, uint_t flag, const ctf_arinfo_t *arp)
721{
722 ctf_dtdef_t *dtd;
723 ctf_id_t type;
724 ctf_file_t *fpd;
648
649 if (arp == NULL)
650 return (ctf_set_errno(fp, EINVAL));
651
725
726 if (arp == NULL)
727 return (ctf_set_errno(fp, EINVAL));
728
729 fpd = fp;
730 if (ctf_lookup_by_id(&fpd, arp->ctr_contents) == NULL &&
731 ctf_dtd_lookup(fp, arp->ctr_contents) == NULL)
732 return (ctf_set_errno(fp, ECTF_BADID));
733
734 fpd = fp;
735 if (ctf_lookup_by_id(&fpd, arp->ctr_index) == NULL &&
736 ctf_dtd_lookup(fp, arp->ctr_index) == NULL)
737 return (ctf_set_errno(fp, ECTF_BADID));
738
652 if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR)
653 return (CTF_ERR); /* errno is set for us */
654
655 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ARRAY, flag, 0);
656 dtd->dtd_data.ctt_size = 0;
657 dtd->dtd_u.dtu_arr = *arp;
739 if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR)
740 return (CTF_ERR); /* errno is set for us */
741
742 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_ARRAY, flag, 0);
743 dtd->dtd_data.ctt_size = 0;
744 dtd->dtd_u.dtu_arr = *arp;
745 ctf_ref_inc(fp, arp->ctr_contents);
746 ctf_ref_inc(fp, arp->ctr_index);
658
659 return (type);
660}
661
662int
663ctf_set_array(ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
664{
747
748 return (type);
749}
750
751int
752ctf_set_array(ctf_file_t *fp, ctf_id_t type, const ctf_arinfo_t *arp)
753{
754 ctf_file_t *fpd;
665 ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, type);
666
667 if (!(fp->ctf_flags & LCTF_RDWR))
668 return (ctf_set_errno(fp, ECTF_RDONLY));
669
670 if (dtd == NULL || CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
671 return (ctf_set_errno(fp, ECTF_BADID));
672
755 ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, type);
756
757 if (!(fp->ctf_flags & LCTF_RDWR))
758 return (ctf_set_errno(fp, ECTF_RDONLY));
759
760 if (dtd == NULL || CTF_INFO_KIND(dtd->dtd_data.ctt_info) != CTF_K_ARRAY)
761 return (ctf_set_errno(fp, ECTF_BADID));
762
763 fpd = fp;
764 if (ctf_lookup_by_id(&fpd, arp->ctr_contents) == NULL &&
765 ctf_dtd_lookup(fp, arp->ctr_contents) == NULL)
766 return (ctf_set_errno(fp, ECTF_BADID));
767
768 fpd = fp;
769 if (ctf_lookup_by_id(&fpd, arp->ctr_index) == NULL &&
770 ctf_dtd_lookup(fp, arp->ctr_index) == NULL)
771 return (ctf_set_errno(fp, ECTF_BADID));
772
773 ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_contents);
774 ctf_ref_dec(fp, dtd->dtd_u.dtu_arr.ctr_index);
673 fp->ctf_flags |= LCTF_DIRTY;
674 dtd->dtd_u.dtu_arr = *arp;
775 fp->ctf_flags |= LCTF_DIRTY;
776 dtd->dtd_u.dtu_arr = *arp;
777 ctf_ref_inc(fp, arp->ctr_contents);
778 ctf_ref_inc(fp, arp->ctr_index);
675
676 return (0);
677}
678
679ctf_id_t
680ctf_add_function(ctf_file_t *fp, uint_t flag,
681 const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
682{
683 ctf_dtdef_t *dtd;
684 ctf_id_t type;
685 uint_t vlen;
779
780 return (0);
781}
782
783ctf_id_t
784ctf_add_function(ctf_file_t *fp, uint_t flag,
785 const ctf_funcinfo_t *ctc, const ctf_id_t *argv)
786{
787 ctf_dtdef_t *dtd;
788 ctf_id_t type;
789 uint_t vlen;
790 int i;
686 ctf_id_t *vdat = NULL;
791 ctf_id_t *vdat = NULL;
792 ctf_file_t *fpd;
687
688 if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0 ||
689 (ctc->ctc_argc != 0 && argv == NULL))
690 return (ctf_set_errno(fp, EINVAL));
691
692 vlen = ctc->ctc_argc;
693 if (ctc->ctc_flags & CTF_FUNC_VARARG)
694 vlen++; /* add trailing zero to indicate varargs (see below) */
695
696 if (vlen > CTF_MAX_VLEN)
697 return (ctf_set_errno(fp, EOVERFLOW));
698
793
794 if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0 ||
795 (ctc->ctc_argc != 0 && argv == NULL))
796 return (ctf_set_errno(fp, EINVAL));
797
798 vlen = ctc->ctc_argc;
799 if (ctc->ctc_flags & CTF_FUNC_VARARG)
800 vlen++; /* add trailing zero to indicate varargs (see below) */
801
802 if (vlen > CTF_MAX_VLEN)
803 return (ctf_set_errno(fp, EOVERFLOW));
804
805 fpd = fp;
806 if (ctf_lookup_by_id(&fpd, ctc->ctc_return) == NULL &&
807 ctf_dtd_lookup(fp, ctc->ctc_return) == NULL)
808 return (ctf_set_errno(fp, ECTF_BADID));
809
810 for (i = 0; i < ctc->ctc_argc; i++) {
811 fpd = fp;
812 if (ctf_lookup_by_id(&fpd, argv[i]) == NULL &&
813 ctf_dtd_lookup(fp, argv[i]) == NULL)
814 return (ctf_set_errno(fp, ECTF_BADID));
815 }
816
699 if (vlen != 0 && (vdat = ctf_alloc(sizeof (ctf_id_t) * vlen)) == NULL)
700 return (ctf_set_errno(fp, EAGAIN));
701
702 if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR) {
703 ctf_free(vdat, sizeof (ctf_id_t) * vlen);
704 return (CTF_ERR); /* errno is set for us */
705 }
706
707 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_FUNCTION, flag, vlen);
708 dtd->dtd_data.ctt_type = (ushort_t)ctc->ctc_return;
709
817 if (vlen != 0 && (vdat = ctf_alloc(sizeof (ctf_id_t) * vlen)) == NULL)
818 return (ctf_set_errno(fp, EAGAIN));
819
820 if ((type = ctf_add_generic(fp, flag, NULL, &dtd)) == CTF_ERR) {
821 ctf_free(vdat, sizeof (ctf_id_t) * vlen);
822 return (CTF_ERR); /* errno is set for us */
823 }
824
825 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_FUNCTION, flag, vlen);
826 dtd->dtd_data.ctt_type = (ushort_t)ctc->ctc_return;
827
828 ctf_ref_inc(fp, ctc->ctc_return);
829 for (i = 0; i < ctc->ctc_argc; i++)
830 ctf_ref_inc(fp, argv[i]);
831
710 bcopy(argv, vdat, sizeof (ctf_id_t) * ctc->ctc_argc);
711 if (ctc->ctc_flags & CTF_FUNC_VARARG)
712 vdat[vlen - 1] = 0; /* add trailing zero to indicate varargs */
713 dtd->dtd_u.dtu_argv = vdat;
714
715 return (type);
716}
717

--- 102 unchanged lines hidden (view full) ---

820 return (type);
821}
822
823ctf_id_t
824ctf_add_typedef(ctf_file_t *fp, uint_t flag, const char *name, ctf_id_t ref)
825{
826 ctf_dtdef_t *dtd;
827 ctf_id_t type;
832 bcopy(argv, vdat, sizeof (ctf_id_t) * ctc->ctc_argc);
833 if (ctc->ctc_flags & CTF_FUNC_VARARG)
834 vdat[vlen - 1] = 0; /* add trailing zero to indicate varargs */
835 dtd->dtd_u.dtu_argv = vdat;
836
837 return (type);
838}
839

--- 102 unchanged lines hidden (view full) ---

942 return (type);
943}
944
945ctf_id_t
946ctf_add_typedef(ctf_file_t *fp, uint_t flag, const char *name, ctf_id_t ref)
947{
948 ctf_dtdef_t *dtd;
949 ctf_id_t type;
950 ctf_file_t *fpd;
828
951
829 if (ref == CTF_ERR || ref < 0 || ref > CTF_MAX_TYPE)
952 fpd = fp;
953 if (ref == CTF_ERR || (ctf_lookup_by_id(&fpd, ref) == NULL &&
954 ctf_dtd_lookup(fp, ref) == NULL))
830 return (ctf_set_errno(fp, EINVAL));
831
832 if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
833 return (CTF_ERR); /* errno is set for us */
834
835 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_TYPEDEF, flag, 0);
836 dtd->dtd_data.ctt_type = (ushort_t)ref;
955 return (ctf_set_errno(fp, EINVAL));
956
957 if ((type = ctf_add_generic(fp, flag, name, &dtd)) == CTF_ERR)
958 return (CTF_ERR); /* errno is set for us */
959
960 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(CTF_K_TYPEDEF, flag, 0);
961 dtd->dtd_data.ctt_type = (ushort_t)ref;
962 ctf_ref_inc(fp, ref);
837
838 return (type);
839}
840
841ctf_id_t
842ctf_add_volatile(ctf_file_t *fp, uint_t flag, ctf_id_t ref)
843{
844 return (ctf_add_reftype(fp, flag, ref, CTF_K_VOLATILE));

--- 158 unchanged lines hidden (view full) ---

1003 dtd->dtd_data.ctt_size = (ushort_t)ssize;
1004
1005 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1);
1006 ctf_list_append(&dtd->dtd_u.dtu_members, dmd);
1007
1008 if (s != NULL)
1009 fp->ctf_dtstrlen += strlen(s) + 1;
1010
963
964 return (type);
965}
966
967ctf_id_t
968ctf_add_volatile(ctf_file_t *fp, uint_t flag, ctf_id_t ref)
969{
970 return (ctf_add_reftype(fp, flag, ref, CTF_K_VOLATILE));

--- 158 unchanged lines hidden (view full) ---

1129 dtd->dtd_data.ctt_size = (ushort_t)ssize;
1130
1131 dtd->dtd_data.ctt_info = CTF_TYPE_INFO(kind, root, vlen + 1);
1132 ctf_list_append(&dtd->dtd_u.dtu_members, dmd);
1133
1134 if (s != NULL)
1135 fp->ctf_dtstrlen += strlen(s) + 1;
1136
1137 ctf_ref_inc(fp, type);
1011 fp->ctf_flags |= LCTF_DIRTY;
1012 return (0);
1013}
1014
1138 fp->ctf_flags |= LCTF_DIRTY;
1139 return (0);
1140}
1141
1142/*
1143 * This removes a type from the dynamic section. This will fail if the type is
1144 * referenced by another type. Note that the CTF ID is never reused currently by
1145 * CTF. Note that if this container is a parent container then we just outright
1146 * refuse to remove the type. There currently is no notion of searching for the
1147 * ctf_dtdef_t in parent containers. If there is, then this constraint could
1148 * become finer grained.
1149 */
1150int
1151ctf_delete_type(ctf_file_t *fp, ctf_id_t type)
1152{
1153 ctf_file_t *fpd;
1154 ctf_dtdef_t *dtd = ctf_dtd_lookup(fp, type);
1155
1156 if (!(fp->ctf_flags & LCTF_RDWR))
1157 return (ctf_set_errno(fp, ECTF_RDONLY));
1158
1159 /*
1160 * We want to give as useful an errno as possible. That means that we
1161 * want to distinguish between a type which does not exist and one for
1162 * which the type is not dynamic.
1163 */
1164 fpd = fp;
1165 if (ctf_lookup_by_id(&fpd, type) == NULL &&
1166 ctf_dtd_lookup(fp, type) == NULL)
1167 return (CTF_ERR); /* errno is set for us */
1168
1169 if (dtd == NULL)
1170 return (ctf_set_errno(fp, ECTF_NOTDYN));
1171
1172 if (dtd->dtd_ref != 0 || fp->ctf_refcnt > 1)
1173 return (ctf_set_errno(fp, ECTF_REFERENCED));
1174
1175 ctf_dtd_delete(fp, dtd);
1176 fp->ctf_flags |= LCTF_DIRTY;
1177 return (0);
1178}
1179
1015static int
1016enumcmp(const char *name, int value, void *arg)
1017{
1018 ctf_bundle_t *ctb = arg;
1019 int bvalue;
1020
1021 return (ctf_enum_value(ctb->ctb_file, ctb->ctb_type,
1022 name, &bvalue) == CTF_ERR || value != bvalue);

--- 75 unchanged lines hidden (view full) ---

1098
1099 ctf_dtdef_t *dtd;
1100 ctf_funcinfo_t ctc;
1101 ssize_t size;
1102
1103 ctf_hash_t *hp;
1104 ctf_helem_t *hep;
1105
1180static int
1181enumcmp(const char *name, int value, void *arg)
1182{
1183 ctf_bundle_t *ctb = arg;
1184 int bvalue;
1185
1186 return (ctf_enum_value(ctb->ctb_file, ctb->ctb_type,
1187 name, &bvalue) == CTF_ERR || value != bvalue);

--- 75 unchanged lines hidden (view full) ---

1263
1264 ctf_dtdef_t *dtd;
1265 ctf_funcinfo_t ctc;
1266 ssize_t size;
1267
1268 ctf_hash_t *hp;
1269 ctf_helem_t *hep;
1270
1271 if (dst_fp == src_fp)
1272 return (src_type);
1273
1106 if (!(dst_fp->ctf_flags & LCTF_RDWR))
1107 return (ctf_set_errno(dst_fp, ECTF_RDONLY));
1108
1109 if ((tp = ctf_lookup_by_id(&src_fp, src_type)) == NULL)
1110 return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
1111
1112 name = ctf_strptr(src_fp, tp->ctt_name);
1113 kind = LCTF_INFO_KIND(src_fp, tp->ctt_info);

--- 194 unchanged lines hidden (view full) ---

1308 dmd != NULL; dmd = ctf_list_next(dmd)) {
1309 if ((dmd->dmd_type = ctf_add_type(dst_fp, src_fp,
1310 dmd->dmd_type)) == CTF_ERR)
1311 errs++;
1312 }
1313
1314 if (errs)
1315 return (CTF_ERR); /* errno is set for us */
1274 if (!(dst_fp->ctf_flags & LCTF_RDWR))
1275 return (ctf_set_errno(dst_fp, ECTF_RDONLY));
1276
1277 if ((tp = ctf_lookup_by_id(&src_fp, src_type)) == NULL)
1278 return (ctf_set_errno(dst_fp, ctf_errno(src_fp)));
1279
1280 name = ctf_strptr(src_fp, tp->ctt_name);
1281 kind = LCTF_INFO_KIND(src_fp, tp->ctt_info);

--- 194 unchanged lines hidden (view full) ---

1476 dmd != NULL; dmd = ctf_list_next(dmd)) {
1477 if ((dmd->dmd_type = ctf_add_type(dst_fp, src_fp,
1478 dmd->dmd_type)) == CTF_ERR)
1479 errs++;
1480 }
1481
1482 if (errs)
1483 return (CTF_ERR); /* errno is set for us */
1484
1485 /*
1486 * Now that we know that we can't fail, we go through and bump
1487 * all the reference counts on the member types.
1488 */
1489 for (dmd = ctf_list_next(&dtd->dtd_u.dtu_members);
1490 dmd != NULL; dmd = ctf_list_next(dmd))
1491 ctf_ref_inc(dst_fp, dmd->dmd_type);
1316 break;
1317 }
1318
1319 case CTF_K_ENUM:
1320 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
1321 if (ctf_enum_iter(src_fp, src_type, enumcmp, &dst) ||
1322 ctf_enum_iter(dst_fp, dst_type, enumcmp, &src))
1323 return (ctf_set_errno(dst_fp, ECTF_CONFLICT));

--- 43 unchanged lines hidden ---
1492 break;
1493 }
1494
1495 case CTF_K_ENUM:
1496 if (dst_type != CTF_ERR && dst_kind != CTF_K_FORWARD) {
1497 if (ctf_enum_iter(src_fp, src_type, enumcmp, &dst) ||
1498 ctf_enum_iter(dst_fp, dst_type, enumcmp, &src))
1499 return (ctf_set_errno(dst_fp, ECTF_CONFLICT));

--- 43 unchanged lines hidden ---