/* Postprocess module symbol versions
 *
 * Copyright 2003       Kai Germaschewski
 * Copyright 2002-2004  Rusty Russell, IBM Corporation
 * Copyright 2006-2008  Sam Ravnborg
 * Based in part on module-init-tools/depmod.c,file2alias
 *
 * This software may be used and distributed according to the terms
 * of the GNU General Public License, incorporated herein by reference.
 *
 * Usage: modpost vmlinux module1.o module2.o ...
 */

#define _GNU_SOURCE
#include <elf.h>
#include <fnmatch.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <limits.h>
#include <stdbool.h>
#include <errno.h>

#include <hash.h>
#include <hashtable.h>
#include <list.h>
#include <xalloc.h>
#include "modpost.h"
#include "../../include/linux/license.h"

#define MODULE_NS_PREFIX "module:"

static bool module_enabled;
/* Are we using CONFIG_MODVERSIONS? */
static bool modversions;
/* Is CONFIG_MODULE_SRCVERSION_ALL set? */
static bool all_versions;
/* Is CONFIG_BASIC_MODVERSIONS set? */
static bool basic_modversions;
/* Is CONFIG_EXTENDED_MODVERSIONS set? */
static bool extended_modversions;
/* If we are modposting external module set to 1 */
static bool external_module;
/* Only warn about unresolved symbols */
static bool warn_unresolved;

static int sec_mismatch_count;
static bool sec_mismatch_warn_only = true;
/* Trim EXPORT_SYMBOLs that are unused by in-tree modules */
static bool trim_unused_exports;

/* ignore missing files */
static bool ignore_missing_files;
/* If set to 1, only warn (instead of error) about missing ns imports */
static bool allow_missing_ns_imports;

static bool error_occurred;

static bool extra_warn __attribute__((unused));

bool target_is_big_endian;
bool host_is_big_endian;

/*
 * Cut off the warnings when there are too many. This typically occurs when
 * vmlinux is missing. ('make modules' without building vmlinux.)
 */
#define MAX_UNRESOLVED_REPORTS	10
static unsigned int nr_unresolved;

/* In kernel, this size is defined in linux/module.h;
 * here we use Elf_Addr instead of long for covering cross-compile
 */

#define MODULE_NAME_LEN (64 - sizeof(Elf_Addr))

void modpost_log(bool is_error, const char *fmt, ...)
{
	va_list arglist;

	if (is_error) {
		fprintf(stderr, "ERROR: ");
		error_occurred = true;
	} else {
		fprintf(stderr, "WARNING: ");
	}

	fprintf(stderr, "modpost: ");

	va_start(arglist, fmt);
	vfprintf(stderr, fmt, arglist);
	va_end(arglist);
}

static inline bool strends(const char *str, const char *postfix)
{
	if (strlen(str) < strlen(postfix))
		return false;

	return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
}

/**
 * get_basename - return the last part of a pathname.
 *
 * @path: path to extract the filename from.
 */
const char *get_basename(const char *path)
{
	const char *tail = strrchr(path, '/');

	return tail ? tail + 1 : path;
}

char *read_text_file(const char *filename)
{
	struct stat st;
	size_t nbytes;
	int fd;
	char *buf;

	fd = open(filename, O_RDONLY);
	if (fd < 0) {
		perror(filename);
		exit(1);
	}

	if (fstat(fd, &st) < 0) {
		perror(filename);
		exit(1);
	}

	buf = xmalloc(st.st_size + 1);

	nbytes = st.st_size;

	while (nbytes) {
		ssize_t bytes_read;

		bytes_read = read(fd, buf, nbytes);
		if (bytes_read < 0) {
			perror(filename);
			exit(1);
		}

		nbytes -= bytes_read;
	}
	buf[st.st_size] = '\0';

	close(fd);

	return buf;
}

char *get_line(char **stringp)
{
	char *orig = *stringp, *next;

	/* do not return the unwanted extra line at EOF */
	if (!orig || *orig == '\0')
		return NULL;

	/* don't use strsep here, it is not available everywhere */
	next = strchr(orig, '\n');
	if (next)
		*next++ = '\0';

	*stringp = next;

	return orig;
}

/* A list of all modules we processed */
LIST_HEAD(modules);

static struct module *find_module(const char *filename, const char *modname)
{
	struct module *mod;

	list_for_each_entry(mod, &modules, list) {
		if (!strcmp(mod->dump_file, filename) &&
		    !strcmp(mod->name, modname))
			return mod;
	}
	return NULL;
}

static struct module *new_module(const char *name, size_t namelen)
{
	struct module *mod;

	mod = xmalloc(sizeof(*mod) + namelen + 1);
	memset(mod, 0, sizeof(*mod));

	INIT_LIST_HEAD(&mod->exported_symbols);
	INIT_LIST_HEAD(&mod->unresolved_symbols);
	INIT_LIST_HEAD(&mod->missing_namespaces);
	INIT_LIST_HEAD(&mod->imported_namespaces);
	INIT_LIST_HEAD(&mod->aliases);

	memcpy(mod->name, name, namelen);
	mod->name[namelen] = '\0';
	mod->is_vmlinux = (strcmp(mod->name, "vmlinux") == 0);

	/*
	 * Set mod->is_gpl_compatible to true by default. If MODULE_LICENSE()
	 * is missing, do not check the use for EXPORT_SYMBOL_GPL() because
	 * modpost will exit with an error anyway.
	 */
	mod->is_gpl_compatible = true;

	list_add_tail(&mod->list, &modules);

	return mod;
}

struct symbol {
	struct hlist_node hnode;/* link to hash table */
	struct list_head list;	/* link to module::exported_symbols or module::unresolved_symbols */
	struct module *module;
	char *namespace;
	unsigned int crc;
	bool crc_valid;
	bool weak;
	bool is_func;
	bool is_gpl_only;	/* exported by EXPORT_SYMBOL_GPL */
	bool used;		/* there exists a user of this symbol */
	char name[];
};

static HASHTABLE_DEFINE(symbol_hashtable, 1U << 10);

/**
 * Allocate a new symbols for use in the hash of exported symbols or
 * the list of unresolved symbols per module
 **/
static struct symbol *alloc_symbol(const char *name)
{
	struct symbol *s = xmalloc(sizeof(*s) + strlen(name) + 1);

	memset(s, 0, sizeof(*s));
	strcpy(s->name, name);

	return s;
}

static uint8_t get_symbol_flags(const struct symbol *sym)
{
	return sym->is_gpl_only ? KSYM_FLAG_GPL_ONLY : 0;
}

/* For the hash of exported symbols */
static void hash_add_symbol(struct symbol *sym)
{
	hash_add(symbol_hashtable, &sym->hnode, hash_str(sym->name));
}

static void sym_add_unresolved(const char *name, struct module *mod, bool weak)
{
	struct symbol *sym;

	sym = alloc_symbol(name);
	sym->weak = weak;

	list_add_tail(&sym->list, &mod->unresolved_symbols);
}

static struct symbol *sym_find_with_module(const char *name, struct module *mod)
{
	struct symbol *s;

	/* For our purposes, .foo matches foo.  PPC64 needs this. */
	if (name[0] == '.')
		name++;

	hash_for_each_possible(symbol_hashtable, s, hnode, hash_str(name)) {
		if (strcmp(s->name, name) == 0 && (!mod || s->module == mod))
			return s;
	}
	return NULL;
}

static struct symbol *find_symbol(const char *name)
{
	return sym_find_with_module(name, NULL);
}

struct namespace_list {
	struct list_head list;
	char namespace[];
};

static bool contains_namespace(struct list_head *head, const char *namespace)
{
	struct namespace_list *list;

	/*
	 * The default namespace is null string "", which is always implicitly
	 * contained.
	 */
	if (!namespace[0])
		return true;

	list_for_each_entry(list, head, list) {
		if (!strcmp(list->namespace, namespace))
			return true;
	}

	return false;
}

static void add_namespace(struct list_head *head, const char *namespace)
{
	struct namespace_list *ns_entry;

	if (!contains_namespace(head, namespace)) {
		ns_entry = xmalloc(sizeof(*ns_entry) + strlen(namespace) + 1);
		strcpy(ns_entry->namespace, namespace);
		list_add_tail(&ns_entry->list, head);
	}
}

static void *sym_get_data_by_offset(const struct elf_info *info,
				    unsigned int secindex, unsigned long offset)
{
	Elf_Shdr *sechdr = &info->sechdrs[secindex];

	return (void *)info->hdr + sechdr->sh_offset + offset;
}

void *sym_get_data(const struct elf_info *info, const Elf_Sym *sym)
{
	return sym_get_data_by_offset(info, get_secindex(info, sym),
				      sym->st_value);
}

static const char *sech_name(const struct elf_info *info, Elf_Shdr *sechdr)
{
	return sym_get_data_by_offset(info, info->secindex_strings,
				      sechdr->sh_name);
}

static const char *sec_name(const struct elf_info *info, unsigned int secindex)
{
	/*
	 * If sym->st_shndx is a special section index, there is no
	 * corresponding section header.
	 * Return "" if the index is out of range of info->sechdrs[] array.
	 */
	if (secindex >= info->num_sections)
		return "";

	return sech_name(info, &info->sechdrs[secindex]);
}

