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); 35277592Sdelphij notecount = ms->elf_notes_max; 36186690Sobrien switch (type) { 37186690Sobrien#ifdef ELFCORE 38186690Sobrien case ET_CORE: 39275668Sdelphij phnum = elf_getu16(swap, elfhdr.e_phnum); 40276415Sdelphij if (phnum > ms->elf_phnum_max) 41277592Sdelphij return toomany(ms, "program headers", phnum); 42226048Sobrien flags |= FLAGS_IS_CORE; 43186690Sobrien if (dophn_core(ms, clazz, swap, fd, 44275668Sdelphij (off_t)elf_getu(swap, elfhdr.e_phoff), phnum, 45186690Sobrien (size_t)elf_getu16(swap, elfhdr.e_phentsize), 46277592Sdelphij fsize, &flags, ¬ecount) == -1) 47186690Sobrien return -1; 48186690Sobrien break; 49186690Sobrien#endif 50186690Sobrien case ET_EXEC: 51186690Sobrien case ET_DYN: 52275668Sdelphij phnum = elf_getu16(swap, elfhdr.e_phnum); 53276415Sdelphij if (phnum > ms->elf_phnum_max) 54275668Sdelphij return toomany(ms, "program", phnum); 55275668Sdelphij shnum = elf_getu16(swap, elfhdr.e_shnum); 56276415Sdelphij if (shnum > ms->elf_shnum_max) 57275668Sdelphij return toomany(ms, "section", shnum); 58186690Sobrien if (dophn_exec(ms, clazz, swap, fd, 59275668Sdelphij (off_t)elf_getu(swap, elfhdr.e_phoff), phnum, 60186690Sobrien (size_t)elf_getu16(swap, elfhdr.e_phentsize), 61277592Sdelphij fsize, shnum, &flags, ¬ecount) == -1) 62186690Sobrien return -1; 63186690Sobrien /*FALLTHROUGH*/ 64186690Sobrien case ET_REL: 65275668Sdelphij shnum = elf_getu16(swap, elfhdr.e_shnum); 66276415Sdelphij if (shnum > ms->elf_shnum_max) 67277592Sdelphij return toomany(ms, "section headers", shnum); 68186690Sobrien if (doshn(ms, clazz, swap, fd, 69275668Sdelphij (off_t)elf_getu(swap, elfhdr.e_shoff), shnum, 70186690Sobrien (size_t)elf_getu16(swap, elfhdr.e_shentsize), 71277592Sdelphij fsize, elf_getu16(swap, elfhdr.e_machine), 72277592Sdelphij (int)elf_getu16(swap, elfhdr.e_shstrndx), 73277592Sdelphij &flags, ¬ecount) == -1) 74186690Sobrien return -1; 75186690Sobrien break; 76186690Sobrien 77186690Sobrien default: 78186690Sobrien break; 79186690Sobrien } 80277592Sdelphij if (notecount == 0) 81277592Sdelphij return toomany(ms, "notes", ms->elf_notes_max); 82186690Sobrien return 1; 83