Phoenix
Object-oriented orthogonally persistent operating system
verneed.h
00001 /*
00002  * verneed.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 /*
00021  * vn_version
00022  */
00023 #define VER_NEED_NONE       0
00024 #define VER_NEED_CURRENT    1
00025 #define VER_NEED_NUM        2
00026 
00027 #if VER_NEED_CURRENT != 1
00028 #error libelf currently does not support VER_NEED_CURRENT != 1
00029 #endif /* VER_NEED_CURRENT != 1 */
00030 
00031 #if TOFILE
00032 
00033 static void
00034 __store_vernaux(vernaux_ftype *dst, const vernaux_mtype *src, unsigned enc) {
00035     if (enc == ELFDATA2LSB) {
00036     __store_u32L(dst->vna_hash,  src->vna_hash);
00037     __store_u16L(dst->vna_flags, src->vna_flags);
00038     __store_u16L(dst->vna_other, src->vna_other);
00039     __store_u32L(dst->vna_name,  src->vna_name);
00040     __store_u32L(dst->vna_next,  src->vna_next);
00041     }
00042     else {
00043     __store_u32M(dst->vna_hash,  src->vna_hash);
00044     __store_u16M(dst->vna_flags, src->vna_flags);
00045     __store_u16M(dst->vna_other, src->vna_other);
00046     __store_u32M(dst->vna_name,  src->vna_name);
00047     __store_u32M(dst->vna_next,  src->vna_next);
00048     }
00049 }
00050 
00051 static void
00052 __store_verneed(verneed_ftype *dst, const verneed_mtype *src, unsigned enc) {
00053     if (enc == ELFDATA2LSB) {
00054     __store_u16L(dst->vn_version, src->vn_version);
00055     __store_u16L(dst->vn_cnt,     src->vn_cnt);
00056     __store_u32L(dst->vn_file,    src->vn_file);
00057     __store_u32L(dst->vn_aux,     src->vn_aux);
00058     __store_u32L(dst->vn_next,    src->vn_next);
00059     }
00060     else {
00061     __store_u16M(dst->vn_version, src->vn_version);
00062     __store_u16M(dst->vn_cnt,     src->vn_cnt);
00063     __store_u32M(dst->vn_file,    src->vn_file);
00064     __store_u32M(dst->vn_aux,     src->vn_aux);
00065     __store_u32M(dst->vn_next,    src->vn_next);
00066     }
00067 }
00068 
00069 typedef vernaux_mtype       vernaux_stype;
00070 typedef vernaux_ftype       vernaux_dtype;
00071 typedef verneed_mtype       verneed_stype;
00072 typedef verneed_ftype       verneed_dtype;
00073 typedef align_mtype     verneed_atype;
00074 
00075 #define copy_vernaux_srctotmp(d, s, e)  (*(d) = *(s))
00076 #define copy_vernaux_tmptodst(d, s, e)  __store_vernaux((d), (s), (e))
00077 #define copy_verneed_srctotmp(d, s, e)  (*(d) = *(s))
00078 #define copy_verneed_tmptodst(d, s, e)  __store_verneed((d), (s), (e))
00079 
00080 #define translator_suffix   _tof
00081 
00082 #else /* TOFILE */
00083 
00084 static void
00085 __load_vernaux(vernaux_mtype *dst, const vernaux_ftype *src, unsigned enc) {
00086     if (enc == ELFDATA2LSB) {
00087     dst->vna_hash  = __load_u32L(src->vna_hash);
00088     dst->vna_flags = __load_u16L(src->vna_flags);
00089     dst->vna_other = __load_u16L(src->vna_other);
00090     dst->vna_name  = __load_u32L(src->vna_name);
00091     dst->vna_next  = __load_u32L(src->vna_next);
00092     }
00093     else {
00094     dst->vna_hash  = __load_u32M(src->vna_hash);
00095     dst->vna_flags = __load_u16M(src->vna_flags);
00096     dst->vna_other = __load_u16M(src->vna_other);
00097     dst->vna_name  = __load_u32M(src->vna_name);
00098     dst->vna_next  = __load_u32M(src->vna_next);
00099     }
00100 }
00101 
00102 static void
00103 __load_verneed(verneed_mtype *dst, const verneed_ftype *src, unsigned enc) {
00104     if (enc == ELFDATA2LSB) {
00105     dst->vn_version = __load_u16L(src->vn_version);
00106     dst->vn_cnt     = __load_u16L(src->vn_cnt);
00107     dst->vn_file    = __load_u32L(src->vn_file);
00108     dst->vn_aux     = __load_u32L(src->vn_aux);
00109     dst->vn_next    = __load_u32L(src->vn_next);
00110     }
00111     else {
00112     dst->vn_version = __load_u16M(src->vn_version);
00113     dst->vn_cnt     = __load_u16M(src->vn_cnt);
00114     dst->vn_file    = __load_u32M(src->vn_file);
00115     dst->vn_aux     = __load_u32M(src->vn_aux);
00116     dst->vn_next    = __load_u32M(src->vn_next);
00117     }
00118 }
00119 
00120 typedef vernaux_ftype       vernaux_stype;
00121 typedef vernaux_mtype       vernaux_dtype;
00122 typedef verneed_ftype       verneed_stype;
00123 typedef verneed_mtype       verneed_dtype;
00124 typedef align_ftype     verneed_atype;
00125 
00126 #define copy_vernaux_srctotmp(d, s, e)  __load_vernaux((d), (s), (e))
00127 #define copy_vernaux_tmptodst(d, s, e)  (*(d) = *(s))
00128 #define copy_verneed_srctotmp(d, s, e)  __load_verneed((d), (s), (e))
00129 #define copy_verneed_tmptodst(d, s, e)  (*(d) = *(s))
00130 
00131 #define translator_suffix   _tom
00132 
00133 #endif /* TOFILE */
00134 
00135 #define cat3(a,b,c) a##b##c
00136 #define xlt3(p,e,s) cat3(p,e,s)
00137 #define xltprefix(x)    xlt3(x,_,class_suffix)
00138 #define translator(x,e) xlt3(xltprefix(_elf_##x),e,translator_suffix)
00139 
00140 static size_t
00141 xlt_verneed(unsigned char *dst, const unsigned char *src, size_t n, unsigned enc) {
00142     size_t off;
00143 
00144     if (sizeof(verneed_stype) != sizeof(verneed_dtype)
00145      || sizeof(vernaux_stype) != sizeof(vernaux_dtype)) {
00146     /* never happens for ELF v1 and Verneed v1 */
00147     seterr(ERROR_UNIMPLEMENTED);
00148     return (size_t)-1;
00149     }
00150     /* size translation shortcut */
00151     if (dst == NULL) {
00152     return n;
00153     }
00154     if (src == NULL) {
00155     seterr(ERROR_NULLBUF);
00156     return (size_t)-1;
00157     }
00158     off = 0;
00159     while (off + sizeof(verneed_stype) <= n) {
00160     const verneed_stype *svn;
00161     verneed_dtype *dvn;
00162     verneed_mtype vn;
00163     size_t acount;
00164     size_t aoff;
00165 
00166     /*
00167      * check for proper alignment
00168      */
00169     if (off % sizeof(verneed_atype)) {
00170         seterr(ERROR_VERNEED_FORMAT);
00171         return (size_t)-1;
00172     }
00173     /*
00174      * copy and check src
00175      */
00176     svn = (verneed_stype*)(src + off);
00177     dvn = (verneed_dtype*)(dst + off);
00178     copy_verneed_srctotmp(&vn, svn, enc);
00179     if (vn.vn_version < 1
00180      || vn.vn_version > VER_NEED_CURRENT) {
00181         seterr(ERROR_VERNEED_VERSION);
00182         return (size_t)-1;
00183     }
00184     if (vn.vn_cnt < 1
00185      || vn.vn_aux == 0) {
00186         seterr(ERROR_VERNEED_FORMAT);
00187         return (size_t)-1;
00188     }
00189     copy_verneed_tmptodst(dvn, &vn, enc);
00190     /*
00191      * copy aux array
00192      */
00193     aoff = off + vn.vn_aux;
00194     for (acount = 0; acount < vn.vn_cnt; acount++) {
00195         const vernaux_stype *svna;
00196         vernaux_dtype *dvna;
00197         vernaux_mtype vna;
00198 
00199         /*
00200          * are we still inside the buffer limits?
00201          */
00202         if (aoff + sizeof(vernaux_stype) > n) {
00203         break;
00204         }
00205         /*
00206          * check for proper alignment
00207          */
00208         if (aoff % sizeof(verneed_atype)) {
00209         seterr(ERROR_VERNEED_FORMAT);
00210         return (size_t)-1;
00211         }
00212         /*
00213          * copy and check src
00214          */
00215         svna = (vernaux_stype*)(src + aoff);
00216         dvna = (vernaux_dtype*)(dst + aoff);
00217         copy_vernaux_srctotmp(&vna, svna, enc);
00218         copy_vernaux_tmptodst(dvna, &vna, enc);
00219         /*
00220          * advance to next vernaux
00221          */
00222         if (vna.vna_next == 0) {
00223         /* end of list */
00224         break;
00225         }
00226         aoff += vna.vna_next;
00227     }
00228     /*
00229      * advance to next verneed
00230      */
00231     if (vn.vn_next == 0) {
00232         /* end of list */
00233         break;
00234     }
00235     off += vn.vn_next;
00236     }
00237     return n;
00238 }
00239 
00240 size_t
00241 translator(verneed,L11)(unsigned char *dst, const unsigned char *src, size_t n) {
00242     return xlt_verneed(dst, src, n, ELFDATA2LSB);
00243 }
00244 
00245 size_t
00246 translator(verneed,M11)(unsigned char *dst, const unsigned char *src, size_t n) {
00247     return xlt_verneed(dst, src, n, ELFDATA2MSB);
00248 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines