| skipped 167 lines |
168 | 168 | | } |
169 | 169 | | } |
170 | 170 | | |
171 | | - | tab, tabva, err := file.PCLineTable(versionOverride) |
| 171 | + | tabs, err := file.PCLineTable(versionOverride) |
172 | 172 | | if err != nil { |
173 | 173 | | return ExtractMetadata{}, fmt.Errorf("failed to read pclntab: %w", err) |
174 | 174 | | } |
175 | 175 | | |
176 | | - | if tab.Go12line == nil { |
177 | | - | log.Fatalf("pclntab read, but is nil") |
178 | | - | return ExtractMetadata{}, fmt.Errorf("read pclntab, but parsing failed. The file may not be fully unpacked or corrupted: %w", err) |
| 176 | + | if len(tabs) == 0 { |
| 177 | + | return ExtractMetadata{}, fmt.Errorf("No pclntab candidates found") |
179 | 178 | | } |
180 | 179 | | |
181 | | - | if len(versionOverride) > 0 { |
182 | | - | extractMetadata.Version = versionOverride |
183 | | - | } |
| 180 | + | var moduleData *objfile.ModuleData = nil |
| 181 | + | var finalTab *objfile.PclntabCandidate = &tabs[0] |
| 182 | + | for _, tab := range tabs { |
| 183 | + | if len(versionOverride) > 0 { |
| 184 | + | extractMetadata.Version = versionOverride |
| 185 | + | } |
184 | 186 | | |
185 | | - | // numeric only, go1.17 -> 1.17 |
186 | | - | goVersionIdx := strings.Index(extractMetadata.Version, "go") |
187 | | - | if goVersionIdx != -1 { |
188 | | - | // "devel go1.18-2d1d548 Tue Dec 21 03:55:43 2021 +0000" |
189 | | - | extractMetadata.Version = strings.Split(extractMetadata.Version[goVersionIdx+2:]+" ", " ")[0] |
| 187 | + | // numeric only, go1.17 -> 1.17 |
| 188 | + | goVersionIdx := strings.Index(extractMetadata.Version, "go") |
| 189 | + | if goVersionIdx != -1 { |
| 190 | + | // "devel go1.18-2d1d548 Tue Dec 21 03:55:43 2021 +0000" |
| 191 | + | extractMetadata.Version = strings.Split(extractMetadata.Version[goVersionIdx+2:]+" ", " ")[0] |
190 | 192 | | |
191 | | - | // go1.18-2d1d548 |
192 | | - | extractMetadata.Version = strings.Split(extractMetadata.Version+"-", "-")[0] |
193 | | - | } |
| 193 | + | // go1.18-2d1d548 |
| 194 | + | extractMetadata.Version = strings.Split(extractMetadata.Version+"-", "-")[0] |
| 195 | + | } |
194 | 196 | | |
195 | | - | extractMetadata.TabMeta.CpuQuantum = tab.Go12line.Quantum |
| 197 | + | extractMetadata.TabMeta.CpuQuantum = tab.ParsedPclntab.Go12line.Quantum |
196 | 198 | | |
197 | | - | // quantum is the minimal unit for a program counter (1 on x86, 4 on most other systems). |
198 | | - | // 386: 1, amd64: 1, arm: 4, arm64: 4, mips: 4, mips/64/64le/64be: 4, ppc64/64le: 4, riscv64: 4, s390x: 2, wasm: 1 |
199 | | - | extractMetadata.TabMeta.CpuQuantumStr = "x86/x64/wasm" |
200 | | - | if extractMetadata.TabMeta.CpuQuantum == 2 { |
201 | | - | extractMetadata.TabMeta.CpuQuantumStr = "s390x" |
202 | | - | } else if extractMetadata.TabMeta.CpuQuantum == 4 { |
203 | | - | extractMetadata.TabMeta.CpuQuantumStr = "arm/mips/ppc/riscv" |
204 | | - | } |
| 199 | + | // quantum is the minimal unit for a program counter (1 on x86, 4 on most other systems). |
| 200 | + | // 386: 1, amd64: 1, arm: 4, arm64: 4, mips: 4, mips/64/64le/64be: 4, ppc64/64le: 4, riscv64: 4, s390x: 2, wasm: 1 |
| 201 | + | extractMetadata.TabMeta.CpuQuantumStr = "x86/x64/wasm" |
| 202 | + | if extractMetadata.TabMeta.CpuQuantum == 2 { |
| 203 | + | extractMetadata.TabMeta.CpuQuantumStr = "s390x" |
| 204 | + | } else if extractMetadata.TabMeta.CpuQuantum == 4 { |
| 205 | + | extractMetadata.TabMeta.CpuQuantumStr = "arm/mips/ppc/riscv" |
| 206 | + | } |
205 | 207 | | |
206 | | - | extractMetadata.TabMeta.VA = tabva |
207 | | - | extractMetadata.TabMeta.Version = tab.Go12line.Version.String() |
208 | | - | extractMetadata.TabMeta.Endianess = tab.Go12line.Binary.String() |
209 | | - | extractMetadata.TabMeta.PointerSize = tab.Go12line.Ptrsize |
| 208 | + | extractMetadata.TabMeta.VA = tab.PclntabVA |
| 209 | + | extractMetadata.TabMeta.Version = tab.ParsedPclntab.Go12line.Version.String() |
| 210 | + | extractMetadata.TabMeta.Endianess = tab.ParsedPclntab.Go12line.Binary.String() |
| 211 | + | extractMetadata.TabMeta.PointerSize = tab.ParsedPclntab.Go12line.Ptrsize |
210 | 212 | | |
211 | | - | // this can be a little tricky to locate and parse properly across all go versions |
212 | | - | _, moduleData, err := file.ModuleDataTable(tabva, extractMetadata.Version, extractMetadata.TabMeta.Version, extractMetadata.TabMeta.PointerSize == 8, extractMetadata.TabMeta.Endianess == "LittleEndian") |
213 | | - | if err == nil { |
| 213 | + | // this can be a little tricky to locate and parse properly across all go versions |
| 214 | + | // since moduledata holds a pointer to the pclntab, we can (hopefully) find the right candidate by using it to find the moduledata. |
| 215 | + | // if that location works, then we must have given it the correct pclntab VA. At least in theory... |
| 216 | + | _, tmpModData, err := file.ModuleDataTable(tab.PclntabVA, extractMetadata.Version, extractMetadata.TabMeta.Version, extractMetadata.TabMeta.PointerSize == 8, extractMetadata.TabMeta.Endianess == "LittleEndian") |
| 217 | + | if err == nil && tmpModData != nil { |
| 218 | + | finalTab = &tab |
| 219 | + | moduleData = tmpModData |
| 220 | + | } |
| 221 | + | } |
| 222 | + | |
| 223 | + | if moduleData != nil { |
214 | 224 | | extractMetadata.ModuleMeta = *moduleData |
215 | 225 | | if printTypes && manualTypeAddress == 0 { |
216 | 226 | | types, err := file.ParseTypeLinks(extractMetadata.Version, moduleData, extractMetadata.TabMeta.PointerSize == 8, extractMetadata.TabMeta.Endianess == "LittleEndian") |
| skipped 14 lines |
231 | 241 | | } |
232 | 242 | | |
233 | 243 | | if printFilePaths { |
234 | | - | for k := range tab.Files { |
| 244 | + | for k := range finalTab.ParsedPclntab.Files { |
235 | 245 | | extractMetadata.Files = append(extractMetadata.Files, k) |
236 | 246 | | } |
237 | 247 | | } |
238 | 248 | | |
239 | | - | for _, elem := range tab.Funcs { |
| 249 | + | for _, elem := range finalTab.ParsedPclntab.Funcs { |
240 | 250 | | if isStdPackage(elem.PackageName()) { |
241 | 251 | | if printStdPkgs { |
242 | 252 | | extractMetadata.StdFunctions = append(extractMetadata.StdFunctions, FuncMetadata{ |
| skipped 155 lines |