Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6c5bd235 authored by Sam Ravnborg's avatar Sam Ravnborg
Browse files

kbuild: check section names consistently in modpost



Now that match() is introduced use it consistently so
we can share the section name definitions.

Signed-off-by: default avatarSam Ravnborg <sam@ravnborg.org>
parent 10668220
Loading
Loading
Loading
Loading
+60 −86
Original line number Original line Diff line number Diff line
@@ -625,6 +625,7 @@ static int number_prefix(const char *sym)


/* The pattern is an array of simple patterns.
/* The pattern is an array of simple patterns.
 * "foo" will match an exact string equal to "foo"
 * "foo" will match an exact string equal to "foo"
 * "*foo" will match a string that ends with "foo"
 * "foo*" will match a string that begins with "foo"
 * "foo*" will match a string that begins with "foo"
 * "foo$" will match a string equal to "foo" or "foo.1"
 * "foo$" will match a string equal to "foo" or "foo.1"
 *   where the '1' can be any number including several digits.
 *   where the '1' can be any number including several digits.
@@ -638,8 +639,13 @@ int match(const char *sym, const char * const pat[])
		p = *pat++;
		p = *pat++;
		const char *endp = p + strlen(p) - 1;
		const char *endp = p + strlen(p) - 1;


		/* "*foo" */
		if (*p == '*') {
			if (strrcmp(sym, p + 1) == 0)
				return 1;
		}
		/* "foo*" */
		/* "foo*" */
		if (*endp == '*') {
		else if (*endp == '*') {
			if (strncmp(sym, p, strlen(p) - 1) == 0)
			if (strncmp(sym, p, strlen(p) - 1) == 0)
				return 1;
				return 1;
		}
		}
@@ -660,54 +666,6 @@ int match(const char *sym, const char * const pat[])
	return 0;
	return 0;
}
}


/*
 * Functions used only during module init is marked __init and is stored in
 * a .init.text section. Likewise data is marked __initdata and stored in
 * a .init.data section.
 * If this section is one of these sections return 1
 * See include/linux/init.h for the details
 */
static int init_section(const char *name)
{
	if (strcmp(name, ".init") == 0)
		return 1;
	if (strncmp(name, ".init.", strlen(".init.")) == 0)
		return 1;
	return 0;
}

/*
 * Functions used only during module exit is marked __exit and is stored in
 * a .exit.text section. Likewise data is marked __exitdata and stored in
 * a .exit.data section.
 * If this section is one of these sections return 1
 * See include/linux/init.h for the details
 **/
static int exit_section(const char *name)
{
	if (strcmp(name, ".exit.text") == 0)
		return 1;
	if (strcmp(name, ".exit.data") == 0)
		return 1;
	return 0;

}

/*
 * Data sections are named like this:
 * .data | .data.rel | .data.rel.*
 * Return 1 if the specified section is a data section
 */
static int data_section(const char *name)
{
	if ((strcmp(name, ".data") == 0) ||
	    (strcmp(name, ".data.rel") == 0) ||
	    (strncmp(name, ".data.rel.", strlen(".data.rel.")) == 0))
		return 1;
	else
		return 0;
}

/* sections that we do not want to do full section mismatch check on */
/* sections that we do not want to do full section mismatch check on */
static const char *section_white_list[] =
static const char *section_white_list[] =
	{ ".debug*", ".stab*", ".note*", ".got*", ".toc*", NULL };
	{ ".debug*", ".stab*", ".note*", ".got*", ".toc*", NULL };
@@ -721,9 +679,50 @@ static const char *section_white_list[] =
#define INIT_SECTIONS INIT_DATA_SECTIONS, INIT_TEXT_SECTIONS
#define INIT_SECTIONS INIT_DATA_SECTIONS, INIT_TEXT_SECTIONS
#define EXIT_SECTIONS EXIT_DATA_SECTIONS, EXIT_TEXT_SECTIONS
#define EXIT_SECTIONS EXIT_DATA_SECTIONS, EXIT_TEXT_SECTIONS


#define DATA_SECTIONS ".data$"
#define DATA_SECTIONS ".data$", ".data.rel$"
#define TEXT_SECTIONS ".text$"
#define TEXT_SECTIONS ".text$"