static struct symbol *sym_add_exported(const char *name, struct module *mod,
				       bool gpl_only, const char *namespace)
{
	struct symbol *s = find_symbol(name);

	if (s && (!external_module || s->module->is_vmlinux || s->module == mod)) {
		error("%s: '%s' exported twice. Previous export was in %s%s\n",
		      mod->name, name, s->module->name,
		      s->module->is_vmlinux ? "" : ".ko");
	}

	s = alloc_symbol(name);
	s->module = mod;
	s->is_gpl_only = gpl_only;
	s->namespace = xstrdup(namespace);
	list_add_tail(&s->list, &mod->exported_symbols);
	hash_add_symbol(s);

	return s;
}

static void sym_set_crc(struct symbol *sym, unsigned int crc)
{
	sym->crc = crc;
	sym->crc_valid = true;
}

static void *grab_file(const char *filename, size_t *size)
{
	struct stat st;
	void *map = MAP_FAILED;
	int fd;

	fd = open(filename, O_RDONLY);
	if (fd < 0)
		return NULL;
	if (fstat(fd, &st))
		goto failed;

	*size = st.st_size;
	map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);

failed:
	close(fd);
	if (map == MAP_FAILED)
		return NULL;
	return map;
}

static void release_file(void *file, size_t size)
{
	munmap(file, size);
}

static int parse_elf(struct elf_info *info, const char *filename)
{
	unsigned int i;
	Elf_Ehdr *hdr;
	Elf_Shdr *sechdrs;
	Elf_Sym  *sym;
	const char *secstrings;
	unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U;

	hdr = grab_file(filename, &info->size);
	if (!hdr) {
		if (ignore_missing_files) {
			fprintf(stderr, "%s: %s (ignored)\n", filename,
				strerror(errno));
			return 0;
		}
		perror(filename);
		exit(1);
	}
	info->hdr = hdr;
	if (info->size < sizeof(*hdr)) {
		/* file too small, assume this is an empty .o file */
		return 0;
	}
	/* Is this a valid ELF file? */
	if ((hdr->e_ident[EI_MAG0] != ELFMAG0) ||
	    (hdr->e_ident[EI_MAG1] != ELFMAG1) ||
	    (hdr->e_ident[EI_MAG2] != ELFMAG2) ||
	    (hdr->e_ident[EI_MAG3] != ELFMAG3)) {
		/* Not an ELF file - silently ignore it */
		return 0;
	}

	switch (hdr->e_ident[EI_DATA]) {
	case ELFDATA2LSB:
		target_is_big_endian = false;
		break;
	case ELFDATA2MSB:
		target_is_big_endian = true;
		break;
	default:
		fatal("target endian is unknown\n");
	}

	/* Fix endianness in ELF header */
	hdr->e_type      = TO_NATIVE(hdr->e_type);
	hdr->e_machine   = TO_NATIVE(hdr->e_machine);
	hdr->e_version   = TO_NATIVE(hdr->e_version);
	hdr->e_entry     = TO_NATIVE(hdr->e_entry);
	hdr->e_phoff     = TO_NATIVE(hdr->e_phoff);
	hdr->e_shoff     = TO_NATIVE(hdr->e_shoff);
	hdr->e_flags     = TO_NATIVE(hdr->e_flags);
	hdr->e_ehsize    = TO_NATIVE(hdr->e_ehsize);
	hdr->e_phentsize = TO_NATIVE(hdr->e_phentsize);
	hdr->e_phnum     = TO_NATIVE(hdr->e_phnum);
	hdr->e_shentsize = TO_NATIVE(hdr->e_shentsize);
	hdr->e_shnum     = TO_NATIVE(hdr->e_shnum);
	hdr->e_shstrndx  = TO_NATIVE(hdr->e_shstrndx);
	sechdrs = (void *)hdr + hdr->e_shoff;
	info->sechdrs = sechdrs;

	/* modpost only works for relocatable objects */
	if (hdr->e_type != ET_REL)
		fatal("%s: not relocatable object.", filename);

	/* Check if file offset is correct */
	if (hdr->e_shoff > info->size)
		fatal("section header offset=%lu in file '%s' is bigger than filesize=%zu\n",
		      (unsigned long)hdr->e_shoff, filename, info->size);

	if (hdr->e_shnum == SHN_UNDEF) {
		/*
		 * There are more than 64k sections,
		 * read count from .sh_size.
		 */
		info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
	}
	else {
		info->num_sections = hdr->e_shnum;
	}
	if (hdr->e_shstrndx == SHN_XINDEX) {
		info->secindex_strings = TO_NATIVE(sechdrs[0].sh_link);
	}
	else {
		info->secindex_strings = hdr->e_shstrndx;
	}

	/* Fix endianness in section headers */
	for (i = 0; i < info->num_sections; i++) {
		sechdrs[i].sh_name      = TO_NATIVE(sechdrs[i].sh_name);
		sechdrs[i].sh_type      = TO_NATIVE(sechdrs[i].sh_type);
		sechdrs[i].sh_flags     = TO_NATIVE(sechdrs[i].sh_flags);
		sechdrs[i].sh_addr      = TO_NATIVE(sechdrs[i].sh_addr);
		sechdrs[i].sh_offset    = TO_NATIVE(sechdrs[i].sh_offset);
		sechdrs[i].sh_size      = TO_NATIVE(sechdrs[i].sh_size);
		sechdrs[i].sh_link      = TO_NATIVE(sechdrs[i].sh_link);
		sechdrs[i].sh_info      = TO_NATIVE(sechdrs[i].sh_info);
		sechdrs[i].sh_addralign = TO_NATIVE(sechdrs[i].sh_addralign);
		sechdrs[i].sh_entsize   = TO_NATIVE(sechdrs[i].sh_entsize);
	}
	/* Find symbol table. */
	secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
	for (i = 1; i < info->num_sections; i++) {
		const char *secname;
		int nobits = sechdrs[i].sh_type == SHT_NOBITS;

		if (!nobits && sechdrs[i].sh_offset > info->size)
			fatal("%s is truncated. sechdrs[i].sh_offset=%lu > sizeof(*hrd)=%zu\n",
			      filename, (unsigned long)sechdrs[i].sh_offset,
			      sizeof(*hdr));

		secname = secstrings + sechdrs[i].sh_name;
		if (strcmp(secname, ".modinfo") == 0) {
			if (nobits)
				fatal("%s has NOBITS .modinfo\n", filename);
			info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
			info->modinfo_len = sechdrs[i].sh_size;
		} else if (!strcmp(secname, ".export_symbol")) {
			info->export_symbol_secndx = i;
		} else if (!strcmp(secname, ".no_trim_symbol")) {
			info->no_trim_symbol = (void *)hdr + sechdrs[i].sh_offset;
			info->no_trim_symbol_len = sechdrs[i].sh_size;
		}

		if (sechdrs[i].sh_type == SHT_SYMTAB) {
			unsigned int sh_link_idx;
			symtab_idx = i;
			info->symtab_start = (void *)hdr +
			    sechdrs[i].sh_offset;
			info->symtab_stop  = (void *)hdr +
			    sechdrs[i].sh_offset + sechdrs[i].sh_size;
			sh_link_idx = sechdrs[i].sh_link;
			info->strtab       = (void *)hdr +
			    sechdrs[sh_link_idx].sh_offset;
		}

		/* 32bit section no. table? ("more than 64k sections") */
		if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) {
			symtab_shndx_idx = i;
			info->symtab_shndx_start = (void *)hdr +
			    sechdrs[i].sh_offset;
			info->symtab_shndx_stop  = (void *)hdr +
			    sechdrs[i].sh_offset + sechdrs[i].sh_size;
		}
	}
	if (!info->symtab_start)
		fatal("%s has no symtab?\n", filename);

	/* Fix endianness in symbols */
	for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
		sym->st_shndx = TO_NATIVE(sym->st_shndx);
		sym->st_name  = TO_NATIVE(sym->st_name);
		sym->st_value = TO_NATIVE(sym->st_value);
		sym->st_size  = TO_NATIVE(sym->st_size);
	}

	if (symtab_shndx_idx != ~0U) {
		Elf32_Word *p;
		if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link)
			fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
			      filename, sechdrs[symtab_shndx_idx].sh_link,
			      symtab_idx);
		/* Fix endianness */
		for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
		     p++)
			*p = TO_NATIVE(*p);
	}

	symsearch_init(info);

	return 1;
}

static void parse_elf_finish(struct elf_info *info)
{
	symsearch_finish(info);
	release_file(info->hdr, info->size);
}

static int ignore_undef_symbol(struct elf_info *info, const char *symname)
{
	/* ignore __this_module, it will be resolved shortly */
	if (strcmp(symname, "__this_module") == 0)
		return 1;
	/* ignore global offset table */
	if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
		return 1;
	if (info->hdr->e_machine == EM_PPC)
		/* Special register function linked on all modules during final link of .ko */
		if (strstarts(symname, "_restgpr_") ||
		    strstarts(symname, "_savegpr_") ||
		    strstarts(symname, "_rest32gpr_") ||
		    strstarts(symname, "_save32gpr_") ||
		    strstarts(symname, "_restvr_") ||
		    strstarts(symname, "_savevr_"))
			return 1;
	if (info->hdr->e_machine == EM_PPC64)
		/* Special register function linked on all modules during final link of .ko */
		if (strstarts(symname, "_restgpr0_") ||
		    strstarts(symname, "_savegpr0_") ||
		    strstarts(symname, "_restgpr1_") ||
		    strstarts(symname, "_savegpr1_") ||
		    strstarts(symname, "_restfpr_") ||
		    strstarts(symname, "_savefpr_") ||
		    strstarts(symname, "_restvr_") ||
		    strstarts(symname, "_savevr_") ||
		    strcmp(symname, ".TOC.") == 0)
			return 1;

	/* ignore linker-created section bounds variables */
	if (strstarts(symname, "__start_") || strstarts(symname, "__stop_"))
		return 1;

	/* Do not ignore this symbol */
	return 0;
}

