elf_strptr.c revision 4494:b7c909b5a5e9
15647Sgblack@eecs.umich.edu/*- 25647Sgblack@eecs.umich.edu * Copyright (c) 2006 Joseph Koshy 35647Sgblack@eecs.umich.edu * All rights reserved. 45647Sgblack@eecs.umich.edu * 55647Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 65647Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions 75647Sgblack@eecs.umich.edu * are met: 85647Sgblack@eecs.umich.edu * 1. Redistributions of source code must retain the above copyright 95647Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer. 105647Sgblack@eecs.umich.edu * 2. Redistributions in binary form must reproduce the above copyright 115647Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 125647Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution. 135647Sgblack@eecs.umich.edu * 145647Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 155647Sgblack@eecs.umich.edu * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 165647Sgblack@eecs.umich.edu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 175647Sgblack@eecs.umich.edu * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 185647Sgblack@eecs.umich.edu * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 195647Sgblack@eecs.umich.edu * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 205647Sgblack@eecs.umich.edu * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 215647Sgblack@eecs.umich.edu * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 225647Sgblack@eecs.umich.edu * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 235647Sgblack@eecs.umich.edu * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 245647Sgblack@eecs.umich.edu * SUCH DAMAGE. 255647Sgblack@eecs.umich.edu */ 265647Sgblack@eecs.umich.edu 275647Sgblack@eecs.umich.edu 285647Sgblack@eecs.umich.edu#include <sys/param.h> 295647Sgblack@eecs.umich.edu#ifdef __sun 305647Sgblack@eecs.umich.edu#include <sys/sysmacros.h> 315647Sgblack@eecs.umich.edu#endif 325647Sgblack@eecs.umich.edu 335647Sgblack@eecs.umich.edu#include <assert.h> 345647Sgblack@eecs.umich.edu#include "gelf.h" 355647Sgblack@eecs.umich.edu 365647Sgblack@eecs.umich.edu#include "_libelf.h" 375647Sgblack@eecs.umich.edu 385647Sgblack@eecs.umich.edu/* 395647Sgblack@eecs.umich.edu * Convert an ELF section#,offset pair to a string pointer. 405647Sgblack@eecs.umich.edu */ 415647Sgblack@eecs.umich.edu 425647Sgblack@eecs.umich.educhar * 435647Sgblack@eecs.umich.eduelf_strptr(Elf *e, size_t scndx, size_t offset) 445647Sgblack@eecs.umich.edu{ 455647Sgblack@eecs.umich.edu Elf_Scn *s; 465647Sgblack@eecs.umich.edu Elf_Data *d; 475647Sgblack@eecs.umich.edu size_t alignment, count; 485647Sgblack@eecs.umich.edu GElf_Shdr shdr; 495647Sgblack@eecs.umich.edu 505647Sgblack@eecs.umich.edu if (e == NULL || e->e_kind != ELF_K_ELF) { 515647Sgblack@eecs.umich.edu LIBELF_SET_ERROR(ARGUMENT, 0); 525647Sgblack@eecs.umich.edu return (NULL); 535647Sgblack@eecs.umich.edu } 545647Sgblack@eecs.umich.edu 555647Sgblack@eecs.umich.edu if ((s = elf_getscn(e, scndx)) == NULL || 565647Sgblack@eecs.umich.edu gelf_getshdr(s, &shdr) == NULL) 575647Sgblack@eecs.umich.edu return (NULL); 585648Sgblack@eecs.umich.edu 595647Sgblack@eecs.umich.edu if (shdr.sh_type != SHT_STRTAB || 605647Sgblack@eecs.umich.edu offset >= shdr.sh_size) { 615647Sgblack@eecs.umich.edu LIBELF_SET_ERROR(ARGUMENT, 0); 625648Sgblack@eecs.umich.edu return (NULL); 635648Sgblack@eecs.umich.edu } 645647Sgblack@eecs.umich.edu 655647Sgblack@eecs.umich.edu d = NULL; 665647Sgblack@eecs.umich.edu if (e->e_flags & ELF_F_LAYOUT) { 675647Sgblack@eecs.umich.edu 685647Sgblack@eecs.umich.edu /* 695647Sgblack@eecs.umich.edu * The application is taking responsibility for the 705647Sgblack@eecs.umich.edu * ELF object's layout, so we can directly translate 715647Sgblack@eecs.umich.edu * an offset to a `char *' address using the `d_off' 725647Sgblack@eecs.umich.edu * members of Elf_Data descriptors. 735648Sgblack@eecs.umich.edu */ 745647Sgblack@eecs.umich.edu while ((d = elf_getdata(s, d)) != NULL) { 755648Sgblack@eecs.umich.edu 765648Sgblack@eecs.umich.edu if (d->d_buf == 0 || d->d_size == 0) 775648Sgblack@eecs.umich.edu continue; 785648Sgblack@eecs.umich.edu 795648Sgblack@eecs.umich.edu if (d->d_type != ELF_T_BYTE) { 805648Sgblack@eecs.umich.edu LIBELF_SET_ERROR(DATA, 0); 815648Sgblack@eecs.umich.edu return (NULL); 825648Sgblack@eecs.umich.edu } 835648Sgblack@eecs.umich.edu 845648Sgblack@eecs.umich.edu if (offset >= d->d_off && 855648Sgblack@eecs.umich.edu offset < d->d_off + d->d_size) 865648Sgblack@eecs.umich.edu return ((char *) d->d_buf + offset - d->d_off); 875648Sgblack@eecs.umich.edu } 885648Sgblack@eecs.umich.edu } else { 895648Sgblack@eecs.umich.edu /* 905648Sgblack@eecs.umich.edu * Otherwise, the `d_off' members are not useable and 915648Sgblack@eecs.umich.edu * we need to compute offsets ourselves, taking into 925648Sgblack@eecs.umich.edu * account 'holes' in coverage of the section introduced 935648Sgblack@eecs.umich.edu * by alignment requirements. 945648Sgblack@eecs.umich.edu */ 955648Sgblack@eecs.umich.edu count = (size_t) 0; /* cumulative count of bytes seen */ 965648Sgblack@eecs.umich.edu while ((d = elf_getdata(s, d)) != NULL && count <= offset) { 975648Sgblack@eecs.umich.edu 985648Sgblack@eecs.umich.edu if (d->d_buf == NULL || d->d_size == 0) 995648Sgblack@eecs.umich.edu continue; 1005648Sgblack@eecs.umich.edu 1015648Sgblack@eecs.umich.edu if (d->d_type != ELF_T_BYTE) { 1025648Sgblack@eecs.umich.edu LIBELF_SET_ERROR(DATA, 0); 1035648Sgblack@eecs.umich.edu return (NULL); 1045648Sgblack@eecs.umich.edu } 1055648Sgblack@eecs.umich.edu 1065648Sgblack@eecs.umich.edu if ((alignment = d->d_align) > 1) { 1075648Sgblack@eecs.umich.edu if ((alignment & (alignment - 1)) != 0) { 1085648Sgblack@eecs.umich.edu LIBELF_SET_ERROR(DATA, 0); 1095648Sgblack@eecs.umich.edu return (NULL); 1105648Sgblack@eecs.umich.edu } 1115648Sgblack@eecs.umich.edu count = roundup(count, alignment); 1125648Sgblack@eecs.umich.edu } 1135648Sgblack@eecs.umich.edu 1145648Sgblack@eecs.umich.edu if (offset < count) { 1155648Sgblack@eecs.umich.edu /* offset starts in the 'hole' */ 1165648Sgblack@eecs.umich.edu LIBELF_SET_ERROR(ARGUMENT, 0); 1175648Sgblack@eecs.umich.edu return (NULL); 1185648Sgblack@eecs.umich.edu } 1195648Sgblack@eecs.umich.edu 1205648Sgblack@eecs.umich.edu if (offset < count + d->d_size) { 1215648Sgblack@eecs.umich.edu if (d->d_buf != NULL) 1225648Sgblack@eecs.umich.edu return ((char *) d->d_buf + 1235648Sgblack@eecs.umich.edu offset - count); 1245648Sgblack@eecs.umich.edu LIBELF_SET_ERROR(DATA, 0); 1255648Sgblack@eecs.umich.edu return (NULL); 1265648Sgblack@eecs.umich.edu } 1275648Sgblack@eecs.umich.edu 1285648Sgblack@eecs.umich.edu count += d->d_size; 1295648Sgblack@eecs.umich.edu } 1305648Sgblack@eecs.umich.edu } 1315648Sgblack@eecs.umich.edu 1325648Sgblack@eecs.umich.edu LIBELF_SET_ERROR(ARGUMENT, 0); 1335648Sgblack@eecs.umich.edu return (NULL); 1345648Sgblack@eecs.umich.edu} 1355648Sgblack@eecs.umich.edu