123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687exceptionErrorofstringletverbose=reffalsetypeentry={addr:int64(** start address of the segment *);offset:int64(** file offset *)}typet={vma_offset_text:int64;vma_offset_semaphores:int64}letis_mapped_from_file(e:Owee_linux_maps.entry)=not(e.inode=0L&&e.device_major=0&&e.device_minor=0);;(*
The following calculation give the dynamic address of a symbol:
sym_dynamic_addr
"symbol's dynamic address"
= "segment start"
+ "offset of symbol's static address from the start of its section"
+ "offset of its section from the base of the segment's offset in the file"
= "segment start"
+ "symbol's static address" - "section start"
+ "section offset into the file" - "segment offset into the file"
= seg_addr + (sym_static_addr - sec_addr) + (sec_offset - seg_offset)
= seg_addr + sec_offset - seg_offset - sec_addr + sym_static_addr
Read "segment start" and "segment offset into file" from mmap.
The rest is known from reading elf file.
Precompute the offset of dynamic address from static address
for each type of symbol, making sure it doesn't over/underflow.
*)letvma_offsetmmap_entry(elf_section:Elf.section)=ifmmap_entry.addr<elf_section.addr||elf_section.offset<mmap_entry.offsetthenraise(Failure"Unexpected section sizes");Int64.sub(Int64.add(Int64.submmap_entry.addrmmap_entry.offset)elf_section.offset)elf_section.addr;;letread~pid(elf:Elf.t)=letfilename=elf.filenameinlettext=refNoneinletdata=refNoneinletupdatep(e:Owee_linux_maps.entry)=match!pwith|None->p:=Some{addr=e.address_start;offset=e.offset}|Some_->raise(Error(Printf.sprintf"Unexpected format of /proc/%d/maps: duplicate segment for %s\n"pidfilename))inletowee_entries=Owee_linux_maps.scan_pidpidinList.iter(fun(e:Owee_linux_maps.entry)->ifis_mapped_from_filee&&String.equalfilenamee.pathnamethen(matche.perm_read,e.perm_write,e.perm_execute,e.perm_sharedwith|true,false,true,false->updatetexte|true,true,false,false->updatedatae|_->()))owee_entries;match!text,!data,elf.semaphores_sectionwith|Sometext,Somedata,Somesemaphores_section->{vma_offset_semaphores=vma_offsetdatasemaphores_section;vma_offset_text=vma_offsettextelf.text_section}|None,_,_->raise(Error(Printf.sprintf"Unexpected format of /proc/%d/maps: missing executable segment start"pid))|_,None,_->raise(Error(Printf.sprintf"Unexpected format of /proc/%d/maps: missing write segment start"pid))|_,_,None->raise(Failure(Printf.sprintf"No .probes section in %s"elf.filename));;