static void handle_symbol(struct module *mod, struct elf_info *info,
			  const Elf_Sym *sym, const char *symname)
{
	switch (sym->st_shndx) {
	case SHN_COMMON:
		if (strstarts(symname, "__gnu_lto_")) {
			/* Should warn here, but modpost runs before the linker */
		} else
			warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
		break;
	case SHN_UNDEF:
		/* undefined symbol */
		if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
		    ELF_ST_BIND(sym->st_info) != STB_WEAK)
			break;
		if (ignore_undef_symbol(info, symname))
			break;
		if (info->hdr->e_machine == EM_SPARC ||
		    info->hdr->e_machine == EM_SPARCV9) {
			/* Ignore register directives. */
			if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
				break;
			if (symname[0] == '.') {
				char *munged = xstrdup(symname);
				munged[0] = '_';
				munged[1] = toupper(munged[1]);
				symname = munged;
			}
		}

		sym_add_unresolved(symname, mod,
				   ELF_ST_BIND(sym->st_info) == STB_WEAK);
		break;
	default:
		if (strcmp(symname, "init_module") == 0)
			mod->has_init = true;
		if (strcmp(symname, "cleanup_module") == 0)
			mod->has_cleanup = true;
		break;
	}
}

/**
 * Parse tag=value strings from .modinfo section
 **/
static char *next_string(char *string, unsigned long *secsize)
{
	/* Skip non-zero chars */
	while (string[0]) {
		string++;
		if ((*secsize)-- <= 1)
			return NULL;
	}

	/* Skip any zero padding. */
	while (!string[0]) {
		string++;
		if ((*secsize)-- <= 1)
			return NULL;
	}
	return string;
}

static char *get_next_modinfo(struct elf_info *info, const char *tag,
			      char *prev)
{
	char *p;
	unsigned int taglen = strlen(tag);
	char *modinfo = info->modinfo;
	unsigned long size = info->modinfo_len;

	if (prev) {
		size -= prev - modinfo;
		modinfo = next_string(prev, &size);
	}

	for (p = modinfo; p; p = next_string(p, &size)) {
		if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
			return p + taglen + 1;
	}
	return NULL;
}

static char *get_modinfo(struct elf_info *info, const char *tag)

{
	return get_next_modinfo(info, tag, NULL);
}

static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
{
	return sym ? elf->strtab + sym->st_name : "";
}

/*
 * Check whether the 'string' argument matches one of the 'patterns',
 * an array of shell wildcard patterns (glob).
 *
 * Return true is there is a match.
 */
static bool match(const char *string, const char *const patterns[])
{
	const char *pattern;

	while ((pattern = *patterns++)) {
		if (!fnmatch(pattern, string, 0))
			return true;
	}

	return false;
}

/* useful to pass patterns to match() directly */
#define PATTERNS(...) \
	({ \
		static const char *const patterns[] = {__VA_ARGS__, NULL}; \
		patterns; \
	})

/* sections that we do not want to do full section mismatch check on */
static const char *const section_white_list[] =
{
	".comment*",
	".debug*",
	".zdebug*",		/* Compressed debug sections. */
	".GCC.command.line",	/* record-gcc-switches */
	".mdebug*",        /* alpha, score, mips etc. */
	".pdr",            /* alpha, score, mips etc. */
	".stab*",
	".note*",
	".got*",
	".toc*",
	".xt.prop",				 /* xtensa */
	".xt.lit",         /* xtensa */
	".arcextmap*",			/* arc */
	".gnu.linkonce.arcext*",	/* arc : modules */
	".cmem*",			/* EZchip */
	".fmt_slot*",			/* EZchip */
	".gnu.lto*",
	".discard.*",
	".llvm.call-graph-profile",	/* call graph */
	"__llvm_covfun",
	"__llvm_covmap",
	NULL
};

/*
 * This is used to find sections missing the SHF_ALLOC flag.
 * The cause of this is often a section specified in assembler
 * without "ax" / "aw".
 */
static void check_section(const char *modname, struct elf_info *elf,
			  Elf_Shdr *sechdr)
{
	const char *sec = sech_name(elf, sechdr);

	if (sechdr->sh_type == SHT_PROGBITS &&
	    !(sechdr->sh_flags & SHF_ALLOC) &&
	    !match(sec, section_white_list)) {
		warn("%s (%s): unexpected non-allocatable section.\n"
		     "Did you forget to use \"ax\"/\"aw\" in a .S file?\n"
		     "Note that for example <linux/init.h> contains\n"
		     "section definitions for use in .S files.\n\n",
		     modname, sec);
	}
}



#define ALL_INIT_DATA_SECTIONS \
	".init.setup", ".init.rodata", ".init.data"

#define ALL_PCI_INIT_SECTIONS	\
	".pci_fixup_early", ".pci_fixup_header", ".pci_fixup_final", \
	".pci_fixup_enable", ".pci_fixup_resume", \
	".pci_fixup_resume_early", ".pci_fixup_suspend"

#define ALL_INIT_SECTIONS ".init.*"
#define ALL_EXIT_SECTIONS ".exit.*"

#define DATA_SECTIONS ".data", ".data.rel"
#define TEXT_SECTIONS ".text", ".text.*", ".sched.text", \
		".kprobes.text", ".cpuidle.text", ".noinstr.text", \
		".ltext", ".ltext.*"
#define OTHER_TEXT_SECTIONS ".ref.text", ".head.text", ".spinlock.text", \
		".fixup", ".entry.text", ".exception.text", \
		".coldtext", ".softirqentry.text", ".irqentry.text"

#define ALL_TEXT_SECTIONS  ".init.text", ".exit.text", \
		TEXT_SECTIONS, OTHER_TEXT_SECTIONS

enum mismatch {
	TEXTDATA_TO_ANY_INIT_EXIT,
	XXXINIT_TO_SOME_INIT,
	ANY_INIT_TO_ANY_EXIT,
	ANY_EXIT_TO_ANY_INIT,
	EXTABLE_TO_NON_TEXT,
};

/**
 * Describe how to match sections on different criteria:
 *
 * @fromsec: Array of sections to be matched.
 *
 * @bad_tosec: Relocations applied to a section in @fromsec to a section in
 * this array is forbidden (black-list).  Can be empty.
 *
 * @good_tosec: Relocations applied to a section in @fromsec must be
 * targeting sections in this array (white-list).  Can be empty.
 *
 * @mismatch: Type of mismatch.
 */
struct sectioncheck {
	const char *fromsec[20];
	const char *bad_tosec[20];
	const char *good_tosec[20];
	enum mismatch mismatch;
};

static const struct sectioncheck sectioncheck[] = {
/* Do not reference init/exit code/data from
 * normal code and data
 */
{
	.fromsec = { TEXT_SECTIONS, DATA_SECTIONS, NULL },
	.bad_tosec = { ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS, NULL },
	.mismatch = TEXTDATA_TO_ANY_INIT_EXIT,
},
/* Do not use exit code/data from init code */
{
	.fromsec = { ALL_INIT_SECTIONS, NULL },
	.bad_tosec = { ALL_EXIT_SECTIONS, NULL },
	.mismatch = ANY_INIT_TO_ANY_EXIT,
},
/* Do not use init code/data from exit code */
{
	.fromsec = { ALL_EXIT_SECTIONS, NULL },
	.bad_tosec = { ALL_INIT_SECTIONS, NULL },
	.mismatch = ANY_EXIT_TO_ANY_INIT,
},
{
	.fromsec = { ALL_PCI_INIT_SECTIONS, NULL },
	.bad_tosec = { ALL_INIT_SECTIONS, NULL },
	.mismatch = ANY_INIT_TO_ANY_EXIT,
},
{
	.fromsec = { "__ex_table", NULL },
	/* If you're adding any new black-listed sections in here, consider
	 * adding a special 'printer' for them in scripts/check_extable.
	 */
	.bad_tosec = { ".altinstr_replacement", NULL },
	.good_tosec = {ALL_TEXT_SECTIONS , NULL},
	.mismatch = EXTABLE_TO_NON_TEXT,
}
};

static const struct sectioncheck *section_mismatch(
		const char *fromsec, const char *tosec)
{
	int i;

	/*
	 * The target section could be the SHT_NUL section when we're
	 * handling relocations to un-resolved symbols, trying to match it
	 * doesn't make much sense and causes build failures on parisc
	 * architectures.
	 */
	if (*tosec == '\0')
		return NULL;

	for (i = 0; i < ARRAY_SIZE(sectioncheck); i++) {
		const struct sectioncheck *check = &sectioncheck[i];

		if (match(fromsec, check->fromsec)) {
			if (check->bad_tosec[0] && match(tosec, check->bad_tosec))
				return check;
			if (check->good_tosec[0] && !match(tosec, check->good_tosec))
				return check;
		}
	}
	return NULL;
}

