readSection determines for each byte in this section to which package it belongs.
(section memorySection, addresses []addressLine, program *programSize, getField func(*packageSize, bool) *uint64, packagePathMap map[string]string)
| 872 | // readSection determines for each byte in this section to which package it |
| 873 | // belongs. |
| 874 | func readSection(section memorySection, addresses []addressLine, program *programSize, getField func(*packageSize, bool) *uint64, packagePathMap map[string]string) { |
| 875 | // The addr variable tracks at which address we are while going through this |
| 876 | // section. We start at the beginning. |
| 877 | addr := section.Address |
| 878 | sectionEnd := section.Address + section.Size |
| 879 | if sizesDebug { |
| 880 | fmt.Printf("%08x..%08x %5d: %s\n", addr, sectionEnd, section.Size, section.Type) |
| 881 | } |
| 882 | for _, line := range addresses { |
| 883 | if line.Address < section.Address || line.Address+line.Length > sectionEnd { |
| 884 | // Check that this line is entirely within the section. |
| 885 | // Don't bother dealing with line entries that cross sections (that |
| 886 | // seems rather unlikely anyway). |
| 887 | continue |
| 888 | } |
| 889 | if addr < line.Address { |
| 890 | // There is a gap: there is a space between the current and the |
| 891 | // previous line entry. |
| 892 | // Check whether this is caused by alignment requirements. |
| 893 | addrAligned := (addr + line.Align - 1) &^ (line.Align - 1) |
| 894 | if line.Align > 1 && addrAligned >= line.Address { |
| 895 | // It is, assume that's what causes the gap. |
| 896 | program.getPackage("(padding)").addSize(getField, "", line.Address-addr, true) |
| 897 | } else { |
| 898 | program.getPackage("(unknown)").addSize(getField, "", line.Address-addr, false) |
| 899 | if sizesDebug { |
| 900 | fmt.Printf("%08x..%08x %5d: unknown (gap), alignment=%d\n", addr, line.Address, line.Address-addr, line.Align) |
| 901 | } |
| 902 | } |
| 903 | addr = line.Address |
| 904 | } |
| 905 | if addr > line.Address+line.Length { |
| 906 | // The current line is already covered by a previous line entry. |
| 907 | // Simply skip it. |
| 908 | continue |
| 909 | } |
| 910 | // At this point, addr falls within the current line (probably at the |
| 911 | // start). |
| 912 | length := line.Length |
| 913 | if addr > line.Address { |
| 914 | // There is some overlap: the previous line entry already covered |
| 915 | // part of this line entry. So reduce the length to add to the |
| 916 | // remaining bit of the line entry. |
| 917 | length = line.Length - (addr - line.Address) |
| 918 | } |
| 919 | // Finally, mark this chunk of memory as used by the given package. |
| 920 | packagePath, filename := findPackagePath(line.File, packagePathMap) |
| 921 | program.getPackage(packagePath).addSize(getField, filename, length, line.IsVariable) |
| 922 | addr = line.Address + line.Length |
| 923 | } |
| 924 | if addr < sectionEnd { |
| 925 | // There is a gap at the end of the section. |
| 926 | addrAligned := (addr + section.Align - 1) &^ (section.Align - 1) |
| 927 | if section.Align > 1 && addrAligned >= sectionEnd { |
| 928 | // The gap is caused by the section alignment. |
| 929 | // For example, if a .rodata section ends with a non-aligned string. |
| 930 | program.getPackage("(padding)").addSize(getField, "", sectionEnd-addr, true) |
| 931 | } else { |
no test coverage detected