kernelBase calculates the base for kernel mappings, which usually require special handling. For kernel mappings, tools (like perf) use the address of the kernel relocation symbol (_text or _stext) as the mmap start. Additionally, for obfuscation, ChromeOS profiles have the kernel image remapped to t
(loadSegment *elf.ProgHeader, stextOffset *uint64, start, limit, offset uint64)
| 165 | // the kernel relocation symbol (_text or _stext) as the mmap start. Additionally, |
| 166 | // for obfuscation, ChromeOS profiles have the kernel image remapped to the 0-th page. |
| 167 | func kernelBase(loadSegment *elf.ProgHeader, stextOffset *uint64, start, limit, offset uint64) (uint64, bool) { |
| 168 | const ( |
| 169 | // PAGE_OFFSET for PowerPC64, see arch/powerpc/Kconfig in the kernel sources. |
| 170 | pageOffsetPpc64 = 0xc000000000000000 |
| 171 | pageSize = 4096 |
| 172 | ) |
| 173 | |
| 174 | if loadSegment.Vaddr == start-offset { |
| 175 | return offset, true |
| 176 | } |
| 177 | if start == 0 && limit != 0 && stextOffset != nil { |
| 178 | // ChromeOS remaps its kernel to 0. Nothing else should come |
| 179 | // down this path. Empirical values: |
| 180 | // VADDR=0xffffffff80200000 |
| 181 | // stextOffset=0xffffffff80200198 |
| 182 | return start - *stextOffset, true |
| 183 | } |
| 184 | if start >= 0x8000000000000000 && limit > start && (offset == 0 || offset == pageOffsetPpc64 || offset == start) { |
| 185 | // Some kernels look like: |
| 186 | // VADDR=0xffffffff80200000 |
| 187 | // stextOffset=0xffffffff80200198 |
| 188 | // Start=0xffffffff83200000 |
| 189 | // Limit=0xffffffff84200000 |
| 190 | // Offset=0 (0xc000000000000000 for PowerPC64) (== Start for ASLR kernel) |
| 191 | // So the base should be: |
| 192 | if stextOffset != nil && (start%pageSize) == (*stextOffset%pageSize) { |
| 193 | // perf uses the address of _stext as start. Some tools may |
| 194 | // adjust for this before calling GetBase, in which case the page |
| 195 | // alignment should be different from that of stextOffset. |
| 196 | return start - *stextOffset, true |
| 197 | } |
| 198 | |
| 199 | return start - loadSegment.Vaddr, true |
| 200 | } |
| 201 | if start%pageSize != 0 && stextOffset != nil && *stextOffset%pageSize == start%pageSize { |
| 202 | // ChromeOS remaps its kernel to 0 + start%pageSize. Nothing |
| 203 | // else should come down this path. Empirical values: |
| 204 | // start=0x198 limit=0x2f9fffff offset=0 |
| 205 | // VADDR=0xffffffff81000000 |
| 206 | // stextOffset=0xffffffff81000198 |
| 207 | return start - *stextOffset, true |
| 208 | } |
| 209 | return 0, false |
| 210 | } |
| 211 | |
| 212 | // GetBase determines the base address to subtract from virtual |
| 213 | // address to get symbol table address. For an executable, the base |
no outgoing calls
no test coverage detected
searching dependent graphs…