Phoenix
Object-oriented orthogonally persistent operating system
verdef.h
00001 /*
00002  * verdef.h - copy versioning information.
00003  * Copyright (C) 2001 - 2006 Michael Riepe
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Library General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public
00016  * License along with this library; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
00018  */
00019 
00020 #if VER_DEF_CURRENT != 1
00021 #error libelf currently does not support VER_DEF_CURRENT != 1
00022 #endif /* VER_DEF_CURRENT != 1 */
00023 
00024 #if TOFILE
00025 
00026 static void
00027 __store_verdaux(verdaux_ftype *dst, const verdaux_mtype *src, unsigned enc) {
00028     if (enc == ELFDATA2LSB) {
00029     __store_u32L(dst->vda_name, src->vda_name);
00030     __store_u32L(dst->vda_next, src->vda_next);
00031     }
00032     else {
00033     __store_u32M(dst->vda_name, src->vda_name);
00034     __store_u32M(dst->vda_next, src->vda_next);
00035     }
00036 }
00037 
00038 static void
00039 __store_verdef(verdef_ftype *dst, const verdef_mtype *src, unsigned enc) {
00040     if (enc == ELFDATA2LSB) {
00041     __store_u16L(dst->vd_version, src->vd_version);
00042     __store_u16L(dst->vd_flags,   src->vd_flags);
00043     __store_u16L(dst->vd_ndx,     src->vd_ndx);
00044     __store_u16L(dst->vd_cnt,     src->vd_cnt);
00045     __store_u32L(dst->vd_hash,    src->vd_hash);
00046     __store_u32L(dst->vd_aux,     src->vd_aux);
00047     __store_u32L(dst->vd_next,    src->vd_next);
00048     }
00049     else {
00050     __store_u16M(dst->vd_version, src->vd_version);
00051     __store_u16M(dst->vd_flags,   src->vd_flags);
00052     __store_u16M(dst->vd_ndx,     src->vd_ndx);
00053     __store_u16M(dst->vd_cnt,     src->vd_cnt);
00054     __store_u32M(dst->vd_hash,    src->vd_hash);
00055     __store_u32M(dst->vd_aux,     src->vd_aux);
00056     __store_u32M(dst->vd_next,    src->vd_next);
00057     }
00058 }
00059 
00060 typedef verdaux_mtype       verdaux_stype;
00061 typedef verdaux_ftype       verdaux_dtype;
00062 typedef verdef_mtype        verdef_stype;
00063 typedef verdef_ftype        verdef_dtype;
00064 typedef align_mtype     verdef_atype;
00065 
00066 #define copy_verdaux_srctotmp(d, s, e)  (*(d) = *(s))
00067 #define copy_verdaux_tmptodst(d, s, e)  __store_verdaux((d), (s), (e))
00068 #define copy_verdef_srctotmp(d, s, e)   (*(d) = *(s))
00069 #define copy_verdef_tmptodst(d, s, e)   __store_verdef((d), (s), (e))
00070 
00071 #define translator_suffix   _tof
00072 
00073 #else /* TOFILE */
00074 
00075 static void
00076 __load_verdaux(verdaux_mtype *dst, const verdaux_ftype *src, unsigned enc) {
00077     if (enc == ELFDATA2LSB) {
00078     dst->vda_name = __load_u32L(src->vda_name);
00079     dst->vda_next = __load_u32L(src->vda_next);
00080     }
00081     else {
00082     dst->vda_name = __load_u32M(src->vda_name);
00083     dst->vda_next = __load_u32M(src->vda_next);
00084     }
00085 }
00086 
00087 static void
00088 __load_verdef(verdef_mtype *dst, const verdef_ftype *src, unsigned enc) {
00089     if (enc == ELFDATA2LSB) {
00090     dst->vd_version = __load_u16L(src->vd_version);
00091     dst->vd_flags   = __load_u16L(src->vd_flags);
00092     dst->vd_ndx     = __load_u16L(src->vd_ndx);
00093     dst->vd_cnt     = __load_u16L(src->vd_cnt);
00094     dst->vd_hash    = __load_u32L(src->vd_hash);
00095     dst->vd_aux     = __load_u32L(src->vd_aux);
00096     dst->vd_next    = __load_u32L(src->vd_next);
00097     }
00098     else {
00099     dst->vd_version = __load_u16M(src->vd_version);
00100     dst->vd_flags   = __load_u16M(src->vd_flags);
00101     dst->vd_ndx     = __load_u16M(src->vd_ndx);
00102     dst->vd_cnt     = __load_u16M(src->vd_cnt);
00103     dst->vd_hash    = __load_u32M(src->vd_hash);
00104     dst->vd_aux     = __load_u32M(src->vd_aux);
00105     dst->vd_next    = __load_u32M(src->vd_next);
00106     }
00107 }
00108 
00109 typedef verdaux_ftype       verdaux_stype;
00110 typedef verdaux_mtype       verdaux_dtype;
00111 typedef verdef_ftype        verdef_stype;
00112 typedef verdef_mtype        verdef_dtype;
00113 typedef align_ftype     verdef_atype;
00114 
00115 #define copy_verdaux_srctotmp(d, s, e)  __load_verdaux((d), (s), (e))
00116 #define copy_verdaux_tmptodst(d, s, e)  (*(d) = *(s))
00117 #define copy_verdef_srctotmp(d, s, e)   __load_verdef((d), (s), (e))
00118 #define copy_verdef_tmptodst(d, s, e)   (*(d) = *(s))
00119 
00120 #define translator_suffix   _tom
00121 
00122 #endif /* TOFILE */
00123 
00124 #define cat3(a,b,c) a##b##c
00125 #define xlt3(p,e,s) cat3(p,e,s)
00126 #define xltprefix(x)    xlt3(x,_,class_suffix)
00127 #define translator(x,e) xlt3(xltprefix(_elf_##x),e,translator_suffix)
00128 
00129 static size_t
00130 xlt_verdef(unsigned char *dst, const unsigned char *src, size_t n, unsigned enc) {
00131     size_t off;
00132 
00133     if (sizeof(verdef_stype) != sizeof(verdef_dtype)
00134      || sizeof(verdaux_stype) != sizeof(verdaux_dtype)) {
00135     /* never happens for ELF v1 and Verneed v1 */
00136     seterr(ERROR_UNIMPLEMENTED);
00137     return (size_t)-1;
00138     }
00139     /* size translation shortcut */
00140     if (dst == NULL) {
00141     return n;
00142     }
00143     if (src == NULL) {
00144     seterr(ERROR_NULLBUF);
00145     return (size_t)-1;
00146     }
00147     off = 0;
00148     while (off + sizeof(verdef_stype) <= n) {
00149     const verdef_stype *svd;
00150     verdef_dtype *dvd;
00151     verdef_mtype vd;
00152     size_t acount;
00153     size_t aoff;
00154 
00155     /*
00156      * check for proper alignment
00157      */
00158     if (off % sizeof(verdef_atype)) {
00159         seterr(ERROR_VERDEF_FORMAT);
00160         return (size_t)-1;
00161     }
00162     /*
00163      * copy and check src
00164      */
00165     svd = (verdef_stype*)(src + off);
00166     dvd = (verdef_dtype*)(dst + off);
00167     copy_verdef_srctotmp(&vd, svd, enc);
00168     if (vd.vd_version < 1
00169      || vd.vd_version > VER_DEF_CURRENT) {
00170         seterr(ERROR_VERDEF_VERSION);
00171         return (size_t)-1;
00172     }
00173     if (vd.vd_cnt < 1
00174      || vd.vd_aux == 0) {
00175         seterr(ERROR_VERDEF_FORMAT);
00176         return (size_t)-1;
00177     }
00178     copy_verdef_tmptodst(dvd, &vd, enc);
00179     /*
00180      * copy aux array
00181      */
00182     aoff = off + vd.vd_aux;
00183     for (acount = 0; acount < vd.vd_cnt; acount++) {
00184         const verdaux_stype *svda;
00185         verdaux_dtype *dvda;
00186         verdaux_mtype vda;
00187 
00188         /*
00189          * are we still inside the buffer limits?
00190          */
00191         if (aoff + sizeof(verdaux_stype) > n) {
00192         break;
00193         }
00194         /*
00195          * check for proper alignment
00196          */
00197         if (aoff % sizeof(verdef_atype)) {
00198         seterr(ERROR_VERDEF_FORMAT);
00199         return (size_t)-1;
00200         }
00201         /*
00202          * copy and check src
00203          */
00204         svda = (verdaux_stype*)(src + aoff);
00205         dvda = (verdaux_dtype*)(dst + aoff);
00206         copy_verdaux_srctotmp(&vda, svda, enc);
00207         copy_verdaux_tmptodst(dvda, &vda, enc);
00208         /*
00209          * advance to next verdaux
00210          */
00211         if (vda.vda_next == 0) {
00212         /* end of list */
00213         break;
00214         }
00215         aoff += vda.vda_next;
00216     }
00217     /*
00218      * advance to next verdef
00219      */
00220     if (vd.vd_next == 0) {
00221         /* end of list */
00222         break;
00223     }
00224     off += vd.vd_next;
00225     }
00226     return n;
00227 }
00228 
00229 size_t
00230 translator(verdef,L11)(unsigned char *dst, const unsigned char *src, size_t n) {
00231     return xlt_verdef(dst, src, n, ELFDATA2LSB);
00232 }
00233 
00234 size_t
00235 translator(verdef,M11)(unsigned char *dst, const unsigned char *src, size_t n) {
00236     return xlt_verdef(dst, src, n, ELFDATA2MSB);
00237 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines