break;
case STT_FUNC:
- if (funcoff >= hp->cth_typeoff)
+ if (funcoff >= hp->cth_objtidxoff)
{
*xp = -1u;
break;
hp->cth_stroff = oldhp->cth_stroff;
hp->cth_typeoff = oldhp->cth_typeoff;
hp->cth_varoff = oldhp->cth_varoff;
+ hp->cth_funcidxoff = hp->cth_varoff; /* No index sections. */
+ hp->cth_objtidxoff = hp->cth_funcidxoff;
hp->cth_funcoff = oldhp->cth_funcoff;
hp->cth_objtoff = oldhp->cth_objtoff;
hp->cth_lbloff = oldhp->cth_lbloff;
The upgrade is not done in-place: the ctf_base is moved. ctf_strptr() must
not be called before reallocation is complete.
+ Sections not checked here due to nonexistence or nonpopulated state in older
+ formats: objtidx, funcidx.
+
Type kinds not checked here due to nonexistence in older formats:
CTF_K_SLICE. */
static int
err = ctf_hash_define_type (fp->ctf_names, fp,
LCTF_INDEX_TO_TYPE (fp, id, child),
tp->ctt_name);
- if (err != 0 && err != ECTF_STRTAB)
+ if (err != 0)
return err;
}
break;
err = ctf_hash_insert_type (fp->ctf_names, fp,
LCTF_INDEX_TO_TYPE (fp, id, child),
tp->ctt_name);
- if (err != 0 && err != ECTF_STRTAB)
+ if (err != 0)
return err;
break;
LCTF_INDEX_TO_TYPE (fp, id, child),
tp->ctt_name);
- if (err != 0 && err != ECTF_STRTAB)
+ if (err != 0)
return err;
if (size >= CTF_LSTRUCT_THRESH)
LCTF_INDEX_TO_TYPE (fp, id, child),
tp->ctt_name);
- if (err != 0 && err != ECTF_STRTAB)
+ if (err != 0)
return err;
if (size >= CTF_LSTRUCT_THRESH)
LCTF_INDEX_TO_TYPE (fp, id, child),
tp->ctt_name);
- if (err != 0 && err != ECTF_STRTAB)
+ if (err != 0)
return err;
break;
err = ctf_hash_insert_type (fp->ctf_names, fp,
LCTF_INDEX_TO_TYPE (fp, id, child),
tp->ctt_name);
- if (err != 0 && err != ECTF_STRTAB)
+ if (err != 0)
return err;
break;
err = ctf_hash_insert_type (hp, fp,
LCTF_INDEX_TO_TYPE (fp, id, child),
tp->ctt_name);
- if (err != 0 && err != ECTF_STRTAB)
+ if (err != 0)
return err;
}
break;
err = ctf_hash_insert_type (fp->ctf_names, fp,
LCTF_INDEX_TO_TYPE (fp, id, child),
tp->ctt_name);
- if (err != 0 && err != ECTF_STRTAB)
+ if (err != 0)
return err;
break;
default:
swap_thing (cth->cth_cuname);
swap_thing (cth->cth_objtoff);
swap_thing (cth->cth_funcoff);
+ swap_thing (cth->cth_objtidxoff);
+ swap_thing (cth->cth_funcidxoff);
swap_thing (cth->cth_varoff);
swap_thing (cth->cth_typeoff);
swap_thing (cth->cth_stroff);
}
}
-/* Flip the endianness of the data-object or function sections, an array of
- uint32_t. (The function section has more internal structure, but that
- structure is an array of uint32_t, so can be treated as one big array for
- byte-swapping.) */
+/* Flip the endianness of the data-object or function sections or their indexes,
+ all arrays of uint32_t. (The function section has more internal structure,
+ but that structure is an array of uint32_t, so can be treated as one big
+ array for byte-swapping.) */
static void
flip_objts (void *start, size_t len)
{
flip_lbls (buf + cth->cth_lbloff, cth->cth_objtoff - cth->cth_lbloff);
flip_objts (buf + cth->cth_objtoff, cth->cth_funcoff - cth->cth_objtoff);
- flip_objts (buf + cth->cth_funcoff, cth->cth_varoff - cth->cth_funcoff);
+ flip_objts (buf + cth->cth_funcoff, cth->cth_objtidxoff - cth->cth_funcoff);
+ flip_objts (buf + cth->cth_objtidxoff, cth->cth_funcidxoff - cth->cth_objtidxoff);
+ flip_objts (buf + cth->cth_funcidxoff, cth->cth_varoff - cth->cth_funcidxoff);
flip_vars (buf + cth->cth_varoff, cth->cth_typeoff - cth->cth_varoff);
return flip_types (buf + cth->cth_typeoff, cth->cth_stroff - cth->cth_typeoff);
}
/* Open a CTF file, mocking up a suitable ctf_sect. */
+
ctf_file_t *ctf_simple_open (const char *ctfsect, size_t ctfsect_size,
const char *symsect, size_t symsect_size,
size_t symsect_entsize,
const char *strsect, size_t strsect_size,
int *errp)
+{
+ return ctf_simple_open_internal (ctfsect, ctfsect_size, symsect, symsect_size,
+ symsect_entsize, strsect, strsect_size, NULL,
+ errp);
+}
+
+/* Open a CTF file, mocking up a suitable ctf_sect and overriding the external
+ strtab with a synthetic one. */
+
+ctf_file_t *ctf_simple_open_internal (const char *ctfsect, size_t ctfsect_size,
+ const char *symsect, size_t symsect_size,
+ size_t symsect_entsize,
+ const char *strsect, size_t strsect_size,
+ ctf_dynhash_t *syn_strtab, int *errp)
{
ctf_sect_t skeleton;
strsectp = &str_sect;
}
- return ctf_bufopen (ctfsectp, symsectp, strsectp, errp);
+ return ctf_bufopen_internal (ctfsectp, symsectp, strsectp, syn_strtab, errp);
}
/* Decode the specified CTF buffer and optional symbol table, and create a new
ctf_file_t *
ctf_bufopen (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
const ctf_sect_t *strsect, int *errp)
+{
+ return ctf_bufopen_internal (ctfsect, symsect, strsect, NULL, errp);
+}
+
+/* Like ctf_bufopen, but overriding the external strtab with a synthetic one. */
+
+ctf_file_t *
+ctf_bufopen_internal (const ctf_sect_t *ctfsect, const ctf_sect_t *symsect,
+ const ctf_sect_t *strsect, ctf_dynhash_t *syn_strtab,
+ int *errp)
{
const ctf_preamble_t *pp;
size_t hdrsz = sizeof (ctf_header_t);
libctf_init_debug();
- if (ctfsect == NULL || ((symsect == NULL) != (strsect == NULL)))
+ if ((ctfsect == NULL) || ((symsect != NULL) &&
+ ((strsect == NULL) && syn_strtab == NULL)))
return (ctf_set_open_errno (errp, EINVAL));
if (symsect != NULL && symsect->cts_entsize != sizeof (Elf32_Sym) &&
if (foreign_endian)
flip_header (hp);
-
- ctf_dprintf ("header offsets: %x/%x/%x/%x/%x/%x/%x\n",
- hp->cth_lbloff, hp->cth_objtoff, hp->cth_funcoff,
- hp->cth_varoff, hp->cth_typeoff, hp->cth_stroff,
- hp->cth_strlen);
-
+ fp->ctf_openflags = hp->cth_flags;
fp->ctf_size = hp->cth_stroff + hp->cth_strlen;
ctf_dprintf ("ctf_bufopen: uncompressed size=%lu\n",
(unsigned long) fp->ctf_size);
if (hp->cth_lbloff > fp->ctf_size || hp->cth_objtoff > fp->ctf_size
- || hp->cth_funcoff > fp->ctf_size || hp->cth_typeoff > fp->ctf_size
+ || hp->cth_funcoff > fp->ctf_size || hp->cth_objtidxoff > fp->ctf_size
+ || hp->cth_funcidxoff > fp->ctf_size || hp->cth_typeoff > fp->ctf_size
|| hp->cth_stroff > fp->ctf_size)
return (ctf_set_open_errno (errp, ECTF_CORRUPT));
if (hp->cth_lbloff > hp->cth_objtoff
|| hp->cth_objtoff > hp->cth_funcoff
|| hp->cth_funcoff > hp->cth_typeoff
- || hp->cth_funcoff > hp->cth_varoff
+ || hp->cth_funcoff > hp->cth_objtidxoff
+ || hp->cth_objtidxoff > hp->cth_funcidxoff
+ || hp->cth_funcidxoff > hp->cth_varoff
|| hp->cth_varoff > hp->cth_typeoff || hp->cth_typeoff > hp->cth_stroff)
return (ctf_set_open_errno (errp, ECTF_CORRUPT));
if ((hp->cth_lbloff & 3) || (hp->cth_objtoff & 2)
- || (hp->cth_funcoff & 2) || (hp->cth_varoff & 3)
+ || (hp->cth_funcoff & 2) || (hp->cth_objtidxoff & 2)
+ || (hp->cth_funcidxoff & 2) || (hp->cth_varoff & 3)
|| (hp->cth_typeoff & 3))
return (ctf_set_open_errno (errp, ECTF_CORRUPT));
fp->ctf_str[CTF_STRTAB_1].cts_strs = strsect->cts_data;
fp->ctf_str[CTF_STRTAB_1].cts_len = strsect->cts_size;
}
+ fp->ctf_syn_ext_strtab = syn_strtab;
if (foreign_endian &&
(err = flip_ctf (hp, fp->ctf_buf)) != 0)
if (fp->ctf_strtab.cts_name != _CTF_NULLSTR)
ctf_free ((char *) fp->ctf_strtab.cts_name);
-
else if (fp->ctf_data_mmapped)
ctf_munmap (fp->ctf_data_mmapped, fp->ctf_data_mmapped_len);
ctf_free (fp->ctf_dynbase);
+ ctf_dynhash_destroy (fp->ctf_syn_ext_strtab);
+ ctf_dynhash_destroy (fp->ctf_link_inputs);
+ ctf_dynhash_destroy (fp->ctf_link_outputs);
+
ctf_free (fp->ctf_sxlate);
ctf_free (fp->ctf_txlate);
ctf_free (fp->ctf_ptrtab);