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