16258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper/* Update program header program header table entry. 2159ac52b061c60947a943c102298cd692223274fMark Wielaard Copyright (C) 2000-2010 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is part of elfutils. 46258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper Written by Ulrich Drepper <drepper@redhat.com>, 2000. 5de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is free software; you can redistribute it and/or modify 76258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper it under the terms of either 8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU Lesser General Public License as published by the Free 10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 3 of the License, or (at 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU General Public License as published by the Free 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 2 of the License, or (at 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 18de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 19de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or both in parallel, as here. 20de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 216258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper elfutils is distributed in the hope that it will be useful, but 226258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper WITHOUT ANY WARRANTY; without even the implied warranty of 236258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 246258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper General Public License for more details. 25de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 26de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard You should have received copies of the GNU General Public License and 27de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard the GNU Lesser General Public License along with this program. If 286258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper not, see <http://www.gnu.org/licenses/>. */ 296258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 306258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper#ifdef HAVE_CONFIG_H 31b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh# include <config.h> 326258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper#endif 33b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 34b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh#include <gelf.h> 356258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper#include <string.h> 36b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 37b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh#include "libelfP.h" 38b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 39b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 40159ac52b061c60947a943c102298cd692223274fMark Wielaardint 41b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsiehgelf_update_phdr (Elf *elf, int ndx, GElf_Phdr *src) 42b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh{ 43b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh int result = 0; 44b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 45b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (elf == NULL) 46b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh return 0; 47159ac52b061c60947a943c102298cd692223274fMark Wielaard 48b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (unlikely (elf->kind != ELF_K_ELF)) 49b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh { 50b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh __libelf_seterrno (ELF_E_INVALID_HANDLE); 51b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh return 0; 52b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh } 53b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 546258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper rwlock_wrlock (elf->lock); 55b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 56b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (elf->class == ELFCLASS32) 57b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh { 586258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper Elf32_Phdr *phdr = elf->state.elf32.phdr; 59b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 60b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh /* We have to convert the data to the 32 bit format. This might 61b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh overflow some fields so we have to test for this case before 62b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh copying. */ 63b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (unlikely (src->p_offset > 0xffffffffull) 64b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh || unlikely (src->p_vaddr > 0xffffffffull) 65b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh || unlikely (src->p_paddr > 0xffffffffull) 66b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh || unlikely (src->p_filesz > 0xffffffffull) 67b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh || unlikely (src->p_memsz > 0xffffffffull) 68b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh || unlikely (src->p_align > 0xffffffffull)) 69b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh { 70b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh __libelf_seterrno (ELF_E_INVALID_DATA); 71b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh goto out; 72b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh } 73b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 74b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (phdr == NULL) 75b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh { 76b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh phdr = __elf32_getphdr_wrlock (elf); 77b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (phdr == NULL) 78b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh /* The error number is already set. */ 79b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh goto out; 80b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh } 816258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper 826258e7486eb3eed6e50005946795c5fbf73aa106Ulrich Drepper /* Test whether the index is ok. */ 83b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh size_t phnum; 84b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (ndx >= elf->state.elf32.ehdr->e_phnum 85b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh && (elf->state.elf32.ehdr->e_phnum != PN_XNUM 86b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh || __elf_getphdrnum_rdlock (elf, &phnum) != 0 87b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh || (size_t) ndx >= phnum)) 88b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh { 89b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh __libelf_seterrno (ELF_E_INVALID_INDEX); 90b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh goto out; 91b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh } 92b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 93b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh /* Now correct the pointer to point to the correct element. */ 94b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh phdr += ndx; 95b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 96b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh#define COPY(name) \ 97b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh phdr->name = src->name 98b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh COPY (p_type); 99b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh COPY (p_offset); 100b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh COPY (p_vaddr); 101b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh COPY (p_paddr); 102b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh COPY (p_filesz); 103b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh COPY (p_memsz); 10442f686820a19806da629990bf7ae69a6a2fcfb1fRoland McGrath COPY (p_flags); 105b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh COPY (p_align); 106b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh } 10742f686820a19806da629990bf7ae69a6a2fcfb1fRoland McGrath else 108b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh { 109b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh Elf64_Phdr *phdr = elf->state.elf64.phdr; 110b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 111b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (phdr == NULL) 112b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh { 113b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh phdr = __elf64_getphdr_wrlock (elf); 114b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (phdr == NULL) 115b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh /* The error number is already set. */ 116b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh goto out; 117b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh } 118b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 119b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh /* Test whether the index is ok. */ 120b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh size_t phnum; 121b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh if (ndx >= elf->state.elf64.ehdr->e_phnum 122b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh && (elf->state.elf64.ehdr->e_phnum != PN_XNUM 123b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh || __elf_getphdrnum_rdlock (elf, &phnum) != 0 12442f686820a19806da629990bf7ae69a6a2fcfb1fRoland McGrath || (size_t) ndx >= phnum)) 125b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh { 126b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh __libelf_seterrno (ELF_E_INVALID_INDEX); 127b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh goto out; 128b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh } 129b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 130b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh /* Just copy the data. */ 131b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh memcpy (phdr + ndx, src, sizeof (Elf64_Phdr)); 132159ac52b061c60947a943c102298cd692223274fMark Wielaard } 133159ac52b061c60947a943c102298cd692223274fMark Wielaard 134159ac52b061c60947a943c102298cd692223274fMark Wielaard /* Mark the program header as modified. */ 135b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh elf->state.elf.phdr_flags |= ELF_F_DIRTY; 136b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 137159ac52b061c60947a943c102298cd692223274fMark Wielaard result = 1; 138b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh 139159ac52b061c60947a943c102298cd692223274fMark Wielaard out: 140159ac52b061c60947a943c102298cd692223274fMark Wielaard rwlock_unlock (elf->lock); 141159ac52b061c60947a943c102298cd692223274fMark Wielaard 142b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh return result; 143b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh} 144b1450614fd26d1a9b8ee17fe3f0290d23ddd0748Chih-Hung Hsieh