Skip to content

Commit 1fcccba

Browse files
Daisuke HATAYAMAtorvalds
Daisuke HATAYAMA
authored andcommitted
elf coredump: replace ELF_CORE_EXTRA_* macros by functions
elf_core_dump() and elf_fdpic_core_dump() use #ifdef and the corresponding macro for hiding _multiline_ logics in functions. This patch removes #ifdef and replaces ELF_CORE_EXTRA_* by corresponding functions. For architectures not implemeonting ELF_CORE_EXTRA_*, we use weak functions in order to reduce a range of modification. This cleanup is for my next patches, but I think this cleanup itself is worth doing regardless of my firnal purpose. Signed-off-by: Daisuke HATAYAMA <[email protected]> Cc: "Luck, Tony" <[email protected]> Cc: Jeff Dike <[email protected]> Cc: David Howells <[email protected]> Cc: Greg Ungerer <[email protected]> Cc: Roland McGrath <[email protected]> Cc: Oleg Nesterov <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Alexander Viro <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Alan Cox <[email protected]> Cc: <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 088e7af commit 1fcccba

File tree

13 files changed

+191
-109
lines changed

13 files changed

+191
-109
lines changed

arch/ia64/include/asm/elf.h

-48
Original file line numberDiff line numberDiff line change
@@ -219,54 +219,6 @@ do { \
219219
NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR); \
220220
} while (0)
221221

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 \
233-
do { \
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 \
257-
do { \
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-
270222
/*
271223
* format for entries in the Global Offset Table
272224
*/

arch/ia64/kernel/Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ endif
4545
obj-$(CONFIG_DMAR) += pci-dma.o
4646
obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o
4747

48+
obj-$(CONFIG_BINFMT_ELF) += elfcore.o
49+
4850
# fp_emulate() expects f2-f5,f16-f31 to contain the user-level state.
4951
CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31
5052

arch/ia64/kernel/elfcore.c

+64
Original file line numberDiff line numberDiff line change
@@ -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+
9+
Elf64_Half elf_core_extra_phdrs(void)
10+
{
11+
return GATE_EHDR->e_phnum;
12+
}
13+
14+
int 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+
45+
int 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+
}

arch/um/sys-i386/Makefile

+2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
66
ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \
77
sys_call_table.o tls.o
88

9+
obj-$(CONFIG_BINFMT_ELF) += elfcore.o
10+
911
subarch-obj-y = lib/semaphore_32.o lib/string_32.o
1012
subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o
1113
subarch-obj-$(CONFIG_MODULES) += kernel/module.o

arch/um/sys-i386/asm/elf.h

-43
Original file line numberDiff line numberDiff line change
@@ -116,47 +116,4 @@ do { \
116116
} \
117117
} while (0)
118118

119-
/*
120-
* These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
121-
* extra segments containing the vsyscall DSO contents. Dumping its
122-
* contents makes post-mortem fully interpretable later without matching up
123-
* the same kernel and hardware config to see what PC values meant.
124-
* Dumping its extra ELF program headers includes all the other information
125-
* a debugger needs to easily find how the vsyscall DSO was being used.
126-
*/
127-
#define ELF_CORE_EXTRA_PHDRS \
128-
(vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0 )
129-
130-
#define ELF_CORE_WRITE_EXTRA_PHDRS \
131-
if ( vsyscall_ehdr ) { \
132-
const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr; \
133-
const struct elf_phdr *const phdrp = \
134-
(const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); \
135-
int i; \
136-
Elf32_Off ofs = 0; \
137-
for (i = 0; i < ehdrp->e_phnum; ++i) { \
138-
struct elf_phdr phdr = phdrp[i]; \
139-
if (phdr.p_type == PT_LOAD) { \
140-
ofs = phdr.p_offset = offset; \
141-
offset += phdr.p_filesz; \
142-
} \
143-
else \
144-
phdr.p_offset += ofs; \
145-
phdr.p_paddr = 0; /* match other core phdrs */ \
146-
DUMP_WRITE(&phdr, sizeof(phdr)); \
147-
} \
148-
}
149-
#define ELF_CORE_WRITE_EXTRA_DATA \
150-
if ( vsyscall_ehdr ) { \
151-
const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr; \
152-
const struct elf_phdr *const phdrp = \
153-
(const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); \
154-
int i; \
155-
for (i = 0; i < ehdrp->e_phnum; ++i) { \
156-
if (phdrp[i].p_type == PT_LOAD) \
157-
DUMP_WRITE((void *) phdrp[i].p_vaddr, \
158-
phdrp[i].p_filesz); \
159-
} \
160-
}
161-
162119
#endif

