Allow libkvm to get the kernel va to pa delta without the need for
physaddr. This should allow for a kernel where PHYSADDR and KERNPHYSADDR are both undefined. For now libkvm will use the old method of reading physaddr and kernaddr to allow it to work with old kernels. This could be removed in the future when enough time has passed. Differential Revision: https://reviews.freebsd.org/D939 MFC after: 1 week
This commit is contained in:
parent
a2d27ff80e
commit
58c47a70a3
@ -132,8 +132,10 @@ _kvm_initvtop(kvm_t *kd)
|
||||
u_long kernbase, physaddr, pa;
|
||||
pd_entry_t *l1pt;
|
||||
Elf32_Ehdr *ehdr;
|
||||
Elf32_Phdr *phdr;
|
||||
size_t hdrsz;
|
||||
char minihdr[8];
|
||||
int found, i;
|
||||
|
||||
if (!kd->rawdump) {
|
||||
if (pread(kd->pmfd, &minihdr, 8, 0) == 8) {
|
||||
@ -158,19 +160,33 @@ _kvm_initvtop(kvm_t *kd)
|
||||
hdrsz = ehdr->e_phoff + ehdr->e_phentsize * ehdr->e_phnum;
|
||||
if (_kvm_maphdrs(kd, hdrsz) == -1)
|
||||
return (-1);
|
||||
nl[0].n_name = "kernbase";
|
||||
nl[1].n_name = NULL;
|
||||
if (kvm_nlist(kd, nl) != 0)
|
||||
kernbase = KERNBASE;
|
||||
else
|
||||
kernbase = nl[0].n_value;
|
||||
|
||||
nl[0].n_name = "physaddr";
|
||||
if (kvm_nlist(kd, nl) != 0) {
|
||||
_kvm_err(kd, kd->program, "couldn't get phys addr");
|
||||
return (-1);
|
||||
phdr = (Elf32_Phdr *)((uint8_t *)ehdr + ehdr->e_phoff);
|
||||
found = 0;
|
||||
for (i = 0; i < ehdr->e_phnum; i++) {
|
||||
if (phdr[i].p_type == PT_DUMP_DELTA) {
|
||||
kernbase = phdr[i].p_vaddr;
|
||||
physaddr = phdr[i].p_paddr;
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nl[1].n_name = NULL;
|
||||
if (!found) {
|
||||
nl[0].n_name = "kernbase";
|
||||
if (kvm_nlist(kd, nl) != 0)
|
||||
kernbase = KERNBASE;
|
||||
else
|
||||
kernbase = nl[0].n_value;
|
||||
|
||||
nl[0].n_name = "physaddr";
|
||||
if (kvm_nlist(kd, nl) != 0) {
|
||||
_kvm_err(kd, kd->program, "couldn't get phys addr");
|
||||
return (-1);
|
||||
}
|
||||
physaddr = nl[0].n_value;
|
||||
}
|
||||
physaddr = nl[0].n_value;
|
||||
nl[0].n_name = "kernel_l1pa";
|
||||
if (kvm_nlist(kd, nl) != 0) {
|
||||
_kvm_err(kd, kd->program, "bad namelist");
|
||||
|
@ -245,6 +245,29 @@ cb_dumphdr(struct md_pa *mdp, int seqnr, void *arg)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a header to be used by libkvm to get the va to pa delta
|
||||
*/
|
||||
static int
|
||||
dump_os_header(struct dumperinfo *di)
|
||||
{
|
||||
Elf_Phdr phdr;
|
||||
int error;
|
||||
|
||||
bzero(&phdr, sizeof(phdr));
|
||||
phdr.p_type = PT_DUMP_DELTA;
|
||||
phdr.p_flags = PF_R; /* XXX */
|
||||
phdr.p_offset = 0;
|
||||
phdr.p_vaddr = KERNVIRTADDR;
|
||||
phdr.p_paddr = pmap_kextract(KERNVIRTADDR);
|
||||
phdr.p_filesz = 0;
|
||||
phdr.p_memsz = 0;
|
||||
phdr.p_align = PAGE_SIZE;
|
||||
|
||||
error = buf_write(di, (char*)&phdr, sizeof(phdr));
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
cb_size(struct md_pa *mdp, int seqnr, void *arg)
|
||||
{
|
||||
@ -308,7 +331,7 @@ dumpsys(struct dumperinfo *di)
|
||||
|
||||
/* Calculate dump size. */
|
||||
dumpsize = 0L;
|
||||
ehdr.e_phnum = foreach_chunk(cb_size, &dumpsize);
|
||||
ehdr.e_phnum = foreach_chunk(cb_size, &dumpsize) + 1;
|
||||
hdrsz = ehdr.e_phoff + ehdr.e_phnum * ehdr.e_phentsize;
|
||||
fileofs = MD_ALIGN(hdrsz);
|
||||
dumpsize += fileofs;
|
||||
@ -325,7 +348,7 @@ dumpsys(struct dumperinfo *di)
|
||||
mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_ARM_VERSION, dumpsize, di->blocksize);
|
||||
|
||||
printf("Dumping %llu MB (%d chunks)\n", (long long)dumpsize >> 20,
|
||||
ehdr.e_phnum);
|
||||
ehdr.e_phnum - 1);
|
||||
|
||||
/* Dump leader */
|
||||
error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh));
|
||||
@ -340,6 +363,8 @@ dumpsys(struct dumperinfo *di)
|
||||
|
||||
/* Dump program headers */
|
||||
error = foreach_chunk(cb_dumphdr, di);
|
||||
if (error >= 0)
|
||||
error = dump_os_header(di);
|
||||
if (error < 0)
|
||||
goto fail;
|
||||
buf_flush(di);
|
||||
|
@ -340,6 +340,8 @@ typedef struct {
|
||||
#define PT_GNU_EH_FRAME 0x6474e550
|
||||
#define PT_GNU_STACK 0x6474e551
|
||||
#define PT_GNU_RELRO 0x6474e552
|
||||
#define PT_DUMP_DELTA 0x6fb5d000 /* va->pa map for kernel dumps
|
||||
(currently arm). */
|
||||
#define PT_LOSUNW 0x6ffffffa
|
||||
#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
|
||||
#define PT_SUNWSTACK 0x6ffffffb /* describes the stack segment */
|
||||
|
Loading…
Reference in New Issue
Block a user