xref: /netbsd-src/external/bsd/elftoolchain/dist/libelf/elf_flag.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: elf_flag.c,v 1.3 2016/02/20 02:43:42 christos Exp $	*/
2 
3 /*-
4  * Copyright (c) 2006,2008-2009,2011 Joseph Koshy
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <libelf.h>
30 
31 #include "_libelf.h"
32 
33 __RCSID("$NetBSD: elf_flag.c,v 1.3 2016/02/20 02:43:42 christos Exp $");
34 ELFTC_VCSID("Id: elf_flag.c 3174 2015-03-27 17:13:41Z emaste ");
35 
36 unsigned int
37 elf_flagarhdr(Elf_Arhdr *a, Elf_Cmd c, unsigned int flags)
38 {
39 	unsigned int r;
40 
41 	if (a == NULL)
42 		return (0);
43 
44 	if ((c != ELF_C_SET && c != ELF_C_CLR) ||
45 	    (flags & ~ELF_F_DIRTY) != 0) {
46 		LIBELF_SET_ERROR(ARGUMENT, 0);
47 		return (0);
48 	}
49 
50 	if (c == ELF_C_SET)
51 		r = a->ar_flags |= flags;
52 	else
53 		r = a->ar_flags &= ~flags;
54 
55 	return (r & LIBELF_F_API_MASK);
56 }
57 
58 unsigned int
59 elf_flagdata(Elf_Data *d, Elf_Cmd c, unsigned int flags)
60 {
61 	unsigned int r;
62 	struct _Libelf_Data *ld;
63 
64 	if (d == NULL)
65 		return (0);
66 
67 	if ((c != ELF_C_SET && c != ELF_C_CLR) ||
68 	    (flags & ~ELF_F_DIRTY) != 0) {
69 		LIBELF_SET_ERROR(ARGUMENT, 0);
70 		return (0);
71 	}
72 
73 	ld = (struct _Libelf_Data *) d;
74 
75 	if (c == ELF_C_SET)
76 		r = ld->d_flags |= flags;
77 	else
78 		r = ld->d_flags &= ~flags;
79 
80 	return (r & LIBELF_F_API_MASK);
81 }
82 
83 unsigned int
84 elf_flagehdr(Elf *e, Elf_Cmd c, unsigned int flags)
85 {
86 	int ec;
87 	void *ehdr;
88 
89 	if (e == NULL)
90 		return (0);
91 
92 	if ((c != ELF_C_SET && c != ELF_C_CLR) ||
93 	    (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 ||
94 	    ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
95 		LIBELF_SET_ERROR(ARGUMENT, 0);
96 		return (0);
97 	}
98 
99 	if (ec == ELFCLASS32)
100 		ehdr = e->e_u.e_elf.e_ehdr.e_ehdr32;
101 	else
102 		ehdr = e->e_u.e_elf.e_ehdr.e_ehdr64;
103 
104 	if (ehdr == NULL) {
105 		LIBELF_SET_ERROR(SEQUENCE, 0);
106 		return (0);
107 	}
108 
109 	return (elf_flagelf(e, c, flags));
110 }
111 
112 unsigned int
113 elf_flagelf(Elf *e, Elf_Cmd c, unsigned int flags)
114 {
115 	unsigned int r;
116 
117 	if (e == NULL)
118 		return (0);
119 
120 	if ((c != ELF_C_SET && c != ELF_C_CLR) ||
121 	    (e->e_kind != ELF_K_ELF) ||
122 	    (flags & ~(ELF_F_ARCHIVE | ELF_F_ARCHIVE_SYSV |
123 	    ELF_F_DIRTY | ELF_F_LAYOUT)) != 0) {
124 		LIBELF_SET_ERROR(ARGUMENT, 0);
125 		return (0);
126 	}
127 
128 	if ((flags & ELF_F_ARCHIVE_SYSV) && (flags & ELF_F_ARCHIVE) == 0) {
129 		LIBELF_SET_ERROR(ARGUMENT, 0);
130 		return (0);
131 	}
132 
133 	if ((flags & ELF_F_ARCHIVE) && e->e_cmd != ELF_C_WRITE) {
134 		LIBELF_SET_ERROR(MODE, 0);
135 		return (0);
136 	}
137 
138 	if (c == ELF_C_SET)
139 		r = e->e_flags |= flags;
140 	else
141 		r = e->e_flags &= ~flags;
142 	return (r & LIBELF_F_API_MASK);
143 }
144 
145 unsigned int
146 elf_flagphdr(Elf *e, Elf_Cmd c, unsigned int flags)
147 {
148 	int ec;
149 	void *phdr;
150 
151 	if (e == NULL)
152 		return (0);
153 
154 	if ((c != ELF_C_SET && c != ELF_C_CLR) ||
155 	    (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 ||
156 	    ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
157 		LIBELF_SET_ERROR(ARGUMENT, 0);
158 		return (0);
159 	}
160 
161 	if (ec == ELFCLASS32)
162 		phdr = e->e_u.e_elf.e_phdr.e_phdr32;
163 	else
164 		phdr = e->e_u.e_elf.e_phdr.e_phdr64;
165 
166 	if (phdr == NULL) {
167 		LIBELF_SET_ERROR(SEQUENCE, 0);
168 		return (0);
169 	}
170 
171 	return (elf_flagelf(e, c, flags));
172 }
173 
174 unsigned int
175 elf_flagscn(Elf_Scn *s, Elf_Cmd c, unsigned int flags)
176 {
177 	unsigned int r;
178 
179 	if (s == NULL)
180 		return (0);
181 
182 	if ((c != ELF_C_SET && c != ELF_C_CLR) ||
183 	    (flags & ~ELF_F_DIRTY) != 0) {
184 		LIBELF_SET_ERROR(ARGUMENT, 0);
185 		return (0);
186 	}
187 
188 	if (c == ELF_C_SET)
189 		r = s->s_flags |= flags;
190 	else
191 		r = s->s_flags &= ~flags;
192 	return (r & LIBELF_F_API_MASK);
193 }
194 
195 unsigned int
196 elf_flagshdr(Elf_Scn *s, Elf_Cmd c, unsigned int flags)
197 {
198 	return (elf_flagscn(s, c, flags));
199 }
200