@@ -37,7 +37,6 @@ type deadcodePass2 struct {
3737 ctxt * Link
3838 ldr * loader.Loader
3939 wq workQueue
40- rtmp []loader.Reloc
4140
4241 ifaceMethod map [methodsig ]bool // methods declared in reached interfaces
4342 markableMethods []methodref2 // methods of reached types
@@ -86,9 +85,9 @@ func (d *deadcodePass2) init() {
8685 // but we do keep the symbols it refers to.
8786 exportsIdx := d .ldr .Lookup ("go.plugin.exports" , 0 )
8887 if exportsIdx != 0 {
89- d . ReadRelocSyms (exportsIdx )
90- for i := 0 ; i < len ( d . rtmp ) ; i ++ {
91- d .mark (d . rtmp [ i ] .Sym , 0 )
88+ relocs := d . ldr . Relocs (exportsIdx )
89+ for i := 0 ; i < relocs . Count ; i ++ {
90+ d .mark (relocs . At2 ( i ) .Sym () , 0 )
9291 }
9392 }
9493 }
@@ -119,7 +118,6 @@ func (d *deadcodePass2) init() {
119118}
120119
121120func (d * deadcodePass2 ) flood () {
122- symRelocs := []loader.Reloc {}
123121 auxSyms := []loader.Sym {}
124122 for ! d .wq .empty () {
125123 symIdx := d .wq .pop ()
@@ -128,22 +126,11 @@ func (d *deadcodePass2) flood() {
128126
129127 isgotype := d .ldr .IsGoType (symIdx )
130128 relocs := d .ldr .Relocs (symIdx )
131- // For non-type symbols, we only need the target and the reloc
132- // type, so don't read other fields.
133- // For type symbols we may need all fields for interface
134- // satisfaction check.
135- // TODO: we don't even need the reloc type for non-type non-dwarf
136- // symbols.
137- if isgotype {
138- symRelocs = relocs .ReadAll (symRelocs )
139- } else {
140- symRelocs = relocs .ReadSyms (symRelocs )
141- }
142129
143130 if isgotype {
144131 p := d .ldr .Data (symIdx )
145132 if len (p ) != 0 && decodetypeKind (d .ctxt .Arch , p )& kindMask == kindInterface {
146- for _ , sig := range d .decodeIfaceMethods2 (d .ldr , d .ctxt .Arch , symIdx , symRelocs ) {
133+ for _ , sig := range d .decodeIfaceMethods2 (d .ldr , d .ctxt .Arch , symIdx , & relocs ) {
147134 if d .ctxt .Debugvlog > 1 {
148135 d .ctxt .Logf ("reached iface method: %s\n " , sig )
149136 }
@@ -154,25 +141,26 @@ func (d *deadcodePass2) flood() {
154141
155142 var methods []methodref2
156143 for i := 0 ; i < relocs .Count ; i ++ {
157- r := symRelocs [i ]
158- if r .Type == objabi .R_WEAKADDROFF {
144+ r := relocs .At2 (i )
145+ t := r .Type ()
146+ if t == objabi .R_WEAKADDROFF {
159147 continue
160148 }
161- if r . Type == objabi .R_METHODOFF {
149+ if t == objabi .R_METHODOFF {
162150 if i + 2 >= relocs .Count {
163151 panic ("expect three consecutive R_METHODOFF relocs" )
164152 }
165153 methods = append (methods , methodref2 {src : symIdx , r : i })
166154 i += 2
167155 continue
168156 }
169- if r . Type == objabi .R_USETYPE {
157+ if t == objabi .R_USETYPE {
170158 // type symbol used for DWARF. we need to load the symbol but it may not
171159 // be otherwise reachable in the program.
172160 // do nothing for now as we still load all type symbols.
173161 continue
174162 }
175- d .mark (r .Sym , symIdx )
163+ d .mark (r .Sym () , symIdx )
176164 }
177165 auxSyms = d .ldr .ReadAuxSyms (symIdx , auxSyms )
178166 for i := 0 ; i < len (auxSyms ); i ++ {
@@ -194,7 +182,7 @@ func (d *deadcodePass2) flood() {
194182 // Decode runtime type information for type methods
195183 // to help work out which methods can be called
196184 // dynamically via interfaces.
197- methodsigs := d .decodetypeMethods2 (d .ldr , d .ctxt .Arch , symIdx , symRelocs )
185+ methodsigs := d .decodetypeMethods2 (d .ldr , d .ctxt .Arch , symIdx , & relocs )
198186 if len (methods ) != len (methodsigs ) {
199187 panic (fmt .Sprintf ("%q has %d method relocations for %d methods" , d .ldr .SymName (symIdx ), len (methods ), len (methodsigs )))
200188 }
@@ -227,10 +215,10 @@ func (d *deadcodePass2) mark(symIdx, parent loader.Sym) {
227215}
228216
229217func (d * deadcodePass2 ) markMethod (m methodref2 ) {
230- d . ReadRelocSyms (m .src )
231- d .mark (d . rtmp [ m .r ] .Sym , m .src )
232- d .mark (d . rtmp [ m .r + 1 ] .Sym , m .src )
233- d .mark (d . rtmp [ m .r + 2 ] .Sym , m .src )
218+ relocs := d . ldr . Relocs (m .src )
219+ d .mark (relocs . At2 ( m .r ) .Sym () , m .src )
220+ d .mark (relocs . At2 ( m .r + 1 ) .Sym () , m .src )
221+ d .mark (relocs . At2 ( m .r + 2 ) .Sym () , m .src )
234222}
235223
236224func deadcode2 (ctxt * Link ) {
@@ -313,15 +301,15 @@ func (m methodref2) isExported() bool {
313301// the function type.
314302//
315303// Conveniently this is the layout of both runtime.method and runtime.imethod.
316- func (d * deadcodePass2 ) decodeMethodSig2 (ldr * loader.Loader , arch * sys.Arch , symIdx loader.Sym , symRelocs [] loader.Reloc , off , size , count int ) []methodsig {
304+ func (d * deadcodePass2 ) decodeMethodSig2 (ldr * loader.Loader , arch * sys.Arch , symIdx loader.Sym , relocs * loader.Relocs , off , size , count int ) []methodsig {
317305 var buf bytes.Buffer
318306 var methods []methodsig
319307 for i := 0 ; i < count ; i ++ {
320- buf .WriteString (decodetypeName2 (ldr , symIdx , symRelocs , off ))
321- mtypSym := decodeRelocSym2 (ldr , symIdx , symRelocs , int32 (off + 4 ))
308+ buf .WriteString (decodetypeName3 (ldr , symIdx , relocs , off ))
309+ mtypSym := decodeRelocSym3 (ldr , symIdx , relocs , int32 (off + 4 ))
322310 // FIXME: add some sort of caching here, since we may see some of the
323311 // same symbols over time for param types.
324- d . ReadRelocs (mtypSym )
312+ mrelocs := ldr . Relocs (mtypSym )
325313 mp := ldr .Data (mtypSym )
326314
327315 buf .WriteRune ('(' )
@@ -330,7 +318,7 @@ func (d *deadcodePass2) decodeMethodSig2(ldr *loader.Loader, arch *sys.Arch, sym
330318 if i > 0 {
331319 buf .WriteString (", " )
332320 }
333- a := decodetypeFuncInType2 (ldr , arch , mtypSym , d . rtmp , i )
321+ a := decodetypeFuncInType3 (ldr , arch , mtypSym , & mrelocs , i )
334322 buf .WriteString (ldr .SymName (a ))
335323 }
336324 buf .WriteString (") (" )
@@ -339,7 +327,7 @@ func (d *deadcodePass2) decodeMethodSig2(ldr *loader.Loader, arch *sys.Arch, sym
339327 if i > 0 {
340328 buf .WriteString (", " )
341329 }
342- a := decodetypeFuncOutType2 (ldr , arch , mtypSym , d . rtmp , i )
330+ a := decodetypeFuncOutType3 (ldr , arch , mtypSym , & mrelocs , i )
343331 buf .WriteString (ldr .SymName (a ))
344332 }
345333 buf .WriteRune (')' )
@@ -351,25 +339,26 @@ func (d *deadcodePass2) decodeMethodSig2(ldr *loader.Loader, arch *sys.Arch, sym
351339 return methods
352340}
353341
354- func (d * deadcodePass2 ) decodeIfaceMethods2 (ldr * loader.Loader , arch * sys.Arch , symIdx loader.Sym , symRelocs [] loader.Reloc ) []methodsig {
342+ func (d * deadcodePass2 ) decodeIfaceMethods2 (ldr * loader.Loader , arch * sys.Arch , symIdx loader.Sym , relocs * loader.Relocs ) []methodsig {
355343 p := ldr .Data (symIdx )
356344 if decodetypeKind (arch , p )& kindMask != kindInterface {
357345 panic (fmt .Sprintf ("symbol %q is not an interface" , ldr .SymName (symIdx )))
358346 }
359- rel := decodeReloc2 (ldr , symIdx , symRelocs , int32 (commonsize (arch )+ arch .PtrSize ))
360- if rel .Sym == 0 {
347+ rel := decodeReloc3 (ldr , symIdx , relocs , int32 (commonsize (arch )+ arch .PtrSize ))
348+ s := rel .Sym ()
349+ if s == 0 {
361350 return nil
362351 }
363- if rel . Sym != symIdx {
352+ if s != symIdx {
364353 panic (fmt .Sprintf ("imethod slice pointer in %q leads to a different symbol" , ldr .SymName (symIdx )))
365354 }
366- off := int (rel .Add ) // array of reflect.imethod values
355+ off := int (rel .Add () ) // array of reflect.imethod values
367356 numMethods := int (decodetypeIfaceMethodCount (arch , p ))
368357 sizeofIMethod := 4 + 4
369- return d .decodeMethodSig2 (ldr , arch , symIdx , symRelocs , off , sizeofIMethod , numMethods )
358+ return d .decodeMethodSig2 (ldr , arch , symIdx , relocs , off , sizeofIMethod , numMethods )
370359}
371360
372- func (d * deadcodePass2 ) decodetypeMethods2 (ldr * loader.Loader , arch * sys.Arch , symIdx loader.Sym , symRelocs [] loader.Reloc ) []methodsig {
361+ func (d * deadcodePass2 ) decodetypeMethods2 (ldr * loader.Loader , arch * sys.Arch , symIdx loader.Sym , relocs * loader.Relocs ) []methodsig {
373362 p := ldr .Data (symIdx )
374363 if ! decodetypeHasUncommon (arch , p ) {
375364 panic (fmt .Sprintf ("no methods on %q" , ldr .SymName (symIdx )))
@@ -400,19 +389,5 @@ func (d *deadcodePass2) decodetypeMethods2(ldr *loader.Loader, arch *sys.Arch, s
400389 moff := int (decodeInuxi (arch , p [off + 4 + 2 + 2 :], 4 ))
401390 off += moff // offset to array of reflect.method values
402391 const sizeofMethod = 4 * 4 // sizeof reflect.method in program
403- return d .decodeMethodSig2 (ldr , arch , symIdx , symRelocs , off , sizeofMethod , mcount )
404- }
405-
406- // readRelocs reads the relocations for the specified symbol into the
407- // deadcode relocs work array. Use with care, since the work array
408- // is a singleton.
409- func (d * deadcodePass2 ) ReadRelocs (symIdx loader.Sym ) {
410- relocs := d .ldr .Relocs (symIdx )
411- d .rtmp = relocs .ReadAll (d .rtmp )
412- }
413-
414- // Like ReadRelocs, but only reads target symbols.
415- func (d * deadcodePass2 ) ReadRelocSyms (symIdx loader.Sym ) {
416- relocs := d .ldr .Relocs (symIdx )
417- d .rtmp = relocs .ReadSyms (d .rtmp )
392+ return d .decodeMethodSig2 (ldr , arch , symIdx , relocs , off , sizeofMethod , mcount )
418393}
0 commit comments