diff --git a/ld.go b/ld.go index 1e215842..08c2ea1a 100644 --- a/ld.go +++ b/ld.go @@ -446,22 +446,30 @@ func (linker *Linker) buildModule(codeModule *CodeModule, symbolMap map[string]u } module.ftab = append(module.ftab, initfunctab(module.maxpc, uintptr(len(module.pclntable)), module.text)) - //see:^src/cmd/link/internal/ld/pcln.go findfunctab + // see:^src/cmd/link/internal/ld/pcln.go findfunctab funcbucket := []findfuncbucket{} - for k, _func := range linker._funcs { - funcname := getfuncname(_func, module) - x := linker.symMap[funcname].Offset - b := x / pcbucketsize - i := x % pcbucketsize / (pcbucketsize / nsub) - for lb := b - len(funcbucket); lb >= 0; lb-- { - funcbucket = append(funcbucket, findfuncbucket{ - idx: uint32(k)}) + for k := 0; k < len(linker._funcs); k++ { + lEntry := int(getfuncentry(linker._funcs[k], module.text) - module.text) + lb := lEntry / pcbucketsize + li := lEntry % pcbucketsize / (pcbucketsize / nsub) + + entry := int(module.maxpc - module.text) + if k < len(linker._funcs)-1 { + entry = int(getfuncentry(linker._funcs[k+1], module.text) - module.text) + } + b := entry / pcbucketsize + i := entry % pcbucketsize / (pcbucketsize / nsub) + + for m := b - len(funcbucket); m >= 0; m-- { + funcbucket = append(funcbucket, findfuncbucket{idx: uint32(k)}) + } + if lb < b { + i = nsub - 1 } - if funcbucket[b].subbuckets[i] == 0 && b != 0 && i != 0 { - if k-int(funcbucket[b].idx) >= pcbucketsize/minfunc { - return fmt.Errorf("over %d func in one funcbuckets", k-int(funcbucket[b].idx)) + for n := li + 1; n <= i; n++ { + if funcbucket[lb].subbuckets[n] == 0 { + funcbucket[lb].subbuckets[n] = byte(k - int(funcbucket[lb].idx)) } - funcbucket[b].subbuckets[i] = byte(k - int(funcbucket[b].idx)) } } length := len(funcbucket) * FindFuncBucketSize