/**
 * Whitelist to allow certain references to pass with no warning.
 *
 * Pattern 1:
 *   If a module parameter is declared __initdata and permissions=0
 *   then this is legal despite the warning generated.
 *   We cannot see value of permissions here, so just ignore
 *   this pattern.
 *   The pattern is identified by:
 *   tosec   = .init.data
 *   fromsec = .data*
 *   atsym   =__param*
 *
 * Pattern 1a:
 *   module_param_call() ops can refer to __init set function if permissions=0
 *   The pattern is identified by:
 *   tosec   = .init.text
 *   fromsec = .data*
 *   atsym   = __param_ops_*
 *
 * Pattern 3:
 *   Whitelist all references from .head.text to any init section
 *
 * Pattern 4:
 *   Some symbols belong to init section but still it is ok to reference
 *   these from non-init sections as these symbols don't have any memory
 *   allocated for them and symbol address and value are same. So even
 *   if init section is freed, its ok to reference those symbols.
 *   For ex. symbols marking the init section boundaries.
 *   This pattern is identified by
 *   refsymname = __init_begin, _sinittext, _einittext
 *
 * Pattern 5:
 *   GCC may optimize static inlines when fed constant arg(s) resulting
 *   in functions like cpumask_empty() -- generating an associated symbol
 *   cpumask_empty.constprop.3 that appears in the audit.  If the const that
 *   is passed in comes from __init, like say nmi_ipi_mask, we get a
 *   meaningless section warning.  May need to add isra symbols too...
 *   This pattern is identified by
 *   tosec   = init section
 *   fromsec = text section
 *   refsymname = *.constprop.*
 *
 **/
static int secref_whitelist(const char *fromsec, const char *fromsym,
			    const char *tosec, const char *tosym)
{
	/* Check for pattern 1 */
	if (match(tosec, PATTERNS(ALL_INIT_DATA_SECTIONS)) &&
	    match(fromsec, PATTERNS(DATA_SECTIONS)) &&
	    strstarts(fromsym, "__param"))
		return 0;

	/* Check for pattern 1a */
	if (strcmp(tosec, ".init.text") == 0 &&
	    match(fromsec, PATTERNS(DATA_SECTIONS)) &&
	    strstarts(fromsym, "__param_ops_"))
		return 0;

	/* symbols in data sections that may refer to any init/exit sections */
	if (match(fromsec, PATTERNS(DATA_SECTIONS)) &&
	    match(tosec, PATTERNS(ALL_INIT_SECTIONS, ALL_EXIT_SECTIONS)) &&
	    match(fromsym, PATTERNS("*_ops", "*_ops.llvm.*", "*_console")))
		return 0;

	/* Check for pattern 3 */
	if (strstarts(fromsec, ".head.text") &&
	    match(tosec, PATTERNS(ALL_INIT_SECTIONS)))
		return 0;

	/* Check for pattern 4 */
	if (match(tosym, PATTERNS("__init_begin", "_sinittext", "_einittext")))
		return 0;

	/* Check for pattern 5 */
	if (match(fromsec, PATTERNS(ALL_TEXT_SECTIONS)) &&
	    match(tosec, PATTERNS(ALL_INIT_SECTIONS)) &&
	    match(fromsym, PATTERNS("*.constprop.*")))
		return 0;

	return 1;
}

static Elf_Sym *find_fromsym(struct elf_info *elf, Elf_Addr addr,
			     unsigned int secndx)
{
	return symsearch_find_nearest(elf, addr, secndx, false, ~0);
}

static Elf_Sym *find_tosym(struct elf_info *elf, Elf_Addr addr, Elf_Sym *sym)
{
	Elf_Sym *new_sym;

	/* If the supplied symbol has a valid name, return it */
	if (is_valid_name(elf, sym))
		return sym;

	/*
	 * Strive to find a better symbol name, but the resulting name may not
	 * match the symbol referenced in the original code.
	 */
	new_sym = symsearch_find_nearest(elf, addr, get_secindex(elf, sym),
					 true, 20);
	return new_sym ? new_sym : sym;
}

static bool is_executable_section(struct elf_info *elf, unsigned int secndx)
{
	if (secndx >= elf->num_sections)
		return false;

	return (elf->sechdrs[secndx].sh_flags & SHF_EXECINSTR) != 0;
}

static void default_mismatch_handler(const char *modname, struct elf_info *elf,
				     const struct sectioncheck* const mismatch,
				     Elf_Sym *tsym,
				     unsigned int fsecndx, const char *fromsec, Elf_Addr faddr,
				     const char *tosec, Elf_Addr taddr)
{
	Elf_Sym *from;
	const char *tosym;
	const char *fromsym;
	char taddr_str[16];

	from = find_fromsym(elf, faddr, fsecndx);
	fromsym = sym_name(elf, from);

	tsym = find_tosym(elf, taddr, tsym);
	tosym = sym_name(elf, tsym);

	/* check whitelist - we may ignore it */
	if (!secref_whitelist(fromsec, fromsym, tosec, tosym))
		return;

	sec_mismatch_count++;

	if (!tosym[0])
		snprintf(taddr_str, sizeof(taddr_str), "0x%x", (unsigned int)taddr);

	/*
	 * The format for the reference source:      <symbol_name>+<offset> or <address>
	 * The format for the reference destination: <symbol_name>          or <address>
	 */
	warn("%s: section mismatch in reference: %s%s0x%x (section: %s) -> %s (section: %s)\n",
	     modname, fromsym, fromsym[0] ? "+" : "",
	     (unsigned int)(faddr - (fromsym[0] ? from->st_value : 0)),
	     fromsec, tosym[0] ? tosym : taddr_str, tosec);

	if (mismatch->mismatch == EXTABLE_TO_NON_TEXT) {
		if (match(tosec, mismatch->bad_tosec))
			fatal("The relocation at %s+0x%lx references\n"
			      "section \"%s\" which is black-listed.\n"
			      "Something is seriously wrong and should be fixed.\n"
			      "You might get more information about where this is\n"
			      "coming from by using scripts/check_extable.sh %s\n",
			      fromsec, (long)faddr, tosec, modname);
		else if (is_executable_section(elf, get_secindex(elf, tsym)))
			warn("The relocation at %s+0x%lx references\n"
			     "section \"%s\" which is not in the list of\n"
			     "authorized sections.  If you're adding a new section\n"
			     "and/or if this reference is valid, add \"%s\" to the\n"
			     "list of authorized sections to jump to on fault.\n"
			     "This can be achieved by adding \"%s\" to\n"
			     "OTHER_TEXT_SECTIONS in scripts/mod/modpost.c.\n",
			     fromsec, (long)faddr, tosec, tosec, tosec);
		else
			error("%s+0x%lx references non-executable section '%s'\n",
			      fromsec, (long)faddr, tosec);
	}
}

static void check_export_symbol(struct module *mod, struct elf_info *elf,
				Elf_Addr faddr, const char *secname,
				Elf_Sym *sym)
{
	static const char *prefix = "__export_symbol_";
	const char *label_name, *name, *data;
	Elf_Sym *label;
	struct symbol *s;
	bool is_gpl;

	label = find_fromsym(elf, faddr, elf->export_symbol_secndx);
	label_name = sym_name(elf, label);

	if (!strstarts(label_name, prefix)) {
		error("%s: .export_symbol section contains strange symbol '%s'\n",
		      mod->name, label_name);
		return;
	}

	if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
	    ELF_ST_BIND(sym->st_info) != STB_WEAK) {
		error("%s: local symbol '%s' was exported\n", mod->name,
		      label_name + strlen(prefix));
		return;
	}

	name = sym_name(elf, sym);
	if (strcmp(label_name + strlen(prefix), name)) {
		error("%s: .export_symbol section references '%s', but it does not seem to be an export symbol\n",
		      mod->name, name);
		return;
	}

	data = sym_get_data(elf, label);	/* license */
	if (!strcmp(data, "GPL")) {
		is_gpl = true;
	} else if (!strcmp(data, "")) {
		is_gpl = false;
	} else {
		error("%s: unknown license '%s' was specified for '%s'\n",
		      mod->name, data, name);
		return;
	}

	data += strlen(data) + 1;	/* namespace */
	s = sym_add_exported(name, mod, is_gpl, data);

	/*
	 * We need to be aware whether we are exporting a function or
	 * a data on some architectures.
	 */
	s->is_func = (ELF_ST_TYPE(sym->st_info) == STT_FUNC);

	/*
	 * For parisc64, symbols prefixed $$ from the library have the symbol type
	 * STT_LOPROC. They should be handled as functions too.
	 */
	if (elf->hdr->e_ident[EI_CLASS] == ELFCLASS64 &&
	    elf->hdr->e_machine == EM_PARISC &&
	    ELF_ST_TYPE(sym->st_info) == STT_LOPROC)
		s->is_func = true;

	if (match(secname, PATTERNS(ALL_INIT_SECTIONS)))
		warn("%s: %s: EXPORT_SYMBOL used for init symbol. Remove __init or EXPORT_SYMBOL.\n",
		     mod->name, name);
	else if (match(secname, PATTERNS(ALL_EXIT_SECTIONS)))
		warn("%s: %s: EXPORT_SYMBOL used for exit symbol. Remove __exit or EXPORT_SYMBOL.\n",
		     mod->name, name);
}