/* init data sections */
static const char *init_data_sections[] = { INIT_DATA_SECTIONS, NULL };

/* all init sections */
static const char *init_sections[] = { INIT_SECTIONS, NULL };

/* All init and exit sections (code + data) */
static const char *init_exit_sections[] =
	{INIT_SECTIONS, EXIT_SECTIONS, NULL };

/* data section */
static const char *data_sections[] = { DATA_SECTIONS, NULL };

/* sections that may refer to an init/exit section with no warning */
static const char *initref_sections[] =
{
	".text.init.refok*",
	".exit.text.refok*",
	".data.init.refok*",
	NULL
};


/* symbols in .data that may refer to init/exit sections */
static const char *symbol_white_list[] =
{
	"*driver",
	"*_template", /* scsi uses *_template a lot */
	"*_timer",    /* arm uses ops structures named _timer a lot */
	"*_sht",      /* scsi also used *_sht to some extent */
	"*_ops",
	"*_probe",
	"*_probe_one",
	"*_console",
	NULL
};

static const char *head_sections[] = { ".head.text*", NULL };
static const char *linker_symbols[] =
	{ "__init_begin", "_sinittext", "_einittext", NULL };

struct sectioncheck {
struct sectioncheck {
	const char *fromsec[20];
	const char *fromsec[20];
	const char *tosec[20];
	const char *tosec[20];
@@ -817,54 +816,29 @@ static int secref_whitelist(const char *modname, const char *tosec,
			    const char *fromsec, const char *atsym,
			    const char *fromsec, const char *atsym,
			    const char *refsymname)
			    const char *refsymname)
{
{
	const char **s;
	const char *pat2sym[] = {
		"driver",
		"_template", /* scsi uses *_template a lot */
		"_timer",    /* arm uses ops structures named _timer a lot */
		"_sht",      /* scsi also used *_sht to some extent */
		"_ops",
		"_probe",
		"_probe_one",
		"_console",
		NULL
	};

	const char *pat3refsym[] = {
		"__init_begin",
		"_sinittext",
		"_einittext",
		NULL
	};

	/* Check for pattern 0 */
	/* Check for pattern 0 */
	if ((strncmp(fromsec, ".text.init.refok", strlen(".text.init.refok")) == 0) ||
	if (match(fromsec, initref_sections))
	    (strncmp(fromsec, ".exit.text.refok", strlen(".exit.text.refok")) == 0) ||
	    (strncmp(fromsec, ".data.init.refok", strlen(".data.init.refok")) == 0))
		return 1;
		return 1;


	/* Check for pattern 1 */
	/* Check for pattern 1 */
	if ((strcmp(tosec, ".init.data") == 0) &&
	if (match(tosec, init_data_sections) &&
	    (strncmp(fromsec, ".data", strlen(".data")) == 0) &&
	    match(fromsec, data_sections) &&
	    (strncmp(atsym, "__param", strlen("__param")) == 0))
	    (strncmp(atsym, "__param", strlen("__param")) == 0))
		return 1;
		return 1;


	/* Check for pattern 2 */
	/* Check for pattern 2 */
	if ((init_section(tosec) || exit_section(tosec))
	if (match(tosec, init_exit_sections) &&
	    && data_section(fromsec))
	    match(fromsec, data_sections) &&
		for (s = pat2sym; *s; s++)
	    match(atsym, symbol_white_list))
			if (strrcmp(atsym, *s) == 0)
		return 1;
		return 1;


	/* Check for pattern 3 */
	/* Check for pattern 3 */
	if ((strcmp(fromsec, ".text.head") == 0) &&
	if (match(fromsec, head_sections) &&
	    ((strcmp(tosec, ".init.data") == 0) ||
	    match(tosec, init_sections))
	    (strcmp(tosec, ".init.text") == 0)))
	return 1;
	return 1;


	/* Check for pattern 4 */
	/* Check for pattern 4 */
	for (s = pat3refsym; *s; s++)
	if (match(refsymname, linker_symbols))
		if (strcmp(refsymname, *s) == 0)
		return 1;
		return 1;


	return 0;
	return 0;