00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <private.h>
00025
00026 #ifndef lint
00027 static const char rcsid[] = "@(#) $Id: strptr.c,v 1.1.1.1 2005/10/21 19:00:00 marcel Exp $";
00028 #endif
00029
00030 char*
00031 elf_strptr(Elf *elf, size_t section, size_t offset) {
00032 Elf_Data *data;
00033 Elf_Scn *scn;
00034 size_t n;
00035 char *s;
00036
00037 if (!elf) {
00038 return NULL;
00039 }
00040 elf_assert(elf->e_magic == ELF_MAGIC);
00041 if (!(scn = elf_getscn(elf, section))) {
00042 return NULL;
00043 }
00044 if (scn->s_index == SHN_UNDEF) {
00045 seterr(ERROR_NOSTRTAB);
00046 return NULL;
00047 }
00048
00049
00050
00051 if (elf->e_class == ELFCLASS32) {
00052 if (scn->s_shdr32.sh_type != SHT_STRTAB) {
00053 seterr(ERROR_NOSTRTAB);
00054 return NULL;
00055 }
00056 }
00057 #if __LIBELF64
00058 else if (elf->e_class == ELFCLASS64) {
00059 if (scn->s_shdr64.sh_type != SHT_STRTAB) {
00060 seterr(ERROR_NOSTRTAB);
00061 return NULL;
00062 }
00063 }
00064 #endif
00065 else if (valid_class(elf->e_class)) {
00066 seterr(ERROR_UNIMPLEMENTED);
00067 return NULL;
00068 }
00069 else {
00070 seterr(ERROR_UNKNOWN_CLASS);
00071 return NULL;
00072 }
00073
00074
00075
00076 n = 0;
00077 data = NULL;
00078 if (elf->e_elf_flags & ELF_F_LAYOUT) {
00079
00080
00081
00082
00083 while ((data = elf_getdata(scn, data))) {
00084 n = data->d_off;
00085 if (offset >= n && offset - n < data->d_size) {
00086
00087
00088
00089 break;
00090 }
00091 }
00092 }
00093 else {
00094
00095
00096
00097 while ((data = elf_getdata(scn, data))) {
00098 if (data->d_align > 1) {
00099 n += data->d_align - 1;
00100 n -= n % data->d_align;
00101 }
00102 if (offset < n) {
00103
00104
00105
00106 seterr(ERROR_BADSTROFF);
00107 return NULL;
00108 }
00109 if (offset - n < data->d_size) {
00110
00111
00112
00113 break;
00114 }
00115 n += data->d_size;
00116 }
00117 }
00118 if (data == NULL) {
00119
00120
00121
00122 seterr(ERROR_BADSTROFF);
00123 return NULL;
00124 }
00125 if (data->d_buf == NULL) {
00126
00127
00128
00129 seterr(ERROR_NULLBUF);
00130 return NULL;
00131 }
00132 offset -= n;
00133 s = (char*)data->d_buf;
00134 for (n = offset; n < data->d_size; n++) {
00135 if (s[n] == '\0') {
00136
00137
00138
00139 return s + offset;
00140 }
00141 }
00142
00143
00144
00145
00146 seterr(ERROR_UNTERM);
00147 return NULL;
00148 }