/* Flip the endianness of the CTF header. */
-static void
-flip_header (ctf_header_t *cth)
+void
+ctf_flip_header (ctf_header_t *cth)
{
swap_thing (cth->cth_preamble.ctp_magic);
swap_thing (cth->cth_preamble.ctp_version);
ctf_stype followed by variable data. */
static int
-flip_types (ctf_dict_t *fp, void *start, size_t len)
+flip_types (ctf_dict_t *fp, void *start, size_t len, int to_foreign)
{
ctf_type_t *t = start;
while ((uintptr_t) t < ((uintptr_t) start) + len)
{
+ uint32_t kind;
+ size_t size;
+ uint32_t vlen;
+ size_t vbytes;
+
+ if (to_foreign)
+ {
+ kind = CTF_V2_INFO_KIND (t->ctt_info);
+ size = t->ctt_size;
+ vlen = CTF_V2_INFO_VLEN (t->ctt_info);
+ vbytes = get_vbytes_v2 (fp, kind, size, vlen);
+ }
+
swap_thing (t->ctt_name);
swap_thing (t->ctt_info);
swap_thing (t->ctt_size);
- uint32_t kind = CTF_V2_INFO_KIND (t->ctt_info);
- size_t size = t->ctt_size;
- uint32_t vlen = CTF_V2_INFO_VLEN (t->ctt_info);
- size_t vbytes = get_vbytes_v2 (fp, kind, size, vlen);
+ if (!to_foreign)
+ {
+ kind = CTF_V2_INFO_KIND (t->ctt_info);
+ size = t->ctt_size;
+ vlen = CTF_V2_INFO_VLEN (t->ctt_info);
+ vbytes = get_vbytes_v2 (fp, kind, size, vlen);
+ }
if (_libctf_unlikely_ (size == CTF_LSIZE_SENT))
{
+ if (to_foreign)
+ size = CTF_TYPE_LSIZE (t);
+
swap_thing (t->ctt_lsizehi);
swap_thing (t->ctt_lsizelo);
- size = CTF_TYPE_LSIZE (t);
+
+ if (!to_foreign)
+ size = CTF_TYPE_LSIZE (t);
+
t = (ctf_type_t *) ((uintptr_t) t + sizeof (ctf_type_t));
}
else
}
/* Flip the endianness of BUF, given the offsets in the (already endian-
- converted) CTH.
+ converted) CTH. If TO_FOREIGN is set, flip to foreign-endianness; if not,
+ flip away.
All of this stuff happens before the header is fully initialized, so the
LCTF_*() macros cannot be used yet. Since we do not try to endian-convert v1
data, this is no real loss. */
-static int
-flip_ctf (ctf_dict_t *fp, ctf_header_t *cth, unsigned char *buf)
+int
+ctf_flip (ctf_dict_t *fp, ctf_header_t *cth, unsigned char *buf,
+ int to_foreign)
{
+ ctf_dprintf("flipping endianness\n");
+
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_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 (fp, buf + cth->cth_typeoff, cth->cth_stroff - cth->cth_typeoff);
+ return flip_types (fp, buf + cth->cth_typeoff,
+ cth->cth_stroff - cth->cth_typeoff, to_foreign);
}
/* Set up the ctl hashes in a ctf_dict_t. Called by both writable and
upgrade_header (hp);
if (foreign_endian)
- flip_header (hp);
+ ctf_flip_header (hp);
fp->ctf_openflags = hp->cth_flags;
fp->ctf_size = hp->cth_stroff + hp->cth_strlen;
fp->ctf_syn_ext_strtab = syn_strtab;
if (foreign_endian &&
- (err = flip_ctf (fp, hp, fp->ctf_buf)) != 0)
+ (err = ctf_flip (fp, hp, fp->ctf_buf, 0)) != 0)
{
- /* We can be certain that flip_ctf() will have endian-flipped everything
+ /* We can be certain that ctf_flip() will have endian-flipped everything
other than the types table when we return. In particular the header
is fine, so set it, to allow freeing to use the usual code path. */