1 /*- 2 * Copyright (c) 2016 Kai Wang 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <errno.h> 28 29 #include "_libpe.h" 30 31 ELFTC_VCSID("$Id: pe_flag.c 3312 2016-01-10 09:23:51Z kaiwang27 $"); 32 33 int 34 pe_flag(PE *pe, PE_Cmd c, unsigned int flags) 35 { 36 37 if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR)) { 38 errno = EINVAL; 39 return (-1); 40 } 41 42 if ((flags & ~(PE_F_STRIP_DOS_STUB | PE_F_STRIP_RICH_HEADER | 43 PE_F_STRIP_SYMTAB | PE_F_STRIP_DEBUG)) != 0) { 44 errno = EINVAL; 45 return (-1); 46 } 47 48 if (c == PE_C_SET) 49 pe->pe_flags |= flags; 50 else 51 pe->pe_flags &= ~flags; 52 53 return (0); 54 } 55 56 int 57 pe_flag_dos_header(PE *pe, PE_Cmd c, unsigned int flags) 58 { 59 60 if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR) || 61 (flags & ~PE_F_DIRTY) != 0) { 62 errno = EINVAL; 63 return (-1); 64 } 65 66 if (c == PE_C_SET) 67 pe->pe_flags |= LIBPE_F_DIRTY_DOS_HEADER; 68 else 69 pe->pe_flags &= ~LIBPE_F_DIRTY_DOS_HEADER; 70 71 return (0); 72 } 73 74 int 75 pe_flag_coff_header(PE *pe, PE_Cmd c, unsigned int flags) 76 { 77 78 if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR) || 79 (flags & ~PE_F_DIRTY) != 0) { 80 errno = EINVAL; 81 return (-1); 82 } 83 84 if (c == PE_C_SET) 85 pe->pe_flags |= LIBPE_F_DIRTY_COFF_HEADER; 86 else 87 pe->pe_flags &= ~LIBPE_F_DIRTY_COFF_HEADER; 88 89 return (0); 90 } 91 92 int 93 pe_flag_opt_header(PE *pe, PE_Cmd c, unsigned int flags) 94 { 95 96 if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR) || 97 (flags & ~PE_F_DIRTY) != 0) { 98 errno = EINVAL; 99 return (-1); 100 } 101 102 if (c == PE_C_SET) 103 pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; 104 else 105 pe->pe_flags &= ~LIBPE_F_DIRTY_OPT_HEADER; 106 107 return (0); 108 } 109 110 int 111 pe_flag_data_dir(PE *pe, PE_Cmd c, unsigned int flags) 112 { 113 114 if (pe == NULL || (c != PE_C_SET && c != PE_C_CLR) || 115 (flags & ~PE_F_DIRTY) != 0) { 116 errno = EINVAL; 117 return (-1); 118 } 119 120 if (c == PE_C_SET) 121 pe->pe_flags |= LIBPE_F_DIRTY_OPT_HEADER; 122 else 123 pe->pe_flags &= ~LIBPE_F_DIRTY_OPT_HEADER; 124 125 return (0); 126 } 127 128 int 129 pe_flag_scn(PE_Scn *ps, PE_Cmd c, unsigned int flags) 130 { 131 132 if (ps == NULL || (c != PE_C_SET && c != PE_C_CLR) || 133 (flags & ~(PE_F_DIRTY | PE_F_STRIP_SECTION)) == 0) { 134 errno = EINVAL; 135 return (-1); 136 } 137 138 if (c == PE_C_SET) 139 ps->ps_flags |= flags; 140 else 141 ps->ps_flags &= ~flags; 142 143 return (0); 144 } 145 146 int 147 pe_flag_section_header(PE_Scn *ps, PE_Cmd c, unsigned int flags) 148 { 149 PE *pe; 150 151 if (ps == NULL || (c != PE_C_SET && c != PE_C_CLR) || 152 (flags & ~PE_F_DIRTY) != 0) { 153 errno = EINVAL; 154 return (-1); 155 } 156 157 pe = ps->ps_pe; 158 159 /* The library doesn't support per section header dirty flag. */ 160 if (c == PE_C_SET) 161 pe->pe_flags |= LIBPE_F_DIRTY_SEC_HEADER; 162 else 163 pe->pe_flags &= ~LIBPE_F_DIRTY_SEC_HEADER; 164 165 return (0); 166 } 167 168 int 169 pe_flag_buffer(PE_Buffer *pb, PE_Cmd c, unsigned int flags) 170 { 171 PE_SecBuf *sb; 172 173 if (pb == NULL || (c != PE_C_SET && c != PE_C_CLR) || 174 (flags & ~PE_F_DIRTY) != 0) { 175 errno = EINVAL; 176 return (-1); 177 } 178 179 sb = (PE_SecBuf *) pb; 180 181 if (c == PE_C_SET) 182 sb->sb_flags |= flags; 183 else 184 sb->sb_flags &= ~flags; 185 186 return (0); 187 } 188