arch/um/sys-i386/elfcore.c

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
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+
9+
Elf32_Half elf_core_extra_phdrs(void)
10+
{
11+
return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0;
12+
}
13+
14+
int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
15+
unsigned long limit)
16+
{
17+
if ( vsyscall_ehdr ) {
18+
const struct elfhdr *const ehdrp =
19+
(struct elfhdr *) vsyscall_ehdr;
20+
const struct elf_phdr *const phdrp =
21+
(const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
22+
int i;
23+
Elf32_Off ofs = 0;
24+
25+
for (i = 0; i < ehdrp->e_phnum; ++i) {
26+
struct elf_phdr phdr = phdrp[i];
27+
28+
if (phdr.p_type == PT_LOAD) {
29+
ofs = phdr.p_offset = offset;
30+
offset += phdr.p_filesz;
31+
} else {
32+
phdr.p_offset += ofs;
33+
}
34+
phdr.p_paddr = 0; /* match other core phdrs */
35+
*size += sizeof(phdr);
36+
if (*size > limit
37+
|| !dump_write(file, &phdr, sizeof(phdr)))
38+
return 0;
39+
}
40+
}
41+
return 1;
42+
}
43+
44+
int elf_core_write_extra_data(struct file *file, size_t *size,
45+
unsigned long limit)
46+
{
47+
if ( vsyscall_ehdr ) {
48+
const struct elfhdr *const ehdrp =
49+
(struct elfhdr *) vsyscall_ehdr;
50+
const struct elf_phdr *const phdrp =
51+
(const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
52+
int i;
53+
54+
for (i = 0; i < ehdrp->e_phnum; ++i) {
55+
if (phdrp[i].p_type == PT_LOAD) {
56+
void *addr = (void *) phdrp[i].p_vaddr;
57+
size_t filesz = phdrp[i].p_filesz;
58+
59+
*size += filesz;
60+
if (*size > limit
61+
|| !dump_write(file, addr, filesz))
62+
return 0;
63+
}
64+
}
65+
}
66+
return 1;
67+
}

fs/binfmt_elf.c

+5-9
Original file line numberDiff line numberDiff line change
@@ -1878,9 +1878,7 @@ static int elf_core_dump(struct coredump_params *cprm)
18781878
* Please check DEFAULT_MAX_MAP_COUNT definition when you modify here.
18791879
*/
18801880
segs = current->mm->map_count;
1881-
#ifdef ELF_CORE_EXTRA_PHDRS
1882-
segs += ELF_CORE_EXTRA_PHDRS;
1883-
#endif
1881+
segs += elf_core_extra_phdrs();
18841882

18851883
gate_vma = get_gate_vma(current);
18861884
if (gate_vma != NULL)
@@ -1958,9 +1956,8 @@ static int elf_core_dump(struct coredump_params *cprm)
19581956
goto end_coredump;
19591957
}
19601958

1961-
#ifdef ELF_CORE_WRITE_EXTRA_PHDRS
1962-
ELF_CORE_WRITE_EXTRA_PHDRS;
1963-
#endif
1959+
if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit))
1960+
goto end_coredump;
19641961

19651962
/* write out the notes section */
19661963
if (!write_note_info(&info, cprm->file, &foffset))
@@ -1999,9 +1996,8 @@ static int elf_core_dump(struct coredump_params *cprm)
19991996
}
20001997
}
20011998

2002-
#ifdef ELF_CORE_WRITE_EXTRA_DATA
2003-
ELF_CORE_WRITE_EXTRA_DATA;
2004-
#endif
1999+
if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit))
2000+
goto end_coredump;
20052001

20062002
end_coredump:
20072003
set_fs(fs);

fs/binfmt_elf_fdpic.c

+5-9
Original file line numberDiff line numberDiff line change
@@ -1664,9 +1664,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
16641664
elf_core_copy_regs(&prstatus->pr_reg, cprm->regs);
16651665

