libexec: return physaddr info from ELF headers
This commit is contained in:
parent
b2c2dc72bc
commit
cd9b4b46f4
@ -18,13 +18,14 @@ static int __elfN(check_header)(const Elf_Ehdr *hdr);
|
|||||||
|
|
||||||
int read_header_elf(
|
int read_header_elf(
|
||||||
const char *exec_hdr, /* executable header */
|
const char *exec_hdr, /* executable header */
|
||||||
vir_bytes *text_addr, /* text virtual address */
|
vir_bytes *text_vaddr, /* text virtual address */
|
||||||
|
phys_bytes *text_paddr, /* text physical address */
|
||||||
vir_bytes *text_filebytes, /* text segment size (in the file) */
|
vir_bytes *text_filebytes, /* text segment size (in the file) */
|
||||||
vir_bytes *text_membytes, /* text segment size (in memory) */
|
vir_bytes *text_membytes, /* text segment size (in memory) */
|
||||||
vir_bytes *data_addr, /* data virtual address */
|
vir_bytes *data_vaddr, /* data virtual address */
|
||||||
|
phys_bytes *data_paddr, /* data physical address */
|
||||||
vir_bytes *data_filebytes, /* data segment size (in the file) */
|
vir_bytes *data_filebytes, /* data segment size (in the file) */
|
||||||
vir_bytes *data_membytes, /* data segment size (in memory) */
|
vir_bytes *data_membytes, /* data segment size (in memory) */
|
||||||
phys_bytes *tot_bytes, /* total size */
|
|
||||||
vir_bytes *pc, /* program entry point (initial PC) */
|
vir_bytes *pc, /* program entry point (initial PC) */
|
||||||
off_t *text_offset, /* file offset to text segment */
|
off_t *text_offset, /* file offset to text segment */
|
||||||
off_t *data_offset /* file offset to data segment */
|
off_t *data_offset /* file offset to data segment */
|
||||||
@ -32,14 +33,16 @@ int read_header_elf(
|
|||||||
{
|
{
|
||||||
const Elf_Ehdr *hdr = NULL;
|
const Elf_Ehdr *hdr = NULL;
|
||||||
const Elf_Phdr *phdr = NULL;
|
const Elf_Phdr *phdr = NULL;
|
||||||
unsigned long seg_filebytes, seg_membytes, seg_addr;
|
unsigned long seg_filebytes, seg_membytes;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
assert(exec_hdr != NULL);
|
assert(exec_hdr != NULL);
|
||||||
|
|
||||||
*text_addr = *text_filebytes = *text_membytes = 0;
|
*text_vaddr = *text_paddr = 0;
|
||||||
*data_addr = *data_filebytes = *data_membytes = 0;
|
*text_filebytes = *text_membytes = 0;
|
||||||
*tot_bytes = *pc = *text_offset = *data_offset = 0;
|
*data_vaddr = *data_paddr = 0;
|
||||||
|
*data_filebytes = *data_membytes = 0;
|
||||||
|
*pc = *text_offset = *data_offset = 0;
|
||||||
|
|
||||||
hdr = (const Elf_Ehdr *)exec_hdr;
|
hdr = (const Elf_Ehdr *)exec_hdr;
|
||||||
if (__elfN(check_header)(hdr) != OK || (hdr->e_type != ET_EXEC))
|
if (__elfN(check_header)(hdr) != OK || (hdr->e_type != ET_EXEC))
|
||||||
@ -73,20 +76,21 @@ int read_header_elf(
|
|||||||
case PT_LOAD:
|
case PT_LOAD:
|
||||||
if (phdr[i].p_memsz == 0)
|
if (phdr[i].p_memsz == 0)
|
||||||
break;
|
break;
|
||||||
seg_addr = phdr[i].p_vaddr;
|
|
||||||
seg_filebytes = phdr[i].p_filesz;
|
seg_filebytes = phdr[i].p_filesz;
|
||||||
seg_membytes = round_page(phdr[i].p_memsz + phdr[i].p_vaddr -
|
seg_membytes = round_page(phdr[i].p_memsz + phdr[i].p_vaddr -
|
||||||
trunc_page(phdr[i].p_vaddr));
|
trunc_page(phdr[i].p_vaddr));
|
||||||
|
|
||||||
if (hdr->e_entry >= phdr[i].p_vaddr &&
|
if (hdr->e_entry >= phdr[i].p_vaddr &&
|
||||||
hdr->e_entry < (phdr[i].p_vaddr + phdr[i].p_memsz)) {
|
hdr->e_entry < (phdr[i].p_vaddr + phdr[i].p_memsz)) {
|
||||||
*text_addr = seg_addr;
|
*text_vaddr = phdr[i].p_vaddr;
|
||||||
|
*text_paddr = phdr[i].p_paddr;
|
||||||
*text_filebytes = seg_filebytes;
|
*text_filebytes = seg_filebytes;
|
||||||
*text_membytes = seg_membytes;
|
*text_membytes = seg_membytes;
|
||||||
*pc = (vir_bytes)hdr->e_entry;
|
*pc = (vir_bytes)hdr->e_entry;
|
||||||
*text_offset = phdr[i].p_offset;
|
*text_offset = phdr[i].p_offset;
|
||||||
} else {
|
} else {
|
||||||
*data_addr = seg_addr;
|
*data_vaddr = phdr[i].p_vaddr;
|
||||||
|
*data_paddr = phdr[i].p_paddr;
|
||||||
*data_filebytes = seg_filebytes;
|
*data_filebytes = seg_filebytes;
|
||||||
*data_membytes = seg_membytes;
|
*data_membytes = seg_membytes;
|
||||||
*data_offset = phdr[i].p_offset;
|
*data_offset = phdr[i].p_offset;
|
||||||
@ -97,13 +101,13 @@ int read_header_elf(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*tot_bytes = 0; /* Use default stack size */
|
|
||||||
|
|
||||||
#if ELF_DEBUG
|
#if ELF_DEBUG
|
||||||
printf("Text addr: 0x%x\n", *text_addr);
|
printf("Text vaddr: 0x%x\n", *text_vaddr);
|
||||||
|
printf("Text paddr: 0x%x\n", *text_paddr);
|
||||||
printf("Text filebytes: 0x%x\n", *text_filebytes);
|
printf("Text filebytes: 0x%x\n", *text_filebytes);
|
||||||
printf("Text membytes: 0x%x\n", *text_membytes);
|
printf("Text membytes: 0x%x\n", *text_membytes);
|
||||||
printf("Data addr: 0x%x\n", *data_addr);
|
printf("Data vaddr: 0x%x\n", *data_vaddr);
|
||||||
|
printf("Data paddr: 0x%x\n", *data_paddr);
|
||||||
printf("Data filebyte: 0x%x\n", *data_filebytes);
|
printf("Data filebyte: 0x%x\n", *data_filebytes);
|
||||||
printf("Data membytes: 0x%x\n", *data_membytes);
|
printf("Data membytes: 0x%x\n", *data_membytes);
|
||||||
printf("Tot bytes: 0x%x\n", *tot_bytes);
|
printf("Tot bytes: 0x%x\n", *tot_bytes);
|
||||||
|
@ -11,8 +11,10 @@ int read_header_aout(const char *exec_hdr, size_t exec_len, int *sep_id,
|
|||||||
|
|
||||||
/* ELF routines */
|
/* ELF routines */
|
||||||
int read_header_elf(const char *exec_hdr,
|
int read_header_elf(const char *exec_hdr,
|
||||||
vir_bytes *text_addr, vir_bytes *text_filebytes, vir_bytes *text_membytes,
|
vir_bytes *text_vaddr, phys_bytes *text_paddr,
|
||||||
vir_bytes *data_addr, vir_bytes *data_filebytes, vir_bytes *data_membytes,
|
vir_bytes *text_filebytes, vir_bytes *text_membytes,
|
||||||
phys_bytes *tot_bytes, vir_bytes *pc, off_t *text_offset, off_t *data_offset);
|
vir_bytes *data_vaddr, phys_bytes *data_paddr,
|
||||||
|
vir_bytes *data_filebytes, vir_bytes *data_membytes,
|
||||||
|
vir_bytes *pc, off_t *text_offset, off_t *data_offset);
|
||||||
|
|
||||||
#endif /* !_LIBEXEC_H_ */
|
#endif /* !_LIBEXEC_H_ */
|
||||||
|
@ -239,8 +239,8 @@ static int load_elf(struct exec_info *execi)
|
|||||||
int r;
|
int r;
|
||||||
int proc_e;
|
int proc_e;
|
||||||
phys_bytes tot_bytes; /* total space for program, including gap */
|
phys_bytes tot_bytes; /* total space for program, including gap */
|
||||||
vir_bytes text_addr, text_filebytes, text_membytes;
|
vir_bytes text_vaddr, text_paddr, text_filebytes, text_membytes;
|
||||||
vir_bytes data_addr, data_filebytes, data_membytes;
|
vir_bytes data_vaddr, data_paddr, data_filebytes, data_membytes;
|
||||||
off_t text_offset, data_offset;
|
off_t text_offset, data_offset;
|
||||||
int sep_id, is_elf, load_text, allow_setuid;
|
int sep_id, is_elf, load_text, allow_setuid;
|
||||||
uid_t new_uid;
|
uid_t new_uid;
|
||||||
@ -252,9 +252,11 @@ static int load_elf(struct exec_info *execi)
|
|||||||
proc_e = execi->proc_e;
|
proc_e = execi->proc_e;
|
||||||
|
|
||||||
/* Read the file header and extract the segment sizes. */
|
/* Read the file header and extract the segment sizes. */
|
||||||
r = read_header_elf(execi->image, &text_addr, &text_filebytes, &text_membytes,
|
r = read_header_elf(execi->image, &text_vaddr, &text_paddr,
|
||||||
&data_addr, &data_filebytes, &data_membytes,
|
&text_filebytes, &text_membytes,
|
||||||
&tot_bytes, &execi->pc, &text_offset, &data_offset);
|
&data_vaddr, &data_paddr,
|
||||||
|
&data_filebytes, &data_membytes,
|
||||||
|
&execi->pc, &text_offset, &data_offset);
|
||||||
if (r != OK) {
|
if (r != OK) {
|
||||||
return(r);
|
return(r);
|
||||||
}
|
}
|
||||||
@ -264,10 +266,11 @@ static int load_elf(struct exec_info *execi)
|
|||||||
|
|
||||||
sep_id = 1;
|
sep_id = 1;
|
||||||
is_elf = 1;
|
is_elf = 1;
|
||||||
|
tot_bytes = 0; /* Use default stack size */
|
||||||
|
|
||||||
r = exec_newmem(proc_e,
|
r = exec_newmem(proc_e,
|
||||||
trunc_page(text_addr), text_membytes,
|
trunc_page(text_vaddr), text_membytes,
|
||||||
trunc_page(data_addr), data_membytes,
|
trunc_page(data_vaddr), data_membytes,
|
||||||
tot_bytes, execi->frame_len, sep_id, is_elf,
|
tot_bytes, execi->frame_len, sep_id, is_elf,
|
||||||
0 /*dev*/, proc_e /*inum*/, 0 /*ctime*/,
|
0 /*dev*/, proc_e /*inum*/, 0 /*ctime*/,
|
||||||
execi->progname, new_uid, new_gid,
|
execi->progname, new_uid, new_gid,
|
||||||
@ -281,7 +284,7 @@ static int load_elf(struct exec_info *execi)
|
|||||||
|
|
||||||
/* Read in text and data segments. */
|
/* Read in text and data segments. */
|
||||||
if (load_text) {
|
if (load_text) {
|
||||||
r = read_seg(execi, text_offset, proc_e, T, text_addr, text_filebytes);
|
r = read_seg(execi, text_offset, proc_e, T, text_vaddr, text_filebytes);
|
||||||
if (r != OK)
|
if (r != OK)
|
||||||
{
|
{
|
||||||
printf("RS: load_elf: read_seg failed: %d\n", r);
|
printf("RS: load_elf: read_seg failed: %d\n", r);
|
||||||
@ -292,7 +295,7 @@ static int load_elf(struct exec_info *execi)
|
|||||||
else
|
else
|
||||||
printf("RS: load_elf: not loading text segment\n");
|
printf("RS: load_elf: not loading text segment\n");
|
||||||
|
|
||||||
r = read_seg(execi, data_offset, proc_e, D, data_addr, data_filebytes);
|
r = read_seg(execi, data_offset, proc_e, D, data_vaddr, data_filebytes);
|
||||||
if (r != OK)
|
if (r != OK)
|
||||||
{
|
{
|
||||||
printf("RS: load_elf: read_seg failed: %d\n", r);
|
printf("RS: load_elf: read_seg failed: %d\n", r);
|
||||||
|
@ -258,8 +258,8 @@ static int load_elf(struct exec_info *execi)
|
|||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
int proc_e;
|
int proc_e;
|
||||||
phys_bytes tot_bytes; /* total space for program, including gap */
|
phys_bytes tot_bytes; /* total space for program, including gap */
|
||||||
vir_bytes text_addr, text_filebytes, text_membytes;
|
vir_bytes text_vaddr, text_paddr, text_filebytes, text_membytes;
|
||||||
vir_bytes data_addr, data_filebytes, data_membytes;
|
vir_bytes data_vaddr, data_paddr, data_filebytes, data_membytes;
|
||||||
off_t text_offset, data_offset;
|
off_t text_offset, data_offset;
|
||||||
int sep_id, is_elf;
|
int sep_id, is_elf;
|
||||||
|
|
||||||
@ -271,16 +271,19 @@ static int load_elf(struct exec_info *execi)
|
|||||||
vp = execi->vp;
|
vp = execi->vp;
|
||||||
|
|
||||||
/* Read the file header and extract the segment sizes. */
|
/* Read the file header and extract the segment sizes. */
|
||||||
r = read_header_elf(execi->hdr, &text_addr, &text_filebytes, &text_membytes,
|
r = read_header_elf(execi->hdr, &text_vaddr, &text_paddr,
|
||||||
&data_addr, &data_filebytes, &data_membytes,
|
&text_filebytes, &text_membytes,
|
||||||
&tot_bytes, &execi->pc, &text_offset, &data_offset);
|
&data_vaddr, &data_paddr,
|
||||||
|
&data_filebytes, &data_membytes,
|
||||||
|
&execi->pc, &text_offset, &data_offset);
|
||||||
if (r != OK) return(r);
|
if (r != OK) return(r);
|
||||||
|
|
||||||
sep_id = 1;
|
sep_id = 1;
|
||||||
is_elf = 1;
|
is_elf = 1;
|
||||||
|
tot_bytes = 0; /* Use default stack size */
|
||||||
r = exec_newmem(proc_e,
|
r = exec_newmem(proc_e,
|
||||||
trunc_page(text_addr), text_membytes,
|
trunc_page(text_vaddr), text_membytes,
|
||||||
trunc_page(data_addr), data_membytes,
|
trunc_page(data_vaddr), data_membytes,
|
||||||
tot_bytes, execi->frame_len, sep_id, is_elf,
|
tot_bytes, execi->frame_len, sep_id, is_elf,
|
||||||
vp->v_dev, vp->v_inode_nr, execi->sb.st_ctime,
|
vp->v_dev, vp->v_inode_nr, execi->sb.st_ctime,
|
||||||
execi->progname, execi->new_uid, execi->new_gid,
|
execi->progname, execi->new_uid, execi->new_gid,
|
||||||
@ -293,10 +296,10 @@ static int load_elf(struct exec_info *execi)
|
|||||||
|
|
||||||
/* Read in text and data segments. */
|
/* Read in text and data segments. */
|
||||||
if (execi->load_text)
|
if (execi->load_text)
|
||||||
r = read_seg(vp, text_offset, proc_e, T, text_addr, text_filebytes);
|
r = read_seg(vp, text_offset, proc_e, T, text_vaddr, text_filebytes);
|
||||||
|
|
||||||
if (r == OK)
|
if (r == OK)
|
||||||
r = read_seg(vp, data_offset, proc_e, D, data_addr, data_filebytes);
|
r = read_seg(vp, data_offset, proc_e, D, data_vaddr, data_filebytes);
|
||||||
|
|
||||||
if (r != OK) {
|
if (r != OK) {
|
||||||
printf("VFS: load_elf: read_seg failed: %d\n", r);
|
printf("VFS: load_elf: read_seg failed: %d\n", r);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user