aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/include/asm/elf.h48
-rw-r--r--arch/ia64/kernel/Makefile2
-rw-r--r--arch/ia64/kernel/elfcore.c64
3 files changed, 66 insertions, 48 deletions
diff --git a/arch/ia64/include/asm/elf.h b/arch/ia64/include/asm/elf.h
index 4c41656ede87..b5298eb09adb 100644
--- a/arch/ia64/include/asm/elf.h
+++ b/arch/ia64/include/asm/elf.h
@@ -219,54 +219,6 @@ do { \
219 NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR); \ 219 NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR); \
220} while (0) 220} while (0)
221 221
222
223/*
224 * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
225 * extra segments containing the gate DSO contents. Dumping its
226 * contents makes post-mortem fully interpretable later without matching up
227 * the same kernel and hardware config to see what PC values meant.
228 * Dumping its extra ELF program headers includes all the other information
229 * a debugger needs to easily find how the gate DSO was being used.
230 */
231#define ELF_CORE_EXTRA_PHDRS (GATE_EHDR->e_phnum)
232#define ELF_CORE_WRITE_EXTRA_PHDRS \
233do { \
234 const struct elf_phdr *const gate_phdrs = \
235 (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); \
236 int i; \
237 Elf64_Off ofs = 0; \
238 for (i = 0; i < GATE_EHDR->e_phnum; ++i) { \
239 struct elf_phdr phdr = gate_phdrs[i]; \
240 if (phdr.p_type == PT_LOAD) { \
241 phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \
242 phdr.p_filesz = phdr.p_memsz; \
243 if (ofs == 0) { \
244 ofs = phdr.p_offset = offset; \
245 offset += phdr.p_filesz; \
246 } \
247 else \
248 phdr.p_offset = ofs; \
249 } \
250 else \
251 phdr.p_offset += ofs; \
252 phdr.p_paddr = 0; /* match other core phdrs */ \
253 DUMP_WRITE(&phdr, sizeof(phdr)); \
254 } \
255} while (0)
256#define ELF_CORE_WRITE_EXTRA_DATA \
257do { \
258 const struct elf_phdr *const gate_phdrs = \
259 (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); \
260 int i; \
261 for (i = 0; i < GATE_EHDR->e_phnum; ++i) { \
262 if (gate_phdrs[i].p_type == PT_LOAD) { \
263 DUMP_WRITE((void *) gate_phdrs[i].p_vaddr, \
264 PAGE_ALIGN(gate_phdrs[i].p_memsz)); \
265 break; \
266 } \
267 } \
268} while (0)
269
270/* 222/*
271 * format for entries in the Global Offset Table 223 * format for entries in the Global Offset Table
272 */ 224 */
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 4138282aefa8..db10b1e378b0 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -45,6 +45,8 @@ endif
45obj-$(CONFIG_DMAR) += pci-dma.o 45obj-$(CONFIG_DMAR) += pci-dma.o
46obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o 46obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
47 47
48obj-$(CONFIG_BINFMT_ELF) += elfcore.o
49
48# fp_emulate() expects f2-f5,f16-f31 to contain the user-level state. 50# fp_emulate() expects f2-f5,f16-f31 to contain the user-level state.
49CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31 51CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31
50 52
diff --git a/arch/ia64/kernel/elfcore.c b/arch/ia64/kernel/elfcore.c
new file mode 100644
index 000000000000..57a2298a8581
--- /dev/null
+++ b/arch/ia64/kernel/elfcore.c
@@ -0,0 +1,64 @@
1#include <linux/elf.h>
2#include <linux/coredump.h>
3#include <linux/fs.h>
4#include <linux/mm.h>
5
6#include <asm/elf.h>
7
8
9Elf64_Half elf_core_extra_phdrs(void)
10{
11 return GATE_EHDR->e_phnum;
12}
13
14int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
15 unsigned long limit)
16{
17 const struct elf_phdr *const gate_phdrs =
18 (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
19 int i;
20 Elf64_Off ofs = 0;
21
22 for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
23 struct elf_phdr phdr = gate_phdrs[i];
24
25 if (phdr.p_type == PT_LOAD) {
26 phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz);
27 phdr.p_filesz = phdr.p_memsz;
28 if (ofs == 0) {
29 ofs = phdr.p_offset = offset;
30 offset += phdr.p_filesz;
31 } else {
32 phdr.p_offset = ofs;
33 }
34 } else {
35 phdr.p_offset += ofs;
36 }
37 phdr.p_paddr = 0; /* match other core phdrs */
38 *size += sizeof(phdr);
39 if (*size > limit || !dump_write(file, &phdr, sizeof(phdr)))
40 return 0;
41 }
42 return 1;
43}
44
45int elf_core_write_extra_data(struct file *file, size_t *size,
46 unsigned long limit)
47{
48 const struct elf_phdr *const gate_phdrs =
49 (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
50 int i;
51
52 for (i = 0; i < GATE_EHDR->e_phnum; ++i) {
53 if (gate_phdrs[i].p_type == PT_LOAD) {
54 void *addr = (void *)gate_phdrs[i].p_vaddr;
55 size_t memsz = PAGE_ALIGN(gate_phdrs[i].p_memsz);
56
57 *size += memsz;
58 if (*size > limit || !dump_write(file, addr, memsz))
59 return 0;
60 break;
61 }
62 }
63 return 1;
64}