tools/elf4rom/libs/libelf-0.8.10/lib/verneed.h
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2  * verneed.h - copy versioning information.
       
     3  * Copyright (C) 2001 - 2006 Michael Riepe
       
     4  *
       
     5  * This library is free software; you can redistribute it and/or
       
     6  * modify it under the terms of the GNU Library General Public
       
     7  * License as published by the Free Software Foundation; either
       
     8  * version 2 of the License, or (at your option) any later version.
       
     9  *
       
    10  * This library is distributed in the hope that it will be useful,
       
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    13  * Library General Public License for more details.
       
    14  *
       
    15  * You should have received a copy of the GNU Library General Public
       
    16  * License along with this library; if not, write to the Free Software
       
    17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    18  */
       
    19 
       
    20 #ifndef lint
       
    21 static const char verneed_h_rcsid[] = "@(#) $Id: verneed.h,v 1.12 2006/07/27 22:40:03 michael Exp $";
       
    22 #endif /* lint */
       
    23 
       
    24 #if VER_NEED_CURRENT != 1
       
    25 #error libelf currently does not support VER_NEED_CURRENT != 1
       
    26 #endif /* VER_NEED_CURRENT != 1 */
       
    27 
       
    28 #if TOFILE
       
    29 
       
    30 static void
       
    31 __store_vernaux(vernaux_ftype *dst, const vernaux_mtype *src, unsigned enc) {
       
    32     if (enc == ELFDATA2LSB) {
       
    33 	__store_u32L(dst->vna_hash,  src->vna_hash);
       
    34 	__store_u16L(dst->vna_flags, src->vna_flags);
       
    35 	__store_u16L(dst->vna_other, src->vna_other);
       
    36 	__store_u32L(dst->vna_name,  src->vna_name);
       
    37 	__store_u32L(dst->vna_next,  src->vna_next);
       
    38     }
       
    39     else {
       
    40 	__store_u32M(dst->vna_hash,  src->vna_hash);
       
    41 	__store_u16M(dst->vna_flags, src->vna_flags);
       
    42 	__store_u16M(dst->vna_other, src->vna_other);
       
    43 	__store_u32M(dst->vna_name,  src->vna_name);
       
    44 	__store_u32M(dst->vna_next,  src->vna_next);
       
    45     }
       
    46 }
       
    47 
       
    48 static void
       
    49 __store_verneed(verneed_ftype *dst, const verneed_mtype *src, unsigned enc) {
       
    50     if (enc == ELFDATA2LSB) {
       
    51 	__store_u16L(dst->vn_version, src->vn_version);
       
    52 	__store_u16L(dst->vn_cnt,     src->vn_cnt);
       
    53 	__store_u32L(dst->vn_file,    src->vn_file);
       
    54 	__store_u32L(dst->vn_aux,     src->vn_aux);
       
    55 	__store_u32L(dst->vn_next,    src->vn_next);
       
    56     }
       
    57     else {
       
    58 	__store_u16M(dst->vn_version, src->vn_version);
       
    59 	__store_u16M(dst->vn_cnt,     src->vn_cnt);
       
    60 	__store_u32M(dst->vn_file,    src->vn_file);
       
    61 	__store_u32M(dst->vn_aux,     src->vn_aux);
       
    62 	__store_u32M(dst->vn_next,    src->vn_next);
       
    63     }
       
    64 }
       
    65 
       
    66 typedef vernaux_mtype		vernaux_stype;
       
    67 typedef vernaux_ftype		vernaux_dtype;
       
    68 typedef verneed_mtype		verneed_stype;
       
    69 typedef verneed_ftype		verneed_dtype;
       
    70 typedef align_mtype		verneed_atype;
       
    71 
       
    72 #define copy_vernaux_srctotmp(d, s, e)	(*(d) = *(s))
       
    73 #define copy_vernaux_tmptodst(d, s, e)	__store_vernaux((d), (s), (e))
       
    74 #define copy_verneed_srctotmp(d, s, e)	(*(d) = *(s))
       
    75 #define copy_verneed_tmptodst(d, s, e)	__store_verneed((d), (s), (e))
       
    76 
       
    77 #define translator_suffix	_tof
       
    78 
       
    79 #else /* TOFILE */
       
    80 
       
    81 static void
       
    82 __load_vernaux(vernaux_mtype *dst, const vernaux_ftype *src, unsigned enc) {
       
    83     if (enc == ELFDATA2LSB) {
       
    84 	dst->vna_hash  = __load_u32L(src->vna_hash);
       
    85 	dst->vna_flags = __load_u16L(src->vna_flags);
       
    86 	dst->vna_other = __load_u16L(src->vna_other);
       
    87 	dst->vna_name  = __load_u32L(src->vna_name);
       
    88 	dst->vna_next  = __load_u32L(src->vna_next);
       
    89     }
       
    90     else {
       
    91 	dst->vna_hash  = __load_u32M(src->vna_hash);
       
    92 	dst->vna_flags = __load_u16M(src->vna_flags);
       
    93 	dst->vna_other = __load_u16M(src->vna_other);
       
    94 	dst->vna_name  = __load_u32M(src->vna_name);
       
    95 	dst->vna_next  = __load_u32M(src->vna_next);
       
    96     }
       
    97 }
       
    98 
       
    99 static void
       
   100 __load_verneed(verneed_mtype *dst, const verneed_ftype *src, unsigned enc) {
       
   101     if (enc == ELFDATA2LSB) {
       
   102 	dst->vn_version = __load_u16L(src->vn_version);
       
   103 	dst->vn_cnt     = __load_u16L(src->vn_cnt);
       
   104 	dst->vn_file    = __load_u32L(src->vn_file);
       
   105 	dst->vn_aux     = __load_u32L(src->vn_aux);
       
   106 	dst->vn_next    = __load_u32L(src->vn_next);
       
   107     }
       
   108     else {
       
   109 	dst->vn_version = __load_u16M(src->vn_version);
       
   110 	dst->vn_cnt     = __load_u16M(src->vn_cnt);
       
   111 	dst->vn_file    = __load_u32M(src->vn_file);
       
   112 	dst->vn_aux     = __load_u32M(src->vn_aux);
       
   113 	dst->vn_next    = __load_u32M(src->vn_next);
       
   114     }
       
   115 }
       
   116 
       
   117 typedef vernaux_ftype		vernaux_stype;
       
   118 typedef vernaux_mtype		vernaux_dtype;
       
   119 typedef verneed_ftype		verneed_stype;
       
   120 typedef verneed_mtype		verneed_dtype;
       
   121 typedef align_ftype		verneed_atype;
       
   122 
       
   123 #define copy_vernaux_srctotmp(d, s, e)	__load_vernaux((d), (s), (e))
       
   124 #define copy_vernaux_tmptodst(d, s, e)	(*(d) = *(s))
       
   125 #define copy_verneed_srctotmp(d, s, e)	__load_verneed((d), (s), (e))
       
   126 #define copy_verneed_tmptodst(d, s, e)	(*(d) = *(s))
       
   127 
       
   128 #define translator_suffix	_tom
       
   129 
       
   130 #endif /* TOFILE */
       
   131 
       
   132 #define cat3(a,b,c)	a##b##c
       
   133 #define xlt3(p,e,s)	cat3(p,e,s)
       
   134 #define xltprefix(x)	xlt3(x,_,class_suffix)
       
   135 #define translator(x,e)	xlt3(xltprefix(_elf_##x),e,translator_suffix)
       
   136 
       
   137 static size_t
       
   138 xlt_verneed(unsigned char *dst, const unsigned char *src, size_t n, unsigned enc) {
       
   139     size_t off;
       
   140 
       
   141     if (sizeof(verneed_stype) != sizeof(verneed_dtype)
       
   142      || sizeof(vernaux_stype) != sizeof(vernaux_dtype)) {
       
   143 	/* never happens for ELF v1 and Verneed v1 */
       
   144 	seterr(ERROR_UNIMPLEMENTED);
       
   145 	return (size_t)-1;
       
   146     }
       
   147     /* size translation shortcut */
       
   148     if (dst == NULL) {
       
   149 	return n;
       
   150     }
       
   151     if (src == NULL) {
       
   152 	seterr(ERROR_NULLBUF);
       
   153 	return (size_t)-1;
       
   154     }
       
   155     off = 0;
       
   156     while (off + sizeof(verneed_stype) <= n) {
       
   157 	const verneed_stype *svn;
       
   158 	verneed_dtype *dvn;
       
   159 	verneed_mtype vn;
       
   160 	size_t acount;
       
   161 	size_t aoff;
       
   162 
       
   163 	/*
       
   164 	 * check for proper alignment
       
   165 	 */
       
   166 	if (off % sizeof(verneed_atype)) {
       
   167 	    seterr(ERROR_VERNEED_FORMAT);
       
   168 	    return (size_t)-1;
       
   169 	}
       
   170 	/*
       
   171 	 * copy and check src
       
   172 	 */
       
   173 	svn = (verneed_stype*)(src + off);
       
   174 	dvn = (verneed_dtype*)(dst + off);
       
   175 	copy_verneed_srctotmp(&vn, svn, enc);
       
   176 	if (vn.vn_version < 1
       
   177 	 || vn.vn_version > VER_NEED_CURRENT) {
       
   178 	    seterr(ERROR_VERNEED_VERSION);
       
   179 	    return (size_t)-1;
       
   180 	}
       
   181 	if (vn.vn_cnt < 1
       
   182 	 || vn.vn_aux == 0) {
       
   183 	    seterr(ERROR_VERNEED_FORMAT);
       
   184 	    return (size_t)-1;
       
   185 	}
       
   186 	copy_verneed_tmptodst(dvn, &vn, enc);
       
   187 	/*
       
   188 	 * copy aux array
       
   189 	 */
       
   190 	aoff = off + vn.vn_aux;
       
   191 	for (acount = 0; acount < vn.vn_cnt; acount++) {
       
   192 	    const vernaux_stype *svna;
       
   193 	    vernaux_dtype *dvna;
       
   194 	    vernaux_mtype vna;
       
   195 
       
   196 	    /*
       
   197 	     * are we still inside the buffer limits?
       
   198 	     */
       
   199 	    if (aoff + sizeof(vernaux_stype) > n) {
       
   200 		break;
       
   201 	    }
       
   202 	    /*
       
   203 	     * check for proper alignment
       
   204 	     */
       
   205 	    if (aoff % sizeof(verneed_atype)) {
       
   206 		seterr(ERROR_VERNEED_FORMAT);
       
   207 		return (size_t)-1;
       
   208 	    }
       
   209 	    /*
       
   210 	     * copy and check src
       
   211 	     */
       
   212 	    svna = (vernaux_stype*)(src + aoff);
       
   213 	    dvna = (vernaux_dtype*)(dst + aoff);
       
   214 	    copy_vernaux_srctotmp(&vna, svna, enc);
       
   215 	    copy_vernaux_tmptodst(dvna, &vna, enc);
       
   216 	    /*
       
   217 	     * advance to next vernaux
       
   218 	     */
       
   219 	    if (vna.vna_next == 0) {
       
   220 		/* end of list */
       
   221 		break;
       
   222 	    }
       
   223 	    aoff += vna.vna_next;
       
   224 	}
       
   225 	/*
       
   226 	 * advance to next verneed
       
   227 	 */
       
   228 	if (vn.vn_next == 0) {
       
   229 	    /* end of list */
       
   230 	    break;
       
   231 	}
       
   232 	off += vn.vn_next;
       
   233     }
       
   234     return n;
       
   235 }
       
   236 
       
   237 size_t
       
   238 translator(verneed,L11)(unsigned char *dst, const unsigned char *src, size_t n) {
       
   239     return xlt_verneed(dst, src, n, ELFDATA2LSB);
       
   240 }
       
   241 
       
   242 size_t
       
   243 translator(verneed,M11)(unsigned char *dst, const unsigned char *src, size_t n) {
       
   244     return xlt_verneed(dst, src, n, ELFDATA2MSB);
       
   245 }