findProgramHeader returns the program segment that matches the current mapping and the given address, or an error if it cannot find a unique program header.
(ef *elf.File, addr uint64)
| 535 | // mapping and the given address, or an error if it cannot find a unique program |
| 536 | // header. |
| 537 | func (m *elfMapping) findProgramHeader(ef *elf.File, addr uint64) (*elf.ProgHeader, error) { |
| 538 | // For user space executables, we try to find the actual program segment that |
| 539 | // is associated with the given mapping. Skip this search if limit <= start. |
| 540 | // We cannot use just a check on the start address of the mapping to tell if |
| 541 | // it's a kernel / .ko module mapping, because with quipper address remapping |
| 542 | // enabled, the address would be in the lower half of the address space. |
| 543 | |
| 544 | if m.kernelOffset != nil || m.start >= m.limit || m.limit >= (uint64(1)<<63) { |
| 545 | // For the kernel, find the program segment that includes the .text section. |
| 546 | return elfexec.FindTextProgHeader(ef), nil |
| 547 | } |
| 548 | |
| 549 | // Fetch all the loadable segments. |
| 550 | var phdrs []elf.ProgHeader |
| 551 | for i := range ef.Progs { |
| 552 | if ef.Progs[i].Type == elf.PT_LOAD { |
| 553 | phdrs = append(phdrs, ef.Progs[i].ProgHeader) |
| 554 | } |
| 555 | } |
| 556 | // Some ELF files don't contain any loadable program segments, e.g. .ko |
| 557 | // kernel modules. It's not an error to have no header in such cases. |
| 558 | if len(phdrs) == 0 { |
| 559 | return nil, nil |
| 560 | } |
| 561 | // Get all program headers associated with the mapping. |
| 562 | headers := elfexec.ProgramHeadersForMapping(phdrs, m.offset, m.limit-m.start) |
| 563 | if len(headers) == 0 { |
| 564 | return nil, errors.New("no program header matches mapping info") |
| 565 | } |
| 566 | if len(headers) == 1 { |
| 567 | return headers[0], nil |
| 568 | } |
| 569 | |
| 570 | // Use the file offset corresponding to the address to symbolize, to narrow |
| 571 | // down the header. |
| 572 | return elfexec.HeaderForFileOffset(headers, addr-m.start+m.offset) |
| 573 | } |
| 574 | |
| 575 | // file implements the binutils.ObjFile interface. |
| 576 | type file struct { |
no test coverage detected