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