static void check_section_mismatch(struct module *mod, struct elf_info *elf,
				   Elf_Sym *sym,
				   unsigned int fsecndx, const char *fromsec,
				   Elf_Addr faddr, Elf_Addr taddr)
{
	const char *tosec = sec_name(elf, get_secindex(elf, sym));
	const struct sectioncheck *mismatch;

	if (module_enabled && elf->export_symbol_secndx == fsecndx) {
		check_export_symbol(mod, elf, faddr, tosec, sym);
		return;
	}

	mismatch = section_mismatch(fromsec, tosec);
	if (!mismatch)
		return;

	default_mismatch_handler(mod->name, elf, mismatch, sym,
				 fsecndx, fromsec, faddr,
				 tosec, taddr);
}

static Elf_Addr addend_386_rel(uint32_t *location, unsigned int r_type)
{
	switch (r_type) {
	case R_386_32:
		return get_unaligned_native(location);
	case R_386_PC32:
		return get_unaligned_native(location) + 4;
	}

	return (Elf_Addr)(-1);
}

static int32_t sign_extend32(int32_t value, int index)
{
	uint8_t shift = 31 - index;

	return (int32_t)(value << shift) >> shift;
}

static Elf_Addr addend_arm_rel(void *loc, Elf_Sym *sym, unsigned int r_type)
{
	uint32_t inst, upper, lower, sign, j1, j2;
	int32_t offset;

	switch (r_type) {
	case R_ARM_ABS32:
	case R_ARM_REL32:
		inst = get_unaligned_native((uint32_t *)loc);
		return inst + sym->st_value;
	case R_ARM_MOVW_ABS_NC:
	case R_ARM_MOVT_ABS:
		inst = get_unaligned_native((uint32_t *)loc);
		offset = sign_extend32(((inst & 0xf0000) >> 4) | (inst & 0xfff),
				       15);
		return offset + sym->st_value;
	case R_ARM_PC24:
	case R_ARM_CALL:
	case R_ARM_JUMP24:
		inst = get_unaligned_native((uint32_t *)loc);
		offset = sign_extend32((inst & 0x00ffffff) << 2, 25);
		return offset + sym->st_value + 8;
	case R_ARM_THM_MOVW_ABS_NC:
	case R_ARM_THM_MOVT_ABS:
		upper = get_unaligned_native((uint16_t *)loc);
		lower = get_unaligned_native((uint16_t *)loc + 1);
		offset = sign_extend32(((upper & 0x000f) << 12) |
				       ((upper & 0x0400) << 1) |
				       ((lower & 0x7000) >> 4) |
				       (lower & 0x00ff),
				       15);
		return offset + sym->st_value;
	case R_ARM_THM_JUMP19:
		/*
		 * Encoding T3:
		 * S     = upper[10]
		 * imm6  = upper[5:0]
		 * J1    = lower[13]
		 * J2    = lower[11]
		 * imm11 = lower[10:0]
		 * imm32 = SignExtend(S:J2:J1:imm6:imm11:'0')
		 */
		upper = get_unaligned_native((uint16_t *)loc);
		lower = get_unaligned_native((uint16_t *)loc + 1);

		sign = (upper >> 10) & 1;
		j1 = (lower >> 13) & 1;
		j2 = (lower >> 11) & 1;
		offset = sign_extend32((sign << 20) | (j2 << 19) | (j1 << 18) |
				       ((upper & 0x03f) << 12) |
				       ((lower & 0x07ff) << 1),
				       20);
		return offset + sym->st_value + 4;
	case R_ARM_THM_PC22:
	case R_ARM_THM_JUMP24:
		/*
		 * Encoding T4:
		 * S     = upper[10]
		 * imm10 = upper[9:0]
		 * J1    = lower[13]
		 * J2    = lower[11]
		 * imm11 = lower[10:0]
		 * I1    = NOT(J1 XOR S)
		 * I2    = NOT(J2 XOR S)
		 * imm32 = SignExtend(S:I1:I2:imm10:imm11:'0')
		 */
		upper = get_unaligned_native((uint16_t *)loc);
		lower = get_unaligned_native((uint16_t *)loc + 1);

		sign = (upper >> 10) & 1;
		j1 = (lower >> 13) & 1;
		j2 = (lower >> 11) & 1;
		offset = sign_extend32((sign << 24) |
				       ((~(j1 ^ sign) & 1) << 23) |
				       ((~(j2 ^ sign) & 1) << 22) |
				       ((upper & 0x03ff) << 12) |
				       ((lower & 0x07ff) << 1),
				       24);
		return offset + sym->st_value + 4;
	}

	return (Elf_Addr)(-1);
}

static Elf_Addr addend_mips_rel(uint32_t *location, unsigned int r_type)
{
	uint32_t inst;

	inst = get_unaligned_native(location);
	switch (r_type) {
	case R_MIPS_LO16:
		return inst & 0xffff;
	case R_MIPS_26:
		return (inst & 0x03ffffff) << 2;
	case R_MIPS_32:
		return inst;
	}
	return (Elf_Addr)(-1);
}

#ifndef EM_RISCV
#define EM_RISCV		243
#endif

#ifndef R_RISCV_SUB32
#define R_RISCV_SUB32		39
#endif

#ifndef EM_LOONGARCH
#define EM_LOONGARCH		258
#endif

#ifndef R_LARCH_SUB32
#define R_LARCH_SUB32		55
#endif

#ifndef R_LARCH_RELAX
#define R_LARCH_RELAX		100
#endif

#ifndef R_LARCH_ALIGN
#define R_LARCH_ALIGN		102
#endif

static void get_rel_type_and_sym(struct elf_info *elf, uint64_t r_info,
				 unsigned int *r_type, unsigned int *r_sym)
{
	typedef struct {
		Elf64_Word    r_sym;	/* Symbol index */
		unsigned char r_ssym;	/* Special symbol for 2nd relocation */
		unsigned char r_type3;	/* 3rd relocation type */
		unsigned char r_type2;	/* 2nd relocation type */
		unsigned char r_type;	/* 1st relocation type */
	} Elf64_Mips_R_Info;

	bool is_64bit = (elf->hdr->e_ident[EI_CLASS] == ELFCLASS64);

	if (elf->hdr->e_machine == EM_MIPS && is_64bit) {
		Elf64_Mips_R_Info *mips64_r_info = (void *)&r_info;

		*r_type = mips64_r_info->r_type;
		*r_sym = TO_NATIVE(mips64_r_info->r_sym);
		return;
	}

	if (is_64bit)
		r_info = TO_NATIVE((Elf64_Xword)r_info);
	else
		r_info = TO_NATIVE((Elf32_Word)r_info);

	*r_type = ELF_R_TYPE(r_info);
	*r_sym = ELF_R_SYM(r_info);
}

static void section_rela(struct module *mod, struct elf_info *elf,
			 unsigned int fsecndx, const char *fromsec,
			 const Elf_Rela *start, const Elf_Rela *stop)
{
	const Elf_Rela *rela;

	for (rela = start; rela < stop; rela++) {
		Elf_Sym *tsym;
		Elf_Addr taddr, r_offset;
		unsigned int r_type, r_sym;

		r_offset = TO_NATIVE(rela->r_offset);
		get_rel_type_and_sym(elf, rela->r_info, &r_type, &r_sym);

		tsym = elf->symtab_start + r_sym;
		taddr = tsym->st_value + TO_NATIVE(rela->r_addend);

		switch (elf->hdr->e_machine) {
		case EM_RISCV:
			if (!strcmp("__ex_table", fromsec) &&
			    r_type == R_RISCV_SUB32)
				continue;
			break;
		case EM_LOONGARCH:
			switch (r_type) {
			case R_LARCH_SUB32:
				if (!strcmp("__ex_table", fromsec))
					continue;
				break;
			case R_LARCH_RELAX:
			case R_LARCH_ALIGN:
				/* These relocs do not refer to symbols */
				continue;
			}
			break;
		}

		check_section_mismatch(mod, elf, tsym,
				       fsecndx, fromsec, r_offset, taddr);
	}
}

static void section_rel(struct module *mod, struct elf_info *elf,
			unsigned int fsecndx, const char *fromsec,
			const Elf_Rel *start, const Elf_Rel *stop)
{
	const Elf_Rel *rel;

	for (rel = start; rel < stop; rel++) {
		Elf_Sym *tsym;
		Elf_Addr taddr, r_offset;
		unsigned int r_type, r_sym;
		void *loc;

		r_offset = TO_NATIVE(rel->r_offset);
		get_rel_type_and_sym(elf, rel->r_info, &r_type, &r_sym);

		loc = sym_get_data_by_offset(elf, fsecndx, r_offset);
		tsym = elf->symtab_start + r_sym;

		switch (elf->hdr->e_machine) {
		case EM_386:
			taddr = addend_386_rel(loc, r_type);
			break;
		case EM_ARM:
			taddr = addend_arm_rel(loc, tsym, r_type);
			break;
		case EM_MIPS:
			taddr = addend_mips_rel(loc, r_type);
			break;
		default:
			fatal("Please add code to calculate addend for this architecture\n");
		}

		check_section_mismatch(mod, elf, tsym,
				       fsecndx, fromsec, r_offset, taddr);
	}
}

