Git init
[external/libelf.git] / lib / gelfshdr.c
1 /*
2  * gelfshdr.c - gelf_* translation functions.
3  * Copyright (C) 2000 - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 #include <private.h>
21
22 #if __LIBELF64
23
24 #ifndef lint
25 static const char rcsid[] = "@(#) $Id: gelfshdr.c,v 1.10 2008/05/23 08:15:34 michael Exp $";
26 #endif /* lint */
27
28 #define check_and_copy(type, d, s, name, eret)          \
29     do {                                                \
30         if (sizeof((d)->name) < sizeof((s)->name)       \
31          && (type)(s)->name != (s)->name) {             \
32             seterr(ERROR_BADVALUE);                     \
33             return (eret);                              \
34         }                                               \
35         (d)->name = (type)(s)->name;                    \
36     } while (0)
37
38 GElf_Shdr*
39 gelf_getshdr(Elf_Scn *scn, GElf_Shdr *dst) {
40     GElf_Shdr buf;
41
42     if (!scn) {
43         return NULL;
44     }
45     elf_assert(scn->s_magic == SCN_MAGIC);
46     elf_assert(scn->s_elf);
47     elf_assert(scn->s_elf->e_magic == ELF_MAGIC);
48     if (!dst) {
49         dst = &buf;
50     }
51     if (scn->s_elf->e_class == ELFCLASS64) {
52         *dst = scn->s_shdr64;
53     }
54     else if (scn->s_elf->e_class == ELFCLASS32) {
55         Elf32_Shdr *src = &scn->s_shdr32;
56
57         check_and_copy(GElf_Word,  dst, src, sh_name,      NULL);
58         check_and_copy(GElf_Word,  dst, src, sh_type,      NULL);
59         check_and_copy(GElf_Xword, dst, src, sh_flags,     NULL);
60         check_and_copy(GElf_Addr,  dst, src, sh_addr,      NULL);
61         check_and_copy(GElf_Off,   dst, src, sh_offset,    NULL);
62         check_and_copy(GElf_Xword, dst, src, sh_size,      NULL);
63         check_and_copy(GElf_Word,  dst, src, sh_link,      NULL);
64         check_and_copy(GElf_Word,  dst, src, sh_info,      NULL);
65         check_and_copy(GElf_Xword, dst, src, sh_addralign, NULL);
66         check_and_copy(GElf_Xword, dst, src, sh_entsize,   NULL);
67     }
68     else {
69         if (valid_class(scn->s_elf->e_class)) {
70             seterr(ERROR_UNIMPLEMENTED);
71         }
72         else {
73             seterr(ERROR_UNKNOWN_CLASS);
74         }
75         return NULL;
76     }
77     if (dst == &buf) {
78         dst = (GElf_Shdr*)malloc(sizeof(GElf_Shdr));
79         if (!dst) {
80             seterr(ERROR_MEM_SHDR);
81             return NULL;
82         }
83         *dst = buf;
84     }
85     return dst;
86 }
87
88 int
89 gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *src) {
90     if (!scn || !src) {
91         return 0;
92     }
93     elf_assert(scn->s_magic == SCN_MAGIC);
94     elf_assert(scn->s_elf);
95     elf_assert(scn->s_elf->e_magic == ELF_MAGIC);
96     if (scn->s_elf->e_class == ELFCLASS64) {
97         scn->s_shdr64 = *src;
98     }
99     else if (scn->s_elf->e_class == ELFCLASS32) {
100         Elf32_Shdr *dst = &scn->s_shdr32;
101
102         check_and_copy(Elf32_Word, dst, src, sh_name,      0);
103         check_and_copy(Elf32_Word, dst, src, sh_type,      0);
104         check_and_copy(Elf32_Word, dst, src, sh_flags,     0);
105         check_and_copy(Elf32_Addr, dst, src, sh_addr,      0);
106         check_and_copy(Elf32_Off,  dst, src, sh_offset,    0);
107         check_and_copy(Elf32_Word, dst, src, sh_size,      0);
108         check_and_copy(Elf32_Word, dst, src, sh_link,      0);
109         check_and_copy(Elf32_Word, dst, src, sh_info,      0);
110         check_and_copy(Elf32_Word, dst, src, sh_addralign, 0);
111         check_and_copy(Elf32_Word, dst, src, sh_entsize,   0);
112     }
113     else {
114         if (valid_class(scn->s_elf->e_class)) {
115             seterr(ERROR_UNIMPLEMENTED);
116         }
117         else {
118             seterr(ERROR_UNKNOWN_CLASS);
119         }
120         return 0;
121     }
122     return 1;
123 }
124
125 #endif /* __LIBELF64 */