diff --git a/ctf_encoder.c b/ctf_encoder.c index 3763415..825cfa2 100644 --- a/ctf_encoder.c +++ b/ctf_encoder.c @@ -138,7 +138,7 @@ static int subroutine_type__encode(struct tag *self, uint16_t core_id, int64_t position; struct ftype *ftype = tag__ftype(self); int ctf_id = ctf__add_function_type(ctf, self->type, ftype->nr_parms, - &position); + ftype->unspec_parms, &position); if (ctf_id < 0 || tag__check_id_drift(self, core_id, ctf_id)) return -1; diff --git a/ctf_loader.c b/ctf_loader.c index 6734d0a..5d071fe 100644 --- a/ctf_loader.c +++ b/ctf_loader.c @@ -469,11 +469,17 @@ static int create_new_subroutine_type(struct ctf_state *sp, void *ptr, INIT_LIST_HEAD(&self->lexblock.tags); for (i = 0; i < vlen; i++) { - struct parameter *p = tag__alloc(sizeof(*p)); + uint16_t type = ctf__get16(sp->ctf, &args[i]); - p->tag.tag = DW_TAG_formal_parameter; - p->tag.type = ctf__get16(sp->ctf, &args[i]); - ftype__add_parameter(&self->proto, p); + if (type == 0) + self->proto.unspec_parms = 1; + else { + struct parameter *p = tag__alloc(sizeof(*p)); + + p->tag.tag = DW_TAG_formal_parameter; + p->tag.type = ctf__get16(sp->ctf, &args[i]); + ftype__add_parameter(&self->proto, p); + } } vlen *= sizeof(*args); diff --git a/libctf.c b/libctf.c index 85378e8..e8fd2c8 100644 --- a/libctf.c +++ b/libctf.c @@ -297,10 +297,10 @@ void ctf__add_parameter(struct ctf *self, uint16_t type, int64_t *position) } int ctf__add_function_type(struct ctf *self, uint16_t type, uint16_t nr_parms, - int64_t *position) + bool varargs, int64_t *position) { struct ctf_short_type t; - int len = sizeof(uint16_t) * nr_parms; + int len = sizeof(uint16_t) * (nr_parms + !!varargs); /* * Round up to next multiple of 4 to maintain 32-bit alignment. @@ -309,11 +309,18 @@ int ctf__add_function_type(struct ctf *self, uint16_t type, uint16_t nr_parms, len += 0x2; t.ctf_name = 0; - t.ctf_info = CTF_INFO_ENCODE(CTF_TYPE_KIND_FUNC, nr_parms, 0); + t.ctf_info = CTF_INFO_ENCODE(CTF_TYPE_KIND_FUNC, + nr_parms + !!varargs, 0); t.ctf_type = type; gobuffer__add(&self->types, &t, sizeof(t)); *position = gobuffer__allocate(&self->types, len); + if (varargs) { + unsigned int pos = *position + (nr_parms * sizeof(uint16_t)); + uint16_t *end_of_args = gobuffer__ptr(&self->types, pos); + *end_of_args = 0; + } + return ++self->type_index; } diff --git a/libctf.h b/libctf.h index 9f168fc..62c21b8 100644 --- a/libctf.h +++ b/libctf.h @@ -30,7 +30,7 @@ int ctf__add_array(struct ctf *self, uint16_t type, uint16_t index_type, uint32_t nelems); void ctf__add_parameter(struct ctf *self, uint16_t type, int64_t *position); int ctf__add_function_type(struct ctf *self, uint16_t type, - uint16_t nr_parameters, int64_t *position); + uint16_t nr_parms, bool varargs, int64_t *position); int ctf__add_enumeration_type(struct ctf *self, uint32_t name, uint16_t nr_entries, int64_t *position); void ctf__add_enumerator(struct ctf *self, uint32_t name, uint32_t value,