/**
 * A module includes a number of sections that are discarded
 * either when loaded or when used as built-in.
 * For loaded modules all functions marked __init and all data
 * marked __initdata will be discarded when the module has been initialized.
 * Likewise for modules used built-in the sections marked __exit
 * are discarded because __exit marked function are supposed to be called
 * only when a module is unloaded which never happens for built-in modules.
 * The check_sec_ref() function traverses all relocation records
 * to find all references to a section that reference a section that will
 * be discarded and warns about it.
 **/
static void check_sec_ref(struct module *mod, struct elf_info *elf)
{
	int i;

	/* Walk through all sections */
	for (i = 0; i < elf->num_sections; i++) {
		Elf_Shdr *sechdr = &elf->sechdrs[i];

		check_section(mod->name, elf, sechdr);
		/* We want to process only relocation sections and not .init */
		if (sechdr->sh_type == SHT_REL || sechdr->sh_type == SHT_RELA) {
			/* section to which the relocation applies */
			unsigned int secndx = sechdr->sh_info;
			const char *secname = sec_name(elf, secndx);
			const void *start, *stop;

			/* If the section is known good, skip it */
			if (match(secname, section_white_list))
				continue;

			start = sym_get_data_by_offset(elf, i, 0);
			stop = start + sechdr->sh_size;

			if (sechdr->sh_type == SHT_RELA)
				section_rela(mod, elf, secndx, secname,
					     start, stop);
			else
				section_rel(mod, elf, secndx, secname,
					    start, stop);
		}
	}
}

static char *remove_dot(char *s)
{
	size_t n = strcspn(s, ".");

	if (n && s[n]) {
		size_t m = strspn(s + n + 1, "0123456789");
		if (m && (s[n + m + 1] == '.' || s[n + m + 1] == 0))
			s[n] = 0;
	}
	return s;
}

/*
 * The CRCs are recorded in .*.cmd files in the form of:
 * #SYMVER <name> <crc>
 */
static void extract_crcs_for_object(const char *object, struct module *mod)
{
	char cmd_file[PATH_MAX];
	char *buf, *p;
	const char *base;
	int dirlen, baselen_without_suffix, ret;

	base = get_basename(object);
	dirlen = base - object;

	baselen_without_suffix = strlen(object) - dirlen - strlen(".o");

	/*
	 * When CONFIG_LTO_CLANG_THIN_DIST=y, the ELF is *.thinlto-native.o
	 * but the symbol CRCs are recorded in *.o.cmd file.
	 */
	if (strends(object, ".thinlto-native.o"))
		baselen_without_suffix -= strlen(".thinlto-native");

	ret = snprintf(cmd_file, sizeof(cmd_file), "%.*s.%.*s.o.cmd",
		       dirlen, object, baselen_without_suffix, base);
	if (ret >= sizeof(cmd_file)) {
		error("%s: too long path was truncated\n", cmd_file);
		return;
	}

	buf = read_text_file(cmd_file);
	p = buf;

	while ((p = strstr(p, "\n#SYMVER "))) {
		char *name;
		size_t namelen;
		unsigned int crc;
		struct symbol *sym;

		name = p + strlen("\n#SYMVER ");

		p = strchr(name, ' ');
		if (!p)
			break;

		namelen = p - name;
		p++;

		if (!isdigit(*p))
			continue;	/* skip this line */

		crc = strtoul(p, &p, 0);
		if (*p != '\n')
			continue;	/* skip this line */

		name[namelen] = '\0';

		/*
		 * sym_find_with_module() may return NULL here.
		 * It typically occurs when CONFIG_TRIM_UNUSED_KSYMS=y.
		 * Since commit e1327a127703, genksyms calculates CRCs of all
		 * symbols, including trimmed ones. Ignore orphan CRCs.
		 */
		sym = sym_find_with_module(name, mod);
		if (sym)
			sym_set_crc(sym, crc);
	}

	free(buf);
}

/*
 * The symbol versions (CRC) are recorded in the .*.cmd files.
 * Parse them to retrieve CRCs for the current module.
 */
static void mod_set_crcs(struct module *mod)
{
	char objlist[PATH_MAX];
	char *buf, *p, *obj;
	int ret;

	if (mod->is_vmlinux) {
		strcpy(objlist, ".vmlinux.objs");
	} else {
		/* objects for a module are listed in the *.mod file. */
		ret = snprintf(objlist, sizeof(objlist), "%s.mod", mod->name);
		if (ret >= sizeof(objlist)) {
			error("%s: too long path was truncated\n", objlist);
			return;
		}
	}

	buf = read_text_file(objlist);
	p = buf;

	while ((obj = strsep(&p, "\n")) && obj[0])
		extract_crcs_for_object(obj, mod);

	free(buf);
}

static void read_symbols(const char *modname)
{
	const char *symname;
	char *version;
	char *license;
	char *namespace;
	struct module *mod;
	struct elf_info info = { };
	Elf_Sym *sym;

	if (!parse_elf(&info, modname))
		return;

	if (!strends(modname, ".o")) {
		error("%s: filename must be suffixed with .o\n", modname);
		return;
	}

	/* strip trailing .o */
	mod = new_module(modname, strlen(modname) - strlen(".o"));

	/* save .no_trim_symbol section for later use */
	if (info.no_trim_symbol_len) {
		mod->no_trim_symbol = xmalloc(info.no_trim_symbol_len);
		memcpy(mod->no_trim_symbol, info.no_trim_symbol,
		       info.no_trim_symbol_len);
		mod->no_trim_symbol_len = info.no_trim_symbol_len;
	}

	if (!mod->is_vmlinux) {
		license = get_modinfo(&info, "license");
		if (!license)
			error("missing MODULE_LICENSE() in %s\n", modname);
		while (license) {
			if (!license_is_gpl_compatible(license)) {
				mod->is_gpl_compatible = false;
				break;
			}
			license = get_next_modinfo(&info, "license", license);
		}

		for (namespace = get_modinfo(&info, "import_ns");
		     namespace;
		     namespace = get_next_modinfo(&info, "import_ns", namespace)) {
			if (strstarts(namespace, MODULE_NS_PREFIX))
				error("%s: explicitly importing namespace \"%s\" is not allowed.\n",
				      mod->name, namespace);

			add_namespace(&mod->imported_namespaces, namespace);
		}

		if (!get_modinfo(&info, "description"))
			warn("missing MODULE_DESCRIPTION() in %s\n", modname);
	}

	for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
		symname = remove_dot(info.strtab + sym->st_name);

		handle_symbol(mod, &info, sym, symname);
		handle_moddevtable(mod, &info, sym, symname);
	}

	check_sec_ref(mod, &info);

	if (!mod->is_vmlinux) {
		version = get_modinfo(&info, "version");
		if (version || all_versions)
			get_src_version(mod->name, mod->srcversion,
					sizeof(mod->srcversion) - 1);
	}

	parse_elf_finish(&info);

	if (modversions) {
		/*
		 * Our trick to get versioning for module struct etc. - it's
		 * never passed as an argument to an exported function, so
		 * the automatic versioning doesn't pick it up, but it's really
		 * important anyhow.
		 */
		sym_add_unresolved("module_layout", mod, false);

		mod_set_crcs(mod);
	}
}

static void read_symbols_from_files(const char *filename)
{
	FILE *in = stdin;
	char fname[PATH_MAX];

	in = fopen(filename, "r");
	if (!in)
		fatal("Can't open filenames file %s: %m", filename);

	while (fgets(fname, PATH_MAX, in) != NULL) {
		if (strends(fname, "\n"))
			fname[strlen(fname)-1] = '\0';
		read_symbols(fname);
	}

	fclose(in);
}

#define SZ 500

/* We first write the generated file into memory using the
 * following helper, then compare to the file on disk and
 * only update the later if anything changed */

void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
						      const char *fmt, ...)
{
	char tmp[SZ];
	int len;
	va_list ap;

	va_start(ap, fmt);
	len = vsnprintf(tmp, SZ, fmt, ap);
	va_end(ap);

	if (len < 0) {
		perror("vsnprintf failed");
		exit(1);
	}
	if (len >= SZ)
		fatal("buf_printf output truncated for string %s: %d bytes needed, %d available\n",
		      tmp, len + 1, SZ);

	buf_write(buf, tmp, len);
}

void buf_write(struct buffer *buf, const char *s, int len)
{
	if (buf->size - buf->pos < len) {
		buf->size += len + SZ;
		buf->p = xrealloc(buf->p, buf->size);
	}
	strncpy(buf->p + buf->pos, s, len);
	buf->pos += len;
}

/**
 * verify_module_namespace() - does @modname have access to this symbol's @namespace
 * @namespace: export symbol namespace
 * @modname: module name
 *
 * If @namespace is prefixed with "module:" to indicate it is a module namespace
 * then test if @modname matches any of the comma separated patterns.
 *
 * The patterns only support tail-glob.
 */
