/**Copyright(c)1993,DavidGreenman*Allrightsreserved.**Redistributionanduseinsourceandbinaryforms,withorwithout*modification,arepermittedprovidedt
hatthefollowingconditions*aremet:*1.Redistributionsofsourcecodemustretaintheabovecopyright*notice,thislistofconditionsandthefollowingdisclaimer.*
2.Redistributionsinbinaryformmustreproducetheabovecopyright*notice,thislistofconditionsandthefollowingdisclaimerinthe*documentationand/orothermat
erialsprovidedwiththedistribution.**THISSOFTWAREISPROVIDEDBYTHEAUTHORANDCONTRIBUTORS``ASIS''AND*ANYEXPRESSORIMPLIEDWARRANTIES,INCLUDING,BUTNOTLIM
ITEDTO,THE*IMPLIEDWARRANTIESOFMERCHANTABILITYANDFITNESSFORAPARTICULARPURPOSE*AREDISCLAIMED.INNOEVENTSHALLTHEAUTHORORCONTRIBUTORSBELIABLE*FORANYDI
RECT,INDIRECT,INCIDENTAL,SPECIAL,EXEMPLARY,ORCONSEQUENTIAL*DAMAGES(INCLUDING,BUTNOTLIMITEDTO,PROCUREMENTOFSUBSTITUTEGOODS*ORSERVICES;LOSSOFUSE,DA
TA,ORPROFITS;ORBUSINESSINTERRUPTION)*HOWEVERCAUSEDANDONANYTHEORYOFLIABILITY,WHETHERINCONTRACT,STRICT*LIABILITY,ORTORT(INCLUDINGNEGLIGENCEOROTHERW
ISE)ARISINGINANYWAY*OUTOFTHEUSEOFTHISSOFTWARE,EVENIFADVISEDOFTHEPOSSIBILITYOF*SUCHDAMAGE.**$FreeBSD:src/sys/kern/imgact_aout.c,v1.44.2.41999/09/0
106:12:00sefExp$*/#include<sys/param.h>#include<sys/acct.h>#include<sys/resourcevar.h>#include<sys/exec.h>#include<sys/fcntl.h>#include<sys/imgac
t.h>#include<sys/imgact_aout.h>#include<sys/kernel.h>#include<sys/malloc.h>#include<sys/namei.h>#include<sys/pioctl.h>#include<sys/proc.h>#includ
e<sys/signalvar.h>#include<sys/stat.h>#include<sys/sysent.h>#include<sys/syscall.h>#include<sys/vnode.h>#include<sys/systm.h>#include<machine/md_
var.h>#include<vm/vm.h>#include<vm/vm_param.h>#include<vm/vm_prot.h>#include<sys/lock.h>#include<vm/pmap.h>#include<vm/vm_map.h>#include<vm/vm_ob
ject.h>#include<sys/user.h>staticintexec_aout_imgact__P((structimage_params*imgp));structsysentvecaout_sysvec={SYS_MAXSYSCALL,sysent,0,0,0,0,0,0,
0,sendsig,sigcode,&szsigcode,0,"FreeBSDa.out",aout_coredump};staticintexec_aout_imgact(imgp)structimage_params*imgp;{conststructexec*a_out=(const
structexec*)imgp->image_header;structvmspace*vmspace;structvnode*vp;vm_object_tobject;vm_offset_ttext_end,data_end;unsignedlongvirtual_offset;uns
ignedlongfile_offset;unsignedlongbss_size;interror;/**Linuxand*BSDbinarieslookverymuchalike,*onlythemachineidisdifferent:*0x64forLinux,0x86for*BS
D,0x00forBSDI.*NetBSDisinnetworkbyteorder..ugh.*/if(((a_out->a_magic>>16)&0xff)!=0x86&&((a_out->a_magic>>16)&0xff)!=0&&((((int)ntohl(a_out->a_mag
ic))>>16)&0xff)!=0x86)return-1;/**Setfile/virtualoffsetbasedona.outvariant.*Wedotwocases:hostbyteorderandnetworkbyteorder*(forNetBSDcompatibility
)*/switch((int)(a_out->a_magic&0xffff)){caseZMAGIC:virtual_offset=0;if(a_out->a_text){file_offset=PAGE_SIZE;}else{/*Bill's"screwballmode"*/file_o
ffset=0;}break;caseQMAGIC:virtual_offset=PAGE_SIZE;file_offset=0;/*PassPS_STRINGSforBSD/OSbinariesonly.*/if(N_GETMID(*a_out)==MID_ZERO)imgp->ps_s
trings=PS_STRINGS;break;default:/*NetBSDcompatibility*/switch((int)(ntohl(a_out->a_magic)&0xffff)){caseZMAGIC:caseQMAGIC:virtual_offset=PAGE_SIZE
;file_offset=0;break;default:return(-1);}}bss_size=roundup(a_out->a_bss,PAGE_SIZE);/**Checkvariousfieldsinheaderforvalidity/bounds.*/if(/*entrypo
intmustlaywithtextregion*/a_out->a_entry<virtual_offset||a_out->a_entry>=virtual_offset+a_out->a_text||/*textanddatasizemusteachbepagerounded*/a_
out->a_text&PAGE_MASK||a_out->a_data&PAGE_MASK)return(-1);/*text+datacan'texceedfilesize*/if(a_out->a_data+a_out->a_text>imgp->attr->va_size)retu
rn(EFAULT);/**text/data/bssmustnotexceedlimits*/if(/*textcan'texceedmaximumtextsize*/a_out->a_text>MAXTSIZ||/*data+bsscan'texceedrlimit*/a_out->a
_data+bss_size>imgp->proc->p_rlimit[RLIMIT_DATA].rlim_cur)return(ENOMEM);/*copyinargumentsand/orenvironmentfromoldprocess*/error=exec_extract_str
ings(imgp);if(error)return(error);/**DestroyoldprocessVMandcreateanewone(withanewstack)*/exec_new_vmspace(imgp);/**Thevmspacecanbechangedbyexec_n
ew_vmspace*/vmspace=imgp->proc->p_vmspace;vp=imgp->vp;object=vp->v_object;vm_object_reference(object);text_end=virtual_offset+a_out->a_text;error
=vm_map_insert(&vmspace->vm_map,object,file_offset,virtual_offset,text_end,VM_PROT_READ|VM_PROT_EXECUTE,VM_PROT_ALL,MAP_COPY_NEEDED|MAP_COPY_ON_W
RITE);if(error)return(error);data_end=text_end+a_out->a_data;if(a_out->a_data){vm_object_reference(object);error=vm_map_insert(&vmspace->vm_map,o
bject,file_offset+a_out->a_text,text_end,data_end,VM_PROT_ALL,VM_PROT_ALL,MAP_COPY_NEEDED|MAP_COPY_ON_WRITE);if(error)return(error);}pmap_object_
init_pt(&vmspace->vm_pmap,virtual_offset,object,(vm_pindex_t)OFF_TO_IDX(file_offset),a_out->a_text+a_out->a_data,0);if(bss_size){error=vm_map_ins
ert(&vmspace->vm_map,NULL,0,data_end,data_end+bss_size,VM_PROT_ALL,VM_PROT_ALL,0);if(error)return(error);}/*FillinprocessVMinformation*/vmspace->
vm_tsize=a_out->a_text>>PAGE_SHIFT;vmspace->vm_dsize=(a_out->a_data+bss_size)>>PAGE_SHIFT;vmspace->vm_taddr=(caddr_t)(uintptr_t)virtual_offset;vm
space->vm_daddr=(caddr_t)(uintptr_t)(virtual_offset+a_out->a_text);/*Fillinimage_params*/imgp->interpreted=0;imgp->entry_addr=a_out->a_entry;imgp
->proc->p_sysent=&aout_sysvec;/*Indicatethatthisfileshouldnotbemodified*/imgp->vp->v_flag|=VTEXT;return(0);}/**Dumpcore,intoafilenamedasdescribed
inthecommentsfor*expand_name(),unlesstheprocesswassetuid/setgid.*/intaout_coredump(p,vp,limit)registerstructproc*p;registerstructvnode*vp;off_tli
mit;{registerstructucred*cred=p->p_cred->pc_ucred;registerstructvmspace*vm=p->p_vmspace;interror=0;if(ctob(UPAGES+vm->vm_dsize+vm->vm_ssize)>=lim
it)return(EFAULT);bcopy(p,&p->p_addr->u_kproc.kp_proc,sizeof(structproc));fill_eproc(p,&p->p_addr->u_kproc.kp_eproc);error=cpu_coredump(p,vp,cred
);if(error==0)error=vn_rdwr(UIO_WRITE,vp,vm->vm_daddr,(int)ctob(vm->vm_dsize),(off_t)ctob(UPAGES),UIO_USERSPACE,IO_NODELOCKED|IO_UNIT,cred,(int*)
NULL,p);if(error==0)error=vn_rdwr(UIO_WRITE,vp,(caddr_t)trunc_page(USRSTACK-ctob(vm->vm_ssize)),round_page(ctob(vm->vm_ssize)),(off_t)ctob(UPAGES
)+ctob(vm->vm_dsize),UIO_USERSPACE,IO_NODELOCKED|IO_UNIT,cred,(int*)NULL,p);returnerror;}/**Tellkern_execve.caboutit,withalittlehelpfromthelinker
.*Since`const'objectsendupinthetextsegment,TEXT_SETisthe*correctdirectivetouse.*/staticconststructexecswaout_execsw={exec_aout_imgact,"a.out"};EX
EC_SET(aout,aout_execsw);/*-*Copyright(c)1995-1996SrenSchmidt*Copyright(c)1996PeterWemm*Allrightsreserved.**Redistributionanduseinsourceandbinar
yforms,withorwithout*modification,arepermittedprovidedthatthefollowingconditions*aremet:*1.Redistributionsofsourcecodemustretaintheabovecopyright
*notice,thislistofconditionsandthefollowingdisclaimer*inthispositionandunchanged.*2.Redistributionsinbinaryformmustreproducetheabovecopyright*not
ice,thislistofconditionsandthefollowingdisclaimerinthe*documentationand/orothermaterialsprovidedwiththedistribution.*3.Thenameoftheauthormaynotbe
usedtoendorseorpromoteproducts*derivedfromthissoftwarewithoughspecificpriorwrittenpermission**THISSOFTWAREISPROVIDEDBYTHEAUTHOR``ASIS''ANDANYEXPR
ESSOR*IMPLIEDWARRANTIES,INCLUDING,BUTNOTLIMITEDTO,THEIMPLIEDWARRANTIES*OFMERCHANTABILITYANDFITNESSFORAPARTICULARPURPOSEAREDISCLAIMED.*INNOEVENTSH
ALLTHEAUTHORBELIABLEFORANYDIRECT,INDIRECT,*INCIDENTAL,SPECIAL,EXEMPLARY,ORCONSEQUENTIALDAMAGES(INCLUDING,BUT*NOTLIMITEDTO,PROCUREMENTOFSUBSTITUTE
GOODSORSERVICES;LOSSOFUSE,*DATA,ORPROFITS;ORBUSINESSINTERRUPTION)HOWEVERCAUSEDANDONANY*THEORYOFLIABILITY,WHETHERINCONTRACT,STRICTLIABILITY,ORTORT
*(INCLUDINGNEGLIGENCEOROTHERWISE)ARISINGINANYWAYOUTOFTHEUSEOF*THISSOFTWARE,EVENIFADVISEDOFTHEPOSSIBILITYOFSUCHDAMAGE.**$FreeBSD:src/sys/kern/imga
ct_elf.c,v1.44.2.71999/09/0106:12:01sefExp$*/#include"opt_rlimit.h"#include<sys/param.h>#include<sys/acct.h>#include<sys/exec.h>#include<sys/fcnt
l.h>#include<sys/imgact.h>#include<sys/imgact_elf.h>#include<sys/kernel.h>#include<sys/malloc.h>#include<sys/mman.h>#include<sys/namei.h>#include
<sys/pioctl.h>#include<sys/proc.h>#include<sys/procfs.h>#include<sys/resourcevar.h>#include<sys/signalvar.h>#include<sys/stat.h>#include<sys/sysc
all.h>#include<sys/sysctl.h>#include<sys/sysent.h>#include<sys/systm.h>#include<sys/vnode.h>#include<vm/vm.h>#include<vm/vm_kern.h>#include<vm/vm
_param.h>#include<vm/pmap.h>#include<sys/lock.h>#include<vm/vm_map.h>#include<vm/vm_object.h>#include<vm/vm_prot.h>#include<vm/vm_extern.h>#inclu
de<machine/elf.h>#include<machine/md_var.h>__ElfType(Brandinfo);__ElfType(Auxargs);staticintelf_check_header__P((constElf_Ehdr*hdr,inttype));stat
icintelf_freebsd_fixup__P((long**stack_base,structimage_params*imgp));staticintelf_load_file__P((structproc*p,constchar*file,u_long*addr,u_long*e
ntry));staticintelf_load_section__P((structproc*p,structvmspace*vmspace,structvnode*vp,vm_offset_toffset,caddr_tvmaddr,size_tmemsz,size_tfilsz,vm
_prot_tprot));staticintexec_elf_imgact__P((structimage_params*imgp));staticintelf_trace=0;SYSCTL_INT(_debug,OID_AUTO,elf_trace,CTLFLAG_RW,&elf_tr
ace,0,"");staticstructsysentvecelf_freebsd_sysvec={SYS_MAXSYSCALL,sysent,0,0,0,0,0,0,elf_freebsd_fixup,sendsig,sigcode,&szsigcode,0,"FreeBSDELF",
elf_coredump};staticElf_Brandinfofreebsd_brand_info={"FreeBSD","","/usr/libexec/ld-elf.so.1",&elf_freebsd_sysvec};staticElf_Brandinfo*elf_brand_l
ist[MAX_BRANDS]={&freebsd_brand_info,NULL,NULL,NULL,NULL,NULL,NULL,NULL};intelf_insert_brand_entry(Elf_Brandinfo*entry){inti;for(i=1;i<MAX_BRANDS
;i++){if(elf_brand_list[i]==NULL){elf_brand_list[i]=entry;break;}}if(i==MAX_BRANDS)return-1;return0;}intelf_remove_brand_entry(Elf_Brandinfo*entr
y){inti;for(i=1;i<MAX_BRANDS;i++){if(elf_brand_list[i]==entry){el_brand_list[i]=NULL;break;}}if(i==MAX_BRANDS)return-1;return0;}intelf_brand_inu
se(Elf_Brandinfo*entry){structproc*p;for(p=allproc.lh_first;p!=0;=p->p_list.le_next){if(p->p_sysent==entry->sysvec)returnTRUE;}returnFALSE;}stat
icintelf_check_header(constElf_Ehdr*hdr,inttype){if(!IS_ELF(*hdr)|hdr->e_ident[EI_CLASS]!=ELF_TARG_CLASS||hdr->e_ident[EI_DATA]!=ELF_TARG_DATA||
hdr->e_ident[EI_VERSION]!=EV_CURRENT)returnENOEXEC;if(!ELF_MACHINE_OK(hdr->e_machine))returnENOEXEC;if(hdr->e_type!=type||hdr->e_version!=ELF_TAR
G_VER)returnENOEXEC;return0;}staticintelf_load_section(structproc*p,structvmspace*vmspace,structvnode*vp,vm_offset_toffset,caddr_tvmaddr,size_tme
msz,size_tfilsz,vm_prot_tprot){size_tmap_len;vm_offset_tmap_addr;interror,rv;size_tcopy_len;vm_object_tobject;vm_offset_tfile_addr;vm_offset_tdat
a_buf=0;object=vp->v_object;error=0;map_addr=trunc_page((vm_offset_t)vmaddr);file_addr=trunc_page(offset);/**Wehavetwochoices.Wecaneitherclearthe
datainthelastpage*ofanoversizedmapping,orwecanstarttheanonmappingapage*earlyandcopytheinitializeddataintothatfirstpage.We*choosethesecond..*/if(m
emsz>filsz)map_len=trunc_page(offset+filsz)-file_addr;elsemap_len=round_page(offset+filsz)-file_addr;if(map_len!=0){vm_object_reference(object);v
m_map_lock(&vmspace->vm_map);rv=vm_map_insert(&vmspace->vm_map,object,file_addr,/*fileoffset*/map_addr,/*virtualstart*/map_addr+map_len,/*virtual
end*/prot,VM_PROT_ALL,MAP_COPY_NEEDED|MAP_COPY_ON_WRITE);vm_map_unlock(&vmspace->vm_map);if(rv!=KERN_SUCCESS)returnEINVAL;/*prefaultthepagetables
*/pmap_object_init_pt(&vmspace->vm_pmap,map_addr,object,(vm_pindex_t)OFF_TO_IDX(file_addr),map_len,0);/*wecanstopnowifwe'vecovereditall*/if(memsz
==filsz)return0;}/**Wehavetogettheremainingbitofthefileintothefirstpart*oftheoversizedmapsegment.Thisisnormallybecausethe.data*segmentinthefileis
extendedtoprovidebss.It'saneatidea*totryandsaveapage,butit'sapaininthebehindtoimplement.*/copy_len=(offset+filsz)-trunc_page(offset+filsz);map_ad
dr=trunc_page((vm_offset_t)vmaddr+filsz);map_len=round_page((vm_offset_t)vmaddr+memsz)-map_addr;/*Thishaddamnwellbetterbetrue!*/if(map_len!=0){vm
_map_lock(&vmspace->vm_map);rv=vm_map_insert(&vmspace->vm_map,NULL,0,map_addr,map_addr+map_len,VM_PROT_ALL,VM_PROT_ALL,0);vm_map_unlock(&vmspace-
>vm_map);if(rv!=KERN_SUCCESS)returnEINVAL;}if(copy_len!=0){vm_object_reference(object);rv=vm_map_find(exec_map,object,trunc_page(offset+filsz),&d
ata_buf,PAGE_SIZE,TRUE,VM_PROT_READ,VM_PROT_ALL,MAP_COPY_ON_WRITE|MAP_COPY_NEEDED);if(rv!=KERN_SUCCESS){vm_object_deallocate(object);returnEINVAL
;}pmap_object_init_pt(exec_map->pmap,data_buf,object,(vm_pindex_t)OFF_TO_IDX(trunc_page(offset+filsz)),PAGE_SIZE,1);/*sendthepagefragmenttousersp
ace*/error=copyout((caddr_t)data_buf,(caddr_t)map_addr,copy_len);vm_map_remove(exec_map,data_buf,data_buf+PAGE_SIZE);if(error)return(error);}/**s
etittothespecifiedprotection*/vm_map_protect(&vmspace->vm_map,map_addr,map_addr+map_len,prot,FALSE);returnerror;}staticintelf_load_file(structpro
c*p,constchar*file,u_long*addr,u_long*entry){Elf_Ehdr*hdr=NULL;Elf_Phdr*phdr=NULL;structnameidatand;structvmspace*vmspace=p->p_vmspace;structvatt
rattr;structimage_paramsimage_params,*imgp;vm_prot_tprot;unsignedlongtext_size=0,data_size=0;unsignedlongtext_addr=0,data_addr=0;interror,i;imgp=
&image_params;/**Initializepartofthecommondata*/imgp->proc=p;imgp->uap=NULL;imgp->attr=&attr;imgp->firstpage=NULL;imgp->image_header=(char*)kmem_
alloc_wait(exec_map,PAGE_SIZE);if(imgp->image_header=NULL){nd.ni_vp=NULL;error=ENOMEM;gotofail;}NDINIT(&nd,LOOKUP,LOCKLEAF|FOLLOW,UIO_SYSSPACE,f
ile,p);if(error=namei(&nd)){nd.ni_vp=NULL;gotofail;}imgp->vp=nd.ni_vp;/**Checkpermissions,modes,uid,etconthefile,and"open"it.*/error=exec_check_p
ermissions(imgp);if(error){VOP_UNLOCK(nd.ni_vp,0,p);gotofail;}error=exec_map_first_page(imgp);VOP_UNLOCK(nd.ni_vp,0,p);if(error)gotofail;hdr=(Elf
_Ehdr*)imgp->image_header;if(error=elf_check_header(hdr,ET_DYN))gotofail;/*Onlysupportheadersthatfitwithinfirstpagefornow*/if((hdr->e_phoff>PAGE_
SIZE)||(hdr->e_phoff+hdr->e_phentsize*hdr->e_phnum)>PAGE_SIZE){error=ENOEXEC;gotofail;}phdr=(Elf_Phdr*)(imgp->image_header+hdr->e_phoff);for(i=0;
i<hdr->e_phnum;i++){if(phdr[i].p_type==PT_LOAD){/*Loadablesegment*/prot=0;if(phdr[i].p_flags&PF_X)prot|=VM_PROT_EXECUTE;if(phdr[i].p_flags&PF_W)p
rot|=VM_PROT_WRITE;if(phdr[i].p_flags&PF_R)prot|=VM_PROT_READ;if(error=elf_load_section(p,vmspace,nd.ni_vp,phdr[i].p_offset,(caddr_t)phdr[i].p_va
ddr+(*addr),phdr[i].p_memsz,phdr[i].p_filesz,prot))gotofail;/**Isthis.textor.data??**WeonlyhandleoneeachofthoseyetXXX*/if(hdr->e_entry>=phdr[i].p
_vaddr&&hdr->e_entry<(phdr[i].p_vaddr+phdr[i].p_memsz)){text_addr=trunc_page(phdr[i].p_vaddr+(*addr));text_size=round_page(phdr[i].p_memsz+phdr[i
].p_vaddr-trunc_page(phdr[i].p_vaddr));*entry=(unsignedlong)hdr->e_entry+(*addr);}else{data_addr=trunc_page(phdr[i].p_vaddr+(*addr));data_size=ro
und_page(phdr[i].p_memsz+phdr[i].p_vaddr-trunc_page(phdr[i].p_vaddr));}}}fail:if(imgp->firstpage)exec_unmap_first_page(imgp);if(imgp->image_heade
r)kmem_free_wakeup(exec_map,(vm_offset_t)imgp->image_header,PAGE_SIZE);if(nd.ni_vp)vrele(nd.ni_vp);returnerror;}staticintexec_elf_imgact(structim
age_params*imgp){constElf_Ehdr*hdr=(constElf_Ehdr*)imgp->image_header;constElf_Phdr*phdr;Elf_Auxargs*elf_auxargs=NULL;structvmspace*vmspace;vm_pr
ot_tprot;u_longtext_size=0,data_size=0;u_longtext_addr=0,data_addr=0;u_longaddr,entry=0,proghdr=0;interror,i;constchar*interp=NULL;Elf_Brandinfo*
brand_info;char*brand;charpath[MAXPATHLEN];/**DowehaveavalidELFheader?*/if(elf_check_header(hdr,ET_EXEC))return-1;/**Fromhereondown,wereturnanerr
no,not-1,aswe've*detectedanELFfile.*/if((hdr->e_phoff>PAGE_SIZE)||(hdr->e_phoff+hdr->e_phentsize*hdr->e_phnum)>PAGE_SIZE){/*Onlysupportheadersinf
irstpagefornow*/returnENOEXEC;}phdr=(constElf_Phdr*)(imgp->image_header+hdr->e_phoff);/**Fromthispointon,wemayhaveresourcesthatneedtobefreed.*/if
(error=exec_extract_strings(imgp))gotofail;exec_new_vmspace(imgp);vmspace=imgp->proc->p_vmspace;for(i=0;i<hdr->e_phnum;i++){switch(phdr[i].p_type
){casePT_LOAD:/*Loadablesegment*/prot=0;if(phdr[i].p_flags&PF_X)prot|=VM_PROT_EXECUTE;if(phdr[i].p_flags&PF_W)prot|=VM_PROT_WRITE;if(phdr[i].p_fl
ags&PF_R)prot|=VM_PROT_READ;if(error=elf_load_section(imgp->proc,vmspace,imgp->vp,phdr[i].p_offset,(caddr_t)phdr[i].p_vaddr,phdr[i].p_memsz,phdr[
i].p_filesz,prot))gotofail;/**Isthis.textor.data??**WeonlyhandleoneeachofthoseyetXXX*/if(hdr->e_entry>=phdr[i].p_vaddr&&hdr->e_entry<(phdr[i].p_v
addr+phdr[i].p_memsz)){text_addr=trunc_page(phdr[i].p_vaddr);text_size=round_page(phdr[i].p_memsz+phdr[i].p_vaddr-text_addr);entry=(u_long)hdr->e
_entry;}else{data_addr=trunc_page(phdr[i].p_vaddr);data_size=round_page(phdr[i].p_memsz+phdr[i].p_vaddr-data_addr);}break;casePT_INTERP:/*Pathtoi
nterpreter*/if(phdr[i].p_filesz>MAXPATHLEN||phdr[i].p_offset+phdr[i].p_filesz>PAGE_SIZE){error=ENOEXEC;gotofail;}interp=imgp->image_header+phdr[i
].p_offset;break;casePT_PHDR:/*Programheadertableinfo*/proghdr=phdr[i].p_vaddr;break;default:break;}}vmspace->vm_tsize=text_size>>PAGE_SHIFT;vmsp
ace->vm_taddr=(caddr_t)(uintptr_t)text_addr;vmspace->vm_dsize=data_size>>PAGE_SHIFT;vmspace->vm_daddr=(caddr_t)(uintptr_t)data_addr;addr=ELF_RTLD
_ADDR(vmspace);imgp->entry_addr=entry;/*Iftheexecutablehasabrand,searchforitinthebrandlist.*/brand_info=NULL;brand=(char*)&hdr->e_ident[EI_BRAND]
;if(brand[0]!='\0'){for(i=0;i<MAX_BRANDS;i++){Elf_Brandinfo*bi=elf_brand_list[i];if(bi!=NULL&&strcmp(brand,bi->brand)==0){brand_info=bi;break;}}}
/*Lackingaknownbrand,searchforarecognizedinterpreter.*/if(brand_info==NULL&&interp!=NULL){for(i=0;i<MAX_BRANDS;i++){Elf_Brandinfo*bi=elf_brand_li
st[i];if(bi!=NULL&&strcmp(interp,bi->interp_path)==0){brand_info=bi;break;}}}#ifdef__alpha__/*XXX-AssumeFreeBSDonthealpha.*/if(brand_info==NULL)b
rand_info=&freebsd_brand_info;#endifif(brand_info==NULL){if(brand[0]==0)uprintf("ELFbinarytypenotknown.""Use\"brandelf\"tobrandit.\n");elseuprint
f("ELFbinarytype\"%.*s\"notknown.\n",EI_NIDENT-EI_BRAND,brand);error=ENOEXEC;gotofail;}imgp->proc->p_sysent=brand_info->sysvec;if(interp!=NULL){s
nprintf(path,sizeof(path),"%s%s",brand_info->emul_path,interp);if((error=elf_load_file(imgp->proc,path,&addr,&imgp->entry_addr))!=0){if((error=el
f_load_file(imgp->proc,interp,&addr,&imgp->entry_addr))!=0){uprintf("ELFinterpreter%snotfound\n",path);gotofail;}}}/**Constructauxargstable(usedb
ythefixuproutine)*/elf_auxargs=malloc(sizeof(Elf_Auxargs),M_TEMP,M_WAITOK);elf_auxargs->execfd=-1;elf_auxargs->phdr=proghdr;elf_auxargs->phent=hd
r->e_phentsize;elf_auxargs->phnum=hdr->e_phnum;elf_auxargs->pagesz=PAGE_SIZE;elf_auxargs->base=addr;elf_auxargs->flags=0;elf_auxargs->entry=entry
;elf_auxargs->trace=elf_trace;imgp->auxargs=elf_auxargs;imgp->interpreted=0;/*don'tallowmodifyingthefilewhilewerunit*/imgp->vp->v_flag|=VTEXT;fai
l:returnerror;}staticintelf_freebsd_fixup(long**stack_base,structimage_params*imgp){Elf_Auxargs*args=(Elf_Auxargs*)imgp->auxargs;long*pos;pos=*st
ack_base+(imgp->argc+imgp->envc+2);if(args->trace){AUXARGS_ENTRY(pos,AT_DEBUG,1);}if(args->execfd!=-1){AUXARGS_ENTRY(pos,AT_EXECFD,args->execfd);
}AUXARGS_ENTRY(pos,AT_PHDR,args->phdr);AUXARGS_ENTRY(pos,AT_PHENT,args->phent);AUXARGS_ENTRY(pos,AT_PHNUM,args->phnum);AUXARGS_ENTRY(pos,AT_PAGES
Z,args->pagesz);AUXARGS_ENTRY(pos,AT_FLAGS,args->flags);AUXARGS_ENTRY(pos,AT_ENTRY,args->entry);AUXARGS_ENTRY(pos,AT_BASE,args->base);AUXARGS_ENT
RY(pos,AT_NULL,0);free(imgp->auxargs,M_TEMP);imgp->auxargs=NULL;(*stack_base)--;suword(*stack_base,(long)imgp->argc);return0;}/**Codeforgeneratin
gELFcoredumps.*/typedefvoid(*segment_callback)__P((vm_map_entry_t,void*));/*Closureforcb_put_phdr().*/structphdr_closure{Elf_Phdr*phdr;/*Programh
eadertofillin*/Elf_Offoffset;/*Offsetofsegmentincorefile*/};/*Closureforcb_size_segment().*/structsseg_closure{intcount;/*Countofwritablesegments
.*/size_tsize;/*Totalsizeofallwritablesegments.*/};staticvoidcb_put_phdr__P((vm_map_entry_t,void*));staticvoidcb_size_segment__P((vm_map_entry_t,
void*));staticvoideach_writable_segment__P((structproc*,segment_callback,void*));staticintelf_corehdr__P((structproc*,structvnode*,structucred*,i
nt,void*,size_t));staticvoidelf_puthdr__P((structproc*,void*,size_t*,constprstatus_t*,constprfpregset_t*,constprpsinfo_t*,int));staticvoidelf_put
note__P((void*,size_t*,constchar*,int,constvoid*,size_t));externintosreldate;intelf_coredump(p,vp,limit)registerstructproc*p;registerstructvnode*
vp;off_tlimit;{registerstructucred*cred=p->p_cred->pc_ucred;interror=0;structsseg_closureseginfo;void*hdr;size_thdrsize;/*Sizetheprogramsegments.
*/seginfo.count=0;seginfo.size=0;each_writable_segment(p,cb_size_segment,&seginfo);/**Calculatethesizeofthecorefileheaderareabymaking*adryrunofge
neratingit.Nothingiswritten,butthe*sizeiscalculated.*/hdrsize=0;elf_puthdr((structproc*)NULL,(void*)NULL,&hdrsize,(constprstatus_t*)NULL,(constpr
fpregset_t*)NULL,(constprpsinfo_t*)NULL,seginfo.count);if(hdrsize+seginfo.size>=limit)return(EFAULT);/**Allocatememoryforbuildingtheheader,fillit
up,*andwriteitout.*/hdr=malloc(hdrsize,M_TEMP,M_WAITOK);if(hdr==NULL){returnEINVAL;}error=elf_corehdr(p,vp,cred,seginfo.count,hdr,hdrsize);/*Writ
ethecontentsofallofthewritablesegments.*/if(error==0){Elf_Phdr*php;off_toffset;inti;php=(Elf_Phdr*)((char*)hdr+sizeof(Elf_Ehdr))+1;offset=hdrsize
;for(i=0;i<seginfo.count;i++){error=vn_rdwr(UIO_WRITE,vp,(caddr_t)php->p_vaddr,php->p_filesz,offset,UIO_USERSPACE,IO_NODELOCKED|IO_UNIT,cred,(int
*)NULL,p);if(error!=0)break;offset+=php->p_filesz;php++;}}free(hdr,M_TEMP);returnerror;}/**Acallbackforeach_writable_segment()towriteoutthesegmen
t's*programheaderentry.*/staticvoidcb_put_phdr(entry,closure)vm_map_entry_tentry;void*closure;{structphdr_closure*phc=(structphdr_closure*)closur
e;Elf_Phdr*phdr=phc->phdr;phc->offset=round_page(phc->offset);phdr->p_type=PT_LOAD;phdr->p_offset=phc->offset;phdr->p_vaddr=entry->start;phdr->p_
paddr=0;phdr->p_filesz=phdr->p_memsz=entry->end-entry->start;phdr->p_align=PAGE_SIZE;phdr->p_flags=0;if(entry->protection&VM_PROT_READ)phdr->p_fl
ags|=PF_R;if(entry->protection&VM_PROT_WRITE)phdr->p_flags|=PF_W;if(entry->protection&VM_PROT_EXECUTE)phdr->p_flags|=PF_X;phc->offset+=phdr->p_fi
lesz;phc->phdr++;}/**Acallbackforeach_writable_segment()togatherinformationabout*thenumberofsegmentsandtheirtotalsize.*/staticvoidcb_size_segment
(entry,closure)vm_map_entry_tentry;void*closure;{structsseg_closure*ssc=(structsseg_closure*)closure;ssc->count++;ssc->size+=entry->end-entry->st
art;}/**Foreachwritablesegmentintheprocess'smemorymap,callthegiven*functionwithapointertothemapentryandsomearbitrary*caller-supplieddata.*/static
voideach_writable_segment(p,func,closure)structproc*p;segment_callbackfunc;void*closure;{vm_map_tmap=&p->p_vmspace->vm_map;vm_map_entry_tentry;fo
r(entry=map->header.next;entry!=&map->header;entry=entry->next){vm_object_tobj;if(entry->eflags&(MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)||(entry
->protection&(VM_PROT_READ|VM_PROT_WRITE))!=(VM_PROT_READ|VM_PROT_WRITE))continue;if((obj=entry->object.vm_object)==NULL)continue;/*Findthedeepes
tbackingobject.*/while(obj->backing_object!=NULL)obj=obj->backing_object;/*Ignorememory-mappeddevicesandsuchthings.*/if(obj->type!=OBJT_DEFAULT&&
obj->type!=OBJT_SWAP&&obj->type!=OBJT_VNODE)continue;(*func)(entry,closure);}}/**Writethecorefileheadertothefile,includingpaddingupto*thepageboun
dary.*/staticintelf_corehdr(p,vp,cred,numsegs,hdr,hdrsize)structproc*p;structvnode*vp;structucred*cred;intnumsegs;size_thdrsize;void*hdr;{size_to
ff;prstatus_tstatus;prfpregset_tfpregset;prpsinfo_tpsinfo;/*Gathertheinformationfortheheader.*/bzero(&status,sizeofstatus);status.pr_version=PRST