|
1 /* |
|
2 * 64.xlatetof.c - implementation of the elf64_xlateto[fm](3) functions. |
|
3 * Copyright (C) 1995 - 2006 Michael Riepe |
|
4 * |
|
5 * This library is free software; you can redistribute it and/or |
|
6 * modify it under the terms of the GNU Library General Public |
|
7 * License as published by the Free Software Foundation; either |
|
8 * version 2 of the License, or (at your option) any later version. |
|
9 * |
|
10 * This library is distributed in the hope that it will be useful, |
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 * Library General Public License for more details. |
|
14 * |
|
15 * You should have received a copy of the GNU Library General Public |
|
16 * License along with this library; if not, write to the Free Software |
|
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
18 */ |
|
19 |
|
20 #include <private.h> |
|
21 #include <ext_types.h> |
|
22 #include <byteswap.h> |
|
23 |
|
24 #if __LIBELF64 |
|
25 |
|
26 #ifndef lint |
|
27 static const char rcsid[] = "@(#) $Id: 64.xlatetof.c,v 1.26 2006/07/27 22:33:40 michael Exp $"; |
|
28 #endif /* lint */ |
|
29 |
|
30 /* |
|
31 * Ugly, ugly |
|
32 */ |
|
33 #ifdef _WIN32 |
|
34 # define Cat2(a,b)a##b |
|
35 # define Cat3(a,b,c)a##b##c |
|
36 # define Ex1(m1,m2,a,b)m1##m2(a##b) |
|
37 # define Ex2(m1,m2,a,b,c)m1##m2(a,b##c) |
|
38 #else /* _WIN32 */ |
|
39 # define x |
|
40 # if defined/**/x |
|
41 # define Cat2(a,b)a##b |
|
42 # define Cat3(a,b,c)a##b##c |
|
43 # define Ex1(m1,m2,a,b)m1##m2(a##b) |
|
44 # define Ex2(m1,m2,a,b,c)m1##m2(a,b##c) |
|
45 # else |
|
46 # define Cat2(a,b)a/**/b |
|
47 # define Cat3(a,b,c)a/**/b/**/c |
|
48 # define Ex1(m1,m2,a,b)m1/**/m2(a/**/b) |
|
49 # define Ex2(m1,m2,a,b,c)m1/**/m2(a,b/**/c) |
|
50 # endif |
|
51 # undef x |
|
52 #endif /* _WIN32 */ |
|
53 |
|
54 /* |
|
55 * auxiliary macros for execution order reversal |
|
56 */ |
|
57 #define seq_forw(a,b) a b |
|
58 #define seq_back(a,b) b a |
|
59 |
|
60 /* |
|
61 * function instantiator |
|
62 */ |
|
63 #define copy_type_e_io(name,e,io,tfrom,tto,copy) \ |
|
64 static size_t \ |
|
65 Cat3(name,_,io)(unsigned char *dst, const unsigned char *src, size_t n) { \ |
|
66 n /= sizeof(tfrom); \ |
|
67 if (n && dst) { \ |
|
68 const tfrom *from = (const tfrom*)src; \ |
|
69 tto *to = (tto*)dst; \ |
|
70 size_t i; \ |
|
71 \ |
|
72 if (sizeof(tfrom) < sizeof(tto)) { \ |
|
73 from += n; \ |
|
74 to += n; \ |
|
75 for (i = 0; i < n; i++) { \ |
|
76 --from; \ |
|
77 --to; \ |
|
78 copy(e,io,seq_back) \ |
|
79 } \ |
|
80 } \ |
|
81 else { \ |
|
82 for (i = 0; i < n; i++) { \ |
|
83 copy(e,io,seq_forw) \ |
|
84 from++; \ |
|
85 to++; \ |
|
86 } \ |
|
87 } \ |
|
88 } \ |
|
89 return n * sizeof(tto); \ |
|
90 } |
|
91 |
|
92 #define copy_type_e(name,e,type,copy) \ |
|
93 copy_type_e_io(name,e,tom,Cat2(__ext_,type),type,copy) \ |
|
94 copy_type_e_io(name,e,tof,type,Cat2(__ext_,type),copy) |
|
95 |
|
96 /* |
|
97 * master function instantiator |
|
98 */ |
|
99 #define copy_type(name,version,type,copy) \ |
|
100 copy_type_e(Cat3(name,L,version),L,type,copy) \ |
|
101 copy_type_e(Cat3(name,M,version),M,type,copy) |
|
102 |
|
103 /* |
|
104 * scalar copying |
|
105 */ |
|
106 #define copy_scalar_tom(type) *to = Cat2(__load_,type)(*from); |
|
107 #define copy_scalar_tof(type) Cat2(__store_,type)(*to, *from); |
|
108 |
|
109 /* |
|
110 * structure member copying |
|
111 */ |
|
112 #define copy_tom(mb,type) to->mb = Cat2(__load_,type)(from->mb); |
|
113 #define copy_tof(mb,type) Cat2(__store_,type)(to->mb, from->mb); |
|
114 |
|
115 /* |
|
116 * structure member copying (direction independent) |
|
117 */ |
|
118 #define copy_byte(e,io,mb) to->mb = from->mb; |
|
119 #define copy_addr(e,io,mb) Ex2(copy_,io,mb,u64,e) |
|
120 #define copy_half(e,io,mb) Ex2(copy_,io,mb,u16,e) |
|
121 #define copy_off(e,io,mb) Ex2(copy_,io,mb,u64,e) |
|
122 #define copy_sword(e,io,mb) Ex2(copy_,io,mb,i32,e) |
|
123 #define copy_word(e,io,mb) Ex2(copy_,io,mb,u32,e) |
|
124 #define copy_sxword(e,io,mb) Ex2(copy_,io,mb,i64,e) |
|
125 #define copy_xword(e,io,mb) Ex2(copy_,io,mb,u64,e) |
|
126 #define copy_arr(e,io,mb) \ |
|
127 array_copy(to->mb, sizeof(to->mb), from->mb, sizeof(from->mb)); |
|
128 |
|
129 /* |
|
130 * scalar copying (direction independent) |
|
131 * these macros are used as `copy' arguments to copy_type() |
|
132 */ |
|
133 #define copy_addr_11(e,io,seq) Ex1(copy_scalar_,io,u64,e) |
|
134 #define copy_half_11(e,io,seq) Ex1(copy_scalar_,io,u16,e) |
|
135 #define copy_off_11(e,io,seq) Ex1(copy_scalar_,io,u64,e) |
|
136 #define copy_sword_11(e,io,seq) Ex1(copy_scalar_,io,i32,e) |
|
137 #define copy_word_11(e,io,seq) Ex1(copy_scalar_,io,u32,e) |
|
138 #define copy_sxword_11(e,io,seq)Ex1(copy_scalar_,io,i64,e) |
|
139 #define copy_xword_11(e,io,seq) Ex1(copy_scalar_,io,u64,e) |
|
140 |
|
141 /* |
|
142 * structure copying (direction independent) |
|
143 * these macros are used as `copy' arguments to copy_type() |
|
144 */ |
|
145 #define copy_dyn_11(e,io,seq) \ |
|
146 seq(copy_xword(e,io,d_tag), \ |
|
147 seq(copy_addr(e,io,d_un.d_ptr), \ |
|
148 nullcopy)) |
|
149 #define copy_ehdr_11(e,io,seq) \ |
|
150 seq(copy_arr(e,io,e_ident), \ |
|
151 seq(copy_half(e,io,e_type), \ |
|
152 seq(copy_half(e,io,e_machine), \ |
|
153 seq(copy_word(e,io,e_version), \ |
|
154 seq(copy_addr(e,io,e_entry), \ |
|
155 seq(copy_off(e,io,e_phoff), \ |
|
156 seq(copy_off(e,io,e_shoff), \ |
|
157 seq(copy_word(e,io,e_flags), \ |
|
158 seq(copy_half(e,io,e_ehsize), \ |
|
159 seq(copy_half(e,io,e_phentsize), \ |
|
160 seq(copy_half(e,io,e_phnum), \ |
|
161 seq(copy_half(e,io,e_shentsize), \ |
|
162 seq(copy_half(e,io,e_shnum), \ |
|
163 seq(copy_half(e,io,e_shstrndx), \ |
|
164 nullcopy)))))))))))))) |
|
165 #define copy_phdr_11(e,io,seq) \ |
|
166 seq(copy_word(e,io,p_type), \ |
|
167 seq(copy_word(e,io,p_flags), \ |
|
168 seq(copy_off(e,io,p_offset), \ |
|
169 seq(copy_addr(e,io,p_vaddr), \ |
|
170 seq(copy_addr(e,io,p_paddr), \ |
|
171 seq(copy_xword(e,io,p_filesz), \ |
|
172 seq(copy_xword(e,io,p_memsz), \ |
|
173 seq(copy_xword(e,io,p_align), \ |
|
174 nullcopy)))))))) |
|
175 #if __LIBELF64_IRIX |
|
176 #define copy_rela_11(e,io,seq) \ |
|
177 seq(copy_addr(e,io,r_offset), \ |
|
178 seq(copy_word(e,io,r_sym), \ |
|
179 seq(copy_byte(e,io,r_ssym), \ |
|
180 seq(copy_byte(e,io,r_type3), \ |
|
181 seq(copy_byte(e,io,r_type2), \ |
|
182 seq(copy_byte(e,io,r_type), \ |
|
183 seq(copy_sxword(e,io,r_addend), \ |
|
184 nullcopy))))))) |
|
185 #define copy_rel_11(e,io,seq) \ |
|
186 seq(copy_addr(e,io,r_offset), \ |
|
187 seq(copy_word(e,io,r_sym), \ |
|
188 seq(copy_byte(e,io,r_ssym), \ |
|
189 seq(copy_byte(e,io,r_type3), \ |
|
190 seq(copy_byte(e,io,r_type2), \ |
|
191 seq(copy_byte(e,io,r_type), \ |
|
192 nullcopy)))))) |
|
193 #else /* __LIBELF64_IRIX */ |
|
194 #define copy_rela_11(e,io,seq) \ |
|
195 seq(copy_addr(e,io,r_offset), \ |
|
196 seq(copy_xword(e,io,r_info), \ |
|
197 seq(copy_sxword(e,io,r_addend), \ |
|
198 nullcopy))) |
|
199 #define copy_rel_11(e,io,seq) \ |
|
200 seq(copy_addr(e,io,r_offset), \ |
|
201 seq(copy_xword(e,io,r_info), \ |
|
202 nullcopy)) |
|
203 #endif /* __LIBELF64_IRIX */ |
|
204 #define copy_shdr_11(e,io,seq) \ |
|
205 seq(copy_word(e,io,sh_name), \ |
|
206 seq(copy_word(e,io,sh_type), \ |
|
207 seq(copy_xword(e,io,sh_flags), \ |
|
208 seq(copy_addr(e,io,sh_addr), \ |
|
209 seq(copy_off(e,io,sh_offset), \ |
|
210 seq(copy_xword(e,io,sh_size), \ |
|
211 seq(copy_word(e,io,sh_link), \ |
|
212 seq(copy_word(e,io,sh_info), \ |
|
213 seq(copy_xword(e,io,sh_addralign), \ |
|
214 seq(copy_xword(e,io,sh_entsize), \ |
|
215 nullcopy)))))))))) |
|
216 #define copy_sym_11(e,io,seq) \ |
|
217 seq(copy_word(e,io,st_name), \ |
|
218 seq(copy_byte(e,io,st_info), \ |
|
219 seq(copy_byte(e,io,st_other), \ |
|
220 seq(copy_half(e,io,st_shndx), \ |
|
221 seq(copy_addr(e,io,st_value), \ |
|
222 seq(copy_xword(e,io,st_size), \ |
|
223 nullcopy)))))) |
|
224 |
|
225 #define nullcopy /**/ |
|
226 |
|
227 static size_t |
|
228 byte_copy(unsigned char *dst, const unsigned char *src, size_t n) { |
|
229 if (n && dst && dst != src) { |
|
230 #if HAVE_BROKEN_MEMMOVE |
|
231 size_t i; |
|
232 |
|
233 if (dst >= src + n || dst + n <= src) { |
|
234 memcpy(dst, src, n); |
|
235 } |
|
236 else if (dst < src) { |
|
237 for (i = 0; i < n; i++) { |
|
238 dst[i] = src[i]; |
|
239 } |
|
240 } |
|
241 else { |
|
242 for (i = n; --i; ) { |
|
243 dst[i] = src[i]; |
|
244 } |
|
245 } |
|
246 #else /* HAVE_BROKEN_MEMMOVE */ |
|
247 memmove(dst, src, n); |
|
248 #endif /* HAVE_BROKEN_MEMMOVE */ |
|
249 } |
|
250 return n; |
|
251 } |
|
252 |
|
253 static void |
|
254 array_copy(unsigned char *dst, size_t dlen, const unsigned char *src, size_t slen) { |
|
255 byte_copy(dst, src, dlen < slen ? dlen : slen); |
|
256 if (dlen > slen) { |
|
257 memset(dst + slen, 0, dlen - slen); |
|
258 } |
|
259 } |
|
260 |
|
261 /* |
|
262 * instantiate copy functions |
|
263 */ |
|
264 copy_type(addr_64,_,Elf64_Addr,copy_addr_11) |
|
265 copy_type(half_64,_,Elf64_Half,copy_half_11) |
|
266 copy_type(off_64,_,Elf64_Off,copy_off_11) |
|
267 copy_type(sword_64,_,Elf64_Sword,copy_sword_11) |
|
268 copy_type(word_64,_,Elf64_Word,copy_word_11) |
|
269 copy_type(sxword_64,_,Elf64_Sxword,copy_sxword_11) |
|
270 copy_type(xword_64,_,Elf64_Xword,copy_xword_11) |
|
271 copy_type(dyn_64,11,Elf64_Dyn,copy_dyn_11) |
|
272 copy_type(ehdr_64,11,Elf64_Ehdr,copy_ehdr_11) |
|
273 copy_type(phdr_64,11,Elf64_Phdr,copy_phdr_11) |
|
274 copy_type(rela_64,11,Elf64_Rela,copy_rela_11) |
|
275 copy_type(rel_64,11,Elf64_Rel,copy_rel_11) |
|
276 copy_type(shdr_64,11,Elf64_Shdr,copy_shdr_11) |
|
277 copy_type(sym_64,11,Elf64_Sym,copy_sym_11) |
|
278 |
|
279 typedef size_t (*xlator)(unsigned char*, const unsigned char*, size_t); |
|
280 typedef xlator xltab[ELF_T_NUM][2]; |
|
281 |
|
282 /* |
|
283 * translation table (64-bit, version 1 -> version 1) |
|
284 */ |
|
285 #if PIC |
|
286 static xltab |
|
287 #else /* PIC */ |
|
288 static const xltab |
|
289 #endif /* PIC */ |
|
290 xlate64_11[/*encoding*/] = { |
|
291 { |
|
292 { byte_copy, byte_copy }, |
|
293 { addr_64L__tom, addr_64L__tof }, |
|
294 { dyn_64L11_tom, dyn_64L11_tof }, |
|
295 { ehdr_64L11_tom, ehdr_64L11_tof }, |
|
296 { half_64L__tom, half_64L__tof }, |
|
297 { off_64L__tom, off_64L__tof }, |
|
298 { phdr_64L11_tom, phdr_64L11_tof }, |
|
299 { rela_64L11_tom, rela_64L11_tof }, |
|
300 { rel_64L11_tom, rel_64L11_tof }, |
|
301 { shdr_64L11_tom, shdr_64L11_tof }, |
|
302 { sword_64L__tom, sword_64L__tof }, |
|
303 { sym_64L11_tom, sym_64L11_tof }, |
|
304 { word_64L__tom, word_64L__tof }, |
|
305 { sxword_64L__tom, sxword_64L__tof }, |
|
306 { xword_64L__tom, xword_64L__tof }, |
|
307 #if __LIBELF_SYMBOL_VERSIONS |
|
308 { _elf_verdef_64L11_tom, _elf_verdef_64L11_tof }, |
|
309 { _elf_verneed_64L11_tom, _elf_verneed_64L11_tof }, |
|
310 #else /* __LIBELF_SYMBOL_VERSIONS */ |
|
311 { 0, 0 }, |
|
312 { 0, 0 }, |
|
313 #endif /* __LIBELF_SYMBOL_VERSIONS */ |
|
314 }, |
|
315 { |
|
316 { byte_copy, byte_copy }, |
|
317 { addr_64M__tom, addr_64M__tof }, |
|
318 { dyn_64M11_tom, dyn_64M11_tof }, |
|
319 { ehdr_64M11_tom, ehdr_64M11_tof }, |
|
320 { half_64M__tom, half_64M__tof }, |
|
321 { off_64M__tom, off_64M__tof }, |
|
322 { phdr_64M11_tom, phdr_64M11_tof }, |
|
323 { rela_64M11_tom, rela_64M11_tof }, |
|
324 { rel_64M11_tom, rel_64M11_tof }, |
|
325 { shdr_64M11_tom, shdr_64M11_tof }, |
|
326 { sword_64M__tom, sword_64M__tof }, |
|
327 { sym_64M11_tom, sym_64M11_tof }, |
|
328 { word_64M__tom, word_64M__tof }, |
|
329 { sxword_64M__tom, sxword_64M__tof }, |
|
330 { xword_64M__tom, xword_64M__tof }, |
|
331 #if __LIBELF_SYMBOL_VERSIONS |
|
332 { _elf_verdef_64M11_tom, _elf_verdef_64M11_tof }, |
|
333 { _elf_verneed_64M11_tom, _elf_verneed_64M11_tof }, |
|
334 #else /* __LIBELF_SYMBOL_VERSIONS */ |
|
335 { 0, 0 }, |
|
336 { 0, 0 }, |
|
337 #endif /* __LIBELF_SYMBOL_VERSIONS */ |
|
338 }, |
|
339 }; |
|
340 |
|
341 /* |
|
342 * main translation table (64-bit) |
|
343 */ |
|
344 #if PIC |
|
345 static xltab* |
|
346 #else /* PIC */ |
|
347 static const xltab *const |
|
348 #endif /* PIC */ |
|
349 xlate64[EV_CURRENT - EV_NONE][EV_CURRENT - EV_NONE] = { |
|
350 { xlate64_11, }, |
|
351 }; |
|
352 |
|
353 #define translator(sv,dv,enc,type,d) \ |
|
354 (xlate64[(sv) - EV_NONE - 1] \ |
|
355 [(dv) - EV_NONE - 1] \ |
|
356 [(enc) - ELFDATA2LSB] \ |
|
357 [(type) - ELF_T_BYTE] \ |
|
358 [d]) |
|
359 |
|
360 /* |
|
361 * destination buffer size |
|
362 */ |
|
363 size_t |
|
364 _elf64_xltsize(const Elf_Data *src, unsigned dv, unsigned encode, int tof) { |
|
365 Elf_Type type = src->d_type; |
|
366 unsigned sv = src->d_version; |
|
367 xlator op; |
|
368 |
|
369 if (!valid_version(sv) || !valid_version(dv)) { |
|
370 seterr(ERROR_UNKNOWN_VERSION); |
|
371 return (size_t)-1; |
|
372 } |
|
373 if (tof) { |
|
374 /* |
|
375 * Encoding doesn't really matter (the translator only looks at |
|
376 * the source, which resides in memory), but we need a proper |
|
377 * encoding to select a translator... |
|
378 */ |
|
379 encode = ELFDATA2LSB; |
|
380 } |
|
381 else if (!valid_encoding(encode)) { |
|
382 seterr(ERROR_UNKNOWN_ENCODING); |
|
383 return (size_t)-1; |
|
384 } |
|
385 if (!valid_type(type)) { |
|
386 seterr(ERROR_UNKNOWN_TYPE); |
|
387 return (size_t)-1; |
|
388 } |
|
389 if (!(op = translator(sv, dv, encode, type, tof))) { |
|
390 seterr(ERROR_UNKNOWN_TYPE); |
|
391 return (size_t)-1; |
|
392 } |
|
393 return (*op)(NULL, src->d_buf, src->d_size); |
|
394 } |
|
395 |
|
396 /* |
|
397 * direction-independent translation |
|
398 */ |
|
399 static Elf_Data* |
|
400 elf64_xlate(Elf_Data *dst, const Elf_Data *src, unsigned encode, int tof) { |
|
401 Elf_Type type; |
|
402 int dv; |
|
403 int sv; |
|
404 size_t dsize; |
|
405 size_t tmp; |
|
406 xlator op; |
|
407 |
|
408 if (!src || !dst) { |
|
409 return NULL; |
|
410 } |
|
411 if (!src->d_buf || !dst->d_buf) { |
|
412 seterr(ERROR_NULLBUF); |
|
413 return NULL; |
|
414 } |
|
415 if (!valid_encoding(encode)) { |
|
416 seterr(ERROR_UNKNOWN_ENCODING); |
|
417 return NULL; |
|
418 } |
|
419 sv = src->d_version; |
|
420 dv = dst->d_version; |
|
421 if (!valid_version(sv) || !valid_version(dv)) { |
|
422 seterr(ERROR_UNKNOWN_VERSION); |
|
423 return NULL; |
|
424 } |
|
425 type = src->d_type; |
|
426 if (!valid_type(type)) { |
|
427 seterr(ERROR_UNKNOWN_TYPE); |
|
428 return NULL; |
|
429 } |
|
430 op = translator(sv, dv, encode, type, tof); |
|
431 if (!op) { |
|
432 seterr(ERROR_UNKNOWN_TYPE); |
|
433 return NULL; |
|
434 } |
|
435 dsize = (*op)(NULL, src->d_buf, src->d_size); |
|
436 if (dsize == (size_t)-1) { |
|
437 return NULL; |
|
438 } |
|
439 if (dst->d_size < dsize) { |
|
440 seterr(ERROR_DST2SMALL); |
|
441 return NULL; |
|
442 } |
|
443 if (dsize) { |
|
444 tmp = (*op)(dst->d_buf, src->d_buf, src->d_size); |
|
445 if (tmp == (size_t)-1) { |
|
446 return NULL; |
|
447 } |
|
448 elf_assert(tmp == dsize); |
|
449 } |
|
450 dst->d_size = dsize; |
|
451 dst->d_type = type; |
|
452 return dst; |
|
453 } |
|
454 |
|
455 /* |
|
456 * finally, the "official" translation functions |
|
457 */ |
|
458 Elf_Data* |
|
459 elf64_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned encode) { |
|
460 return elf64_xlate(dst, src, encode, 0); |
|
461 } |
|
462 |
|
463 Elf_Data* |
|
464 elf64_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned encode) { |
|
465 return elf64_xlate(dst, src, encode, 1); |
|
466 } |
|
467 |
|
468 Elf_Data* |
|
469 gelf_xlatetom(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) { |
|
470 if (elf) { |
|
471 if (elf->e_kind != ELF_K_ELF) { |
|
472 seterr(ERROR_NOTELF); |
|
473 } |
|
474 else if (elf->e_class == ELFCLASS32) { |
|
475 return elf32_xlatetom(dst, src, encode); |
|
476 } |
|
477 else if (elf->e_class == ELFCLASS64) { |
|
478 return elf64_xlatetom(dst, src, encode); |
|
479 } |
|
480 else if (valid_class(elf->e_class)) { |
|
481 seterr(ERROR_UNIMPLEMENTED); |
|
482 } |
|
483 else { |
|
484 seterr(ERROR_UNKNOWN_CLASS); |
|
485 } |
|
486 } |
|
487 return NULL; |
|
488 } |
|
489 |
|
490 Elf_Data* |
|
491 gelf_xlatetof(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) { |
|
492 if (elf) { |
|
493 if (elf->e_kind != ELF_K_ELF) { |
|
494 seterr(ERROR_NOTELF); |
|
495 } |
|
496 else if (elf->e_class == ELFCLASS32) { |
|
497 return elf32_xlatetof(dst, src, encode); |
|
498 } |
|
499 else if (elf->e_class == ELFCLASS64) { |
|
500 return elf64_xlatetof(dst, src, encode); |
|
501 } |
|
502 else if (valid_class(elf->e_class)) { |
|
503 seterr(ERROR_UNIMPLEMENTED); |
|
504 } |
|
505 else { |
|
506 seterr(ERROR_UNKNOWN_CLASS); |
|
507 } |
|
508 } |
|
509 return NULL; |
|
510 } |
|
511 |
|
512 #endif /* __LIBELF64__ */ |