1cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath/* Get information from auxiliary vector at the given index. 21ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaard Copyright (C) 2007, 2015 Red Hat, Inc. 3de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is part of elfutils. 4cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 5de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard This file is free software; you can redistribute it and/or modify 6de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard it under the terms of either 7cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 8de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU Lesser General Public License as published by the Free 9de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 3 of the License, or (at 10de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 11de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 12de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or 13de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 14de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard * the GNU General Public License as published by the Free 15de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard Software Foundation; either version 2 of the License, or (at 16de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard your option) any later version 17de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 18de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard or both in parallel, as here. 19de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard 20de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard elfutils is distributed in the hope that it will be useful, but 21cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath WITHOUT ANY WARRANTY; without even the implied warranty of 22cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath General Public License for more details. 24cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 25de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard You should have received copies of the GNU General Public License and 26de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard the GNU Lesser General Public License along with this program. If 27de2ed97f33139af5c7a0811e4ec66fc896a13cf2Mark Wielaard not, see <http://www.gnu.org/licenses/>. */ 28cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 29cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath#ifdef HAVE_CONFIG_H 30cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath# include <config.h> 31cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath#endif 32cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 33cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath#include <assert.h> 34cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath#include <gelf.h> 35cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath#include <string.h> 36cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 37cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath#include "libelfP.h" 38cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 39cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 40cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrathGElf_auxv_t * 411ccdfb683ad6c7e59793136c3a657ddf131cafd1Mark Wielaardgelf_getauxv (Elf_Data *data, int ndx, GElf_auxv_t *dst) 42cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath{ 43cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath Elf_Data_Scn *data_scn = (Elf_Data_Scn *) data; 44cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath GElf_auxv_t *result = NULL; 45cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath Elf *elf; 46cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 47cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath if (data_scn == NULL) 48cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath return NULL; 49cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 50cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath if (unlikely (data_scn->d.d_type != ELF_T_AUXV)) 51cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath { 52cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath __libelf_seterrno (ELF_E_INVALID_HANDLE); 53cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath return NULL; 54cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath } 55cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 56cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath elf = data_scn->s->elf; 57cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 58b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath rwlock_rdlock (elf->lock); 59cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 60cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath /* This is the one place where we have to take advantage of the fact 61cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath that an `Elf_Data' pointer is also a pointer to `Elf_Data_Scn'. 62cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath The interface is broken so that it requires this hack. */ 63cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath if (elf->class == ELFCLASS32) 64cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath { 65cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath Elf32_auxv_t *src; 66cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 67cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath /* Here it gets a bit more complicated. The format of the vector 68cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath entries has to be converted. The user better have provided a 69cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath buffer where we can store the information. While copying the data 70cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath we convert the format. */ 71cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath if (unlikely ((ndx + 1) * sizeof (Elf32_auxv_t) > data_scn->d.d_size)) 72cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath { 73cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath __libelf_seterrno (ELF_E_INVALID_INDEX); 74cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath goto out; 75cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath } 76cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 77cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath src = &((Elf32_auxv_t *) data_scn->d.d_buf)[ndx]; 78cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 79cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath /* This might look like a simple copy operation but it's 80cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath not. There are zero- and sign-extensions going on. */ 81cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath dst->a_type = src->a_type; 82cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath dst->a_un.a_val = src->a_un.a_val; 83cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath } 84cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath else 85cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath { 86cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath /* If this is a 64 bit object it's easy. */ 87cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath assert (sizeof (GElf_auxv_t) == sizeof (Elf64_auxv_t)); 88cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 89cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath /* The data is already in the correct form. Just make sure the 90cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath index is OK. */ 91cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath if (unlikely ((ndx + 1) * sizeof (GElf_auxv_t) > data_scn->d.d_size)) 92cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath { 93cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath __libelf_seterrno (ELF_E_INVALID_INDEX); 94cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath goto out; 95cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath } 96cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 97d0509d49a080796d3257a8cd962039cd9b7f53f6Mark Wielaard memcpy (dst, data_scn->d.d_buf + ndx * sizeof (GElf_auxv_t), 98d0509d49a080796d3257a8cd962039cd9b7f53f6Mark Wielaard sizeof (GElf_auxv_t)); 99cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath } 100cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 101cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath result = dst; 102cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 103cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath out: 104b4d6f0f8064f2b706ea9035ef0393d8299671390Roland McGrath rwlock_unlock (elf->lock); 105cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath 106cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath return result; 107cb6d865011ad98a8ac2018f072f396a2268739caRoland McGrath} 108