summaryrefslogtreecommitdiffstats
path: root/cddl
diff options
context:
space:
mode:
Diffstat (limited to 'cddl')
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c99
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c4
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h1
-rw-r--r--cddl/contrib/opensolaris/tools/ctf/cvt/output.c20
4 files changed, 121 insertions, 3 deletions
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c b/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c
index e3ec1e1..55dd39e 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctf.c
@@ -62,6 +62,18 @@ struct ctf_buf {
int ntholes; /* number of type holes */
};
+/*
+ * Macros to reverse byte order
+ */
+#define BSWAP_8(x) ((x) & 0xff)
+#define BSWAP_16(x) ((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))
+#define BSWAP_32(x) ((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
+
+#define SWAP_16(x) (x) = BSWAP_16(x)
+#define SWAP_32(x) (x) = BSWAP_32(x)
+
+static int target_requires_swap;
+
/*PRINTFLIKE1*/
static void
parseterminate(const char *fmt, ...)
@@ -140,6 +152,11 @@ write_label(void *arg1, void *arg2)
ctl.ctl_label = strtab_insert(&b->ctb_strtab, le->le_name);
ctl.ctl_typeidx = le->le_idx;
+ if (target_requires_swap) {
+ SWAP_32(ctl.ctl_label);
+ SWAP_32(ctl.ctl_typeidx);
+ }
+
ctf_buf_write(b, &ctl, sizeof (ctl));
return (1);
@@ -152,6 +169,10 @@ write_objects(iidesc_t *idp, ctf_buf_t *b)
ctf_buf_write(b, &id, sizeof (id));
+ if (target_requires_swap) {
+ SWAP_16(id);
+ }
+
debug(3, "Wrote object %s (%d)\n", (idp ? idp->ii_name : "(null)"), id);
}
@@ -180,10 +201,21 @@ write_functions(iidesc_t *idp, ctf_buf_t *b)
fdata[0] = CTF_TYPE_INFO(CTF_K_FUNCTION, 1, nargs);
fdata[1] = idp->ii_dtype->t_id;
+
+ if (target_requires_swap) {
+ SWAP_16(fdata[0]);
+ SWAP_16(fdata[1]);
+ }
+
ctf_buf_write(b, fdata, sizeof (fdata));
for (i = 0; i < idp->ii_nargs; i++) {
id = idp->ii_args[i]->t_id;
+
+ if (target_requires_swap) {
+ SWAP_16(id);
+ }
+
ctf_buf_write(b, &id, sizeof (id));
}
@@ -208,11 +240,25 @@ write_sized_type_rec(ctf_buf_t *b, ctf_type_t *ctt, size_t size)
ctt->ctt_size = CTF_LSIZE_SENT;
ctt->ctt_lsizehi = CTF_SIZE_TO_LSIZE_HI(size);
ctt->ctt_lsizelo = CTF_SIZE_TO_LSIZE_LO(size);
+ if (target_requires_swap) {
+ SWAP_32(ctt->ctt_name);
+ SWAP_16(ctt->ctt_info);
+ SWAP_16(ctt->ctt_size);
+ SWAP_32(ctt->ctt_lsizehi);
+ SWAP_32(ctt->ctt_lsizelo);
+ }
ctf_buf_write(b, ctt, sizeof (*ctt));
} else {
ctf_stype_t *cts = (ctf_stype_t *)ctt;
cts->ctt_size = (ushort_t)size;
+
+ if (target_requires_swap) {
+ SWAP_32(cts->ctt_name);
+ SWAP_16(cts->ctt_info);
+ SWAP_16(cts->ctt_size);
+ }
+
ctf_buf_write(b, cts, sizeof (*cts));
}
}
@@ -222,6 +268,12 @@ write_unsized_type_rec(ctf_buf_t *b, ctf_type_t *ctt)
{
ctf_stype_t *cts = (ctf_stype_t *)ctt;
+ if (target_requires_swap) {
+ SWAP_32(cts->ctt_name);
+ SWAP_16(cts->ctt_info);
+ SWAP_16(cts->ctt_size);
+ }
+
ctf_buf_write(b, cts, sizeof (*cts));
}
@@ -296,6 +348,9 @@ write_type(void *arg1, void *arg2)
encoding = ip->intr_fformat;
data = CTF_INT_DATA(encoding, ip->intr_offset, ip->intr_nbits);
+ if (target_requires_swap) {
+ SWAP_32(data);
+ }
ctf_buf_write(b, &data, sizeof (data));
break;
@@ -312,6 +367,11 @@ write_type(void *arg1, void *arg2)
cta.cta_contents = tp->t_ardef->ad_contents->t_id;
cta.cta_index = tp->t_ardef->ad_idxtype->t_id;
cta.cta_nelems = tp->t_ardef->ad_nelems;
+ if (target_requires_swap) {
+ SWAP_16(cta.cta_contents);
+ SWAP_16(cta.cta_index);
+ SWAP_32(cta.cta_nelems);
+ }
ctf_buf_write(b, &cta, sizeof (cta));
break;
@@ -341,6 +401,11 @@ write_type(void *arg1, void *arg2)
offset);
ctm.ctm_type = mp->ml_type->t_id;
ctm.ctm_offset = mp->ml_offset;
+ if (target_requires_swap) {
+ SWAP_32(ctm.ctm_name);
+ SWAP_16(ctm.ctm_type);
+ SWAP_16(ctm.ctm_offset);
+ }
ctf_buf_write(b, &ctm, sizeof (ctm));
}
} else {
@@ -355,6 +420,14 @@ write_type(void *arg1, void *arg2)
CTF_OFFSET_TO_LMEMHI(mp->ml_offset);
ctlm.ctlm_offsetlo =
CTF_OFFSET_TO_LMEMLO(mp->ml_offset);
+
+ if (target_requires_swap) {
+ SWAP_32(ctlm.ctlm_name);
+ SWAP_16(ctlm.ctlm_type);
+ SWAP_32(ctlm.ctlm_offsethi);
+ SWAP_32(ctlm.ctlm_offsetlo);
+ }
+
ctf_buf_write(b, &ctlm, sizeof (ctlm));
}
}
@@ -377,6 +450,12 @@ write_type(void *arg1, void *arg2)
offset = strtab_insert(&b->ctb_strtab, ep->el_name);
cte.cte_name = CTF_TYPE_NAME(CTF_STRTAB_0, offset);
cte.cte_value = ep->el_number;
+
+ if (target_requires_swap) {
+ SWAP_32(cte.cte_name);
+ SWAP_32(cte.cte_value);
+ }
+
ctf_buf_write(b, &cte, sizeof (cte));
i--;
}
@@ -420,6 +499,11 @@ write_type(void *arg1, void *arg2)
for (i = 0; i < (int) tp->t_fndef->fn_nargs; i++) {
id = tp->t_fndef->fn_args[i]->t_id;
+
+ if (target_requires_swap) {
+ SWAP_16(id);
+ }
+
ctf_buf_write(b, &id, sizeof (id));
}
@@ -613,6 +697,9 @@ ctf_gen(iiburst_t *iiburst, size_t *resszp, int do_compress)
int i;
+ target_requires_swap = do_compress & CTF_SWAP_BYTES;
+ do_compress &= ~CTF_SWAP_BYTES;
+
/*
* Prepare the header, and create the CTF output buffers. The data
* object section and function section are both lists of 2-byte
@@ -649,6 +736,18 @@ ctf_gen(iiburst_t *iiburst, size_t *resszp, int do_compress)
h.cth_stroff = ctf_buf_cur(buf);
h.cth_strlen = strtab_size(&buf->ctb_strtab);
+ if (target_requires_swap) {
+ SWAP_16(h.cth_preamble.ctp_magic);
+ SWAP_32(h.cth_parlabel);
+ SWAP_32(h.cth_parname);
+ SWAP_32(h.cth_lbloff);
+ SWAP_32(h.cth_objtoff);
+ SWAP_32(h.cth_funcoff);
+ SWAP_32(h.cth_typeoff);
+ SWAP_32(h.cth_stroff);
+ SWAP_32(h.cth_strlen);
+ }
+
/*
* We only do compression for ctfmerge, as ctfconvert is only
* supposed to be used on intermediary build objects. This is
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c
index 105112d..3e030c7 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctfmerge.c
@@ -620,7 +620,7 @@ copy_ctf_data(char *srcfile, char *destfile, int keep_stabs)
terminate("No CTF data found in source file %s\n", srcfile);
tmpname = mktmpname(destfile, ".ctf");
- write_ctf(srctd, destfile, tmpname, CTF_COMPRESS | keep_stabs);
+ write_ctf(srctd, destfile, tmpname, CTF_COMPRESS | CTF_SWAP_BYTES | keep_stabs);
if (rename(tmpname, destfile) != 0) {
terminate("Couldn't rename temp file %s to %s", tmpname,
destfile);
@@ -1015,7 +1015,7 @@ main(int argc, char **argv)
tmpname = mktmpname(outfile, ".ctf");
write_ctf(savetd, outfile, tmpname,
- CTF_COMPRESS | write_fuzzy_match | dynsym | keep_stabs);
+ CTF_COMPRESS | CTF_SWAP_BYTES | write_fuzzy_match | dynsym | keep_stabs);
if (rename(tmpname, outfile) != 0)
terminate("Couldn't rename output temp file %s", tmpname);
free(tmpname);
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h b/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h
index 52bbf44..93a540d 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/ctftools.h
@@ -391,6 +391,7 @@ void merge_into_master(tdata_t *, tdata_t *, tdata_t *, int);
#define CTF_USE_DYNSYM 0x2 /* use .dynsym not .symtab */
#define CTF_COMPRESS 0x4 /* compress CTF output */
#define CTF_KEEP_STABS 0x8 /* keep .stabs sections */
+#define CTF_SWAP_BYTES 0x10 /* target byte order is different from host */
void write_ctf(tdata_t *, const char *, const char *, int);
diff --git a/cddl/contrib/opensolaris/tools/ctf/cvt/output.c b/cddl/contrib/opensolaris/tools/ctf/cvt/output.c
index 0b04c48..bfe5b7e 100644
--- a/cddl/contrib/opensolaris/tools/ctf/cvt/output.c
+++ b/cddl/contrib/opensolaris/tools/ctf/cvt/output.c
@@ -717,7 +717,7 @@ make_ctf_data(tdata_t *td, Elf *elf, const char *file, size_t *lenp, int flags)
iiburst = sort_iidescs(elf, file, td, flags & CTF_FUZZY_MATCH,
flags & CTF_USE_DYNSYM);
- data = ctf_gen(iiburst, lenp, flags & CTF_COMPRESS);
+ data = ctf_gen(iiburst, lenp, flags & (CTF_COMPRESS | CTF_SWAP_BYTES));
iiburst_free(iiburst);
@@ -730,10 +730,12 @@ write_ctf(tdata_t *td, const char *curname, const char *newname, int flags)
struct stat st;
Elf *elf = NULL;
Elf *telf = NULL;
+ GElf_Ehdr ehdr;
caddr_t data;
size_t len;
int fd = -1;
int tfd = -1;
+ int byteorder;
(void) elf_version(EV_CURRENT);
if ((fd = open(curname, O_RDONLY)) < 0 || fstat(fd, &st) < 0)
@@ -746,6 +748,22 @@ write_ctf(tdata_t *td, const char *curname, const char *newname, int flags)
if ((telf = elf_begin(tfd, ELF_C_WRITE, NULL)) == NULL)
elfterminate(curname, "Cannot write");
+ if (gelf_getehdr(elf, &ehdr)) {
+#if BYTE_ORDER == _BIG_ENDIAN
+ byteorder = ELFDATA2MSB;
+#else
+ byteorder = ELFDATA2LSB;
+#endif
+ /*
+ * If target and host has the same byte order
+ * clear byte swapping request
+ */
+ if (ehdr.e_ident[EI_DATA] == byteorder)
+ flags &= ~CTF_SWAP_BYTES;
+ }
+ else
+ elfterminate(curname, "Failed to get EHDR");
+
data = make_ctf_data(td, elf, curname, &len, flags);
write_file(elf, curname, telf, newname, data, len, flags);
free(data);
OpenPOWER on IntegriCloud