1441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project/* Update data structures for changes. 2cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc. 3cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng This file is part of Red Hat elfutils. 4441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Written by Ulrich Drepper <drepper@redhat.com>, 2000. 5441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 6cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Red Hat elfutils is free software; you can redistribute it and/or modify 7cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng it under the terms of the GNU General Public License as published by the 8cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Free Software Foundation; version 2 of the License. 9cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 10cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Red Hat elfutils is distributed in the hope that it will be useful, but 11cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng WITHOUT ANY WARRANTY; without even the implied warranty of 12cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng General Public License for more details. 14cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 15cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng You should have received a copy of the GNU General Public License along 16cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng with Red Hat elfutils; if not, write to the Free Software Foundation, 17cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA. 18cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 19cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng In addition, as a special exception, Red Hat, Inc. gives You the 20cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng additional right to link the code of Red Hat elfutils with code licensed 21cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng under any Open Source Initiative certified open source license 22cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (http://www.opensource.org/licenses/index.php) which requires the 23cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng distribution of source code with any binary distribution and to 24cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng distribute linked combinations of the two. Non-GPL Code permitted under 25cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng this exception must only link to the code of Red Hat elfutils through 26cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng those well defined interfaces identified in the file named EXCEPTION 27cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng found in the source code files (the "Approved Interfaces"). The files 28cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng of Non-GPL Code may instantiate templates or use macros or inline 29cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng functions from the Approved Interfaces without causing the resulting 30cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng work to be covered by the GNU General Public License. Only Red Hat, 31cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Inc. may make changes or additions to the list of Approved Interfaces. 32cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Red Hat's grant of this exception is conditioned upon your not adding 33cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng any new exceptions. If you wish to add a new Approved Interface or 34cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng exception, please contact Red Hat. You must obey the GNU General Public 35cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng License in all respects for all of the Red Hat elfutils code and other 36cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng code used in conjunction with Red Hat elfutils except the Non-GPL Code 37cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng covered by this exception. If you modify this file, you may extend this 38cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng exception to your version of the file, but you are not obligated to do 39cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng so. If you do not wish to provide this exception without modification, 40cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng you must delete this exception statement from your version and license 41cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng this file solely under the GPL without exception. 42cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 43cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Red Hat elfutils is an included package of the Open Invention Network. 44cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng An included package of the Open Invention Network is a package for which 45cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Open Invention Network licensees cross-license their patents. No patent 46cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng license is granted, either expressly or impliedly, by designation as an 47cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng included package. Should you wish to participate in the Open Invention 48cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Network licensing program, please visit www.openinventionnetwork.com 49cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng <http://www.openinventionnetwork.com>. */ 50441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 51441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#ifdef HAVE_CONFIG_H 52441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project# include <config.h> 53441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#endif 54441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 55441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <assert.h> 56cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng#include <endian.h> 57441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <libelf.h> 58441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <stdbool.h> 59441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <string.h> 60441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include <sys/param.h> 61441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 62441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include "libelfP.h" 63441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#include "elf-knowledge.h" 64441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 65441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#ifndef LIBELFBITS 66441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project# define LIBELFBITS 32 67441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#endif 68441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 69441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 70441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 71441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectstatic int 72441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source ProjectELFW(default_ehdr,LIBELFBITS) (Elf *elf, ElfW2(LIBELFBITS,Ehdr) *ehdr, 73441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size_t shnum, int *change_bop) 74441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 75441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Always write the magic bytes. */ 76441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (memcmp (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0) 77441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 78441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project memcpy (&ehdr->e_ident[EI_MAG0], ELFMAG, SELFMAG); 79441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; 80441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 81441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 82441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Always set the file class. */ 83441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project update_if_changed (ehdr->e_ident[EI_CLASS], ELFW(ELFCLASS,LIBELFBITS), 84441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf->state.ELFW(elf,LIBELFBITS).ehdr_flags); 85441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 86441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Set the data encoding if necessary. */ 87441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (ehdr->e_ident[EI_DATA] == ELFDATANONE)) 88441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 89441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_ident[EI_DATA] = 90441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project BYTE_ORDER == BIG_ENDIAN ? ELFDATA2MSB : ELFDATA2LSB; 91441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; 92441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 93441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else if (unlikely (ehdr->e_ident[EI_DATA] >= ELFDATANUM)) 94441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 95441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project __libelf_seterrno (ELF_E_DATA_ENCODING); 96441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return 1; 97441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 98441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 99441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project *change_bop = ((BYTE_ORDER == LITTLE_ENDIAN 100441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ehdr->e_ident[EI_DATA] != ELFDATA2LSB) 101441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project || (BYTE_ORDER == BIG_ENDIAN 102441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && ehdr->e_ident[EI_DATA] != ELFDATA2MSB)); 103441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 104441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Unconditionally overwrite the ELF version. */ 105441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project update_if_changed (ehdr->e_ident[EI_VERSION], EV_CURRENT, 106441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf->state.ELFW(elf,LIBELFBITS).ehdr_flags); 107441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 108441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (ehdr->e_version == EV_NONE) 109441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project || unlikely (ehdr->e_version >= EV_NUM)) 110441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 111441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project __libelf_seterrno (ELF_E_UNKNOWN_VERSION); 112441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return 1; 113441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 114441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 115441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (shnum >= SHN_LORESERVE)) 116441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 117441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project update_if_changed (ehdr->e_shnum, 0, 118441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf->state.ELFW(elf,LIBELFBITS).ehdr_flags); 119441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 120441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 121441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project update_if_changed (ehdr->e_shnum, shnum, 122441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf->state.ELFW(elf,LIBELFBITS).ehdr_flags); 123441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 124441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (ehdr->e_ehsize != elf_typesize (LIBELFBITS, ELF_T_EHDR, 1))) 125441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 126441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_ehsize = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1); 127441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ELF_F_DIRTY; 128441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 129441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 130441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return 0; 131441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 132441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 133441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 134441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Projectoff_t 135cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Chenginternal_function 136cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng__elfw2(LIBELFBITS,updatenull_wrlock) (Elf *elf, int *change_bop, size_t shnum) 137441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project{ 138cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ElfW2(LIBELFBITS,Ehdr) *ehdr; 139441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int changed = 0; 140441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project int ehdr_flags = 0; 141cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 142cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ehdr = __elfw2(LIBELFBITS,getehdr_wrlock) (elf); 143441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 144441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Set the default values. */ 145441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ELFW(default_ehdr,LIBELFBITS) (elf, ehdr, shnum, change_bop) != 0) 146441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return -1; 147441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 148441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* At least the ELF header is there. */ 149cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng off_t size = elf_typesize (LIBELFBITS, ELF_T_EHDR, 1); 150441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 151441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Set the program header position. */ 152cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (elf->state.ELFW(elf,LIBELFBITS).phdr == NULL 153cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng && (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN 154cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng || ehdr->e_type == ET_CORE)) 155cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (void) __elfw2(LIBELFBITS,getphdr_wrlock) (elf); 156441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (elf->state.ELFW(elf,LIBELFBITS).phdr != NULL) 157441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 158cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Only executables, shared objects, and core files have a program 159cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng header. */ 160cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN 161cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng && unlikely (ehdr->e_type != ET_CORE)) 162441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 163441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project __libelf_seterrno (ELF_E_INVALID_PHDR); 164441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return -1; 165441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 166441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 167441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (elf->flags & ELF_F_LAYOUT) 168441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 169441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* The user is supposed to fill out e_phoff. Use it and 170441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project e_phnum to determine the maximum extend. */ 171441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size = MAX ((size_t) size, 172441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr->e_phoff 173441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project + elf_typesize (LIBELFBITS, ELF_T_PHDR, ehdr->e_phnum)); 174441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 175441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 176441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 177441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project update_if_changed (ehdr->e_phoff, 178441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_typesize (LIBELFBITS, ELF_T_EHDR, 1), 179441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr_flags); 180441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 181441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* We need no alignment here. */ 182441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size += elf_typesize (LIBELFBITS, ELF_T_PHDR, ehdr->e_phnum); 183441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 184441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 185441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 186441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shnum > 0) 187441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 188441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_ScnList *list; 189441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project bool first = true; 190441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 191441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project assert (elf->state.ELFW(elf,LIBELFBITS).scns.cnt > 0); 192441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 193441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shnum >= SHN_LORESERVE) 194441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 195441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* We have to fill in the number of sections in the header 196441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project of the zeroth section. */ 197cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Scn *scn0 = &elf->state.ELFW(elf,LIBELFBITS).scns.data[0]; 198441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 199cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng update_if_changed (scn0->shdr.ELFW(e,LIBELFBITS)->sh_size, 200cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng shnum, scn0->shdr_flags); 201cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 202441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 203441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Go over all sections and find out how large they are. */ 204441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project list = &elf->state.ELFW(elf,LIBELFBITS).scns; 205441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 206cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Load the section headers if necessary. This loads the 207cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng headers for all sections. */ 208cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (list->data[1].shdr.ELFW(e,LIBELFBITS) == NULL) 209cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng (void) __elfw2(LIBELFBITS,getshdr_wrlock) (&list->data[1]); 210cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 211441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project do 212441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 213cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng for (size_t cnt = first == true; cnt < list->cnt; ++cnt) 214441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 215441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Scn *scn = &list->data[cnt]; 216441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ElfW2(LIBELFBITS,Shdr) *shdr = scn->shdr.ELFW(e,LIBELFBITS); 217441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project off_t offset = 0; 218441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 219441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project assert (shdr != NULL); 220cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ElfW2(LIBELFBITS,Word) sh_entsize = shdr->sh_entsize; 221cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng ElfW2(LIBELFBITS,Word) sh_align = shdr->sh_addralign ?: 1; 222441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 223441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Set the sh_entsize value if we can reliably detect it. */ 224441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project switch (shdr->sh_type) 225441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 226441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_SYMTAB: 227441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1); 228441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 229441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_RELA: 230441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sh_entsize = elf_typesize (LIBELFBITS, ELF_T_RELA, 1); 231441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 232441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_GROUP: 233441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Only relocatable files can contain section groups. */ 234441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (ehdr->e_type != ET_REL) 235441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 236441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project __libelf_seterrno (ELF_E_GROUP_NOT_REL); 237441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return -1; 238441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 239441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* FALLTHROUGH */ 240441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_SYMTAB_SHNDX: 241441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sh_entsize = elf_typesize (32, ELF_T_WORD, 1); 242441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 243441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_HASH: 244441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sh_entsize = SH_ENTSIZE_HASH (ehdr); 245441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 246441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_DYNAMIC: 247441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sh_entsize = elf_typesize (LIBELFBITS, ELF_T_DYN, 1); 248441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 249441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_REL: 250441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sh_entsize = elf_typesize (LIBELFBITS, ELF_T_REL, 1); 251441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 252441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_DYNSYM: 253441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYM, 1); 254441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 255441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_SUNW_move: 256441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sh_entsize = elf_typesize (LIBELFBITS, ELF_T_MOVE, 1); 257441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 258441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project case SHT_SUNW_syminfo: 259441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project sh_entsize = elf_typesize (LIBELFBITS, ELF_T_SYMINFO, 1); 260441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 261441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project default: 262441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project break; 263441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 264441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 265441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* If the section header contained the wrong entry size 266441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project correct it and mark the header as modified. */ 267441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project update_if_changed (shdr->sh_entsize, sh_entsize, 268441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project scn->shdr_flags); 269441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 270cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (scn->data_read == 0 271cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng && __libelf_set_rawdata_wrlock (scn) != 0) 272cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Something went wrong. The error value is already set. */ 273cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return -1; 274cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 275441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Iterate over all data blocks. */ 276441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (list->data[cnt].data_list_rear != NULL) 277441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 278441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Elf_Data_List *dl = &scn->data_list; 279441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 280441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while (dl != NULL) 281441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 282cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng Elf_Data *data = &dl->data.d; 283cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (dl == &scn->data_list && data->d_buf == NULL 284cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng && scn->rawdata.d.d_buf != NULL) 285cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng data = &scn->rawdata.d; 286cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 287cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (data->d_version == EV_NONE) 288cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng || unlikely (data->d_version >= EV_NUM)) 289441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 290441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project __libelf_seterrno (ELF_E_UNKNOWN_VERSION); 291441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return -1; 292441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 293441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 294cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely (! powerof2 (data->d_align))) 295441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 296441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project __libelf_seterrno (ELF_E_INVALID_ALIGN); 297441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return -1; 298441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 299441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 300cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng sh_align = MAX (sh_align, data->d_align); 301441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 302441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (elf->flags & ELF_F_LAYOUT) 303441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 304441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* The user specified the offset and the size. 305441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project All we have to do is check whether this block 306441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project fits in the size specified for the section. */ 307cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (unlikely ((GElf_Word) (data->d_off 308cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng + data->d_size) 309441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project > shdr->sh_size)) 310441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 311441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project __libelf_seterrno (ELF_E_SECTION_TOO_SMALL); 312441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return -1; 313441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 314441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 315441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 316441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 317441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Determine the padding. */ 318cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng offset = ((offset + data->d_align - 1) 319cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng & ~(data->d_align - 1)); 320441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 321cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng update_if_changed (data->d_off, offset, changed); 322441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 323cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng offset += data->d_size; 324441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 325441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 326441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Next data block. */ 327441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project dl = dl->next; 328441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 329441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 330cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng else 331cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* Get the size of the section from the raw data. If 332cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng none is available the value is zero. */ 333cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng offset += scn->rawdata.d.d_size; 334441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 335441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (elf->flags & ELF_F_LAYOUT) 336441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 337441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size = MAX ((GElf_Word) size, 338441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project shdr->sh_offset 339441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project + (shdr->sh_type != SHT_NOBITS 340441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ? shdr->sh_size : 0)); 341441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 342441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* The alignment must be a power of two. This is a 343441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project requirement from the ELF specification. Additionally 344441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project we test for the alignment of the section being large 345441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project enough for the largest alignment required by a data 346441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project block. */ 347441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (unlikely (! powerof2 (shdr->sh_addralign)) 348441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project || unlikely (shdr->sh_addralign < sh_align)) 349441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 350441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project __libelf_seterrno (ELF_E_INVALID_ALIGN); 351441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return -1; 352441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 353441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 354441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 355441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 356441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* How much alignment do we need for this section. */ 357441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project update_if_changed (shdr->sh_addralign, sh_align, 358441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project scn->shdr_flags); 359441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 360441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size = (size + sh_align - 1) & ~(sh_align - 1); 361cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng int offset_changed = 0; 362441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project update_if_changed (shdr->sh_offset, (GElf_Word) size, 363cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng offset_changed); 364cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng changed |= offset_changed; 365cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng 366cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (offset_changed && scn->data_list_rear == NULL) 367cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng { 368cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng /* The position of the section in the file 369cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng changed. Create the section data list. */ 370cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng if (__elf_getdata_rdlock (scn, NULL) == NULL) 371cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng return -1; 372cc6695e2684ce93cdf8bd2da63d55d2cf49ff076Ben Cheng } 373441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 374441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* See whether the section size is correct. */ 375441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project update_if_changed (shdr->sh_size, (GElf_Word) offset, 376441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project changed); 377441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 378441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_type != SHT_NOBITS) 379441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size += offset; 380441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 381441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project scn->flags |= changed; 382441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 383441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 384441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Check that the section size is actually a multiple of 385441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project the entry size. */ 386441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (shdr->sh_entsize != 0 387441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && unlikely (shdr->sh_size % shdr->sh_entsize != 0) 388441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project && (elf->flags & ELF_F_PERMISSIVE) == 0) 389441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 390441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project __libelf_seterrno (ELF_E_INVALID_SHENTSIZE); 391441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return -1; 392441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 393441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 394441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 395441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project assert (list->next == NULL || list->cnt == list->max); 396441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 397441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project first = false; 398441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 399441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project while ((list = list->next) != NULL); 400441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 401441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Store section information. */ 402441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project if (elf->flags & ELF_F_LAYOUT) 403441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 404441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* The user is supposed to fill out e_phoff. Use it and 405441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project e_phnum to determine the maximum extend. */ 406441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size = MAX ((GElf_Word) size, 407441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project (ehdr->e_shoff 408441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project + (elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum)))); 409441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 410441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project else 411441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project { 412441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Align for section header table. 413441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 414441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project Yes, we use `sizeof' and not `__alignof__' since we do not 415441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project want to be surprised by architectures with less strict 416441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project alignment rules. */ 417441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project#define SHDR_ALIGN sizeof (ElfW2(LIBELFBITS,Off)) 418441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size = (size + SHDR_ALIGN - 1) & ~(SHDR_ALIGN - 1); 419441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 420441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project update_if_changed (ehdr->e_shoff, (GElf_Word) size, elf->flags); 421441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project update_if_changed (ehdr->e_shentsize, 422441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf_typesize (LIBELFBITS, ELF_T_SHDR, 1), 423441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project ehdr_flags); 424441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 425441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project /* Account for the section header size. */ 426441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project size += elf_typesize (LIBELFBITS, ELF_T_SHDR, shnum); 427441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 428441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project } 429441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 430441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project elf->state.ELFW(elf,LIBELFBITS).ehdr_flags |= ehdr_flags; 431441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project 432441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project return size; 433441f72d43a9b550baa779fc82f70816da5f74f0eThe Android Open Source Project} 434