static bool verify_module_namespace(const char *namespace, const char *modname)
{
	size_t len, modlen = strlen(modname);
	const char *prefix = "module:";
	const char *sep;
	bool glob;

	if (!strstarts(namespace, prefix))
		return false;

	for (namespace += strlen(prefix); *namespace; namespace = sep) {
		sep = strchrnul(namespace, ',');
		len = sep - namespace;

		glob = false;
		if (sep[-1] == '*') {
			len--;
			glob = true;
		}

		if (*sep)
			sep++;

		if (strncmp(namespace, modname, len) == 0 && (glob || len == modlen))
			return true;
	}

	return false;
}

static void check_exports(struct module *mod)
{
	struct symbol *s, *exp;

	list_for_each_entry(s, &mod->unresolved_symbols, list) {
		const char *basename;
		exp = find_symbol(s->name);
		if (!exp) {
			if (!s->weak && nr_unresolved++ < MAX_UNRESOLVED_REPORTS)
				modpost_log(!warn_unresolved,
					    "\"%s\" [%s.ko] undefined!\n",
					    s->name, mod->name);
			continue;
		}
		if (exp->module == mod) {
			error("\"%s\" [%s.ko] was exported without definition\n",
			      s->name, mod->name);
			continue;
		}

		exp->used = true;
		s->module = exp->module;
		s->crc_valid = exp->crc_valid;
		s->crc = exp->crc;

		basename = get_basename(mod->name);

		if (!verify_module_namespace(exp->namespace, basename) &&
		    !contains_namespace(&mod->imported_namespaces, exp->namespace)) {
			modpost_log(!allow_missing_ns_imports,
				    "module %s uses symbol %s from namespace %s, but does not import it.\n",
				    basename, exp->name, exp->namespace);
			add_namespace(&mod->missing_namespaces, exp->namespace);
		}

		if (!mod->is_gpl_compatible && exp->is_gpl_only)
			error("GPL-incompatible module %s.ko uses GPL-only symbol '%s'\n",
			      basename, exp->name);
	}
}

static void handle_white_list_exports(const char *white_list)
{
	char *buf, *p, *name;

	buf = read_text_file(white_list);
	p = buf;

	while ((name = strsep(&p, "\n"))) {
		struct symbol *sym = find_symbol(name);

		if (sym)
			sym->used = true;
	}

	free(buf);
}

/*
 * Keep symbols recorded in the .no_trim_symbol section. This is necessary to
 * prevent CONFIG_TRIM_UNUSED_KSYMS from dropping EXPORT_SYMBOL because
 * symbol_get() relies on the symbol being present in the ksymtab for lookups.
 */
static void keep_no_trim_symbols(struct module *mod)
{
	unsigned long size = mod->no_trim_symbol_len;

	for (char *s = mod->no_trim_symbol; s; s = next_string(s , &size)) {
		struct symbol *sym;

		/*
		 * If find_symbol() returns NULL, this symbol is not provided
		 * by any module, and symbol_get() will fail.
		 */
		sym = find_symbol(s);
		if (sym)
			sym->used = true;
	}
}

static void check_modname_len(struct module *mod)
{
	const char *mod_name;

	mod_name = get_basename(mod->name);

	if (strlen(mod_name) >= MODULE_NAME_LEN)
		error("module name is too long [%s.ko]\n", mod->name);
}

/**
 * Header for the generated file
 **/
static void add_header(struct buffer *b, struct module *mod)
{
	buf_printf(b, "#include <linux/module.h>\n");
	buf_printf(b, "#include <linux/export-internal.h>\n");
	buf_printf(b, "#include <linux/compiler.h>\n");
	buf_printf(b, "\n");
	buf_printf(b, "MODULE_INFO(name, KBUILD_MODNAME);\n");
	buf_printf(b, "\n");
	buf_printf(b, "__visible struct module __this_module\n");
	buf_printf(b, "__section(\".gnu.linkonce.this_module\") = {\n");
	buf_printf(b, "\t.name = KBUILD_MODNAME,\n");
	if (mod->has_init)
		buf_printf(b, "\t.init = init_module,\n");
	if (mod->has_cleanup)
		buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"
			      "\t.exit = cleanup_module,\n"
			      "#endif\n");
	buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n");
	buf_printf(b, "};\n");

	if (!external_module)
		buf_printf(b, "\nMODULE_INFO(intree, \"Y\");\n");

	if (strstarts(mod->name, "drivers/staging"))
		buf_printf(b, "\nMODULE_INFO(staging, \"Y\");\n");

	if (strstarts(mod->name, "tools/testing"))
		buf_printf(b, "\nMODULE_INFO(test, \"Y\");\n");
}

static void add_exported_symbols(struct buffer *buf, struct module *mod)
{
	struct symbol *sym;

	/* generate struct for exported symbols */
	buf_printf(buf, "\n");
	list_for_each_entry(sym, &mod->exported_symbols, list) {
		if (trim_unused_exports && !sym->used)
			continue;

		buf_printf(buf, "KSYMTAB_%s(%s, \"%s\");\n",
			   sym->is_func ? "FUNC" : "DATA", sym->name,
			   sym->namespace);

		buf_printf(buf, "SYMBOL_FLAGS(%s, 0x%02x);\n",
			   sym->name, get_symbol_flags(sym));
	}

	if (!modversions)
		return;

	/* record CRCs for exported symbols */
	buf_printf(buf, "\n");
	list_for_each_entry(sym, &mod->exported_symbols, list) {
		if (trim_unused_exports && !sym->used)
			continue;

		if (!sym->crc_valid)
			warn("EXPORT symbol \"%s\" [%s%s] version generation failed, symbol will not be versioned.\n"
			     "Is \"%s\" prototyped in <asm/asm-prototypes.h>?\n",
			     sym->name, mod->name, mod->is_vmlinux ? "" : ".ko",
			     sym->name);

		buf_printf(buf, "SYMBOL_CRC(%s, 0x%08x);\n",
			   sym->name, sym->crc);
	}
}

/**
 * Record CRCs for unresolved symbols, supporting long names
 */
static void add_extended_versions(struct buffer *b, struct module *mod)
{
	struct symbol *s;

	if (!extended_modversions)
		return;

	buf_printf(b, "\n");
	buf_printf(b, "static const u32 ____version_ext_crcs[]\n");
	buf_printf(b, "__used __section(\"__version_ext_crcs\") = {\n");
	list_for_each_entry(s, &mod->unresolved_symbols, list) {
		if (!s->module)
			continue;
		if (!s->crc_valid) {
			warn("\"%s\" [%s.ko] has no CRC!\n",
				s->name, mod->name);
			continue;
		}
		buf_printf(b, "\t0x%08x,\n", s->crc);
	}
	buf_printf(b, "};\n");

	buf_printf(b, "static const char ____version_ext_names[]\n");
	buf_printf(b, "__used __section(\"__version_ext_names\") =\n");
	list_for_each_entry(s, &mod->unresolved_symbols, list) {
		if (!s->module)
			continue;
		if (!s->crc_valid)
			/*
			 * We already warned on this when producing the crc
			 * table.
			 * We need to skip its name too, as the indexes in
			 * both tables need to align.
			 */
			continue;
		buf_printf(b, "\t\"%s\\0\"\n", s->name);
	}
	buf_printf(b, ";\n");
}

/**
 * Record CRCs for unresolved symbols
 **/
static void add_versions(struct buffer *b, struct module *mod)
{
	struct symbol *s;

	if (!basic_modversions)
		return;

	buf_printf(b, "\n");
	buf_printf(b, "static const struct modversion_info ____versions[]\n");
	buf_printf(b, "__used __section(\"__versions\") = {\n");

	list_for_each_entry(s, &mod->unresolved_symbols, list) {
		if (!s->module)
			continue;
		if (!s->crc_valid) {
			warn("\"%s\" [%s.ko] has no CRC!\n",
				s->name, mod->name);
			continue;
		}
		if (strlen(s->name) >= MODULE_NAME_LEN) {
			if (extended_modversions) {
				/* this symbol will only be in the extended info */
				continue;
			} else {
				error("too long symbol \"%s\" [%s.ko]\n",
				      s->name, mod->name);
				break;
			}
		}
		buf_printf(b, "\t{ 0x%08x, \"%s\" },\n",
			   s->crc, s->name);
	}

	buf_printf(b, "};\n");
}

static void add_depends(struct buffer *b, struct module *mod)
{
	struct symbol *s;
	int first = 1;

	/* Clear ->seen flag of modules that own symbols needed by this. */
	list_for_each_entry(s, &mod->unresolved_symbols, list) {
		if (s->module)
			s->module->seen = s->module->is_vmlinux;
	}

	buf_printf(b, "\n");
	buf_printf(b, "MODULE_INFO(depends, \"");
	list_for_each_entry(s, &mod->unresolved_symbols, list) {
		const char *p;
		if (!s->module)
			continue;

		if (s->module->seen)
			continue;

		s->module->seen = true;
		p = get_basename(s->module->name);
		buf_printf(b, "%s%s", first ? "" : ",", p);
		first = 0;
	}
	buf_printf(b, "\");\n");
}

static void add_srcversion(struct buffer *b, struct module *mod)
{
	if (mod->srcversion[0]) {
		buf_printf(b, "\n");
		buf_printf(b, "MODULE_INFO(srcversion, \"%s\");\n",
			   mod->srcversion);
	}
}

