~ubuntu-branches/ubuntu/precise/makedumpfile/precise

« back to all changes in this revision

Viewing changes to .pc/0003-PATCH-BUGFIX-Avoid-SIGSEGV-when-specifying-V-option.patch/makedumpfile.c

  • Committer: Bazaar Package Importer
  • Author(s): John Wright
  • Date: 2011-04-26 20:05:16 UTC
  • mfrom: (1.1.4 upstream) (7.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20110426200516-7dzi6nnzouzfto2f
Tags: 1.3.7-2
* Cherry-pick upstream commits:
  - [PATCH] BUGFIX: Avoid SIGSEGV when specifying -V option.
    (5b8c2da75cbdb230019a3b956793fb768055b977)
  - [PATCH] Copy correct nr_cpus info to dumpfile during re-filtering.
    (c4f1c98a9827c1c0e41772c1954940fbf1b48048)
* kdump-tools.init: Don't exit with failure status except for bad
  usage.  This way, even if /etc/default/kdump-tools has USE_KDUMP=1
  but the kernel command line or debug kernels are not set up,
  installation of a new version of the package will not leave it
  unconfigured.  (Closes: #623470)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * makedumpfile.c
 
3
 *
 
4
 * Copyright (C) 2006, 2007, 2008, 2009  NEC Corporation
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or modify
 
7
 * it under the terms of the GNU General Public License as published by
 
8
 * the Free Software Foundation; either version 2 of the License, or
 
9
 * (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 */
 
16
#include "makedumpfile.h"
 
17
#include <sys/time.h>
 
18
 
 
19
struct symbol_table     symbol_table;
 
20
struct size_table       size_table;
 
21
struct offset_table     offset_table;
 
22
struct array_table      array_table;
 
23
struct number_table     number_table;
 
24
struct srcfile_table    srcfile_table;
 
25
 
 
26
struct dwarf_info       dwarf_info;
 
27
struct vm_table         vt = { 0 };
 
28
struct DumpInfo         *info = NULL;
 
29
 
 
30
char filename_stdout[] = FILENAME_STDOUT;
 
31
int message_level;
 
32
 
 
33
/*
 
34
 * Forward declarations
 
35
 */
 
36
void print_progress(const char          *msg,
 
37
                    unsigned long       current,
 
38
                    unsigned long       end);
 
39
 
 
40
/*
 
41
 * Message texts
 
42
 */
 
43
#define PROGRESS_COPY           "Copying data               "
 
44
#define PROGRESS_HOLES          "Checking for memory holes  "
 
45
#define PROGRESS_UNN_PAGES      "Excluding unnecessary pages"
 
46
#define PROGRESS_FREE_PAGES     "Excluding free pages       "
 
47
#define PROGRESS_ZERO_PAGES     "Excluding zero pages       "
 
48
#define PROGRESS_XEN_DOMAIN     "Excluding xen user domain  "
 
49
#define PROGRESS_MAXLEN         "35"
 
50
 
 
51
/*
 
52
 * The numbers of the excluded pages
 
53
 */
 
54
unsigned long long pfn_zero;
 
55
unsigned long long pfn_memhole;
 
56
unsigned long long pfn_cache;
 
57
unsigned long long pfn_cache_private;
 
58
unsigned long long pfn_user;
 
59
unsigned long long pfn_free;
 
60
 
 
61
int retcd = FAILED;     /* return code */
 
62
 
 
63
void
 
64
show_version(void)
 
65
{
 
66
        MSG("makedumpfile: version " VERSION " (released on " RELEASE_DATE ")\n");
 
67
        MSG("\n");
 
68
}
 
69
 
 
70
void
 
71
print_execution_time(char *step_name, struct timeval *tv_start)
 
72
{
 
73
        struct timeval tv_end;
 
74
        time_t diff_sec;
 
75
        suseconds_t diff_usec;
 
76
 
 
77
        gettimeofday(&tv_end, NULL);
 
78
 
 
79
        diff_sec  = tv_end.tv_sec - tv_start->tv_sec;
 
80
        diff_usec = tv_end.tv_usec - tv_start->tv_usec;
 
81
        if (diff_usec < 0) {
 
82
                diff_sec--;
 
83
                diff_usec += 1000000;
 
84
        }
 
85
        REPORT_MSG("STEP [%s] : %ld.%06ld seconds\n",
 
86
                   step_name, diff_sec, diff_usec);
 
87
}
 
88
 
 
89
#define INITIALIZE_LONG_TABLE(table, value) \
 
90
do { \
 
91
        size_member = sizeof(long); \
 
92
        num_member  = sizeof(table) / size_member; \
 
93
        ptr_long_table = (long *)&table; \
 
94
        for (i = 0; i < num_member; i++, ptr_long_table++) \
 
95
                *ptr_long_table = value; \
 
96
} while (0)
 
97
 
 
98
void
 
99
initialize_tables(void)
 
100
{
 
101
        int i, size_member, num_member;
 
102
        unsigned long long *ptr_symtable;
 
103
        long *ptr_long_table;
 
104
 
 
105
        /*
 
106
         * Initialize the symbol table.
 
107
         */
 
108
        size_member = sizeof(symbol_table.mem_map);
 
109
        num_member  = sizeof(symbol_table) / size_member;
 
110
 
 
111
        ptr_symtable = (unsigned long long *)&symbol_table;
 
112
 
 
113
        for (i = 0; i < num_member; i++, ptr_symtable++)
 
114
                *ptr_symtable = NOT_FOUND_SYMBOL;
 
115
 
 
116
        INITIALIZE_LONG_TABLE(size_table, NOT_FOUND_STRUCTURE);
 
117
        INITIALIZE_LONG_TABLE(offset_table, NOT_FOUND_STRUCTURE);
 
118
        INITIALIZE_LONG_TABLE(array_table, NOT_FOUND_STRUCTURE);
 
119
        INITIALIZE_LONG_TABLE(number_table, NOT_FOUND_NUMBER);
 
120
}
 
121
 
 
122
/*
 
123
 * Convert Physical Address to File Offset.
 
124
 *  If this function returns 0x0, File Offset isn't found.
 
125
 *  The File Offset 0x0 is in the ELF header.
 
126
 *  It is not in the memory image.
 
127
 */
 
128
off_t
 
129
paddr_to_offset(unsigned long long paddr)
 
130
{
 
131
        int i;
 
132
        off_t offset;
 
133
        struct pt_load_segment *pls;
 
134
 
 
135
        for (i = offset = 0; i < info->num_load_memory; i++) {
 
136
                pls = &info->pt_load_segments[i];
 
137
                if ((paddr >= pls->phys_start)
 
138
                    && (paddr < pls->phys_end)) {
 
139
                        offset = (off_t)(paddr - pls->phys_start) +
 
140
                                pls->file_offset;
 
141
                                break;
 
142
                }
 
143
        }
 
144
        return offset;
 
145
}
 
146
 
 
147
unsigned long long
 
148
vaddr_to_paddr_general(unsigned long long vaddr)
 
149
{
 
150
        int i;
 
151
        unsigned long long paddr = NOT_PADDR;
 
152
        struct pt_load_segment *pls;
 
153
 
 
154
        if (info->flag_refiltering)
 
155
                return NOT_PADDR;
 
156
 
 
157
        for (i = 0; i < info->num_load_memory; i++) {
 
158
                pls = &info->pt_load_segments[i];
 
159
                if ((vaddr >= pls->virt_start)
 
160
                    && (vaddr < pls->virt_end)) {
 
161
                        paddr = (off_t)(vaddr - pls->virt_start) +
 
162
                                pls->phys_start;
 
163
                                break;
 
164
                }
 
165
        }
 
166
        return paddr;
 
167
}
 
168
 
 
169
/*
 
170
 * This function is slow because it doesn't use the memory.
 
171
 * It is useful at few calls like get_str_osrelease_from_vmlinux().
 
172
 */
 
173
off_t
 
174
vaddr_to_offset_slow(int fd, char *filename, unsigned long long vaddr)
 
175
{
 
176
        off_t offset = 0;
 
177
        int i, phnum, num_load, flag_elf64, elf_format;
 
178
        Elf64_Phdr load64;
 
179
        Elf32_Phdr load32;
 
180
 
 
181
        elf_format = check_elf_format(fd, filename, &phnum, &num_load);
 
182
 
 
183
        if (elf_format == ELF64)
 
184
                flag_elf64 = TRUE;
 
185
        else if (elf_format == ELF32)
 
186
                flag_elf64 = FALSE;
 
187
        else
 
188
                return 0;
 
189
 
 
190
        for (i = 0; i < phnum; i++) {
 
191
                if (flag_elf64) { /* ELF64 */
 
192
                        if (!get_elf64_phdr(fd, filename, i, &load64)) {
 
193
                                ERRMSG("Can't find Phdr %d.\n", i);
 
194
                                return 0;
 
195
                        }
 
196
                        if (load64.p_type != PT_LOAD)
 
197
                                continue;
 
198
 
 
199
                        if ((vaddr < load64.p_vaddr)
 
200
                            || (load64.p_vaddr + load64.p_filesz <= vaddr))
 
201
                                continue;
 
202
 
 
203
                        offset = load64.p_offset + (vaddr - load64.p_vaddr);
 
204
                        break;
 
205
                } else {         /* ELF32 */
 
206
                        if (!get_elf32_phdr(fd, filename, i, &load32)) {
 
207
                                ERRMSG("Can't find Phdr %d.\n", i);
 
208
                                return 0;
 
209
                        }
 
210
                        if (load32.p_type != PT_LOAD)
 
211
                                continue;
 
212
 
 
213
                        if ((vaddr < load32.p_vaddr)
 
214
                            || (load32.p_vaddr + load32.p_filesz <= vaddr))
 
215
                                continue;
 
216
 
 
217
                        offset = load32.p_offset + (vaddr - load32.p_vaddr);
 
218
                        break;
 
219
                }
 
220
        }
 
221
 
 
222
        return offset;
 
223
}
 
224
 
 
225
/*
 
226
 * Translate a domain-0's physical address to machine address.
 
227
 */
 
228
unsigned long long
 
229
ptom_xen(unsigned long long paddr)
 
230
{
 
231
        unsigned long mfn;
 
232
        unsigned long long maddr, pfn, mfn_idx, frame_idx;
 
233
 
 
234
        pfn = paddr_to_pfn(paddr);
 
235
        mfn_idx   = pfn / MFNS_PER_FRAME;
 
236
        frame_idx = pfn % MFNS_PER_FRAME;
 
237
 
 
238
        if (mfn_idx >= info->p2m_frames) {
 
239
                ERRMSG("Invalid mfn_idx(%llu).\n", mfn_idx);
 
240
                return NOT_PADDR;
 
241
        }
 
242
        maddr = pfn_to_paddr(info->p2m_mfn_frame_list[mfn_idx])
 
243
                + sizeof(unsigned long) * frame_idx;
 
244
        if (!readmem(MADDR_XEN, maddr, &mfn, sizeof(mfn))) {
 
245
                ERRMSG("Can't get mfn.\n");
 
246
                return NOT_PADDR;
 
247
        }
 
248
        maddr  = pfn_to_paddr(mfn);
 
249
        maddr |= PAGEOFFSET(paddr);
 
250
 
 
251
        return maddr;
 
252
}
 
253
 
 
254
/*
 
255
 * Get the number of the page descriptors from the ELF info.
 
256
 */
 
257
int
 
258
get_max_mapnr(void)
 
259
{
 
260
        int i;
 
261
        unsigned long long max_paddr;
 
262
        struct pt_load_segment *pls;
 
263
 
 
264
        if (info->flag_refiltering) {
 
265
                info->max_mapnr = info->dh_memory->max_mapnr;
 
266
                return TRUE;
 
267
        }
 
268
 
 
269
        for (i = 0, max_paddr = 0; i < info->num_load_memory; i++) {
 
270
                pls = &info->pt_load_segments[i];
 
271
                if (max_paddr < pls->phys_end)
 
272
                        max_paddr = pls->phys_end;
 
273
        }
 
274
        info->max_mapnr = paddr_to_pfn(max_paddr);
 
275
 
 
276
        DEBUG_MSG("\n");
 
277
        DEBUG_MSG("max_mapnr    : %llx\n", info->max_mapnr);
 
278
 
 
279
        return TRUE;
 
280
}
 
281
 
 
282
/*
 
283
 * Get the number of the page descriptors for Xen.
 
284
 */
 
285
int
 
286
get_dom0_mapnr()
 
287
{
 
288
        unsigned long max_pfn;
 
289
 
 
290
        if (SYMBOL(max_pfn) == NOT_FOUND_SYMBOL)
 
291
                return FALSE;
 
292
 
 
293
        if (!readmem(VADDR, SYMBOL(max_pfn), &max_pfn, sizeof max_pfn))
 
294
                return FALSE;
 
295
 
 
296
        info->dom0_mapnr = max_pfn;
 
297
 
 
298
        return TRUE;
 
299
}
 
300
 
 
301
int
 
302
is_in_same_page(unsigned long vaddr1, unsigned long vaddr2)
 
303
{
 
304
        if (round(vaddr1, info->page_size) == round(vaddr2, info->page_size))
 
305
                return TRUE;
 
306
 
 
307
        return FALSE;
 
308
}
 
309
 
 
310
#define BITMAP_SECT_LEN 4096
 
311
static inline int is_dumpable(struct dump_bitmap *, unsigned long long);
 
312
unsigned long
 
313
pfn_to_pos(unsigned long long pfn)
 
314
{
 
315
        unsigned long desc_pos, i;
 
316
 
 
317
        desc_pos = info->valid_pages[pfn / BITMAP_SECT_LEN];
 
318
        for (i = round(pfn, BITMAP_SECT_LEN); i < pfn; i++)
 
319
                if (is_dumpable(info->bitmap_memory, i))
 
320
                        desc_pos++;
 
321
 
 
322
        return desc_pos;
 
323
}
 
324
 
 
325
int
 
326
read_page_desc(unsigned long long paddr, page_desc_t *pd)
 
327
{
 
328
        struct disk_dump_header *dh;
 
329
        unsigned long desc_pos;
 
330
        unsigned long long pfn;
 
331
        off_t offset;
 
332
 
 
333
        /*
 
334
         * Find page descriptor
 
335
         */
 
336
        dh = info->dh_memory;
 
337
        offset
 
338
            = (DISKDUMP_HEADER_BLOCKS + dh->sub_hdr_size + dh->bitmap_blocks)
 
339
                * dh->block_size;
 
340
        pfn = paddr_to_pfn(paddr);
 
341
        desc_pos = pfn_to_pos(pfn);
 
342
        offset += (off_t)desc_pos * sizeof(page_desc_t);
 
343
        if (lseek(info->fd_memory, offset, SEEK_SET) < 0) {
 
344
                ERRMSG("Can't seek %s. %s\n",
 
345
                                 info->name_memory, strerror(errno));
 
346
                return FALSE;
 
347
        }
 
348
 
 
349
        /*
 
350
         * Read page descriptor
 
351
         */
 
352
        if (read(info->fd_memory, pd, sizeof(*pd)) != sizeof(*pd)) {
 
353
                ERRMSG("Can't read %s. %s\n",
 
354
                                info->name_memory, strerror(errno));
 
355
                return FALSE;
 
356
        }
 
357
 
 
358
        /*
 
359
         * Sanity check
 
360
         */
 
361
        if (pd->size > dh->block_size)
 
362
                return FALSE;
 
363
 
 
364
        return TRUE;
 
365
}
 
366
 
 
367
int
 
368
readpmem_kdump_compressed(unsigned long long paddr, void *bufptr, size_t size)
 
369
{
 
370
        page_desc_t pd;
 
371
        char buf[info->page_size];
 
372
        char buf2[info->page_size];
 
373
        int ret;
 
374
        unsigned long retlen, page_offset;
 
375
 
 
376
        page_offset = paddr % info->page_size;
 
377
 
 
378
        if (!is_dumpable(info->bitmap_memory, paddr_to_pfn(paddr))) {
 
379
                ERRMSG("pfn(%llx) is excluded from %s.\n",
 
380
                                paddr_to_pfn(paddr), info->name_memory);
 
381
                goto error;
 
382
        }
 
383
 
 
384
        if (!read_page_desc(paddr, &pd)) {
 
385
                ERRMSG("Can't read page_desc: %llx\n", paddr);
 
386
                goto error;
 
387
        }
 
388
 
 
389
        if (lseek(info->fd_memory, pd.offset, SEEK_SET) < 0) {
 
390
                ERRMSG("Can't seek %s. %s\n",
 
391
                                info->name_memory, strerror(errno));
 
392
                goto error;
 
393
        }
 
394
 
 
395
        /*
 
396
         * Read page data
 
397
         */
 
398
        if (read(info->fd_memory, buf, pd.size) != pd.size) {
 
399
                ERRMSG("Can't read %s. %s\n",
 
400
                                info->name_memory, strerror(errno));
 
401
                goto error;
 
402
        }
 
403
 
 
404
        if (pd.flags & DUMP_DH_COMPRESSED) {
 
405
                retlen = info->page_size;
 
406
                ret = uncompress((unsigned char *)buf2, &retlen,
 
407
                                        (unsigned char *)buf, pd.size);
 
408
                if ((ret != Z_OK) || (retlen != info->page_size)) {
 
409
                        ERRMSG("Uncompress failed: %d\n", ret);
 
410
                        goto error;
 
411
                }
 
412
                memcpy(bufptr, buf2 + page_offset, size);
 
413
        } else
 
414
                memcpy(bufptr, buf + page_offset, size);
 
415
 
 
416
        return size;
 
417
error:
 
418
        ERRMSG("type_addr: %d, addr:%llx, size:%zd\n", PADDR, paddr, size);
 
419
        return FALSE;
 
420
}
 
421
 
 
422
int
 
423
readmem(int type_addr, unsigned long long addr, void *bufptr, size_t size)
 
424
{
 
425
        size_t read_size, next_size;
 
426
        off_t offset = 0;
 
427
        unsigned long long next_addr;
 
428
        unsigned long long paddr, maddr = NOT_PADDR;
 
429
        char *next_ptr;
 
430
        const off_t failed = (off_t)-1;
 
431
 
 
432
        switch (type_addr) {
 
433
        case VADDR:
 
434
                if ((paddr = vaddr_to_paddr(addr)) == NOT_PADDR) {
 
435
                        ERRMSG("Can't convert a virtual address(%llx) to physical address.\n",
 
436
                            addr);
 
437
                        goto error;
 
438
                }
 
439
                if (vt.mem_flags & MEMORY_XEN) {
 
440
                        if ((maddr = ptom_xen(paddr)) == NOT_PADDR) {
 
441
                                ERRMSG("Can't convert a physical address(%llx) to machine address.\n",
 
442
                                    paddr);
 
443
                                return FALSE;
 
444
                        }
 
445
                        paddr = maddr;
 
446
                }
 
447
                break;
 
448
        case PADDR:
 
449
                paddr = addr;
 
450
                if (vt.mem_flags & MEMORY_XEN) {
 
451
                        if ((maddr  = ptom_xen(paddr)) == NOT_PADDR) {
 
452
                                ERRMSG("Can't convert a physical address(%llx) to machine address.\n",
 
453
                                    paddr);
 
454
                                return FALSE;
 
455
                        }
 
456
                        paddr = maddr;
 
457
                }
 
458
                break;
 
459
        case VADDR_XEN:
 
460
                if ((paddr = kvtop_xen(addr)) == NOT_PADDR) {
 
461
                        ERRMSG("Can't convert a virtual address(%llx) to machine address.\n",
 
462
                            addr);
 
463
                        goto error;
 
464
                }
 
465
                break;
 
466
        case MADDR_XEN:
 
467
                paddr = addr;
 
468
                break;
 
469
        default:
 
470
                ERRMSG("Invalid address type (%d).\n", type_addr);
 
471
                goto error;
 
472
        }
 
473
 
 
474
        read_size = size;
 
475
 
 
476
        /*
 
477
         * Read each page, because pages are not necessarily continuous.
 
478
         * Ex) pages in vmalloc area
 
479
         */
 
480
        if (!is_in_same_page(addr, addr + size - 1)) {
 
481
                read_size = info->page_size - (addr % info->page_size);
 
482
                next_addr = roundup(addr + 1, info->page_size);
 
483
                next_size = size - read_size;
 
484
                next_ptr  = (char *)bufptr + read_size;
 
485
 
 
486
                if (!readmem(type_addr, next_addr, next_ptr, next_size))
 
487
                        goto error;
 
488
        }
 
489
 
 
490
        if (info->flag_refiltering)
 
491
                return readpmem_kdump_compressed(paddr, bufptr, read_size);
 
492
 
 
493
        if (!(offset = paddr_to_offset(paddr))) {
 
494
                ERRMSG("Can't convert a physical address(%llx) to offset.\n",
 
495
                    paddr);
 
496
                goto error;
 
497
        }
 
498
 
 
499
        if (lseek(info->fd_memory, offset, SEEK_SET) == failed) {
 
500
                ERRMSG("Can't seek the dump memory(%s). (offset: %llx) %s\n",
 
501
                    info->name_memory, offset, strerror(errno));
 
502
                goto error;
 
503
        }
 
504
 
 
505
        if (read(info->fd_memory, bufptr, read_size) != read_size) {
 
506
                ERRMSG("Can't read the dump memory(%s). %s\n",
 
507
                    info->name_memory, strerror(errno));
 
508
                goto error;
 
509
        }
 
510
 
 
511
        return size;
 
512
error:
 
513
        ERRMSG("type_addr: %d, addr:%llx, size:%zd\n", type_addr, addr, size);
 
514
        return FALSE;
 
515
}
 
516
 
 
517
int32_t
 
518
get_kernel_version(char *release)
 
519
{
 
520
        int32_t version;
 
521
        long maj, min, rel;
 
522
        char *start, *end;
 
523
 
 
524
        /*
 
525
         * This method checks that vmlinux and vmcore are same kernel version.
 
526
         */
 
527
        start = release;
 
528
        maj = strtol(start, &end, 10);
 
529
        if (maj == LONG_MAX)
 
530
                return FALSE;
 
531
 
 
532
        start = end + 1;
 
533
        min = strtol(start, &end, 10);
 
534
        if (min == LONG_MAX)
 
535
                return FALSE;
 
536
 
 
537
        start = end + 1;
 
538
        rel = strtol(start, &end, 10);
 
539
        if (rel == LONG_MAX)
 
540
                return FALSE;
 
541
 
 
542
        version = KERNEL_VERSION(maj, min, rel);
 
543
 
 
544
        if ((version < OLDEST_VERSION) || (LATEST_VERSION < version)) {
 
545
                MSG("The kernel version is not supported.\n");
 
546
                MSG("The created dumpfile may be incomplete.\n");
 
547
        }
 
548
        return version;
 
549
}
 
550
 
 
551
int
 
552
is_page_size(long page_size)
 
553
{
 
554
        /*
 
555
         * Page size is restricted to a hamming weight of 1.
 
556
         */
 
557
        if (page_size > 0 && !(page_size & (page_size - 1)))
 
558
                return TRUE;
 
559
 
 
560
        return FALSE;
 
561
}
 
562
 
 
563
int
 
564
set_page_size(long page_size)
 
565
{
 
566
        if (!is_page_size(page_size)) {
 
567
                ERRMSG("Invalid page_size: %ld", page_size);
 
568
                return FALSE;
 
569
        }
 
570
        info->page_size = page_size;
 
571
        info->page_shift = ffs(info->page_size) - 1;
 
572
        DEBUG_MSG("page_size    : %ld\n", info->page_size);
 
573
 
 
574
        return TRUE;
 
575
}
 
576
 
 
577
int
 
578
fallback_to_current_page_size(void)
 
579
{
 
580
 
 
581
        if (!set_page_size(sysconf(_SC_PAGE_SIZE)))
 
582
                return FALSE;
 
583
 
 
584
        DEBUG_MSG("WARNING: Cannot determine page size (no vmcoreinfo).\n");
 
585
        DEBUG_MSG("Using the dump kernel page size: %ld\n",
 
586
            info->page_size);
 
587
 
 
588
        return TRUE;
 
589
}
 
590
 
 
591
int
 
592
check_release(void)
 
593
{
 
594
        unsigned long utsname;
 
595
 
 
596
        /*
 
597
         * Get the kernel version.
 
598
         */
 
599
        if (SYMBOL(system_utsname) != NOT_FOUND_SYMBOL) {
 
600
                utsname = SYMBOL(system_utsname);
 
601
        } else if (SYMBOL(init_uts_ns) != NOT_FOUND_SYMBOL) {
 
602
                utsname = SYMBOL(init_uts_ns) + sizeof(int);
 
603
        } else {
 
604
                ERRMSG("Can't get the symbol of system_utsname.\n");
 
605
                return FALSE;
 
606
        }
 
607
        if (!readmem(VADDR, utsname, &info->system_utsname,
 
608
                                        sizeof(struct utsname))) {
 
609
                ERRMSG("Can't get the address of system_utsname.\n");
 
610
                return FALSE;
 
611
        }
 
612
 
 
613
        if (info->flag_read_vmcoreinfo) {
 
614
                if (strcmp(info->system_utsname.release, info->release)) {
 
615
                        ERRMSG("%s and %s don't match.\n",
 
616
                            info->name_vmcoreinfo, info->name_memory);
 
617
                        retcd = WRONG_RELEASE;
 
618
                        return FALSE;
 
619
                }
 
620
        }
 
621
 
 
622
        info->kernel_version = get_kernel_version(info->system_utsname.release);
 
623
        if (info->kernel_version == FALSE) {
 
624
                ERRMSG("Can't get the kernel version.\n");
 
625
                return FALSE;
 
626
        }
 
627
 
 
628
        return TRUE;
 
629
}
 
630
 
 
631
void
 
632
print_usage(void)
 
633
{
 
634
        MSG("\n");
 
635
        MSG("Usage:\n");
 
636
        MSG("  Creating DUMPFILE:\n");
 
637
        MSG("  # makedumpfile    [-c|-E] [-d DL] [-x VMLINUX|-i VMCOREINFO] VMCORE DUMPFILE\n");
 
638
        MSG("\n");
 
639
        MSG("  Outputting the dump data in the flattened format to the standard output:\n");
 
640
        MSG("  # makedumpfile -F [-c|-E] [-d DL] [-x VMLINUX|-i VMCOREINFO] VMCORE\n");
 
641
        MSG("\n");
 
642
        MSG("  Rearranging the dump data in the flattened format to a readable DUMPFILE:\n");
 
643
        MSG("  # makedumpfile -R DUMPFILE\n");
 
644
        MSG("\n");
 
645
        MSG("  Split the dump data to multiple DUMPFILEs in parallel:\n");
 
646
        MSG("  # makedumpfile --split [OPTION] [-x VMLINUX|-i VMCOREINFO] VMCORE DUMPFILE1\n");
 
647
        MSG("    DUMPFILE2 [DUMPFILE3 ..]\n");
 
648
        MSG("\n");
 
649
        MSG("  Reassemble multiple DUMPFILEs:\n");
 
650
        MSG("  # makedumpfile --reassemble DUMPFILE1 DUMPFILE2 [DUMPFILE3 ..] DUMPFILE\n");
 
651
        MSG("\n");
 
652
        MSG("  Generating VMCOREINFO:\n");
 
653
        MSG("  # makedumpfile -g VMCOREINFO -x VMLINUX\n");
 
654
        MSG("\n");
 
655
        MSG("  Extracting the dmesg log from a VMCORE:\n");
 
656
        MSG("  # makedumpfile --dump-dmesg [-x VMLINUX|-i VMCOREINFO] VMCORE LOGFILE\n");
 
657
        MSG("\n");
 
658
        MSG("\n");
 
659
        MSG("  Creating DUMPFILE of Xen:\n");
 
660
        MSG("  # makedumpfile -E [--xen-syms XEN-SYMS|--xen-vmcoreinfo VMCOREINFO] VMCORE DUMPFILE\n");
 
661
        MSG("\n");
 
662
        MSG("  Generating VMCOREINFO of Xen:\n");
 
663
        MSG("  # makedumpfile -g VMCOREINFO --xen-syms XEN-SYMS\n");
 
664
        MSG("\n");
 
665
        MSG("\n");
 
666
        MSG("Available options:\n");
 
667
        MSG("  [-c]:\n");
 
668
        MSG("      Compress dump data by each page.\n");
 
669
        MSG("      A user cannot specify this option with -E option, because the ELF format\n");
 
670
        MSG("      does not support compressed data.\n");
 
671
        MSG("      THIS IS ONLY FOR THE CRASH UTILITY.\n");
 
672
        MSG("\n");
 
673
        MSG("  [-d DL]:\n");
 
674
        MSG("      Specify the type of unnecessary page for analysis.\n");
 
675
        MSG("      Pages of the specified type are not copied to DUMPFILE. The page type\n");
 
676
        MSG("      marked in the following table is excluded. A user can specify multiple\n");
 
677
        MSG("      page types by setting the sum of each page type for Dump_Level (DL).\n");
 
678
        MSG("      The maximum of Dump_Level is 31.\n");
 
679
        MSG("      Note that Dump_Level for Xen dump filtering is 0 or 1.\n");
 
680
        MSG("\n");
 
681
        MSG("      Dump  |  zero   cache   cache    user    free\n");
 
682
        MSG("      Level |  page   page    private  data    page\n");
 
683
        MSG("     -------+---------------------------------------\n");
 
684
        MSG("         0  |\n");
 
685
        MSG("         1  |  X\n");
 
686
        MSG("         2  |         X\n");
 
687
        MSG("         4  |         X       X\n");
 
688
        MSG("         8  |                          X\n");
 
689
        MSG("        16  |                                  X\n");
 
690
        MSG("        31  |  X      X       X        X       X\n");
 
691
        MSG("\n");
 
692
        MSG("  [-E]:\n");
 
693
        MSG("      Create DUMPFILE in the ELF format.\n");
 
694
        MSG("      This option cannot be specified with -c option, because the ELF\n");
 
695
        MSG("      format does not support compressed data.\n");
 
696
        MSG("\n");
 
697
        MSG("  [-x VMLINUX]:\n");
 
698
        MSG("      Specify the first kernel's VMLINUX to analyze the first kernel's\n");
 
699
        MSG("      memory usage.\n");
 
700
        MSG("      The page size of the first kernel and the second kernel should match.\n");
 
701
        MSG("\n");
 
702
        MSG("  [-i VMCOREINFO]:\n");
 
703
        MSG("      Specify VMCOREINFO instead of VMLINUX for analyzing the first kernel's\n");
 
704
        MSG("      memory usage.\n");
 
705
        MSG("      VMCOREINFO should be made beforehand by makedumpfile with -g option,\n");
 
706
        MSG("      and it contains the first kernel's information. This option is necessary\n");
 
707
        MSG("      if VMCORE does not contain VMCOREINFO, [-x VMLINUX] is not specified,\n");
 
708
        MSG("      and dump_level is 2 or more.\n");
 
709
        MSG("\n");
 
710
        MSG("  [-g VMCOREINFO]:\n");
 
711
        MSG("      Generate VMCOREINFO from the first kernel's VMLINUX.\n");
 
712
        MSG("      VMCOREINFO must be generated on the system that is running the first\n");
 
713
        MSG("      kernel. With -i option, a user can specify VMCOREINFO generated on the\n");
 
714
        MSG("      other system that is running the same first kernel. [-x VMLINUX] must\n");
 
715
        MSG("      be specified.\n");
 
716
        MSG("\n");
 
717
        MSG("  [-F]:\n");
 
718
        MSG("      Output the dump data in the flattened format to the standard output\n");
 
719
        MSG("      for transporting the dump data by SSH.\n");
 
720
        MSG("      Analysis tools cannot read the flattened format directly. For analysis,\n");
 
721
        MSG("      the dump data in the flattened format should be rearranged to a readable\n");
 
722
        MSG("      DUMPFILE by -R option.\n");
 
723
        MSG("\n");
 
724
        MSG("  [-R]:\n");
 
725
        MSG("      Rearrange the dump data in the flattened format from the standard input\n");
 
726
        MSG("      to a readable DUMPFILE.\n");
 
727
        MSG("\n");
 
728
        MSG("  [--split]:\n");
 
729
        MSG("      Split the dump data to multiple DUMPFILEs in parallel. If specifying\n");
 
730
        MSG("      DUMPFILEs on different storage devices, a device can share I/O load with\n");
 
731
        MSG("      other devices and it reduces time for saving the dump data. The file size\n");
 
732
        MSG("      of each DUMPFILE is smaller than the system memory size which is divided\n");
 
733
        MSG("      by the number of DUMPFILEs.\n");
 
734
        MSG("      This feature supports only the kdump-compressed format.\n");
 
735
        MSG("\n");
 
736
        MSG("  [--reassemble]:\n");
 
737
        MSG("      Reassemble multiple DUMPFILEs, which are created by --split option,\n");
 
738
        MSG("      into one DUMPFILE. dumpfile1 and dumpfile2 are reassembled into dumpfile.\n");
 
739
        MSG("\n");
 
740
        MSG("  [--xen-syms XEN-SYMS]:\n");
 
741
        MSG("      Specify the XEN-SYMS to analyze Xen's memory usage.\n");
 
742
        MSG("\n");
 
743
        MSG("  [--xen-vmcoreinfo VMCOREINFO]:\n");
 
744
        MSG("      Specify the VMCOREINFO of Xen to analyze Xen's memory usage.\n");
 
745
        MSG("\n");
 
746
        MSG("  [--xen_phys_start XEN_PHYS_START_ADDRESS]:\n");
 
747
        MSG("      This option is only for x86_64.\n");
 
748
        MSG("      Specify the XEN_PHYS_START_ADDRESS, if the xen code/data is relocatable\n");
 
749
        MSG("      and VMCORE does not contain XEN_PHYS_START_ADDRESS in the CRASHINFO.\n");
 
750
        MSG("\n");
 
751
        MSG("  [-X]:\n");
 
752
        MSG("      Exclude all the user domain pages from Xen kdump's VMCORE, and extract\n");
 
753
        MSG("      the part of Xen and domain-0.\n");
 
754
        MSG("\n");
 
755
        MSG("  [--message-level ML]:\n");
 
756
        MSG("      Specify the message types.\n");
 
757
        MSG("      Users can restrict output printed by specifying Message_Level (ML) with\n");
 
758
        MSG("      this option. The message type marked with an X in the following table is\n");
 
759
        MSG("      printed. For example, according to the table, specifying 7 as ML means\n");
 
760
        MSG("      progress indicator, common message, and error message are printed, and\n");
 
761
        MSG("      this is a default value.\n");
 
762
        MSG("      Note that the maximum value of message_level is 31.\n");
 
763
        MSG("\n");
 
764
        MSG("      Message | progress    common    error     debug     report\n");
 
765
        MSG("      Level   | indicator   message   message   message   message\n");
 
766
        MSG("     ---------+------------------------------------------------------\n");
 
767
        MSG("            0 |\n");
 
768
        MSG("            1 |     X\n");
 
769
        MSG("            2 |                X\n");
 
770
        MSG("            4 |                          X\n");
 
771
        MSG("          * 7 |     X          X         X\n");
 
772
        MSG("            8 |                                    X\n");
 
773
        MSG("           16 |                                              X\n");
 
774
        MSG("           31 |     X          X         X         X         X\n");
 
775
        MSG("\n");
 
776
        MSG("  [--vtop VIRTUAL_ADDRESS]:\n");
 
777
        MSG("      This option is useful, when user debugs the translation problem\n");
 
778
        MSG("      of virtual address. If specifing the VIRTUAL_ADDRESS, its physical\n");
 
779
        MSG("      address is printed.\n");
 
780
        MSG("\n");
 
781
        MSG("  [--dump-dmesg]:\n");
 
782
        MSG("      This option overrides the normal behavior of makedumpfile. Instead of\n");
 
783
        MSG("      compressing and filtering a VMCORE to make it smaller, it simply\n");
 
784
        MSG("      extracts the dmesg log from a VMCORE and writes it to the specified\n");
 
785
        MSG("      LOGFILE. If a VMCORE does not contain VMCOREINFO for dmesg, it is\n");
 
786
        MSG("      necessary to specfiy [-x VMLINUX] or [-i VMCOREINFO].\n");
 
787
        MSG("\n");
 
788
        MSG("  [-D]:\n");
 
789
        MSG("      Print debugging message.\n");
 
790
        MSG("\n");
 
791
        MSG("  [-f]:\n");
 
792
        MSG("      Overwrite DUMPFILE even if it already exists.\n");
 
793
        MSG("\n");
 
794
        MSG("  [-h]:\n");
 
795
        MSG("      Show help message.\n");
 
796
        MSG("\n");
 
797
        MSG("  [-b <order>]\n");
 
798
        MSG("      Specify the cache 2^order pages in ram when generating vmcore info\n");
 
799
        MSG("      before writing to output\n");
 
800
        MSG("\n");
 
801
        MSG("  [-v]:\n");
 
802
        MSG("      Show the version of makedumpfile.\n");
 
803
        MSG("\n");
 
804
        MSG("  VMLINUX:\n");
 
805
        MSG("      This is a pathname to the first kernel's vmlinux.\n");
 
806
        MSG("      This file must have the debug information of the first kernel to analyze\n");
 
807
        MSG("      the first kernel's memory usage.\n");
 
808
        MSG("\n");
 
809
        MSG("  VMCORE:\n");
 
810
        MSG("      This is a pathname to the first kernel's memory core image.\n");
 
811
        MSG("      This argument is generally /proc/vmcore.\n");
 
812
        MSG("\n");
 
813
        MSG("  DUMPFILE:\n");
 
814
        MSG("      This is a pathname to a file created by this command.\n");
 
815
        MSG("\n");
 
816
        MSG("  XEN-SYMS:\n");
 
817
        MSG("      This is a pathname to the xen-syms.\n");
 
818
        MSG("      This file must have the debug information of Xen to analyze\n");
 
819
        MSG("      Xen's memory usage.\n");
 
820
        MSG("\n");
 
821
}
 
822
 
 
823
int
 
824
open_vmcoreinfo(char *mode)
 
825
{
 
826
        FILE *file_vmcoreinfo;
 
827
 
 
828
        if ((file_vmcoreinfo = fopen(info->name_vmcoreinfo, mode)) == NULL) {
 
829
                ERRMSG("Can't open the vmcoreinfo file(%s). %s\n",
 
830
                    info->name_vmcoreinfo, strerror(errno));
 
831
                return FALSE;
 
832
        }
 
833
        info->file_vmcoreinfo = file_vmcoreinfo;
 
834
        return TRUE;
 
835
}
 
836
 
 
837
int
 
838
open_kernel_file(void)
 
839
{
 
840
        int fd;
 
841
 
 
842
        if (info->name_vmlinux) {
 
843
                if ((fd = open(info->name_vmlinux, O_RDONLY)) < 0) {
 
844
                        ERRMSG("Can't open the kernel file(%s). %s\n",
 
845
                            info->name_vmlinux, strerror(errno));
 
846
                        return FALSE;
 
847
                }
 
848
                info->fd_vmlinux = fd;
 
849
        }
 
850
        if (info->name_xen_syms) {
 
851
                if ((fd = open(info->name_xen_syms, O_RDONLY)) < 0) {
 
852
                        ERRMSG("Can't open the kernel file(%s). %s\n",
 
853
                            info->name_xen_syms, strerror(errno));
 
854
                        return FALSE;
 
855
                }
 
856
                info->fd_xen_syms = fd;
 
857
        }
 
858
        return TRUE;
 
859
}
 
860
 
 
861
int
 
862
check_kdump_compressed(char *filename)
 
863
{
 
864
        struct disk_dump_header dh;
 
865
 
 
866
        if (!__read_disk_dump_header(&dh, filename))
 
867
                return ERROR;
 
868
 
 
869
        if (strncmp(dh.signature, KDUMP_SIGNATURE, SIG_LEN))
 
870
                return FALSE;
 
871
 
 
872
        return TRUE;
 
873
}
 
874
 
 
875
int
 
876
get_kdump_compressed_header_info(char *filename)
 
877
{
 
878
        struct disk_dump_header dh;
 
879
        struct kdump_sub_header kh;
 
880
 
 
881
        if (!read_disk_dump_header(&dh, filename))
 
882
                return FALSE;
 
883
 
 
884
        if (!read_kdump_sub_header(&kh, filename))
 
885
                return FALSE;
 
886
 
 
887
        if (dh.header_version < 1) {
 
888
                ERRMSG("header does not have dump_level member\n");
 
889
                return FALSE;
 
890
        }
 
891
        DEBUG_MSG("diskdump main header\n");
 
892
        DEBUG_MSG("  signature        : %s\n", dh.signature);
 
893
        DEBUG_MSG("  header_version   : %d\n", dh.header_version);
 
894
        DEBUG_MSG("  status           : %d\n", dh.status);
 
895
        DEBUG_MSG("  block_size       : %d\n", dh.block_size);
 
896
        DEBUG_MSG("  sub_hdr_size     : %d\n", dh.sub_hdr_size);
 
897
        DEBUG_MSG("  bitmap_blocks    : %d\n", dh.bitmap_blocks);
 
898
        DEBUG_MSG("  max_mapnr        : 0x%x\n", dh.max_mapnr);
 
899
        DEBUG_MSG("  total_ram_blocks : %d\n", dh.total_ram_blocks);
 
900
        DEBUG_MSG("  device_blocks    : %d\n", dh.device_blocks);
 
901
        DEBUG_MSG("  written_blocks   : %d\n", dh.written_blocks);
 
902
        DEBUG_MSG("  current_cpu      : %d\n", dh.current_cpu);
 
903
        DEBUG_MSG("  nr_cpus          : %d\n", dh.nr_cpus);
 
904
        DEBUG_MSG("kdump sub header\n");
 
905
        DEBUG_MSG("  phys_base        : 0x%lx\n", kh.phys_base);
 
906
        DEBUG_MSG("  dump_level       : %d\n", kh.dump_level);
 
907
        DEBUG_MSG("  split            : %d\n", kh.split);
 
908
        DEBUG_MSG("  start_pfn        : 0x%lx\n", kh.start_pfn);
 
909
        DEBUG_MSG("  end_pfn          : 0x%lx\n", kh.end_pfn);
 
910
 
 
911
        info->dh_memory = malloc(sizeof(dh));
 
912
        if (info->dh_memory == NULL) {
 
913
                ERRMSG("Can't allocate memory for the header. %s\n",
 
914
                    strerror(errno));
 
915
                return FALSE;
 
916
        }
 
917
        memcpy(info->dh_memory, &dh, sizeof(dh));
 
918
        memcpy(&info->timestamp, &dh.timestamp, sizeof(dh.timestamp));
 
919
 
 
920
        info->kh_memory = malloc(sizeof(kh));
 
921
        if (info->kh_memory == NULL) {
 
922
                ERRMSG("Can't allocate memory for the sub header. %s\n",
 
923
                    strerror(errno));
 
924
                goto error;
 
925
        }
 
926
        memcpy(info->kh_memory, &kh, sizeof(kh));
 
927
 
 
928
        if (dh.header_version >= 3) {
 
929
                /* A dumpfile contains vmcoreinfo data. */
 
930
                info->offset_vmcoreinfo = kh.offset_vmcoreinfo;
 
931
                info->size_vmcoreinfo   = kh.size_vmcoreinfo;
 
932
        }
 
933
        if (dh.header_version >= 4) {
 
934
                /* A dumpfile contains ELF note section. */
 
935
                info->offset_note = kh.offset_note;
 
936
                info->size_note   = kh.size_note;
 
937
        }
 
938
        return TRUE;
 
939
error:
 
940
        free(info->dh_memory);
 
941
        info->dh_memory = NULL;
 
942
 
 
943
        return FALSE;
 
944
}
 
945
 
 
946
int
 
947
open_dump_memory(void)
 
948
{
 
949
        int fd, status;
 
950
 
 
951
        if ((fd = open(info->name_memory, O_RDONLY)) < 0) {
 
952
                ERRMSG("Can't open the dump memory(%s). %s\n",
 
953
                    info->name_memory, strerror(errno));
 
954
                return FALSE;
 
955
        }
 
956
        info->fd_memory = fd;
 
957
 
 
958
        status = check_kdump_compressed(info->name_memory);
 
959
        if (status == TRUE) {
 
960
                info->flag_refiltering = TRUE;
 
961
                return get_kdump_compressed_header_info(info->name_memory);
 
962
        } else if (status == FALSE) {
 
963
                return TRUE;
 
964
        } else {
 
965
                return FALSE;
 
966
        }
 
967
}
 
968
 
 
969
int
 
970
open_dump_file(void)
 
971
{
 
972
        int fd;
 
973
        int open_flags = O_RDWR|O_CREAT|O_TRUNC;
 
974
 
 
975
        if (!info->flag_force)
 
976
                open_flags |= O_EXCL;
 
977
 
 
978
        if (info->flag_flatten) {
 
979
                fd = STDOUT_FILENO;
 
980
                info->name_dumpfile = filename_stdout;
 
981
        } else if ((fd = open(info->name_dumpfile, open_flags,
 
982
            S_IRUSR|S_IWUSR)) < 0) {
 
983
                ERRMSG("Can't open the dump file(%s). %s\n",
 
984
                    info->name_dumpfile, strerror(errno));
 
985
                return FALSE;
 
986
        }
 
987
        info->fd_dumpfile = fd;
 
988
        return TRUE;
 
989
}
 
990
 
 
991
int
 
992
open_dump_bitmap(void)
 
993
{
 
994
        int i, fd;
 
995
        char *tmpname;
 
996
 
 
997
        tmpname = getenv("TMPDIR");
 
998
        if (!tmpname)
 
999
                tmpname = "/tmp";
 
1000
 
 
1001
        if ((info->name_bitmap = (char *)malloc(sizeof(FILENAME_BITMAP) +
 
1002
                                                strlen(tmpname) + 1)) == NULL) {
 
1003
                ERRMSG("Can't allocate memory for the filename. %s\n",
 
1004
                    strerror(errno));
 
1005
                return FALSE;
 
1006
        }
 
1007
        strcpy(info->name_bitmap, tmpname);
 
1008
        strcat(info->name_bitmap, "/");
 
1009
        strcat(info->name_bitmap, FILENAME_BITMAP);
 
1010
        if ((fd = mkstemp(info->name_bitmap)) < 0) {
 
1011
                ERRMSG("Can't open the bitmap file(%s). %s\n",
 
1012
                    info->name_bitmap, strerror(errno));
 
1013
                return FALSE;
 
1014
        }
 
1015
        info->fd_bitmap = fd;
 
1016
 
 
1017
        if (info->flag_split) {
 
1018
                /*
 
1019
                 * Reserve file descriptors of bitmap for creating split
 
1020
                 * dumpfiles by multiple processes, because a bitmap file will
 
1021
                 * be unlinked just after this and it is not possible to open
 
1022
                 * a bitmap file later.
 
1023
                 */
 
1024
                for (i = 0; i < info->num_dumpfile; i++) {
 
1025
                        if ((fd = open(info->name_bitmap, O_RDONLY)) < 0) {
 
1026
                                ERRMSG("Can't open the bitmap file(%s). %s\n",
 
1027
                                    info->name_bitmap, strerror(errno));
 
1028
                                return FALSE;
 
1029
                        }
 
1030
                        SPLITTING_FD_BITMAP(i) = fd;
 
1031
                }
 
1032
        }
 
1033
        unlink(info->name_bitmap);
 
1034
 
 
1035
        return TRUE;
 
1036
}
 
1037
 
 
1038
/*
 
1039
 * Open the following files when it generates the vmcoreinfo file.
 
1040
 * - vmlinux
 
1041
 * - vmcoreinfo file
 
1042
 */
 
1043
int
 
1044
open_files_for_generating_vmcoreinfo(void)
 
1045
{
 
1046
        if (!open_kernel_file())
 
1047
                return FALSE;
 
1048
 
 
1049
        if (!open_vmcoreinfo("w"))
 
1050
                return FALSE;
 
1051
 
 
1052
        return TRUE;
 
1053
}
 
1054
 
 
1055
/*
 
1056
 * Open the following file when it rearranges the dump data.
 
1057
 * - dump file
 
1058
 */
 
1059
int
 
1060
open_files_for_rearranging_dumpdata(void)
 
1061
{
 
1062
        if (!open_dump_file())
 
1063
                return FALSE;
 
1064
 
 
1065
        return TRUE;
 
1066
}
 
1067
 
 
1068
/*
 
1069
 * Open the following files when it creates the dump file.
 
1070
 * - dump mem
 
1071
 * - dump file
 
1072
 * - bit map
 
1073
 * if it reads the vmcoreinfo file
 
1074
 *   - vmcoreinfo file
 
1075
 * else
 
1076
 *   - vmlinux
 
1077
 */
 
1078
int
 
1079
open_files_for_creating_dumpfile(void)
 
1080
{
 
1081
        if (info->flag_read_vmcoreinfo) {
 
1082
                if (!open_vmcoreinfo("r"))
 
1083
                        return FALSE;
 
1084
        } else {
 
1085
                if (!open_kernel_file())
 
1086
                        return FALSE;
 
1087
        }
 
1088
        if (!open_dump_memory())
 
1089
                return FALSE;
 
1090
 
 
1091
        if (!open_dump_bitmap())
 
1092
                return FALSE;
 
1093
 
 
1094
        return TRUE;
 
1095
}
 
1096
 
 
1097
int
 
1098
dump_Elf_load(Elf64_Phdr *prog, int num_load)
 
1099
{
 
1100
        struct pt_load_segment *pls;
 
1101
 
 
1102
        if (prog->p_type != PT_LOAD) {
 
1103
                ERRMSG("%s isn't the dump memory.\n", info->name_memory);
 
1104
                return FALSE;
 
1105
        }
 
1106
 
 
1107
        pls = &info->pt_load_segments[num_load];
 
1108
        pls->phys_start  = prog->p_paddr;
 
1109
        pls->phys_end    = pls->phys_start + prog->p_filesz;
 
1110
        pls->virt_start  = prog->p_vaddr;
 
1111
        pls->virt_end    = pls->virt_start + prog->p_filesz;
 
1112
        pls->file_offset = prog->p_offset;
 
1113
 
 
1114
        DEBUG_MSG("LOAD (%d)\n", num_load);
 
1115
        DEBUG_MSG("  phys_start : %llx\n", pls->phys_start);
 
1116
        DEBUG_MSG("  phys_end   : %llx\n", pls->phys_end);
 
1117
        DEBUG_MSG("  virt_start : %llx\n", pls->virt_start);
 
1118
        DEBUG_MSG("  virt_end   : %llx\n", pls->virt_end);
 
1119
 
 
1120
        return TRUE;
 
1121
}
 
1122
 
 
1123
int
 
1124
get_elf64_ehdr(Elf64_Ehdr *ehdr)
 
1125
{
 
1126
        const off_t failed = (off_t)-1;
 
1127
 
 
1128
        if (lseek(info->fd_memory, 0, SEEK_SET) == failed) {
 
1129
                ERRMSG("Can't seek the dump memory(%s). %s\n",
 
1130
                    info->name_memory, strerror(errno));
 
1131
                return FALSE;
 
1132
        }
 
1133
        if (read(info->fd_memory, ehdr, sizeof(Elf64_Ehdr))
 
1134
            != sizeof(Elf64_Ehdr)) {
 
1135
                ERRMSG("Can't read the dump memory(%s). %s\n",
 
1136
                    info->name_memory, strerror(errno));
 
1137
                return FALSE;
 
1138
        }
 
1139
        if (ehdr->e_ident[EI_CLASS] != ELFCLASS64) {
 
1140
                ERRMSG("Can't get valid e_ident.\n");
 
1141
                return FALSE;
 
1142
        }
 
1143
        return TRUE;
 
1144
}
 
1145
 
 
1146
int
 
1147
get_elf64_phdr(int fd, char *filename, int index, Elf64_Phdr *phdr)
 
1148
{
 
1149
        off_t offset;
 
1150
        const off_t failed = (off_t)-1;
 
1151
 
 
1152
        offset = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) * index;
 
1153
 
 
1154
        if (lseek(fd, offset, SEEK_SET) == failed) {
 
1155
                ERRMSG("Can't seek %s. %s\n", filename, strerror(errno));
 
1156
                return FALSE;
 
1157
        }
 
1158
        if (read(fd, phdr, sizeof(Elf64_Phdr)) != sizeof(Elf64_Phdr)) {
 
1159
                ERRMSG("Can't read %s. %s\n", filename, strerror(errno));
 
1160
                return FALSE;
 
1161
        }
 
1162
        return TRUE;
 
1163
}
 
1164
 
 
1165
int
 
1166
get_elf32_ehdr(Elf32_Ehdr *ehdr)
 
1167
{
 
1168
        const off_t failed = (off_t)-1;
 
1169
 
 
1170
        if (lseek(info->fd_memory, 0, SEEK_SET) == failed) {
 
1171
                ERRMSG("Can't seek the dump memory(%s). %s\n",
 
1172
                    info->name_memory, strerror(errno));
 
1173
                return FALSE;
 
1174
        }
 
1175
        if (read(info->fd_memory, ehdr, sizeof(Elf32_Ehdr))
 
1176
            != sizeof(Elf32_Ehdr)) {
 
1177
                ERRMSG("Can't read the dump memory(%s). %s\n",
 
1178
                    info->name_memory, strerror(errno));
 
1179
                return FALSE;
 
1180
        }
 
1181
        if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
 
1182
                ERRMSG("Can't get valid e_ident.\n");
 
1183
                return FALSE;
 
1184
        }
 
1185
        return TRUE;
 
1186
}
 
1187
 
 
1188
int
 
1189
get_elf32_phdr(int fd, char *filename, int index, Elf32_Phdr *phdr)
 
1190
{
 
1191
        off_t offset;
 
1192
        const off_t failed = (off_t)-1;
 
1193
 
 
1194
        offset = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr) * index;
 
1195
 
 
1196
        if (lseek(fd, offset, SEEK_SET) == failed) {
 
1197
                ERRMSG("Can't seek %s. %s\n", filename, strerror(errno));
 
1198
                return FALSE;
 
1199
        }
 
1200
        if (read(fd, phdr, sizeof(Elf32_Phdr)) != sizeof(Elf32_Phdr)) {
 
1201
                ERRMSG("Can't read %s. %s\n", filename, strerror(errno));
 
1202
                return FALSE;
 
1203
        }
 
1204
        return TRUE;
 
1205
}
 
1206
 
 
1207
int
 
1208
get_elf_phdr_memory(int index, Elf64_Phdr *phdr)
 
1209
{
 
1210
        Elf32_Phdr phdr32;
 
1211
 
 
1212
        if (info->flag_elf64_memory) { /* ELF64 */
 
1213
                if (!get_elf64_phdr(info->fd_memory, info->name_memory,
 
1214
                    index, phdr)) {
 
1215
                        ERRMSG("Can't find Phdr %d.\n", index);
 
1216
                        return FALSE;
 
1217
                }
 
1218
        } else {
 
1219
                if (!get_elf32_phdr(info->fd_memory, info->name_memory,
 
1220
                    index, &phdr32)) {
 
1221
                        ERRMSG("Can't find Phdr %d.\n", index);
 
1222
                        return FALSE;
 
1223
                }
 
1224
                memset(phdr, 0, sizeof(Elf64_Phdr));
 
1225
                phdr->p_type   = phdr32.p_type;
 
1226
                phdr->p_flags  = phdr32.p_flags;
 
1227
                phdr->p_offset = phdr32.p_offset;
 
1228
                phdr->p_vaddr  = phdr32.p_vaddr;
 
1229
                phdr->p_paddr  = phdr32.p_paddr;
 
1230
                phdr->p_filesz = phdr32.p_filesz;
 
1231
                phdr->p_memsz  = phdr32.p_memsz;
 
1232
                phdr->p_align  = phdr32.p_align;
 
1233
        }
 
1234
        return TRUE;
 
1235
}
 
1236
 
 
1237
int
 
1238
check_elf_format(int fd, char *filename, int *phnum, int *num_load)
 
1239
{
 
1240
        int i;
 
1241
        Elf64_Ehdr ehdr64;
 
1242
        Elf64_Phdr load64;
 
1243
        Elf32_Ehdr ehdr32;
 
1244
        Elf32_Phdr load32;
 
1245
        const off_t failed = (off_t)-1;
 
1246
 
 
1247
        if (lseek(fd, 0, SEEK_SET) == failed) {
 
1248
                ERRMSG("Can't seek %s. %s\n", filename, strerror(errno));
 
1249
                return FALSE;
 
1250
        }
 
1251
        if (read(fd, &ehdr64, sizeof(Elf64_Ehdr)) != sizeof(Elf64_Ehdr)) {
 
1252
                ERRMSG("Can't read %s. %s\n", filename, strerror(errno));
 
1253
                return FALSE;
 
1254
        }
 
1255
        if (lseek(fd, 0, SEEK_SET) == failed) {
 
1256
                ERRMSG("Can't seek %s. %s\n", filename, strerror(errno));
 
1257
                return FALSE;
 
1258
        }
 
1259
        if (read(fd, &ehdr32, sizeof(Elf32_Ehdr)) != sizeof(Elf32_Ehdr)) {
 
1260
                ERRMSG("Can't read %s. %s\n", filename, strerror(errno));
 
1261
                return FALSE;
 
1262
        }
 
1263
        (*num_load) = 0;
 
1264
        if ((ehdr64.e_ident[EI_CLASS] == ELFCLASS64)
 
1265
            && (ehdr32.e_ident[EI_CLASS] != ELFCLASS32)) {
 
1266
                (*phnum) = ehdr64.e_phnum;
 
1267
                for (i = 0; i < ehdr64.e_phnum; i++) {
 
1268
                        if (!get_elf64_phdr(fd, filename, i, &load64)) {
 
1269
                                ERRMSG("Can't find Phdr %d.\n", i);
 
1270
                                return FALSE;
 
1271
                        }
 
1272
                        if (load64.p_type == PT_LOAD)
 
1273
                                (*num_load)++;
 
1274
                }
 
1275
                return ELF64;
 
1276
 
 
1277
        } else if ((ehdr64.e_ident[EI_CLASS] != ELFCLASS64)
 
1278
            && (ehdr32.e_ident[EI_CLASS] == ELFCLASS32)) {
 
1279
                (*phnum) = ehdr32.e_phnum;
 
1280
                for (i = 0; i < ehdr32.e_phnum; i++) {
 
1281
                        if (!get_elf32_phdr(fd, filename, i, &load32)) {
 
1282
                                ERRMSG("Can't find Phdr %d.\n", i);
 
1283
                                return FALSE;
 
1284
                        }
 
1285
                        if (load32.p_type == PT_LOAD)
 
1286
                                (*num_load)++;
 
1287
                }
 
1288
                return ELF32;
 
1289
        }
 
1290
        ERRMSG("Can't get valid ehdr.\n");
 
1291
        return FALSE;
 
1292
}
 
1293
 
 
1294
int
 
1295
get_elf_info(void)
 
1296
{
 
1297
        int i, j, phnum, num_load, elf_format;
 
1298
        Elf64_Phdr phdr;
 
1299
 
 
1300
        /*
 
1301
         * Check ELF64 or ELF32.
 
1302
         */
 
1303
        elf_format = check_elf_format(info->fd_memory, info->name_memory,
 
1304
            &phnum, &num_load);
 
1305
 
 
1306
        if (elf_format == ELF64)
 
1307
                info->flag_elf64_memory = TRUE;
 
1308
        else if (elf_format == ELF32)
 
1309
                info->flag_elf64_memory = FALSE;
 
1310
        else
 
1311
                return FALSE;
 
1312
 
 
1313
        info->num_load_memory = num_load;
 
1314
 
 
1315
        if (!info->num_load_memory) {
 
1316
                ERRMSG("Can't get the number of PT_LOAD.\n");
 
1317
                return FALSE;
 
1318
        }
 
1319
        if ((info->pt_load_segments = (struct pt_load_segment *)
 
1320
            calloc(1, sizeof(struct pt_load_segment) *
 
1321
            info->num_load_memory)) == NULL) {
 
1322
                ERRMSG("Can't allocate memory for the PT_LOAD. %s\n",
 
1323
                    strerror(errno));
 
1324
                return FALSE;
 
1325
        }
 
1326
        info->offset_note = 0;
 
1327
        info->size_note   = 0;
 
1328
        for (i = 0, j = 0; i < phnum; i++) {
 
1329
                if (!get_elf_phdr_memory(i, &phdr))
 
1330
                        return FALSE;
 
1331
 
 
1332
                if (phdr.p_type == PT_NOTE) {
 
1333
                        info->offset_note = phdr.p_offset;
 
1334
                        info->size_note   = phdr.p_filesz;
 
1335
                }
 
1336
                if (phdr.p_type != PT_LOAD)
 
1337
                        continue;
 
1338
 
 
1339
                if (j == 0) {
 
1340
                        info->offset_load_memory = phdr.p_offset;
 
1341
                        if (!info->offset_load_memory) {
 
1342
                                ERRMSG("Can't get the offset of page data.\n");
 
1343
                                return FALSE;
 
1344
                        }
 
1345
                }
 
1346
                if (j >= info->num_load_memory)
 
1347
                        return FALSE;
 
1348
                if(!dump_Elf_load(&phdr, j))
 
1349
                        return FALSE;
 
1350
                j++;
 
1351
        }
 
1352
        if (info->offset_note == 0 || info->size_note == 0) {
 
1353
                ERRMSG("Can't find PT_NOTE Phdr.\n");
 
1354
                return FALSE;
 
1355
        }
 
1356
        if (!get_pt_note_info(info->offset_note, info->size_note)) {
 
1357
                ERRMSG("Can't get PT_NOTE information.\n");
 
1358
                return FALSE;
 
1359
        }
 
1360
 
 
1361
        return TRUE;
 
1362
}
 
1363
 
 
1364
unsigned long long
 
1365
get_symbol_addr(char *symname)
 
1366
{
 
1367
        int i;
 
1368
        unsigned long long symbol = NOT_FOUND_SYMBOL;
 
1369
        Elf *elfd = NULL;
 
1370
        GElf_Shdr shdr;
 
1371
        GElf_Sym sym;
 
1372
        Elf_Data *data = NULL;
 
1373
        Elf_Scn *scn = NULL;
 
1374
        char *sym_name = NULL;
 
1375
        const off_t failed = (off_t)-1;
 
1376
 
 
1377
        if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
 
1378
                ERRMSG("Can't seek the kernel file(%s). %s\n",
 
1379
                    dwarf_info.name_debuginfo, strerror(errno));
 
1380
                return NOT_FOUND_SYMBOL;
 
1381
        }
 
1382
        if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ, NULL))) {
 
1383
                ERRMSG("Can't get first elf header of %s.\n",
 
1384
                    dwarf_info.name_debuginfo);
 
1385
                return NOT_FOUND_SYMBOL;
 
1386
        }
 
1387
        while ((scn = elf_nextscn(elfd, scn)) != NULL) {
 
1388
                if (gelf_getshdr(scn, &shdr) == NULL) {
 
1389
                        ERRMSG("Can't get section header.\n");
 
1390
                        goto out;
 
1391
                }
 
1392
                if (shdr.sh_type == SHT_SYMTAB)
 
1393
                        break;
 
1394
        }
 
1395
        if (!scn) {
 
1396
                ERRMSG("Can't find symbol table.\n");
 
1397
                goto out;
 
1398
        }
 
1399
 
 
1400
        data = elf_getdata(scn, data);
 
1401
 
 
1402
        if ((!data) || (data->d_size == 0)) {
 
1403
                ERRMSG("No data in symbol table.\n");
 
1404
                goto out;
 
1405
        }
 
1406
 
 
1407
        for (i = 0; i < (shdr.sh_size/shdr.sh_entsize); i++) {
 
1408
                if (gelf_getsym(data, i, &sym) == NULL) {
 
1409
                        ERRMSG("Can't get symbol at index %d.\n", i);
 
1410
                        goto out;
 
1411
                }
 
1412
                sym_name = elf_strptr(elfd, shdr.sh_link, sym.st_name);
 
1413
 
 
1414
                if (sym_name == NULL)
 
1415
                        continue;
 
1416
 
 
1417
                if (!strcmp(sym_name, symname)) {
 
1418
                        symbol = sym.st_value;
 
1419
                        break;
 
1420
                }
 
1421
        }
 
1422
out:
 
1423
        if (elfd != NULL)
 
1424
                elf_end(elfd);
 
1425
 
 
1426
        return symbol;
 
1427
}
 
1428
 
 
1429
unsigned long
 
1430
get_next_symbol_addr(char *symname)
 
1431
{
 
1432
        int i;
 
1433
        unsigned long symbol = NOT_FOUND_SYMBOL;
 
1434
        unsigned long next_symbol = NOT_FOUND_SYMBOL;
 
1435
        Elf *elfd = NULL;
 
1436
        GElf_Shdr shdr;
 
1437
        GElf_Sym sym;
 
1438
        Elf_Data *data = NULL;
 
1439
        Elf_Scn *scn = NULL;
 
1440
        char *sym_name = NULL;
 
1441
        const off_t failed = (off_t)-1;
 
1442
 
 
1443
        if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
 
1444
                ERRMSG("Can't seek the kernel file(%s). %s\n",
 
1445
                    dwarf_info.name_debuginfo, strerror(errno));
 
1446
                return NOT_FOUND_SYMBOL;
 
1447
        }
 
1448
        if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ, NULL))) {
 
1449
                ERRMSG("Can't get first elf header of %s.\n",
 
1450
                    dwarf_info.name_debuginfo);
 
1451
                return NOT_FOUND_SYMBOL;
 
1452
        }
 
1453
        while ((scn = elf_nextscn(elfd, scn)) != NULL) {
 
1454
                if (gelf_getshdr(scn, &shdr) == NULL) {
 
1455
                        ERRMSG("Can't get section header.\n");
 
1456
                        goto out;
 
1457
                }
 
1458
                if (shdr.sh_type == SHT_SYMTAB)
 
1459
                        break;
 
1460
        }
 
1461
        if (!scn) {
 
1462
                ERRMSG("Can't find symbol table.\n");
 
1463
                goto out;
 
1464
        }
 
1465
 
 
1466
        data = elf_getdata(scn, data);
 
1467
 
 
1468
        if ((!data) || (data->d_size == 0)) {
 
1469
                ERRMSG("No data in symbol table.\n");
 
1470
                goto out;
 
1471
        }
 
1472
 
 
1473
        for (i = 0; i < (shdr.sh_size/shdr.sh_entsize); i++) {
 
1474
                if (gelf_getsym(data, i, &sym) == NULL) {
 
1475
                        ERRMSG("Can't get symbol at index %d.\n", i);
 
1476
                        goto out;
 
1477
                }
 
1478
                sym_name = elf_strptr(elfd, shdr.sh_link, sym.st_name);
 
1479
 
 
1480
                if (sym_name == NULL)
 
1481
                        continue;
 
1482
 
 
1483
                if (!strcmp(sym_name, symname)) {
 
1484
                        symbol = sym.st_value;
 
1485
                        break;
 
1486
                }
 
1487
        }
 
1488
 
 
1489
        if (symbol == NOT_FOUND_SYMBOL)
 
1490
                goto out;
 
1491
 
 
1492
        /*
 
1493
         * Search for next symbol.
 
1494
         */
 
1495
        for (i = 0; i < (shdr.sh_size/shdr.sh_entsize); i++) {
 
1496
                if (gelf_getsym(data, i, &sym) == NULL) {
 
1497
                        ERRMSG("Can't get symbol at index %d.\n", i);
 
1498
                        goto out;
 
1499
                }
 
1500
                sym_name = elf_strptr(elfd, shdr.sh_link, sym.st_name);
 
1501
 
 
1502
                if (sym_name == NULL)
 
1503
                        continue;
 
1504
 
 
1505
                if (symbol < sym.st_value) {
 
1506
                        if (next_symbol == NOT_FOUND_SYMBOL)
 
1507
                                next_symbol = sym.st_value;
 
1508
 
 
1509
                        else if (sym.st_value < next_symbol)
 
1510
                                next_symbol = sym.st_value;
 
1511
                }
 
1512
        }
 
1513
out:
 
1514
        if (elfd != NULL)
 
1515
                elf_end(elfd);
 
1516
 
 
1517
        return next_symbol;
 
1518
}
 
1519
 
 
1520
int
 
1521
is_kvaddr(unsigned long long addr)
 
1522
{
 
1523
        return (addr >= (unsigned long long)(KVBASE));
 
1524
}
 
1525
 
 
1526
static int
 
1527
get_data_member_location(Dwarf_Die *die, long *offset)
 
1528
{
 
1529
        size_t expcnt;
 
1530
        Dwarf_Attribute attr;
 
1531
        Dwarf_Op *expr;
 
1532
 
 
1533
        if (dwarf_attr(die, DW_AT_data_member_location, &attr) == NULL)
 
1534
                return FALSE;
 
1535
 
 
1536
        if (dwarf_getlocation(&attr, &expr, &expcnt) < 0)
 
1537
                return FALSE;
 
1538
 
 
1539
        (*offset) = expr[0].number;
 
1540
 
 
1541
        return TRUE;
 
1542
}
 
1543
 
 
1544
static int
 
1545
get_die_type(Dwarf *dwarfd, Dwarf_Die *die, Dwarf_Die *die_type)
 
1546
{
 
1547
        Dwarf_Attribute attr;
 
1548
        Dwarf_Off offset_type, offset_cu;
 
1549
 
 
1550
        offset_cu = dwarf_dieoffset(die) - dwarf_cuoffset(die);
 
1551
 
 
1552
        /*
 
1553
         * Get the offset of DW_AT_type.
 
1554
         */
 
1555
        if (dwarf_attr(die, DW_AT_type, &attr) == NULL)
 
1556
                return FALSE;
 
1557
 
 
1558
        if (dwarf_formref(&attr, &offset_type) < 0)
 
1559
                return FALSE;
 
1560
 
 
1561
        if (dwarf_offdie(dwarfd, offset_type + offset_cu, die_type) == NULL) {
 
1562
                ERRMSG("Can't get CU die.\n");
 
1563
                return FALSE;
 
1564
        }
 
1565
        return TRUE;
 
1566
}
 
1567
 
 
1568
static int
 
1569
get_data_array_length(Dwarf *dwarfd, Dwarf_Die *die)
 
1570
{
 
1571
        int tag;
 
1572
        Dwarf_Attribute attr;
 
1573
        Dwarf_Die die_type;
 
1574
        Dwarf_Word upper_bound;
 
1575
 
 
1576
        if (!get_die_type(dwarfd, die, &die_type)) {
 
1577
                ERRMSG("Can't get CU die of DW_AT_type.\n");
 
1578
                return FALSE;
 
1579
        }
 
1580
        tag = dwarf_tag(&die_type);
 
1581
        if (tag != DW_TAG_array_type) {
 
1582
                /*
 
1583
                 * This kernel doesn't have the member of array.
 
1584
                 */
 
1585
                return TRUE;
 
1586
        }
 
1587
 
 
1588
        /*
 
1589
         * Get the demanded array length.
 
1590
         */
 
1591
        dwarf_child(&die_type, &die_type);
 
1592
        do {
 
1593
                tag  = dwarf_tag(&die_type);
 
1594
                if (tag == DW_TAG_subrange_type)
 
1595
                        break;
 
1596
        } while (dwarf_siblingof(&die_type, &die_type));
 
1597
 
 
1598
        if (tag != DW_TAG_subrange_type)
 
1599
                return FALSE;
 
1600
 
 
1601
        if (dwarf_attr(&die_type, DW_AT_upper_bound, &attr) == NULL)
 
1602
                return FALSE;
 
1603
 
 
1604
        if (dwarf_formudata(&attr, &upper_bound) < 0)
 
1605
                return FALSE;
 
1606
 
 
1607
        if (upper_bound < 0)
 
1608
                return FALSE;
 
1609
 
 
1610
        dwarf_info.array_length = upper_bound + 1;
 
1611
 
 
1612
        return TRUE;
 
1613
}
 
1614
 
 
1615
static int
 
1616
check_array_type(Dwarf *dwarfd, Dwarf_Die *die)
 
1617
{
 
1618
        int tag;
 
1619
        Dwarf_Die die_type;
 
1620
 
 
1621
        if (!get_die_type(dwarfd, die, &die_type)) {
 
1622
                ERRMSG("Can't get CU die of DW_AT_type.\n");
 
1623
                return FALSE;
 
1624
        }
 
1625
        tag = dwarf_tag(&die_type);
 
1626
        if (tag == DW_TAG_array_type)
 
1627
                dwarf_info.array_length = FOUND_ARRAY_TYPE;
 
1628
 
 
1629
        return TRUE;
 
1630
}
 
1631
 
 
1632
/*
 
1633
 * Function for searching struct page.union.struct.mapping.
 
1634
 */
 
1635
int
 
1636
__search_mapping(Dwarf *dwarfd, Dwarf_Die *die, long *offset)
 
1637
{
 
1638
        int tag;
 
1639
        const char *name;
 
1640
        Dwarf_Die child, *walker;
 
1641
 
 
1642
        if (dwarf_child(die, &child) != 0)
 
1643
                return FALSE;
 
1644
 
 
1645
        walker = &child;
 
1646
        do {
 
1647
                tag  = dwarf_tag(walker);
 
1648
                name = dwarf_diename(walker);
 
1649
 
 
1650
                if (tag != DW_TAG_member)
 
1651
                        continue;
 
1652
                if ((!name) || strcmp(name, dwarf_info.member_name))
 
1653
                        continue;
 
1654
                if (!get_data_member_location(walker, offset))
 
1655
                        continue;
 
1656
                return TRUE;
 
1657
 
 
1658
        } while (!dwarf_siblingof(walker, walker));
 
1659
 
 
1660
        return FALSE;
 
1661
}
 
1662
 
 
1663
/*
 
1664
 * Function for searching struct page.union.struct.
 
1665
 */
 
1666
int
 
1667
search_mapping(Dwarf *dwarfd, Dwarf_Die *die, long *offset)
 
1668
{
 
1669
        Dwarf_Die child, *walker;
 
1670
        Dwarf_Die die_struct;
 
1671
 
 
1672
        if (dwarf_child(die, &child) != 0)
 
1673
                return FALSE;
 
1674
 
 
1675
        walker = &child;
 
1676
 
 
1677
        do {
 
1678
                if (dwarf_tag(walker) != DW_TAG_member)
 
1679
                        continue;
 
1680
                if (!get_die_type(dwarfd, walker, &die_struct))
 
1681
                        continue;
 
1682
                if (dwarf_tag(&die_struct) != DW_TAG_structure_type)
 
1683
                        continue;
 
1684
                if (__search_mapping(dwarfd, &die_struct, offset))
 
1685
                        return TRUE;
 
1686
        } while (!dwarf_siblingof(walker, walker));
 
1687
 
 
1688
        return FALSE;
 
1689
}
 
1690
 
 
1691
static void
 
1692
search_member(Dwarf *dwarfd, Dwarf_Die *die)
 
1693
{
 
1694
        int tag;
 
1695
        long offset, offset_union;
 
1696
        const char *name;
 
1697
        Dwarf_Die child, *walker, die_union;
 
1698
 
 
1699
        if (dwarf_child(die, &child) != 0)
 
1700
                return;
 
1701
 
 
1702
        walker = &child;
 
1703
 
 
1704
        do {
 
1705
                tag  = dwarf_tag(walker);
 
1706
                name = dwarf_diename(walker);
 
1707
 
 
1708
                if (tag != DW_TAG_member)
 
1709
                        continue;
 
1710
 
 
1711
                switch (dwarf_info.cmd) {
 
1712
                case DWARF_INFO_GET_MEMBER_OFFSET:
 
1713
                        if ((!name) || strcmp(name, dwarf_info.member_name))
 
1714
                                continue;
 
1715
                        /*
 
1716
                         * Get the member offset.
 
1717
                         */
 
1718
                        if (!get_data_member_location(walker, &offset))
 
1719
                                continue;
 
1720
                        dwarf_info.member_offset = offset;
 
1721
                        return;
 
1722
                case DWARF_INFO_GET_MEMBER_OFFSET_IN_UNION:
 
1723
                        if (!get_die_type(dwarfd, walker, &die_union))
 
1724
                                continue;
 
1725
                        if (dwarf_tag(&die_union) != DW_TAG_union_type)
 
1726
                                continue;
 
1727
                        /*
 
1728
                         * Search page.mapping in union.
 
1729
                         */
 
1730
                        if (!search_mapping(dwarfd, &die_union, &offset_union))
 
1731
                                continue;
 
1732
                        /*
 
1733
                         * Get the member offset.
 
1734
                         */
 
1735
                        if (!get_data_member_location(walker, &offset))
 
1736
                                continue;
 
1737
                        dwarf_info.member_offset = offset + offset_union;
 
1738
                        return;
 
1739
                case DWARF_INFO_GET_MEMBER_OFFSET_1ST_UNION:
 
1740
                        if (!get_die_type(dwarfd, walker, &die_union))
 
1741
                                continue;
 
1742
                        if (dwarf_tag(&die_union) != DW_TAG_union_type)
 
1743
                                continue;
 
1744
                        /*
 
1745
                         * Get the member offset.
 
1746
                         */
 
1747
                        if (!get_data_member_location(walker, &offset))
 
1748
                                continue;
 
1749
                        dwarf_info.member_offset = offset;
 
1750
                        return;
 
1751
                case DWARF_INFO_GET_MEMBER_ARRAY_LENGTH:
 
1752
                        if ((!name) || strcmp(name, dwarf_info.member_name))
 
1753
                                continue;
 
1754
                        /*
 
1755
                         * Get the member length.
 
1756
                         */
 
1757
                        if (!get_data_array_length(dwarfd, walker))
 
1758
                                continue;
 
1759
                        return;
 
1760
                }
 
1761
        } while (!dwarf_siblingof(walker, walker));
 
1762
 
 
1763
        /*
 
1764
         * Return even if not found.
 
1765
         */
 
1766
        return;
 
1767
}
 
1768
 
 
1769
int
 
1770
is_search_structure(int cmd)
 
1771
{
 
1772
        if ((cmd == DWARF_INFO_GET_STRUCT_SIZE)
 
1773
            || (cmd == DWARF_INFO_GET_MEMBER_OFFSET)
 
1774
            || (cmd == DWARF_INFO_GET_MEMBER_OFFSET_IN_UNION)
 
1775
            || (cmd == DWARF_INFO_GET_MEMBER_OFFSET_1ST_UNION)
 
1776
            || (cmd == DWARF_INFO_GET_MEMBER_ARRAY_LENGTH))
 
1777
                return TRUE;
 
1778
        else
 
1779
                return FALSE;
 
1780
}
 
1781
 
 
1782
int
 
1783
is_search_number(int cmd)
 
1784
{
 
1785
        if (cmd == DWARF_INFO_GET_ENUM_NUMBER)
 
1786
                return TRUE;
 
1787
        else
 
1788
                return FALSE;
 
1789
}
 
1790
 
 
1791
int
 
1792
is_search_symbol(int cmd)
 
1793
{
 
1794
        if ((cmd == DWARF_INFO_GET_SYMBOL_ARRAY_LENGTH)
 
1795
            || (cmd == DWARF_INFO_CHECK_SYMBOL_ARRAY_TYPE))
 
1796
                return TRUE;
 
1797
        else
 
1798
                return FALSE;
 
1799
}
 
1800
 
 
1801
int
 
1802
is_search_typedef(int cmd)
 
1803
{
 
1804
        if ((cmd == DWARF_INFO_GET_TYPEDEF_SIZE)
 
1805
            || (cmd == DWARF_INFO_GET_TYPEDEF_SRCNAME))
 
1806
                return TRUE;
 
1807
        else
 
1808
                return FALSE;
 
1809
}
 
1810
 
 
1811
static void
 
1812
search_structure(Dwarf *dwarfd, Dwarf_Die *die, int *found)
 
1813
{
 
1814
        int tag;
 
1815
        const char *name;
 
1816
 
 
1817
        /*
 
1818
         * If we get to here then we don't have any more
 
1819
         * children, check to see if this is a relevant tag
 
1820
         */
 
1821
        do {
 
1822
                tag  = dwarf_tag(die);
 
1823
                name = dwarf_diename(die);
 
1824
                if ((tag != DW_TAG_structure_type) || (!name)
 
1825
                    || strcmp(name, dwarf_info.struct_name))
 
1826
                        continue;
 
1827
                /*
 
1828
                 * Skip if DW_AT_byte_size is not included.
 
1829
                 */
 
1830
                dwarf_info.struct_size = dwarf_bytesize(die);
 
1831
 
 
1832
                if (dwarf_info.struct_size > 0)
 
1833
                        break;
 
1834
 
 
1835
        } while (!dwarf_siblingof(die, die));
 
1836
 
 
1837
        if (dwarf_info.struct_size <= 0) {
 
1838
                /*
 
1839
                 * Not found the demanded structure.
 
1840
                 */
 
1841
                return;
 
1842
        }
 
1843
 
 
1844
        /*
 
1845
         * Found the demanded structure.
 
1846
         */
 
1847
        *found = TRUE;
 
1848
        switch (dwarf_info.cmd) {
 
1849
        case DWARF_INFO_GET_STRUCT_SIZE:
 
1850
                break;
 
1851
        case DWARF_INFO_GET_MEMBER_OFFSET:
 
1852
        case DWARF_INFO_GET_MEMBER_OFFSET_IN_UNION:
 
1853
        case DWARF_INFO_GET_MEMBER_OFFSET_1ST_UNION:
 
1854
        case DWARF_INFO_GET_MEMBER_ARRAY_LENGTH:
 
1855
                search_member(dwarfd, die);
 
1856
                break;
 
1857
        }
 
1858
}
 
1859
 
 
1860
static void
 
1861
search_number(Dwarf *dwarfd, Dwarf_Die *die, int *found)
 
1862
{
 
1863
        int tag;
 
1864
        Dwarf_Word const_value;
 
1865
        Dwarf_Attribute attr;
 
1866
        Dwarf_Die child, *walker;
 
1867
        const char *name;
 
1868
 
 
1869
        do {
 
1870
                tag  = dwarf_tag(die);
 
1871
                if (tag != DW_TAG_enumeration_type)
 
1872
                        continue;
 
1873
 
 
1874
                if (dwarf_child(die, &child) != 0)
 
1875
                        continue;
 
1876
 
 
1877
                walker = &child;
 
1878
 
 
1879
                do {
 
1880
                        tag  = dwarf_tag(walker);
 
1881
                        name = dwarf_diename(walker);
 
1882
 
 
1883
                        if ((tag != DW_TAG_enumerator) || (!name)
 
1884
                            || strcmp(name, dwarf_info.enum_name))
 
1885
                                continue;
 
1886
 
 
1887
                        if (!dwarf_attr(walker, DW_AT_const_value, &attr))
 
1888
                                continue;
 
1889
 
 
1890
                        if (dwarf_formudata(&attr, &const_value) < 0)
 
1891
                                continue;
 
1892
 
 
1893
                        *found = TRUE;
 
1894
                        dwarf_info.enum_number = (long)const_value;
 
1895
 
 
1896
                } while (!dwarf_siblingof(walker, walker));
 
1897
 
 
1898
        } while (!dwarf_siblingof(die, die));
 
1899
}
 
1900
 
 
1901
static void
 
1902
search_typedef(Dwarf *dwarfd, Dwarf_Die *die, int *found)
 
1903
{
 
1904
        int tag = 0;
 
1905
        char *src_name = NULL;
 
1906
        const char *name;
 
1907
        Dwarf_Die die_type;
 
1908
 
 
1909
        /*
 
1910
         * If we get to here then we don't have any more
 
1911
         * children, check to see if this is a relevant tag
 
1912
         */
 
1913
        do {
 
1914
                tag  = dwarf_tag(die);
 
1915
                name = dwarf_diename(die);
 
1916
 
 
1917
                if ((tag != DW_TAG_typedef) || (!name)
 
1918
                    || strcmp(name, dwarf_info.struct_name))
 
1919
                        continue;
 
1920
 
 
1921
                if (dwarf_info.cmd == DWARF_INFO_GET_TYPEDEF_SIZE) {
 
1922
                        if (!get_die_type(dwarfd, die, &die_type)) {
 
1923
                                ERRMSG("Can't get CU die of DW_AT_type.\n");
 
1924
                                break;
 
1925
                        }
 
1926
                        dwarf_info.struct_size = dwarf_bytesize(&die_type);
 
1927
                        if (dwarf_info.struct_size <= 0)
 
1928
                                continue;
 
1929
 
 
1930
                        *found = TRUE;
 
1931
                        break;
 
1932
                } else if (dwarf_info.cmd == DWARF_INFO_GET_TYPEDEF_SRCNAME) {
 
1933
                        src_name = (char *)dwarf_decl_file(die);
 
1934
                        if (!src_name)
 
1935
                                continue;
 
1936
 
 
1937
                        *found = TRUE;
 
1938
                        strncpy(dwarf_info.src_name, src_name, LEN_SRCFILE);
 
1939
                        break;
 
1940
                }
 
1941
        } while (!dwarf_siblingof(die, die));
 
1942
}
 
1943
 
 
1944
static void
 
1945
search_symbol(Dwarf *dwarfd, Dwarf_Die *die, int *found)
 
1946
{
 
1947
        int tag;
 
1948
        const char *name;
 
1949
 
 
1950
        /*
 
1951
         * If we get to here then we don't have any more
 
1952
         * children, check to see if this is a relevant tag
 
1953
         */
 
1954
        do {
 
1955
                tag  = dwarf_tag(die);
 
1956
                name = dwarf_diename(die);
 
1957
 
 
1958
                if ((tag == DW_TAG_variable) && (name)
 
1959
                    && !strcmp(name, dwarf_info.symbol_name))
 
1960
                        break;
 
1961
 
 
1962
        } while (!dwarf_siblingof(die, die));
 
1963
 
 
1964
        if ((tag != DW_TAG_variable) || (!name)
 
1965
            || strcmp(name, dwarf_info.symbol_name)) {
 
1966
                /*
 
1967
                 * Not found the demanded symbol.
 
1968
                 */
 
1969
                return;
 
1970
        }
 
1971
 
 
1972
        /*
 
1973
         * Found the demanded symbol.
 
1974
         */
 
1975
        *found = TRUE;
 
1976
        switch (dwarf_info.cmd) {
 
1977
        case DWARF_INFO_GET_SYMBOL_ARRAY_LENGTH:
 
1978
                get_data_array_length(dwarfd, die);
 
1979
                break;
 
1980
        case DWARF_INFO_CHECK_SYMBOL_ARRAY_TYPE:
 
1981
                check_array_type(dwarfd, die);
 
1982
                break;
 
1983
        }
 
1984
}
 
1985
 
 
1986
static void
 
1987
search_die_tree(Dwarf *dwarfd, Dwarf_Die *die, int *found)
 
1988
{
 
1989
        Dwarf_Die child;
 
1990
 
 
1991
        /*
 
1992
         * start by looking at the children
 
1993
         */
 
1994
        if (dwarf_child(die, &child) == 0)
 
1995
                search_die_tree(dwarfd, &child, found);
 
1996
 
 
1997
        if (*found)
 
1998
                return;
 
1999
 
 
2000
        if (is_search_structure(dwarf_info.cmd))
 
2001
                search_structure(dwarfd, die, found);
 
2002
 
 
2003
        else if (is_search_number(dwarf_info.cmd))
 
2004
                search_number(dwarfd, die, found);
 
2005
 
 
2006
        else if (is_search_symbol(dwarf_info.cmd))
 
2007
                search_symbol(dwarfd, die, found);
 
2008
 
 
2009
        else if (is_search_typedef(dwarf_info.cmd))
 
2010
                search_typedef(dwarfd, die, found);
 
2011
}
 
2012
 
 
2013
int
 
2014
get_debug_info(void)
 
2015
{
 
2016
        int found = FALSE;
 
2017
        char *name = NULL;
 
2018
        size_t shstrndx, header_size;
 
2019
        uint8_t address_size, offset_size;
 
2020
        Dwarf *dwarfd = NULL;
 
2021
        Elf *elfd = NULL;
 
2022
        Dwarf_Off off = 0, next_off = 0, abbrev_offset = 0;
 
2023
        Elf_Scn *scn = NULL;
 
2024
        GElf_Shdr scnhdr_mem, *scnhdr = NULL;
 
2025
        Dwarf_Die cu_die;
 
2026
        const off_t failed = (off_t)-1;
 
2027
 
 
2028
        int ret = FALSE;
 
2029
 
 
2030
        if (lseek(dwarf_info.fd_debuginfo, 0, SEEK_SET) == failed) {
 
2031
                ERRMSG("Can't seek the kernel file(%s). %s\n",
 
2032
                    dwarf_info.name_debuginfo, strerror(errno));
 
2033
                return FALSE;
 
2034
        }
 
2035
        if (!(elfd = elf_begin(dwarf_info.fd_debuginfo, ELF_C_READ_MMAP, NULL))) {
 
2036
                ERRMSG("Can't get first elf header of %s.\n",
 
2037
                    dwarf_info.name_debuginfo);
 
2038
                return FALSE;
 
2039
        }
 
2040
        if (!(dwarfd = dwarf_begin_elf(elfd, DWARF_C_READ, NULL))) {
 
2041
                ERRMSG("Can't create a handle for a new debug session.\n");
 
2042
                goto out;
 
2043
        }
 
2044
        if (elf_getshstrndx(elfd, &shstrndx) < 0) {
 
2045
                ERRMSG("Can't get the section index of the string table.\n");
 
2046
                goto out;
 
2047
        }
 
2048
 
 
2049
        /*
 
2050
         * Search for ".debug_info" section.
 
2051
         */
 
2052
        while ((scn = elf_nextscn(elfd, scn)) != NULL) {
 
2053
                scnhdr = gelf_getshdr(scn, &scnhdr_mem);
 
2054
                name = elf_strptr(elfd, shstrndx, scnhdr->sh_name);
 
2055
                if (!strcmp(name, ".debug_info"))
 
2056
                        break;
 
2057
        }
 
2058
        if (strcmp(name, ".debug_info")) {
 
2059
                ERRMSG("Can't get .debug_info section.\n");
 
2060
                goto out;
 
2061
        }
 
2062
 
 
2063
        /*
 
2064
         * Search by each CompileUnit.
 
2065
         */
 
2066
        while (dwarf_nextcu(dwarfd, off, &next_off, &header_size,
 
2067
            &abbrev_offset, &address_size, &offset_size) == 0) {
 
2068
                off += header_size;
 
2069
                if (dwarf_offdie(dwarfd, off, &cu_die) == NULL) {
 
2070
                        ERRMSG("Can't get CU die.\n");
 
2071
                        goto out;
 
2072
                }
 
2073
                search_die_tree(dwarfd, &cu_die, &found);
 
2074
                if (found)
 
2075
                        break;
 
2076
                off = next_off;
 
2077
        }
 
2078
        ret = TRUE;
 
2079
out:
 
2080
        if (dwarfd != NULL)
 
2081
                dwarf_end(dwarfd);
 
2082
        if (elfd != NULL)
 
2083
                elf_end(elfd);
 
2084
 
 
2085
        return ret;
 
2086
}
 
2087
 
 
2088
/*
 
2089
 * Get the size of structure.
 
2090
 */
 
2091
long
 
2092
get_structure_size(char *structname, int flag_typedef)
 
2093
{
 
2094
        if (flag_typedef)
 
2095
                dwarf_info.cmd = DWARF_INFO_GET_TYPEDEF_SIZE;
 
2096
        else
 
2097
                dwarf_info.cmd = DWARF_INFO_GET_STRUCT_SIZE;
 
2098
 
 
2099
        dwarf_info.struct_name = structname;
 
2100
        dwarf_info.struct_size = NOT_FOUND_STRUCTURE;
 
2101
 
 
2102
        if (!get_debug_info())
 
2103
                return FAILED_DWARFINFO;
 
2104
 
 
2105
        return dwarf_info.struct_size;
 
2106
}
 
2107
 
 
2108
/*
 
2109
 * Get the offset of member.
 
2110
 */
 
2111
long
 
2112
get_member_offset(char *structname, char *membername, int cmd)
 
2113
{
 
2114
        dwarf_info.cmd = cmd;
 
2115
        dwarf_info.struct_name = structname;
 
2116
        dwarf_info.struct_size = NOT_FOUND_STRUCTURE;
 
2117
        dwarf_info.member_name = membername;
 
2118
        dwarf_info.member_offset = NOT_FOUND_STRUCTURE;
 
2119
 
 
2120
        if (!get_debug_info())
 
2121
                return FAILED_DWARFINFO;
 
2122
 
 
2123
        return dwarf_info.member_offset;
 
2124
}
 
2125
 
 
2126
/*
 
2127
 * Get the length of array.
 
2128
 */
 
2129
long
 
2130
get_array_length(char *name01, char *name02, unsigned int cmd)
 
2131
{
 
2132
        switch (cmd) {
 
2133
        case DWARF_INFO_GET_SYMBOL_ARRAY_LENGTH:
 
2134
                dwarf_info.symbol_name = name01;
 
2135
                break;
 
2136
        case DWARF_INFO_CHECK_SYMBOL_ARRAY_TYPE:
 
2137
                dwarf_info.symbol_name = name01;
 
2138
                break;
 
2139
        case DWARF_INFO_GET_MEMBER_ARRAY_LENGTH:
 
2140
                dwarf_info.struct_name = name01;
 
2141
                dwarf_info.member_name = name02;
 
2142
                break;
 
2143
        }
 
2144
        dwarf_info.cmd           = cmd;
 
2145
        dwarf_info.struct_size   = NOT_FOUND_STRUCTURE;
 
2146
        dwarf_info.member_offset = NOT_FOUND_STRUCTURE;
 
2147
        dwarf_info.array_length  = NOT_FOUND_STRUCTURE;
 
2148
 
 
2149
        if (!get_debug_info())
 
2150
                return FAILED_DWARFINFO;
 
2151
 
 
2152
        return dwarf_info.array_length;
 
2153
}
 
2154
 
 
2155
long
 
2156
get_enum_number(char *enum_name) {
 
2157
 
 
2158
        dwarf_info.cmd         = DWARF_INFO_GET_ENUM_NUMBER;
 
2159
        dwarf_info.enum_name   = enum_name;
 
2160
        dwarf_info.enum_number = NOT_FOUND_NUMBER;
 
2161
 
 
2162
        if (!get_debug_info())
 
2163
                return FAILED_DWARFINFO;
 
2164
 
 
2165
        return dwarf_info.enum_number;
 
2166
}
 
2167
 
 
2168
/*
 
2169
 * Get the source filename.
 
2170
 */
 
2171
int
 
2172
get_source_filename(char *structname, char *src_name, int cmd)
 
2173
{
 
2174
        dwarf_info.cmd = cmd;
 
2175
        dwarf_info.struct_name = structname;
 
2176
 
 
2177
        if (!get_debug_info())
 
2178
                return FALSE;
 
2179
 
 
2180
        strncpy(src_name, dwarf_info.src_name, LEN_SRCFILE);
 
2181
 
 
2182
        return TRUE;
 
2183
}
 
2184
 
 
2185
int
 
2186
get_symbol_info(void)
 
2187
{
 
2188
        /*
 
2189
         * Get symbol info.
 
2190
         */
 
2191
        SYMBOL_INIT(mem_map, "mem_map");
 
2192
        SYMBOL_INIT(vmem_map, "vmem_map");
 
2193
        SYMBOL_INIT(mem_section, "mem_section");
 
2194
        SYMBOL_INIT(pkmap_count, "pkmap_count");
 
2195
        SYMBOL_INIT_NEXT(pkmap_count_next, "pkmap_count");
 
2196
        SYMBOL_INIT(system_utsname, "system_utsname");
 
2197
        SYMBOL_INIT(init_uts_ns, "init_uts_ns");
 
2198
        SYMBOL_INIT(_stext, "_stext");
 
2199
        SYMBOL_INIT(swapper_pg_dir, "swapper_pg_dir");
 
2200
        SYMBOL_INIT(init_level4_pgt, "init_level4_pgt");
 
2201
        SYMBOL_INIT(vmlist, "vmlist");
 
2202
        SYMBOL_INIT(phys_base, "phys_base");
 
2203
        SYMBOL_INIT(node_online_map, "node_online_map");
 
2204
        SYMBOL_INIT(node_states, "node_states");
 
2205
        SYMBOL_INIT(node_memblk, "node_memblk");
 
2206
        SYMBOL_INIT(node_data, "node_data");
 
2207
        SYMBOL_INIT(pgdat_list, "pgdat_list");
 
2208
        SYMBOL_INIT(contig_page_data, "contig_page_data");
 
2209
        SYMBOL_INIT(log_buf, "log_buf");
 
2210
        SYMBOL_INIT(log_buf_len, "log_buf_len");
 
2211
        SYMBOL_INIT(log_end, "log_end");
 
2212
        SYMBOL_INIT(max_pfn, "max_pfn");
 
2213
 
 
2214
        if (SYMBOL(node_data) != NOT_FOUND_SYMBOL)
 
2215
                SYMBOL_ARRAY_TYPE_INIT(node_data, "node_data");
 
2216
        if (SYMBOL(pgdat_list) != NOT_FOUND_SYMBOL)
 
2217
                SYMBOL_ARRAY_LENGTH_INIT(pgdat_list, "pgdat_list");
 
2218
        if (SYMBOL(mem_section) != NOT_FOUND_SYMBOL)
 
2219
                SYMBOL_ARRAY_LENGTH_INIT(mem_section, "mem_section");
 
2220
        if (SYMBOL(node_memblk) != NOT_FOUND_SYMBOL)
 
2221
                SYMBOL_ARRAY_LENGTH_INIT(node_memblk, "node_memblk");
 
2222
 
 
2223
        return TRUE;
 
2224
}
 
2225
 
 
2226
int
 
2227
get_structure_info(void)
 
2228
{
 
2229
        /*
 
2230
         * Get offsets of the page_discriptor's members.
 
2231
         */
 
2232
        SIZE_INIT(page, "page");
 
2233
        OFFSET_INIT(page.flags, "page", "flags");
 
2234
        OFFSET_INIT(page._count, "page", "_count");
 
2235
 
 
2236
        OFFSET_INIT(page.mapping, "page", "mapping");
 
2237
 
 
2238
        /*
 
2239
         * On linux-2.6.16 or later, page.mapping is defined
 
2240
         * in anonymous union.
 
2241
         */
 
2242
        if (OFFSET(page.mapping) == NOT_FOUND_STRUCTURE)
 
2243
                OFFSET_IN_UNION_INIT(page.mapping, "page", "mapping");
 
2244
 
 
2245
        /*
 
2246
         * Some vmlinux(s) don't have debugging information about
 
2247
         * page.mapping. Then, makedumpfile assumes that there is
 
2248
         * "mapping" next to "private(unsigned long)" in the first
 
2249
         * union.
 
2250
         */
 
2251
        if (OFFSET(page.mapping) == NOT_FOUND_STRUCTURE) {
 
2252
                OFFSET(page.mapping) = get_member_offset("page", NULL,
 
2253
                    DWARF_INFO_GET_MEMBER_OFFSET_1ST_UNION);
 
2254
                if (OFFSET(page.mapping) == FAILED_DWARFINFO)
 
2255
                        return FALSE;
 
2256
                if (OFFSET(page.mapping) != NOT_FOUND_STRUCTURE)
 
2257
                        OFFSET(page.mapping) += sizeof(unsigned long);
 
2258
        }
 
2259
 
 
2260
        OFFSET_INIT(page.lru, "page", "lru");
 
2261
 
 
2262
        /*
 
2263
         * Get offsets of the mem_section's members.
 
2264
         */
 
2265
        SIZE_INIT(mem_section, "mem_section");
 
2266
        OFFSET_INIT(mem_section.section_mem_map, "mem_section",
 
2267
            "section_mem_map");
 
2268
 
 
2269
        /*
 
2270
         * Get offsets of the pglist_data's members.
 
2271
         */
 
2272
        SIZE_INIT(pglist_data, "pglist_data");
 
2273
        OFFSET_INIT(pglist_data.node_zones, "pglist_data", "node_zones");
 
2274
        OFFSET_INIT(pglist_data.nr_zones, "pglist_data", "nr_zones");
 
2275
        OFFSET_INIT(pglist_data.node_mem_map, "pglist_data", "node_mem_map");
 
2276
        OFFSET_INIT(pglist_data.node_start_pfn, "pglist_data","node_start_pfn");
 
2277
        OFFSET_INIT(pglist_data.node_spanned_pages, "pglist_data",
 
2278
            "node_spanned_pages");
 
2279
        OFFSET_INIT(pglist_data.pgdat_next, "pglist_data", "pgdat_next");
 
2280
 
 
2281
        /*
 
2282
         * Get offsets of the zone's members.
 
2283
         */
 
2284
        SIZE_INIT(zone, "zone");
 
2285
        OFFSET_INIT(zone.free_pages, "zone", "free_pages");
 
2286
        OFFSET_INIT(zone.free_area, "zone", "free_area");
 
2287
        OFFSET_INIT(zone.vm_stat, "zone", "vm_stat");
 
2288
        OFFSET_INIT(zone.spanned_pages, "zone", "spanned_pages");
 
2289
        MEMBER_ARRAY_LENGTH_INIT(zone.free_area, "zone", "free_area");
 
2290
 
 
2291
        /*
 
2292
         * Get offsets of the free_area's members.
 
2293
         */
 
2294
        SIZE_INIT(free_area, "free_area");
 
2295
        OFFSET_INIT(free_area.free_list, "free_area", "free_list");
 
2296
        MEMBER_ARRAY_LENGTH_INIT(free_area.free_list, "free_area", "free_list");
 
2297
 
 
2298
        /*
 
2299
         * Get offsets of the list_head's members.
 
2300
         */
 
2301
        SIZE_INIT(list_head, "list_head");
 
2302
        OFFSET_INIT(list_head.next, "list_head", "next");
 
2303
        OFFSET_INIT(list_head.prev, "list_head", "prev");
 
2304
 
 
2305
        /*
 
2306
         * Get offsets of the node_memblk_s's members.
 
2307
         */
 
2308
        SIZE_INIT(node_memblk_s, "node_memblk_s");
 
2309
        OFFSET_INIT(node_memblk_s.start_paddr, "node_memblk_s", "start_paddr");
 
2310
        OFFSET_INIT(node_memblk_s.size, "node_memblk_s", "size");
 
2311
        OFFSET_INIT(node_memblk_s.nid, "node_memblk_s", "nid");
 
2312
 
 
2313
        OFFSET_INIT(vm_struct.addr, "vm_struct", "addr");
 
2314
 
 
2315
        ENUM_NUMBER_INIT(NR_FREE_PAGES, "NR_FREE_PAGES");
 
2316
        ENUM_NUMBER_INIT(N_ONLINE, "N_ONLINE");
 
2317
 
 
2318
        ENUM_NUMBER_INIT(PG_lru, "PG_lru");
 
2319
        ENUM_NUMBER_INIT(PG_private, "PG_private");
 
2320
        ENUM_NUMBER_INIT(PG_swapcache, "PG_swapcache");
 
2321
 
 
2322
        TYPEDEF_SIZE_INIT(nodemask_t, "nodemask_t");
 
2323
 
 
2324
        return TRUE;
 
2325
}
 
2326
 
 
2327
int
 
2328
get_srcfile_info(void)
 
2329
{
 
2330
        TYPEDEF_SRCFILE_INIT(pud_t, "pud_t");
 
2331
 
 
2332
        return TRUE;
 
2333
}
 
2334
 
 
2335
int
 
2336
get_value_for_old_linux(void)
 
2337
{
 
2338
        if (NUMBER(PG_lru) == NOT_FOUND_NUMBER)
 
2339
                NUMBER(PG_lru) = PG_lru_ORIGINAL;
 
2340
        if (NUMBER(PG_private) == NOT_FOUND_NUMBER)
 
2341
                NUMBER(PG_private) = PG_private_ORIGINAL;
 
2342
        if (NUMBER(PG_swapcache) == NOT_FOUND_NUMBER)
 
2343
                NUMBER(PG_swapcache) = PG_swapcache_ORIGINAL;
 
2344
        return TRUE;
 
2345
}
 
2346
 
 
2347
int
 
2348
get_str_osrelease_from_vmlinux(void)
 
2349
{
 
2350
        struct utsname system_utsname;
 
2351
        unsigned long long utsname;
 
2352
        off_t offset;
 
2353
        const off_t failed = (off_t)-1;
 
2354
 
 
2355
        /*
 
2356
         * Get the kernel version.
 
2357
         */
 
2358
        if (SYMBOL(system_utsname) != NOT_FOUND_SYMBOL) {
 
2359
                utsname = SYMBOL(system_utsname);
 
2360
        } else if (SYMBOL(init_uts_ns) != NOT_FOUND_SYMBOL) {
 
2361
                utsname = SYMBOL(init_uts_ns) + sizeof(int);
 
2362
        } else {
 
2363
                ERRMSG("Can't get the symbol of system_utsname.\n");
 
2364
                return FALSE;
 
2365
        }
 
2366
        offset = vaddr_to_offset_slow(dwarf_info.fd_debuginfo,
 
2367
            dwarf_info.name_debuginfo, utsname);
 
2368
 
 
2369
        if (!offset) {
 
2370
                ERRMSG("Can't convert vaddr (%llx) of utsname to an offset.\n",
 
2371
                    utsname);
 
2372
                return FALSE;
 
2373
        }
 
2374
        if (lseek(dwarf_info.fd_debuginfo, offset, SEEK_SET) == failed) {
 
2375
                ERRMSG("Can't seek %s. %s\n", dwarf_info.name_debuginfo,
 
2376
                    strerror(errno));
 
2377
                return FALSE;
 
2378
        }
 
2379
        if (read(dwarf_info.fd_debuginfo, &system_utsname, sizeof system_utsname)
 
2380
            != sizeof system_utsname) {
 
2381
                ERRMSG("Can't read %s. %s\n", dwarf_info.name_debuginfo,
 
2382
                    strerror(errno));
 
2383
                return FALSE;
 
2384
        }
 
2385
        if (!strncpy(info->release, system_utsname.release, STRLEN_OSRELEASE)){
 
2386
                ERRMSG("Can't do strncpy for osrelease.");
 
2387
                return FALSE;
 
2388
        }
 
2389
        return TRUE;
 
2390
}
 
2391
 
 
2392
int
 
2393
is_sparsemem_extreme(void)
 
2394
{
 
2395
        if (ARRAY_LENGTH(mem_section)
 
2396
             == (NR_MEM_SECTIONS() / _SECTIONS_PER_ROOT_EXTREME()))
 
2397
                return TRUE;
 
2398
        else
 
2399
                return FALSE;
 
2400
}
 
2401
 
 
2402
int
 
2403
get_mem_type(void)
 
2404
{
 
2405
        int ret;
 
2406
 
 
2407
        if ((SIZE(page) == NOT_FOUND_STRUCTURE)
 
2408
            || (OFFSET(page.flags) == NOT_FOUND_STRUCTURE)
 
2409
            || (OFFSET(page._count) == NOT_FOUND_STRUCTURE)
 
2410
            || (OFFSET(page.mapping) == NOT_FOUND_STRUCTURE)) {
 
2411
                ret = NOT_FOUND_MEMTYPE;
 
2412
        } else if ((((SYMBOL(node_data) != NOT_FOUND_SYMBOL)
 
2413
                && (ARRAY_LENGTH(node_data) != NOT_FOUND_STRUCTURE))
 
2414
            || ((SYMBOL(pgdat_list) != NOT_FOUND_SYMBOL)
 
2415
                && (OFFSET(pglist_data.pgdat_next) != NOT_FOUND_STRUCTURE))
 
2416
            || ((SYMBOL(pgdat_list) != NOT_FOUND_SYMBOL)
 
2417
                && (ARRAY_LENGTH(pgdat_list) != NOT_FOUND_STRUCTURE)))
 
2418
            && (SIZE(pglist_data) != NOT_FOUND_STRUCTURE)
 
2419
            && (OFFSET(pglist_data.node_mem_map) != NOT_FOUND_STRUCTURE)
 
2420
            && (OFFSET(pglist_data.node_start_pfn) != NOT_FOUND_STRUCTURE)
 
2421
            && (OFFSET(pglist_data.node_spanned_pages) !=NOT_FOUND_STRUCTURE)){
 
2422
                ret = DISCONTIGMEM;
 
2423
        } else if ((SYMBOL(mem_section) != NOT_FOUND_SYMBOL)
 
2424
            && (SIZE(mem_section) != NOT_FOUND_STRUCTURE)
 
2425
            && (OFFSET(mem_section.section_mem_map) != NOT_FOUND_STRUCTURE)
 
2426
            && (ARRAY_LENGTH(mem_section) != NOT_FOUND_STRUCTURE)) {
 
2427
                if (is_sparsemem_extreme())
 
2428
                        ret = SPARSEMEM_EX;
 
2429
                else
 
2430
                        ret = SPARSEMEM;
 
2431
        } else if (SYMBOL(mem_map) != NOT_FOUND_SYMBOL) {
 
2432
                ret = FLATMEM;
 
2433
        } else {
 
2434
                ret = NOT_FOUND_MEMTYPE;
 
2435
        }
 
2436
 
 
2437
        return ret;
 
2438
}
 
2439
 
 
2440
int
 
2441
generate_vmcoreinfo(void)
 
2442
{
 
2443
        if (!set_page_size(sysconf(_SC_PAGE_SIZE)))
 
2444
                return FALSE;
 
2445
 
 
2446
        dwarf_info.fd_debuginfo   = info->fd_vmlinux;
 
2447
        dwarf_info.name_debuginfo = info->name_vmlinux;
 
2448
 
 
2449
        if (!get_symbol_info())
 
2450
                return FALSE;
 
2451
 
 
2452
        if (!get_structure_info())
 
2453
                return FALSE;
 
2454
 
 
2455
        if (!get_srcfile_info())
 
2456
                return FALSE;
 
2457
 
 
2458
        if ((SYMBOL(system_utsname) == NOT_FOUND_SYMBOL)
 
2459
            && (SYMBOL(init_uts_ns) == NOT_FOUND_SYMBOL)) {
 
2460
                ERRMSG("Can't get the symbol of system_utsname.\n");
 
2461
                return FALSE;
 
2462
        }
 
2463
        if (!get_str_osrelease_from_vmlinux())
 
2464
                return FALSE;
 
2465
 
 
2466
        if (!(info->kernel_version = get_kernel_version(info->release)))
 
2467
                return FALSE;
 
2468
 
 
2469
        if (get_mem_type() == NOT_FOUND_MEMTYPE) {
 
2470
                ERRMSG("Can't find the memory type.\n");
 
2471
                return FALSE;
 
2472
        }
 
2473
 
 
2474
        /*
 
2475
         * write 1st kernel's OSRELEASE
 
2476
         */
 
2477
        fprintf(info->file_vmcoreinfo, "%s%s\n", STR_OSRELEASE,
 
2478
            info->release);
 
2479
 
 
2480
        /*
 
2481
         * write 1st kernel's PAGESIZE
 
2482
         */
 
2483
        fprintf(info->file_vmcoreinfo, "%s%ld\n", STR_PAGESIZE,
 
2484
            info->page_size);
 
2485
 
 
2486
        /*
 
2487
         * write the symbol of 1st kernel
 
2488
         */
 
2489
        WRITE_SYMBOL("mem_map", mem_map);
 
2490
        WRITE_SYMBOL("vmem_map", vmem_map);
 
2491
        WRITE_SYMBOL("mem_section", mem_section);
 
2492
        WRITE_SYMBOL("pkmap_count", pkmap_count);
 
2493
        WRITE_SYMBOL("pkmap_count_next", pkmap_count_next);
 
2494
        WRITE_SYMBOL("system_utsname", system_utsname);
 
2495
        WRITE_SYMBOL("init_uts_ns", init_uts_ns);
 
2496
        WRITE_SYMBOL("_stext", _stext);
 
2497
        WRITE_SYMBOL("swapper_pg_dir", swapper_pg_dir);
 
2498
        WRITE_SYMBOL("init_level4_pgt", init_level4_pgt);
 
2499
        WRITE_SYMBOL("vmlist", vmlist);
 
2500
        WRITE_SYMBOL("phys_base", phys_base);
 
2501
        WRITE_SYMBOL("node_online_map", node_online_map);
 
2502
        WRITE_SYMBOL("node_states", node_states);
 
2503
        WRITE_SYMBOL("node_data", node_data);
 
2504
        WRITE_SYMBOL("pgdat_list", pgdat_list);
 
2505
        WRITE_SYMBOL("contig_page_data", contig_page_data);
 
2506
        WRITE_SYMBOL("log_buf", log_buf);
 
2507
        WRITE_SYMBOL("log_buf_len", log_buf_len);
 
2508
        WRITE_SYMBOL("log_end", log_end);
 
2509
        WRITE_SYMBOL("max_pfn", max_pfn);
 
2510
 
 
2511
        /*
 
2512
         * write the structure size of 1st kernel
 
2513
         */
 
2514
        WRITE_STRUCTURE_SIZE("page", page);
 
2515
        WRITE_STRUCTURE_SIZE("mem_section", mem_section);
 
2516
        WRITE_STRUCTURE_SIZE("pglist_data", pglist_data);
 
2517
        WRITE_STRUCTURE_SIZE("zone", zone);
 
2518
        WRITE_STRUCTURE_SIZE("free_area", free_area);
 
2519
        WRITE_STRUCTURE_SIZE("list_head", list_head);
 
2520
        WRITE_STRUCTURE_SIZE("node_memblk_s", node_memblk_s);
 
2521
        WRITE_STRUCTURE_SIZE("nodemask_t", nodemask_t);
 
2522
 
 
2523
        /*
 
2524
         * write the member offset of 1st kernel
 
2525
         */
 
2526
        WRITE_MEMBER_OFFSET("page.flags", page.flags);
 
2527
        WRITE_MEMBER_OFFSET("page._count", page._count);
 
2528
        WRITE_MEMBER_OFFSET("page.mapping", page.mapping);
 
2529
        WRITE_MEMBER_OFFSET("page.lru", page.lru);
 
2530
        WRITE_MEMBER_OFFSET("mem_section.section_mem_map",
 
2531
            mem_section.section_mem_map);
 
2532
        WRITE_MEMBER_OFFSET("pglist_data.node_zones", pglist_data.node_zones);
 
2533
        WRITE_MEMBER_OFFSET("pglist_data.nr_zones", pglist_data.nr_zones);
 
2534
        WRITE_MEMBER_OFFSET("pglist_data.node_mem_map",
 
2535
            pglist_data.node_mem_map);
 
2536
        WRITE_MEMBER_OFFSET("pglist_data.node_start_pfn",
 
2537
            pglist_data.node_start_pfn);
 
2538
        WRITE_MEMBER_OFFSET("pglist_data.node_spanned_pages",
 
2539
            pglist_data.node_spanned_pages);
 
2540
        WRITE_MEMBER_OFFSET("pglist_data.pgdat_next", pglist_data.pgdat_next);
 
2541
        WRITE_MEMBER_OFFSET("zone.free_pages", zone.free_pages);
 
2542
        WRITE_MEMBER_OFFSET("zone.free_area", zone.free_area);
 
2543
        WRITE_MEMBER_OFFSET("zone.vm_stat", zone.vm_stat);
 
2544
        WRITE_MEMBER_OFFSET("zone.spanned_pages", zone.spanned_pages);
 
2545
        WRITE_MEMBER_OFFSET("free_area.free_list", free_area.free_list);
 
2546
        WRITE_MEMBER_OFFSET("list_head.next", list_head.next);
 
2547
        WRITE_MEMBER_OFFSET("list_head.prev", list_head.prev);
 
2548
        WRITE_MEMBER_OFFSET("node_memblk_s.start_paddr", node_memblk_s.start_paddr);
 
2549
        WRITE_MEMBER_OFFSET("node_memblk_s.size", node_memblk_s.size);
 
2550
        WRITE_MEMBER_OFFSET("node_memblk_s.nid", node_memblk_s.nid);
 
2551
        WRITE_MEMBER_OFFSET("vm_struct.addr", vm_struct.addr);
 
2552
 
 
2553
        if (SYMBOL(node_data) != NOT_FOUND_SYMBOL)
 
2554
                WRITE_ARRAY_LENGTH("node_data", node_data);
 
2555
        if (SYMBOL(pgdat_list) != NOT_FOUND_SYMBOL)
 
2556
                WRITE_ARRAY_LENGTH("pgdat_list", pgdat_list);
 
2557
        if (SYMBOL(mem_section) != NOT_FOUND_SYMBOL)
 
2558
                WRITE_ARRAY_LENGTH("mem_section", mem_section);
 
2559
        if (SYMBOL(node_memblk) != NOT_FOUND_SYMBOL)
 
2560
                WRITE_ARRAY_LENGTH("node_memblk", node_memblk);
 
2561
 
 
2562
        WRITE_ARRAY_LENGTH("zone.free_area", zone.free_area);
 
2563
        WRITE_ARRAY_LENGTH("free_area.free_list", free_area.free_list);
 
2564
 
 
2565
        WRITE_NUMBER("NR_FREE_PAGES", NR_FREE_PAGES);
 
2566
        WRITE_NUMBER("N_ONLINE", N_ONLINE);
 
2567
 
 
2568
        WRITE_NUMBER("PG_lru", PG_lru);
 
2569
        WRITE_NUMBER("PG_private", PG_private);
 
2570
        WRITE_NUMBER("PG_swapcache", PG_swapcache);
 
2571
 
 
2572
        /*
 
2573
         * write the source file of 1st kernel
 
2574
         */
 
2575
        WRITE_SRCFILE("pud_t", pud_t);
 
2576
 
 
2577
        return TRUE;
 
2578
}
 
2579
 
 
2580
int
 
2581
read_vmcoreinfo_basic_info(void)
 
2582
{
 
2583
        time_t tv_sec = 0;
 
2584
        long page_size = FALSE;
 
2585
        char buf[BUFSIZE_FGETS], *endp;
 
2586
        unsigned int get_release = FALSE, i;
 
2587
 
 
2588
        if (fseek(info->file_vmcoreinfo, 0, SEEK_SET) < 0) {
 
2589
                ERRMSG("Can't seek the vmcoreinfo file(%s). %s\n",
 
2590
                    info->name_vmcoreinfo, strerror(errno));
 
2591
                return FALSE;
 
2592
        }
 
2593
 
 
2594
        while (fgets(buf, BUFSIZE_FGETS, info->file_vmcoreinfo)) {
 
2595
                i = strlen(buf);
 
2596
                if (!i)
 
2597
                        break;
 
2598
                if (buf[i - 1] == '\n')
 
2599
                        buf[i - 1] = '\0';
 
2600
                if (strncmp(buf, STR_OSRELEASE, strlen(STR_OSRELEASE)) == 0) {
 
2601
                        get_release = TRUE;
 
2602
                        /* if the release have been stored, skip this time. */
 
2603
                        if (strlen(info->release))
 
2604
                                continue;
 
2605
                        strcpy(info->release, buf + strlen(STR_OSRELEASE));
 
2606
                }
 
2607
                if (strncmp(buf, STR_PAGESIZE, strlen(STR_PAGESIZE)) == 0) {
 
2608
                        page_size = strtol(buf+strlen(STR_PAGESIZE),&endp,10);
 
2609
                        if ((!page_size || page_size == LONG_MAX)
 
2610
                            || strlen(endp) != 0) {
 
2611
                                ERRMSG("Invalid data in %s: %s",
 
2612
                                    info->name_vmcoreinfo, buf);
 
2613
                                return FALSE;
 
2614
                        }
 
2615
                        if (!set_page_size(page_size)) {
 
2616
                                ERRMSG("Invalid data in %s: %s",
 
2617
                                    info->name_vmcoreinfo, buf);
 
2618
                                return FALSE;
 
2619
                        }
 
2620
                }
 
2621
                if (strncmp(buf, STR_CRASHTIME, strlen(STR_CRASHTIME)) == 0) {
 
2622
                        tv_sec = strtol(buf+strlen(STR_CRASHTIME),&endp,10);
 
2623
                        if ((!tv_sec || tv_sec == LONG_MAX)
 
2624
                            || strlen(endp) != 0) {
 
2625
                                ERRMSG("Invalid data in %s: %s",
 
2626
                                    info->name_vmcoreinfo, buf);
 
2627
                                return FALSE;
 
2628
                        }
 
2629
                        info->timestamp.tv_sec = tv_sec;
 
2630
                }
 
2631
                if (strncmp(buf, STR_CONFIG_X86_PAE,
 
2632
                    strlen(STR_CONFIG_X86_PAE)) == 0)
 
2633
                        vt.mem_flags |= MEMORY_X86_PAE;
 
2634
 
 
2635
                if (strncmp(buf, STR_CONFIG_PGTABLE_3,
 
2636
                    strlen(STR_CONFIG_PGTABLE_3)) == 0)
 
2637
                        vt.mem_flags |= MEMORY_PAGETABLE_3L;
 
2638
 
 
2639
                if (strncmp(buf, STR_CONFIG_PGTABLE_4,
 
2640
                    strlen(STR_CONFIG_PGTABLE_4)) == 0)
 
2641
                        vt.mem_flags |= MEMORY_PAGETABLE_4L;
 
2642
        }
 
2643
        if (!get_release || !info->page_size) {
 
2644
                ERRMSG("Invalid format in %s", info->name_vmcoreinfo);
 
2645
                return FALSE;
 
2646
        }
 
2647
        return TRUE;
 
2648
}
 
2649
 
 
2650
unsigned long
 
2651
read_vmcoreinfo_symbol(char *str_symbol)
 
2652
{
 
2653
        unsigned long symbol = NOT_FOUND_SYMBOL;
 
2654
        char buf[BUFSIZE_FGETS], *endp;
 
2655
        unsigned int i;
 
2656
 
 
2657
        if (fseek(info->file_vmcoreinfo, 0, SEEK_SET) < 0) {
 
2658
                ERRMSG("Can't seek the vmcoreinfo file(%s). %s\n",
 
2659
                    info->name_vmcoreinfo, strerror(errno));
 
2660
                return INVALID_SYMBOL_DATA;
 
2661
        }
 
2662
 
 
2663
        while (fgets(buf, BUFSIZE_FGETS, info->file_vmcoreinfo)) {
 
2664
                i = strlen(buf);
 
2665
                if (!i)
 
2666
                        break;
 
2667
                if (buf[i - 1] == '\n')
 
2668
                        buf[i - 1] = '\0';
 
2669
                if (strncmp(buf, str_symbol, strlen(str_symbol)) == 0) {
 
2670
                        symbol = strtoul(buf + strlen(str_symbol), &endp, 16);
 
2671
                        if ((!symbol || symbol == ULONG_MAX)
 
2672
                            || strlen(endp) != 0) {
 
2673
                                ERRMSG("Invalid data in %s: %s",
 
2674
                                    info->name_vmcoreinfo, buf);
 
2675
                                return INVALID_SYMBOL_DATA;
 
2676
                        }
 
2677
                        break;
 
2678
                }
 
2679
        }
 
2680
        return symbol;
 
2681
}
 
2682
 
 
2683
long
 
2684
read_vmcoreinfo_long(char *str_structure)
 
2685
{
 
2686
        long data = NOT_FOUND_LONG_VALUE;
 
2687
        char buf[BUFSIZE_FGETS], *endp;
 
2688
        unsigned int i;
 
2689
 
 
2690
        if (fseek(info->file_vmcoreinfo, 0, SEEK_SET) < 0) {
 
2691
                ERRMSG("Can't seek the vmcoreinfo file(%s). %s\n",
 
2692
                    info->name_vmcoreinfo, strerror(errno));
 
2693
                return INVALID_STRUCTURE_DATA;
 
2694
        }
 
2695
 
 
2696
        while (fgets(buf, BUFSIZE_FGETS, info->file_vmcoreinfo)) {
 
2697
                i = strlen(buf);
 
2698
                if (!i)
 
2699
                        break;
 
2700
                if (buf[i - 1] == '\n')
 
2701
                        buf[i - 1] = '\0';
 
2702
                if (strncmp(buf, str_structure, strlen(str_structure)) == 0) {
 
2703
                        data = strtol(buf + strlen(str_structure), &endp, 10);
 
2704
                        if ((data == LONG_MAX) || strlen(endp) != 0) {
 
2705
                                ERRMSG("Invalid data in %s: %s",
 
2706
                                    info->name_vmcoreinfo, buf);
 
2707
                                return INVALID_STRUCTURE_DATA;
 
2708
                        }
 
2709
                        break;
 
2710
                }
 
2711
        }
 
2712
        return data;
 
2713
}
 
2714
 
 
2715
int
 
2716
read_vmcoreinfo_string(char *str_in, char *str_out)
 
2717
{
 
2718
        char buf[BUFSIZE_FGETS];
 
2719
        unsigned int i;
 
2720
 
 
2721
        if (fseek(info->file_vmcoreinfo, 0, SEEK_SET) < 0) {
 
2722
                ERRMSG("Can't seek the vmcoreinfo file(%s). %s\n",
 
2723
                    info->name_vmcoreinfo, strerror(errno));
 
2724
                return FALSE;
 
2725
        }
 
2726
 
 
2727
        while (fgets(buf, BUFSIZE_FGETS, info->file_vmcoreinfo)) {
 
2728
                i = strlen(buf);
 
2729
                if (!i)
 
2730
                        break;
 
2731
                if (buf[i - 1] == '\n')
 
2732
                        buf[i - 1] = '\0';
 
2733
                if (strncmp(buf, str_in, strlen(str_in)) == 0) {
 
2734
                        strncpy(str_out, buf + strlen(str_in), LEN_SRCFILE - strlen(str_in));
 
2735
                        break;
 
2736
                }
 
2737
        }
 
2738
        return TRUE;
 
2739
}
 
2740
 
 
2741
int
 
2742
read_vmcoreinfo(void)
 
2743
{
 
2744
        if (!read_vmcoreinfo_basic_info())
 
2745
                return FALSE;
 
2746
 
 
2747
        READ_SYMBOL("mem_map", mem_map);
 
2748
        READ_SYMBOL("vmem_map", vmem_map);
 
2749
        READ_SYMBOL("mem_section", mem_section);
 
2750
        READ_SYMBOL("pkmap_count", pkmap_count);
 
2751
        READ_SYMBOL("pkmap_count_next", pkmap_count_next);
 
2752
        READ_SYMBOL("system_utsname", system_utsname);
 
2753
        READ_SYMBOL("init_uts_ns", init_uts_ns);
 
2754
        READ_SYMBOL("_stext", _stext);
 
2755
        READ_SYMBOL("swapper_pg_dir", swapper_pg_dir);
 
2756
        READ_SYMBOL("init_level4_pgt", init_level4_pgt);
 
2757
        READ_SYMBOL("vmlist", vmlist);
 
2758
        READ_SYMBOL("phys_base", phys_base);
 
2759
        READ_SYMBOL("node_online_map", node_online_map);
 
2760
        READ_SYMBOL("node_states", node_states);
 
2761
        READ_SYMBOL("node_data", node_data);
 
2762
        READ_SYMBOL("pgdat_list", pgdat_list);
 
2763
        READ_SYMBOL("contig_page_data", contig_page_data);
 
2764
        READ_SYMBOL("log_buf", log_buf);
 
2765
        READ_SYMBOL("log_buf_len", log_buf_len);
 
2766
        READ_SYMBOL("log_end", log_end);
 
2767
        READ_SYMBOL("max_pfn", max_pfn);
 
2768
 
 
2769
        READ_STRUCTURE_SIZE("page", page);
 
2770
        READ_STRUCTURE_SIZE("mem_section", mem_section);
 
2771
        READ_STRUCTURE_SIZE("pglist_data", pglist_data);
 
2772
        READ_STRUCTURE_SIZE("zone", zone);
 
2773
        READ_STRUCTURE_SIZE("free_area", free_area);
 
2774
        READ_STRUCTURE_SIZE("list_head", list_head);
 
2775
        READ_STRUCTURE_SIZE("node_memblk_s", node_memblk_s);
 
2776
        READ_STRUCTURE_SIZE("nodemask_t", nodemask_t);
 
2777
 
 
2778
        READ_MEMBER_OFFSET("page.flags", page.flags);
 
2779
        READ_MEMBER_OFFSET("page._count", page._count);
 
2780
        READ_MEMBER_OFFSET("page.mapping", page.mapping);
 
2781
        READ_MEMBER_OFFSET("page.lru", page.lru);
 
2782
        READ_MEMBER_OFFSET("mem_section.section_mem_map",
 
2783
            mem_section.section_mem_map);
 
2784
        READ_MEMBER_OFFSET("pglist_data.node_zones", pglist_data.node_zones);
 
2785
        READ_MEMBER_OFFSET("pglist_data.nr_zones", pglist_data.nr_zones);
 
2786
        READ_MEMBER_OFFSET("pglist_data.node_mem_map",pglist_data.node_mem_map);
 
2787
        READ_MEMBER_OFFSET("pglist_data.node_start_pfn",
 
2788
            pglist_data.node_start_pfn);
 
2789
        READ_MEMBER_OFFSET("pglist_data.node_spanned_pages",
 
2790
            pglist_data.node_spanned_pages);
 
2791
        READ_MEMBER_OFFSET("pglist_data.pgdat_next", pglist_data.pgdat_next);
 
2792
        READ_MEMBER_OFFSET("zone.free_pages", zone.free_pages);
 
2793
        READ_MEMBER_OFFSET("zone.free_area", zone.free_area);
 
2794
        READ_MEMBER_OFFSET("zone.vm_stat", zone.vm_stat);
 
2795
        READ_MEMBER_OFFSET("zone.spanned_pages", zone.spanned_pages);
 
2796
        READ_MEMBER_OFFSET("free_area.free_list", free_area.free_list);
 
2797
        READ_MEMBER_OFFSET("list_head.next", list_head.next);
 
2798
        READ_MEMBER_OFFSET("list_head.prev", list_head.prev);
 
2799
        READ_MEMBER_OFFSET("node_memblk_s.start_paddr", node_memblk_s.start_paddr);
 
2800
        READ_MEMBER_OFFSET("node_memblk_s.size", node_memblk_s.size);
 
2801
        READ_MEMBER_OFFSET("node_memblk_s.nid", node_memblk_s.nid);
 
2802
        READ_MEMBER_OFFSET("vm_struct.addr", vm_struct.addr);
 
2803
 
 
2804
        READ_ARRAY_LENGTH("node_data", node_data);
 
2805
        READ_ARRAY_LENGTH("pgdat_list", pgdat_list);
 
2806
        READ_ARRAY_LENGTH("mem_section", mem_section);
 
2807
        READ_ARRAY_LENGTH("node_memblk", node_memblk);
 
2808
        READ_ARRAY_LENGTH("zone.free_area", zone.free_area);
 
2809
        READ_ARRAY_LENGTH("free_area.free_list", free_area.free_list);
 
2810
 
 
2811
        READ_NUMBER("NR_FREE_PAGES", NR_FREE_PAGES);
 
2812
        READ_NUMBER("N_ONLINE", N_ONLINE);
 
2813
 
 
2814
        READ_NUMBER("PG_lru", PG_lru);
 
2815
        READ_NUMBER("PG_private", PG_private);
 
2816
        READ_NUMBER("PG_swapcache", PG_swapcache);
 
2817
 
 
2818
        READ_SRCFILE("pud_t", pud_t);
 
2819
 
 
2820
        return TRUE;
 
2821
}
 
2822
 
 
2823
#define MAX_SIZE_NHDR   MAX(sizeof(Elf64_Nhdr), sizeof(Elf32_Nhdr))
 
2824
 
 
2825
off_t
 
2826
offset_next_note(void *note)
 
2827
{
 
2828
        off_t offset;
 
2829
        Elf64_Nhdr *note64;
 
2830
        Elf32_Nhdr *note32;
 
2831
 
 
2832
        /*
 
2833
         * Both name and desc in ELF Note elements are padded to
 
2834
         * 4 byte boundary.
 
2835
         */
 
2836
        if (info->flag_elf64_memory) {
 
2837
                note64 = (Elf64_Nhdr *)note;
 
2838
                offset = sizeof(Elf64_Nhdr)
 
2839
                    + roundup(note64->n_namesz, 4)
 
2840
                    + roundup(note64->n_descsz, 4);
 
2841
        } else {
 
2842
                note32 = (Elf32_Nhdr *)note;
 
2843
                offset = sizeof(Elf32_Nhdr)
 
2844
                    + roundup(note32->n_namesz, 4)
 
2845
                    + roundup(note32->n_descsz, 4);
 
2846
        }
 
2847
        return offset;
 
2848
}
 
2849
 
 
2850
int
 
2851
note_type(void *note)
 
2852
{
 
2853
        int type;
 
2854
        Elf64_Nhdr *note64;
 
2855
        Elf32_Nhdr *note32;
 
2856
 
 
2857
        if (info->flag_elf64_memory) {
 
2858
                note64 = (Elf64_Nhdr *)note;
 
2859
                type = note64->n_type;
 
2860
        } else {
 
2861
                note32 = (Elf32_Nhdr *)note;
 
2862
                type = note32->n_type;
 
2863
        }
 
2864
        return type;
 
2865
}
 
2866
 
 
2867
int
 
2868
note_descsz(void *note)
 
2869
{
 
2870
        int size;
 
2871
        Elf64_Nhdr *note64;
 
2872
        Elf32_Nhdr *note32;
 
2873
 
 
2874
        if (info->flag_elf64_memory) {
 
2875
                note64 = (Elf64_Nhdr *)note;
 
2876
                size = note64->n_descsz;
 
2877
        } else {
 
2878
                note32 = (Elf32_Nhdr *)note;
 
2879
                size = note32->n_descsz;
 
2880
        }
 
2881
        return size;
 
2882
}
 
2883
 
 
2884
off_t
 
2885
offset_note_desc(void *note)
 
2886
{
 
2887
        off_t offset;
 
2888
        Elf64_Nhdr *note64;
 
2889
        Elf32_Nhdr *note32;
 
2890
 
 
2891
        if (info->flag_elf64_memory) {
 
2892
                note64 = (Elf64_Nhdr *)note;
 
2893
                offset = sizeof(Elf64_Nhdr) + roundup(note64->n_namesz, 4);
 
2894
        } else {
 
2895
                note32 = (Elf32_Nhdr *)note;
 
2896
                offset = sizeof(Elf32_Nhdr) + roundup(note32->n_namesz, 4);
 
2897
        }
 
2898
        return offset;
 
2899
}
 
2900
 
 
2901
int
 
2902
get_pt_note_info(off_t off_note, unsigned long sz_note)
 
2903
{
 
2904
        int n_type, size_desc;
 
2905
        unsigned long p2m_mfn;
 
2906
        off_t offset, offset_desc, off_p2m = 0;
 
2907
        char buf[VMCOREINFO_XEN_NOTE_NAME_BYTES];
 
2908
        char note[MAX_SIZE_NHDR];
 
2909
        const off_t failed = (off_t)-1;
 
2910
 
 
2911
        offset = off_note;
 
2912
        while (offset < off_note + sz_note) {
 
2913
                if (lseek(info->fd_memory, offset, SEEK_SET) == failed) {
 
2914
                        ERRMSG("Can't seek the dump memory(%s). %s\n",
 
2915
                            info->name_memory, strerror(errno));
 
2916
                        return FALSE;
 
2917
                }
 
2918
                if (read(info->fd_memory, note, sizeof(note)) != sizeof(note)) {
 
2919
                        ERRMSG("Can't read the dump memory(%s). %s\n",
 
2920
                            info->name_memory, strerror(errno));
 
2921
                        return FALSE;
 
2922
                }
 
2923
                if (read(info->fd_memory, &buf, sizeof(buf)) != sizeof(buf)) {
 
2924
                        ERRMSG("Can't read the dump memory(%s). %s\n",
 
2925
                            info->name_memory, strerror(errno));
 
2926
                        return FALSE;
 
2927
                }
 
2928
                n_type = note_type(note);
 
2929
 
 
2930
                if (n_type == NT_PRSTATUS) {
 
2931
                        info->nr_cpus++;
 
2932
                        offset += offset_next_note(note);
 
2933
                        continue;
 
2934
                }
 
2935
                offset_desc = offset + offset_note_desc(note);
 
2936
                size_desc   = note_descsz(note);
 
2937
 
 
2938
                /*
 
2939
                 * Check whether /proc/vmcore contains vmcoreinfo,
 
2940
                 * and get both the offset and the size.
 
2941
                 *
 
2942
                 * NOTE: The owner name of xen should be checked at first,
 
2943
                 *       because its name is "VMCOREINFO_XEN" and the one
 
2944
                 *       of linux is "VMCOREINFO".
 
2945
                 */
 
2946
                if (!strncmp(VMCOREINFO_XEN_NOTE_NAME, buf,
 
2947
                    VMCOREINFO_XEN_NOTE_NAME_BYTES)) {
 
2948
                        info->offset_vmcoreinfo_xen = offset_desc;
 
2949
                        info->size_vmcoreinfo_xen   = size_desc;
 
2950
                } else if (!strncmp(VMCOREINFO_NOTE_NAME, buf,
 
2951
                    VMCOREINFO_NOTE_NAME_BYTES)) {
 
2952
                        info->offset_vmcoreinfo = offset_desc;
 
2953
                        info->size_vmcoreinfo   = size_desc;
 
2954
 
 
2955
                /*
 
2956
                 * Check whether /proc/vmcore contains xen's note.
 
2957
                 */
 
2958
                } else if (n_type == XEN_ELFNOTE_CRASH_INFO) {
 
2959
                        vt.mem_flags |= MEMORY_XEN;
 
2960
                        info->offset_xen_crash_info = offset_desc;
 
2961
                        info->size_xen_crash_info   = size_desc;
 
2962
 
 
2963
                        off_p2m = offset + offset_next_note(note)
 
2964
                                         - sizeof(p2m_mfn);
 
2965
                        if (lseek(info->fd_memory, off_p2m, SEEK_SET)
 
2966
                            == failed){
 
2967
                                ERRMSG("Can't seek the dump memory(%s). %s\n",
 
2968
                                    info->name_memory, strerror(errno));
 
2969
                                return FALSE;
 
2970
                        }
 
2971
                        if (read(info->fd_memory, &p2m_mfn, sizeof(p2m_mfn))
 
2972
                             != sizeof(p2m_mfn)) {
 
2973
                                ERRMSG("Can't read the dump memory(%s). %s\n",
 
2974
                                    info->name_memory, strerror(errno));
 
2975
                                return FALSE;
 
2976
                        }
 
2977
                        info->p2m_mfn = p2m_mfn;
 
2978
                }
 
2979
                offset += offset_next_note(note);
 
2980
        }
 
2981
        if (vt.mem_flags & MEMORY_XEN)
 
2982
                DEBUG_MSG("Xen kdump\n");
 
2983
        else
 
2984
                DEBUG_MSG("Linux kdump\n");
 
2985
 
 
2986
        return TRUE;
 
2987
}
 
2988
 
 
2989
/*
 
2990
 * Extract vmcoreinfo from /proc/vmcore and output it to /tmp/vmcoreinfo.tmp.
 
2991
 */
 
2992
int
 
2993
copy_vmcoreinfo(off_t offset, unsigned long size)
 
2994
{
 
2995
        int fd;
 
2996
        char buf[VMCOREINFO_BYTES];
 
2997
        const off_t failed = (off_t)-1;
 
2998
 
 
2999
        if (!offset || !size)
 
3000
                return FALSE;
 
3001
 
 
3002
        if ((fd = mkstemp(info->name_vmcoreinfo)) < 0) {
 
3003
                ERRMSG("Can't open the vmcoreinfo file(%s). %s\n",
 
3004
                    info->name_vmcoreinfo, strerror(errno));
 
3005
                return FALSE;
 
3006
        }
 
3007
        if (lseek(info->fd_memory, offset, SEEK_SET) == failed) {
 
3008
                ERRMSG("Can't seek the dump memory(%s). %s\n",
 
3009
                    info->name_memory, strerror(errno));
 
3010
                return FALSE;
 
3011
        }
 
3012
        if (read(info->fd_memory, &buf, size) != size) {
 
3013
                ERRMSG("Can't read the dump memory(%s). %s\n",
 
3014
                    info->name_memory, strerror(errno));
 
3015
                return FALSE;
 
3016
        }
 
3017
        if (write(fd, &buf, size) != size) {
 
3018
                ERRMSG("Can't write the vmcoreinfo file(%s). %s\n",
 
3019
                    info->name_vmcoreinfo, strerror(errno));
 
3020
                return FALSE;
 
3021
        }
 
3022
        if (close(fd) < 0) {
 
3023
                ERRMSG("Can't close the vmcoreinfo file(%s). %s\n",
 
3024
                    info->name_vmcoreinfo, strerror(errno));
 
3025
                return FALSE;
 
3026
        }
 
3027
        return TRUE;
 
3028
}
 
3029
 
 
3030
int
 
3031
read_vmcoreinfo_from_vmcore(off_t offset, unsigned long size, int flag_xen_hv)
 
3032
{
 
3033
        int ret = FALSE;
 
3034
 
 
3035
        /*
 
3036
         * Copy vmcoreinfo to /tmp/vmcoreinfoXXXXXX.
 
3037
         */
 
3038
        if (!(info->name_vmcoreinfo = strdup(FILENAME_VMCOREINFO))) {
 
3039
                MSG("Can't duplicate strings(%s).\n", FILENAME_VMCOREINFO);
 
3040
                return FALSE;
 
3041
        }
 
3042
        if (!copy_vmcoreinfo(offset, size))
 
3043
                goto out;
 
3044
 
 
3045
        /*
 
3046
         * Read vmcoreinfo from /tmp/vmcoreinfoXXXXXX.
 
3047
         */
 
3048
        if (!open_vmcoreinfo("r"))
 
3049
                goto out;
 
3050
 
 
3051
        unlink(info->name_vmcoreinfo);
 
3052
 
 
3053
        if (flag_xen_hv) {
 
3054
                if (!read_vmcoreinfo_xen())
 
3055
                        goto out;
 
3056
        } else {
 
3057
                if (!read_vmcoreinfo())
 
3058
                        goto out;
 
3059
        }
 
3060
        close_vmcoreinfo();
 
3061
 
 
3062
        ret = TRUE;
 
3063
out:
 
3064
        free(info->name_vmcoreinfo);
 
3065
        info->name_vmcoreinfo = NULL;
 
3066
 
 
3067
        return ret;
 
3068
}
 
3069
 
 
3070
/*
 
3071
 * Get the number of online nodes.
 
3072
 */
 
3073
int
 
3074
get_nodes_online(void)
 
3075
{
 
3076
        int len, i, j, online;
 
3077
        unsigned long node_online_map = 0, bitbuf, *maskptr;
 
3078
 
 
3079
        if ((SYMBOL(node_online_map) == NOT_FOUND_SYMBOL)
 
3080
            && (SYMBOL(node_states) == NOT_FOUND_SYMBOL))
 
3081
                return 0;
 
3082
 
 
3083
        if (SIZE(nodemask_t) == NOT_FOUND_STRUCTURE) {
 
3084
                ERRMSG("Can't get the size of nodemask_t.\n");
 
3085
                return 0;
 
3086
        }
 
3087
 
 
3088
        len = SIZE(nodemask_t);
 
3089
        vt.node_online_map_len = len/sizeof(unsigned long);
 
3090
        if (!(vt.node_online_map = (unsigned long *)malloc(len))) {
 
3091
                ERRMSG("Can't allocate memory for the node online map. %s\n",
 
3092
                    strerror(errno));
 
3093
                return 0;
 
3094
        }
 
3095
        if (SYMBOL(node_online_map) != NOT_FOUND_SYMBOL) {
 
3096
                node_online_map = SYMBOL(node_online_map);
 
3097
        } else if (SYMBOL(node_states) != NOT_FOUND_SYMBOL) {
 
3098
                /*
 
3099
                 * For linux-2.6.23-rc4-mm1
 
3100
                 */
 
3101
                node_online_map = SYMBOL(node_states)
 
3102
                     + (SIZE(nodemask_t) * NUMBER(N_ONLINE));
 
3103
        }
 
3104
        if (!readmem(VADDR, node_online_map, vt.node_online_map, len)){
 
3105
                ERRMSG("Can't get the node online map.\n");
 
3106
                return 0;
 
3107
        }
 
3108
        online = 0;
 
3109
        maskptr = (unsigned long *)vt.node_online_map;
 
3110
        for (i = 0; i < vt.node_online_map_len; i++, maskptr++) {
 
3111
                bitbuf = *maskptr;
 
3112
                for (j = 0; j < sizeof(bitbuf) * 8; j++) {
 
3113
                        online += bitbuf & 1;
 
3114
                        bitbuf = bitbuf >> 1;
 
3115
                }
 
3116
        }
 
3117
        return online;
 
3118
}
 
3119
 
 
3120
int
 
3121
get_numnodes(void)
 
3122
{
 
3123
        if (!(vt.numnodes = get_nodes_online())) {
 
3124
                vt.numnodes = 1;
 
3125
        }
 
3126
        DEBUG_MSG("\n");
 
3127
        DEBUG_MSG("num of NODEs : %d\n", vt.numnodes);
 
3128
        DEBUG_MSG("\n");
 
3129
 
 
3130
        return TRUE;
 
3131
}
 
3132
 
 
3133
int
 
3134
next_online_node(int first)
 
3135
{
 
3136
        int i, j, node;
 
3137
        unsigned long mask, *maskptr;
 
3138
 
 
3139
        /* It cannot occur */
 
3140
        if ((first/(sizeof(unsigned long) * 8)) >= vt.node_online_map_len) {
 
3141
                ERRMSG("next_online_node: %d is too large!\n", first);
 
3142
                return -1;
 
3143
        }
 
3144
 
 
3145
        maskptr = (unsigned long *)vt.node_online_map;
 
3146
        for (i = node = 0; i <  vt.node_online_map_len; i++, maskptr++) {
 
3147
                mask = *maskptr;
 
3148
                for (j = 0; j < (sizeof(unsigned long) * 8); j++, node++) {
 
3149
                        if (mask & 1) {
 
3150
                                if (node >= first)
 
3151
                                        return node;
 
3152
                        }
 
3153
                        mask >>= 1;
 
3154
                }
 
3155
        }
 
3156
        return -1;
 
3157
}
 
3158
 
 
3159
unsigned long
 
3160
next_online_pgdat(int node)
 
3161
{
 
3162
        int i;
 
3163
        unsigned long pgdat;
 
3164
 
 
3165
        /*
 
3166
         * Get the pglist_data structure from symbol "node_data".
 
3167
         *     The array number of symbol "node_data" cannot be gotten
 
3168
         *     from vmlinux. Instead, check it is DW_TAG_array_type.
 
3169
         */
 
3170
        if ((SYMBOL(node_data) == NOT_FOUND_SYMBOL)
 
3171
            || (ARRAY_LENGTH(node_data) == NOT_FOUND_STRUCTURE))
 
3172
                goto pgdat2;
 
3173
 
 
3174
        if (!readmem(VADDR, SYMBOL(node_data) + (node * sizeof(void *)),
 
3175
            &pgdat, sizeof pgdat))
 
3176
                goto pgdat2;
 
3177
 
 
3178
        if (!is_kvaddr(pgdat))
 
3179
                goto pgdat2;
 
3180
 
 
3181
        return pgdat;
 
3182
 
 
3183
pgdat2:
 
3184
        /*
 
3185
         * Get the pglist_data structure from symbol "pgdat_list".
 
3186
         */
 
3187
        if (SYMBOL(pgdat_list) == NOT_FOUND_SYMBOL)
 
3188
                goto pgdat3;
 
3189
 
 
3190
        else if ((0 < node)
 
3191
            && (ARRAY_LENGTH(pgdat_list) == NOT_FOUND_STRUCTURE))
 
3192
                goto pgdat3;
 
3193
 
 
3194
        else if ((ARRAY_LENGTH(pgdat_list) != NOT_FOUND_STRUCTURE)
 
3195
            && (ARRAY_LENGTH(pgdat_list) < node))
 
3196
                goto pgdat3;
 
3197
 
 
3198
        if (!readmem(VADDR, SYMBOL(pgdat_list) + (node * sizeof(void *)),
 
3199
            &pgdat, sizeof pgdat))
 
3200
                goto pgdat3;
 
3201
 
 
3202
        if (!is_kvaddr(pgdat))
 
3203
                goto pgdat3;
 
3204
 
 
3205
        return pgdat;
 
3206
 
 
3207
pgdat3:
 
3208
        /*
 
3209
         * linux-2.6.16 or former
 
3210
         */
 
3211
        if ((SYMBOL(pgdat_list) == NOT_FOUND_SYMBOL)
 
3212
            || (OFFSET(pglist_data.pgdat_next) == NOT_FOUND_STRUCTURE))
 
3213
                goto pgdat4;
 
3214
 
 
3215
        if (!readmem(VADDR, SYMBOL(pgdat_list), &pgdat, sizeof pgdat))
 
3216
                goto pgdat4;
 
3217
 
 
3218
        if (!is_kvaddr(pgdat))
 
3219
                goto pgdat4;
 
3220
 
 
3221
        if (node == 0)
 
3222
                return pgdat;
 
3223
 
 
3224
        for (i = 1; i <= node; i++) {
 
3225
                if (!readmem(VADDR, pgdat+OFFSET(pglist_data.pgdat_next),
 
3226
                    &pgdat, sizeof pgdat))
 
3227
                        goto pgdat4;
 
3228
 
 
3229
                if (!is_kvaddr(pgdat))
 
3230
                        goto pgdat4;
 
3231
        }
 
3232
        return pgdat;
 
3233
 
 
3234
pgdat4:
 
3235
        /*
 
3236
         * Get the pglist_data structure from symbol "contig_page_data".
 
3237
         */
 
3238
        if (SYMBOL(contig_page_data) == NOT_FOUND_SYMBOL)
 
3239
                return FALSE;
 
3240
 
 
3241
        if (node != 0)
 
3242
                return FALSE;
 
3243
 
 
3244
        return SYMBOL(contig_page_data);
 
3245
}
 
3246
 
 
3247
void
 
3248
dump_mem_map(unsigned long long pfn_start,
 
3249
    unsigned long long pfn_end, unsigned long mem_map, int num_mm)
 
3250
{
 
3251
        struct mem_map_data *mmd;
 
3252
 
 
3253
        mmd = &info->mem_map_data[num_mm];
 
3254
        mmd->pfn_start = pfn_start;
 
3255
        mmd->pfn_end   = pfn_end;
 
3256
        mmd->mem_map   = mem_map;
 
3257
 
 
3258
        DEBUG_MSG("mem_map (%d)\n", num_mm);
 
3259
        DEBUG_MSG("  mem_map    : %lx\n", mem_map);
 
3260
        DEBUG_MSG("  pfn_start  : %llx\n", pfn_start);
 
3261
        DEBUG_MSG("  pfn_end    : %llx\n", pfn_end);
 
3262
 
 
3263
        return;
 
3264
}
 
3265
 
 
3266
int
 
3267
get_mm_flatmem(void)
 
3268
{
 
3269
        unsigned long mem_map;
 
3270
 
 
3271
        /*
 
3272
         * Get the address of the symbol "mem_map".
 
3273
         */
 
3274
        if (!readmem(VADDR, SYMBOL(mem_map), &mem_map, sizeof mem_map)
 
3275
            || !mem_map) {
 
3276
                ERRMSG("Can't get the address of mem_map.\n");
 
3277
                return FALSE;
 
3278
        }
 
3279
        info->num_mem_map = 1;
 
3280
        if ((info->mem_map_data = (struct mem_map_data *)
 
3281
            malloc(sizeof(struct mem_map_data)*info->num_mem_map)) == NULL) {
 
3282
                ERRMSG("Can't allocate memory for the mem_map_data. %s\n",
 
3283
                    strerror(errno));
 
3284
                return FALSE;
 
3285
        }
 
3286
        if (vt.mem_flags & MEMORY_XEN)
 
3287
                dump_mem_map(0, info->dom0_mapnr, mem_map, 0);
 
3288
        else
 
3289
                dump_mem_map(0, info->max_mapnr, mem_map, 0);
 
3290
 
 
3291
        return TRUE;
 
3292
}
 
3293
 
 
3294
int
 
3295
get_node_memblk(int num_memblk,
 
3296
    unsigned long *start_paddr, unsigned long *size, int *nid)
 
3297
{
 
3298
        unsigned long node_memblk;
 
3299
 
 
3300
        if (ARRAY_LENGTH(node_memblk) <= num_memblk) {
 
3301
                ERRMSG("Invalid num_memblk.\n");
 
3302
                return FALSE;
 
3303
        }
 
3304
        node_memblk = SYMBOL(node_memblk) + SIZE(node_memblk_s) * num_memblk;
 
3305
        if (!readmem(VADDR, node_memblk+OFFSET(node_memblk_s.start_paddr),
 
3306
            start_paddr, sizeof(unsigned long))) {
 
3307
                ERRMSG("Can't get node_memblk_s.start_paddr.\n");
 
3308
                return FALSE;
 
3309
        }
 
3310
        if (!readmem(VADDR, node_memblk + OFFSET(node_memblk_s.size),
 
3311
            size, sizeof(unsigned long))) {
 
3312
                ERRMSG("Can't get node_memblk_s.size.\n");
 
3313
                return FALSE;
 
3314
        }
 
3315
        if (!readmem(VADDR, node_memblk + OFFSET(node_memblk_s.nid),
 
3316
            nid, sizeof(int))) {
 
3317
                ERRMSG("Can't get node_memblk_s.nid.\n");
 
3318
                return FALSE;
 
3319
        }
 
3320
        return TRUE;
 
3321
}
 
3322
 
 
3323
int
 
3324
get_num_mm_discontigmem(void)
 
3325
{
 
3326
        int i, nid;
 
3327
        unsigned long start_paddr, size;
 
3328
 
 
3329
        if ((SYMBOL(node_memblk) == NOT_FOUND_SYMBOL)
 
3330
            || (ARRAY_LENGTH(node_memblk) == NOT_FOUND_STRUCTURE)
 
3331
            || (SIZE(node_memblk_s) == NOT_FOUND_STRUCTURE)
 
3332
            || (OFFSET(node_memblk_s.start_paddr) == NOT_FOUND_STRUCTURE)
 
3333
            || (OFFSET(node_memblk_s.size) == NOT_FOUND_STRUCTURE)
 
3334
            || (OFFSET(node_memblk_s.nid) == NOT_FOUND_STRUCTURE)) {
 
3335
                return vt.numnodes;
 
3336
        } else {
 
3337
                for (i = 0; i < ARRAY_LENGTH(node_memblk); i++) {
 
3338
                        if (!get_node_memblk(i, &start_paddr, &size, &nid)) {
 
3339
                                ERRMSG("Can't get the node_memblk (%d)\n", i);
 
3340
                                return 0;
 
3341
                        }
 
3342
                        if (!start_paddr && !size &&!nid)
 
3343
                                break;
 
3344
 
 
3345
                        DEBUG_MSG("nid : %d\n", nid);
 
3346
                        DEBUG_MSG("  start_paddr: %lx\n", start_paddr);
 
3347
                        DEBUG_MSG("  size       : %lx\n", size);
 
3348
                }
 
3349
                if (i == 0) {
 
3350
                        /*
 
3351
                         * On non-NUMA systems, node_memblk_s is not set.
 
3352
                         */
 
3353
                        return vt.numnodes;
 
3354
                } else {
 
3355
                        return i;
 
3356
                }
 
3357
        }
 
3358
}
 
3359
 
 
3360
int
 
3361
separate_mem_map(struct mem_map_data *mmd, int *id_mm, int nid_pgdat,
 
3362
    unsigned long mem_map_pgdat, unsigned long pfn_start_pgdat)
 
3363
{
 
3364
        int i, nid;
 
3365
        unsigned long start_paddr, size, pfn_start, pfn_end, mem_map;
 
3366
 
 
3367
        for (i = 0; i < ARRAY_LENGTH(node_memblk); i++) {
 
3368
                if (!get_node_memblk(i, &start_paddr, &size, &nid)) {
 
3369
                        ERRMSG("Can't get the node_memblk (%d)\n", i);
 
3370
                        return FALSE;
 
3371
                }
 
3372
                if (!start_paddr && !size && !nid)
 
3373
                        break;
 
3374
 
 
3375
                /*
 
3376
                 * Check pglist_data.node_id and node_memblk_s.nid match.
 
3377
                 */
 
3378
                if (nid_pgdat != nid)
 
3379
                        continue;
 
3380
 
 
3381
                pfn_start = paddr_to_pfn(start_paddr);
 
3382
                pfn_end   = paddr_to_pfn(start_paddr + size);
 
3383
 
 
3384
                if (pfn_start < pfn_start_pgdat) {
 
3385
                        ERRMSG("node_memblk_s.start_paddr of node (%d) is invalid.\n", nid);
 
3386
                        return FALSE;
 
3387
                }
 
3388
                if (info->max_mapnr < pfn_end) {
 
3389
                        DEBUG_MSG("pfn_end of node (%d) is over max_mapnr.\n",
 
3390
                            nid);
 
3391
                        DEBUG_MSG("  pfn_start: %lx\n", pfn_start);
 
3392
                        DEBUG_MSG("  pfn_end  : %lx\n", pfn_end);
 
3393
                        DEBUG_MSG("  max_mapnr: %llx\n", info->max_mapnr);
 
3394
 
 
3395
                        pfn_end = info->max_mapnr;
 
3396
                }
 
3397
 
 
3398
                mem_map = mem_map_pgdat+SIZE(page)*(pfn_start-pfn_start_pgdat);
 
3399
 
 
3400
                mmd->pfn_start = pfn_start;
 
3401
                mmd->pfn_end   = pfn_end;
 
3402
                mmd->mem_map   = mem_map;
 
3403
 
 
3404
                mmd++;
 
3405
                (*id_mm)++;
 
3406
        }
 
3407
        return TRUE;
 
3408
}
 
3409
 
 
3410
int
 
3411
get_mm_discontigmem(void)
 
3412
{
 
3413
        int i, j, id_mm, node, num_mem_map, separate_mm = FALSE;
 
3414
        unsigned long pgdat, mem_map, pfn_start, pfn_end, node_spanned_pages;
 
3415
        unsigned long vmem_map;
 
3416
        struct mem_map_data temp_mmd;
 
3417
 
 
3418
        num_mem_map = get_num_mm_discontigmem();
 
3419
        if (num_mem_map < vt.numnodes) {
 
3420
                ERRMSG("Can't get the number of mem_map.\n");
 
3421
                return FALSE;
 
3422
        }
 
3423
        struct mem_map_data mmd[num_mem_map];
 
3424
        if (vt.numnodes < num_mem_map) {
 
3425
                separate_mm = TRUE;
 
3426
        }
 
3427
 
 
3428
        /*
 
3429
         * Note:
 
3430
         *  This note is only for ia64 discontigmem kernel.
 
3431
         *  It is better to take mem_map information from a symbol vmem_map
 
3432
         *  instead of pglist_data.node_mem_map, because some node_mem_map
 
3433
         *  sometimes does not have mem_map information corresponding to its
 
3434
         *  node_start_pfn.
 
3435
         */
 
3436
        if (SYMBOL(vmem_map) != NOT_FOUND_SYMBOL) {
 
3437
                if (!readmem(VADDR, SYMBOL(vmem_map), &vmem_map, sizeof vmem_map)) {
 
3438
                        ERRMSG("Can't get vmem_map.\n");
 
3439
                        return FALSE;
 
3440
                }
 
3441
        }
 
3442
 
 
3443
        /*
 
3444
         * Get the first node_id.
 
3445
         */
 
3446
        if ((node = next_online_node(0)) < 0) {
 
3447
                ERRMSG("Can't get next online node.\n");
 
3448
                return FALSE;
 
3449
        }
 
3450
        if (!(pgdat = next_online_pgdat(node))) {
 
3451
                ERRMSG("Can't get pgdat list.\n");
 
3452
                return FALSE;
 
3453
        }
 
3454
        id_mm = 0;
 
3455
        for (i = 0; i < vt.numnodes; i++) {
 
3456
                if (!readmem(VADDR, pgdat + OFFSET(pglist_data.node_start_pfn),
 
3457
                    &pfn_start, sizeof pfn_start)) {
 
3458
                        ERRMSG("Can't get node_start_pfn.\n");
 
3459
                        return FALSE;
 
3460
                }
 
3461
                if (!readmem(VADDR,pgdat+OFFSET(pglist_data.node_spanned_pages),
 
3462
                    &node_spanned_pages, sizeof node_spanned_pages)) {
 
3463
                        ERRMSG("Can't get node_spanned_pages.\n");
 
3464
                        return FALSE;
 
3465
                }
 
3466
                pfn_end = pfn_start + node_spanned_pages;
 
3467
 
 
3468
                if (SYMBOL(vmem_map) == NOT_FOUND_SYMBOL) {
 
3469
                        if (!readmem(VADDR, pgdat + OFFSET(pglist_data.node_mem_map),
 
3470
                            &mem_map, sizeof mem_map)) {
 
3471
                                ERRMSG("Can't get mem_map.\n");
 
3472
                                return FALSE;
 
3473
                        }
 
3474
                } else
 
3475
                        mem_map = vmem_map + (SIZE(page) * pfn_start);
 
3476
 
 
3477
                if (separate_mm) {
 
3478
                        /*
 
3479
                         * For some ia64 NUMA systems.
 
3480
                         * On some systems, a node has the separated memory.
 
3481
                         * And pglist_data(s) have the duplicated memory range
 
3482
                         * like following:
 
3483
                         *
 
3484
                         * Nid:      Physical address
 
3485
                         *  0 : 0x1000000000 - 0x2000000000
 
3486
                         *  1 : 0x2000000000 - 0x3000000000
 
3487
                         *  2 : 0x0000000000 - 0x6020000000 <- Overlapping
 
3488
                         *  3 : 0x3000000000 - 0x4000000000
 
3489
                         *  4 : 0x4000000000 - 0x5000000000
 
3490
                         *  5 : 0x5000000000 - 0x6000000000
 
3491
                         *
 
3492
                         * Then, mem_map(s) should be separated by
 
3493
                         * node_memblk_s info.
 
3494
                         */
 
3495
                        if (!separate_mem_map(&mmd[id_mm], &id_mm, node,
 
3496
                            mem_map, pfn_start)) {
 
3497
                                ERRMSG("Can't separate mem_map.\n");
 
3498
                                return FALSE;
 
3499
                        }
 
3500
                } else {
 
3501
                        if (info->max_mapnr < pfn_end) {
 
3502
                                DEBUG_MSG("pfn_end of node (%d) is over max_mapnr.\n",
 
3503
                                    node);
 
3504
                                DEBUG_MSG("  pfn_start: %lx\n", pfn_start);
 
3505
                                DEBUG_MSG("  pfn_end  : %lx\n", pfn_end);
 
3506
                                DEBUG_MSG("  max_mapnr: %llx\n", info->max_mapnr);
 
3507
 
 
3508
                                pfn_end = info->max_mapnr;
 
3509
                        }
 
3510
 
 
3511
                        /*
 
3512
                         * The number of mem_map is the same as the number
 
3513
                         * of nodes.
 
3514
                         */
 
3515
                        mmd[id_mm].pfn_start = pfn_start;
 
3516
                        mmd[id_mm].pfn_end   = pfn_end;
 
3517
                        mmd[id_mm].mem_map   = mem_map;
 
3518
                        id_mm++;
 
3519
                }
 
3520
 
 
3521
                /*
 
3522
                 * Get pglist_data of the next node.
 
3523
                 */
 
3524
                if (i < (vt.numnodes - 1)) {
 
3525
                        if ((node = next_online_node(node + 1)) < 0) {
 
3526
                                ERRMSG("Can't get next online node.\n");
 
3527
                                return FALSE;
 
3528
                        } else if (!(pgdat = next_online_pgdat(node))) {
 
3529
                                ERRMSG("Can't determine pgdat list (node %d).\n",
 
3530
                                    node);
 
3531
                                return FALSE;
 
3532
                        }
 
3533
                }
 
3534
        }
 
3535
 
 
3536
        /*
 
3537
         * Sort mem_map by pfn_start.
 
3538
         */
 
3539
        for (i = 0; i < (num_mem_map - 1); i++) {
 
3540
                for (j = i + 1; j < num_mem_map; j++) {
 
3541
                        if (mmd[j].pfn_start < mmd[i].pfn_start) {
 
3542
                                temp_mmd = mmd[j];
 
3543
                                mmd[j] = mmd[i];
 
3544
                                mmd[i] = temp_mmd;
 
3545
                        }
 
3546
                }
 
3547
        }
 
3548
 
 
3549
        /*
 
3550
         * Calculate the number of mem_map.
 
3551
         */
 
3552
        info->num_mem_map = num_mem_map;
 
3553
        if (mmd[0].pfn_start != 0)
 
3554
                info->num_mem_map++;
 
3555
 
 
3556
        for (i = 0; i < num_mem_map - 1; i++) {
 
3557
                if (mmd[i].pfn_end > mmd[i + 1].pfn_start) {
 
3558
                        ERRMSG("The mem_map is overlapped with the next one.\n");
 
3559
                        ERRMSG("mmd[%d].pfn_end   = %llx\n", i, mmd[i].pfn_end);
 
3560
                        ERRMSG("mmd[%d].pfn_start = %llx\n", i + 1, mmd[i + 1].pfn_start);
 
3561
                        return FALSE;
 
3562
                } else if (mmd[i].pfn_end == mmd[i + 1].pfn_start)
 
3563
                        /*
 
3564
                         * Continuous mem_map
 
3565
                         */
 
3566
                        continue;
 
3567
 
 
3568
                /*
 
3569
                 * Discontinuous mem_map
 
3570
                 */
 
3571
                info->num_mem_map++;
 
3572
        }
 
3573
        if (mmd[num_mem_map - 1].pfn_end < info->max_mapnr)
 
3574
                info->num_mem_map++;
 
3575
 
 
3576
        if ((info->mem_map_data = (struct mem_map_data *)
 
3577
            malloc(sizeof(struct mem_map_data)*info->num_mem_map)) == NULL) {
 
3578
                ERRMSG("Can't allocate memory for the mem_map_data. %s\n",
 
3579
                    strerror(errno));
 
3580
                return FALSE;
 
3581
        }
 
3582
 
 
3583
        /*
 
3584
         * Create mem_map data.
 
3585
         */
 
3586
        id_mm = 0;
 
3587
        if (mmd[0].pfn_start != 0) {
 
3588
                dump_mem_map(0, mmd[0].pfn_start, NOT_MEMMAP_ADDR, id_mm);
 
3589
                id_mm++;
 
3590
        }
 
3591
        for (i = 0; i < num_mem_map; i++) {
 
3592
                dump_mem_map(mmd[i].pfn_start, mmd[i].pfn_end,
 
3593
                    mmd[i].mem_map, id_mm);
 
3594
                id_mm++;
 
3595
                if ((i < num_mem_map - 1)
 
3596
                    && (mmd[i].pfn_end != mmd[i + 1].pfn_start)) {
 
3597
                        dump_mem_map(mmd[i].pfn_end, mmd[i +1].pfn_start,
 
3598
                            NOT_MEMMAP_ADDR, id_mm);
 
3599
                        id_mm++;
 
3600
                }
 
3601
        }
 
3602
        i = num_mem_map - 1;
 
3603
        if (vt.mem_flags & MEMORY_XEN) {
 
3604
                if (mmd[i].pfn_end < info->dom0_mapnr)
 
3605
                        dump_mem_map(mmd[i].pfn_end, info->dom0_mapnr,
 
3606
                            NOT_MEMMAP_ADDR, id_mm);
 
3607
        } else {
 
3608
                if (mmd[i].pfn_end < info->max_mapnr)
 
3609
                        dump_mem_map(mmd[i].pfn_end, info->max_mapnr,
 
3610
                            NOT_MEMMAP_ADDR, id_mm);
 
3611
        }
 
3612
        return TRUE;
 
3613
}
 
3614
 
 
3615
unsigned long
 
3616
nr_to_section(unsigned long nr, unsigned long *mem_sec)
 
3617
{
 
3618
        unsigned long addr;
 
3619
 
 
3620
        if (is_sparsemem_extreme())
 
3621
                addr = mem_sec[SECTION_NR_TO_ROOT(nr)] +
 
3622
                    (nr & SECTION_ROOT_MASK()) * SIZE(mem_section);
 
3623
        else
 
3624
                addr = SYMBOL(mem_section) + (nr * SIZE(mem_section));
 
3625
 
 
3626
        if (!is_kvaddr(addr))
 
3627
                return NOT_KV_ADDR;
 
3628
 
 
3629
        return addr;
 
3630
}
 
3631
 
 
3632
unsigned long
 
3633
section_mem_map_addr(unsigned long addr)
 
3634
{
 
3635
        char *mem_section;
 
3636
        unsigned long map;
 
3637
 
 
3638
        if (!is_kvaddr(addr))
 
3639
                return NOT_KV_ADDR;
 
3640
 
 
3641
        if ((mem_section = malloc(SIZE(mem_section))) == NULL) {
 
3642
                ERRMSG("Can't allocate memory for a struct mem_section. %s\n",
 
3643
                    strerror(errno));
 
3644
                return NOT_KV_ADDR;
 
3645
        }
 
3646
        if (!readmem(VADDR, addr, mem_section, SIZE(mem_section))) {
 
3647
                ERRMSG("Can't get a struct mem_section(%lx).\n", addr);
 
3648
                free(mem_section);
 
3649
                return NOT_KV_ADDR;
 
3650
        }
 
3651
        map = ULONG(mem_section + OFFSET(mem_section.section_mem_map));
 
3652
        map &= SECTION_MAP_MASK;
 
3653
        free(mem_section);
 
3654
 
 
3655
        return map;
 
3656
}
 
3657
 
 
3658
unsigned long
 
3659
sparse_decode_mem_map(unsigned long coded_mem_map, unsigned long section_nr)
 
3660
{
 
3661
        if (!is_kvaddr(coded_mem_map))
 
3662
                return NOT_KV_ADDR;
 
3663
 
 
3664
        return coded_mem_map +
 
3665
            (SECTION_NR_TO_PFN(section_nr) * SIZE(page));
 
3666
}
 
3667
 
 
3668
int
 
3669
get_mm_sparsemem(void)
 
3670
{
 
3671
        unsigned int section_nr, mem_section_size, num_section;
 
3672
        unsigned long long pfn_start, pfn_end;
 
3673
        unsigned long section, mem_map;
 
3674
        unsigned long *mem_sec = NULL;
 
3675
 
 
3676
        int ret = FALSE;
 
3677
 
 
3678
        /*
 
3679
         * Get the address of the symbol "mem_section".
 
3680
         */
 
3681
        num_section = divideup(info->max_mapnr, PAGES_PER_SECTION());
 
3682
        if (is_sparsemem_extreme()) {
 
3683
                info->sections_per_root = _SECTIONS_PER_ROOT_EXTREME();
 
3684
                mem_section_size = sizeof(void *) * NR_SECTION_ROOTS();
 
3685
        } else {
 
3686
                info->sections_per_root = _SECTIONS_PER_ROOT();
 
3687
                mem_section_size = SIZE(mem_section) * NR_SECTION_ROOTS();
 
3688
        }
 
3689
        if ((mem_sec = malloc(mem_section_size)) == NULL) {
 
3690
                ERRMSG("Can't allocate memory for the mem_section. %s\n",
 
3691
                    strerror(errno));
 
3692
                return FALSE;
 
3693
        }
 
3694
        if (!readmem(VADDR, SYMBOL(mem_section), mem_sec,
 
3695
            mem_section_size)) {
 
3696
                ERRMSG("Can't get the address of mem_section.\n");
 
3697
                goto out;
 
3698
        }
 
3699
        info->num_mem_map = num_section;
 
3700
        if ((info->mem_map_data = (struct mem_map_data *)
 
3701
            malloc(sizeof(struct mem_map_data)*info->num_mem_map)) == NULL) {
 
3702
                ERRMSG("Can't allocate memory for the mem_map_data. %s\n",
 
3703
                    strerror(errno));
 
3704
                goto out;
 
3705
        }
 
3706
        for (section_nr = 0; section_nr < num_section; section_nr++) {
 
3707
                section = nr_to_section(section_nr, mem_sec);
 
3708
                mem_map = section_mem_map_addr(section);
 
3709
                mem_map = sparse_decode_mem_map(mem_map, section_nr);
 
3710
                if (!is_kvaddr(mem_map))
 
3711
                        mem_map = NOT_MEMMAP_ADDR;
 
3712
                pfn_start = section_nr * PAGES_PER_SECTION();
 
3713
                pfn_end   = pfn_start + PAGES_PER_SECTION();
 
3714
                if (info->max_mapnr < pfn_end)
 
3715
                        pfn_end = info->max_mapnr;
 
3716
                dump_mem_map(pfn_start, pfn_end, mem_map, section_nr);
 
3717
        }
 
3718
        ret = TRUE;
 
3719
out:
 
3720
        if (mem_sec != NULL)
 
3721
                free(mem_sec);
 
3722
 
 
3723
        return ret;
 
3724
}
 
3725
 
 
3726
int
 
3727
get_mem_map_without_mm(void)
 
3728
{
 
3729
        info->num_mem_map = 1;
 
3730
        if ((info->mem_map_data = (struct mem_map_data *)
 
3731
            malloc(sizeof(struct mem_map_data)*info->num_mem_map)) == NULL) {
 
3732
                ERRMSG("Can't allocate memory for the mem_map_data. %s\n",
 
3733
                    strerror(errno));
 
3734
                return FALSE;
 
3735
        }
 
3736
        if (vt.mem_flags & MEMORY_XEN)
 
3737
                dump_mem_map(0, info->dom0_mapnr, NOT_MEMMAP_ADDR, 0);
 
3738
        else
 
3739
                dump_mem_map(0, info->max_mapnr, NOT_MEMMAP_ADDR, 0);
 
3740
 
 
3741
        return TRUE;
 
3742
}
 
3743
 
 
3744
int
 
3745
get_mem_map(void)
 
3746
{
 
3747
        int ret;
 
3748
 
 
3749
        if (vt.mem_flags & MEMORY_XEN) {
 
3750
                if (!get_dom0_mapnr()) {
 
3751
                        ERRMSG("Can't domain-0 pfn.\n");
 
3752
                        return FALSE;
 
3753
                }
 
3754
                DEBUG_MSG("domain-0 pfn : %llx\n", info->dom0_mapnr);
 
3755
        }
 
3756
 
 
3757
        switch (get_mem_type()) {
 
3758
        case SPARSEMEM:
 
3759
                DEBUG_MSG("\n");
 
3760
                DEBUG_MSG("Memory type  : SPARSEMEM\n");
 
3761
                DEBUG_MSG("\n");
 
3762
                ret = get_mm_sparsemem();
 
3763
                break;
 
3764
        case SPARSEMEM_EX:
 
3765
                DEBUG_MSG("\n");
 
3766
                DEBUG_MSG("Memory type  : SPARSEMEM_EX\n");
 
3767
                DEBUG_MSG("\n");
 
3768
                ret = get_mm_sparsemem();
 
3769
                break;
 
3770
        case DISCONTIGMEM:
 
3771
                DEBUG_MSG("\n");
 
3772
                DEBUG_MSG("Memory type  : DISCONTIGMEM\n");
 
3773
                DEBUG_MSG("\n");
 
3774
                ret = get_mm_discontigmem();
 
3775
                break;
 
3776
        case FLATMEM:
 
3777
                DEBUG_MSG("\n");
 
3778
                DEBUG_MSG("Memory type  : FLATMEM\n");
 
3779
                DEBUG_MSG("\n");
 
3780
                ret = get_mm_flatmem();
 
3781
                break;
 
3782
        default:
 
3783
                ERRMSG("Can't distinguish the memory type.\n");
 
3784
                ret = FALSE;
 
3785
                break;
 
3786
        }
 
3787
        return ret;
 
3788
}
 
3789
 
 
3790
int
 
3791
initialize_bitmap_memory(void)
 
3792
{
 
3793
        struct disk_dump_header *dh;
 
3794
        struct dump_bitmap *bmp;
 
3795
        off_t bitmap_offset;
 
3796
        int bitmap_len, max_sect_len;
 
3797
        unsigned long pfn;
 
3798
        int i, j;
 
3799
        long block_size;
 
3800
 
 
3801
        dh = info->dh_memory;
 
3802
        block_size = dh->block_size;
 
3803
 
 
3804
        bitmap_offset
 
3805
            = (DISKDUMP_HEADER_BLOCKS + dh->sub_hdr_size) * block_size;
 
3806
        bitmap_len = block_size * dh->bitmap_blocks;
 
3807
 
 
3808
        bmp = malloc(sizeof(struct dump_bitmap));
 
3809
        if (bmp == NULL) {
 
3810
                ERRMSG("Can't allocate memory for the memory-bitmap. %s\n",
 
3811
                    strerror(errno));
 
3812
                return FALSE;
 
3813
        }
 
3814
        bmp->fd        = info->fd_memory;
 
3815
        bmp->file_name = info->name_memory;
 
3816
        bmp->no_block  = -1;
 
3817
        memset(bmp->buf, 0, BUFSIZE_BITMAP);
 
3818
        bmp->offset = bitmap_offset + bitmap_len / 2;
 
3819
        info->bitmap_memory = bmp;
 
3820
 
 
3821
        max_sect_len = divideup(dh->max_mapnr, BITMAP_SECT_LEN);
 
3822
        info->valid_pages = calloc(sizeof(ulong), max_sect_len);
 
3823
        if (info->valid_pages == NULL) {
 
3824
                ERRMSG("Can't allocate memory for the valid_pages. %s\n",
 
3825
                    strerror(errno));
 
3826
                free(bmp);
 
3827
                return FALSE;
 
3828
        }
 
3829
        for (i = 1, pfn = 0; i < max_sect_len; i++) {
 
3830
                info->valid_pages[i] = info->valid_pages[i - 1];
 
3831
                for (j = 0; j < BITMAP_SECT_LEN; j++, pfn++)
 
3832
                        if (is_dumpable(info->bitmap_memory, pfn))
 
3833
                                info->valid_pages[i]++;
 
3834
        }
 
3835
 
 
3836
        return TRUE;
 
3837
}
 
3838
 
 
3839
int
 
3840
initial(void)
 
3841
{
 
3842
        int debug_info = FALSE;
 
3843
 
 
3844
        if (!(vt.mem_flags & MEMORY_XEN) && info->flag_exclude_xen_dom) {
 
3845
                MSG("'-X' option is disable,");
 
3846
                MSG("because %s is not Xen's memory core image.\n", info->name_memory);
 
3847
                MSG("Commandline parameter is invalid.\n");
 
3848
                MSG("Try `makedumpfile --help' for more information.\n");
 
3849
                return FALSE;
 
3850
        }
 
3851
 
 
3852
        if (info->flag_refiltering) {
 
3853
                if (info->flag_elf_dumpfile) {
 
3854
                        MSG("'-E' option is disable, ");
 
3855
                        MSG("because %s is kdump compressed format.\n",
 
3856
                                                        info->name_memory);
 
3857
                        return FALSE;
 
3858
                }
 
3859
                info->phys_base = info->kh_memory->phys_base;
 
3860
                info->max_dump_level |= info->kh_memory->dump_level;
 
3861
 
 
3862
                if (!initialize_bitmap_memory())
 
3863
                        return FALSE;
 
3864
 
 
3865
        } else if (!get_phys_base())
 
3866
                return FALSE;
 
3867
 
 
3868
        /*
 
3869
         * Get the debug information for analysis from the vmcoreinfo file
 
3870
         */
 
3871
        if (info->flag_read_vmcoreinfo) {
 
3872
                if (!read_vmcoreinfo())
 
3873
                        return FALSE;
 
3874
                close_vmcoreinfo();
 
3875
                debug_info = TRUE;
 
3876
        /*
 
3877
         * Get the debug information for analysis from the kernel file
 
3878
         */
 
3879
        } else if (info->name_vmlinux) {
 
3880
                dwarf_info.fd_debuginfo   = info->fd_vmlinux;
 
3881
                dwarf_info.name_debuginfo = info->name_vmlinux;
 
3882
 
 
3883
                if (!get_symbol_info())
 
3884
                        return FALSE;
 
3885
 
 
3886
                if (!get_structure_info())
 
3887
                        return FALSE;
 
3888
 
 
3889
                if (!get_srcfile_info())
 
3890
                        return FALSE;
 
3891
 
 
3892
                debug_info = TRUE;
 
3893
        } else {
 
3894
                /*
 
3895
                 * Check whether /proc/vmcore contains vmcoreinfo,
 
3896
                 * and get both the offset and the size.
 
3897
                 */
 
3898
                if (!info->offset_vmcoreinfo || !info->size_vmcoreinfo) {
 
3899
                        if (info->max_dump_level <= DL_EXCLUDE_ZERO)
 
3900
                                goto out;
 
3901
 
 
3902
                        MSG("%s doesn't contain vmcoreinfo.\n",
 
3903
                            info->name_memory);
 
3904
                        MSG("Specify '-x' option or '-i' option.\n");
 
3905
                        MSG("Commandline parameter is invalid.\n");
 
3906
                        MSG("Try `makedumpfile --help' for more information.\n");
 
3907
                        return FALSE;
 
3908
                }
 
3909
        }
 
3910
 
 
3911
        /*
 
3912
         * Get the debug information from /proc/vmcore.
 
3913
         * NOTE: Don't move this code to the above, because the debugging
 
3914
         *       information token by -x/-i option is overwritten by vmcoreinfo
 
3915
         *       in /proc/vmcore. vmcoreinfo in /proc/vmcore is more reliable
 
3916
         *       than -x/-i option.
 
3917
         */
 
3918
        if (info->offset_vmcoreinfo && info->size_vmcoreinfo) {
 
3919
                if (!read_vmcoreinfo_from_vmcore(info->offset_vmcoreinfo,
 
3920
                    info->size_vmcoreinfo, FALSE))
 
3921
                        return FALSE;
 
3922
                debug_info = TRUE;
 
3923
        }
 
3924
 
 
3925
        if (!get_value_for_old_linux())
 
3926
                return FALSE;
 
3927
out:
 
3928
        if (!info->page_size) {
 
3929
                /*
 
3930
                 * If we cannot get page_size from a vmcoreinfo file,
 
3931
                 * fall back to the current kernel page size.
 
3932
                 */
 
3933
                if (!fallback_to_current_page_size())
 
3934
                        return FALSE;
 
3935
        }
 
3936
        if (!get_max_mapnr())
 
3937
                return FALSE;
 
3938
 
 
3939
        if (debug_info) {
 
3940
                if (!get_machdep_info())
 
3941
                        return FALSE;
 
3942
 
 
3943
                if (!check_release())
 
3944
                        return FALSE;
 
3945
 
 
3946
                if (!get_versiondep_info())
 
3947
                        return FALSE;
 
3948
 
 
3949
                if (!get_numnodes())
 
3950
                        return FALSE;
 
3951
 
 
3952
                if (!get_mem_map())
 
3953
                        return FALSE;
 
3954
        } else {
 
3955
                if (!get_mem_map_without_mm())
 
3956
                        return FALSE;
 
3957
        }
 
3958
 
 
3959
        return TRUE;
 
3960
}
 
3961
 
 
3962
void
 
3963
initialize_bitmap(struct dump_bitmap *bitmap)
 
3964
{
 
3965
        bitmap->fd        = info->fd_bitmap;
 
3966
        bitmap->file_name = info->name_bitmap;
 
3967
        bitmap->no_block  = -1;
 
3968
        memset(bitmap->buf, 0, BUFSIZE_BITMAP);
 
3969
}
 
3970
 
 
3971
void
 
3972
initialize_1st_bitmap(struct dump_bitmap *bitmap)
 
3973
{
 
3974
        initialize_bitmap(bitmap);
 
3975
        bitmap->offset = 0;
 
3976
}
 
3977
 
 
3978
void
 
3979
initialize_2nd_bitmap(struct dump_bitmap *bitmap)
 
3980
{
 
3981
        initialize_bitmap(bitmap);
 
3982
        bitmap->offset = info->len_bitmap / 2;
 
3983
}
 
3984
 
 
3985
int
 
3986
set_bitmap(struct dump_bitmap *bitmap, unsigned long long pfn,
 
3987
    int val)
 
3988
{
 
3989
        int byte, bit;
 
3990
        off_t old_offset, new_offset;
 
3991
        old_offset = bitmap->offset + BUFSIZE_BITMAP * bitmap->no_block;
 
3992
        new_offset = bitmap->offset + BUFSIZE_BITMAP * (pfn / PFN_BUFBITMAP);
 
3993
 
 
3994
        if (0 <= bitmap->no_block && old_offset != new_offset) {
 
3995
                if (lseek(bitmap->fd, old_offset, SEEK_SET) < 0 ) {
 
3996
                        ERRMSG("Can't seek the bitmap(%s). %s\n",
 
3997
                            bitmap->file_name, strerror(errno));
 
3998
                        return FALSE;
 
3999
                }
 
4000
                if (write(bitmap->fd, bitmap->buf, BUFSIZE_BITMAP)
 
4001
                    != BUFSIZE_BITMAP) {
 
4002
                        ERRMSG("Can't write the bitmap(%s). %s\n",
 
4003
                            bitmap->file_name, strerror(errno));
 
4004
                        return FALSE;
 
4005
                }
 
4006
        }
 
4007
        if (old_offset != new_offset) {
 
4008
                if (lseek(bitmap->fd, new_offset, SEEK_SET) < 0 ) {
 
4009
                        ERRMSG("Can't seek the bitmap(%s). %s\n",
 
4010
                            bitmap->file_name, strerror(errno));
 
4011
                        return FALSE;
 
4012
                }
 
4013
                if (read(bitmap->fd, bitmap->buf, BUFSIZE_BITMAP)
 
4014
                    != BUFSIZE_BITMAP) {
 
4015
                        ERRMSG("Can't read the bitmap(%s). %s\n",
 
4016
                            bitmap->file_name, strerror(errno));
 
4017
                        return FALSE;
 
4018
                }
 
4019
                bitmap->no_block = pfn / PFN_BUFBITMAP;
 
4020
        }
 
4021
        /*
 
4022
         * If val is 0, clear bit on the bitmap.
 
4023
         */
 
4024
        byte = (pfn%PFN_BUFBITMAP)>>3;
 
4025
        bit  = (pfn%PFN_BUFBITMAP) & 7;
 
4026
        if (val)
 
4027
                bitmap->buf[byte] |= 1<<bit;
 
4028
        else
 
4029
                bitmap->buf[byte] &= ~(1<<bit);
 
4030
 
 
4031
        return TRUE;
 
4032
}
 
4033
 
 
4034
int
 
4035
sync_bitmap(struct dump_bitmap *bitmap)
 
4036
{
 
4037
        off_t offset;
 
4038
        offset = bitmap->offset + BUFSIZE_BITMAP * bitmap->no_block;
 
4039
 
 
4040
        /*
 
4041
         * The bitmap buffer is not dirty, and it is not necessary
 
4042
         * to write out it.
 
4043
         */
 
4044
        if (bitmap->no_block < 0)
 
4045
                return TRUE;
 
4046
 
 
4047
        if (lseek(bitmap->fd, offset, SEEK_SET) < 0 ) {
 
4048
                ERRMSG("Can't seek the bitmap(%s). %s\n",
 
4049
                    bitmap->file_name, strerror(errno));
 
4050
                return FALSE;
 
4051
        }
 
4052
        if (write(bitmap->fd, bitmap->buf, BUFSIZE_BITMAP)
 
4053
            != BUFSIZE_BITMAP) {
 
4054
                ERRMSG("Can't write the bitmap(%s). %s\n",
 
4055
                    bitmap->file_name, strerror(errno));
 
4056
                return FALSE;
 
4057
        }
 
4058
        return TRUE;
 
4059
}
 
4060
 
 
4061
int
 
4062
sync_1st_bitmap(void)
 
4063
{
 
4064
        return sync_bitmap(info->bitmap1);
 
4065
}
 
4066
 
 
4067
int
 
4068
sync_2nd_bitmap(void)
 
4069
{
 
4070
        return sync_bitmap(info->bitmap2);
 
4071
}
 
4072
 
 
4073
int
 
4074
set_bit_on_1st_bitmap(unsigned long long pfn)
 
4075
{
 
4076
        return set_bitmap(info->bitmap1, pfn, 1);
 
4077
}
 
4078
 
 
4079
int
 
4080
clear_bit_on_2nd_bitmap(unsigned long long pfn)
 
4081
{
 
4082
        return set_bitmap(info->bitmap2, pfn, 0);
 
4083
}
 
4084
 
 
4085
int
 
4086
clear_bit_on_2nd_bitmap_for_kernel(unsigned long long pfn)
 
4087
{
 
4088
        unsigned long long maddr;
 
4089
 
 
4090
        if (vt.mem_flags & MEMORY_XEN) {
 
4091
                maddr = ptom_xen(pfn_to_paddr(pfn));
 
4092
                if (maddr == NOT_PADDR) {
 
4093
                        ERRMSG("Can't convert a physical address(%llx) to machine address.\n",
 
4094
                            pfn_to_paddr(pfn));
 
4095
                        return FALSE;
 
4096
                }
 
4097
                pfn = paddr_to_pfn(maddr);
 
4098
        }
 
4099
        return clear_bit_on_2nd_bitmap(pfn);
 
4100
}
 
4101
 
 
4102
static inline int
 
4103
is_on(char *bitmap, int i)
 
4104
{
 
4105
        return bitmap[i>>3] & (1 << (i & 7));
 
4106
}
 
4107
 
 
4108
static inline int
 
4109
is_dumpable(struct dump_bitmap *bitmap, unsigned long long pfn)
 
4110
{
 
4111
        off_t offset;
 
4112
        if (pfn == 0 || bitmap->no_block != pfn/PFN_BUFBITMAP) {
 
4113
                offset = bitmap->offset + BUFSIZE_BITMAP*(pfn/PFN_BUFBITMAP);
 
4114
                lseek(bitmap->fd, offset, SEEK_SET);
 
4115
                read(bitmap->fd, bitmap->buf, BUFSIZE_BITMAP);
 
4116
                if (pfn == 0)
 
4117
                        bitmap->no_block = 0;
 
4118
                else
 
4119
                        bitmap->no_block = pfn/PFN_BUFBITMAP;
 
4120
        }
 
4121
        return is_on(bitmap->buf, pfn%PFN_BUFBITMAP);
 
4122
}
 
4123
 
 
4124
static inline int
 
4125
is_in_segs(unsigned long long paddr)
 
4126
{
 
4127
        if (info->flag_refiltering) {
 
4128
                static struct dump_bitmap bitmap1 = {0};
 
4129
 
 
4130
                if (bitmap1.fd == 0)
 
4131
                        initialize_1st_bitmap(&bitmap1);
 
4132
 
 
4133
                return is_dumpable(&bitmap1, paddr_to_pfn(paddr));
 
4134
        }
 
4135
 
 
4136
        if (paddr_to_offset(paddr))
 
4137
                return TRUE;
 
4138
        else
 
4139
                return FALSE;
 
4140
}
 
4141
 
 
4142
static inline int
 
4143
is_zero_page(unsigned char *buf, long page_size)
 
4144
{
 
4145
        size_t i;
 
4146
 
 
4147
        for (i = 0; i < page_size; i++)
 
4148
                if (buf[i])
 
4149
                        return FALSE;
 
4150
        return TRUE;
 
4151
}
 
4152
 
 
4153
int
 
4154
read_cache(struct cache_data *cd)
 
4155
{
 
4156
        const off_t failed = (off_t)-1;
 
4157
 
 
4158
        if (lseek(cd->fd, cd->offset, SEEK_SET) == failed) {
 
4159
                ERRMSG("Can't seek the dump file(%s). %s\n",
 
4160
                    cd->file_name, strerror(errno));
 
4161
                return FALSE;
 
4162
        }
 
4163
        if (read(cd->fd, cd->buf, cd->cache_size) != cd->cache_size) {
 
4164
                ERRMSG("Can't read the dump file(%s). %s\n",
 
4165
                    cd->file_name, strerror(errno));
 
4166
                return FALSE;
 
4167
        }
 
4168
        cd->offset += cd->cache_size;
 
4169
        return TRUE;
 
4170
}
 
4171
 
 
4172
int
 
4173
is_bigendian(void)
 
4174
{
 
4175
        int i = 0x12345678;
 
4176
 
 
4177
        if (*(char *)&i == 0x12)
 
4178
                return TRUE;
 
4179
        else
 
4180
                return FALSE;
 
4181
}
 
4182
 
 
4183
int
 
4184
write_and_check_space(int fd, void *buf, size_t buf_size, char *file_name)
 
4185
{
 
4186
        int status, written_size = 0;
 
4187
 
 
4188
        while (written_size < buf_size) {
 
4189
                status = write(fd, buf + written_size,
 
4190
                                   buf_size - written_size);
 
4191
                if (0 < status) {
 
4192
                        written_size += status;
 
4193
                        continue;
 
4194
                }
 
4195
                if (errno == ENOSPC)
 
4196
                        info->flag_nospace = TRUE;
 
4197
                MSG("\nCan't write the dump file(%s). %s\n",
 
4198
                    file_name, strerror(errno));
 
4199
                return FALSE;
 
4200
        }
 
4201
        return TRUE;
 
4202
}
 
4203
 
 
4204
int
 
4205
write_buffer(int fd, off_t offset, void *buf, size_t buf_size, char *file_name)
 
4206
{
 
4207
        struct makedumpfile_data_header fdh;
 
4208
        const off_t failed = (off_t)-1;
 
4209
 
 
4210
        if (fd == STDOUT_FILENO) {
 
4211
                /*
 
4212
                 * Output a header of flattened format instead of
 
4213
                 * lseek(). For sending dump data to a different
 
4214
                 * architecture, change the values to big endian.
 
4215
                 */
 
4216
                if (is_bigendian()){
 
4217
                        fdh.offset   = offset;
 
4218
                        fdh.buf_size = buf_size;
 
4219
                } else {
 
4220
                        fdh.offset   = bswap_64(offset);
 
4221
                        fdh.buf_size = bswap_64(buf_size);
 
4222
                }
 
4223
                if (!write_and_check_space(fd, &fdh, sizeof(fdh), file_name))
 
4224
                        return FALSE;
 
4225
        } else {
 
4226
                if (lseek(fd, offset, SEEK_SET) == failed) {
 
4227
                        ERRMSG("Can't seek the dump file(%s). %s\n",
 
4228
                            file_name, strerror(errno));
 
4229
                        return FALSE;
 
4230
                }
 
4231
        }
 
4232
        if (!write_and_check_space(fd, buf, buf_size, file_name))
 
4233
                return FALSE;
 
4234
 
 
4235
        return TRUE;
 
4236
}
 
4237
 
 
4238
int
 
4239
write_cache(struct cache_data *cd, void *buf, size_t size)
 
4240
{
 
4241
        memcpy(cd->buf + cd->buf_size, buf, size);
 
4242
        cd->buf_size += size;
 
4243
 
 
4244
        if (cd->buf_size < cd->cache_size)
 
4245
                return TRUE;
 
4246
 
 
4247
        if (!write_buffer(cd->fd, cd->offset, cd->buf, cd->cache_size,
 
4248
            cd->file_name))
 
4249
                return FALSE;
 
4250
 
 
4251
        cd->buf_size -= cd->cache_size;
 
4252
        memcpy(cd->buf, cd->buf + cd->cache_size, cd->buf_size);
 
4253
        cd->offset += cd->cache_size;
 
4254
        return TRUE;
 
4255
}
 
4256
 
 
4257
int
 
4258
write_cache_bufsz(struct cache_data *cd)
 
4259
{
 
4260
        if (!cd->buf_size)
 
4261
                return TRUE;
 
4262
 
 
4263
        if (!write_buffer(cd->fd, cd->offset, cd->buf, cd->buf_size,
 
4264
            cd->file_name))
 
4265
                return FALSE;
 
4266
 
 
4267
        cd->offset  += cd->buf_size;
 
4268
        cd->buf_size = 0;
 
4269
        return TRUE;
 
4270
}
 
4271
 
 
4272
int
 
4273
read_buf_from_stdin(void *buf, int buf_size)
 
4274
{
 
4275
        int read_size = 0, tmp_read_size = 0;
 
4276
        time_t last_time, tm;
 
4277
 
 
4278
        last_time = time(NULL);
 
4279
 
 
4280
        while (read_size != buf_size) {
 
4281
 
 
4282
                tmp_read_size = read(STDIN_FILENO, buf + read_size,
 
4283
                    buf_size - read_size);
 
4284
 
 
4285
                if (tmp_read_size < 0) {
 
4286
                        ERRMSG("Can't read STDIN. %s\n", strerror(errno));
 
4287
                        return FALSE;
 
4288
 
 
4289
                } else if (0 == tmp_read_size) {
 
4290
                        /*
 
4291
                         * If it cannot get any data from a standard input
 
4292
                         * for a long time, break this loop.
 
4293
                         */
 
4294
                        tm = time(NULL);
 
4295
                        if (TIMEOUT_STDIN < (tm - last_time)) {
 
4296
                                ERRMSG("Can't get any data from STDIN.\n");
 
4297
                                return FALSE;
 
4298
                        }
 
4299
                } else {
 
4300
                        read_size += tmp_read_size;
 
4301
                        last_time = time(NULL);
 
4302
                }
 
4303
        }
 
4304
        return TRUE;
 
4305
}
 
4306
 
 
4307
int
 
4308
read_start_flat_header(void)
 
4309
{
 
4310
        char buf[MAX_SIZE_MDF_HEADER];
 
4311
        struct makedumpfile_header fh;
 
4312
 
 
4313
        /*
 
4314
         * Get flat header.
 
4315
         */
 
4316
        if (!read_buf_from_stdin(buf, MAX_SIZE_MDF_HEADER)) {
 
4317
                ERRMSG("Can't get header of flattened format.\n");
 
4318
                return FALSE;
 
4319
        }
 
4320
        memcpy(&fh, buf, sizeof(fh));
 
4321
 
 
4322
        if (!is_bigendian()){
 
4323
                fh.type    = bswap_64(fh.type);
 
4324
                fh.version = bswap_64(fh.version);
 
4325
        }
 
4326
 
 
4327
        /*
 
4328
         * Check flat header.
 
4329
         */
 
4330
        if (strcmp(fh.signature, MAKEDUMPFILE_SIGNATURE)) {
 
4331
                ERRMSG("Can't get signature of flattened format.\n");
 
4332
                return FALSE;
 
4333
        }
 
4334
        if (fh.type != TYPE_FLAT_HEADER) {
 
4335
                ERRMSG("Can't get type of flattened format.\n");
 
4336
                return FALSE;
 
4337
        }
 
4338
 
 
4339
        return TRUE;
 
4340
}
 
4341
 
 
4342
int
 
4343
read_flat_data_header(struct makedumpfile_data_header *fdh)
 
4344
{
 
4345
        if (!read_buf_from_stdin(fdh,
 
4346
            sizeof(struct makedumpfile_data_header))) {
 
4347
                ERRMSG("Can't get header of flattened format.\n");
 
4348
                return FALSE;
 
4349
        }
 
4350
        if (!is_bigendian()){
 
4351
                fdh->offset   = bswap_64(fdh->offset);
 
4352
                fdh->buf_size = bswap_64(fdh->buf_size);
 
4353
        }
 
4354
        return TRUE;
 
4355
}
 
4356
 
 
4357
int
 
4358
rearrange_dumpdata(void)
 
4359
{
 
4360
        int read_size, tmp_read_size;
 
4361
        char buf[SIZE_BUF_STDIN];
 
4362
        struct makedumpfile_data_header fdh;
 
4363
 
 
4364
        /*
 
4365
         * Get flat header.
 
4366
         */
 
4367
        if (!read_start_flat_header()) {
 
4368
                ERRMSG("Can't get header of flattened format.\n");
 
4369
                return FALSE;
 
4370
        }
 
4371
 
 
4372
        /*
 
4373
         * Read the first data header.
 
4374
         */
 
4375
        if (!read_flat_data_header(&fdh)) {
 
4376
                ERRMSG("Can't get header of flattened format.\n");
 
4377
                return FALSE;
 
4378
        }
 
4379
 
 
4380
        do {
 
4381
                read_size = 0;
 
4382
                while (read_size < fdh.buf_size) {
 
4383
                        if (sizeof(buf) < (fdh.buf_size - read_size))
 
4384
                                tmp_read_size = sizeof(buf);
 
4385
                        else
 
4386
                                tmp_read_size = fdh.buf_size - read_size;
 
4387
 
 
4388
                        if (!read_buf_from_stdin(buf, tmp_read_size)) {
 
4389
                                ERRMSG("Can't get data of flattened format.\n");
 
4390
                                return FALSE;
 
4391
                        }
 
4392
                        if (!write_buffer(info->fd_dumpfile,
 
4393
                            fdh.offset + read_size, buf, tmp_read_size,
 
4394
                            info->name_dumpfile))
 
4395
                                return FALSE;
 
4396
 
 
4397
                        read_size += tmp_read_size;
 
4398
                }
 
4399
                /*
 
4400
                 * Read the next header.
 
4401
                 */
 
4402
                if (!read_flat_data_header(&fdh)) {
 
4403
                        ERRMSG("Can't get data header of flattened format.\n");
 
4404
                        return FALSE;
 
4405
                }
 
4406
 
 
4407
        } while ((0 <= fdh.offset) && (0 < fdh.buf_size));
 
4408
 
 
4409
        if ((fdh.offset != END_FLAG_FLAT_HEADER)
 
4410
            || (fdh.buf_size != END_FLAG_FLAT_HEADER)) {
 
4411
                ERRMSG("Can't get valid end header of flattened format.\n");
 
4412
                return FALSE;
 
4413
        }
 
4414
 
 
4415
        return TRUE;
 
4416
}
 
4417
 
 
4418
/*
 
4419
 * Same as paddr_to_offset() but makes sure that the specified offset (hint)
 
4420
 * in the segment.
 
4421
 */
 
4422
off_t
 
4423
paddr_to_offset2(unsigned long long paddr, off_t hint)
 
4424
{
 
4425
        int i;
 
4426
        off_t offset;
 
4427
        unsigned long long len;
 
4428
        struct pt_load_segment *pls;
 
4429
 
 
4430
        for (i = offset = 0; i < info->num_load_memory; i++) {
 
4431
                pls = &info->pt_load_segments[i];
 
4432
                len = pls->phys_end - pls->phys_start;
 
4433
                if ((paddr >= pls->phys_start)
 
4434
                    && (paddr < pls->phys_end)
 
4435
                    && (hint >= pls->file_offset)
 
4436
                    && (hint < pls->file_offset + len)) {
 
4437
                        offset = (off_t)(paddr - pls->phys_start) +
 
4438
                                pls->file_offset;
 
4439
                                break;
 
4440
                }
 
4441
        }
 
4442
        return offset;
 
4443
}
 
4444
 
 
4445
unsigned long long
 
4446
page_to_pfn(unsigned long page)
 
4447
{
 
4448
        unsigned int num;
 
4449
        unsigned long long pfn = ULONGLONG_MAX;
 
4450
        unsigned long long index = 0;
 
4451
        struct mem_map_data *mmd;
 
4452
 
 
4453
        mmd = info->mem_map_data;
 
4454
        for (num = 0; num < info->num_mem_map; num++, mmd++) {
 
4455
                if (mmd->mem_map == NOT_MEMMAP_ADDR)
 
4456
                        continue;
 
4457
                if (page < mmd->mem_map)
 
4458
                        continue;
 
4459
                index = (page - mmd->mem_map) / SIZE(page);
 
4460
                if (index > mmd->pfn_end - mmd->pfn_start)
 
4461
                        continue;
 
4462
                pfn = mmd->pfn_start + index;
 
4463
                break;
 
4464
        }
 
4465
        if (pfn == ULONGLONG_MAX) {
 
4466
                ERRMSG("Can't convert the address of page descriptor (%lx) to pfn.\n", page);
 
4467
                return ULONGLONG_MAX;
 
4468
        }
 
4469
        return pfn;
 
4470
}
 
4471
 
 
4472
int
 
4473
reset_bitmap_of_free_pages(unsigned long node_zones)
 
4474
{
 
4475
 
 
4476
        int order, i, migrate_type, migrate_types;
 
4477
        unsigned long curr, previous, head, curr_page, curr_prev;
 
4478
        unsigned long addr_free_pages, free_pages = 0, found_free_pages = 0;
 
4479
        unsigned long long pfn, start_pfn;
 
4480
 
 
4481
        /*
 
4482
         * On linux-2.6.24 or later, free_list is divided into the array.
 
4483
         */
 
4484
        migrate_types = ARRAY_LENGTH(free_area.free_list);
 
4485
        if (migrate_types == NOT_FOUND_STRUCTURE)
 
4486
                migrate_types = 1;
 
4487
 
 
4488
        for (order = (ARRAY_LENGTH(zone.free_area) - 1); order >= 0; --order) {
 
4489
                for (migrate_type = 0; migrate_type < migrate_types;
 
4490
                     migrate_type++) {
 
4491
                        head = node_zones + OFFSET(zone.free_area)
 
4492
                                + SIZE(free_area) * order
 
4493
                                + OFFSET(free_area.free_list)
 
4494
                                + SIZE(list_head) * migrate_type;
 
4495
                        previous = head;
 
4496
                        if (!readmem(VADDR, head + OFFSET(list_head.next),
 
4497
                                     &curr, sizeof curr)) {
 
4498
                                ERRMSG("Can't get next list_head.\n");
 
4499
                                return FALSE;
 
4500
                        }
 
4501
                        for (;curr != head;) {
 
4502
                                curr_page = curr - OFFSET(page.lru);
 
4503
                                start_pfn = page_to_pfn(curr_page);
 
4504
                                if (start_pfn == ULONGLONG_MAX)
 
4505
                                        return FALSE;
 
4506
 
 
4507
                                if (!readmem(VADDR, curr+OFFSET(list_head.prev),
 
4508
                                             &curr_prev, sizeof curr_prev)) {
 
4509
                                        ERRMSG("Can't get prev list_head.\n");
 
4510
                                        return FALSE;
 
4511
                                }
 
4512
                                if (previous != curr_prev) {
 
4513
                                        ERRMSG("The free list is broken.\n");
 
4514
                                        retcd = ANALYSIS_FAILED;
 
4515
                                        return FALSE;
 
4516
                                }
 
4517
                                for (i = 0; i < (1<<order); i++) {
 
4518
                                        pfn = start_pfn + i;
 
4519
                                        clear_bit_on_2nd_bitmap_for_kernel(pfn);
 
4520
                                }
 
4521
                                found_free_pages += i;
 
4522
 
 
4523
                                previous = curr;
 
4524
                                if (!readmem(VADDR, curr+OFFSET(list_head.next),
 
4525
                                             &curr, sizeof curr)) {
 
4526
                                        ERRMSG("Can't get next list_head.\n");
 
4527
                                        return FALSE;
 
4528
                                }
 
4529
                        }
 
4530
                }
 
4531
        }
 
4532
 
 
4533
        /*
 
4534
         * Check the number of free pages.
 
4535
         */
 
4536
        if (OFFSET(zone.free_pages) != NOT_FOUND_STRUCTURE) {
 
4537
                addr_free_pages = node_zones + OFFSET(zone.free_pages);
 
4538
 
 
4539
        } else if (OFFSET(zone.vm_stat) != NOT_FOUND_STRUCTURE) {
 
4540
                /*
 
4541
                 * On linux-2.6.21 or later, the number of free_pages is
 
4542
                 * in vm_stat[NR_FREE_PAGES].
 
4543
                 */
 
4544
                addr_free_pages = node_zones + OFFSET(zone.vm_stat)
 
4545
                    + sizeof(long) * NUMBER(NR_FREE_PAGES);
 
4546
 
 
4547
        } else {
 
4548
                ERRMSG("Can't get addr_free_pages.\n");
 
4549
                return FALSE;
 
4550
        }
 
4551
        if (!readmem(VADDR, addr_free_pages, &free_pages, sizeof free_pages)) {
 
4552
                ERRMSG("Can't get free_pages.\n");
 
4553
                return FALSE;
 
4554
        }
 
4555
        if (free_pages != found_free_pages) {
 
4556
                /*
 
4557
                 * On linux-2.6.21 or later, the number of free_pages is
 
4558
                 * sometimes different from the one of the list "free_area",
 
4559
                 * because the former is flushed asynchronously.
 
4560
                 */
 
4561
                DEBUG_MSG("The number of free_pages is invalid.\n");
 
4562
                DEBUG_MSG("  free_pages       = %ld\n", free_pages);
 
4563
                DEBUG_MSG("  found_free_pages = %ld\n", found_free_pages);
 
4564
        }
 
4565
        pfn_free += found_free_pages;
 
4566
 
 
4567
        return TRUE;
 
4568
}
 
4569
 
 
4570
int
 
4571
dump_dmesg()
 
4572
{
 
4573
        int log_buf_len, length_log, length_oldlog, ret = FALSE;
 
4574
        unsigned long log_buf, log_end, index;
 
4575
        unsigned long log_end_2_6_24;
 
4576
        unsigned      log_end_2_6_25;
 
4577
        char *log_buffer = NULL;
 
4578
 
 
4579
        /*
 
4580
         * log_end has been changed to "unsigned" since linux-2.6.25.
 
4581
         *   2.6.24 or former: static unsigned long log_end;
 
4582
         *   2.6.25 or later : static unsigned log_end;
 
4583
         */
 
4584
        if (!open_files_for_creating_dumpfile())
 
4585
                return FALSE;
 
4586
 
 
4587
        if (!info->flag_refiltering) {
 
4588
                if (!get_elf_info())
 
4589
                        return FALSE;
 
4590
        }
 
4591
        if (!initial())
 
4592
                return FALSE;
 
4593
 
 
4594
        if ((SYMBOL(log_buf) == NOT_FOUND_SYMBOL)
 
4595
            || (SYMBOL(log_buf_len) == NOT_FOUND_SYMBOL)
 
4596
            || (SYMBOL(log_end) == NOT_FOUND_SYMBOL)) {
 
4597
                ERRMSG("Can't find some symbols for log_buf.\n");
 
4598
                return FALSE;
 
4599
        }
 
4600
        if (!readmem(VADDR, SYMBOL(log_buf), &log_buf, sizeof(log_buf))) {
 
4601
                ERRMSG("Can't get log_buf.\n");
 
4602
                return FALSE;
 
4603
        }
 
4604
        if (info->kernel_version >= KERNEL_VERSION(2, 6, 25)) {
 
4605
                if (!readmem(VADDR, SYMBOL(log_end), &log_end_2_6_25,
 
4606
                    sizeof(log_end_2_6_25))) {
 
4607
                        ERRMSG("Can't to get log_end.\n");
 
4608
                        return FALSE;
 
4609
                }
 
4610
                log_end = log_end_2_6_25;
 
4611
        } else {
 
4612
                if (!readmem(VADDR, SYMBOL(log_end), &log_end_2_6_24,
 
4613
                    sizeof(log_end_2_6_24))) {
 
4614
                        ERRMSG("Can't to get log_end.\n");
 
4615
                        return FALSE;
 
4616
                }
 
4617
                log_end = log_end_2_6_24;
 
4618
        }
 
4619
        if (!readmem(VADDR, SYMBOL(log_buf_len), &log_buf_len,
 
4620
            sizeof(log_buf_len))) {
 
4621
                ERRMSG("Can't get log_buf_len.\n");
 
4622
                return FALSE;
 
4623
        }
 
4624
        DEBUG_MSG("\n");
 
4625
        DEBUG_MSG("log_buf      : %lx\n", log_buf);
 
4626
        DEBUG_MSG("log_end      : %lx\n", log_end);
 
4627
        DEBUG_MSG("log_buf_len  : %d\n", log_buf_len);
 
4628
 
 
4629
        if ((log_buffer = malloc(log_buf_len)) == NULL) {
 
4630
                ERRMSG("Can't allocate memory for log_buf. %s\n",
 
4631
                    strerror(errno));
 
4632
                return FALSE;
 
4633
        }
 
4634
 
 
4635
        if (log_end < log_buf_len) {
 
4636
                length_log = log_end;
 
4637
                if(!readmem(VADDR, log_buf, log_buffer, length_log)) {
 
4638
                        ERRMSG("Can't read dmesg log.\n");
 
4639
                        goto out;
 
4640
                }
 
4641
        } else {
 
4642
                index = log_end & (log_buf_len - 1);
 
4643
                DEBUG_MSG("index        : %lx\n", index);
 
4644
                length_log = log_buf_len;
 
4645
                length_oldlog = log_buf_len - index;
 
4646
                if(!readmem(VADDR, log_buf + index, log_buffer, length_oldlog)) {
 
4647
                        ERRMSG("Can't read old dmesg log.\n");
 
4648
                        goto out;
 
4649
                }
 
4650
                if(!readmem(VADDR, log_buf, log_buffer + length_oldlog, index)) {
 
4651
                        ERRMSG("Can't read new dmesg log.\n");
 
4652
                        goto out;
 
4653
                }
 
4654
        }
 
4655
        DEBUG_MSG("length_log   : %d\n", length_log);
 
4656
 
 
4657
        if (!open_dump_file()) {
 
4658
                ERRMSG("Can't open output file.\n");
 
4659
                goto out;
 
4660
        }
 
4661
        if (write(info->fd_dumpfile, log_buffer, length_log) < 0)
 
4662
                goto out;
 
4663
 
 
4664
        if (!close_files_for_creating_dumpfile())
 
4665
                goto out;
 
4666
 
 
4667
        ret = TRUE;
 
4668
out:
 
4669
        if (log_buffer)
 
4670
                free(log_buffer);
 
4671
 
 
4672
        return ret;
 
4673
}
 
4674
 
 
4675
 
 
4676
int
 
4677
_exclude_free_page(void)
 
4678
{
 
4679
        int i, nr_zones, num_nodes, node;
 
4680
        unsigned long node_zones, zone, spanned_pages, pgdat;
 
4681
        struct timeval tv_start;
 
4682
 
 
4683
        if ((node = next_online_node(0)) < 0) {
 
4684
                ERRMSG("Can't get next online node.\n");
 
4685
                return FALSE;
 
4686
        }
 
4687
        if (!(pgdat = next_online_pgdat(node))) {
 
4688
                ERRMSG("Can't get pgdat list.\n");
 
4689
                return FALSE;
 
4690
        }
 
4691
        gettimeofday(&tv_start, NULL);
 
4692
 
 
4693
        for (num_nodes = 1; num_nodes <= vt.numnodes; num_nodes++) {
 
4694
 
 
4695
                print_progress(PROGRESS_FREE_PAGES, num_nodes - 1, vt.numnodes);
 
4696
 
 
4697
                node_zones = pgdat + OFFSET(pglist_data.node_zones);
 
4698
 
 
4699
                if (!readmem(VADDR, pgdat + OFFSET(pglist_data.nr_zones),
 
4700
                    &nr_zones, sizeof(nr_zones))) {
 
4701
                        ERRMSG("Can't get nr_zones.\n");
 
4702
                        return FALSE;
 
4703
                }
 
4704
 
 
4705
                for (i = 0; i < nr_zones; i++) {
 
4706
 
 
4707
                        print_progress(PROGRESS_FREE_PAGES, i + nr_zones * (num_nodes - 1),
 
4708
                                        nr_zones * vt.numnodes);
 
4709
 
 
4710
                        zone = node_zones + (i * SIZE(zone));
 
4711
                        if (!readmem(VADDR, zone + OFFSET(zone.spanned_pages),
 
4712
                            &spanned_pages, sizeof spanned_pages)) {
 
4713
                                ERRMSG("Can't get spanned_pages.\n");
 
4714
                                return FALSE;
 
4715
                        }
 
4716
                        if (!spanned_pages)
 
4717
                                continue;
 
4718
                        if (!reset_bitmap_of_free_pages(zone))
 
4719
                                return FALSE;
 
4720
                }
 
4721
                if (num_nodes < vt.numnodes) {
 
4722
                        if ((node = next_online_node(node + 1)) < 0) {
 
4723
                                ERRMSG("Can't get next online node.\n");
 
4724
                                return FALSE;
 
4725
                        } else if (!(pgdat = next_online_pgdat(node))) {
 
4726
                                ERRMSG("Can't determine pgdat list (node %d).\n",
 
4727
                                    node);
 
4728
                                return FALSE;
 
4729
                        }
 
4730
                }
 
4731
        }
 
4732
 
 
4733
        /*
 
4734
         * print [100 %]
 
4735
         */
 
4736
        print_progress(PROGRESS_FREE_PAGES, vt.numnodes, vt.numnodes);
 
4737
        print_execution_time(PROGRESS_FREE_PAGES, &tv_start);
 
4738
 
 
4739
        return TRUE;
 
4740
}
 
4741
 
 
4742
int
 
4743
exclude_free_page(void)
 
4744
{
 
4745
        /*
 
4746
         * Check having necessary information.
 
4747
         */
 
4748
        if ((SYMBOL(node_data) == NOT_FOUND_SYMBOL)
 
4749
            && (SYMBOL(pgdat_list) == NOT_FOUND_SYMBOL)
 
4750
            && (SYMBOL(contig_page_data) == NOT_FOUND_SYMBOL)) {
 
4751
                ERRMSG("Can't get necessary symbols for excluding free pages.\n");
 
4752
                return FALSE;
 
4753
        }
 
4754
        if ((SIZE(zone) == NOT_FOUND_STRUCTURE)
 
4755
            || ((OFFSET(zone.free_pages) == NOT_FOUND_STRUCTURE)
 
4756
                && (OFFSET(zone.vm_stat) == NOT_FOUND_STRUCTURE))
 
4757
            || (OFFSET(zone.free_area) == NOT_FOUND_STRUCTURE)
 
4758
            || (OFFSET(zone.spanned_pages) == NOT_FOUND_STRUCTURE)
 
4759
            || (OFFSET(pglist_data.node_zones) == NOT_FOUND_STRUCTURE)
 
4760
            || (OFFSET(pglist_data.nr_zones) == NOT_FOUND_STRUCTURE)
 
4761
            || (SIZE(free_area) == NOT_FOUND_STRUCTURE)
 
4762
            || (OFFSET(free_area.free_list) == NOT_FOUND_STRUCTURE)
 
4763
            || (OFFSET(list_head.next) == NOT_FOUND_STRUCTURE)
 
4764
            || (OFFSET(list_head.prev) == NOT_FOUND_STRUCTURE)
 
4765
            || (OFFSET(page.lru) == NOT_FOUND_STRUCTURE)
 
4766
            || (ARRAY_LENGTH(zone.free_area) == NOT_FOUND_STRUCTURE)) {
 
4767
                ERRMSG("Can't get necessary structures for excluding free pages.\n");
 
4768
                return FALSE;
 
4769
        }
 
4770
 
 
4771
        /*
 
4772
         * Detect free pages and update 2nd-bitmap.
 
4773
         */
 
4774
        if (!_exclude_free_page())
 
4775
                return FALSE;
 
4776
 
 
4777
        return TRUE;
 
4778
}
 
4779
 
 
4780
/*
 
4781
 * If using a dumpfile in kdump-compressed format as a source file
 
4782
 * instead of /proc/vmcore, 1st-bitmap of a new dumpfile must be
 
4783
 * the same as the one of a source file.
 
4784
 */
 
4785
int
 
4786
copy_1st_bitmap_from_memory(void)
 
4787
{
 
4788
        char buf[info->dh_memory->block_size];
 
4789
        off_t offset_page;
 
4790
        off_t bitmap_offset;
 
4791
        struct disk_dump_header *dh = info->dh_memory;
 
4792
 
 
4793
        bitmap_offset = (DISKDUMP_HEADER_BLOCKS + dh->sub_hdr_size)
 
4794
                         * dh->block_size;
 
4795
 
 
4796
        if (lseek(info->fd_memory, bitmap_offset, SEEK_SET) < 0) {
 
4797
                ERRMSG("Can't seek %s. %s\n",
 
4798
                                info->name_memory, strerror(errno));
 
4799
                return FALSE;
 
4800
        }
 
4801
        if (lseek(info->bitmap1->fd, info->bitmap1->offset, SEEK_SET) < 0) {
 
4802
                ERRMSG("Can't seek the bitmap(%s). %s\n",
 
4803
                    info->bitmap1->file_name, strerror(errno));
 
4804
                return FALSE;
 
4805
        }
 
4806
        offset_page = 0;
 
4807
        while (offset_page < (info->len_bitmap / 2)) {
 
4808
                if (read(info->fd_memory, buf, sizeof(buf)) != sizeof(buf)) {
 
4809
                        ERRMSG("Can't read %s. %s\n",
 
4810
                                        info->name_memory, strerror(errno));
 
4811
                        return FALSE;
 
4812
                }
 
4813
                if (write(info->bitmap1->fd, buf, sizeof(buf)) != sizeof(buf)) {
 
4814
                        ERRMSG("Can't write the bitmap(%s). %s\n",
 
4815
                            info->bitmap1->file_name, strerror(errno));
 
4816
                        return FALSE;
 
4817
                }
 
4818
                offset_page += sizeof(buf);
 
4819
        }
 
4820
        return TRUE;
 
4821
}
 
4822
 
 
4823
int
 
4824
create_1st_bitmap(void)
 
4825
{
 
4826
        int i;
 
4827
        char buf[info->page_size];
 
4828
        unsigned long long pfn, pfn_start, pfn_end, pfn_bitmap1;
 
4829
        struct pt_load_segment *pls;
 
4830
        struct timeval tv_start;
 
4831
        off_t offset_page;
 
4832
 
 
4833
        if (info->flag_refiltering)
 
4834
                return copy_1st_bitmap_from_memory();
 
4835
 
 
4836
        /*
 
4837
         * At first, clear all the bits on the 1st-bitmap.
 
4838
         */
 
4839
        memset(buf, 0, sizeof(buf));
 
4840
 
 
4841
        if (lseek(info->bitmap1->fd, info->bitmap1->offset, SEEK_SET) < 0) {
 
4842
                ERRMSG("Can't seek the bitmap(%s). %s\n",
 
4843
                    info->bitmap1->file_name, strerror(errno));
 
4844
                return FALSE;
 
4845
        }
 
4846
        offset_page = 0;
 
4847
        while (offset_page < (info->len_bitmap / 2)) {
 
4848
                if (write(info->bitmap1->fd, buf, info->page_size)
 
4849
                    != info->page_size) {
 
4850
                        ERRMSG("Can't write the bitmap(%s). %s\n",
 
4851
                            info->bitmap1->file_name, strerror(errno));
 
4852
                        return FALSE;
 
4853
                }
 
4854
                offset_page += info->page_size;
 
4855
        }
 
4856
 
 
4857
        gettimeofday(&tv_start, NULL);
 
4858
 
 
4859
        /*
 
4860
         * If page is on memory hole, set bit on the 1st-bitmap.
 
4861
         */
 
4862
        for (i = pfn_bitmap1 = 0; i < info->num_load_memory; i++) {
 
4863
 
 
4864
                print_progress(PROGRESS_HOLES, i, info->num_load_memory);
 
4865
 
 
4866
                pls = &info->pt_load_segments[i];
 
4867
                pfn_start = paddr_to_pfn(pls->phys_start);
 
4868
                pfn_end   = paddr_to_pfn(pls->phys_end);
 
4869
 
 
4870
                if (!is_in_segs(pfn_to_paddr(pfn_start)))
 
4871
                        pfn_start++;
 
4872
                for (pfn = pfn_start; pfn < pfn_end; pfn++) {
 
4873
                        set_bit_on_1st_bitmap(pfn);
 
4874
                        pfn_bitmap1++;
 
4875
                }
 
4876
        }
 
4877
        pfn_memhole = info->max_mapnr - pfn_bitmap1;
 
4878
 
 
4879
        /*
 
4880
         * print 100 %
 
4881
         */
 
4882
        print_progress(PROGRESS_HOLES, info->max_mapnr, info->max_mapnr);
 
4883
        print_execution_time(PROGRESS_HOLES, &tv_start);
 
4884
 
 
4885
        if (!sync_1st_bitmap())
 
4886
                return FALSE;
 
4887
 
 
4888
        return TRUE;
 
4889
}
 
4890
 
 
4891
/*
 
4892
 * Exclude the page filled with zero in case of creating an elf dumpfile.
 
4893
 */
 
4894
int
 
4895
exclude_zero_pages(void)
 
4896
{
 
4897
        unsigned long long pfn, paddr;
 
4898
        struct dump_bitmap bitmap2;
 
4899
        struct timeval tv_start;
 
4900
        unsigned char buf[info->page_size];
 
4901
 
 
4902
        initialize_2nd_bitmap(&bitmap2);
 
4903
 
 
4904
        gettimeofday(&tv_start, NULL);
 
4905
 
 
4906
        for (pfn = 0, paddr = pfn_to_paddr(pfn); pfn < info->max_mapnr;
 
4907
            pfn++, paddr += info->page_size) {
 
4908
 
 
4909
                print_progress(PROGRESS_ZERO_PAGES, pfn, info->max_mapnr);
 
4910
 
 
4911
                if (!is_in_segs(paddr))
 
4912
                        continue;
 
4913
 
 
4914
                if (!is_dumpable(&bitmap2, pfn))
 
4915
                        continue;
 
4916
 
 
4917
                if (vt.mem_flags & MEMORY_XEN) {
 
4918
                        if (!readmem(MADDR_XEN, paddr, buf, info->page_size)) {
 
4919
                                ERRMSG("Can't get the page data(pfn:%llx, max_mapnr:%llx).\n",
 
4920
                                    pfn, info->max_mapnr);
 
4921
                                return FALSE;
 
4922
                        }
 
4923
                } else {
 
4924
                        if (!readmem(PADDR, paddr, buf, info->page_size)) {
 
4925
                                ERRMSG("Can't get the page data(pfn:%llx, max_mapnr:%llx).\n",
 
4926
                                    pfn, info->max_mapnr);
 
4927
                                return FALSE;
 
4928
                        }
 
4929
                }
 
4930
                if (is_zero_page(buf, info->page_size)) {
 
4931
                        clear_bit_on_2nd_bitmap(pfn);
 
4932
                        pfn_zero++;
 
4933
                }
 
4934
        }
 
4935
 
 
4936
        /*
 
4937
         * print [100 %]
 
4938
         */
 
4939
        print_progress(PROGRESS_ZERO_PAGES, info->max_mapnr, info->max_mapnr);
 
4940
        print_execution_time(PROGRESS_ZERO_PAGES, &tv_start);
 
4941
 
 
4942
        return TRUE;
 
4943
}
 
4944
 
 
4945
int
 
4946
__exclude_unnecessary_pages(unsigned long mem_map,
 
4947
    unsigned long long pfn_start, unsigned long long pfn_end)
 
4948
{
 
4949
        unsigned long long pfn, pfn_mm, maddr;
 
4950
        unsigned long long pfn_read_start, pfn_read_end, index_pg;
 
4951
        unsigned char page_cache[SIZE(page) * PGMM_CACHED];
 
4952
        unsigned char *pcache;
 
4953
        unsigned int _count;
 
4954
        unsigned long flags, mapping;
 
4955
 
 
4956
        /*
 
4957
         * Refresh the buffer of struct page, when changing mem_map.
 
4958
         */
 
4959
        pfn_read_start = ULONGLONG_MAX;
 
4960
        pfn_read_end   = 0;
 
4961
 
 
4962
        for (pfn = pfn_start; pfn < pfn_end; pfn++, mem_map += SIZE(page)) {
 
4963
 
 
4964
                /*
 
4965
                 * Exclude the memory hole.
 
4966
                 */
 
4967
                if (vt.mem_flags & MEMORY_XEN) {
 
4968
                        maddr = ptom_xen(pfn_to_paddr(pfn));
 
4969
                        if (maddr == NOT_PADDR) {
 
4970
                                ERRMSG("Can't convert a physical address(%llx) to machine address.\n",
 
4971
                                    pfn_to_paddr(pfn));
 
4972
                                return FALSE;
 
4973
                        }
 
4974
                        if (!is_in_segs(maddr))
 
4975
                                continue;
 
4976
                } else {
 
4977
                        if (!is_in_segs(pfn_to_paddr(pfn)))
 
4978
                                continue;
 
4979
                }
 
4980
 
 
4981
                index_pg = pfn % PGMM_CACHED;
 
4982
                if (pfn < pfn_read_start || pfn_read_end < pfn) {
 
4983
                        if (roundup(pfn + 1, PGMM_CACHED) < pfn_end)
 
4984
                                pfn_mm = PGMM_CACHED - index_pg;
 
4985
                        else
 
4986
                                pfn_mm = pfn_end - pfn;
 
4987
 
 
4988
                        if (!readmem(VADDR, mem_map,
 
4989
                            page_cache + (index_pg * SIZE(page)),
 
4990
                            SIZE(page) * pfn_mm)) {
 
4991
                                ERRMSG("Can't read the buffer of struct page.\n");
 
4992
                                return FALSE;
 
4993
                        }
 
4994
                        pfn_read_start = pfn;
 
4995
                        pfn_read_end   = pfn + pfn_mm - 1;
 
4996
                }
 
4997
                pcache  = page_cache + (index_pg * SIZE(page));
 
4998
 
 
4999
                flags   = ULONG(pcache + OFFSET(page.flags));
 
5000
                _count  = UINT(pcache + OFFSET(page._count));
 
5001
                mapping = ULONG(pcache + OFFSET(page.mapping));
 
5002
 
 
5003
                /*
 
5004
                 * Exclude the cache page without the private page.
 
5005
                 */
 
5006
                if ((info->dump_level & DL_EXCLUDE_CACHE)
 
5007
                    && (isLRU(flags) || isSwapCache(flags))
 
5008
                    && !isPrivate(flags) && !isAnon(mapping)) {
 
5009
                        clear_bit_on_2nd_bitmap_for_kernel(pfn);
 
5010
                        pfn_cache++;
 
5011
                }
 
5012
                /*
 
5013
                 * Exclude the cache page with the private page.
 
5014
                 */
 
5015
                else if ((info->dump_level & DL_EXCLUDE_CACHE_PRI)
 
5016
                    && (isLRU(flags) || isSwapCache(flags))
 
5017
                    && !isAnon(mapping)) {
 
5018
                        clear_bit_on_2nd_bitmap_for_kernel(pfn);
 
5019
                        pfn_cache_private++;
 
5020
                }
 
5021
                /*
 
5022
                 * Exclude the data page of the user process.
 
5023
                 */
 
5024
                else if ((info->dump_level & DL_EXCLUDE_USER_DATA)
 
5025
                    && isAnon(mapping)) {
 
5026
                        clear_bit_on_2nd_bitmap_for_kernel(pfn);
 
5027
                        pfn_user++;
 
5028
                }
 
5029
        }
 
5030
        return TRUE;
 
5031
}
 
5032
 
 
5033
int
 
5034
exclude_unnecessary_pages(void)
 
5035
{
 
5036
        unsigned int mm;
 
5037
        struct mem_map_data *mmd;
 
5038
        struct timeval tv_start;
 
5039
 
 
5040
        gettimeofday(&tv_start, NULL);
 
5041
 
 
5042
        for (mm = 0; mm < info->num_mem_map; mm++) {
 
5043
                print_progress(PROGRESS_UNN_PAGES, mm, info->num_mem_map);
 
5044
 
 
5045
                mmd = &info->mem_map_data[mm];
 
5046
 
 
5047
                if (mmd->mem_map == NOT_MEMMAP_ADDR)
 
5048
                        continue;
 
5049
 
 
5050
                if (!__exclude_unnecessary_pages(mmd->mem_map,
 
5051
                                                 mmd->pfn_start, mmd->pfn_end))
 
5052
                        return FALSE;
 
5053
        }
 
5054
 
 
5055
        /*
 
5056
         * print [100 %]
 
5057
         */
 
5058
        print_progress(PROGRESS_UNN_PAGES, info->num_mem_map, info->num_mem_map);
 
5059
        print_execution_time(PROGRESS_UNN_PAGES, &tv_start);
 
5060
 
 
5061
        return TRUE;
 
5062
}
 
5063
 
 
5064
int
 
5065
copy_bitmap(void)
 
5066
{
 
5067
        off_t offset;
 
5068
        unsigned char buf[info->page_size];
 
5069
        const off_t failed = (off_t)-1;
 
5070
 
 
5071
        offset = 0;
 
5072
        while (offset < (info->len_bitmap / 2)) {
 
5073
                if (lseek(info->bitmap1->fd, info->bitmap1->offset + offset,
 
5074
                    SEEK_SET) == failed) {
 
5075
                        ERRMSG("Can't seek the bitmap(%s). %s\n",
 
5076
                            info->name_bitmap, strerror(errno));
 
5077
                        return FALSE;
 
5078
                }
 
5079
                if (read(info->bitmap1->fd, buf, sizeof(buf)) != sizeof(buf)) {
 
5080
                        ERRMSG("Can't read the dump memory(%s). %s\n",
 
5081
                            info->name_memory, strerror(errno));
 
5082
                        return FALSE;
 
5083
                }
 
5084
                if (lseek(info->bitmap2->fd, info->bitmap2->offset + offset,
 
5085
                    SEEK_SET) == failed) {
 
5086
                        ERRMSG("Can't seek the bitmap(%s). %s\n",
 
5087
                            info->name_bitmap, strerror(errno));
 
5088
                        return FALSE;
 
5089
                }
 
5090
                if (write(info->bitmap2->fd, buf, sizeof(buf)) != sizeof(buf)) {
 
5091
                        ERRMSG("Can't write the bitmap(%s). %s\n",
 
5092
                        info->name_bitmap, strerror(errno));
 
5093
                        return FALSE;
 
5094
                }
 
5095
                offset += sizeof(buf);
 
5096
        }
 
5097
 
 
5098
        return TRUE;
 
5099
}
 
5100
 
 
5101
int
 
5102
create_2nd_bitmap(void)
 
5103
{
 
5104
        /*
 
5105
         * Copy 1st-bitmap to 2nd-bitmap.
 
5106
         */
 
5107
        if (!copy_bitmap()) {
 
5108
                ERRMSG("Can't copy 1st-bitmap to 2nd-bitmap.\n");
 
5109
                return FALSE;
 
5110
        }
 
5111
 
 
5112
        /*
 
5113
         * Exclude cache pages, cache private pages, user data pages.
 
5114
         */
 
5115
        if (info->dump_level & DL_EXCLUDE_CACHE ||
 
5116
            info->dump_level & DL_EXCLUDE_CACHE_PRI ||
 
5117
            info->dump_level & DL_EXCLUDE_USER_DATA) {
 
5118
                if (!exclude_unnecessary_pages()) {
 
5119
                        ERRMSG("Can't exclude unnecessary pages.\n");
 
5120
                        return FALSE;
 
5121
                }
 
5122
        }
 
5123
 
 
5124
        /*
 
5125
         * Exclude free pages.
 
5126
         */
 
5127
        if (info->dump_level & DL_EXCLUDE_FREE)
 
5128
                if (!exclude_free_page())
 
5129
                        return FALSE;
 
5130
 
 
5131
        /*
 
5132
         * Exclude Xen user domain.
 
5133
         */
 
5134
        if (info->flag_exclude_xen_dom) {
 
5135
                if (!exclude_xen_user_domain()) {
 
5136
                        ERRMSG("Can't exclude xen user domain.\n");
 
5137
                        return FALSE;
 
5138
                }
 
5139
        }
 
5140
 
 
5141
        /*
 
5142
         * Exclude pages filled with zero for creating an ELF dumpfile.
 
5143
         *
 
5144
         * Note: If creating a kdump-compressed dumpfile, makedumpfile
 
5145
         *       checks zero-pages while copying dumpable pages to a
 
5146
         *       dumpfile from /proc/vmcore. That is valuable for the
 
5147
         *       speed, because each page is read one time only.
 
5148
         *       Otherwise (if creating an ELF dumpfile), makedumpfile
 
5149
         *       should check zero-pages at this time because 2nd-bitmap
 
5150
         *       should be fixed for creating an ELF header. That is slow
 
5151
         *       due to reading each page two times, but it is necessary.
 
5152
         */
 
5153
        if ((info->dump_level & DL_EXCLUDE_ZERO) && info->flag_elf_dumpfile) {
 
5154
                /*
 
5155
                 * 2nd-bitmap should be flushed at this time, because
 
5156
                 * exclude_zero_pages() checks 2nd-bitmap.
 
5157
                 */
 
5158
                if (!sync_2nd_bitmap())
 
5159
                        return FALSE;
 
5160
 
 
5161
                if (!exclude_zero_pages()) {
 
5162
                        ERRMSG("Can't exclude pages filled with zero for creating an ELF dumpfile.\n");
 
5163
                        return FALSE;
 
5164
                }
 
5165
        }
 
5166
 
 
5167
        if (!sync_2nd_bitmap())
 
5168
                return FALSE;
 
5169
 
 
5170
        return TRUE;
 
5171
}
 
5172
 
 
5173
int
 
5174
prepare_bitmap_buffer(void)
 
5175
{
 
5176
        unsigned long tmp;
 
5177
 
 
5178
        /*
 
5179
         * Create 2 bitmaps (1st-bitmap & 2nd-bitmap) on block_size boundary.
 
5180
         * The crash utility requires both of them to be aligned to block_size
 
5181
         * boundary.
 
5182
         */
 
5183
        tmp = divideup(divideup(info->max_mapnr, BITPERBYTE), info->page_size);
 
5184
        info->len_bitmap = tmp*info->page_size*2;
 
5185
 
 
5186
        /*
 
5187
         * Prepare bitmap buffers for creating dump bitmap.
 
5188
         */
 
5189
        if ((info->bitmap1 = malloc(sizeof(struct dump_bitmap))) == NULL) {
 
5190
                ERRMSG("Can't allocate memory for the 1st-bitmap. %s\n",
 
5191
                    strerror(errno));
 
5192
                return FALSE;
 
5193
        }
 
5194
        if ((info->bitmap2 = malloc(sizeof(struct dump_bitmap))) == NULL) {
 
5195
                ERRMSG("Can't allocate memory for the 2nd-bitmap. %s\n",
 
5196
                    strerror(errno));
 
5197
                return FALSE;
 
5198
        }
 
5199
        initialize_1st_bitmap(info->bitmap1);
 
5200
        initialize_2nd_bitmap(info->bitmap2);
 
5201
 
 
5202
        return TRUE;
 
5203
}
 
5204
 
 
5205
void
 
5206
free_bitmap_buffer(void)
 
5207
{
 
5208
        if (info->bitmap1) {
 
5209
                free(info->bitmap1);
 
5210
                info->bitmap1 = NULL;
 
5211
        }
 
5212
        if (info->bitmap2) {
 
5213
                free(info->bitmap2);
 
5214
                info->bitmap2 = NULL;
 
5215
        }
 
5216
 
 
5217
        return;
 
5218
}
 
5219
 
 
5220
int
 
5221
create_dump_bitmap(void)
 
5222
{
 
5223
        int ret = FALSE;
 
5224
 
 
5225
        if (!prepare_bitmap_buffer())
 
5226
                goto out;
 
5227
 
 
5228
        if (!create_1st_bitmap())
 
5229
                goto out;
 
5230
 
 
5231
        if (!create_2nd_bitmap())
 
5232
                goto out;
 
5233
 
 
5234
        ret = TRUE;
 
5235
out:
 
5236
        free_bitmap_buffer();
 
5237
 
 
5238
        return ret;
 
5239
}
 
5240
 
 
5241
int
 
5242
get_phnum_memory(void)
 
5243
{
 
5244
        int phnum;
 
5245
        Elf64_Ehdr ehdr64;
 
5246
        Elf32_Ehdr ehdr32;
 
5247
 
 
5248
        if (info->flag_elf64_memory) { /* ELF64 */
 
5249
                if (!get_elf64_ehdr(&ehdr64)) {
 
5250
                        ERRMSG("Can't get ehdr64.\n");
 
5251
                        return FALSE;
 
5252
                }
 
5253
                phnum = ehdr64.e_phnum;
 
5254
        } else {                /* ELF32 */
 
5255
                if (!get_elf32_ehdr(&ehdr32)) {
 
5256
                        ERRMSG("Can't get ehdr32.\n");
 
5257
                        return FALSE;
 
5258
                }
 
5259
                phnum = ehdr32.e_phnum;
 
5260
        }
 
5261
 
 
5262
        return phnum;
 
5263
}
 
5264
 
 
5265
int
 
5266
get_loads_dumpfile(void)
 
5267
{
 
5268
        int i, phnum, num_new_load = 0;
 
5269
        long page_size = info->page_size;
 
5270
        unsigned long long pfn, pfn_start, pfn_end, num_excluded;
 
5271
        unsigned long frac_head, frac_tail;
 
5272
        Elf64_Phdr load;
 
5273
        struct dump_bitmap bitmap2;
 
5274
 
 
5275
        initialize_2nd_bitmap(&bitmap2);
 
5276
 
 
5277
        if (!(phnum = get_phnum_memory()))
 
5278
                return FALSE;
 
5279
 
 
5280
        for (i = 0; i < phnum; i++) {
 
5281
                if (!get_elf_phdr_memory(i, &load))
 
5282
                        return FALSE;
 
5283
                if (load.p_type != PT_LOAD)
 
5284
                        continue;
 
5285
 
 
5286
                pfn_start = paddr_to_pfn(load.p_paddr);
 
5287
                pfn_end   = paddr_to_pfn(load.p_paddr + load.p_memsz);
 
5288
                frac_head = page_size - (load.p_paddr % page_size);
 
5289
                frac_tail = (load.p_paddr + load.p_memsz) % page_size;
 
5290
 
 
5291
                num_new_load++;
 
5292
                num_excluded = 0;
 
5293
 
 
5294
                if (frac_head && (frac_head != page_size))
 
5295
                        pfn_start++;
 
5296
                if (frac_tail)
 
5297
                        pfn_end++;
 
5298
 
 
5299
                for (pfn = pfn_start; pfn < pfn_end; pfn++) {
 
5300
                        if (!is_dumpable(&bitmap2, pfn)) {
 
5301
                                num_excluded++;
 
5302
                                continue;
 
5303
                        }
 
5304
 
 
5305
                        /*
 
5306
                         * If the number of the contiguous pages to be excluded
 
5307
                         * is 256 or more, those pages are excluded really.
 
5308
                         * And a new PT_LOAD segment is created.
 
5309
                         */
 
5310
                        if (num_excluded >= PFN_EXCLUDED) {
 
5311
                                num_new_load++;
 
5312
                        }
 
5313
                        num_excluded = 0;
 
5314
                }
 
5315
        }
 
5316
        return num_new_load;
 
5317
}
 
5318
 
 
5319
int
 
5320
prepare_cache_data(struct cache_data *cd)
 
5321
{
 
5322
        cd->fd         = info->fd_dumpfile;
 
5323
        cd->file_name  = info->name_dumpfile;
 
5324
        cd->cache_size = info->page_size << info->block_order;
 
5325
        cd->buf_size   = 0;
 
5326
        cd->buf        = NULL;
 
5327
 
 
5328
        if ((cd->buf = malloc(cd->cache_size + info->page_size)) == NULL) {
 
5329
                ERRMSG("Can't allocate memory for the data buffer. %s\n",
 
5330
                    strerror(errno));
 
5331
                return FALSE;
 
5332
        }
 
5333
        return TRUE;
 
5334
}
 
5335
 
 
5336
void
 
5337
free_cache_data(struct cache_data *cd)
 
5338
{
 
5339
        free(cd->buf);
 
5340
        cd->buf = NULL;
 
5341
}
 
5342
 
 
5343
int
 
5344
write_start_flat_header()
 
5345
{
 
5346
        char buf[MAX_SIZE_MDF_HEADER];
 
5347
        struct makedumpfile_header fh;
 
5348
 
 
5349
        if (!info->flag_flatten)
 
5350
                return FALSE;
 
5351
 
 
5352
        strcpy(fh.signature, MAKEDUMPFILE_SIGNATURE);
 
5353
 
 
5354
        /*
 
5355
         * For sending dump data to a different architecture, change the values
 
5356
         * to big endian.
 
5357
         */
 
5358
        if (is_bigendian()){
 
5359
                fh.type    = TYPE_FLAT_HEADER;
 
5360
                fh.version = VERSION_FLAT_HEADER;
 
5361
        } else {
 
5362
                fh.type    = bswap_64(TYPE_FLAT_HEADER);
 
5363
                fh.version = bswap_64(VERSION_FLAT_HEADER);
 
5364
        }
 
5365
 
 
5366
        memset(buf, 0, sizeof(buf));
 
5367
        memcpy(buf, &fh, sizeof(fh));
 
5368
 
 
5369
        if (!write_and_check_space(info->fd_dumpfile, buf, MAX_SIZE_MDF_HEADER,
 
5370
            info->name_dumpfile))
 
5371
                return FALSE;
 
5372
 
 
5373
        return TRUE;
 
5374
}
 
5375
 
 
5376
int
 
5377
write_end_flat_header(void)
 
5378
{
 
5379
        struct makedumpfile_data_header fdh;
 
5380
 
 
5381
        if (!info->flag_flatten)
 
5382
                return FALSE;
 
5383
 
 
5384
        fdh.offset   = END_FLAG_FLAT_HEADER;
 
5385
        fdh.buf_size = END_FLAG_FLAT_HEADER;
 
5386
 
 
5387
        if (!write_and_check_space(info->fd_dumpfile, &fdh, sizeof(fdh),
 
5388
            info->name_dumpfile))
 
5389
                return FALSE;
 
5390
 
 
5391
        return TRUE;
 
5392
}
 
5393
 
 
5394
int
 
5395
write_elf_phdr(struct cache_data *cd_hdr, Elf64_Phdr *load)
 
5396
{
 
5397
        Elf32_Phdr load32;
 
5398
 
 
5399
        if (info->flag_elf64_memory) { /* ELF64 */
 
5400
                if (!write_cache(cd_hdr, load, sizeof(Elf64_Phdr)))
 
5401
                        return FALSE;
 
5402
 
 
5403
        } else {
 
5404
                memset(&load32, 0, sizeof(Elf32_Phdr));
 
5405
                load32.p_type   = load->p_type;
 
5406
                load32.p_flags  = load->p_flags;
 
5407
                load32.p_offset = load->p_offset;
 
5408
                load32.p_vaddr  = load->p_vaddr;
 
5409
                load32.p_paddr  = load->p_paddr;
 
5410
                load32.p_filesz = load->p_filesz;
 
5411
                load32.p_memsz  = load->p_memsz;
 
5412
                load32.p_align  = load->p_align;
 
5413
 
 
5414
                if (!write_cache(cd_hdr, &load32, sizeof(Elf32_Phdr)))
 
5415
                        return FALSE;
 
5416
        }
 
5417
        return TRUE;
 
5418
}
 
5419
 
 
5420
int
 
5421
write_elf_header(struct cache_data *cd_header)
 
5422
{
 
5423
        int i, num_loads_dumpfile, phnum;
 
5424
        off_t offset_note_memory, offset_note_dumpfile;
 
5425
        size_t size_note;
 
5426
        Elf64_Ehdr ehdr64;
 
5427
        Elf32_Ehdr ehdr32;
 
5428
        Elf64_Phdr note;
 
5429
 
 
5430
        char *buf = NULL;
 
5431
        const off_t failed = (off_t)-1;
 
5432
 
 
5433
        int ret = FALSE;
 
5434
 
 
5435
        if (!info->flag_elf_dumpfile)
 
5436
                return FALSE;
 
5437
 
 
5438
        /*
 
5439
         * Get the PT_LOAD number of the dumpfile.
 
5440
         */
 
5441
        if (!(num_loads_dumpfile = get_loads_dumpfile())) {
 
5442
                ERRMSG("Can't get a number of PT_LOAD.\n");
 
5443
                goto out;
 
5444
        }
 
5445
 
 
5446
        if (info->flag_elf64_memory) { /* ELF64 */
 
5447
                if (!get_elf64_ehdr(&ehdr64)) {
 
5448
                        ERRMSG("Can't get ehdr64.\n");
 
5449
                        goto out;
 
5450
                }
 
5451
                /*
 
5452
                 * PT_NOTE(1) + PT_LOAD(1+)
 
5453
                 */
 
5454
                ehdr64.e_phnum = 1 + num_loads_dumpfile;
 
5455
        } else {                /* ELF32 */
 
5456
                if (!get_elf32_ehdr(&ehdr32)) {
 
5457
                        ERRMSG("Can't get ehdr32.\n");
 
5458
                        goto out;
 
5459
                }
 
5460
                /*
 
5461
                 * PT_NOTE(1) + PT_LOAD(1+)
 
5462
                 */
 
5463
                ehdr32.e_phnum = 1 + num_loads_dumpfile;
 
5464
        }
 
5465
 
 
5466
        /*
 
5467
         * Write an ELF header.
 
5468
         */
 
5469
        if (info->flag_elf64_memory) { /* ELF64 */
 
5470
                if (!write_buffer(info->fd_dumpfile, 0, &ehdr64, sizeof(ehdr64),
 
5471
                    info->name_dumpfile))
 
5472
                        goto out;
 
5473
 
 
5474
        } else {                /* ELF32 */
 
5475
                if (!write_buffer(info->fd_dumpfile, 0, &ehdr32, sizeof(ehdr32),
 
5476
                    info->name_dumpfile))
 
5477
                        goto out;
 
5478
        }
 
5479
 
 
5480
        /*
 
5481
         * Write a PT_NOTE header.
 
5482
         */
 
5483
        if (!(phnum = get_phnum_memory()))
 
5484
                goto out;
 
5485
 
 
5486
        for (i = 0; i < phnum; i++) {
 
5487
                if (!get_elf_phdr_memory(i, &note))
 
5488
                        return FALSE;
 
5489
                if (note.p_type == PT_NOTE)
 
5490
                        break;
 
5491
        }
 
5492
        if (note.p_type != PT_NOTE) {
 
5493
                ERRMSG("Can't get a PT_NOTE header.\n");
 
5494
                goto out;
 
5495
        }
 
5496
 
 
5497
        if (info->flag_elf64_memory) { /* ELF64 */
 
5498
                cd_header->offset    = sizeof(ehdr64);
 
5499
                offset_note_dumpfile = sizeof(ehdr64)
 
5500
                    + sizeof(Elf64_Phdr) * ehdr64.e_phnum;
 
5501
        } else {
 
5502
                cd_header->offset    = sizeof(ehdr32);
 
5503
                offset_note_dumpfile = sizeof(ehdr32)
 
5504
                    + sizeof(Elf32_Phdr) * ehdr32.e_phnum;
 
5505
        }
 
5506
        offset_note_memory = note.p_offset;
 
5507
        note.p_offset      = offset_note_dumpfile;
 
5508
        size_note          = note.p_filesz;
 
5509
 
 
5510
        if (!write_elf_phdr(cd_header, &note))
 
5511
                goto out;
 
5512
 
 
5513
        /*
 
5514
         * Write a PT_NOTE segment.
 
5515
         * PT_LOAD header will be written later.
 
5516
         */
 
5517
        if ((buf = malloc(size_note)) == NULL) {
 
5518
                ERRMSG("Can't allocate memory for PT_NOTE segment. %s\n",
 
5519
                    strerror(errno));
 
5520
                goto out;
 
5521
        }
 
5522
        if (lseek(info->fd_memory, offset_note_memory, SEEK_SET) == failed) {
 
5523
                ERRMSG("Can't seek the dump memory(%s). %s\n",
 
5524
                    info->name_memory, strerror(errno));
 
5525
                goto out;
 
5526
        }
 
5527
        if (read(info->fd_memory, buf, size_note) != size_note) {
 
5528
                ERRMSG("Can't read the dump memory(%s). %s\n",
 
5529
                    info->name_memory, strerror(errno));
 
5530
                goto out;
 
5531
        }
 
5532
        if (!write_buffer(info->fd_dumpfile, offset_note_dumpfile, buf,
 
5533
            size_note, info->name_dumpfile))
 
5534
                goto out;
 
5535
 
 
5536
        /*
 
5537
         * Set an offset of PT_LOAD segment.
 
5538
         */
 
5539
        info->offset_load_dumpfile = offset_note_dumpfile + size_note;
 
5540
 
 
5541
        ret = TRUE;
 
5542
out:
 
5543
        if (buf != NULL)
 
5544
                free(buf);
 
5545
 
 
5546
        return ret;
 
5547
}
 
5548
 
 
5549
int
 
5550
write_kdump_header(void)
 
5551
{
 
5552
        int ret = FALSE;
 
5553
        size_t size;
 
5554
        struct disk_dump_header *dh = info->dump_header;
 
5555
        struct kdump_sub_header kh;
 
5556
        char *buf = NULL;
 
5557
 
 
5558
        if (info->flag_elf_dumpfile)
 
5559
                return FALSE;
 
5560
 
 
5561
        /*
 
5562
         * Write common header
 
5563
         */
 
5564
        strncpy(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE));
 
5565
        dh->header_version = 4;
 
5566
        dh->block_size     = info->page_size;
 
5567
        dh->sub_hdr_size   = sizeof(kh) + info->size_note;
 
5568
        dh->sub_hdr_size   = divideup(dh->sub_hdr_size, dh->block_size);
 
5569
        dh->max_mapnr      = info->max_mapnr;
 
5570
        dh->nr_cpus        = info->nr_cpus;
 
5571
        dh->bitmap_blocks  = divideup(info->len_bitmap, dh->block_size);
 
5572
        memcpy(&dh->timestamp, &info->timestamp, sizeof(dh->timestamp));
 
5573
        memcpy(&dh->utsname, &info->system_utsname, sizeof(dh->utsname));
 
5574
 
 
5575
        size = sizeof(struct disk_dump_header);
 
5576
        if (!write_buffer(info->fd_dumpfile, 0, dh, size, info->name_dumpfile))
 
5577
                return FALSE;
 
5578
 
 
5579
        /*
 
5580
         * Write sub header
 
5581
         */
 
5582
        size = sizeof(struct kdump_sub_header);
 
5583
        memset(&kh, 0, size);
 
5584
        kh.phys_base  = info->phys_base;
 
5585
        kh.dump_level = info->dump_level;
 
5586
        if (info->flag_split) {
 
5587
                kh.split = 1;
 
5588
                kh.start_pfn = info->split_start_pfn;
 
5589
                kh.end_pfn   = info->split_end_pfn;
 
5590
        }
 
5591
        if (info->offset_note && info->size_note) {
 
5592
                /*
 
5593
                 * Write ELF note section
 
5594
                 */
 
5595
                kh.offset_note
 
5596
                        = DISKDUMP_HEADER_BLOCKS * dh->block_size + sizeof(kh);
 
5597
                kh.size_note = info->size_note;
 
5598
 
 
5599
                buf = malloc(info->size_note);
 
5600
                if (buf == NULL) {
 
5601
                        ERRMSG("Can't allocate memory for ELF note section. %s\n",
 
5602
                            strerror(errno));
 
5603
                        return FALSE;
 
5604
                }
 
5605
                if (lseek(info->fd_memory, info->offset_note, SEEK_SET) < 0) {
 
5606
                        ERRMSG("Can't seek the dump memory(%s). %s\n",
 
5607
                            info->name_memory, strerror(errno));
 
5608
                        goto out;
 
5609
                }
 
5610
                if (read(info->fd_memory, buf, info->size_note)
 
5611
                    != info->size_note) {
 
5612
                        ERRMSG("Can't read the dump memory(%s). %s\n",
 
5613
                            info->name_memory, strerror(errno));
 
5614
                        goto out;
 
5615
                }
 
5616
                if (!write_buffer(info->fd_dumpfile, kh.offset_note, buf,
 
5617
                    kh.size_note, info->name_dumpfile))
 
5618
                        goto out;
 
5619
 
 
5620
                if (info->offset_vmcoreinfo && info->size_vmcoreinfo) {
 
5621
                        /*
 
5622
                         * Set vmcoreinfo data
 
5623
                         *
 
5624
                         * NOTE: ELF note section contains vmcoreinfo data, and
 
5625
                         *       kh.offset_vmcoreinfo points the vmcoreinfo data.
 
5626
                         */
 
5627
                        kh.offset_vmcoreinfo
 
5628
                            = info->offset_vmcoreinfo - info->offset_note
 
5629
                              + kh.offset_note;
 
5630
                        kh.size_vmcoreinfo = info->size_vmcoreinfo;
 
5631
                }
 
5632
        }
 
5633
        if (!write_buffer(info->fd_dumpfile, dh->block_size, &kh,
 
5634
            size, info->name_dumpfile))
 
5635
                goto out;
 
5636
 
 
5637
        info->offset_bitmap1
 
5638
            = (DISKDUMP_HEADER_BLOCKS + dh->sub_hdr_size) * dh->block_size;
 
5639
 
 
5640
        ret = TRUE;
 
5641
out:
 
5642
        if (buf)
 
5643
                free(buf);
 
5644
 
 
5645
        return ret;
 
5646
}
 
5647
 
 
5648
void
 
5649
print_progress(const char *msg, unsigned long current, unsigned long end)
 
5650
{
 
5651
        int progress;
 
5652
        time_t tm;
 
5653
        static time_t last_time = 0;
 
5654
 
 
5655
        if (current < end) {
 
5656
                tm = time(NULL);
 
5657
                if (tm - last_time < 1)
 
5658
                        return;
 
5659
                last_time = tm;
 
5660
                progress = current * 100 / end;
 
5661
        } else
 
5662
                progress = 100;
 
5663
 
 
5664
        PROGRESS_MSG("\r");
 
5665
        PROGRESS_MSG("%-" PROGRESS_MAXLEN "s: [%3d %%] ", msg, progress);
 
5666
}
 
5667
 
 
5668
unsigned long long
 
5669
get_num_dumpable(void)
 
5670
{
 
5671
        unsigned long long pfn, num_dumpable;
 
5672
        struct dump_bitmap bitmap2;
 
5673
 
 
5674
        initialize_2nd_bitmap(&bitmap2);
 
5675
 
 
5676
        for (pfn = 0, num_dumpable = 0; pfn < info->max_mapnr; pfn++) {
 
5677
                if (is_dumpable(&bitmap2, pfn))
 
5678
                        num_dumpable++;
 
5679
        }
 
5680
        return num_dumpable;
 
5681
}
 
5682
 
 
5683
int
 
5684
write_elf_load_segment(struct cache_data *cd_page, unsigned long long paddr,
 
5685
                       off_t off_memory, long long size)
 
5686
{
 
5687
        long page_size = info->page_size;
 
5688
        long long bufsz_write;
 
5689
        char buf[info->page_size];
 
5690
 
 
5691
        off_memory = paddr_to_offset2(paddr, off_memory);
 
5692
        if (!off_memory) {
 
5693
                ERRMSG("Can't convert physaddr(%llx) to an offset.\n",
 
5694
                    paddr);
 
5695
                return FALSE;
 
5696
        }
 
5697
        if (lseek(info->fd_memory, off_memory, SEEK_SET) < 0) {
 
5698
                ERRMSG("Can't seek the dump memory(%s). %s\n",
 
5699
                    info->name_memory, strerror(errno));
 
5700
                return FALSE;
 
5701
        }
 
5702
 
 
5703
        while (size > 0) {
 
5704
                if (size >= page_size)
 
5705
                        bufsz_write = page_size;
 
5706
                else
 
5707
                        bufsz_write = size;
 
5708
 
 
5709
                if (read(info->fd_memory, buf, bufsz_write) != bufsz_write) {
 
5710
                        ERRMSG("Can't read the dump memory(%s). %s\n",
 
5711
                            info->name_memory, strerror(errno));
 
5712
                        return FALSE;
 
5713
                }
 
5714
                if (!write_cache(cd_page, buf, bufsz_write))
 
5715
                        return FALSE;
 
5716
 
 
5717
                size -= page_size;
 
5718
        }
 
5719
        return TRUE;
 
5720
}
 
5721
 
 
5722
int
 
5723
write_elf_pages(struct cache_data *cd_header, struct cache_data *cd_page)
 
5724
{
 
5725
        int i, phnum;
 
5726
        long page_size = info->page_size;
 
5727
        unsigned long long pfn, pfn_start, pfn_end, paddr, num_excluded;
 
5728
        unsigned long long num_dumpable, num_dumped = 0, per;
 
5729
        unsigned long long memsz, filesz;
 
5730
        unsigned long frac_head, frac_tail;
 
5731
        off_t off_seg_load, off_memory;
 
5732
        Elf64_Phdr load;
 
5733
        struct dump_bitmap bitmap2;
 
5734
        struct timeval tv_start;
 
5735
 
 
5736
        if (!info->flag_elf_dumpfile)
 
5737
                return FALSE;
 
5738
 
 
5739
        initialize_2nd_bitmap(&bitmap2);
 
5740
 
 
5741
        num_dumpable = get_num_dumpable();
 
5742
        per = num_dumpable / 100;
 
5743
 
 
5744
        off_seg_load    = info->offset_load_dumpfile;
 
5745
        cd_page->offset = info->offset_load_dumpfile;
 
5746
 
 
5747
        if (!(phnum = get_phnum_memory()))
 
5748
                return FALSE;
 
5749
 
 
5750
        gettimeofday(&tv_start, NULL);
 
5751
 
 
5752
        for (i = 0; i < phnum; i++) {
 
5753
                if (!get_elf_phdr_memory(i, &load))
 
5754
                        return FALSE;
 
5755
 
 
5756
                if (load.p_type != PT_LOAD)
 
5757
                        continue;
 
5758
 
 
5759
                off_memory= load.p_offset;
 
5760
                paddr     = load.p_paddr;
 
5761
                pfn_start = paddr_to_pfn(load.p_paddr);
 
5762
                pfn_end   = paddr_to_pfn(load.p_paddr + load.p_memsz);
 
5763
                frac_head = page_size - (load.p_paddr % page_size);
 
5764
                frac_tail = (load.p_paddr + load.p_memsz)%page_size;
 
5765
 
 
5766
                num_excluded = 0;
 
5767
                memsz  = 0;
 
5768
                filesz = 0;
 
5769
                if (frac_head && (frac_head != page_size)) {
 
5770
                        memsz  = frac_head;
 
5771
                        filesz = frac_head;
 
5772
                        pfn_start++;
 
5773
                }
 
5774
 
 
5775
                if (frac_tail)
 
5776
                        pfn_end++;
 
5777
 
 
5778
                for (pfn = pfn_start; pfn < pfn_end; pfn++) {
 
5779
                        if (!is_dumpable(&bitmap2, pfn)) {
 
5780
                                num_excluded++;
 
5781
                                if ((pfn == pfn_end - 1) && frac_tail)
 
5782
                                        memsz += frac_tail;
 
5783
                                else
 
5784
                                        memsz += page_size;
 
5785
                                continue;
 
5786
                        }
 
5787
 
 
5788
                        if ((num_dumped % per) == 0)
 
5789
                                print_progress(PROGRESS_COPY, num_dumped, num_dumpable);
 
5790
 
 
5791
                        num_dumped++;
 
5792
 
 
5793
                        /*
 
5794
                         * The dumpable pages are continuous.
 
5795
                         */
 
5796
                        if (!num_excluded) {
 
5797
                                if ((pfn == pfn_end - 1) && frac_tail) {
 
5798
                                        memsz  += frac_tail;
 
5799
                                        filesz += frac_tail;
 
5800
                                } else {
 
5801
                                        memsz  += page_size;
 
5802
                                        filesz += page_size;
 
5803
                                }
 
5804
                                continue;
 
5805
                        /*
 
5806
                         * If the number of the contiguous pages to be excluded
 
5807
                         * is 255 or less, those pages are not excluded.
 
5808
                         */
 
5809
                        } else if (num_excluded < PFN_EXCLUDED) {
 
5810
                                if ((pfn == pfn_end - 1) && frac_tail) {
 
5811
                                        memsz  += frac_tail;
 
5812
                                        filesz += (page_size*num_excluded
 
5813
                                            + frac_tail);
 
5814
                                }else {
 
5815
                                        memsz  += page_size;
 
5816
                                        filesz += (page_size*num_excluded
 
5817
                                            + page_size);
 
5818
                                }
 
5819
                                num_excluded = 0;
 
5820
                                continue;
 
5821
                        }
 
5822
 
 
5823
                        /*
 
5824
                         * If the number of the contiguous pages to be excluded
 
5825
                         * is 256 or more, those pages are excluded really.
 
5826
                         * And a new PT_LOAD segment is created.
 
5827
                         */
 
5828
                        load.p_memsz  = memsz;
 
5829
                        load.p_filesz = filesz;
 
5830
                        load.p_offset = off_seg_load;
 
5831
 
 
5832
                        /*
 
5833
                         * Write a PT_LOAD header.
 
5834
                         */
 
5835
                        if (!write_elf_phdr(cd_header, &load))
 
5836
                                return FALSE;
 
5837
 
 
5838
                        /*
 
5839
                         * Write a PT_LOAD segment.
 
5840
                         */
 
5841
                        if (!write_elf_load_segment(cd_page, paddr, off_memory,
 
5842
                            load.p_filesz))
 
5843
                                return FALSE;
 
5844
 
 
5845
                        load.p_paddr += load.p_memsz;
 
5846
#ifdef __x86__
 
5847
                        /*
 
5848
                         * FIXME:
 
5849
                         *  (x86) Fill PT_LOAD headers with appropriate
 
5850
                         *        virtual addresses.
 
5851
                         */
 
5852
                        if (load.p_paddr < MAXMEM)
 
5853
                                load.p_vaddr += load.p_memsz;
 
5854
#else
 
5855
                        load.p_vaddr += load.p_memsz;
 
5856
#endif /* x86 */
 
5857
                        paddr  = load.p_paddr;
 
5858
                        off_seg_load += load.p_filesz;
 
5859
 
 
5860
                        num_excluded = 0;
 
5861
                        memsz  = page_size;
 
5862
                        filesz = page_size;
 
5863
                }
 
5864
                /*
 
5865
                 * Write the last PT_LOAD.
 
5866
                 */
 
5867
                load.p_memsz  = memsz;
 
5868
                load.p_filesz = filesz;
 
5869
                load.p_offset = off_seg_load;
 
5870
 
 
5871
                /*
 
5872
                 * Write a PT_LOAD header.
 
5873
                 */
 
5874
                if (!write_elf_phdr(cd_header, &load))
 
5875
                        return FALSE;
 
5876
 
 
5877
                /*
 
5878
                 * Write a PT_LOAD segment.
 
5879
                 */
 
5880
                if (!write_elf_load_segment(cd_page, paddr, off_memory, load.p_filesz))
 
5881
                        return FALSE;
 
5882
 
 
5883
                off_seg_load += load.p_filesz;
 
5884
        }
 
5885
        if (!write_cache_bufsz(cd_header))
 
5886
                return FALSE;
 
5887
        if (!write_cache_bufsz(cd_page))
 
5888
                return FALSE;
 
5889
 
 
5890
        /*
 
5891
         * print [100 %]
 
5892
         */
 
5893
        print_progress(PROGRESS_COPY, num_dumpable, num_dumpable);
 
5894
        print_execution_time(PROGRESS_COPY, &tv_start);
 
5895
        PROGRESS_MSG("\n");
 
5896
 
 
5897
        return TRUE;
 
5898
}
 
5899
 
 
5900
/*
 
5901
 * This function is specific for reading page.
 
5902
 *
 
5903
 * If reading the separated page on different PT_LOAD segments,
 
5904
 * this function gets the page data from both segments. This is
 
5905
 * worthy of ia64 /proc/vmcore. In ia64 /proc/vmcore, region 5
 
5906
 * segment is overlapping to region 7 segment. The following is
 
5907
 * example (page_size is 16KBytes):
 
5908
 *
 
5909
 *  region |       paddr        |       memsz
 
5910
 * --------+--------------------+--------------------
 
5911
 *     5   | 0x0000000004000000 | 0x0000000000638ce0
 
5912
 *     7   | 0x0000000004000000 | 0x0000000000db3000
 
5913
 *
 
5914
 * In the above example, the last page of region 5 is 0x4638000
 
5915
 * and the segment does not contain complete data of this page.
 
5916
 * Then this function gets the data of 0x4638000 - 0x4638ce0
 
5917
 * from region 5, and gets the remaining data from region 7.
 
5918
 */
 
5919
int
 
5920
read_pfn(unsigned long long pfn, unsigned char *buf)
 
5921
{
 
5922
        unsigned long long paddr;
 
5923
        off_t offset1, offset2;
 
5924
        size_t size1, size2;
 
5925
 
 
5926
        paddr = pfn_to_paddr(pfn);
 
5927
        if (info->flag_refiltering) {
 
5928
                if (!readmem(PADDR, paddr, buf, info->page_size)) {
 
5929
                        ERRMSG("Can't get the page data.\n");
 
5930
                        return FALSE;
 
5931
                }
 
5932
                return TRUE;
 
5933
        }
 
5934
 
 
5935
        offset1 = paddr_to_offset(paddr);
 
5936
        offset2 = paddr_to_offset(paddr + info->page_size);
 
5937
 
 
5938
        /*
 
5939
         * Check the separated page on different PT_LOAD segments.
 
5940
         */
 
5941
        if (offset1 + info->page_size == offset2) {
 
5942
                size1 = info->page_size;
 
5943
        } else {
 
5944
                for (size1 = 1; size1 < info->page_size; size1++) {
 
5945
                        offset2 = paddr_to_offset(paddr + size1);
 
5946
                        if (offset1 + size1 != offset2)
 
5947
                                break;
 
5948
                }
 
5949
        }
 
5950
        if (!readmem(PADDR, paddr, buf, size1)) {
 
5951
                ERRMSG("Can't get the page data.\n");
 
5952
                return FALSE;
 
5953
        }
 
5954
        if (size1 != info->page_size) {
 
5955
                size2 = info->page_size - size1;
 
5956
                if (!offset2) {
 
5957
                        memset(buf + size1, 0, size2);
 
5958
                } else {
 
5959
                        if (!readmem(PADDR, paddr + size1, buf + size1, size2)) {
 
5960
                                ERRMSG("Can't get the page data.\n");
 
5961
                                return FALSE;
 
5962
                        }
 
5963
                }
 
5964
        }
 
5965
        return TRUE;
 
5966
}
 
5967
 
 
5968
int
 
5969
write_kdump_pages(struct cache_data *cd_header, struct cache_data *cd_page)
 
5970
{
 
5971
        unsigned long long pfn, per, num_dumpable, num_dumped = 0;
 
5972
        unsigned long long start_pfn, end_pfn;
 
5973
        unsigned long size_out;
 
5974
        struct page_desc pd, pd_zero;
 
5975
        off_t offset_data = 0;
 
5976
        struct disk_dump_header *dh = info->dump_header;
 
5977
        unsigned char buf[info->page_size], *buf_out = NULL;
 
5978
        unsigned long len_buf_out;
 
5979
        struct dump_bitmap bitmap2;
 
5980
        struct timeval tv_start;
 
5981
        const off_t failed = (off_t)-1;
 
5982
 
 
5983
        int ret = FALSE;
 
5984
 
 
5985
        if (info->flag_elf_dumpfile)
 
5986
                return FALSE;
 
5987
 
 
5988
        initialize_2nd_bitmap(&bitmap2);
 
5989
 
 
5990
        len_buf_out = compressBound(info->page_size);
 
5991
        if ((buf_out = malloc(len_buf_out)) == NULL) {
 
5992
                ERRMSG("Can't allocate memory for the compression buffer. %s\n",
 
5993
                    strerror(errno));
 
5994
                goto out;
 
5995
        }
 
5996
 
 
5997
        num_dumpable = get_num_dumpable();
 
5998
        per = num_dumpable / 100;
 
5999
 
 
6000
        /*
 
6001
         * Calculate the offset of the page data.
 
6002
         */
 
6003
        cd_header->offset
 
6004
            = (DISKDUMP_HEADER_BLOCKS + dh->sub_hdr_size + dh->bitmap_blocks)
 
6005
                * dh->block_size;
 
6006
        cd_page->offset = cd_header->offset + sizeof(page_desc_t)*num_dumpable;
 
6007
        offset_data  = cd_page->offset;
 
6008
 
 
6009
        /*
 
6010
         * Set a fileoffset of Physical Address 0x0.
 
6011
         */
 
6012
        if (lseek(info->fd_memory, info->offset_load_memory, SEEK_SET)
 
6013
            == failed) {
 
6014
                ERRMSG("Can't seek the dump memory(%s). %s\n",
 
6015
                    info->name_memory, strerror(errno));
 
6016
                goto out;
 
6017
        }
 
6018
 
 
6019
        /*
 
6020
         * Write the data of zero-filled page.
 
6021
         */
 
6022
        gettimeofday(&tv_start, NULL);
 
6023
        if (info->dump_level & DL_EXCLUDE_ZERO) {
 
6024
                pd_zero.size = info->page_size;
 
6025
                pd_zero.flags = 0;
 
6026
                pd_zero.offset = offset_data;
 
6027
                pd_zero.page_flags = 0;
 
6028
                memset(buf, 0, pd_zero.size);
 
6029
                if (!write_cache(cd_page, buf, pd_zero.size))
 
6030
                        goto out;
 
6031
                offset_data  += pd_zero.size;
 
6032
        }
 
6033
        if (info->flag_split) {
 
6034
                start_pfn = info->split_start_pfn;
 
6035
                end_pfn   = info->split_end_pfn;
 
6036
        }
 
6037
        else {
 
6038
                start_pfn = 0;
 
6039
                end_pfn   = info->max_mapnr;
 
6040
        }
 
6041
 
 
6042
        for (pfn = start_pfn; pfn < end_pfn; pfn++) {
 
6043
 
 
6044
                if ((num_dumped % per) == 0)
 
6045
                        print_progress(PROGRESS_COPY, num_dumped, num_dumpable);
 
6046
 
 
6047
                /*
 
6048
                 * Check the excluded page.
 
6049
                 */
 
6050
                if (!is_dumpable(&bitmap2, pfn))
 
6051
                        continue;
 
6052
 
 
6053
                num_dumped++;
 
6054
 
 
6055
                if (!read_pfn(pfn, buf))
 
6056
                        goto out;
 
6057
 
 
6058
                /*
 
6059
                 * Exclude the page filled with zeros.
 
6060
                 */
 
6061
                if ((info->dump_level & DL_EXCLUDE_ZERO)
 
6062
                    && is_zero_page(buf, info->page_size)) {
 
6063
                        if (!write_cache(cd_header, &pd_zero, sizeof(page_desc_t)))
 
6064
                                goto out;
 
6065
                        pfn_zero++;
 
6066
                        continue;
 
6067
                }
 
6068
                /*
 
6069
                 * Compress the page data.
 
6070
                 */
 
6071
                size_out = len_buf_out;
 
6072
                if (info->flag_compress
 
6073
                    && (compress2(buf_out, &size_out, buf,
 
6074
                    info->page_size, Z_BEST_SPEED) == Z_OK)
 
6075
                    && (size_out < info->page_size)) {
 
6076
                        pd.flags = 1;
 
6077
                        pd.size  = size_out;
 
6078
                        memcpy(buf, buf_out, pd.size);
 
6079
                } else {
 
6080
                        pd.flags = 0;
 
6081
                        pd.size  = info->page_size;
 
6082
                }
 
6083
                pd.page_flags = 0;
 
6084
                pd.offset     = offset_data;
 
6085
                offset_data  += pd.size;
 
6086
 
 
6087
                /*
 
6088
                 * Write the page header.
 
6089
                 */
 
6090
                if (!write_cache(cd_header, &pd, sizeof(page_desc_t)))
 
6091
                        goto out;
 
6092
 
 
6093
                /*
 
6094
                 * Write the page data.
 
6095
                 */
 
6096
                if (!write_cache(cd_page, buf, pd.size))
 
6097
                        goto out;
 
6098
        }
 
6099
 
 
6100
        /*
 
6101
         * Write the remainder.
 
6102
         */
 
6103
        if (!write_cache_bufsz(cd_page))
 
6104
                goto out;
 
6105
        if (!write_cache_bufsz(cd_header))
 
6106
                goto out;
 
6107
 
 
6108
        /*
 
6109
         * print [100 %]
 
6110
         */
 
6111
        print_progress(PROGRESS_COPY, num_dumpable, num_dumpable);
 
6112
        print_execution_time(PROGRESS_COPY, &tv_start);
 
6113
        PROGRESS_MSG("\n");
 
6114
 
 
6115
        ret = TRUE;
 
6116
out:
 
6117
        if (buf_out != NULL)
 
6118
                free(buf_out);
 
6119
 
 
6120
        return ret;
 
6121
}
 
6122
 
 
6123
int
 
6124
write_kdump_bitmap(void)
 
6125
{
 
6126
        struct cache_data bm;
 
6127
        long buf_size;
 
6128
        off_t offset;
 
6129
 
 
6130
        int ret = FALSE;
 
6131
 
 
6132
        if (info->flag_elf_dumpfile)
 
6133
                return FALSE;
 
6134
 
 
6135
        bm.fd        = info->fd_bitmap;
 
6136
        bm.file_name = info->name_bitmap;
 
6137
        bm.offset    = 0;
 
6138
        bm.buf       = NULL;
 
6139
 
 
6140
        if ((bm.buf = calloc(1, BUFSIZE_BITMAP)) == NULL) {
 
6141
                ERRMSG("Can't allocate memory for dump bitmap buffer. %s\n",
 
6142
                    strerror(errno));
 
6143
                goto out;
 
6144
        }
 
6145
        offset = info->offset_bitmap1;
 
6146
        buf_size = info->len_bitmap;
 
6147
 
 
6148
        while (buf_size > 0) {
 
6149
                if (buf_size >= BUFSIZE_BITMAP)
 
6150
                        bm.cache_size = BUFSIZE_BITMAP;
 
6151
                else
 
6152
                        bm.cache_size = buf_size;
 
6153
 
 
6154
                if(!read_cache(&bm))
 
6155
                        goto out;
 
6156
 
 
6157
                if (!write_buffer(info->fd_dumpfile, offset,
 
6158
                    bm.buf, bm.cache_size, info->name_dumpfile))
 
6159
                        goto out;
 
6160
 
 
6161
                offset += bm.cache_size;
 
6162
                buf_size -= BUFSIZE_BITMAP;
 
6163
        }
 
6164
        ret = TRUE;
 
6165
out:
 
6166
        if (bm.buf != NULL)
 
6167
                free(bm.buf);
 
6168
 
 
6169
        return ret;
 
6170
}
 
6171
 
 
6172
void
 
6173
close_vmcoreinfo(void)
 
6174
{
 
6175
        if(fclose(info->file_vmcoreinfo) < 0)
 
6176
                ERRMSG("Can't close the vmcoreinfo file(%s). %s\n",
 
6177
                    info->name_vmcoreinfo, strerror(errno));
 
6178
}
 
6179
 
 
6180
void
 
6181
close_dump_memory(void)
 
6182
{
 
6183
        if ((info->fd_memory = close(info->fd_memory)) < 0)
 
6184
                ERRMSG("Can't close the dump memory(%s). %s\n",
 
6185
                    info->name_memory, strerror(errno));
 
6186
}
 
6187
 
 
6188
void
 
6189
close_dump_file(void)
 
6190
{
 
6191
        if (info->flag_flatten)
 
6192
                return;
 
6193
 
 
6194
        if ((info->fd_dumpfile = close(info->fd_dumpfile)) < 0)
 
6195
                ERRMSG("Can't close the dump file(%s). %s\n",
 
6196
                    info->name_dumpfile, strerror(errno));
 
6197
}
 
6198
 
 
6199
void
 
6200
close_dump_bitmap(void)
 
6201
{
 
6202
        if ((info->fd_bitmap = close(info->fd_bitmap)) < 0)
 
6203
                ERRMSG("Can't close the bitmap file(%s). %s\n",
 
6204
                    info->name_bitmap, strerror(errno));
 
6205
        free(info->name_bitmap);
 
6206
        info->name_bitmap = NULL;
 
6207
}
 
6208
 
 
6209
void
 
6210
close_kernel_file(void)
 
6211
{
 
6212
        if (info->name_vmlinux) {
 
6213
                if ((info->fd_vmlinux = close(info->fd_vmlinux)) < 0) {
 
6214
                        ERRMSG("Can't close the kernel file(%s). %s\n",
 
6215
                            info->name_vmlinux, strerror(errno));
 
6216
                }
 
6217
        }
 
6218
        if (info->name_xen_syms) {
 
6219
                if ((info->fd_xen_syms = close(info->fd_xen_syms)) < 0) {
 
6220
                        ERRMSG("Can't close the kernel file(%s). %s\n",
 
6221
                            info->name_xen_syms, strerror(errno));
 
6222
                }
 
6223
        }
 
6224
}
 
6225
 
 
6226
/*
 
6227
 * Close the following files when it generates the vmcoreinfo file.
 
6228
 * - vmlinux
 
6229
 * - vmcoreinfo file
 
6230
 */
 
6231
int
 
6232
close_files_for_generating_vmcoreinfo(void)
 
6233
{
 
6234
        close_kernel_file();
 
6235
 
 
6236
        close_vmcoreinfo();
 
6237
 
 
6238
        return TRUE;
 
6239
}
 
6240
 
 
6241
/*
 
6242
 * Close the following file when it rearranges the dump data.
 
6243
 * - dump file
 
6244
 */
 
6245
int
 
6246
close_files_for_rearranging_dumpdata(void)
 
6247
{
 
6248
        close_dump_file();
 
6249
 
 
6250
        return TRUE;
 
6251
}
 
6252
 
 
6253
/*
 
6254
 * Close the following files when it creates the dump file.
 
6255
 * - dump mem
 
6256
 * - dump file
 
6257
 * - bit map
 
6258
 * if it reads the vmcoreinfo file
 
6259
 *   - vmcoreinfo file
 
6260
 * else
 
6261
 *   - vmlinux
 
6262
 */
 
6263
int
 
6264
close_files_for_creating_dumpfile(void)
 
6265
{
 
6266
        if (info->max_dump_level > DL_EXCLUDE_ZERO)
 
6267
                close_kernel_file();
 
6268
 
 
6269
        /* free name for vmcoreinfo */
 
6270
        if (info->offset_vmcoreinfo && info->size_vmcoreinfo) {
 
6271
                free(info->name_vmcoreinfo);
 
6272
                info->name_vmcoreinfo = NULL;
 
6273
        }
 
6274
        close_dump_memory();
 
6275
 
 
6276
        close_dump_bitmap();
 
6277
 
 
6278
        return TRUE;
 
6279
}
 
6280
 
 
6281
/*
 
6282
 * for Xen extraction
 
6283
 */
 
6284
int
 
6285
get_symbol_info_xen(void)
 
6286
{
 
6287
        /*
 
6288
         * Common symbol
 
6289
         */
 
6290
        SYMBOL_INIT(dom_xen, "dom_xen");
 
6291
        SYMBOL_INIT(dom_io, "dom_io");
 
6292
        SYMBOL_INIT(domain_list, "domain_list");
 
6293
        SYMBOL_INIT(frame_table, "frame_table");
 
6294
        SYMBOL_INIT(alloc_bitmap, "alloc_bitmap");
 
6295
        SYMBOL_INIT(max_page, "max_page");
 
6296
        SYMBOL_INIT(xenheap_phys_end, "xenheap_phys_end");
 
6297
 
 
6298
        /*
 
6299
         * Architecture specific
 
6300
         */
 
6301
        SYMBOL_INIT(pgd_l2, "idle_pg_table_l2");        /* x86 */
 
6302
        SYMBOL_INIT(pgd_l3, "idle_pg_table_l3");        /* x86-PAE */
 
6303
        if (SYMBOL(pgd_l3) == NOT_FOUND_SYMBOL)
 
6304
                SYMBOL_INIT(pgd_l3, "idle_pg_table");   /* x86-PAE */
 
6305
        SYMBOL_INIT(pgd_l4, "idle_pg_table_4");         /* x86_64 */
 
6306
        if (SYMBOL(pgd_l4) == NOT_FOUND_SYMBOL)
 
6307
                SYMBOL_INIT(pgd_l4, "idle_pg_table");           /* x86_64 */
 
6308
 
 
6309
        SYMBOL_INIT(xen_heap_start, "xen_heap_start");  /* ia64 */
 
6310
        SYMBOL_INIT(xen_pstart, "xen_pstart");          /* ia64 */
 
6311
        SYMBOL_INIT(frametable_pg_dir, "frametable_pg_dir");    /* ia64 */
 
6312
 
 
6313
        return TRUE;
 
6314
}
 
6315
 
 
6316
int
 
6317
get_structure_info_xen(void)
 
6318
{
 
6319
        SIZE_INIT(page_info, "page_info");
 
6320
        OFFSET_INIT(page_info.count_info, "page_info", "count_info");
 
6321
        /*
 
6322
         * _domain is the first member of union u
 
6323
         */
 
6324
        OFFSET_INIT(page_info._domain, "page_info", "u");
 
6325
 
 
6326
        SIZE_INIT(domain, "domain");
 
6327
        OFFSET_INIT(domain.domain_id, "domain", "domain_id");
 
6328
        OFFSET_INIT(domain.next_in_list, "domain", "next_in_list");
 
6329
 
 
6330
        return TRUE;
 
6331
}
 
6332
 
 
6333
int
 
6334
get_xen_phys_start(void)
 
6335
{
 
6336
        off_t offset;
 
6337
        unsigned long xen_phys_start;
 
6338
        const off_t failed = (off_t)-1;
 
6339
 
 
6340
        if (info->xen_phys_start)
 
6341
                return TRUE;
 
6342
 
 
6343
        if (info->size_xen_crash_info >= SIZE_XEN_CRASH_INFO_V2) {
 
6344
                offset = info->offset_xen_crash_info + info->size_xen_crash_info
 
6345
                         - sizeof(unsigned long) * 2;
 
6346
                if (lseek(info->fd_memory, offset, SEEK_SET) == failed) {
 
6347
                        ERRMSG("Can't seek the dump memory(%s). %s\n",
 
6348
                            info->name_memory, strerror(errno));
 
6349
                        return FALSE;
 
6350
                }
 
6351
                if (read(info->fd_memory, &xen_phys_start, sizeof(unsigned long))
 
6352
                    != sizeof(unsigned long)) {
 
6353
                        ERRMSG("Can't read the dump memory(%s). %s\n",
 
6354
                            info->name_memory, strerror(errno));
 
6355
                        return FALSE;
 
6356
                }
 
6357
                info->xen_phys_start = xen_phys_start;
 
6358
        }
 
6359
 
 
6360
        return TRUE;
 
6361
}
 
6362
 
 
6363
int
 
6364
get_xen_info(void)
 
6365
{
 
6366
        unsigned long domain;
 
6367
        unsigned int domain_id;
 
6368
        int num_domain;
 
6369
 
 
6370
        if (SYMBOL(alloc_bitmap) == NOT_FOUND_SYMBOL) {
 
6371
                ERRMSG("Can't get the symbol of alloc_bitmap.\n");
 
6372
                return FALSE;
 
6373
        }
 
6374
        if (!readmem(VADDR_XEN, SYMBOL(alloc_bitmap), &info->alloc_bitmap,
 
6375
              sizeof(info->alloc_bitmap))) {
 
6376
                ERRMSG("Can't get the value of alloc_bitmap.\n");
 
6377
                return FALSE;
 
6378
        }
 
6379
        if (SYMBOL(max_page) == NOT_FOUND_SYMBOL) {
 
6380
                ERRMSG("Can't get the symbol of max_page.\n");
 
6381
                return FALSE;
 
6382
        }
 
6383
        if (!readmem(VADDR_XEN, SYMBOL(max_page), &info->max_page,
 
6384
            sizeof(info->max_page))) {
 
6385
                ERRMSG("Can't get the value of max_page.\n");
 
6386
                return FALSE;
 
6387
        }
 
6388
 
 
6389
        /*
 
6390
         * Walk through domain_list
 
6391
         */
 
6392
        if (SYMBOL(domain_list) == NOT_FOUND_SYMBOL) {
 
6393
                ERRMSG("Can't get the symbol of domain_list.\n");
 
6394
                return FALSE;
 
6395
        }
 
6396
        if (!readmem(VADDR_XEN, SYMBOL(domain_list), &domain, sizeof(domain))){
 
6397
                ERRMSG("Can't get the value of domain_list.\n");
 
6398
                return FALSE;
 
6399
        }
 
6400
 
 
6401
        /*
 
6402
         * Get numbers of domain first
 
6403
         */
 
6404
        num_domain = 0;
 
6405
        while (domain) {
 
6406
                num_domain++;
 
6407
                if (!readmem(VADDR_XEN, domain + OFFSET(domain.next_in_list),
 
6408
                    &domain, sizeof(domain))) {
 
6409
                        ERRMSG("Can't get through the domain_list.\n");
 
6410
                        return FALSE;
 
6411
                }
 
6412
        }
 
6413
 
 
6414
        if ((info->domain_list = (struct domain_list *)
 
6415
              malloc(sizeof(struct domain_list) * (num_domain + 2))) == NULL) {
 
6416
                ERRMSG("Can't allcate memory for domain_list.\n");
 
6417
                return FALSE;
 
6418
        }
 
6419
 
 
6420
        info->num_domain = num_domain + 2;
 
6421
 
 
6422
        if (!readmem(VADDR_XEN, SYMBOL(domain_list), &domain, sizeof(domain))) {
 
6423
                ERRMSG("Can't get the value of domain_list.\n");
 
6424
                return FALSE;
 
6425
        }
 
6426
        num_domain = 0;
 
6427
        while (domain) {
 
6428
                if (!readmem(VADDR_XEN, domain + OFFSET(domain.domain_id),
 
6429
                      &domain_id, sizeof(domain_id))) {
 
6430
                        ERRMSG("Can't get the domain_id.\n");
 
6431
                        return FALSE;
 
6432
                }
 
6433
                info->domain_list[num_domain].domain_addr = domain;
 
6434
                info->domain_list[num_domain].domain_id = domain_id;
 
6435
                /*
 
6436
                 * pickled_id is set by architecture specific
 
6437
                 */
 
6438
                num_domain++;
 
6439
 
 
6440
                if (!readmem(VADDR_XEN, domain + OFFSET(domain.next_in_list),
 
6441
                     &domain, sizeof(domain))) {
 
6442
                        ERRMSG("Can't get through the domain_list.\n");
 
6443
                        return FALSE;
 
6444
                }
 
6445
        }
 
6446
 
 
6447
        /*
 
6448
         * special domains
 
6449
         */
 
6450
        if (SYMBOL(dom_xen) == NOT_FOUND_SYMBOL) {
 
6451
                ERRMSG("Can't get the symbol of dom_xen.\n");
 
6452
                return FALSE;
 
6453
        }
 
6454
        if (!readmem(VADDR_XEN, SYMBOL(dom_xen), &domain, sizeof(domain))) {
 
6455
                ERRMSG("Can't get the value of dom_xen.\n");
 
6456
                return FALSE;
 
6457
        }
 
6458
        if (!readmem(VADDR_XEN, domain + OFFSET(domain.domain_id), &domain_id,
 
6459
            sizeof(domain_id))) {
 
6460
                ERRMSG( "Can't get the value of dom_xen domain_id.\n");
 
6461
                return FALSE;
 
6462
        }
 
6463
        info->domain_list[num_domain].domain_addr = domain;
 
6464
        info->domain_list[num_domain].domain_id = domain_id;
 
6465
        num_domain++;
 
6466
 
 
6467
        if (SYMBOL(dom_io) == NOT_FOUND_SYMBOL) {
 
6468
                ERRMSG("Can't get the symbol of dom_io.\n");
 
6469
                return FALSE;
 
6470
        }
 
6471
        if (!readmem(VADDR_XEN, SYMBOL(dom_io), &domain, sizeof(domain))) {
 
6472
                ERRMSG("Can't get the value of dom_io.\n");
 
6473
                return FALSE;
 
6474
        }
 
6475
        if (!readmem(VADDR_XEN, domain + OFFSET(domain.domain_id), &domain_id,
 
6476
            sizeof(domain_id))) {
 
6477
                ERRMSG( "Can't get the value of dom_io domain_id.\n");
 
6478
                return FALSE;
 
6479
        }
 
6480
        info->domain_list[num_domain].domain_addr = domain;
 
6481
        info->domain_list[num_domain].domain_id = domain_id;
 
6482
 
 
6483
        /*
 
6484
         * Get architecture specific data
 
6485
         */
 
6486
        if (!get_xen_info_arch())
 
6487
                return FALSE;
 
6488
 
 
6489
        return TRUE;
 
6490
}
 
6491
 
 
6492
void
 
6493
show_data_xen(void)
 
6494
{
 
6495
        int i;
 
6496
 
 
6497
        /*
 
6498
         * Show data for debug
 
6499
         */
 
6500
        MSG("\n");
 
6501
        MSG("SYMBOL(dom_xen): %llx\n", SYMBOL(dom_xen));
 
6502
        MSG("SYMBOL(dom_io): %llx\n", SYMBOL(dom_io));
 
6503
        MSG("SYMBOL(domain_list): %llx\n", SYMBOL(domain_list));
 
6504
        MSG("SYMBOL(xen_heap_start): %llx\n", SYMBOL(xen_heap_start));
 
6505
        MSG("SYMBOL(frame_table): %llx\n", SYMBOL(frame_table));
 
6506
        MSG("SYMBOL(alloc_bitmap): %llx\n", SYMBOL(alloc_bitmap));
 
6507
        MSG("SYMBOL(max_page): %llx\n", SYMBOL(max_page));
 
6508
        MSG("SYMBOL(pgd_l2): %llx\n", SYMBOL(pgd_l2));
 
6509
        MSG("SYMBOL(pgd_l3): %llx\n", SYMBOL(pgd_l3));
 
6510
        MSG("SYMBOL(pgd_l4): %llx\n", SYMBOL(pgd_l4));
 
6511
        MSG("SYMBOL(xenheap_phys_end): %llx\n", SYMBOL(xenheap_phys_end));
 
6512
        MSG("SYMBOL(xen_pstart): %llx\n", SYMBOL(xen_pstart));
 
6513
        MSG("SYMBOL(frametable_pg_dir): %llx\n", SYMBOL(frametable_pg_dir));
 
6514
 
 
6515
        MSG("SIZE(page_info): %ld\n", SIZE(page_info));
 
6516
        MSG("OFFSET(page_info.count_info): %ld\n", OFFSET(page_info.count_info));
 
6517
        MSG("OFFSET(page_info._domain): %ld\n", OFFSET(page_info._domain));
 
6518
        MSG("SIZE(domain): %ld\n", SIZE(domain));
 
6519
        MSG("OFFSET(domain.domain_id): %ld\n", OFFSET(domain.domain_id));
 
6520
        MSG("OFFSET(domain.next_in_list): %ld\n", OFFSET(domain.next_in_list));
 
6521
 
 
6522
        MSG("\n");
 
6523
        MSG("xen_phys_start: %lx\n", info->xen_phys_start);
 
6524
        MSG("frame_table_vaddr: %lx\n", info->frame_table_vaddr);
 
6525
        MSG("xen_heap_start: %lx\n", info->xen_heap_start);
 
6526
        MSG("xen_heap_end:%lx\n", info->xen_heap_end);
 
6527
        MSG("alloc_bitmap: %lx\n", info->alloc_bitmap);
 
6528
        MSG("max_page: %lx\n", info->max_page);
 
6529
        MSG("num_domain: %d\n", info->num_domain);
 
6530
        for (i = 0; i < info->num_domain; i++) {
 
6531
                MSG(" %u: %x: %lx\n", info->domain_list[i].domain_id,
 
6532
                        info->domain_list[i].pickled_id,
 
6533
                        info->domain_list[i].domain_addr);
 
6534
        }
 
6535
}
 
6536
 
 
6537
int
 
6538
generate_vmcoreinfo_xen(void)
 
6539
{
 
6540
        if ((info->page_size = sysconf(_SC_PAGE_SIZE)) <= 0) {
 
6541
                ERRMSG("Can't get the size of page.\n");
 
6542
                return FALSE;
 
6543
        }
 
6544
        dwarf_info.fd_debuginfo   = info->fd_xen_syms;
 
6545
        dwarf_info.name_debuginfo = info->name_xen_syms;
 
6546
 
 
6547
        if (!get_symbol_info_xen())
 
6548
                return FALSE;
 
6549
 
 
6550
        if (!get_structure_info_xen())
 
6551
                return FALSE;
 
6552
 
 
6553
        /*
 
6554
         * write 1st kernel's PAGESIZE
 
6555
         */
 
6556
        fprintf(info->file_vmcoreinfo, "%s%ld\n", STR_PAGESIZE,
 
6557
            info->page_size);
 
6558
 
 
6559
        /*
 
6560
         * write the symbol of 1st kernel
 
6561
         */
 
6562
        WRITE_SYMBOL("dom_xen", dom_xen);
 
6563
        WRITE_SYMBOL("dom_io", dom_io);
 
6564
        WRITE_SYMBOL("domain_list", domain_list);
 
6565
        WRITE_SYMBOL("xen_heap_start", xen_heap_start);
 
6566
        WRITE_SYMBOL("frame_table", frame_table);
 
6567
        WRITE_SYMBOL("alloc_bitmap", alloc_bitmap);
 
6568
        WRITE_SYMBOL("max_page", max_page);
 
6569
        WRITE_SYMBOL("pgd_l2", pgd_l2);
 
6570
        WRITE_SYMBOL("pgd_l3", pgd_l3);
 
6571
        WRITE_SYMBOL("pgd_l4", pgd_l4);
 
6572
        WRITE_SYMBOL("xenheap_phys_end", xenheap_phys_end);
 
6573
        WRITE_SYMBOL("xen_pstart", xen_pstart);
 
6574
        WRITE_SYMBOL("frametable_pg_dir", frametable_pg_dir);
 
6575
 
 
6576
        /*
 
6577
         * write the structure size of 1st kernel
 
6578
         */
 
6579
        WRITE_STRUCTURE_SIZE("page_info", page_info);
 
6580
        WRITE_STRUCTURE_SIZE("domain", domain);
 
6581
 
 
6582
        /*
 
6583
         * write the member offset of 1st kernel
 
6584
         */
 
6585
        WRITE_MEMBER_OFFSET("page_info.count_info", page_info.count_info);
 
6586
        WRITE_MEMBER_OFFSET("page_info._domain", page_info._domain);
 
6587
        WRITE_MEMBER_OFFSET("domain.domain_id", domain.domain_id);
 
6588
        WRITE_MEMBER_OFFSET("domain.next_in_list", domain.next_in_list);
 
6589
 
 
6590
        return TRUE;
 
6591
}
 
6592
 
 
6593
int
 
6594
read_vmcoreinfo_basic_info_xen(void)
 
6595
{
 
6596
        long page_size = FALSE;
 
6597
        char buf[BUFSIZE_FGETS], *endp;
 
6598
        unsigned int i;
 
6599
 
 
6600
        if (fseek(info->file_vmcoreinfo, 0, SEEK_SET) < 0) {
 
6601
                ERRMSG("Can't seek the vmcoreinfo file(%s). %s\n",
 
6602
                    info->name_vmcoreinfo, strerror(errno));
 
6603
                return FALSE;
 
6604
        }
 
6605
 
 
6606
        while (fgets(buf, BUFSIZE_FGETS, info->file_vmcoreinfo)) {
 
6607
                i = strlen(buf);
 
6608
                if (!i)
 
6609
                        break;
 
6610
                if (buf[i - 1] == '\n')
 
6611
                        buf[i - 1] = '\0';
 
6612
                if (strncmp(buf, STR_PAGESIZE, strlen(STR_PAGESIZE)) == 0) {
 
6613
                        page_size = strtol(buf+strlen(STR_PAGESIZE),&endp,10);
 
6614
                        if ((!page_size || page_size == LONG_MAX)
 
6615
                            || strlen(endp) != 0) {
 
6616
                                ERRMSG("Invalid data in %s: %s",
 
6617
                                    info->name_vmcoreinfo, buf);
 
6618
                                return FALSE;
 
6619
                        }
 
6620
                        if (!set_page_size(page_size)) {
 
6621
                                ERRMSG("Invalid data in %s: %s",
 
6622
                                    info->name_vmcoreinfo, buf);
 
6623
                                return FALSE;
 
6624
                        }
 
6625
                        break;
 
6626
                }
 
6627
        }
 
6628
        if (!info->page_size) {
 
6629
                ERRMSG("Invalid format in %s", info->name_vmcoreinfo);
 
6630
                return FALSE;
 
6631
        }
 
6632
        return TRUE;
 
6633
}
 
6634
 
 
6635
int
 
6636
read_vmcoreinfo_xen(void)
 
6637
{
 
6638
        if (!read_vmcoreinfo_basic_info_xen())
 
6639
                return FALSE;
 
6640
 
 
6641
        READ_SYMBOL("dom_xen", dom_xen);
 
6642
        READ_SYMBOL("dom_io", dom_io);
 
6643
        READ_SYMBOL("domain_list", domain_list);
 
6644
        READ_SYMBOL("xen_heap_start", xen_heap_start);
 
6645
        READ_SYMBOL("frame_table", frame_table);
 
6646
        READ_SYMBOL("alloc_bitmap", alloc_bitmap);
 
6647
        READ_SYMBOL("max_page", max_page);
 
6648
        READ_SYMBOL("pgd_l2", pgd_l2);
 
6649
        READ_SYMBOL("pgd_l3", pgd_l3);
 
6650
        READ_SYMBOL("pgd_l4", pgd_l4);
 
6651
        READ_SYMBOL("xenheap_phys_end", xenheap_phys_end);
 
6652
        READ_SYMBOL("xen_pstart", xen_pstart);
 
6653
        READ_SYMBOL("frametable_pg_dir", frametable_pg_dir);
 
6654
 
 
6655
        READ_STRUCTURE_SIZE("page_info", page_info);
 
6656
        READ_STRUCTURE_SIZE("domain", domain);
 
6657
 
 
6658
        READ_MEMBER_OFFSET("page_info.count_info", page_info.count_info);
 
6659
        READ_MEMBER_OFFSET("page_info._domain", page_info._domain);
 
6660
        READ_MEMBER_OFFSET("domain.domain_id", domain.domain_id);
 
6661
        READ_MEMBER_OFFSET("domain.next_in_list", domain.next_in_list);
 
6662
 
 
6663
        return TRUE;
 
6664
}
 
6665
 
 
6666
int
 
6667
allocated_in_map(unsigned long long pfn)
 
6668
{
 
6669
        static unsigned long long cur_idx = -1;
 
6670
        static unsigned long cur_word;
 
6671
        unsigned long long idx;
 
6672
 
 
6673
        idx = pfn / PAGES_PER_MAPWORD;
 
6674
        if (idx != cur_idx) {
 
6675
                if (!readmem(VADDR_XEN,
 
6676
                    info->alloc_bitmap + idx * sizeof(unsigned long),
 
6677
                    &cur_word, sizeof(cur_word))) {
 
6678
                        ERRMSG("Can't access alloc_bitmap.\n");
 
6679
                        return 0;
 
6680
                }
 
6681
                cur_idx = idx;
 
6682
        }
 
6683
 
 
6684
        return !!(cur_word & (1UL << (pfn & (PAGES_PER_MAPWORD - 1))));
 
6685
}
 
6686
 
 
6687
int
 
6688
is_select_domain(unsigned int id)
 
6689
{
 
6690
        int i;
 
6691
 
 
6692
        /* selected domain is fix to dom0 only now !!
 
6693
           (yes... domain_list is not necessary right now,
 
6694
                   it can get from "dom0" directly) */
 
6695
 
 
6696
        for (i = 0; i < info->num_domain; i++) {
 
6697
                if (info->domain_list[i].domain_id == 0 &&
 
6698
                    info->domain_list[i].pickled_id == id)
 
6699
                        return TRUE;
 
6700
        }
 
6701
 
 
6702
        return FALSE;
 
6703
}
 
6704
 
 
6705
int
 
6706
exclude_xen_user_domain(void)
 
6707
{
 
6708
        int i;
 
6709
        unsigned int count_info, _domain;
 
6710
        unsigned long page_info_addr;
 
6711
        unsigned long long pfn, pfn_end;
 
6712
        unsigned long long j, size;
 
6713
        struct pt_load_segment *pls;
 
6714
        struct timeval tv_start;
 
6715
 
 
6716
        gettimeofday(&tv_start, NULL);
 
6717
 
 
6718
        /*
 
6719
         * NOTE: the first half of bitmap is not used for Xen extraction
 
6720
         */
 
6721
        for (i = 0; i < info->num_load_memory; i++) {
 
6722
 
 
6723
                print_progress(PROGRESS_XEN_DOMAIN, i, info->num_load_memory);
 
6724
 
 
6725
                pls = &info->pt_load_segments[i];
 
6726
                pfn     = paddr_to_pfn(pls->phys_start);
 
6727
                pfn_end = paddr_to_pfn(pls->phys_end);
 
6728
                size    = pfn_end - pfn;
 
6729
 
 
6730
                for (j = 0; pfn < pfn_end; pfn++, j++) {
 
6731
                        print_progress(PROGRESS_XEN_DOMAIN, j + (size * i),
 
6732
                                        size * info->num_load_memory);
 
6733
 
 
6734
                        if (!allocated_in_map(pfn)) {
 
6735
                                clear_bit_on_2nd_bitmap(pfn);
 
6736
                                continue;
 
6737
                        }
 
6738
 
 
6739
                        page_info_addr = info->frame_table_vaddr + pfn * SIZE(page_info);
 
6740
                        if (!readmem(VADDR_XEN,
 
6741
                              page_info_addr + OFFSET(page_info.count_info),
 
6742
                              &count_info, sizeof(count_info))) {
 
6743
                                clear_bit_on_2nd_bitmap(pfn);
 
6744
                                continue;       /* page_info may not exist */
 
6745
                        }
 
6746
                        if (!readmem(VADDR_XEN,
 
6747
                              page_info_addr + OFFSET(page_info._domain),
 
6748
                              &_domain, sizeof(_domain))) {
 
6749
                                ERRMSG("Can't get page_info._domain.\n");
 
6750
                                return FALSE;
 
6751
                        }
 
6752
                        /*
 
6753
                         * select:
 
6754
                         *  - anonymous (_domain == 0), or
 
6755
                         *  - xen heap area, or
 
6756
                         *  - selected domain page
 
6757
                         */
 
6758
                        if (_domain == 0)
 
6759
                                continue;
 
6760
                        if (info->xen_heap_start <= pfn && pfn < info->xen_heap_end)
 
6761
                                continue;
 
6762
                        if ((count_info & 0xffff) && is_select_domain(_domain))
 
6763
                                continue;
 
6764
                        clear_bit_on_2nd_bitmap(pfn);
 
6765
                }
 
6766
        }
 
6767
 
 
6768
        /*
 
6769
         * print [100 %]
 
6770
         */
 
6771
        print_progress(PROGRESS_XEN_DOMAIN, info->num_load_memory, info->num_load_memory);
 
6772
        print_execution_time(PROGRESS_XEN_DOMAIN, &tv_start);
 
6773
 
 
6774
        return TRUE;
 
6775
}
 
6776
 
 
6777
int
 
6778
initial_xen(void)
 
6779
{
 
6780
#ifdef __powerpc__
 
6781
        MSG("\n");
 
6782
        MSG("ppc64 xen is not supported.\n");
 
6783
        return FALSE;
 
6784
#else
 
6785
        if(!info->flag_elf_dumpfile) {
 
6786
                MSG("Specify '-E' option for Xen.\n");
 
6787
                MSG("Commandline parameter is invalid.\n");
 
6788
                MSG("Try `makedumpfile --help' for more information.\n");
 
6789
                return FALSE;
 
6790
        }
 
6791
#ifndef __x86_64__
 
6792
        if (DL_EXCLUDE_ZERO < info->max_dump_level) {
 
6793
                MSG("Dump_level is invalid. It should be 0 or 1.\n");
 
6794
                MSG("Commandline parameter is invalid.\n");
 
6795
                MSG("Try `makedumpfile --help' for more information.\n");
 
6796
                return FALSE;
 
6797
        }
 
6798
#endif
 
6799
        if (!fallback_to_current_page_size())
 
6800
                return FALSE;
 
6801
        /*
 
6802
         * Get the debug information for analysis from the vmcoreinfo file
 
6803
         */
 
6804
        if (info->flag_read_vmcoreinfo) {
 
6805
                if (!read_vmcoreinfo_xen())
 
6806
                        return FALSE;
 
6807
                close_vmcoreinfo();
 
6808
        /*
 
6809
         * Get the debug information for analysis from the xen-syms file
 
6810
         */
 
6811
        } else if (info->name_xen_syms) {
 
6812
                dwarf_info.fd_debuginfo   = info->fd_xen_syms;
 
6813
                dwarf_info.name_debuginfo = info->name_xen_syms;
 
6814
 
 
6815
                if (!get_symbol_info_xen())
 
6816
                        return FALSE;
 
6817
                if (!get_structure_info_xen())
 
6818
                        return FALSE;
 
6819
        /*
 
6820
         * Get the debug information for analysis from /proc/vmcore
 
6821
         */
 
6822
        } else {
 
6823
                /*
 
6824
                 * Check whether /proc/vmcore contains vmcoreinfo,
 
6825
                 * and get both the offset and the size.
 
6826
                 */
 
6827
                if (!info->offset_vmcoreinfo_xen || !info->size_vmcoreinfo_xen){
 
6828
                        if (!info->flag_exclude_xen_dom)
 
6829
                                goto out;
 
6830
 
 
6831
                        MSG("%s doesn't contain a vmcoreinfo for Xen.\n",
 
6832
                            info->name_memory);
 
6833
                        MSG("Specify '--xen-syms' option or '--xen-vmcoreinfo' option.\n");
 
6834
                        MSG("Commandline parameter is invalid.\n");
 
6835
                        MSG("Try `makedumpfile --help' for more information.\n");
 
6836
                        return FALSE;
 
6837
                }
 
6838
                /*
 
6839
                 * Get the debug information from /proc/vmcore
 
6840
                 */
 
6841
                if (!read_vmcoreinfo_from_vmcore(info->offset_vmcoreinfo_xen,
 
6842
                    info->size_vmcoreinfo_xen, TRUE))
 
6843
                        return FALSE;
 
6844
        }
 
6845
        if (!get_xen_phys_start())
 
6846
                return FALSE;
 
6847
        if (!get_xen_info())
 
6848
                return FALSE;
 
6849
 
 
6850
        if (message_level & ML_PRINT_DEBUG_MSG)
 
6851
                show_data_xen();
 
6852
out:
 
6853
        if (!get_max_mapnr())
 
6854
                return FALSE;
 
6855
 
 
6856
        return TRUE;
 
6857
#endif
 
6858
}
 
6859
 
 
6860
void
 
6861
print_vtop(void)
 
6862
{
 
6863
        unsigned long long paddr;
 
6864
 
 
6865
        if (!info->vaddr_for_vtop)
 
6866
                return;
 
6867
 
 
6868
        MSG("\n");
 
6869
        MSG("Translating virtual address %lx to physical address.\n", info->vaddr_for_vtop);
 
6870
 
 
6871
        paddr = vaddr_to_paddr(info->vaddr_for_vtop);
 
6872
 
 
6873
        MSG("VIRTUAL           PHYSICAL\n");
 
6874
        MSG("%16lx  %llx\n", info->vaddr_for_vtop, paddr);
 
6875
        MSG("\n");
 
6876
 
 
6877
        info->vaddr_for_vtop = 0;
 
6878
 
 
6879
        return;
 
6880
}
 
6881
 
 
6882
void
 
6883
print_report(void)
 
6884
{
 
6885
        unsigned long long pfn_original, pfn_excluded, shrinking;
 
6886
 
 
6887
        /*
 
6888
         * /proc/vmcore doesn't contain the memory hole area.
 
6889
         */
 
6890
        pfn_original = info->max_mapnr - pfn_memhole;
 
6891
 
 
6892
        pfn_excluded = pfn_zero + pfn_cache + pfn_cache_private
 
6893
            + pfn_user + pfn_free;
 
6894
        shrinking = (pfn_original - pfn_excluded) * 100;
 
6895
        shrinking = shrinking / pfn_original;
 
6896
 
 
6897
        REPORT_MSG("\n");
 
6898
        REPORT_MSG("Original pages  : 0x%016llx\n", pfn_original);
 
6899
        REPORT_MSG("  Excluded pages   : 0x%016llx\n", pfn_excluded);
 
6900
        REPORT_MSG("    Pages filled with zero  : 0x%016llx\n", pfn_zero);
 
6901
        REPORT_MSG("    Cache pages             : 0x%016llx\n", pfn_cache);
 
6902
        REPORT_MSG("    Cache pages + private   : 0x%016llx\n",
 
6903
            pfn_cache_private);
 
6904
        REPORT_MSG("    User process data pages : 0x%016llx\n", pfn_user);
 
6905
        REPORT_MSG("    Free pages              : 0x%016llx\n", pfn_free);
 
6906
        REPORT_MSG("  Remaining pages  : 0x%016llx\n",
 
6907
            pfn_original - pfn_excluded);
 
6908
        REPORT_MSG("  (The number of pages is reduced to %lld%%.)\n",
 
6909
            shrinking);
 
6910
        REPORT_MSG("Memory Hole     : 0x%016llx\n", pfn_memhole);
 
6911
        REPORT_MSG("--------------------------------------------------\n");
 
6912
        REPORT_MSG("Total pages     : 0x%016llx\n", info->max_mapnr);
 
6913
        REPORT_MSG("\n");
 
6914
}
 
6915
 
 
6916
int
 
6917
writeout_dumpfile(void)
 
6918
{
 
6919
        int ret = FALSE;
 
6920
        struct cache_data cd_header, cd_page;
 
6921
 
 
6922
        info->flag_nospace = FALSE;
 
6923
 
 
6924
        if (!open_dump_file())
 
6925
                return FALSE;
 
6926
 
 
6927
        if (info->flag_flatten) {
 
6928
                if (!write_start_flat_header())
 
6929
                        return FALSE;
 
6930
        }
 
6931
        if (!prepare_cache_data(&cd_header))
 
6932
                return FALSE;
 
6933
 
 
6934
        if (!prepare_cache_data(&cd_page)) {
 
6935
                free_cache_data(&cd_header);
 
6936
                return FALSE;
 
6937
        }
 
6938
        if (info->flag_elf_dumpfile) {
 
6939
                if (!write_elf_header(&cd_header))
 
6940
                        goto out;
 
6941
                if (!write_elf_pages(&cd_header, &cd_page))
 
6942
                        goto out;
 
6943
        } else {
 
6944
                if (!write_kdump_header())
 
6945
                        goto out;
 
6946
                if (!write_kdump_pages(&cd_header, &cd_page))
 
6947
                        goto out;
 
6948
                if (!write_kdump_bitmap())
 
6949
                        goto out;
 
6950
        }
 
6951
        if (info->flag_flatten) {
 
6952
                if (!write_end_flat_header())
 
6953
                        goto out;
 
6954
        }
 
6955
 
 
6956
        ret = TRUE;
 
6957
out:
 
6958
        free_cache_data(&cd_header);
 
6959
        free_cache_data(&cd_page);
 
6960
 
 
6961
        close_dump_file();
 
6962
 
 
6963
        if ((ret == FALSE) && info->flag_nospace)
 
6964
                return NOSPACE;
 
6965
        else
 
6966
                return ret;
 
6967
}
 
6968
 
 
6969
int
 
6970
setup_splitting(void)
 
6971
{
 
6972
        int i;
 
6973
        unsigned long long j, pfn_per_dumpfile;
 
6974
        unsigned long long start_pfn, end_pfn;
 
6975
        unsigned long long num_dumpable = get_num_dumpable();
 
6976
        struct dump_bitmap bitmap2;
 
6977
 
 
6978
        if (info->num_dumpfile <= 1)
 
6979
                return FALSE;
 
6980
 
 
6981
        initialize_2nd_bitmap(&bitmap2);
 
6982
 
 
6983
        pfn_per_dumpfile = num_dumpable / info->num_dumpfile;
 
6984
        start_pfn = end_pfn = 0;
 
6985
        for (i = 0; i < info->num_dumpfile; i++) {
 
6986
                start_pfn = end_pfn;
 
6987
                if (i == (info->num_dumpfile - 1)) {
 
6988
                        end_pfn  = info->max_mapnr;
 
6989
                } else {
 
6990
                        for (j = 0; j < pfn_per_dumpfile; end_pfn++) {
 
6991
                                if (is_dumpable(&bitmap2, end_pfn))
 
6992
                                        j++;
 
6993
                        }
 
6994
                }
 
6995
                SPLITTING_START_PFN(i) = start_pfn;
 
6996
                SPLITTING_END_PFN(i)   = end_pfn;
 
6997
        }
 
6998
 
 
6999
        return TRUE;
 
7000
}
 
7001
 
 
7002
/*
 
7003
 * This function is for creating split dumpfiles by multiple
 
7004
 * processes. Each child process should re-open a /proc/vmcore
 
7005
 * file, because it prevents each other from affectting the file
 
7006
 * offset due to read(2) call.
 
7007
 */
 
7008
int
 
7009
reopen_dump_memory()
 
7010
{
 
7011
        close_dump_memory();
 
7012
 
 
7013
        if ((info->fd_memory = open(info->name_memory, O_RDONLY)) < 0) {
 
7014
                ERRMSG("Can't open the dump memory(%s). %s\n",
 
7015
                    info->name_memory, strerror(errno));
 
7016
                return FALSE;
 
7017
        }
 
7018
        return TRUE;
 
7019
}
 
7020
 
 
7021
int
 
7022
get_next_dump_level(int index)
 
7023
{
 
7024
        if (info->num_dump_level <= index)
 
7025
                return -1;
 
7026
 
 
7027
        return info->array_dump_level[index];
 
7028
}
 
7029
 
 
7030
int
 
7031
delete_dumpfile(void)
 
7032
{
 
7033
        int i;
 
7034
 
 
7035
        if (info->flag_flatten)
 
7036
                return TRUE;
 
7037
 
 
7038
        if (info->flag_split) {
 
7039
                for (i = 0; i < info->num_dumpfile; i++)
 
7040
                        unlink(SPLITTING_DUMPFILE(i));
 
7041
        } else {
 
7042
                unlink(info->name_dumpfile);
 
7043
        }
 
7044
        return TRUE;
 
7045
}
 
7046
 
 
7047
int
 
7048
writeout_multiple_dumpfiles(void)
 
7049
{
 
7050
        int i, status, ret = TRUE;
 
7051
        pid_t pid;
 
7052
        pid_t array_pid[info->num_dumpfile];
 
7053
 
 
7054
        if (!setup_splitting())
 
7055
                return FALSE;
 
7056
 
 
7057
        for (i = 0; i < info->num_dumpfile; i++) {
 
7058
                if ((pid = fork()) < 0) {
 
7059
                        return FALSE;
 
7060
 
 
7061
                } else if (pid == 0) { /* Child */
 
7062
                        info->name_dumpfile   = SPLITTING_DUMPFILE(i);
 
7063
                        info->fd_bitmap       = SPLITTING_FD_BITMAP(i);
 
7064
                        info->split_start_pfn = SPLITTING_START_PFN(i);
 
7065
                        info->split_end_pfn   = SPLITTING_END_PFN(i);
 
7066
 
 
7067
                        if (!reopen_dump_memory())
 
7068
                                exit(1);
 
7069
                        if ((status = writeout_dumpfile()) == FALSE)
 
7070
                                exit(1);
 
7071
                        else if (status == NOSPACE)
 
7072
                                exit(2);
 
7073
                        exit(0);
 
7074
                }
 
7075
                array_pid[i] = pid;
 
7076
        }
 
7077
        for (i = 0; i < info->num_dumpfile; i++) {
 
7078
                waitpid(array_pid[i], &status, WUNTRACED);
 
7079
                if (!WIFEXITED(status) || WEXITSTATUS(status) == 1) {
 
7080
                        ERRMSG("Child process(%d) finished imcompletely.(%d)\n",
 
7081
                            array_pid[i], status);
 
7082
                        ret = FALSE;
 
7083
                } else if ((ret == TRUE) && (WEXITSTATUS(status) == 2))
 
7084
                        ret = NOSPACE;
 
7085
        }
 
7086
        return ret;
 
7087
}
 
7088
 
 
7089
int
 
7090
create_dumpfile(void)
 
7091
{
 
7092
        int num_retry, status, new_level;
 
7093
 
 
7094
        if (!open_files_for_creating_dumpfile())
 
7095
                return FALSE;
 
7096
 
 
7097
        if (!info->flag_refiltering) {
 
7098
                if (!get_elf_info())
 
7099
                        return FALSE;
 
7100
        }
 
7101
        if (vt.mem_flags & MEMORY_XEN) {
 
7102
                if (!initial_xen())
 
7103
                        return FALSE;
 
7104
        }
 
7105
        if (!initial())
 
7106
                return FALSE;
 
7107
 
 
7108
        print_vtop();
 
7109
 
 
7110
        num_retry = 0;
 
7111
retry:
 
7112
        if (info->flag_refiltering) {
 
7113
                /* Change dump level */
 
7114
                new_level = info->dump_level | info->kh_memory->dump_level;
 
7115
                if (new_level != info->dump_level) {
 
7116
                        info->dump_level = new_level;
 
7117
                        MSG("dump_level is changed to %d, " \
 
7118
                                "because %s was created by dump_level(%d).",
 
7119
                                new_level, info->name_memory,
 
7120
                                info->kh_memory->dump_level);
 
7121
                }
 
7122
        }
 
7123
 
 
7124
        if (!create_dump_bitmap())
 
7125
                return FALSE;
 
7126
 
 
7127
        if (info->flag_split) {
 
7128
                if ((status = writeout_multiple_dumpfiles()) == FALSE)
 
7129
                        return FALSE;
 
7130
        } else {
 
7131
                if ((status = writeout_dumpfile()) == FALSE)
 
7132
                        return FALSE;
 
7133
        }
 
7134
        if (status == NOSPACE) {
 
7135
                /*
 
7136
                 * If specifying the other dump_level, makedumpfile tries
 
7137
                 * to create a dumpfile with it again.
 
7138
                 */
 
7139
                num_retry++;
 
7140
                if ((info->dump_level = get_next_dump_level(num_retry)) < 0)
 
7141
                        return FALSE;
 
7142
                MSG("Retry to create a dumpfile by dump_level(%d).\n",
 
7143
                    info->dump_level);
 
7144
                if (!delete_dumpfile())
 
7145
                        return FALSE;
 
7146
                goto retry;
 
7147
        }
 
7148
        print_report();
 
7149
 
 
7150
        if (!close_files_for_creating_dumpfile())
 
7151
                return FALSE;
 
7152
 
 
7153
        return TRUE;
 
7154
}
 
7155
 
 
7156
int
 
7157
__read_disk_dump_header(struct disk_dump_header *dh, char *filename)
 
7158
{
 
7159
        int fd, ret = FALSE;
 
7160
 
 
7161
        if ((fd = open(filename, O_RDONLY)) < 0) {
 
7162
                ERRMSG("Can't open a file(%s). %s\n",
 
7163
                    filename, strerror(errno));
 
7164
                return FALSE;
 
7165
        }
 
7166
        if (lseek(fd, 0x0, SEEK_SET) < 0) {
 
7167
                ERRMSG("Can't seek a file(%s). %s\n",
 
7168
                    filename, strerror(errno));
 
7169
                goto out;
 
7170
        }
 
7171
        if (read(fd, dh, sizeof(struct disk_dump_header))
 
7172
            != sizeof(struct disk_dump_header)) {
 
7173
                ERRMSG("Can't read a file(%s). %s\n",
 
7174
                    filename, strerror(errno));
 
7175
                goto out;
 
7176
        }
 
7177
        ret = TRUE;
 
7178
out:
 
7179
        close(fd);
 
7180
 
 
7181
        return ret;
 
7182
}
 
7183
 
 
7184
int
 
7185
read_disk_dump_header(struct disk_dump_header *dh, char *filename)
 
7186
{
 
7187
        if (!__read_disk_dump_header(dh, filename))
 
7188
                return FALSE;
 
7189
 
 
7190
        if (strncmp(dh->signature, KDUMP_SIGNATURE, strlen(KDUMP_SIGNATURE))) {
 
7191
                ERRMSG("%s is not the kdump-compressed format.\n",
 
7192
                    filename);
 
7193
                return FALSE;
 
7194
        }
 
7195
        return TRUE;
 
7196
}
 
7197
 
 
7198
int
 
7199
read_kdump_sub_header(struct kdump_sub_header *kh, char *filename)
 
7200
{
 
7201
        int fd, ret = FALSE;
 
7202
        struct disk_dump_header dh;
 
7203
        off_t offset;
 
7204
 
 
7205
        if (!read_disk_dump_header(&dh, filename))
 
7206
                return FALSE;
 
7207
 
 
7208
        offset = DISKDUMP_HEADER_BLOCKS * dh.block_size;
 
7209
 
 
7210
        if ((fd = open(filename, O_RDONLY)) < 0) {
 
7211
                ERRMSG("Can't open a file(%s). %s\n",
 
7212
                    filename, strerror(errno));
 
7213
                return FALSE;
 
7214
        }
 
7215
        if (lseek(fd, offset, SEEK_SET) < 0) {
 
7216
                ERRMSG("Can't seek a file(%s). %s\n",
 
7217
                    filename, strerror(errno));
 
7218
                goto out;
 
7219
        }
 
7220
        if (read(fd, kh, sizeof(struct kdump_sub_header))
 
7221
             != sizeof(struct kdump_sub_header)) {
 
7222
                ERRMSG("Can't read a file(%s). %s\n",
 
7223
                    filename, strerror(errno));
 
7224
                goto out;
 
7225
        }
 
7226
        ret = TRUE;
 
7227
out:
 
7228
        close(fd);
 
7229
 
 
7230
        return ret;
 
7231
}
 
7232
 
 
7233
int
 
7234
store_splitting_info(void)
 
7235
{
 
7236
        int i;
 
7237
        struct disk_dump_header dh, tmp_dh;
 
7238
        struct kdump_sub_header kh;
 
7239
 
 
7240
        for (i = 0; i < info->num_dumpfile; i++) {
 
7241
                if (!read_disk_dump_header(&tmp_dh, SPLITTING_DUMPFILE(i)))
 
7242
                        return FALSE;
 
7243
 
 
7244
                if (i == 0) {
 
7245
                        memcpy(&dh, &tmp_dh, sizeof(tmp_dh));
 
7246
                        info->max_mapnr = dh.max_mapnr;
 
7247
                        if (!set_page_size(dh.block_size))
 
7248
                                return FALSE;
 
7249
                        DEBUG_MSG("max_mapnr    : %llx\n", info->max_mapnr);
 
7250
                        DEBUG_MSG("page_size    : %ld\n", info->page_size);
 
7251
                }
 
7252
 
 
7253
                /*
 
7254
                 * Check whether multiple dumpfiles are parts of
 
7255
                 * the same /proc/vmcore.
 
7256
                 */
 
7257
                if (memcmp(&dh, &tmp_dh, sizeof(tmp_dh))) {
 
7258
                        ERRMSG("Invalid dumpfile(%s).\n",
 
7259
                            SPLITTING_DUMPFILE(i));
 
7260
                        return FALSE;
 
7261
                }
 
7262
                if (!read_kdump_sub_header(&kh, SPLITTING_DUMPFILE(i)))
 
7263
                        return FALSE;
 
7264
 
 
7265
                if (i == 0) {
 
7266
                        info->dump_level = kh.dump_level;
 
7267
                        DEBUG_MSG("dump_level   : %d\n", info->dump_level);
 
7268
                }
 
7269
                SPLITTING_START_PFN(i) = kh.start_pfn;
 
7270
                SPLITTING_END_PFN(i)   = kh.end_pfn;
 
7271
        }
 
7272
        return TRUE;
 
7273
}
 
7274
 
 
7275
void
 
7276
sort_splitting_info(void)
 
7277
{
 
7278
        int i, j;
 
7279
        unsigned long long start_pfn, end_pfn;
 
7280
        char *name_dumpfile;
 
7281
 
 
7282
        /*
 
7283
         * Sort splitting_info by start_pfn.
 
7284
         */
 
7285
        for (i = 0; i < (info->num_dumpfile - 1); i++) {
 
7286
                for (j = i; j < info->num_dumpfile; j++) {
 
7287
                        if (SPLITTING_START_PFN(i) < SPLITTING_START_PFN(j))
 
7288
                                continue;
 
7289
                        start_pfn     = SPLITTING_START_PFN(i);
 
7290
                        end_pfn       = SPLITTING_END_PFN(i);
 
7291
                        name_dumpfile = SPLITTING_DUMPFILE(i);
 
7292
 
 
7293
                        SPLITTING_START_PFN(i) = SPLITTING_START_PFN(j);
 
7294
                        SPLITTING_END_PFN(i)   = SPLITTING_END_PFN(j);
 
7295
                        SPLITTING_DUMPFILE(i)  = SPLITTING_DUMPFILE(j);
 
7296
 
 
7297
                        SPLITTING_START_PFN(j) = start_pfn;
 
7298
                        SPLITTING_END_PFN(j)   = end_pfn;
 
7299
                        SPLITTING_DUMPFILE(j)  = name_dumpfile;
 
7300
                }
 
7301
        }
 
7302
 
 
7303
        DEBUG_MSG("num_dumpfile : %d\n", info->num_dumpfile);
 
7304
        for (i = 0; i < info->num_dumpfile; i++) {
 
7305
                DEBUG_MSG("dumpfile (%s)\n", SPLITTING_DUMPFILE(i));
 
7306
                DEBUG_MSG("  start_pfn  : %llx\n", SPLITTING_START_PFN(i));
 
7307
                DEBUG_MSG("  end_pfn    : %llx\n", SPLITTING_END_PFN(i));
 
7308
        }
 
7309
}
 
7310
 
 
7311
int
 
7312
check_splitting_info(void)
 
7313
{
 
7314
        int i;
 
7315
        unsigned long long end_pfn;
 
7316
 
 
7317
        /*
 
7318
         * Check whether there are not lack of /proc/vmcore.
 
7319
         */
 
7320
        if (SPLITTING_START_PFN(0) != 0) {
 
7321
                ERRMSG("There is not dumpfile corresponding to pfn 0x%x - 0x%llx.\n",
 
7322
                    0x0, SPLITTING_START_PFN(0));
 
7323
                return FALSE;
 
7324
        }
 
7325
        end_pfn = SPLITTING_END_PFN(0);
 
7326
 
 
7327
        for (i = 1; i < info->num_dumpfile; i++) {
 
7328
                if (end_pfn != SPLITTING_START_PFN(i)) {
 
7329
                        ERRMSG("There is not dumpfile corresponding to pfn 0x%llx - 0x%llx.\n",
 
7330
                            end_pfn, SPLITTING_START_PFN(i));
 
7331
                        return FALSE;
 
7332
                }
 
7333
                end_pfn = SPLITTING_END_PFN(i);
 
7334
        }
 
7335
        if (end_pfn != info->max_mapnr) {
 
7336
                ERRMSG("There is not dumpfile corresponding to pfn 0x%llx - 0x%llx.\n",
 
7337
                    end_pfn, info->max_mapnr);
 
7338
                return FALSE;
 
7339
        }
 
7340
 
 
7341
        return TRUE;
 
7342
}
 
7343
 
 
7344
int
 
7345
get_splitting_info(void)
 
7346
{
 
7347
        if (!store_splitting_info())
 
7348
                return FALSE;
 
7349
 
 
7350
        sort_splitting_info();
 
7351
 
 
7352
        if (!check_splitting_info())
 
7353
                return FALSE;
 
7354
 
 
7355
        return TRUE;
 
7356
}
 
7357
 
 
7358
int
 
7359
reassemble_kdump_header(void)
 
7360
{
 
7361
        int fd, ret = FALSE;
 
7362
        off_t offset_bitmap;
 
7363
        struct disk_dump_header dh;
 
7364
        struct kdump_sub_header kh;
 
7365
        char *buf_bitmap;
 
7366
 
 
7367
        /*
 
7368
         * Write common header.
 
7369
         */
 
7370
        if (!read_disk_dump_header(&dh, SPLITTING_DUMPFILE(0)))
 
7371
                return FALSE;
 
7372
 
 
7373
        if (lseek(info->fd_dumpfile, 0x0, SEEK_SET) < 0) {
 
7374
                ERRMSG("Can't seek a file(%s). %s\n",
 
7375
                    info->name_dumpfile, strerror(errno));
 
7376
                return FALSE;
 
7377
        }
 
7378
        if (write(info->fd_dumpfile, &dh, sizeof(dh)) != sizeof(dh)) {
 
7379
                ERRMSG("Can't write a file(%s). %s\n",
 
7380
                    info->name_dumpfile, strerror(errno));
 
7381
                return FALSE;
 
7382
        }
 
7383
 
 
7384
        /*
 
7385
         * Write sub header.
 
7386
         */
 
7387
        if (!read_kdump_sub_header(&kh, SPLITTING_DUMPFILE(0)))
 
7388
                return FALSE;
 
7389
 
 
7390
        kh.split = 0;
 
7391
        kh.start_pfn = 0;
 
7392
        kh.end_pfn   = 0;
 
7393
 
 
7394
        if (lseek(info->fd_dumpfile, info->page_size, SEEK_SET) < 0) {
 
7395
                ERRMSG("Can't seek a file(%s). %s\n",
 
7396
                    info->name_dumpfile, strerror(errno));
 
7397
                return FALSE;
 
7398
        }
 
7399
        if (write(info->fd_dumpfile, &kh, sizeof(kh)) != sizeof(kh)) {
 
7400
                ERRMSG("Can't write a file(%s). %s\n",
 
7401
                    info->name_dumpfile, strerror(errno));
 
7402
                return FALSE;
 
7403
        }
 
7404
 
 
7405
        /*
 
7406
         * Write dump bitmap to both a dumpfile and a bitmap file.
 
7407
         */
 
7408
        offset_bitmap
 
7409
            = (DISKDUMP_HEADER_BLOCKS + dh.sub_hdr_size) * dh.block_size;
 
7410
        info->len_bitmap = dh.bitmap_blocks * dh.block_size;
 
7411
        if ((buf_bitmap = malloc(info->len_bitmap)) == NULL) {
 
7412
                ERRMSG("Can't allcate memory for bitmap.\n");
 
7413
                return FALSE;
 
7414
        }
 
7415
 
 
7416
        if ((fd = open(SPLITTING_DUMPFILE(0), O_RDONLY)) < 0) {
 
7417
                ERRMSG("Can't open a file(%s). %s\n",
 
7418
                    SPLITTING_DUMPFILE(0), strerror(errno));
 
7419
                free(buf_bitmap);
 
7420
                return FALSE;
 
7421
        }
 
7422
        if (lseek(fd, offset_bitmap, SEEK_SET) < 0) {
 
7423
                ERRMSG("Can't seek a file(%s). %s\n",
 
7424
                    SPLITTING_DUMPFILE(0), strerror(errno));
 
7425
                goto out;
 
7426
        }
 
7427
        if (read(fd, buf_bitmap, info->len_bitmap) != info->len_bitmap) {
 
7428
                ERRMSG("Can't read a file(%s). %s\n",
 
7429
                    SPLITTING_DUMPFILE(0), strerror(errno));
 
7430
                goto out;
 
7431
        }
 
7432
 
 
7433
        if (lseek(info->fd_dumpfile, offset_bitmap, SEEK_SET) < 0) {
 
7434
                ERRMSG("Can't seek a file(%s). %s\n",
 
7435
                    info->name_dumpfile, strerror(errno));
 
7436
                goto out;
 
7437
        }
 
7438
        if (write(info->fd_dumpfile, buf_bitmap, info->len_bitmap)
 
7439
            != info->len_bitmap) {
 
7440
                ERRMSG("Can't write a file(%s). %s\n",
 
7441
                    info->name_dumpfile, strerror(errno));
 
7442
                goto out;
 
7443
        }
 
7444
 
 
7445
        if (lseek(info->fd_bitmap, 0x0, SEEK_SET) < 0) {
 
7446
                ERRMSG("Can't seek a file(%s). %s\n",
 
7447
                    info->name_bitmap, strerror(errno));
 
7448
                goto out;
 
7449
        }
 
7450
        if (write(info->fd_bitmap, buf_bitmap, info->len_bitmap)
 
7451
            != info->len_bitmap) {
 
7452
                ERRMSG("Can't write a file(%s). %s\n",
 
7453
                    info->name_bitmap, strerror(errno));
 
7454
                goto out;
 
7455
        }
 
7456
 
 
7457
        ret = TRUE;
 
7458
out:
 
7459
        close(fd);
 
7460
 
 
7461
        return ret;
 
7462
}
 
7463
 
 
7464
int
 
7465
reassemble_kdump_pages(void)
 
7466
{
 
7467
        int i, fd = 0, ret = FALSE;
 
7468
        off_t offset_first_ph, offset_ph_org;
 
7469
        off_t offset_data_new, offset_zero_page = 0;
 
7470
        unsigned long long pfn, start_pfn, end_pfn;
 
7471
        unsigned long long num_dumpable, num_dumped;
 
7472
        struct dump_bitmap bitmap2;
 
7473
        struct disk_dump_header dh;
 
7474
        struct page_desc pd, pd_zero;
 
7475
        struct cache_data cd_pd, cd_data;
 
7476
        struct timeval tv_start;
 
7477
        char *data = NULL;
 
7478
 
 
7479
        initialize_2nd_bitmap(&bitmap2);
 
7480
 
 
7481
        if (!read_disk_dump_header(&dh, SPLITTING_DUMPFILE(0)))
 
7482
                return FALSE;
 
7483
 
 
7484
        if (!prepare_cache_data(&cd_pd))
 
7485
                return FALSE;
 
7486
 
 
7487
        if (!prepare_cache_data(&cd_data)) {
 
7488
                free_cache_data(&cd_pd);
 
7489
                return FALSE;
 
7490
        }
 
7491
        if ((data = malloc(info->page_size)) == NULL) {
 
7492
                ERRMSG("Can't allcate memory for page data.\n");
 
7493
                free_cache_data(&cd_pd);
 
7494
                free_cache_data(&cd_data);
 
7495
                return FALSE;
 
7496
        }
 
7497
        num_dumpable = get_num_dumpable();
 
7498
        num_dumped = 0;
 
7499
 
 
7500
        offset_first_ph
 
7501
            = (DISKDUMP_HEADER_BLOCKS + dh.sub_hdr_size + dh.bitmap_blocks)
 
7502
                * dh.block_size;
 
7503
        cd_pd.offset    = offset_first_ph;
 
7504
        offset_data_new = offset_first_ph + sizeof(page_desc_t) * num_dumpable;
 
7505
        cd_data.offset  = offset_data_new;
 
7506
 
 
7507
        /*
 
7508
         * Write page header of zero-filled page.
 
7509
         */
 
7510
        gettimeofday(&tv_start, NULL);
 
7511
        if (info->dump_level & DL_EXCLUDE_ZERO) {
 
7512
                /*
 
7513
                 * makedumpfile outputs the data of zero-filled page at first
 
7514
                 * if excluding zero-filled page, so the offset of first data
 
7515
                 * is for zero-filled page in all dumpfiles.
 
7516
                 */
 
7517
                offset_zero_page = offset_data_new;
 
7518
 
 
7519
                pd_zero.size = info->page_size;
 
7520
                pd_zero.flags = 0;
 
7521
                pd_zero.offset = offset_data_new;
 
7522
                pd_zero.page_flags = 0;
 
7523
                memset(data, 0, pd_zero.size);
 
7524
                if (!write_cache(&cd_data, data, pd_zero.size))
 
7525
                        goto out;
 
7526
                offset_data_new  += pd_zero.size;
 
7527
        }
 
7528
 
 
7529
        for (i = 0; i < info->num_dumpfile; i++) {
 
7530
                if ((fd = open(SPLITTING_DUMPFILE(i), O_RDONLY)) < 0) {
 
7531
                        ERRMSG("Can't open a file(%s). %s\n",
 
7532
                            SPLITTING_DUMPFILE(i), strerror(errno));
 
7533
                        goto out;
 
7534
                }
 
7535
                start_pfn = SPLITTING_START_PFN(i);
 
7536
                end_pfn   = SPLITTING_END_PFN(i);
 
7537
 
 
7538
                offset_ph_org = offset_first_ph;
 
7539
                for (pfn = start_pfn; pfn < end_pfn; pfn++) {
 
7540
                        if (!is_dumpable(&bitmap2, pfn))
 
7541
                                continue;
 
7542
 
 
7543
                        num_dumped++;
 
7544
 
 
7545
                        print_progress(PROGRESS_COPY, num_dumped, num_dumpable);
 
7546
 
 
7547
                        if (lseek(fd, offset_ph_org, SEEK_SET) < 0) {
 
7548
                                ERRMSG("Can't seek a file(%s). %s\n",
 
7549
                                    SPLITTING_DUMPFILE(i), strerror(errno));
 
7550
                                goto out;
 
7551
                        }
 
7552
                        if (read(fd, &pd, sizeof(pd)) != sizeof(pd)) {
 
7553
                                ERRMSG("Can't read a file(%s). %s\n",
 
7554
                                    SPLITTING_DUMPFILE(i), strerror(errno));
 
7555
                                goto out;
 
7556
                        }
 
7557
                        if (lseek(fd, pd.offset, SEEK_SET) < 0) {
 
7558
                                ERRMSG("Can't seek a file(%s). %s\n",
 
7559
                                    SPLITTING_DUMPFILE(i), strerror(errno));
 
7560
                                goto out;
 
7561
                        }
 
7562
                        if (read(fd, data, pd.size) != pd.size) {
 
7563
                                ERRMSG("Can't read a file(%s). %s\n",
 
7564
                                    SPLITTING_DUMPFILE(i), strerror(errno));
 
7565
                                goto out;
 
7566
                        }
 
7567
                        if ((info->dump_level & DL_EXCLUDE_ZERO)
 
7568
                            && (pd.offset == offset_zero_page)) {
 
7569
                                /*
 
7570
                                 * Handle the data of zero-filled page.
 
7571
                                 */
 
7572
                                if (!write_cache(&cd_pd, &pd_zero,
 
7573
                                    sizeof(pd_zero)))
 
7574
                                        goto out;
 
7575
                                offset_ph_org += sizeof(pd);
 
7576
                                continue;
 
7577
                        }
 
7578
                        pd.offset = offset_data_new;
 
7579
                        if (!write_cache(&cd_pd, &pd, sizeof(pd)))
 
7580
                                goto out;
 
7581
                        offset_ph_org += sizeof(pd);
 
7582
 
 
7583
                        if (!write_cache(&cd_data, data, pd.size))
 
7584
                                goto out;
 
7585
 
 
7586
                        offset_data_new += pd.size;
 
7587
                }
 
7588
                close(fd);
 
7589
                fd = 0;
 
7590
        }
 
7591
        if (!write_cache_bufsz(&cd_pd))
 
7592
                goto out;
 
7593
        if (!write_cache_bufsz(&cd_data))
 
7594
                goto out;
 
7595
 
 
7596
        print_progress(PROGRESS_COPY, num_dumpable, num_dumpable);
 
7597
        print_execution_time(PROGRESS_COPY, &tv_start);
 
7598
 
 
7599
        ret = TRUE;
 
7600
out:
 
7601
        free_cache_data(&cd_pd);
 
7602
        free_cache_data(&cd_data);
 
7603
 
 
7604
        if (data)
 
7605
                free(data);
 
7606
        if (fd > 0)
 
7607
                close(fd);
 
7608
 
 
7609
        return ret;
 
7610
}
 
7611
 
 
7612
int
 
7613
reassemble_dumpfile(void)
 
7614
{
 
7615
        if (!get_splitting_info())
 
7616
                return FALSE;
 
7617
 
 
7618
        if (!open_dump_bitmap())
 
7619
                return FALSE;
 
7620
 
 
7621
        if (!open_dump_file())
 
7622
                return FALSE;
 
7623
 
 
7624
        if (!reassemble_kdump_header())
 
7625
                return FALSE;
 
7626
 
 
7627
        if (!reassemble_kdump_pages())
 
7628
                return FALSE;
 
7629
 
 
7630
        close_dump_file();
 
7631
        close_dump_bitmap();
 
7632
 
 
7633
        return TRUE;
 
7634
}
 
7635
 
 
7636
int
 
7637
check_param_for_generating_vmcoreinfo(int argc, char *argv[])
 
7638
{
 
7639
        if (argc != optind)
 
7640
                return FALSE;
 
7641
 
 
7642
        if (info->flag_compress        || info->dump_level
 
7643
            || info->flag_elf_dumpfile || info->flag_read_vmcoreinfo
 
7644
            || info->flag_flatten      || info->flag_rearrange
 
7645
            || info->flag_exclude_xen_dom
 
7646
            || (!info->name_vmlinux && !info->name_xen_syms))
 
7647
 
 
7648
                return FALSE;
 
7649
 
 
7650
        return TRUE;
 
7651
}
 
7652
 
 
7653
/*
 
7654
 * Parameters for creating dumpfile from the dump data
 
7655
 * of flattened format by rearranging the dump data.
 
7656
 */
 
7657
int
 
7658
check_param_for_rearranging_dumpdata(int argc, char *argv[])
 
7659
{
 
7660
        if (argc != optind + 1)
 
7661
                return FALSE;
 
7662
 
 
7663
        if (info->flag_compress        || info->dump_level
 
7664
            || info->flag_elf_dumpfile || info->flag_read_vmcoreinfo
 
7665
            || info->name_vmlinux      || info->name_xen_syms
 
7666
            || info->flag_flatten      || info->flag_generate_vmcoreinfo
 
7667
            || info->flag_exclude_xen_dom)
 
7668
                return FALSE;
 
7669
 
 
7670
        info->name_dumpfile = argv[optind];
 
7671
        return TRUE;
 
7672
}
 
7673
 
 
7674
/*
 
7675
 * Parameters for reassembling multiple dumpfiles into one dumpfile.
 
7676
 */
 
7677
int
 
7678
check_param_for_reassembling_dumpfile(int argc, char *argv[])
 
7679
{
 
7680
        int i;
 
7681
 
 
7682
        info->num_dumpfile  = argc - optind - 1;
 
7683
        info->name_dumpfile = argv[argc - 1];
 
7684
 
 
7685
        DEBUG_MSG("num_dumpfile : %d\n", info->num_dumpfile);
 
7686
 
 
7687
        if (info->flag_compress        || info->dump_level
 
7688
            || info->flag_elf_dumpfile || info->flag_read_vmcoreinfo
 
7689
            || info->name_vmlinux      || info->name_xen_syms
 
7690
            || info->flag_flatten      || info->flag_generate_vmcoreinfo
 
7691
            || info->flag_exclude_xen_dom || info->flag_split)
 
7692
                return FALSE;
 
7693
 
 
7694
        if ((info->splitting_info
 
7695
            = malloc(sizeof(splitting_info_t) * info->num_dumpfile))
 
7696
            == NULL) {
 
7697
                MSG("Can't allocate memory for splitting_info.\n");
 
7698
                return FALSE;
 
7699
        }
 
7700
        for (i = 0; i < info->num_dumpfile; i++)
 
7701
                SPLITTING_DUMPFILE(i) = argv[optind + i];
 
7702
 
 
7703
        return TRUE;
 
7704
}
 
7705
 
 
7706
/*
 
7707
 * Check parameters to create the dump file.
 
7708
 */
 
7709
int
 
7710
check_param_for_creating_dumpfile(int argc, char *argv[])
 
7711
{
 
7712
        int i;
 
7713
 
 
7714
        if (info->flag_generate_vmcoreinfo || info->flag_rearrange)
 
7715
                return FALSE;
 
7716
 
 
7717
        if ((message_level < MIN_MSG_LEVEL)
 
7718
            || (MAX_MSG_LEVEL < message_level)) {
 
7719
                message_level = DEFAULT_MSG_LEVEL;
 
7720
                MSG("Message_level is invalid.\n");
 
7721
                return FALSE;
 
7722
        }
 
7723
        if ((info->flag_compress && info->flag_elf_dumpfile)
 
7724
            || (info->flag_read_vmcoreinfo && info->name_vmlinux)
 
7725
            || (info->flag_read_vmcoreinfo && info->name_xen_syms))
 
7726
                return FALSE;
 
7727
 
 
7728
        if (info->flag_flatten && info->flag_split)
 
7729
                return FALSE;
 
7730
 
 
7731
        if ((argc == optind + 2) && !info->flag_flatten
 
7732
                                 && !info->flag_split) {
 
7733
                /*
 
7734
                 * Parameters for creating the dumpfile from vmcore.
 
7735
                 */
 
7736
                info->name_memory   = argv[optind];
 
7737
                info->name_dumpfile = argv[optind+1];
 
7738
 
 
7739
        } else if ((argc > optind + 2) && info->flag_split) {
 
7740
                /*
 
7741
                 * Parameters for creating multiple dumpfiles from vmcore.
 
7742
                 */
 
7743
                info->num_dumpfile = argc - optind - 1;
 
7744
                info->name_memory  = argv[optind];
 
7745
 
 
7746
                if (info->flag_elf_dumpfile) {
 
7747
                        MSG("Options for splitting dumpfile cannot be used with Elf format.\n");
 
7748
                        return FALSE;
 
7749
                }
 
7750
                if ((info->splitting_info
 
7751
                    = malloc(sizeof(splitting_info_t) * info->num_dumpfile))
 
7752
                    == NULL) {
 
7753
                        MSG("Can't allocate memory for splitting_info.\n");
 
7754
                        return FALSE;
 
7755
                }
 
7756
                for (i = 0; i < info->num_dumpfile; i++)
 
7757
                        SPLITTING_DUMPFILE(i) = argv[optind + 1 + i];
 
7758
 
 
7759
        } else if ((argc == optind + 1) && info->flag_flatten) {
 
7760
                /*
 
7761
                 * Parameters for outputting the dump data of the
 
7762
                 * flattened format to STDOUT.
 
7763
                 */
 
7764
                info->name_memory   = argv[optind];
 
7765
 
 
7766
        } else
 
7767
                return FALSE;
 
7768
 
 
7769
        return TRUE;
 
7770
}
 
7771
 
 
7772
int
 
7773
parse_dump_level(char *str_dump_level)
 
7774
{
 
7775
        int i, ret = FALSE;
 
7776
        char *buf, *ptr;
 
7777
 
 
7778
        if (!(buf = strdup(str_dump_level))) {
 
7779
                MSG("Can't duplicate strings(%s).\n", str_dump_level);
 
7780
                return FALSE;
 
7781
        }
 
7782
        info->max_dump_level = 0;
 
7783
        info->num_dump_level = 0;
 
7784
        ptr = buf;
 
7785
        while(TRUE) {
 
7786
                ptr = strtok(ptr, ",");
 
7787
                if (!ptr)
 
7788
                        break;
 
7789
 
 
7790
                i = atoi(ptr);
 
7791
                if ((i < MIN_DUMP_LEVEL) || (MAX_DUMP_LEVEL < i)) {
 
7792
                        MSG("Dump_level(%d) is invalid.\n", i);
 
7793
                        goto out;
 
7794
                }
 
7795
                if (NUM_ARRAY_DUMP_LEVEL <= info->num_dump_level) {
 
7796
                        MSG("Dump_level is invalid.\n");
 
7797
                        goto out;
 
7798
                }
 
7799
                if (info->max_dump_level < i)
 
7800
                        info->max_dump_level = i;
 
7801
                if (info->num_dump_level == 0)
 
7802
                        info->dump_level = i;
 
7803
                info->array_dump_level[info->num_dump_level] = i;
 
7804
                info->num_dump_level++;
 
7805
                ptr = NULL;
 
7806
        }
 
7807
        ret = TRUE;
 
7808
out:
 
7809
        free(buf);
 
7810
 
 
7811
        return ret;
 
7812
}
 
7813
 
 
7814
static struct option longopts[] = {
 
7815
        {"split", no_argument, NULL, 's'}, 
 
7816
        {"reassemble", no_argument, NULL, 'r'},
 
7817
        {"xen-syms", required_argument, NULL, 'y'},
 
7818
        {"xen-vmcoreinfo", required_argument, NULL, 'z'},
 
7819
        {"xen_phys_start", required_argument, NULL, 'P'},
 
7820
        {"message-level", required_argument, NULL, 'm'},
 
7821
        {"vtop", required_argument, NULL, 'V'},
 
7822
        {"dump-dmesg", no_argument, NULL, 'M'}, 
 
7823
        {"help", no_argument, NULL, 'h'},
 
7824
        {0, 0, 0, 0}
 
7825
};
 
7826
 
 
7827
int
 
7828
main(int argc, char *argv[])
 
7829
{
 
7830
        int i, opt, flag_debug = FALSE;
 
7831
 
 
7832
        if ((info = calloc(1, sizeof(struct DumpInfo))) == NULL) {
 
7833
                ERRMSG("Can't allocate memory for the pagedesc cache. %s.\n",
 
7834
                    strerror(errno));
 
7835
                goto out;
 
7836
        }
 
7837
        if ((info->dump_header = calloc(1, sizeof(struct disk_dump_header)))
 
7838
            == NULL) {
 
7839
                ERRMSG("Can't allocate memory for the dump header. %s\n",
 
7840
                    strerror(errno));
 
7841
                goto out;
 
7842
        }
 
7843
        initialize_tables();
 
7844
 
 
7845
        info->block_order = DEFAULT_ORDER;
 
7846
        message_level = DEFAULT_MSG_LEVEL;
 
7847
        while ((opt = getopt_long(argc, argv, "b:cDd:EFfg:hi:MRrsVvXx:", longopts,
 
7848
            NULL)) != -1) {
 
7849
                switch (opt) {
 
7850
                case 'b':
 
7851
                        info->block_order = atoi(optarg);
 
7852
                        break;
 
7853
                case 'c':
 
7854
                        info->flag_compress = 1;
 
7855
                        break;
 
7856
                case 'D':
 
7857
                        flag_debug = TRUE;
 
7858
                        break;
 
7859
                case 'd':
 
7860
                        if (!parse_dump_level(optarg))
 
7861
                                goto out;
 
7862
                        break;
 
7863
                case 'E':
 
7864
                        info->flag_elf_dumpfile = 1;
 
7865
                        break;
 
7866
                case 'F':
 
7867
                        info->flag_flatten = 1;
 
7868
                        break;
 
7869
                case 'f':
 
7870
                        info->flag_force = 1;
 
7871
                        break;
 
7872
                case 'g':
 
7873
                        info->flag_generate_vmcoreinfo = 1;
 
7874
                        info->name_vmcoreinfo = optarg;
 
7875
                        break;
 
7876
                case 'h':
 
7877
                        info->flag_show_usage = 1;
 
7878
                        break;
 
7879
                case 'i':
 
7880
                        info->flag_read_vmcoreinfo = 1;
 
7881
                        info->name_vmcoreinfo = optarg;
 
7882
                        break;
 
7883
                case 'm':
 
7884
                        message_level = atoi(optarg);
 
7885
                        break;
 
7886
                case 'M':
 
7887
                        info->flag_dmesg = 1;
 
7888
                        break;
 
7889
                case 'P':
 
7890
                        info->xen_phys_start = strtoul(optarg, NULL, 0);
 
7891
                        break;
 
7892
                case 'R':
 
7893
                        info->flag_rearrange = 1;
 
7894
                        break;
 
7895
                case 's':
 
7896
                        info->flag_split = 1;
 
7897
                        break;
 
7898
                case 'r':
 
7899
                        info->flag_reassemble = 1;
 
7900
                        break;
 
7901
                case 'V':
 
7902
                        info->vaddr_for_vtop = strtoul(optarg, NULL, 0);
 
7903
                        break;
 
7904
                case 'v':
 
7905
                        info->flag_show_version = 1;
 
7906
                        break;
 
7907
                case 'X':
 
7908
                        info->flag_exclude_xen_dom = 1;
 
7909
                        break;
 
7910
                case 'x':
 
7911
                        info->name_vmlinux = optarg;
 
7912
                        break;
 
7913
                case 'y':
 
7914
                        info->name_xen_syms = optarg;
 
7915
                        break;
 
7916
                case 'z':
 
7917
                        info->flag_read_vmcoreinfo = 1;
 
7918
                        info->name_vmcoreinfo = optarg;
 
7919
                        break;
 
7920
                case '?':
 
7921
                        MSG("Commandline parameter is invalid.\n");
 
7922
                        MSG("Try `makedumpfile --help' for more information.\n");
 
7923
                        goto out;
 
7924
                }
 
7925
        }
 
7926
        if (flag_debug)
 
7927
                message_level |= ML_PRINT_DEBUG_MSG;
 
7928
 
 
7929
        if (info->flag_show_usage) {
 
7930
                print_usage();
 
7931
                return COMPLETED;
 
7932
        }
 
7933
        if (info->flag_show_version) {
 
7934
                show_version();
 
7935
                return COMPLETED;
 
7936
        }
 
7937
 
 
7938
        if (elf_version(EV_CURRENT) == EV_NONE ) {
 
7939
                /*
 
7940
                 * library out of date
 
7941
                 */
 
7942
                ERRMSG("Elf library out of date!\n");
 
7943
                goto out;
 
7944
        }
 
7945
        if (info->flag_generate_vmcoreinfo) {
 
7946
                if (!check_param_for_generating_vmcoreinfo(argc, argv)) {
 
7947
                        MSG("Commandline parameter is invalid.\n");
 
7948
                        MSG("Try `makedumpfile --help' for more information.\n");
 
7949
                        goto out;
 
7950
                }
 
7951
                if (!open_files_for_generating_vmcoreinfo())
 
7952
                        goto out;
 
7953
 
 
7954
                if (info->name_xen_syms) {
 
7955
                        if (!generate_vmcoreinfo_xen())
 
7956
                                goto out;
 
7957
                } else {
 
7958
                        if (!generate_vmcoreinfo())
 
7959
                                goto out;
 
7960
                }
 
7961
 
 
7962
                if (!close_files_for_generating_vmcoreinfo())
 
7963
                        goto out;
 
7964
 
 
7965
                MSG("\n");
 
7966
                MSG("The vmcoreinfo is saved to %s.\n", info->name_vmcoreinfo);
 
7967
 
 
7968
        } else if (info->flag_rearrange) {
 
7969
                if (!check_param_for_rearranging_dumpdata(argc, argv)) {
 
7970
                        MSG("Commandline parameter is invalid.\n");
 
7971
                        MSG("Try `makedumpfile --help' for more information.\n");
 
7972
                        goto out;
 
7973
                }
 
7974
                if (!open_files_for_rearranging_dumpdata())
 
7975
                        goto out;
 
7976
 
 
7977
                if (!rearrange_dumpdata())
 
7978
                        goto out;
 
7979
 
 
7980
                if (!close_files_for_rearranging_dumpdata())
 
7981
                        goto out;
 
7982
 
 
7983
                MSG("\n");
 
7984
                MSG("The dumpfile is saved to %s.\n", info->name_dumpfile);
 
7985
        } else if (info->flag_reassemble) {
 
7986
                if (!check_param_for_reassembling_dumpfile(argc, argv)) {
 
7987
                        MSG("Commandline parameter is invalid.\n");
 
7988
                        MSG("Try `makedumpfile --help' for more information.\n");
 
7989
                        goto out;
 
7990
                }
 
7991
                if (!reassemble_dumpfile())
 
7992
                        goto out;
 
7993
 
 
7994
                MSG("\n");
 
7995
                MSG("The dumpfile is saved to %s.\n", info->name_dumpfile);
 
7996
        } else if (info->flag_dmesg) {
 
7997
                if (!check_param_for_creating_dumpfile(argc, argv)) {
 
7998
                        MSG("Commandline parameter is invalid.\n");
 
7999
                        MSG("Try `makedumpfile --help' for more information.\n");
 
8000
                        goto out;
 
8001
                }
 
8002
                if (!dump_dmesg())
 
8003
                        goto out;
 
8004
 
 
8005
                MSG("\n");
 
8006
                MSG("The dmesg log is saved to %s.\n", info->name_dumpfile);
 
8007
        } else {
 
8008
                if (!check_param_for_creating_dumpfile(argc, argv)) {
 
8009
                        MSG("Commandline parameter is invalid.\n");
 
8010
                        MSG("Try `makedumpfile --help' for more information.\n");
 
8011
                        goto out;
 
8012
                }
 
8013
                if (!create_dumpfile())
 
8014
                        goto out;
 
8015
 
 
8016
                MSG("\n");
 
8017
                if (info->flag_split) {
 
8018
                        MSG("The dumpfiles are saved to ");
 
8019
                        for (i = 0; i < info->num_dumpfile; i++) {
 
8020
                                if (i != (info->num_dumpfile - 1))
 
8021
                                        MSG("%s, ", SPLITTING_DUMPFILE(i));
 
8022
                                else
 
8023
                                        MSG("and %s.\n", SPLITTING_DUMPFILE(i));
 
8024
                        }
 
8025
                } else {
 
8026
                        MSG("The dumpfile is saved to %s.\n", info->name_dumpfile);
 
8027
                }
 
8028
        }
 
8029
        retcd = COMPLETED;
 
8030
out:
 
8031
        MSG("\n");
 
8032
        if (retcd == COMPLETED)
 
8033
                MSG("makedumpfile Completed.\n");
 
8034
        else
 
8035
                MSG("makedumpfile Failed.\n");
 
8036
 
 
8037
        if (info) {
 
8038
                if (info->dh_memory)
 
8039
                        free(info->dh_memory);
 
8040
                if (info->kh_memory)
 
8041
                        free(info->kh_memory);
 
8042
                if (info->valid_pages)
 
8043
                        free(info->valid_pages);
 
8044
                if (info->bitmap_memory)
 
8045
                        free(info->bitmap_memory);
 
8046
                if (info->fd_memory)
 
8047
                        close(info->fd_memory);
 
8048
                if (info->fd_dumpfile)
 
8049
                        close(info->fd_dumpfile);
 
8050
                if (info->fd_bitmap)
 
8051
                        close(info->fd_bitmap);
 
8052
                if (info->pt_load_segments != NULL)
 
8053
                        free(info->pt_load_segments);
 
8054
                if (vt.node_online_map != NULL)
 
8055
                        free(vt.node_online_map);
 
8056
                if (info->mem_map_data != NULL)
 
8057
                        free(info->mem_map_data);
 
8058
                if (info->dump_header != NULL)
 
8059
                        free(info->dump_header);
 
8060
                if (info->splitting_info != NULL)
 
8061
                        free(info->splitting_info);
 
8062
                if (info->p2m_mfn_frame_list != NULL)
 
8063
                        free(info->p2m_mfn_frame_list);
 
8064
                free(info);
 
8065
        }
 
8066
        return retcd;
 
8067
}