scripts/recordmcount.h

Source file repositories/reference/linux-study-clean/scripts/recordmcount.h

File Facts

System
Linux kernel
Corpus path
scripts/recordmcount.h
Extension
.h
Size
19832 bytes
Lines
698
Domain
Support Tooling And Documentation
Bucket
scripts
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

if (rel_entsize == sizeof(Elf_Rela)) {
				((Elf_Rela *)mrelp)->r_addend = addend;
				*mlocp++ = 0;
			} else
				*mlocp++ = addend;

			mrelp = (Elf_Rel *)(rel_entsize + (void *)mrelp);
		}
		relp = (Elf_Rel const *)(rel_entsize + (void *)relp);
	}
	*mrelpp = mrelp;
	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 int nop_mcount(Elf_Shdr const *const relhdr,
		      Elf_Ehdr const *const ehdr,
		      const char *const txtname)
{
	Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
		+ (void *)ehdr);
	Elf_Sym const *sym0;
	char const *str0;
	Elf_Rel const *relp;
	Elf_Shdr const *const shdr = &shdr0[w(relhdr->sh_info)];
	unsigned rel_entsize = _w(relhdr->sh_entsize);
	unsigned const nrel = _w(relhdr->sh_size) / rel_entsize;
	unsigned mcountsym = 0;
	unsigned t;
	int once = 0;

	get_sym_str_and_relp(relhdr, ehdr, &sym0, &str0, &relp);

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

		if (!mcountsym)
			mcountsym = get_mcountsym(sym0, relp, str0);

		if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) {
			if (make_nop)
				ret = make_nop((void *)ehdr, _w(shdr->sh_offset) + _w(relp->r_offset));
			if (warn_on_notrace_sect && !once) {
				printf("Section %s has mcount callers being ignored\n",
				       txtname);
				once = 1;
				/* just warn? */
				if (!make_nop)
					return 0;
			}
		}

		/*
		 * 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);
			if (ulseek((void *)relp - (void *)ehdr, SEEK_SET) < 0)
				return -1;
			if (uwrite(&rel, sizeof(rel)) < 0)
				return -1;
		}
		relp = (Elf_Rel const *)(rel_entsize + (void *)relp);
	}
	return 0;
}

/*
 * Find a symbol in the given section, to be used as the base for relocating
 * the table of offsets of calls to mcount.  A local or global symbol suffices,
 * but avoid a Weak symbol because it may be overridden; the change in value
 * would invalidate the relocations of the offsets of the calls to mcount.
 * Often the found symbol will be the unnamed local symbol generated by
 * GNU 'as' for the start of each section.  For example:
 *    Num:    Value  Size Type    Bind   Vis      Ndx Name
 *      2: 00000000     0 SECTION LOCAL  DEFAULT    1
 */
static int find_secsym_ndx(unsigned const txtndx,
				char const *const txtname,
				uint_t *const recvalp,
				unsigned int *sym_index,
				Elf_Shdr const *const symhdr,
				Elf32_Word const *symtab,

Annotation

Implementation Notes