File kdump-relocatable-check-config.patch of Package kdump
From: Petr Tesarik <ptesarik@suse.com>
Date: Fri Aug 28 11:04:58 2015 +0200
Subject: Use kernel config to check if a kernel is relocatable
References: bsc#941088
Git-commit 9ed2a1d91d332ea20a876bd4d05c1804947caeaa
Patch-mainline: v0.8.16
The ELF type is apparently always EXEC, regardless of whether
the kernel was compiled with CONFIG_RELOCATABLE=y, or not. So,
it is necessary to check the actual configuration.
Signed-off-by: Petr Tesarik <ptesarik@suse.com>
diff --git a/kdumptool/kerneltool.cc b/kdumptool/kerneltool.cc
index a85b112..5d463ac 100644
--- a/kdumptool/kerneltool.cc
+++ b/kdumptool/kerneltool.cc
@@ -340,8 +340,8 @@ bool KernelTool::elfIsRelocatable() const
throw KSystemError("Seek failed", errno);
}
+ unsigned short machine;
string arch;
- bool reloc = false;
if (e_ident[EI_CLASS] == ELFCLASS32) {
Elf32_Ehdr hdr;
@@ -351,7 +351,6 @@ bool KernelTool::elfIsRelocatable() const
throw KSystemError("Couldn't read ELF header", errno);
}
- unsigned short machine;
if (e_ident[EI_DATA] == ELFDATA2LSB)
machine = le16toh(hdr.e_machine);
else if (e_ident[EI_DATA] == ELFDATA2MSB)
@@ -359,10 +358,6 @@ bool KernelTool::elfIsRelocatable() const
else
throw KError("elfIsRelocatable(): Invalid ELF data encoding");
- arch = archFromElfMachine(machine);
-
- if (hdr.e_type == ET_DYN)
- reloc = true;
} else if (e_ident[EI_CLASS] == ELFCLASS64) {
Elf64_Ehdr hdr;
@@ -372,27 +367,23 @@ bool KernelTool::elfIsRelocatable() const
throw KSystemError("Couldn't read ELF header", errno);
}
- if (hdr.e_type == ET_DYN)
- reloc = true;
-
- unsigned short machine;
if (e_ident[EI_DATA] == ELFDATA2LSB)
machine = le16toh(hdr.e_machine);
else if (e_ident[EI_DATA] == ELFDATA2MSB)
machine = be16toh(hdr.e_machine);
else
throw KError("elfIsRelocatable(): Invalid ELF data encoding");
-
- arch = archFromElfMachine(machine);
} else {
throw KError("elfIsRelocatable(): Invalid ELF class");
}
+ arch = archFromElfMachine(machine);
gzclose(fp);
Debug::debug()->dbg("Detected arch %s", arch.c_str());
- return isArchAlwaysRelocatable(arch) || reloc;
+ return isArchAlwaysRelocatable(arch) ||
+ (hasConfigRelocatable(arch) && isConfigRelocatable());
}
// -----------------------------------------------------------------------------
@@ -403,6 +394,28 @@ bool KernelTool::isArchAlwaysRelocatable(const string &machine) const
}
// -----------------------------------------------------------------------------
+bool KernelTool::hasConfigRelocatable(const string &machine) const
+ throw ()
+{
+ return Util::isX86(machine) || machine == "ppc64" || machine == "ppc";
+}
+
+// -----------------------------------------------------------------------------
+bool KernelTool::isConfigRelocatable() const
+ throw (KError)
+{
+ try {
+ Kconfig *kconfig = retrieveKernelConfig();
+ KconfigValue kv = kconfig->get("CONFIG_RELOCATABLE");
+ return (kv.getType() == KconfigValue::T_TRISTATE &&
+ kv.getTristateValue() == KconfigValue::ON);
+ } catch (KError &e) {
+ Debug::debug()->dbg("%s (assume non-relocatable)", e.what());
+ return false;
+ }
+}
+
+// -----------------------------------------------------------------------------
string KernelTool::archFromElfMachine(unsigned long long et_machine) const
throw ()
{
diff --git a/kdumptool/kerneltool.h b/kdumptool/kerneltool.h
index 33e6c14..acf2aaf 100644
--- a/kdumptool/kerneltool.h
+++ b/kdumptool/kerneltool.h
@@ -163,6 +163,26 @@ class KernelTool {
throw ();
/**
+ * Checks if the architecture has CONFIG_RELOCATABLE.
+ *
+ * @param[in] machine the machine, e.g. "ppc64"
+ * @return @c true if it has CONFIG_RELOCATABLE option.
+ * @c false otherwise
+ */
+ bool hasConfigRelocatable(const std::string &machine) const
+ throw ();
+
+ /**
+ * Checks if the kernel was compiled with CONFIG_RELOCATABLE.
+ *
+ * @param[in] machine the machine, e.g. "ppc64"
+ * @return @c true if configured with CONFIG_RELOCATABLE=y.
+ * @c false otherwise
+ */
+ bool isConfigRelocatable() const
+ throw (KError);
+
+ /**
* Checks if a ELF kernel image is relocatable.
*
* @return @c true if the ELF kernel is relocatable, @c false otherwise