static void write_buf(struct buffer *b, const char *fname)
{
	FILE *file;

	if (error_occurred)
		return;

	file = fopen(fname, "w");
	if (!file) {
		perror(fname);
		exit(1);
	}
	if (fwrite(b->p, 1, b->pos, file) != b->pos) {
		perror(fname);
		exit(1);
	}
	if (fclose(file) != 0) {
		perror(fname);
		exit(1);
	}
}

static void write_if_changed(struct buffer *b, const char *fname)
{
	char *tmp;
	FILE *file;
	struct stat st;

	file = fopen(fname, "r");
	if (!file)
		goto write;

	if (fstat(fileno(file), &st) < 0)
		goto close_write;

	if (st.st_size != b->pos)
		goto close_write;

	tmp = xmalloc(b->pos);
	if (fread(tmp, 1, b->pos, file) != b->pos)
		goto free_write;

	if (memcmp(tmp, b->p, b->pos) != 0)
		goto free_write;

	free(tmp);
	fclose(file);
	return;

 free_write:
	free(tmp);
 close_write:
	fclose(file);
 write:
	write_buf(b, fname);
}

static void write_vmlinux_export_c_file(struct module *mod)
{
	struct buffer buf = { };
	struct module_alias *alias, *next;

	buf_printf(&buf,
		   "#include <linux/export-internal.h>\n");

	add_exported_symbols(&buf, mod);

	buf_printf(&buf,
		   "#include <linux/module.h>\n"
		   "#undef __MODULE_INFO_PREFIX\n"
		   "#define __MODULE_INFO_PREFIX\n");

	list_for_each_entry_safe(alias, next, &mod->aliases, node) {
		buf_printf(&buf, "MODULE_INFO(%s.alias, \"%s\");\n",
			   alias->builtin_modname, alias->str);
		list_del(&alias->node);
		free(alias->builtin_modname);
		free(alias);
	}

	write_if_changed(&buf, ".vmlinux.export.c");
	free(buf.p);
}

/* do sanity checks, and generate *.mod.c file */
static void write_mod_c_file(struct module *mod)
{
	struct buffer buf = { };
	struct module_alias *alias, *next;
	char fname[PATH_MAX];
	int ret;

	add_header(&buf, mod);
	add_exported_symbols(&buf, mod);
	add_versions(&buf, mod);
	add_extended_versions(&buf, mod);
	add_depends(&buf, mod);

	buf_printf(&buf, "\n");
	list_for_each_entry_safe(alias, next, &mod->aliases, node) {
		buf_printf(&buf, "MODULE_ALIAS(\"%s\");\n", alias->str);
		list_del(&alias->node);
		free(alias);
	}

	add_srcversion(&buf, mod);

	ret = snprintf(fname, sizeof(fname), "%s.mod.c", mod->name);
	if (ret >= sizeof(fname)) {
		error("%s: too long path was truncated\n", fname);
		goto free;
	}

	write_if_changed(&buf, fname);

free:
	free(buf.p);
}

/* parse Module.symvers file. line format:
 * 0x12345678<tab>symbol<tab>module<tab>export<tab>namespace
 **/
static void read_dump(const char *fname)
{
	char *buf, *pos, *line;

	buf = read_text_file(fname);
	if (!buf)
		/* No symbol versions, silently ignore */
		return;

	pos = buf;

	while ((line = get_line(&pos))) {
		char *symname, *namespace, *modname, *d, *export;
		unsigned int crc;
		struct module *mod;
		struct symbol *s;
		bool gpl_only;

		if (!(symname = strchr(line, '\t')))
			goto fail;
		*symname++ = '\0';
		if (!(modname = strchr(symname, '\t')))
			goto fail;
		*modname++ = '\0';
		if (!(export = strchr(modname, '\t')))
			goto fail;
		*export++ = '\0';
		if (!(namespace = strchr(export, '\t')))
			goto fail;
		*namespace++ = '\0';

		crc = strtoul(line, &d, 16);
		if (*symname == '\0' || *modname == '\0' || *d != '\0')
			goto fail;

		if (!strcmp(export, "EXPORT_SYMBOL_GPL")) {
			gpl_only = true;
		} else if (!strcmp(export, "EXPORT_SYMBOL")) {
			gpl_only = false;
		} else {
			error("%s: unknown license %s. skip", symname, export);
			continue;
		}

		mod = find_module(fname, modname);
		if (!mod) {
			mod = new_module(modname, strlen(modname));
			mod->dump_file = fname;
		}
		s = sym_add_exported(symname, mod, gpl_only, namespace);
		sym_set_crc(s, crc);
	}
	free(buf);
	return;
fail:
	free(buf);
	fatal("parse error in symbol dump file\n");
}

static void write_dump(const char *fname)
{
	struct buffer buf = { };
	struct module *mod;
	struct symbol *sym;

	list_for_each_entry(mod, &modules, list) {
		if (mod->dump_file)
			continue;
		list_for_each_entry(sym, &mod->exported_symbols, list) {
			if (trim_unused_exports && !sym->used)
				continue;

			buf_printf(&buf, "0x%08x\t%s\t%s\tEXPORT_SYMBOL%s\t%s\n",
				   sym->crc, sym->name, mod->name,
				   sym->is_gpl_only ? "_GPL" : "",
				   sym->namespace);
		}
	}
	write_buf(&buf, fname);
	free(buf.p);
}

static void write_namespace_deps_files(const char *fname)
{
	struct module *mod;
	struct namespace_list *ns;
	struct buffer ns_deps_buf = {};

	list_for_each_entry(mod, &modules, list) {

		if (mod->dump_file || list_empty(&mod->missing_namespaces))
			continue;

		buf_printf(&ns_deps_buf, "%s.ko:", mod->name);

		list_for_each_entry(ns, &mod->missing_namespaces, list)
			buf_printf(&ns_deps_buf, " %s", ns->namespace);

		buf_printf(&ns_deps_buf, "\n");
	}

	write_if_changed(&ns_deps_buf, fname);
	free(ns_deps_buf.p);
}

struct dump_list {
	struct list_head list;
	const char *file;
};

static void check_host_endian(void)
{
	static const union {
		short s;
		char c[2];
	} endian_test = { .c = {0x01, 0x02} };

	switch (endian_test.s) {
	case 0x0102:
		host_is_big_endian = true;
		break;
	case 0x0201:
		host_is_big_endian = false;
		break;
	default:
		fatal("Unknown host endian\n");
	}
}

int main(int argc, char **argv)
{
	struct module *mod;
	char *missing_namespace_deps = NULL;
	char *unused_exports_white_list = NULL;
	char *dump_write = NULL, *files_source = NULL;
	int opt;
	LIST_HEAD(dump_lists);
	struct dump_list *dl, *dl2;

	while ((opt = getopt(argc, argv, "ei:MmnT:to:au:WwENd:xb")) != -1) {
		switch (opt) {
		case 'e':
			external_module = true;
			break;
		case 'i':
			dl = xmalloc(sizeof(*dl));
			dl->file = optarg;
			list_add_tail(&dl->list, &dump_lists);
			break;
		case 'M':
			module_enabled = true;
			break;
		case 'm':
			modversions = true;
			break;
		case 'n':
			ignore_missing_files = true;
			break;
		case 'o':
			dump_write = optarg;
			break;
		case 'a':
			all_versions = true;
			break;
		case 'T':
			files_source = optarg;
			break;
		case 't':
			trim_unused_exports = true;
			break;
		case 'u':
			unused_exports_white_list = optarg;
			break;
		case 'W':
			extra_warn = true;
			break;
		case 'w':
			warn_unresolved = true;
			break;
		case 'E':
			sec_mismatch_warn_only = false;
			break;
		case 'N':
			allow_missing_ns_imports = true;
			break;
		case 'd':
			missing_namespace_deps = optarg;
			break;
		case 'b':
			basic_modversions = true;
			break;
		case 'x':
			extended_modversions = true;
			break;
		default:
			exit(1);
		}
	}

	check_host_endian();

	list_for_each_entry_safe(dl, dl2, &dump_lists, list) {
		read_dump(dl->file);
		list_del(&dl->list);
		free(dl);
	}

	while (optind < argc)
		read_symbols(argv[optind++]);

	if (files_source)
		read_symbols_from_files(files_source);

	list_for_each_entry(mod, &modules, list) {
		keep_no_trim_symbols(mod);

		if (mod->dump_file || mod->is_vmlinux)
			continue;

		check_modname_len(mod);
		check_exports(mod);
	}

	if (unused_exports_white_list)
		handle_white_list_exports(unused_exports_white_list);

	list_for_each_entry(mod, &modules, list) {
		if (mod->dump_file)
			continue;

		if (mod->is_vmlinux)
			write_vmlinux_export_c_file(mod);
		else
			write_mod_c_file(mod);
	}

	if (missing_namespace_deps)
		write_namespace_deps_files(missing_namespace_deps);

	if (dump_write)
		write_dump(dump_write);
	if (sec_mismatch_count && !sec_mismatch_warn_only)
		error("Section mismatches detected.\n"
		      "Set CONFIG_SECTION_MISMATCH_WARN_ONLY=y to allow them.\n");

	if (nr_unresolved > MAX_UNRESOLVED_REPORTS)
		warn("suppressed %u unresolved symbol warnings because there were too many)\n",
		     nr_unresolved - MAX_UNRESOLVED_REPORTS);

	return error_occurred ? 1 : 0;
}
