1 /* $NetBSD: elf_flag.c,v 1.2 2014/03/09 16:58:04 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 <sys/cdefs.h> 30 31 #include <libelf.h> 32 33 #include "_libelf.h" 34 35 __RCSID("$NetBSD: elf_flag.c,v 1.2 2014/03/09 16:58:04 christos Exp $"); 36 ELFTC_VCSID("Id: elf_flag.c 2272 2011-12-03 17:07:31Z jkoshy "); 37 38 unsigned int 39 elf_flagarhdr(Elf_Arhdr *a, Elf_Cmd c, unsigned int flags) 40 { 41 unsigned int r; 42 43 if (a == NULL) 44 return (0); 45 46 if ((c != ELF_C_SET && c != ELF_C_CLR) || 47 (flags & ~ELF_F_DIRTY) != 0) { 48 LIBELF_SET_ERROR(ARGUMENT, 0); 49 return (0); 50 } 51 52 if (c == ELF_C_SET) 53 r = a->ar_flags |= flags; 54 else 55 r = a->ar_flags &= ~flags; 56 57 return (r & LIBELF_F_API_MASK); 58 } 59 60 unsigned int 61 elf_flagdata(Elf_Data *d, Elf_Cmd c, unsigned int flags) 62 { 63 unsigned int r; 64 struct _Libelf_Data *ld; 65 66 if (d == NULL) 67 return (0); 68 69 if ((c != ELF_C_SET && c != ELF_C_CLR) || 70 (flags & ~ELF_F_DIRTY) != 0) { 71 LIBELF_SET_ERROR(ARGUMENT, 0); 72 return (0); 73 } 74 75 ld = (struct _Libelf_Data *) d; 76 77 if (c == ELF_C_SET) 78 r = ld->d_flags |= flags; 79 else 80 r = ld->d_flags &= ~flags; 81 82 return (r & LIBELF_F_API_MASK); 83 } 84 85 unsigned int 86 elf_flagehdr(Elf *e, Elf_Cmd c, unsigned int flags) 87 { 88 int ec; 89 void *ehdr; 90 91 if (e == NULL) 92 return (0); 93 94 if ((c != ELF_C_SET && c != ELF_C_CLR) || 95 (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 || 96 ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { 97 LIBELF_SET_ERROR(ARGUMENT, 0); 98 return (0); 99 } 100 101 if (ec == ELFCLASS32) 102 ehdr = e->e_u.e_elf.e_ehdr.e_ehdr32; 103 else 104 ehdr = e->e_u.e_elf.e_ehdr.e_ehdr64; 105 106 if (ehdr == NULL) { 107 LIBELF_SET_ERROR(SEQUENCE, 0); 108 return (0); 109 } 110 111 return (elf_flagelf(e, c, flags)); 112 } 113 114 unsigned int 115 elf_flagelf(Elf *e, Elf_Cmd c, unsigned int flags) 116 { 117 int r; 118 119 if (e == NULL) 120 return (0); 121 122 if ((c != ELF_C_SET && c != ELF_C_CLR) || 123 (e->e_kind != ELF_K_ELF) || 124 (flags & ~(ELF_F_ARCHIVE | ELF_F_ARCHIVE_SYSV | 125 ELF_F_DIRTY | ELF_F_LAYOUT)) != 0) { 126 LIBELF_SET_ERROR(ARGUMENT, 0); 127 return (0); 128 } 129 130 if ((flags & ELF_F_ARCHIVE_SYSV) && (flags & ELF_F_ARCHIVE) == 0) { 131 LIBELF_SET_ERROR(ARGUMENT, 0); 132 return (0); 133 } 134 135 if ((flags & ELF_F_ARCHIVE) && e->e_cmd != ELF_C_WRITE) { 136 LIBELF_SET_ERROR(MODE, 0); 137 return (0); 138 } 139 140 if (c == ELF_C_SET) 141 r = e->e_flags |= flags; 142 else 143 r = e->e_flags &= ~flags; 144 return (r & LIBELF_F_API_MASK); 145 } 146 147 unsigned int 148 elf_flagphdr(Elf *e, Elf_Cmd c, unsigned int flags) 149 { 150 int ec; 151 void *phdr; 152 153 if (e == NULL) 154 return (0); 155 156 if ((c != ELF_C_SET && c != ELF_C_CLR) || 157 (e->e_kind != ELF_K_ELF) || (flags & ~ELF_F_DIRTY) != 0 || 158 ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) { 159 LIBELF_SET_ERROR(ARGUMENT, 0); 160 return (0); 161 } 162 163 if (ec == ELFCLASS32) 164 phdr = e->e_u.e_elf.e_phdr.e_phdr32; 165 else 166 phdr = e->e_u.e_elf.e_phdr.e_phdr64; 167 168 if (phdr == NULL) { 169 LIBELF_SET_ERROR(SEQUENCE, 0); 170 return (0); 171 } 172 173 return (elf_flagelf(e, c, flags)); 174 } 175 176 unsigned int 177 elf_flagscn(Elf_Scn *s, Elf_Cmd c, unsigned int flags) 178 { 179 int r; 180 181 if (s == NULL) 182 return (0); 183 184 if ((c != ELF_C_SET && c != ELF_C_CLR) || 185 (flags & ~ELF_F_DIRTY) != 0) { 186 LIBELF_SET_ERROR(ARGUMENT, 0); 187 return (0); 188 } 189 190 if (c == ELF_C_SET) 191 r = s->s_flags |= flags; 192 else 193 r = s->s_flags &= ~flags; 194 return (r & LIBELF_F_API_MASK); 195 } 196 197 unsigned int 198 elf_flagshdr(Elf_Scn *s, Elf_Cmd c, unsigned int flags) 199 { 200 return (elf_flagscn(s, c, flags)); 201 } 202