diff options
Diffstat (limited to 'libctf/ctf-create.c')
-rw-r--r-- | libctf/ctf-create.c | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/libctf/ctf-create.c b/libctf/ctf-create.c index 808da37..67a3f19 100644 --- a/libctf/ctf-create.c +++ b/libctf/ctf-create.c @@ -900,7 +900,7 @@ ctf_add_reftype (ctf_file_t *fp, uint32_t flag, ctf_id_t ref, uint32_t kind) if (ref == CTF_ERR || ref > CTF_MAX_TYPE) return (ctf_set_errno (fp, EINVAL)); - if (ctf_lookup_by_id (&tmp, ref) == NULL) + if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL) return CTF_ERR; /* errno is set for us. */ if ((type = ctf_add_generic (fp, flag, NULL, kind, &dtd)) == CTF_ERR) @@ -957,12 +957,13 @@ ctf_add_slice (ctf_file_t *fp, uint32_t flag, ctf_id_t ref, if (ref == CTF_ERR || ref > CTF_MAX_TYPE) return (ctf_set_errno (fp, EINVAL)); - if ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL) + if (ref != 0 && ((tp = ctf_lookup_by_id (&tmp, ref)) == NULL)) return CTF_ERR; /* errno is set for us. */ kind = ctf_type_kind_unsliced (tmp, ref); if ((kind != CTF_K_INTEGER) && (kind != CTF_K_FLOAT) && - (kind != CTF_K_ENUM)) + (kind != CTF_K_ENUM) + && (ref != 0)) return (ctf_set_errno (fp, ECTF_NOTINTFP)); if ((type = ctf_add_generic (fp, flag, NULL, CTF_K_SLICE, &dtd)) == CTF_ERR) @@ -1008,7 +1009,8 @@ ctf_add_array (ctf_file_t *fp, uint32_t flag, const ctf_arinfo_t *arp) if (arp == NULL) return (ctf_set_errno (fp, EINVAL)); - if (ctf_lookup_by_id (&tmp, arp->ctr_contents) == NULL) + if (arp->ctr_contents != 0 + && ctf_lookup_by_id (&tmp, arp->ctr_contents) == NULL) return CTF_ERR; /* errno is set for us. */ tmp = fp; @@ -1062,13 +1064,14 @@ ctf_add_function (ctf_file_t *fp, uint32_t flag, if (ctc->ctc_flags & CTF_FUNC_VARARG) vlen++; /* Add trailing zero to indicate varargs (see below). */ - if (ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL) + if (ctc->ctc_return != 0 + && ctf_lookup_by_id (&tmp, ctc->ctc_return) == NULL) return CTF_ERR; /* errno is set for us. */ for (i = 0; i < ctc->ctc_argc; i++) { tmp = fp; - if (ctf_lookup_by_id (&tmp, argv[i]) == NULL) + if (argv[i] != 0 && ctf_lookup_by_id (&tmp, argv[i]) == NULL) return CTF_ERR; /* errno is set for us. */ } @@ -1259,7 +1262,7 @@ ctf_add_typedef (ctf_file_t *fp, uint32_t flag, const char *name, if (ref == CTF_ERR || ref > CTF_MAX_TYPE) return (ctf_set_errno (fp, EINVAL)); - if (ctf_lookup_by_id (&tmp, ref) == NULL) + if (ref != 0 && ctf_lookup_by_id (&tmp, ref) == NULL) return CTF_ERR; /* errno is set for us. */ if ((type = ctf_add_generic (fp, flag, name, CTF_K_TYPEDEF, @@ -1387,7 +1390,20 @@ ctf_add_member_offset (ctf_file_t *fp, ctf_id_t souid, const char *name, if ((msize = ctf_type_size (fp, type)) < 0 || (malign = ctf_type_align (fp, type)) < 0) - return -1; /* errno is set for us. */ + { + /* The unimplemented type, and any type that resolves to it, has no size + and no alignment: it can correspond to any number of compiler-inserted + types. */ + + if (ctf_errno (fp) == ECTF_NONREPRESENTABLE) + { + msize = 0; + malign = 0; + ctf_set_errno (fp, 0); + } + else + return -1; /* errno is set for us. */ + } if ((dmd = malloc (sizeof (ctf_dmdef_t))) == NULL) return (ctf_set_errno (fp, EAGAIN)); @@ -1415,6 +1431,16 @@ ctf_add_member_offset (ctf_file_t *fp, ctf_id_t souid, const char *name, ctf_encoding_t linfo; ssize_t lsize; + /* Propagate any error from ctf_type_resolve. If the last member was + of unimplemented type, this may be -ECTF_NONREPRESENTABLE: we + cannot insert right after such a member without explicit offset + specification, because its alignment and size is not known. */ + if (ltype == CTF_ERR) + { + free (dmd); + return -1; /* errno is set for us. */ + } + if (ctf_type_encoding (fp, ltype, &linfo) == 0) off += linfo.cte_bits; else if ((lsize = ctf_type_size (fp, ltype)) > 0) |