gofed / symbols-extractor

Extractor of symbols from Go based projects
BSD 3-Clause "New" or "Revised" License
7 stars 3 forks source link

The second operand &{true -3 int builtin} of << is not uint, at pos 5655 #160

Closed ingvagabund closed 3 years ago

ingvagabund commented 3 years ago

Reproduced by running:

./extract --stdlib --symbol-table-dir generated --cgo-symbols-path cgo/cgo.yml

Parsing error logged:

I0221 13:10:56.752245 3955722 file_parser.go:393] File "runtime"/"mpagealloc.go" parse "l2" Funcs error: parseBinaryExpr: The second operand &{true -3 int builtin} of << is not uint, at pos 5655

Code snippet (from go1.15.linux.amd64/src/runtime/mpagealloc.go):

const (
        // The size of a bitmap chunk, i.e. the amount of bits (that is, pages) to consider
        // in the bitmap at once.
        pallocChunkPages    = 1 << logPallocChunkPages
        pallocChunkBytes    = pallocChunkPages * pageSize
        logPallocChunkPages = 9
        logPallocChunkBytes = logPallocChunkPages + pageShift

        // The number of radix bits for each level.
        //
        // The value of 3 is chosen such that the block of summaries we need to scan at
        // each level fits in 64 bytes (2^3 summaries * 8 bytes per summary), which is
        // close to the L1 cache line width on many systems. Also, a value of 3 fits 4 tree
        // levels perfectly into the 21-bit pallocBits summary field at the root level.
        //
        // The following equation explains how each of the constants relate:
        // summaryL0Bits + (summaryLevels-1)*summaryLevelBits + logPallocChunkBytes = heapAddrBits
        //
        // summaryLevels is an architecture-dependent value defined in mpagealloc_*.go.
        summaryLevelBits = 3
        summaryL0Bits    = heapAddrBits - logPallocChunkBytes - (summaryLevels-1)*summaryLevelBits

        // pallocChunksL2Bits is the number of bits of the chunk index number
        // covered by the second level of the chunks map.
        //
        // See (*pageAlloc).chunks for more details. Update the documentation
        // there should this change.
        pallocChunksL2Bits  = heapAddrBits - logPallocChunkBytes - pallocChunksL1Bits
        pallocChunksL1Shift = pallocChunksL2Bits
)
...
// l2 returns the index into the second level of (*pageAlloc).chunks.
func (i chunkIdx) l2() uint {
        if pallocChunksL1Bits == 0 {
                return uint(i)
        } else {
                return uint(i) & (1<<pallocChunksL2Bits - 1)
        }
}
ingvagabund commented 3 years ago

from go1.15.linux.amd64/src/runtime/malloc.go:

heapAddrBits = (_64bit*(1-sys.GoarchWasm)*(1-sys.GoosDarwin*sys.GoarchArm64))*48 + (1-_64bit+sys.GoarchWasm)*(32-(sys.GoarchMips+sys.GoarchMipsle)) + 33*sys.GoosDarwin*sys.GoarchArm64
_64bit = 1 << (^uintptr(0) >> 63) / 2
const pageShift = _PageShift

from go1.15.linux.amd64/src/runtime/internal/sys/zgoarch_amd64.go:

const GoosDarwin = 0
const GoarchArm64 = 0
const GoarchMipsle = 0
const GoarchMips = 0
const GoarchWasm = 0

from go1.15.linux.amd64/src/runtime/sizeclasses.go:

const _PageShift      = 13

from go1.15.linux.amd64/src/runtime/mpagealloc_64bits.go:

const pallocChunksL1Bits = 13
ingvagabund commented 3 years ago

Fixed through https://github.com/gofed/symbols-extractor/commit/dbc8552e9f960defb030917e449ad33a9b596320#diff-04fe068cb2459e374af742fd033b4138b7d07a5289b5b8a4431ff1b7792d1aa1R546