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