/ external / libelf / gelf_ehdr.c
gelf_ehdr.c
  1  /*-
  2   * Copyright (c) 2006,2008 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 <assert.h>
 30  #include <gelf.h>
 31  #include <libelf.h>
 32  #include <limits.h>
 33  #include <string.h>
 34  
 35  #include "_libelf.h"
 36  
 37  ELFTC_VCSID("$Id$");
 38  
 39  Elf32_Ehdr *
 40  elf32_getehdr(Elf *e)
 41  {
 42  	return (_libelf_ehdr(e, ELFCLASS32, 0));
 43  }
 44  
 45  Elf64_Ehdr *
 46  elf64_getehdr(Elf *e)
 47  {
 48  	return (_libelf_ehdr(e, ELFCLASS64, 0));
 49  }
 50  
 51  GElf_Ehdr *
 52  gelf_getehdr(Elf *e, GElf_Ehdr *d)
 53  {
 54  	int ec;
 55  	Elf32_Ehdr *eh32;
 56  	Elf64_Ehdr *eh64;
 57  
 58  	if (d == NULL || e == NULL ||
 59  	    ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
 60  		LIBELF_SET_ERROR(ARGUMENT, 0);
 61  		return (NULL);
 62  	}
 63  
 64  	if (ec == ELFCLASS32) {
 65  		if ((eh32 = _libelf_ehdr(e, ELFCLASS32, 0)) == NULL)
 66  			return (NULL);
 67  
 68  		(void) memcpy(d->e_ident, eh32->e_ident,
 69  		    sizeof(eh32->e_ident));
 70  		d->e_type		= eh32->e_type;
 71  		d->e_machine		= eh32->e_machine;
 72  		d->e_version		= eh32->e_version;
 73  		d->e_entry		= eh32->e_entry;
 74  		d->e_phoff		= eh32->e_phoff;
 75  		d->e_shoff		= eh32->e_shoff;
 76  		d->e_flags		= eh32->e_flags;
 77  		d->e_ehsize		= eh32->e_ehsize;
 78  		d->e_phentsize		= eh32->e_phentsize;
 79  		d->e_phnum		= eh32->e_phnum;
 80  		d->e_shentsize		= eh32->e_shentsize;
 81  		d->e_shnum		= eh32->e_shnum;
 82  		d->e_shstrndx		= eh32->e_shstrndx;
 83  
 84  		return (d);
 85  	}
 86  
 87  	assert(ec == ELFCLASS64);
 88  
 89  	if ((eh64 = _libelf_ehdr(e, ELFCLASS64, 0)) == NULL)
 90  		return (NULL);
 91  	*d = *eh64;
 92  
 93  	return (d);
 94  }
 95  
 96  Elf32_Ehdr *
 97  elf32_newehdr(Elf *e)
 98  {
 99  	return (_libelf_ehdr(e, ELFCLASS32, 1));
100  }
101  
102  Elf64_Ehdr *
103  elf64_newehdr(Elf *e)
104  {
105  	return (_libelf_ehdr(e, ELFCLASS64, 1));
106  }
107  
108  void *
109  gelf_newehdr(Elf *e, int ec)
110  {
111  	if (e != NULL &&
112  	    (ec == ELFCLASS32 || ec == ELFCLASS64))
113  		return (_libelf_ehdr(e, ec, 1));
114  
115  	LIBELF_SET_ERROR(ARGUMENT, 0);
116  	return (NULL);
117  }
118  
119  int
120  gelf_update_ehdr(Elf *e, GElf_Ehdr *s)
121  {
122  	int ec;
123  	void *ehdr;
124  	Elf32_Ehdr *eh32;
125  	Elf64_Ehdr *eh64;
126  
127  	if (s== NULL || e == NULL || e->e_kind != ELF_K_ELF ||
128  	    ((ec = e->e_class) != ELFCLASS32 && ec != ELFCLASS64)) {
129  		LIBELF_SET_ERROR(ARGUMENT, 0);
130  		return (0);
131  	}
132  
133  	if (e->e_cmd == ELF_C_READ) {
134  		LIBELF_SET_ERROR(MODE, 0);
135  		return (0);
136  	}
137  
138  	if ((ehdr = _libelf_ehdr(e, ec, 0)) == NULL)
139  		return (0);
140  
141  	(void) elf_flagehdr(e, ELF_C_SET, ELF_F_DIRTY);
142  
143  	if (ec == ELFCLASS64) {
144  		eh64 = (Elf64_Ehdr *) ehdr;
145  		*eh64 = *s;
146  		return (1);
147  	}
148  
149  	eh32 = (Elf32_Ehdr *) ehdr;
150  
151  	(void) memcpy(eh32->e_ident, s->e_ident, sizeof(eh32->e_ident));
152  
153  	eh32->e_type      = s->e_type;
154  	eh32->e_machine   = s->e_machine;
155  	eh32->e_version   = s->e_version;
156  	LIBELF_COPY_U32(eh32, s, e_entry);
157  	LIBELF_COPY_U32(eh32, s, e_phoff);
158  	LIBELF_COPY_U32(eh32, s, e_shoff);
159  	eh32->e_flags     = s->e_flags;
160  	eh32->e_ehsize    = s->e_ehsize;
161  	eh32->e_phentsize = s->e_phentsize;
162  	eh32->e_phnum     = s->e_phnum;
163  	eh32->e_shentsize = s->e_shentsize;
164  	eh32->e_shnum     = s->e_shnum;
165  	eh32->e_shstrndx  = s->e_shstrndx;
166  
167  	return (1);
168  }