summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2016-03-07 19:59:08 +0000
committerdim <dim@FreeBSD.org>2016-03-07 19:59:08 +0000
commit9f6c0beb36d11aa18540a6697d10617db187affc (patch)
treeaf6223c199080a497dac7aa02e8493c242b48e09
parent8526db178678c940e9594ff82ef9746ae465950d (diff)
downloadFreeBSD-src-9f6c0beb36d11aa18540a6697d10617db187affc.zip
FreeBSD-src-9f6c0beb36d11aa18540a6697d10617db187affc.tar.gz
MFC r296419 (by kib):
In the link_elf_obj.c, handle sections of type SHT_AMD64_UNWIND same as SHT_PROGBITS. This is needed after the clang 3.8 import, which generates that type for .eh_frame section, which had SHT_PROGBITS type before. Reported by: Nikolai Lifanov <lifanov@mail.lifanov.com> PR: 207729 Tested by: dim (previous version) Sponsored by: The FreeBSD Foundation MFC r296428: Since kernel modules can now contain sections of type SHT_AMD64_UNWIND, the boot loader should not skip over these anymore while loading images. Otherwise the kernel can still panic when it doesn't find the .eh_frame section belonging to the .rela.eh_frame section. Unfortunately this will require installing boot loaders from sys/boot before attempting to boot with a new kernel. Reviewed by: kib Approved by: re (marius)
-rw-r--r--sys/boot/common/load_elf_obj.c3
-rw-r--r--sys/kern/link_elf_obj.c29
2 files changed, 31 insertions, 1 deletions
diff --git a/sys/boot/common/load_elf_obj.c b/sys/boot/common/load_elf_obj.c
index 626f2d9..b983ecb 100644
--- a/sys/boot/common/load_elf_obj.c
+++ b/sys/boot/common/load_elf_obj.c
@@ -221,6 +221,9 @@ __elfN(obj_loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
switch (shdr[i].sh_type) {
case SHT_PROGBITS:
case SHT_NOBITS:
+#if defined(__i386__) || defined(__amd64__)
+ case SHT_AMD64_UNWIND:
+#endif
lastaddr = roundup(lastaddr, shdr[i].sh_addralign);
shdr[i].sh_addr = (Elf_Addr)lastaddr;
lastaddr += shdr[i].sh_size;
diff --git a/sys/kern/link_elf_obj.c b/sys/kern/link_elf_obj.c
index 453d8ce..dc13283 100644
--- a/sys/kern/link_elf_obj.c
+++ b/sys/kern/link_elf_obj.c
@@ -257,6 +257,9 @@ link_elf_link_preload(linker_class_t cls, const char *filename,
switch (shdr[i].sh_type) {
case SHT_PROGBITS:
case SHT_NOBITS:
+#ifdef __amd64__
+ case SHT_AMD64_UNWIND:
+#endif
ef->nprogtab++;
break;
case SHT_SYMTAB:
@@ -327,9 +330,16 @@ link_elf_link_preload(linker_class_t cls, const char *filename,
switch (shdr[i].sh_type) {
case SHT_PROGBITS:
case SHT_NOBITS:
+#ifdef __amd64__
+ case SHT_AMD64_UNWIND:
+#endif
ef->progtab[pb].addr = (void *)shdr[i].sh_addr;
if (shdr[i].sh_type == SHT_PROGBITS)
ef->progtab[pb].name = "<<PROGBITS>>";
+#ifdef __amd64__
+ else if (shdr[i].sh_type == SHT_AMD64_UNWIND)
+ ef->progtab[pb].name = "<<UNWIND>>";
+#endif
else
ef->progtab[pb].name = "<<NOBITS>>";
ef->progtab[pb].size = shdr[i].sh_size;
@@ -553,6 +563,9 @@ link_elf_load_file(linker_class_t cls, const char *filename,
switch (shdr[i].sh_type) {
case SHT_PROGBITS:
case SHT_NOBITS:
+#ifdef __amd64__
+ case SHT_AMD64_UNWIND:
+#endif
ef->nprogtab++;
break;
case SHT_SYMTAB:
@@ -659,6 +672,9 @@ link_elf_load_file(linker_class_t cls, const char *filename,
switch (shdr[i].sh_type) {
case SHT_PROGBITS:
case SHT_NOBITS:
+#ifdef __amd64__
+ case SHT_AMD64_UNWIND:
+#endif
alignmask = shdr[i].sh_addralign - 1;
mapsize += alignmask;
mapsize &= ~alignmask;
@@ -726,6 +742,9 @@ link_elf_load_file(linker_class_t cls, const char *filename,
switch (shdr[i].sh_type) {
case SHT_PROGBITS:
case SHT_NOBITS:
+#ifdef __amd64__
+ case SHT_AMD64_UNWIND:
+#endif
alignmask = shdr[i].sh_addralign - 1;
mapbase += alignmask;
mapbase &= ~alignmask;
@@ -734,6 +753,10 @@ link_elf_load_file(linker_class_t cls, const char *filename,
ef->shstrtab + shdr[i].sh_name;
else if (shdr[i].sh_type == SHT_PROGBITS)
ef->progtab[pb].name = "<<PROGBITS>>";
+#ifdef __amd64__
+ else if (shdr[i].sh_type == SHT_AMD64_UNWIND)
+ ef->progtab[pb].name = "<<UNWIND>>";
+#endif
else
ef->progtab[pb].name = "<<NOBITS>>";
if (ef->progtab[pb].name != NULL &&
@@ -755,7 +778,11 @@ link_elf_load_file(linker_class_t cls, const char *filename,
}
ef->progtab[pb].size = shdr[i].sh_size;
ef->progtab[pb].sec = i;
- if (shdr[i].sh_type == SHT_PROGBITS) {
+ if (shdr[i].sh_type == SHT_PROGBITS
+#ifdef __amd64__
+ || shdr[i].sh_type == SHT_AMD64_UNWIND
+#endif
+ ) {
error = vn_rdwr(UIO_READ, nd.ni_vp,
ef->progtab[pb].addr,
shdr[i].sh_size, shdr[i].sh_offset,
OpenPOWER on IntegriCloud