"Fossies" - the Fresh Open Source Software Archive

Member "libelf-0.8.13/lib/strptr.c" (23 May 2008, 3393 Bytes) of package /linux/misc/old/libelf-0.8.13.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "strptr.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * strptr.c - implementation of the elf_strptr(3) function.
    3  * Copyright (C) 1995 - 2007 Michael Riepe
    4  *
    5  * This library is free software; you can redistribute it and/or
    6  * modify it under the terms of the GNU Library General Public
    7  * License as published by the Free Software Foundation; either
    8  * version 2 of the License, or (at your option) any later version.
    9  *
   10  * This library is distributed in the hope that it will be useful,
   11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13  * Library General Public License for more details.
   14  *
   15  * You should have received a copy of the GNU Library General Public
   16  * License along with this library; if not, write to the Free Software
   17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
   18  */
   19 
   20 #include <private.h>
   21 
   22 #ifndef lint
   23 static const char rcsid[] = "@(#) $Id: strptr.c,v 1.12 2008/05/23 08:15:35 michael Exp $";
   24 #endif /* lint */
   25 
   26 char*
   27 elf_strptr(Elf *elf, size_t section, size_t offset) {
   28     Elf_Data *data;
   29     Elf_Scn *scn;
   30     size_t n;
   31     char *s;
   32 
   33     if (!elf) {
   34     return NULL;
   35     }
   36     elf_assert(elf->e_magic == ELF_MAGIC);
   37     if (!(scn = elf_getscn(elf, section))) {
   38     return NULL;
   39     }
   40     if (scn->s_index == SHN_UNDEF) {
   41     seterr(ERROR_NOSTRTAB);
   42     return NULL;
   43     }
   44     /*
   45      * checking the section header is more appropriate
   46      */
   47     if (elf->e_class == ELFCLASS32) {
   48     if (scn->s_shdr32.sh_type != SHT_STRTAB) {
   49         seterr(ERROR_NOSTRTAB);
   50         return NULL;
   51     }
   52     }
   53 #if __LIBELF64
   54     else if (elf->e_class == ELFCLASS64) {
   55     if (scn->s_shdr64.sh_type != SHT_STRTAB) {
   56         seterr(ERROR_NOSTRTAB);
   57         return NULL;
   58     }
   59     }
   60 #endif /* __LIBELF64 */
   61     else if (valid_class(elf->e_class)) {
   62     seterr(ERROR_UNIMPLEMENTED);
   63     return NULL;
   64     }
   65     else {
   66     seterr(ERROR_UNKNOWN_CLASS);
   67     return NULL;
   68     }
   69     /*
   70      * Find matching buffer
   71      */
   72     n = 0;
   73     data = NULL;
   74     if (elf->e_elf_flags & ELF_F_LAYOUT) {
   75     /*
   76      * Programmer is responsible for d_off
   77      * Note: buffers may be in any order!
   78      */
   79     while ((data = elf_getdata(scn, data))) {
   80         n = data->d_off;
   81         if (offset >= n && offset - n < data->d_size) {
   82         /*
   83          * Found it
   84          */
   85         break;
   86         }
   87     }
   88     }
   89     else {
   90     /*
   91      * Calculate offsets myself
   92      */
   93     while ((data = elf_getdata(scn, data))) {
   94         if (data->d_align > 1) {
   95         n += data->d_align - 1;
   96         n -= n % data->d_align;
   97         }
   98         if (offset < n) {
   99         /*
  100          * Invalid offset: points into a hole
  101          */
  102         seterr(ERROR_BADSTROFF);
  103         return NULL;
  104         }
  105         if (offset - n < data->d_size) {
  106         /*
  107          * Found it
  108          */
  109         break;
  110         }
  111         n += data->d_size;
  112     }
  113     }
  114     if (data == NULL) {
  115     /*
  116      * Not found
  117      */
  118     seterr(ERROR_BADSTROFF);
  119     return NULL;
  120     }
  121     if (data->d_buf == NULL) {
  122     /*
  123      * Buffer is NULL (usually the programmers' fault)
  124      */
  125     seterr(ERROR_NULLBUF);
  126     return NULL;
  127     }
  128     offset -= n;
  129     s = (char*)data->d_buf;
  130     if (!(_elf_sanity_checks & SANITY_CHECK_STRPTR)) {
  131     return s + offset;
  132     }
  133     /*
  134      * Perform extra sanity check
  135      */
  136     for (n = offset; n < data->d_size; n++) {
  137     if (s[n] == '\0') {
  138         /*
  139          * Return properly NUL terminated string
  140          */
  141         return s + offset;
  142     }
  143     }
  144     /*
  145      * String is not NUL terminated
  146      * Return error to avoid SEGV in application
  147      */
  148     seterr(ERROR_UNTERM);
  149     return NULL;
  150 }