00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <private.h>
00025 #include <ext_types.h>
00026 #include <byteswap.h>
00027
00028 #ifndef lint
00029 static const char rcsid[] = "@(#) $Id: 32.xlatetof.c,v 1.1.1.1 2005/10/21 19:00:00 marcel Exp $";
00030 #endif
00031
00032
00033
00034
00035 #define x
00036 #if definedx
00037 # define Cat2(a,b)a##b
00038 # define Cat3(a,b,c)a##b##c
00039 # define Ex1(m1,m2,a,b)m1##m2(a##b)
00040 # define Ex2(m1,m2,a,b,c)m1##m2(a,b##c)
00041 #else
00042 # define Cat2(a,b)ab
00043 # define Cat3(a,b,c)abc
00044 # define Ex1(m1,m2,a,b)m1m2(ab)
00045 # define Ex2(m1,m2,a,b,c)m1m2(a,bc)
00046 #endif
00047 #undef x
00048
00049
00050
00051
00052 #define seq_forw(a,b) a b
00053 #define seq_back(a,b) b a
00054
00055
00056
00057
00058 #define copy_type_e_io(name,e,io,tfrom,tto,copy) \
00059 static size_t \
00060 Cat3(name,_,io)(unsigned char *dst, const unsigned char *src, size_t n) { \
00061 n /= sizeof(tfrom); \
00062 if (n && dst) { \
00063 const tfrom *from = (const tfrom*)src; \
00064 tto *to = (tto*)dst; \
00065 size_t i; \
00066 \
00067 if (sizeof(tfrom) < sizeof(tto)) { \
00068 from += n; \
00069 to += n; \
00070 for (i = 0; i < n; i++) { \
00071 --from; \
00072 --to; \
00073 copy(e,io,seq_back) \
00074 } \
00075 } \
00076 else { \
00077 for (i = 0; i < n; i++) { \
00078 copy(e,io,seq_forw) \
00079 from++; \
00080 to++; \
00081 } \
00082 } \
00083 } \
00084 return n * sizeof(tto); \
00085 }
00086
00087 #define copy_type_e(name,e,type,copy) \
00088 copy_type_e_io(name,e,tom,Cat2(__ext_,type),type,copy) \
00089 copy_type_e_io(name,e,tof,type,Cat2(__ext_,type),copy)
00090
00091
00092
00093
00094 #define copy_type(name,version,type,copy) \
00095 copy_type_e(Cat3(name,L,version),L,type,copy) \
00096 copy_type_e(Cat3(name,M,version),M,type,copy)
00097
00098
00099
00100
00101 #define copy_scalar_tom(type) *to = Cat2(__load_,type)(*from);
00102 #define copy_scalar_tof(type) Cat2(__store_,type)(*to, *from);
00103
00104
00105
00106
00107 #define copy_tom(mb,type) to->mb = Cat2(__load_,type)(from->mb);
00108 #define copy_tof(mb,type) Cat2(__store_,type)(to->mb, from->mb);
00109
00110
00111
00112
00113 #define copy_byte(e,io,mb) to->mb = from->mb;
00114 #define copy_addr(e,io,mb) Ex2(copy_,io,mb,u32,e)
00115 #define copy_half(e,io,mb) Ex2(copy_,io,mb,u16,e)
00116 #define copy_off(e,io,mb) Ex2(copy_,io,mb,u32,e)
00117 #define copy_sword(e,io,mb) Ex2(copy_,io,mb,i32,e)
00118 #define copy_word(e,io,mb) Ex2(copy_,io,mb,u32,e)
00119 #define copy_arr(e,io,mb) \
00120 array_copy(to->mb, sizeof(to->mb), from->mb, sizeof(from->mb));
00121
00122
00123
00124
00125
00126 #define copy_addr_11(e,io,seq) Ex1(copy_scalar_,io,u32,e)
00127 #define copy_half_11(e,io,seq) Ex1(copy_scalar_,io,u16,e)
00128 #define copy_off_11(e,io,seq) Ex1(copy_scalar_,io,u32,e)
00129 #define copy_sword_11(e,io,seq) Ex1(copy_scalar_,io,i32,e)
00130 #define copy_word_11(e,io,seq) Ex1(copy_scalar_,io,u32,e)
00131
00132
00133
00134
00135
00136 #define copy_dyn_11(e,io,seq) \
00137 seq(copy_sword(e,io,d_tag), \
00138 seq(copy_addr(e,io,d_un.d_ptr), \
00139 nullcopy))
00140 #define copy_ehdr_11(e,io,seq) \
00141 seq(copy_arr(e,io,e_ident), \
00142 seq(copy_half(e,io,e_type), \
00143 seq(copy_half(e,io,e_machine), \
00144 seq(copy_word(e,io,e_version), \
00145 seq(copy_addr(e,io,e_entry), \
00146 seq(copy_off(e,io,e_phoff), \
00147 seq(copy_off(e,io,e_shoff), \
00148 seq(copy_word(e,io,e_flags), \
00149 seq(copy_half(e,io,e_ehsize), \
00150 seq(copy_half(e,io,e_phentsize), \
00151 seq(copy_half(e,io,e_phnum), \
00152 seq(copy_half(e,io,e_shentsize), \
00153 seq(copy_half(e,io,e_shnum), \
00154 seq(copy_half(e,io,e_shstrndx), \
00155 nullcopy))))))))))))))
00156 #define copy_phdr_11(e,io,seq) \
00157 seq(copy_word(e,io,p_type), \
00158 seq(copy_off(e,io,p_offset), \
00159 seq(copy_addr(e,io,p_vaddr), \
00160 seq(copy_addr(e,io,p_paddr), \
00161 seq(copy_word(e,io,p_filesz), \
00162 seq(copy_word(e,io,p_memsz), \
00163 seq(copy_word(e,io,p_flags), \
00164 seq(copy_word(e,io,p_align), \
00165 nullcopy))))))))
00166 #define copy_rela_11(e,io,seq) \
00167 seq(copy_addr(e,io,r_offset), \
00168 seq(copy_word(e,io,r_info), \
00169 seq(copy_sword(e,io,r_addend), \
00170 nullcopy)))
00171 #define copy_rel_11(e,io,seq) \
00172 seq(copy_addr(e,io,r_offset), \
00173 seq(copy_word(e,io,r_info), \
00174 nullcopy))
00175 #define copy_shdr_11(e,io,seq) \
00176 seq(copy_word(e,io,sh_name), \
00177 seq(copy_word(e,io,sh_type), \
00178 seq(copy_word(e,io,sh_flags), \
00179 seq(copy_addr(e,io,sh_addr), \
00180 seq(copy_off(e,io,sh_offset), \
00181 seq(copy_word(e,io,sh_size), \
00182 seq(copy_word(e,io,sh_link), \
00183 seq(copy_word(e,io,sh_info), \
00184 seq(copy_word(e,io,sh_addralign), \
00185 seq(copy_word(e,io,sh_entsize), \
00186 nullcopy))))))))))
00187 #define copy_sym_11(e,io,seq) \
00188 seq(copy_word(e,io,st_name), \
00189 seq(copy_addr(e,io,st_value), \
00190 seq(copy_word(e,io,st_size), \
00191 seq(copy_byte(e,io,st_info), \
00192 seq(copy_byte(e,io,st_other), \
00193 seq(copy_half(e,io,st_shndx), \
00194 nullcopy))))))
00195
00196 #define nullcopy
00197
00198 static size_t
00199 byte_copy(unsigned char *dst, const unsigned char *src, size_t n) {
00200 if (n && dst && dst != src) {
00201 #if HAVE_BROKEN_MEMMOVE
00202 size_t i;
00203
00204 if (dst >= src + n || dst + n <= src) {
00205 memcpy(dst, src, n);
00206 }
00207 else if (dst < src) {
00208 for (i = 0; i < n; i++) {
00209 dst[i] = src[i];
00210 }
00211 }
00212 else {
00213 for (i = n; --i; ) {
00214 dst[i] = src[i];
00215 }
00216 }
00217 #else
00218 memmove(dst, src, n);
00219 #endif
00220 }
00221 return n;
00222 }
00223
00224 static void
00225 array_copy(unsigned char *dst, size_t dlen, const unsigned char *src, size_t slen) {
00226 byte_copy(dst, src, dlen < slen ? dlen : slen);
00227 if (dlen > slen) {
00228 memset(dst + slen, 0, dlen - slen);
00229 }
00230 }
00231
00232
00233
00234
00235 copy_type(addr_32,_,Elf32_Addr,copy_addr_11)
00236 copy_type(half_32,_,Elf32_Half,copy_half_11)
00237 copy_type(off_32,_,Elf32_Off,copy_off_11)
00238 copy_type(sword_32,_,Elf32_Sword,copy_sword_11)
00239 copy_type(word_32,_,Elf32_Word,copy_word_11)
00240 copy_type(dyn_32,11,Elf32_Dyn,copy_dyn_11)
00241 copy_type(ehdr_32,11,Elf32_Ehdr,copy_ehdr_11)
00242 copy_type(phdr_32,11,Elf32_Phdr,copy_phdr_11)
00243 copy_type(rela_32,11,Elf32_Rela,copy_rela_11)
00244 copy_type(rel_32,11,Elf32_Rel,copy_rel_11)
00245 copy_type(shdr_32,11,Elf32_Shdr,copy_shdr_11)
00246 copy_type(sym_32,11,Elf32_Sym,copy_sym_11)
00247
00248 typedef size_t (*xlator)(unsigned char*, const unsigned char*, size_t);
00249 typedef xlator xltab[ELF_T_NUM][2];
00250
00251
00252
00253
00254 #if PIC
00255 static xltab
00256 #else
00257 static const xltab
00258 #endif
00259 xlate32_11[] = {
00260 {
00261 { byte_copy, byte_copy },
00262 { addr_32L__tom, addr_32L__tof },
00263 { dyn_32L11_tom, dyn_32L11_tof },
00264 { ehdr_32L11_tom, ehdr_32L11_tof },
00265 { half_32L__tom, half_32L__tof },
00266 { off_32L__tom, off_32L__tof },
00267 { phdr_32L11_tom, phdr_32L11_tof },
00268 { rela_32L11_tom, rela_32L11_tof },
00269 { rel_32L11_tom, rel_32L11_tof },
00270 { shdr_32L11_tom, shdr_32L11_tof },
00271 { sword_32L__tom, sword_32L__tof },
00272 { sym_32L11_tom, sym_32L11_tof },
00273 { word_32L__tom, word_32L__tof },
00274 { NULL, NULL },
00275 { NULL, NULL },
00276 #if __LIBELF_SYMBOL_VERSIONS
00277 { _elf_verdef_32L11_tom, _elf_verdef_32L11_tof },
00278 { _elf_verneed_32L11_tom, _elf_verneed_32L11_tof },
00279 #else
00280 { NULL, NULL },
00281 { NULL, NULL },
00282 #endif
00283 },
00284 {
00285 { byte_copy, byte_copy },
00286 { addr_32M__tom, addr_32M__tof },
00287 { dyn_32M11_tom, dyn_32M11_tof },
00288 { ehdr_32M11_tom, ehdr_32M11_tof },
00289 { half_32M__tom, half_32M__tof },
00290 { off_32M__tom, off_32M__tof },
00291 { phdr_32M11_tom, phdr_32M11_tof },
00292 { rela_32M11_tom, rela_32M11_tof },
00293 { rel_32M11_tom, rel_32M11_tof },
00294 { shdr_32M11_tom, shdr_32M11_tof },
00295 { sword_32M__tom, sword_32M__tof },
00296 { sym_32M11_tom, sym_32M11_tof },
00297 { word_32M__tom, word_32M__tof },
00298 { NULL, NULL },
00299 { NULL, NULL },
00300 #if __LIBELF_SYMBOL_VERSIONS
00301 { _elf_verdef_32M11_tom, _elf_verdef_32M11_tof },
00302 { _elf_verneed_32M11_tom, _elf_verneed_32M11_tof },
00303 #else
00304 { NULL, NULL },
00305 { NULL, NULL },
00306 #endif
00307 },
00308 };
00309
00310
00311
00312
00313 #if PIC
00314 static xltab*
00315 #else
00316 static const xltab *const
00317 #endif
00318 xlate32[EV_CURRENT - EV_NONE][EV_CURRENT - EV_NONE] = {
00319 { xlate32_11, },
00320 };
00321
00322 #define translator(sv,dv,enc,type,d) \
00323 (xlate32[(sv) - EV_NONE - 1] \
00324 [(dv) - EV_NONE - 1] \
00325 [(enc) - ELFDATA2LSB] \
00326 [(type) - ELF_T_BYTE] \
00327 [d])
00328
00329
00330
00331
00332 size_t
00333 _elf32_xltsize(const Elf_Data *src, unsigned dv, unsigned encode, int tof) {
00334 Elf_Type type = src->d_type;
00335 unsigned sv = src->d_version;
00336 xlator op;
00337
00338 if (!valid_version(sv) || !valid_version(dv)) {
00339 seterr(ERROR_UNKNOWN_VERSION);
00340 return (size_t)-1;
00341 }
00342 if (tof) {
00343
00344
00345
00346
00347
00348 encode = ELFDATA2LSB;
00349 }
00350 else if (!valid_encoding(encode)) {
00351 seterr(ERROR_UNKNOWN_ENCODING);
00352 return (size_t)-1;
00353 }
00354 if (!valid_type(type)) {
00355 seterr(ERROR_UNKNOWN_TYPE);
00356 return (size_t)-1;
00357 }
00358 if (!(op = translator(sv, dv, encode, type, tof))) {
00359 seterr(ERROR_UNKNOWN_TYPE);
00360 return (size_t)-1;
00361 }
00362 return (*op)(NULL, src->d_buf, src->d_size);
00363 }
00364
00365
00366
00367
00368 static Elf_Data*
00369 elf32_xlate(Elf_Data *dst, const Elf_Data *src, unsigned encode, int tof) {
00370 Elf_Type type;
00371 int dv;
00372 int sv;
00373 size_t dsize;
00374 size_t tmp;
00375 xlator op;
00376
00377 if (!src || !dst) {
00378 return NULL;
00379 }
00380 if (!src->d_buf || !dst->d_buf) {
00381 seterr(ERROR_NULLBUF);
00382 return NULL;
00383 }
00384 if (!valid_encoding(encode)) {
00385 seterr(ERROR_UNKNOWN_ENCODING);
00386 return NULL;
00387 }
00388 sv = src->d_version;
00389 dv = dst->d_version;
00390 if (!valid_version(sv) || !valid_version(dv)) {
00391 seterr(ERROR_UNKNOWN_VERSION);
00392 return NULL;
00393 }
00394 type = src->d_type;
00395 if (!valid_type(type)) {
00396 seterr(ERROR_UNKNOWN_TYPE);
00397 return NULL;
00398 }
00399 op = translator(sv, dv, encode, type, tof);
00400 if (!op) {
00401 seterr(ERROR_UNKNOWN_TYPE);
00402 return NULL;
00403 }
00404 dsize = (*op)(NULL, src->d_buf, src->d_size);
00405 if (dst->d_size < dsize) {
00406 seterr(ERROR_DST2SMALL);
00407 return NULL;
00408 }
00409 if (dsize) {
00410 tmp = (*op)(dst->d_buf, src->d_buf, src->d_size);
00411 elf_assert(tmp == dsize);
00412 }
00413 dst->d_size = dsize;
00414 dst->d_type = type;
00415 return dst;
00416 }
00417
00418
00419
00420
00421 Elf_Data*
00422 elf32_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned encode) {
00423 return elf32_xlate(dst, src, encode, 0);
00424 }
00425
00426 Elf_Data*
00427 elf32_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned encode) {
00428 return elf32_xlate(dst, src, encode, 1);
00429 }