tools/elf4rom/libs/libelf-0.8.10/lib/verdef.h
changeset 34 92d87f2e53c2
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/verdef.h	Fri Jan 15 09:07:44 2010 +0000
@@ -0,0 +1,241 @@
+/*
+ * verdef.h - copy versioning information.
+ * Copyright (C) 2001 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef lint
+static const char verdef_h_rcsid[] = "@(#) $Id: verdef.h,v 1.12 2006/07/27 22:56:11 michael Exp $";
+#endif /* lint */
+
+#if VER_DEF_CURRENT != 1
+#error libelf currently does not support VER_DEF_CURRENT != 1
+#endif /* VER_DEF_CURRENT != 1 */
+
+#if TOFILE
+
+static void
+__store_verdaux(verdaux_ftype *dst, const verdaux_mtype *src, unsigned enc) {
+    if (enc == ELFDATA2LSB) {
+	__store_u32L(dst->vda_name, src->vda_name);
+	__store_u32L(dst->vda_next, src->vda_next);
+    }
+    else {
+	__store_u32M(dst->vda_name, src->vda_name);
+	__store_u32M(dst->vda_next, src->vda_next);
+    }
+}
+
+static void
+__store_verdef(verdef_ftype *dst, const verdef_mtype *src, unsigned enc) {
+    if (enc == ELFDATA2LSB) {
+	__store_u16L(dst->vd_version, src->vd_version);
+	__store_u16L(dst->vd_flags,   src->vd_flags);
+	__store_u16L(dst->vd_ndx,     src->vd_ndx);
+	__store_u16L(dst->vd_cnt,     src->vd_cnt);
+	__store_u32L(dst->vd_hash,    src->vd_hash);
+	__store_u32L(dst->vd_aux,     src->vd_aux);
+	__store_u32L(dst->vd_next,    src->vd_next);
+    }
+    else {
+	__store_u16M(dst->vd_version, src->vd_version);
+	__store_u16M(dst->vd_flags,   src->vd_flags);
+	__store_u16M(dst->vd_ndx,     src->vd_ndx);
+	__store_u16M(dst->vd_cnt,     src->vd_cnt);
+	__store_u32M(dst->vd_hash,    src->vd_hash);
+	__store_u32M(dst->vd_aux,     src->vd_aux);
+	__store_u32M(dst->vd_next,    src->vd_next);
+    }
+}
+
+typedef verdaux_mtype		verdaux_stype;
+typedef verdaux_ftype		verdaux_dtype;
+typedef verdef_mtype		verdef_stype;
+typedef verdef_ftype		verdef_dtype;
+typedef align_mtype		verdef_atype;
+
+#define copy_verdaux_srctotmp(d, s, e)	(*(d) = *(s))
+#define copy_verdaux_tmptodst(d, s, e)	__store_verdaux((d), (s), (e))
+#define copy_verdef_srctotmp(d, s, e)	(*(d) = *(s))
+#define copy_verdef_tmptodst(d, s, e)	__store_verdef((d), (s), (e))
+
+#define translator_suffix	_tof
+
+#else /* TOFILE */
+
+static void
+__load_verdaux(verdaux_mtype *dst, const verdaux_ftype *src, unsigned enc) {
+    if (enc == ELFDATA2LSB) {
+	dst->vda_name = __load_u32L(src->vda_name);
+	dst->vda_next = __load_u32L(src->vda_next);
+    }
+    else {
+	dst->vda_name = __load_u32M(src->vda_name);
+	dst->vda_next = __load_u32M(src->vda_next);
+    }
+}
+
+static void
+__load_verdef(verdef_mtype *dst, const verdef_ftype *src, unsigned enc) {
+    if (enc == ELFDATA2LSB) {
+	dst->vd_version = __load_u16L(src->vd_version);
+	dst->vd_flags   = __load_u16L(src->vd_flags);
+	dst->vd_ndx     = __load_u16L(src->vd_ndx);
+	dst->vd_cnt     = __load_u16L(src->vd_cnt);
+	dst->vd_hash    = __load_u32L(src->vd_hash);
+	dst->vd_aux     = __load_u32L(src->vd_aux);
+	dst->vd_next    = __load_u32L(src->vd_next);
+    }
+    else {
+	dst->vd_version = __load_u16M(src->vd_version);
+	dst->vd_flags   = __load_u16M(src->vd_flags);
+	dst->vd_ndx     = __load_u16M(src->vd_ndx);
+	dst->vd_cnt     = __load_u16M(src->vd_cnt);
+	dst->vd_hash    = __load_u32M(src->vd_hash);
+	dst->vd_aux     = __load_u32M(src->vd_aux);
+	dst->vd_next    = __load_u32M(src->vd_next);
+    }
+}
+
+typedef verdaux_ftype		verdaux_stype;
+typedef verdaux_mtype		verdaux_dtype;
+typedef verdef_ftype		verdef_stype;
+typedef verdef_mtype		verdef_dtype;
+typedef align_ftype		verdef_atype;
+
+#define copy_verdaux_srctotmp(d, s, e)	__load_verdaux((d), (s), (e))
+#define copy_verdaux_tmptodst(d, s, e)	(*(d) = *(s))
+#define copy_verdef_srctotmp(d, s, e)	__load_verdef((d), (s), (e))
+#define copy_verdef_tmptodst(d, s, e)	(*(d) = *(s))
+
+#define translator_suffix	_tom
+
+#endif /* TOFILE */
+
+#define cat3(a,b,c)	a##b##c
+#define xlt3(p,e,s)	cat3(p,e,s)
+#define xltprefix(x)	xlt3(x,_,class_suffix)
+#define translator(x,e)	xlt3(xltprefix(_elf_##x),e,translator_suffix)
+
+static size_t
+xlt_verdef(unsigned char *dst, const unsigned char *src, size_t n, unsigned enc) {
+    size_t off;
+
+    if (sizeof(verdef_stype) != sizeof(verdef_dtype)
+     || sizeof(verdaux_stype) != sizeof(verdaux_dtype)) {
+	/* never happens for ELF v1 and Verneed v1 */
+	seterr(ERROR_UNIMPLEMENTED);
+	return (size_t)-1;
+    }
+    /* size translation shortcut */
+    if (dst == NULL) {
+	return n;
+    }
+    if (src == NULL) {
+	seterr(ERROR_NULLBUF);
+	return (size_t)-1;
+    }
+    off = 0;
+    while (off + sizeof(verdef_stype) <= n) {
+	const verdef_stype *svd;
+	verdef_dtype *dvd;
+	verdef_mtype vd;
+	size_t acount;
+	size_t aoff;
+
+	/*
+	 * check for proper alignment
+	 */
+	if (off % sizeof(verdef_atype)) {
+	    seterr(ERROR_VERDEF_FORMAT);
+	    return (size_t)-1;
+	}
+	/*
+	 * copy and check src
+	 */
+	svd = (verdef_stype*)(src + off);
+	dvd = (verdef_dtype*)(dst + off);
+	copy_verdef_srctotmp(&vd, svd, enc);
+	if (vd.vd_version < 1
+	 || vd.vd_version > VER_DEF_CURRENT) {
+	    seterr(ERROR_VERDEF_VERSION);
+	    return (size_t)-1;
+	}
+	if (vd.vd_cnt < 1
+	 || vd.vd_aux == 0) {
+	    seterr(ERROR_VERDEF_FORMAT);
+	    return (size_t)-1;
+	}
+	copy_verdef_tmptodst(dvd, &vd, enc);
+	/*
+	 * copy aux array
+	 */
+	aoff = off + vd.vd_aux;
+	for (acount = 0; acount < vd.vd_cnt; acount++) {
+	    const verdaux_stype *svda;
+	    verdaux_dtype *dvda;
+	    verdaux_mtype vda;
+
+	    /*
+	     * are we still inside the buffer limits?
+	     */
+	    if (aoff + sizeof(verdaux_stype) > n) {
+		break;
+	    }
+	    /*
+	     * check for proper alignment
+	     */
+	    if (aoff % sizeof(verdef_atype)) {
+		seterr(ERROR_VERDEF_FORMAT);
+		return (size_t)-1;
+	    }
+	    /*
+	     * copy and check src
+	     */
+	    svda = (verdaux_stype*)(src + aoff);
+	    dvda = (verdaux_dtype*)(dst + aoff);
+	    copy_verdaux_srctotmp(&vda, svda, enc);
+	    copy_verdaux_tmptodst(dvda, &vda, enc);
+	    /*
+	     * advance to next verdaux
+	     */
+	    if (vda.vda_next == 0) {
+		/* end of list */
+		break;
+	    }
+	    aoff += vda.vda_next;
+	}
+	/*
+	 * advance to next verdef
+	 */
+	if (vd.vd_next == 0) {
+	    /* end of list */
+	    break;
+	}
+	off += vd.vd_next;
+    }
+    return n;
+}
+
+size_t
+translator(verdef,L11)(unsigned char *dst, const unsigned char *src, size_t n) {
+    return xlt_verdef(dst, src, n, ELFDATA2LSB);
+}
+
+size_t
+translator(verdef,M11)(unsigned char *dst, const unsigned char *src, size_t n) {
+    return xlt_verdef(dst, src, n, ELFDATA2MSB);
+}