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: getdata.c,v 1.1.1.1 2005/10/21 19:00:00 marcel Exp $";
00028 #endif
00029
00030 static Elf_Data*
00031 _elf_cook_scn(Elf *elf, Elf_Scn *scn, Scn_Data *sd) {
00032 Elf_Data dst;
00033 Elf_Data src;
00034 int flag = 0;
00035 size_t dlen;
00036
00037 elf_assert(elf->e_data);
00038
00039
00040
00041
00042 src = sd->sd_data;
00043 src.d_version = elf->e_version;
00044 if (elf->e_rawdata) {
00045 src.d_buf = elf->e_rawdata + scn->s_offset;
00046 }
00047 else {
00048 src.d_buf = elf->e_data + scn->s_offset;
00049 }
00050
00051
00052
00053
00054 dst = sd->sd_data;
00055 if (elf->e_class == ELFCLASS32) {
00056 dlen = _elf32_xltsize(&src, dst.d_version, elf->e_encoding, 0);
00057 }
00058 #if __LIBELF64
00059 else if (elf->e_class == ELFCLASS64) {
00060 dlen = _elf64_xltsize(&src, dst.d_version, elf->e_encoding, 0);
00061 }
00062 #endif
00063 else {
00064 elf_assert(valid_class(elf->e_class));
00065 seterr(ERROR_UNIMPLEMENTED);
00066 return NULL;
00067 }
00068 if (dlen == (size_t)-1) {
00069 return NULL;
00070 }
00071 dst.d_size = dlen;
00072 if (elf->e_rawdata != elf->e_data && dst.d_size <= src.d_size) {
00073 dst.d_buf = elf->e_data + scn->s_offset;
00074 }
00075 else if (!(dst.d_buf = malloc(dst.d_size))) {
00076 seterr(ERROR_MEM_SCNDATA);
00077 return NULL;
00078 }
00079 else {
00080 flag = 1;
00081 }
00082
00083
00084
00085
00086 if (_elf_xlatetom(elf, &dst, &src)) {
00087 sd->sd_memdata = (char*)dst.d_buf;
00088 sd->sd_data = dst;
00089 if (!(sd->sd_free_data = flag)) {
00090 elf->e_cooked = 1;
00091 }
00092 return &sd->sd_data;
00093 }
00094
00095 if (flag) {
00096 free(dst.d_buf);
00097 }
00098 return NULL;
00099 }
00100
00101 Elf_Data*
00102 elf_getdata(Elf_Scn *scn, Elf_Data *data) {
00103 Scn_Data *sd;
00104 Elf *elf;
00105
00106 if (!scn) {
00107 return NULL;
00108 }
00109 elf_assert(scn->s_magic == SCN_MAGIC);
00110 if (scn->s_index == SHN_UNDEF) {
00111 seterr(ERROR_NULLSCN);
00112 }
00113 else if (data) {
00114 for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
00115 elf_assert(sd->sd_magic == DATA_MAGIC);
00116 elf_assert(sd->sd_scn == scn);
00117 if (data == &sd->sd_data) {
00118
00119
00120
00121 return &sd->sd_link->sd_data;
00122 }
00123 }
00124 seterr(ERROR_SCNDATAMISMATCH);
00125 }
00126 else if ((sd = scn->s_data_1)) {
00127 elf_assert(sd->sd_magic == DATA_MAGIC);
00128 elf_assert(sd->sd_scn == scn);
00129 elf = scn->s_elf;
00130 elf_assert(elf);
00131 elf_assert(elf->e_magic == ELF_MAGIC);
00132 if (sd->sd_freeme) {
00133
00134 return &sd->sd_data;
00135 }
00136 else if (scn->s_type == SHT_NULL) {
00137 seterr(ERROR_NULLSCN);
00138 }
00139 else if (sd->sd_memdata) {
00140
00141 return &sd->sd_data;
00142 }
00143 else if (scn->s_offset < 0 || scn->s_offset > elf->e_size) {
00144 seterr(ERROR_OUTSIDE);
00145 }
00146 else if (scn->s_type == SHT_NOBITS || !scn->s_size) {
00147
00148 return &sd->sd_data;
00149 }
00150 else if (scn->s_offset + scn->s_size > elf->e_size) {
00151 seterr(ERROR_TRUNC_SCN);
00152 }
00153 else if (valid_class(elf->e_class)) {
00154 return _elf_cook_scn(elf, scn, sd);
00155 }
00156 else {
00157 seterr(ERROR_UNKNOWN_CLASS);
00158 }
00159 }
00160 return NULL;
00161 }