Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 257044
b: refs/heads/master
c: 68eb1d2
h: refs/heads/master
v: v3
  • Loading branch information
Steven Rostedt authored and Steven Rostedt committed May 17, 2011
1 parent e3fbbeb commit cb20e97
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: df2ccb69454d022ce99e3a3b7ee7f9fb4a4e9563
refs/heads/master: 68eb1d2e5370c6da4c871c80fdccbe315dc2f3c1
40 changes: 38 additions & 2 deletions trunk/scripts/recordmcount.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,34 @@ umalloc(size_t size)
return addr;
}

static unsigned char ideal_nop5_x86_64[5] = { 0x0f, 0x1f, 0x44, 0x00, 0x00 };
static unsigned char ideal_nop5_x86_32[5] = { 0x3e, 0x8d, 0x74, 0x26, 0x00 };
static unsigned char *ideal_nop;

static char rel_type_nop;

static int (*make_nop)(void *map, size_t const offset);

static int make_nop_x86(void *map, size_t const offset)
{
uint32_t *ptr;
unsigned char *op;

/* Confirm we have 0xe8 0x0 0x0 0x0 0x0 */
ptr = map + offset;
if (*ptr != 0)
return -1;

op = map + offset - 1;
if (*op != 0xe8)
return -1;

/* convert to nop */
ulseek(fd_map, offset - 1, SEEK_SET);
uwrite(fd_map, ideal_nop, 5);
return 0;
}

/*
* Get the whole file as a programming convenience in order to avoid
* malloc+lseek+read+free of many pieces. If successful, then mmap
Expand Down Expand Up @@ -301,7 +329,11 @@ do_file(char const *const fname)
w2(ehdr->e_machine), fname);
fail_file();
break;
case EM_386: reltype = R_386_32; break;
case EM_386:
reltype = R_386_32;
make_nop = make_nop_x86;
ideal_nop = ideal_nop5_x86_32;
break;
case EM_ARM: reltype = R_ARM_ABS32;
altmcount = "__gnu_mcount_nc";
break;
Expand All @@ -312,7 +344,11 @@ do_file(char const *const fname)
case EM_S390: /* reltype: e_class */ gpfx = '_'; break;
case EM_SH: reltype = R_SH_DIR32; break;
case EM_SPARCV9: reltype = R_SPARC_64; gpfx = '_'; break;
case EM_X86_64: reltype = R_X86_64_64; break;
case EM_X86_64:
make_nop = make_nop_x86;
ideal_nop = ideal_nop5_x86_64;
reltype = R_X86_64_64;
break;
} /* end switch */

