Phoenix
Object-oriented orthogonally persistent operating system
|
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 }