12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273exceptionErrorofstringletverbose=reffalsemodulePid_or_self=structtypet=|Selfofint|Otherofintletself()=Self(Unix.getpid())letof_pidpid=matchpid=Unix.getpid()with|true->Selfpid|false->Otherpid;;letproc_path~filename=function|Self_->"/proc/self/"^filename|Otherpid->Printf.sprintf"/proc/%d/%s"pidfilename;;letget_exet=proc_path~filename:"exe"t|>Unix.readlinkletto_pid=function|Selfpid|Otherpid->pid;;endtypeentry={addr:int64(** start address of the segment *);offset:int64(** file offset *)}typet={vma_offset_text:int64;vma_offset_data:int64;vma_offset_semaphores:int64}letdefault={vma_offset_text=0L;vma_offset_data=0L;vma_offset_semaphores=0L}(* 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.
*)let_vma_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)=ifelf.piethenfailwith"Probes-lib has not implemented support for position independent executables.";default;;