16661666
segs = current->mm->map_count;
1667-
#ifdef ELF_CORE_EXTRA_PHDRS
1668-
segs += ELF_CORE_EXTRA_PHDRS;
1669-
#endif
1667+
segs += elf_core_extra_phdrs();
16701668

16711669
/* Set up header */
16721670
fill_elf_fdpic_header(elf, segs + 1); /* including notes section */
@@ -1773,9 +1771,8 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
17731771
goto end_coredump;
17741772
}
17751773

1776-
#ifdef ELF_CORE_WRITE_EXTRA_PHDRS
1777-
ELF_CORE_WRITE_EXTRA_PHDRS;
1778-
#endif
1774+
if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit))
1775+
goto end_coredump;
17791776

17801777
/* write out the notes section */
17811778
for (i = 0; i < numnote; i++)
@@ -1799,9 +1796,8 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
17991796
mm_flags) < 0)
18001797
goto end_coredump;
18011798

1802-
#ifdef ELF_CORE_WRITE_EXTRA_DATA
1803-
ELF_CORE_WRITE_EXTRA_DATA;
1804-
#endif
1799+
if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit))
1800+
goto end_coredump;
18051801

18061802
if (cprm->file->f_pos != offset) {
18071803
/* Sanity check */

fs/compat_binfmt_elf.c

+2
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@
2828

2929
#undef elfhdr
3030
#undef elf_phdr
31+
#undef elf_shdr
3132
#undef elf_note
3233
#undef elf_addr_t
3334
#define elfhdr elf32_hdr
3435
#define elf_phdr elf32_phdr
36+
#define elf_shdr elf32_shdr
3537
#define elf_note elf32_note
3638
#define elf_addr_t Elf32_Addr
3739

include/linux/elf.h

+2
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ extern Elf32_Dyn _DYNAMIC [];
396396
#define elf_phdr elf32_phdr
397397
#define elf_note elf32_note
398398
#define elf_addr_t Elf32_Off
399+
#define Elf_Half Elf32_Half
399400

400401
#else
401402

@@ -404,6 +405,7 @@ extern Elf64_Dyn _DYNAMIC [];
404405
#define elf_phdr elf64_phdr
405406
#define elf_note elf64_note
406407
#define elf_addr_t Elf64_Off
408+
#define Elf_Half Elf64_Half
407409

408410
#endif
409411

include/linux/elfcore.h

+16
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include <linux/user.h>
99
#endif
1010
#include <linux/ptrace.h>
11+
#include <linux/elf.h>
12+
#include <linux/fs.h>
1113

1214
struct elf_siginfo
1315
{
@@ -150,5 +152,19 @@ static inline int elf_core_copy_task_xfpregs(struct task_struct *t, elf_fpxregse
150152

151153
#endif /* __KERNEL__ */
152154

155+
/*
156+
* These functions parameterize elf_core_dump in fs/binfmt_elf.c to write out
157+
* extra segments containing the gate DSO contents. Dumping its
158+
* contents makes post-mortem fully interpretable later without matching up
159+
* the same kernel and hardware config to see what PC values meant.
160+
* Dumping its extra ELF program headers includes all the other information
161+
* a debugger needs to easily find how the gate DSO was being used.
162+
*/
163+
extern Elf_Half elf_core_extra_phdrs(void);
164+
extern int
165+
elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
166+
unsigned long limit);
167+
extern int
168+
elf_core_write_extra_data(struct file *file, size_t *size, unsigned long limit);
153169

154170
#endif /* _LINUX_ELFCORE_H */

kernel/Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
9191
obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
9292
obj-$(CONFIG_TRACEPOINTS) += tracepoint.o
9393
obj-$(CONFIG_LATENCYTOP) += latencytop.o
94+
obj-$(CONFIG_BINFMT_ELF) += elfcore.o
95+
obj-$(CONFIG_COMPAT_BINFMT_ELF) += elfcore.o
96+
obj-$(CONFIG_BINFMT_ELF_FDPIC) += elfcore.o
9497
obj-$(CONFIG_FUNCTION_TRACER) += trace/
9598
obj-$(CONFIG_TRACING) += trace/
9699
obj-$(CONFIG_X86_DS) += trace/

0 commit comments

Comments
 (0)