| ... | ... | @@ -64,42 +64,33 @@ const have_dl_phdr_info = posix.system.dl_phdr_info != void; |
| 64 | 64 | const dl_phdr_info = if (have_dl_phdr_info) posix.dl_phdr_info else anyopaque; |
| 65 | 65 | |
| 66 | 66 | const IterFnError = error{ |
| 67 | | MissingPtLoadSegment, |
| 68 | | MissingLoad, |
| 67 | MissingLoadSegment, |
| 68 | MissingEhdrLoadSegment, |
| 69 | 69 | BadElfMagic, |
| 70 | | FailedConsistencyCheck, |
| 70 | PhnumMismatch, |
| 71 | 71 | }; |
| 72 | 72 | |
| 73 | 73 | fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void { |
| 74 | 74 | _ = size; |
| 75 | 75 | // Count how many libraries are loaded |
| 76 | | counter.* += @as(usize, 1); |
| 76 | counter.* += 1; |
| 77 | 77 | |
| 78 | | // The image should contain at least a PT.LOAD segment |
| 79 | | if (info.phnum < 1) return error.MissingPtLoadSegment; |
| 80 | | |
| 81 | | // Quick & dirty validation of the phdr pointers, make sure we're not |
| 82 | | // pointing to some random gibberish |
| 83 | | var i: usize = 0; |
| 84 | | var found_load = false; |
| 85 | | while (i < info.phnum) : (i += 1) { |
| 86 | | const phdr = info.phdr[i]; |
| 78 | // The image should contain at least one loadable segment |
| 79 | if (info.phnum < 1) return error.MissingLoadSegment; |
| 87 | 80 | |
| 81 | // For some quick and dirty validation, find the phdr which contains the ELF |
| 82 | // header, and check it makes sense. |
| 83 | for (info.phdr[0..info.phnum]) |phdr| { |
| 88 | 84 | if (phdr.type != .LOAD) continue; |
| 89 | | |
| 90 | | const reloc_addr = info.addr + phdr.vaddr; |
| 91 | | // Find the ELF header |
| 92 | | const elf_header = @as(*elf.Ehdr, @ptrFromInt(reloc_addr - phdr.offset)); |
| 93 | | // Validate the magic |
| 94 | | if (!mem.eql(u8, elf_header.e_ident[0..4], elf.MAGIC)) return error.BadElfMagic; |
| 95 | | // Consistency check |
| 96 | | if (elf_header.e_phnum != info.phnum) return error.FailedConsistencyCheck; |
| 97 | | |
| 98 | | found_load = true; |
| 85 | if (phdr.offset != 0) continue; |
| 86 | // This segment holds the ELF header at the start |
| 87 | const ehdr: *elf.Ehdr = @ptrFromInt(info.addr + phdr.vaddr); |
| 88 | if (!mem.eql(u8, ehdr.e_ident[0..4], elf.MAGIC)) return error.BadElfMagic; |
| 89 | if (ehdr.e_phnum != info.phnum) return error.PhnumMismatch; |
| 99 | 90 | break; |
| 91 | } else { |
| 92 | return error.MissingEhdrLoadSegment; |
| 100 | 93 | } |
| 101 | | |
| 102 | | if (!found_load) return error.MissingLoad; |
| 103 | 94 | } |
| 104 | 95 | |
| 105 | 96 | test "dl_iterate_phdr" { |