[Converted from Gnats 2273] I am using gdb to open a linux kernel core file generated for x86_64 platform. But gdb is not analyzing the dumps properly. Its getting the wrong symbol values. For example, following case prints two different values for same symbol panic_timeout. #gdb vmlinux (gdb) p &panic_timeout $1 = (int *) 0xffffffff808a1fa8 #gdb vmlinux vmcore (gdb) p &panic_timeout $1 = (int *) 0xffffffff008aaebf First one is the right value. Why gdb is giving incorrect results while opened with vmcore? The bug can be reproduced with mainline GDB 6.6. This problem is not present in gdb 6.4. It works perfectly fine. Note, this vmlinux file is of ET_DYN type. It has been compiled as an executable and then an external program changes elf type to ET_DYN because this is a fully relocatable executable and can be loaded at any physical address. The patch to build such a kernel is attached to the bug report. vmlinux ELF header is as follows. ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: DYN (Shared object file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x200000 Start of program headers: 64 (bytes into file) Start of section headers: 61579848 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 5 Size of section headers: 64 (bytes) Number of section headers: 51 Section header string table index: 48 vmcore ELF header and PT_LOAD headers are as follows. ELF Header: Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data: 2's complement, little endian Version: 1 (current) OS/ABI: UNIX - System V ABI Version: 0 Type: CORE (Core file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x0 Start of program headers: 64 (bytes into file) Start of section headers: 0 (bytes into file) Flags: 0x0 Size of this header: 64 (bytes) Size of program headers: 56 (bytes) Number of program headers: 6 Size of section headers: 0 (bytes) Number of section headers: 0 Section header string table index: 0 There are no sections in this file. Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flags Align NOTE 0x0000000000000190 0x0000000000000000 0x0000000000000000 0x0000000000000b20 0x0000000000000b20 0 LOAD 0x0000000000000cb0 0xffffffff80200000 0x0000000000200000 0x0000000000742000 0x0000000000742000 RWE 0 LOAD 0x0000000000742cb0 0xffff810000000000 0x0000000000000000 0x00000000000a0000 0x00000000000a0000 RWE 0 LOAD 0x00000000007e2cb0 0xffff810000100000 0x0000000000100000 0x0000000000f00000 0x0000000000f00000 RWE 0 LOAD 0x00000000016e2cb0 0xffff810009000000 0x0000000009000000 0x00000000c6f8dc80 0x00000000c6f8dc80 RWE 0 LOAD 0x00000000c8670930 0xffff810100000000 0x0000000100000000 0x0000000130000000 0x0000000130000000 RWE 0 I found out that the error appeared with following change: cvs diff -u -D "2006-01-24 22:30:00 -0000" -D "2006-01-24 22:40:00 -0000" (Patch is attached.) The problem is svr4_solib_create_inferior_hook() -> svr4_relocate_main_executable(). If I comment out this function, everything works fine. ;-) Release: 6.5 Environment: GNU/Linux
From: Bernhard Walle <bwalle@suse.de> To: gdb-gnats@sources.redhat.com Cc: Subject: Re: corefiles/2273: Invalid relocation if executable is marked as ET_DYN Date: Mon, 18 Jun 2007 15:21:26 +0200 As I don't know how to send multiple attachments, here's the kernel patch inline: ----- From ebiederm@xmission.com Wed May 30 23:15:10 2007 Date: Mon, 30 Apr 2007 09:12:39 -0600 From: "Eric W. Biederman" <ebiederm@xmission.com> To: Andi Kleen <ak@suse.de>, Andrew Morton <akpm@linux-foundation.org> Cc: Helge Hafting <helgehaf@aitel.hist.no>, Horms <horms@verge.net.au>, Kexec Mailing List <kexec@lists.infradead.org>, Jurriaan <thunder7@xs4all.nl>, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] x86_64: Reflect the relocatability of the kernel in the ELF header. Currently because vmlinux does not reflect that the kernel is relocatable we still have to support CONFIG_PHYSICAL_START. So this patch adds a small c program to do what we cannot do with a linker script set the elf header type to ET_DYN. Since last time I have fixed the type to be in my code ET_DYN (oops), and verified this works with kexec. I realized while testing that we don't have anyway of identifying a kernel vmlinux as linux so we probably want to add an ELF note but that will be another patch. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> --- arch/x86_64/Kconfig | 4 +++ arch/x86_64/Makefile | 10 +++++++ scripts/Makefile | 11 ++++--- scripts/mketrel.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 scripts/mketrel.c diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index b00adb9..95949c3 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -121,6 +121,10 @@ config ARCH_HAS_ILOG2_U64 bool default n +config ELF_RELOCATABLE + bool + default y + source "init/Kconfig" diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index a81a84a..7c0434c 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile @@ -125,6 +125,16 @@ define archhelp echo ' isoimage - Create a boot CD-ROM image' endef +ifeq ($(CONFIG_RELOCATABLE),y) +define cmd_vmlinux__ + $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) -o $@ \ + -T $(vmlinux-lds) $(vmlinux-init) \ + --start-group $(vmlinux-main) --end-group \ + $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) FORCE ,$^) \ + && scripts/mketrel $@ +endef +endif + CLEAN_FILES += arch/$(ARCH)/boot/fdimage \ arch/$(ARCH)/boot/image.iso \ arch/$(ARCH)/boot/mtools.conf diff --git a/scripts/Makefile b/scripts/Makefile index 1c73c5a..ddba550 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -7,11 +7,12 @@ # conmakehash: Create chartable # conmakehash: Create arrays for initializing the kernel console tables -hostprogs-$(CONFIG_KALLSYMS) += kallsyms -hostprogs-$(CONFIG_LOGO) += pnmtologo -hostprogs-$(CONFIG_VT) += conmakehash -hostprogs-$(CONFIG_PROM_CONSOLE) += conmakehash -hostprogs-$(CONFIG_IKCONFIG) += bin2c +hostprogs-$(CONFIG_KALLSYMS) += kallsyms +hostprogs-$(CONFIG_LOGO) += pnmtologo +hostprogs-$(CONFIG_VT) += conmakehash +hostprogs-$(CONFIG_PROM_CONSOLE) += conmakehash +hostprogs-$(CONFIG_IKCONFIG) += bin2c +hostprogs-$(CONFIG_ELF_RELOCATABLE) += mketrel always := $(hostprogs-y) $(hostprogs-m) diff --git a/scripts/mketrel.c b/scripts/mketrel.c new file mode 100644 index 0000000..aa0408a --- /dev/null +++ b/scripts/mketrel.c @@ -0,0 +1,70 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <elf.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <stdarg.h> +#include <stdlib.h> + +static int fd; +unsigned char e_ident[EI_NIDENT]; + +void die(const char * str, ...) +{ + va_list args; + va_start(args, str); + vfprintf(stderr, str, args); + fputc('\n', stderr); + exit(1); +} + +void file_open(const char *name) +{ + if ((fd = open(name, O_RDWR, 0)) < 0) + die("Unable to open `%s': %m", name); +} + +static void mketrel(void) +{ + unsigned char e_type[2]; + if (read(fd, &e_ident, sizeof(e_ident)) != sizeof(e_ident)) + die("Cannot read ELF header: %s\n", strerror(errno)); + + if (memcmp(e_ident, ELFMAG, 4) != 0) + die("No ELF magic\n"); + + if ((e_ident[EI_CLASS] != ELFCLASS64) && + (e_ident[EI_CLASS] != ELFCLASS32)) + die("Unrecognized ELF class: %x\n", e_ident[EI_CLASS]); + + if ((e_ident[EI_DATA] != ELFDATA2LSB) && + (e_ident[EI_DATA] != ELFDATA2MSB)) + die("Unrecognized ELF data encoding: %x\n", e_ident[EI_DATA]); + + if (e_ident[EI_VERSION] != EV_CURRENT) + die("Unknown ELF version: %d\n", e_ident[EI_VERSION]); + + if (e_ident[EI_DATA] == ELFDATA2LSB) { + e_type[0] = ET_DYN & 0xff; + e_type[1] = ET_DYN >> 8; + } else { + e_type[1] = ET_DYN & 0xff; + e_type[0] = ET_DYN >> 8; + } + + if (write(fd, &e_type, sizeof(e_type)) != sizeof(e_type)) + die("Cannot write ELF type: %s\n", strerror(errno)); +} + +int main(int argc, char **argv) +{ + if (argc != 2) + die("Usage: mketrel: vmlinux"); + file_open(argv[1]); + mketrel(); + close(fd); + return 0; +} -- 1.5.1.1.181.g2de0 _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
I believe this problem gets fixed by: http://cvs.fedoraproject.org/viewvc/rpms/gdb/devel/gdb-6.5-bz203661-emit-relocs.patch?content-type=text%2Fplain&view=co