1186690Sobrien/* 2186690Sobrien * Copyright (c) Christos Zoulas 2008. 3186690Sobrien * All Rights Reserved. 4186690Sobrien * 5186690Sobrien * Redistribution and use in source and binary forms, with or without 6186690Sobrien * modification, are permitted provided that the following conditions 7186690Sobrien * are met: 8186690Sobrien * 1. Redistributions of source code must retain the above copyright 9186690Sobrien * notice immediately at the beginning of the file, without modification, 10186690Sobrien * this list of conditions, and the following disclaimer. 11186690Sobrien * 2. Redistributions in binary form must reproduce the above copyright 12186690Sobrien * notice, this list of conditions and the following disclaimer in the 13186690Sobrien * documentation and/or other materials provided with the distribution. 14186690Sobrien * 15186690Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16186690Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17186690Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18186690Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 19186690Sobrien * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20186690Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21186690Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22186690Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23186690Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24186690Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25186690Sobrien * SUCH DAMAGE. 26186690Sobrien */ 27186690Sobrien if (nbytes <= sizeof(elfhdr)) 28186690Sobrien return 0; 29186690Sobrien 30186690Sobrien u.l = 1; 31186690Sobrien (void)memcpy(&elfhdr, buf, sizeof elfhdr); 32186690Sobrien swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[EI_DATA]; 33186690Sobrien 34186690Sobrien type = elf_getu16(swap, elfhdr.e_type); 35186690Sobrien switch (type) { 36186690Sobrien#ifdef ELFCORE 37186690Sobrien case ET_CORE: 38275671Sdelphij phnum = elf_getu16(swap, elfhdr.e_phnum); 39275671Sdelphij if (phnum > MAX_PHNUM) 40275671Sdelphij return toomany(ms, "program", phnum); 41234449Sobrien flags |= FLAGS_IS_CORE; 42186690Sobrien if (dophn_core(ms, clazz, swap, fd, 43275671Sdelphij (off_t)elf_getu(swap, elfhdr.e_phoff), phnum, 44186690Sobrien (size_t)elf_getu16(swap, elfhdr.e_phentsize), 45186690Sobrien fsize, &flags) == -1) 46186690Sobrien return -1; 47186690Sobrien break; 48186690Sobrien#endif 49186690Sobrien case ET_EXEC: 50186690Sobrien case ET_DYN: 51275671Sdelphij phnum = elf_getu16(swap, elfhdr.e_phnum); 52275671Sdelphij if (phnum > MAX_PHNUM) 53275671Sdelphij return toomany(ms, "program", phnum); 54275671Sdelphij shnum = elf_getu16(swap, elfhdr.e_shnum); 55275671Sdelphij if (shnum > MAX_SHNUM) 56275671Sdelphij return toomany(ms, "section", shnum); 57186690Sobrien if (dophn_exec(ms, clazz, swap, fd, 58275671Sdelphij (off_t)elf_getu(swap, elfhdr.e_phoff), phnum, 59186690Sobrien (size_t)elf_getu16(swap, elfhdr.e_phentsize), 60275671Sdelphij fsize, &flags, shnum) == -1) 61186690Sobrien return -1; 62186690Sobrien /*FALLTHROUGH*/ 63186690Sobrien case ET_REL: 64275671Sdelphij shnum = elf_getu16(swap, elfhdr.e_shnum); 65275671Sdelphij if (shnum > MAX_SHNUM) 66275671Sdelphij return toomany(ms, "section", shnum); 67186690Sobrien if (doshn(ms, clazz, swap, fd, 68275671Sdelphij (off_t)elf_getu(swap, elfhdr.e_shoff), shnum, 69186690Sobrien (size_t)elf_getu16(swap, elfhdr.e_shentsize), 70234449Sobrien fsize, &flags, elf_getu16(swap, elfhdr.e_machine)) == -1) 71186690Sobrien return -1; 72186690Sobrien break; 73186690Sobrien 74186690Sobrien default: 75186690Sobrien break; 76186690Sobrien } 77186690Sobrien return 1; 78