178 */
179 res = (res << (64 - shift)) >> (64 - shift);
180
181 return (res);
182 }
183
184 /*
185 * Extract a DWARF encoded datum
186 *
187 * entry:
188 * data - Base of data buffer containing encoded bytes
189 * dotp - Address of variable containing index within data
190 * at which the desired datum starts.
191 * ehe_flags - DWARF encoding
192 * eident - ELF header e_ident[] array for object being processed
193 * sh_base - Base address of ELF section containing desired datum
194 * sh_offset - Offset relative to sh_base of desired datum.
195 */
196 uint64_t
197 dwarf_ehe_extract(unsigned char *data, uint64_t *dotp, uint_t ehe_flags,
198 unsigned char *eident, uint64_t sh_base, uint64_t sh_offset)
199 {
200 uint64_t dot = *dotp;
201 uint_t lsb;
202 uint_t wordsize;
203 uint_t fsize;
204 uint64_t result;
205
206 if (eident[EI_DATA] == ELFDATA2LSB)
207 lsb = 1;
208 else
209 lsb = 0;
210
211 if (eident[EI_CLASS] == ELFCLASS64)
212 wordsize = 8;
213 else
214 wordsize = 4;
215
216 switch (ehe_flags & 0x0f) {
217 case DW_EH_PE_omit:
218 return (0);
264 val = data[dot];
265 result |= val << ((fsize - cnt - 1) * 8);
266 }
267 }
268 /*
269 * perform sign extension
270 */
271 if ((ehe_flags & DW_EH_PE_signed) &&
272 (fsize < sizeof (uint64_t))) {
273 int64_t sresult;
274 uint_t bitshift;
275 sresult = result;
276 bitshift = (sizeof (uint64_t) - fsize) * 8;
277 sresult = (sresult << bitshift) >> bitshift;
278 result = sresult;
279 }
280
281 /*
282 * If value is relative to a base address, adjust it
283 */
284 if (result) {
285 switch (ehe_flags & 0xf0) {
286 case DW_EH_PE_pcrel:
287 result += sh_base + sh_offset;
288 break;
289
290 case DW_EH_PE_datarel:
291 result += sh_base;
292 break;
293 }
294 }
295 *dotp = dot;
296 return (result);
297 }
|
178 */
179 res = (res << (64 - shift)) >> (64 - shift);
180
181 return (res);
182 }
183
184 /*
185 * Extract a DWARF encoded datum
186 *
187 * entry:
188 * data - Base of data buffer containing encoded bytes
189 * dotp - Address of variable containing index within data
190 * at which the desired datum starts.
191 * ehe_flags - DWARF encoding
192 * eident - ELF header e_ident[] array for object being processed
193 * sh_base - Base address of ELF section containing desired datum
194 * sh_offset - Offset relative to sh_base of desired datum.
195 */
196 uint64_t
197 dwarf_ehe_extract(unsigned char *data, uint64_t *dotp, uint_t ehe_flags,
198 unsigned char *eident, boolean_t frame_hdr, uint64_t sh_base,
199 uint64_t sh_offset, uint64_t dbase)
200 {
201 uint64_t dot = *dotp;
202 uint_t lsb;
203 uint_t wordsize;
204 uint_t fsize;
205 uint64_t result;
206
207 if (eident[EI_DATA] == ELFDATA2LSB)
208 lsb = 1;
209 else
210 lsb = 0;
211
212 if (eident[EI_CLASS] == ELFCLASS64)
213 wordsize = 8;
214 else
215 wordsize = 4;
216
217 switch (ehe_flags & 0x0f) {
218 case DW_EH_PE_omit:
219 return (0);
265 val = data[dot];
266 result |= val << ((fsize - cnt - 1) * 8);
267 }
268 }
269 /*
270 * perform sign extension
271 */
272 if ((ehe_flags & DW_EH_PE_signed) &&
273 (fsize < sizeof (uint64_t))) {
274 int64_t sresult;
275 uint_t bitshift;
276 sresult = result;
277 bitshift = (sizeof (uint64_t) - fsize) * 8;
278 sresult = (sresult << bitshift) >> bitshift;
279 result = sresult;
280 }
281
282 /*
283 * If value is relative to a base address, adjust it
284 */
285 switch (ehe_flags & 0xf0) {
286 case DW_EH_PE_pcrel:
287 result += sh_base + sh_offset;
288 break;
289
290 /*
291 * datarel is relative to .eh_frame_hdr if within .eh_frame,
292 * but GOT if not.
293 */
294 case DW_EH_PE_datarel:
295 if (frame_hdr)
296 result += sh_base;
297 else
298 result += dbase;
299 break;
300 }
301
302 /* Truncate the result to its specified size */
303 result = (result << ((sizeof (uint64_t) - fsize) * 8)) >>
304 ((sizeof (uint64_t) - fsize) * 8);
305
306 *dotp = dot;
307 return (result);
308 }
|