| ... | ... | @@ -22,7 +22,11 @@ pub fn lookup(vername: []const u8, name: []const u8) usize { |
| 22 | 22 | }) { |
| 23 | 23 | const this_ph = @intToPtr(*elf.Phdr, ph_addr); |
| 24 | 24 | switch (this_ph.p_type) { |
| 25 | | elf.PT_LOAD => base = vdso_addr + this_ph.p_offset - this_ph.p_vaddr, |
| 25 | // On WSL1 as well as older kernels, the VDSO ELF image is pre-linked in the upper half |
| 26 | // of the memory space (e.g. p_vaddr = 0xffffffffff700000 on WSL1). |
| 27 | // Wrapping operations are used on this line as well as subsequent calculations relative to base |
| 28 | // (lines 47, 78) to ensure no overflow check is tripped. |
| 29 | elf.PT_LOAD => base = vdso_addr +% this_ph.p_offset -% this_ph.p_vaddr, |
| 26 | 30 | elf.PT_DYNAMIC => maybe_dynv = @intToPtr([*]usize, vdso_addr + this_ph.p_offset), |
| 27 | 31 | else => {}, |
| 28 | 32 | } |
| ... | ... | @@ -40,7 +44,7 @@ pub fn lookup(vername: []const u8, name: []const u8) usize { |
| 40 | 44 | { |
| 41 | 45 | var i: usize = 0; |
| 42 | 46 | while (dynv[i] != 0) : (i += 2) { |
| 43 | | const p = base + dynv[i + 1]; |
| 47 | const p = base +% dynv[i + 1]; |
| 44 | 48 | switch (dynv[i]) { |
| 45 | 49 | elf.DT_STRTAB => maybe_strings = @intToPtr([*]u8, p), |
| 46 | 50 | elf.DT_SYMTAB => maybe_syms = @intToPtr([*]elf.Sym, p), |
| ... | ... | @@ -71,7 +75,7 @@ pub fn lookup(vername: []const u8, name: []const u8) usize { |
| 71 | 75 | if (!checkver(maybe_verdef.?, versym[i], vername, strings)) |
| 72 | 76 | continue; |
| 73 | 77 | } |
| 74 | | return base + syms[i].st_value; |
| 78 | return base +% syms[i].st_value; |
| 75 | 79 | } |
| 76 | 80 | |
| 77 | 81 | return 0; |