Skip to content

Commit a2cddc8

Browse files
committed
/home/fox/release/dtrace/2009/dtrace-20090721.tar.bz2
1 parent efb2b78 commit a2cddc8

3 files changed

Lines changed: 78 additions & 7 deletions

File tree

.release

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
date=Mon Jul 20 23:29:57 BST 2009
2-
release=dtrace-20090720
3-
build=131
1+
date=Tue Jul 21 23:57:32 BST 2009
2+
release=dtrace-20090721
3+
build=134

driver/dtrace_isa.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,12 @@ return;
226226
#endif
227227
}
228228

229+
/**********************************************************************/
230+
/* Get user space stack for the probed process. We need to handle */
231+
/* 32 + 64 bit binaries, if we are on a 64b kernel, and also frame */
232+
/* pointer/no frame pointer. We use the DWARF code to walk the CFA */
233+
/* frames to tell us where we can find the return address. */
234+
/**********************************************************************/
229235
void
230236
dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit)
231237
{ uint64_t *pcstack_end = pcstack + pcstack_limit;
@@ -317,12 +323,58 @@ dtrace_getupcstack(uint64_t *pcstack, int pcstack_limit)
317323
bos = sp = task_pt_regs(current)->rsp;
318324
#endif
319325

326+
#if 0
320327
while (pcstack < pcstack_end &&
321328
sp >= bos) {
322329
if (validate_ptr(sp))
323330
*pcstack++ = sp[0];
324331
sp++;
325332
}
333+
#endif
334+
335+
/***********************************************/
336+
/* Find base of the code area for ELF */
337+
/* header. */
338+
/***********************************************/
339+
while (pcstack < pcstack_end &&
340+
sp >= bos) {
341+
struct vm_area_struct *vm = find_vma(current->mm, sp[0]);
342+
int cfa_offset;
343+
char dw[200];
344+
int do_dwarf_phdr(char *, char *);
345+
int dw_find_ret_addr(char *, unsigned long, int *);
346+
347+
348+
if (vm == NULL)
349+
break;
350+
/***********************************************/
351+
/* Work out where the .eh_frame section is */
352+
/* in memory. */
353+
/***********************************************/
354+
char *ptr = vm->vm_start;
355+
printk("elf=%02x %02x %02x %02x\n", ptr[0], ptr[1], ptr[2], ptr[3]);
356+
if (do_dwarf_phdr((char *) vm->vm_start, &dw) < 0) {
357+
printk("sorry - no phdr\n");
358+
break;
359+
}
360+
361+
/***********************************************/
362+
/* Now process the CFA machinery to find */
363+
/* where the next return address is on the */
364+
/* stack (relative to where we are). */
365+
/***********************************************/
366+
if (dw_find_ret_addr(dw, *sp, &cfa_offset) < 0) {
367+
printk("sorry..\n");
368+
break;
369+
}
370+
371+
printk("vm=%p %p: %p\n", vm, vm->vm_start, *(long *) vm->vm_start);
372+
sp = (char *) sp + cfa_offset;
373+
break;
374+
if (validate_ptr(sp))
375+
*pcstack++ = sp[0];
376+
sp++;
377+
}
326378
#if 0
327379
int lvl = 0;
328380
*pcstack++ = sp[0];

driver/dwarf.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ The rules in the register set now apply to location L1.
113113
#include <stdlib.h>
114114
#include <string.h>
115115
#include <sys/types.h>
116-
#include <dwarf.h>
116+
//#include <dwarf.h> /* Might not have dwarf.h, but we dont need it */
117117
#include <elf.h>
118118
#include <libelf.h>
119119
#endif
@@ -122,7 +122,9 @@ The rules in the register set now apply to location L1.
122122
/* Kernel mode definitions. */
123123
/**********************************************************************/
124124
#if defined(_KERNEL)
125-
# define printf if (0) printk
125+
# define printf if (1) printk
126+
#else
127+
# define printk printf
126128
#endif
127129

128130
#define DW_EH_PE_FORMAT_MASK 0x0f /* format of the encoded value */
@@ -319,9 +321,17 @@ do_dwarf_phdr(char *ptr, dw_info_t *dw)
319321
Elf64_Phdr *phdr;
320322
int i;
321323

324+
/***********************************************/
325+
/* Check for ELF magic header. */
326+
/***********************************************/
327+
if (ptr[0] != 0x7f || ptr[1] != 'E' || ptr[2] != 'L' || ptr[3] != 'F')
328+
return -1;
329+
322330
ehdr = (Elf64_Ehdr *) ptr;
323331
phdr = (Elf64_Phdr *) ((char *) ehdr + ehdr->e_phoff);
324332

333+
memset(dw, 0, sizeof *dw);
334+
325335
for (i = 0; i < ehdr->e_phnum; i++) {
326336
if (do_phdr)
327337
printf("%d: type=%x offset=%lx size=%lx vaddr=%p\n",
@@ -338,6 +348,9 @@ do_dwarf_phdr(char *ptr, dw_info_t *dw)
338348
dw->eh_frame_hdr_data = (char *) phdr->p_vaddr;
339349

340350
addr = (char *) phdr->p_vaddr + phdr->p_memsz;
351+
#if defined(_KERNEL)
352+
addr = ptr + (long) addr;
353+
#endif
341354
if ((long) addr & 0x7)
342355
addr = (char *) (((long) addr | 7) + 1);
343356
dw->eh_frame_sec = &dw->eh_frame_s;
@@ -385,6 +398,7 @@ dw_find_ret_addr(dw_info_t *dw, unsigned long pc, int *cfa_offsetp)
385398

386399
char *aug = NULL;
387400

401+
printk("here....1 fp=%p\n", fp);
388402
/***********************************************/
389403
/* Walk the series of CIE/FDE entries til */
390404
/* we find one that matches the target */
@@ -403,6 +417,7 @@ dw_find_ret_addr(dw_info_t *dw, unsigned long pc, int *cfa_offsetp)
403417
fp_start = fp;
404418

405419
cie = *(uint32_t *) fp; fp += 4;
420+
printk("here....%d\n", __LINE__);
406421
if (cie == 0) {
407422
printf("\nCIE length=%08x\n", len);
408423
version = *fp++;
@@ -432,8 +447,8 @@ dw_find_ret_addr(dw_info_t *dw, unsigned long pc, int *cfa_offsetp)
432447
}
433448
printf("\n");
434449
}
435-
fp += aug_len;
436450
a = fp;
451+
fp += aug_len;
437452
for (p = aug; ; p++) {
438453
int ok = 1;
439454
//printf("aug %x %c\n", *p, *p ? *p : 'x');
@@ -445,7 +460,7 @@ dw_find_ret_addr(dw_info_t *dw, unsigned long pc, int *cfa_offsetp)
445460
a += 1 + size_of_encoded_value(*a);
446461
break;
447462
case 'R':
448-
//printf("R encoding %x\n", *a);
463+
printf("R encoding %x\n", *a);
449464
dw->fde_encoding = *a++;
450465
break;
451466
case 'z':
@@ -465,6 +480,10 @@ dw_find_ret_addr(dw_info_t *dw, unsigned long pc, int *cfa_offsetp)
465480
dw->pc_end = *(uint32_t *) fp; fp += 4;
466481
//printf("pc_begin=%p vad=%p %p\n", pc_begin, p_eh->p_vaddr, fp-eh_frame_data);
467482
if ((dw->fde_encoding & 0x70) == DW_EH_PE_pcrel) {
483+
printk("pc_begin1=%p\n", dw->pc_begin);
484+
printk("pc_begin2=%p\n", dw->eh_frame_sec->sh_addr);
485+
printk("pc_begin3=%p\n", fp - dw->eh_frame_data - 8);
486+
printk("looking for %p\n", pc);
468487
dw->pc_begin += dw->eh_frame_sec->sh_addr;
469488
dw->pc_begin += fp - dw->eh_frame_data - 8;
470489
}

0 commit comments

Comments
 (0)