1284194Sdelphij/* 2284194Sdelphij * Copyright (c) Christos Zoulas 2008. 3284194Sdelphij * All Rights Reserved. 4284194Sdelphij * 5284194Sdelphij * Redistribution and use in source and binary forms, with or without 6284194Sdelphij * modification, are permitted provided that the following conditions 7284194Sdelphij * are met: 8284194Sdelphij * 1. Redistributions of source code must retain the above copyright 9284194Sdelphij * notice immediately at the beginning of the file, without modification, 10284194Sdelphij * this list of conditions, and the following disclaimer. 11284194Sdelphij * 2. Redistributions in binary form must reproduce the above copyright 12284194Sdelphij * notice, this list of conditions and the following disclaimer in the 13284194Sdelphij * documentation and/or other materials provided with the distribution. 14284194Sdelphij * 15284194Sdelphij * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16284194Sdelphij * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17284194Sdelphij * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18284194Sdelphij * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 19284194Sdelphij * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20284194Sdelphij * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21284194Sdelphij * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22284194Sdelphij * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23284194Sdelphij * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24284194Sdelphij * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25284194Sdelphij * SUCH DAMAGE. 26284194Sdelphij */ 27284194Sdelphij if (nbytes <= sizeof(elfhdr)) 28284194Sdelphij return 0; 29284194Sdelphij 30284194Sdelphij u.l = 1; 31284194Sdelphij (void)memcpy(&elfhdr, buf, sizeof elfhdr); 32284194Sdelphij swap = (u.c[sizeof(int32_t) - 1] + 1) != elfhdr.e_ident[EI_DATA]; 33284194Sdelphij 34284194Sdelphij type = elf_getu16(swap, elfhdr.e_type); 35284194Sdelphij notecount = ms->elf_notes_max; 36284194Sdelphij switch (type) { 37284194Sdelphij#ifdef ELFCORE 38284194Sdelphij case ET_CORE: 39284194Sdelphij phnum = elf_getu16(swap, elfhdr.e_phnum); 40284194Sdelphij if (phnum > ms->elf_phnum_max) 41284194Sdelphij return toomany(ms, "program headers", phnum); 42284194Sdelphij flags |= FLAGS_IS_CORE; 43284194Sdelphij if (dophn_core(ms, clazz, swap, fd, 44284194Sdelphij (off_t)elf_getu(swap, elfhdr.e_phoff), phnum, 45284194Sdelphij (size_t)elf_getu16(swap, elfhdr.e_phentsize), 46284194Sdelphij fsize, &flags, ¬ecount) == -1) 47284194Sdelphij return -1; 48284194Sdelphij break; 49284194Sdelphij#endif 50284194Sdelphij case ET_EXEC: 51284194Sdelphij case ET_DYN: 52284194Sdelphij phnum = elf_getu16(swap, elfhdr.e_phnum); 53284194Sdelphij if (phnum > ms->elf_phnum_max) 54284194Sdelphij return toomany(ms, "program", phnum); 55284194Sdelphij shnum = elf_getu16(swap, elfhdr.e_shnum); 56284194Sdelphij if (shnum > ms->elf_shnum_max) 57284194Sdelphij return toomany(ms, "section", shnum); 58284194Sdelphij if (dophn_exec(ms, clazz, swap, fd, 59284194Sdelphij (off_t)elf_getu(swap, elfhdr.e_phoff), phnum, 60284194Sdelphij (size_t)elf_getu16(swap, elfhdr.e_phentsize), 61284194Sdelphij fsize, shnum, &flags, ¬ecount) == -1) 62284194Sdelphij return -1; 63284194Sdelphij /*FALLTHROUGH*/ 64284194Sdelphij case ET_REL: 65284194Sdelphij shnum = elf_getu16(swap, elfhdr.e_shnum); 66284194Sdelphij if (shnum > ms->elf_shnum_max) 67284194Sdelphij return toomany(ms, "section headers", shnum); 68284194Sdelphij if (doshn(ms, clazz, swap, fd, 69284194Sdelphij (off_t)elf_getu(swap, elfhdr.e_shoff), shnum, 70284194Sdelphij (size_t)elf_getu16(swap, elfhdr.e_shentsize), 71284194Sdelphij fsize, elf_getu16(swap, elfhdr.e_machine), 72284194Sdelphij (int)elf_getu16(swap, elfhdr.e_shstrndx), 73284194Sdelphij &flags, ¬ecount) == -1) 74284194Sdelphij return -1; 75284194Sdelphij break; 76284194Sdelphij 77284194Sdelphij default: 78284194Sdelphij break; 79284194Sdelphij } 80284194Sdelphij if (notecount == 0) 81284194Sdelphij return toomany(ms, "notes", ms->elf_notes_max); 82284194Sdelphij return 1; 83