switch (ehdr->e_ident[EI_CLASS]) {
Expand Down
82 changes: 78 additions & 4 deletions trunk/scripts/recordmcount.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#undef fn_is_fake_mcount
#undef MIPS_is_fake_mcount
#undef sift_rel_mcount
#undef nop_mcount
#undef find_secsym_ndx
#undef __has_rel_mcount
#undef has_rel_mcount
Expand All @@ -49,6 +50,7 @@
#ifdef RECORD_MCOUNT_64
# define append_func append64
# define sift_rel_mcount sift64_rel_mcount
# define nop_mcount nop_mcount_64
# define find_secsym_ndx find64_secsym_ndx
# define __has_rel_mcount __has64_rel_mcount
# define has_rel_mcount has64_rel_mcount
Expand Down Expand Up @@ -77,6 +79,7 @@
#else
# define append_func append32
# define sift_rel_mcount sift32_rel_mcount
# define nop_mcount nop_mcount_32
# define find_secsym_ndx find32_secsym_ndx
# define __has_rel_mcount __has32_rel_mcount
# define has_rel_mcount has32_rel_mcount
Expand Down Expand Up @@ -304,6 +307,70 @@ static uint_t *sift_rel_mcount(uint_t *mlocp,
return mlocp;
}

/*
* Read the relocation table again, but this time its called on sections
* that are not going to be traced. The mcount calls here will be converted
* into nops.
*/
static void nop_mcount(Elf_Shdr const *const relhdr,
Elf_Ehdr const *const ehdr)
{
Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
+ (void *)ehdr);
unsigned const symsec_sh_link = w(relhdr->sh_link);
Elf_Shdr const *const symsec = &shdr0[symsec_sh_link];
Elf_Sym const *const sym0 = (Elf_Sym const *)(_w(symsec->sh_offset)
+ (void *)ehdr);

Elf_Shdr const *const strsec = &shdr0[w(symsec->sh_link)];
char const *const str0 = (char const *)(_w(strsec->sh_offset)
+ (void *)ehdr);

Elf_Rel const *const rel0 = (Elf_Rel const *)(_w(relhdr->sh_offset)
+ (void *)ehdr);
unsigned rel_entsize = _w(relhdr->sh_entsize);
unsigned const nrel = _w(relhdr->sh_size) / rel_entsize;
Elf_Rel const *relp = rel0;

Elf_Shdr const *const shdr = &shdr0[w(relhdr->sh_info)];

unsigned mcountsym = 0;
unsigned t;

for (t = nrel; t; --t) {
int ret = -1;

if (!mcountsym) {
Elf_Sym const *const symp =
&sym0[Elf_r_sym(relp)];
char const *symname = &str0[w(symp->st_name)];
char const *mcount = gpfx == '_' ? "_mcount" : "mcount";

if (symname[0] == '.')
++symname; /* ppc64 hack */
if (strcmp(mcount, symname) == 0 ||
(altmcount && strcmp(altmcount, symname) == 0))
mcountsym = Elf_r_sym(relp);
}

if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp))
ret = make_nop((void *)ehdr, shdr->sh_offset + relp->r_offset);

/*
* If we successfully removed the mcount, mark the relocation
* as a nop (don't do anything with it).
*/
if (!ret) {
Elf_Rel rel;
rel = *(Elf_Rel *)relp;
Elf_r_info(&rel, Elf_r_sym(relp), rel_type_nop);
ulseek(fd_map, (void *)relp - (void *)ehdr, SEEK_SET);
uwrite(fd_map, &rel, sizeof(rel));
}
relp = (Elf_Rel const *)(rel_entsize + (void *)relp);
}
}


/*
* Find a symbol in the given section, to be used as the base for relocating
Expand Down Expand Up @@ -360,8 +427,7 @@ __has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */
succeed_file();
}
if (w(txthdr->sh_type) != SHT_PROGBITS ||
!(w(txthdr->sh_flags) & SHF_EXECINSTR) ||
!is_mcounted_section_name(txtname))
!(w(txthdr->sh_flags) & SHF_EXECINSTR))
return NULL;
return txtname;
}
Expand All @@ -384,9 +450,11 @@ static unsigned tot_relsize(Elf_Shdr const *const shdr0,
{
unsigned totrelsz = 0;
Elf_Shdr const *shdrp = shdr0;
char const *txtname;

for (; nhdr; --nhdr, ++shdrp) {
if (has_rel_mcount(shdrp, shdr0, shstrtab, fname))
txtname = has_rel_mcount(shdrp, shdr0, shstrtab, fname);
if (txtname && is_mcounted_section_name(txtname))
totrelsz += _w(shdrp->sh_size);
}
return totrelsz;
Expand Down Expand Up @@ -422,7 +490,7 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype)
for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) {
char const *const txtname = has_rel_mcount(relhdr, shdr0,
shstrtab, fname);
if (txtname) {
if (txtname && is_mcounted_section_name(txtname)) {
uint_t recval = 0;
unsigned const recsym = find_secsym_ndx(
w(relhdr->sh_info), txtname, &recval,
Expand All @@ -433,6 +501,12 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype)
mlocp = sift_rel_mcount(mlocp,
(void *)mlocp - (void *)mloc0, &mrelp,
relhdr, ehdr, recsym, recval, reltype);
} else if (make_nop && txtname) {
/*
* This section is ignored by ftrace, but still
* has mcount calls. Convert them to nops now.
*/
nop_mcount(relhdr, ehdr);
}
}
if (mloc0 != mlocp) {
Expand Down

0 comments on commit cb20e97

Please sign in to comment.