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