Skip to content

Commit 0a5bbba

Browse files
committed
cmd/link/internal/loadpe: refactor readpesym()
Rewrite the helper "readpesym()" and the code that calls it to pass in most of the values it needs via a state object (the signature was getting a bit too busy/lengthy). No change in functionality, this is just a refactor. Updates golang#35006. Change-Id: I6153ee3a9be3eb885694323ae8e07ec4c8eed646 Reviewed-on: https://go-review.googlesource.com/c/go/+/382836 Reviewed-by: Cherry Mui <[email protected]> Trust: Than McIntosh <[email protected]> Run-TryBot: Than McIntosh <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent ebe624d commit 0a5bbba

1 file changed

Lines changed: 51 additions & 35 deletions

File tree

  • src/cmd/link/internal/loadpe

src/cmd/link/internal/loadpe/ldpe.go

Lines changed: 51 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,29 @@ func makeUpdater(l *loader.Loader, bld *loader.SymbolBuilder, s loader.Sym) *loa
173173
return bld
174174
}
175175

176+
// peLoaderState holds various bits of useful state information needed
177+
// while loading a PE object file.
178+
type peLoaderState struct {
179+
l *loader.Loader
180+
arch *sys.Arch
181+
f *pe.File
182+
sectsyms map[*pe.Section]loader.Sym
183+
sectdata map[*pe.Section][]byte
184+
localSymVersion int
185+
}
186+
176187
// Load loads the PE file pn from input.
177188
// Symbols are written into syms, and a slice of the text symbols is returned.
178189
// If an .rsrc section or set of .rsrc$xx sections is found, its symbols are
179190
// returned as rsrc.
180191
func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Reader, pkg string, length int64, pn string) (textp []loader.Sym, rsrc []loader.Sym, err error) {
181-
lookup := l.LookupOrCreateCgoExport
182-
sectsyms := make(map[*pe.Section]loader.Sym)
183-
sectdata := make(map[*pe.Section][]byte)
192+
state := &peLoaderState{
193+
l: l,
194+
arch: arch,
195+
sectsyms: make(map[*pe.Section]loader.Sym),
196+
sectdata: make(map[*pe.Section][]byte),
197+
localSymVersion: localSymVersion,
198+
}
184199

185200
// Some input files are archives containing multiple of
186201
// object files, and pe.NewFile seeks to the start of
@@ -194,6 +209,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
194209
return nil, nil, err
195210
}
196211
defer f.Close()
212+
state.f = f
197213

198214
// TODO return error if found .cormeta
199215

@@ -210,7 +226,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
210226
}
211227

212228
name := fmt.Sprintf("%s(%s)", pkg, sect.Name)
213-
s := lookup(name, localSymVersion)
229+
s := state.l.LookupOrCreateCgoExport(name, localSymVersion)
214230
bld := l.MakeSymbolUpdater(s)
215231

216232
switch sect.Characteristics & (IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE | IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE) {
@@ -235,19 +251,19 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
235251
if err != nil {
236252
return nil, nil, err
237253
}
238-
sectdata[sect] = data
254+
state.sectdata[sect] = data
239255
bld.SetData(data)
240256
}
241257
bld.SetSize(int64(sect.Size))
242-
sectsyms[sect] = s
258+
state.sectsyms[sect] = s
243259
if sect.Name == ".rsrc" || strings.HasPrefix(sect.Name, ".rsrc$") {
244260
rsrc = append(rsrc, s)
245261
}
246262
}
247263

248264
// load relocations
249265
for _, rsect := range f.Sections {
250-
if _, found := sectsyms[rsect]; !found {
266+
if _, found := state.sectsyms[rsect]; !found {
251267
continue
252268
}
253269
if rsect.NumberOfRelocations == 0 {
@@ -263,13 +279,13 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
263279
}
264280

265281
splitResources := strings.HasPrefix(rsect.Name, ".rsrc$")
266-
sb := l.MakeSymbolUpdater(sectsyms[rsect])
282+
sb := l.MakeSymbolUpdater(state.sectsyms[rsect])
267283
for j, r := range rsect.Relocs {
268284
if int(r.SymbolTableIndex) >= len(f.COFFSymbols) {
269285
return nil, nil, fmt.Errorf("relocation number %d symbol index idx=%d cannot be large then number of symbols %d", j, r.SymbolTableIndex, len(f.COFFSymbols))
270286
}
271287
pesym := &f.COFFSymbols[r.SymbolTableIndex]
272-
_, gosym, err := readpesym(l, arch, lookup, f, pesym, sectsyms, localSymVersion)
288+
_, gosym, err := state.readpesym(pesym)
273289
if err != nil {
274290
return nil, nil, err
275291
}
@@ -292,60 +308,60 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
292308
case sys.I386, sys.AMD64:
293309
switch r.Type {
294310
default:
295-
return nil, nil, fmt.Errorf("%s: %v: unknown relocation type %v", pn, sectsyms[rsect], r.Type)
311+
return nil, nil, fmt.Errorf("%s: %v: unknown relocation type %v", pn, state.sectsyms[rsect], r.Type)
296312

297313
case IMAGE_REL_I386_REL32, IMAGE_REL_AMD64_REL32,
298314
IMAGE_REL_AMD64_ADDR32, // R_X86_64_PC32
299315
IMAGE_REL_AMD64_ADDR32NB:
300316
rType = objabi.R_PCREL
301317

302-
rAdd = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rOff:])))
318+
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
303319

304320
case IMAGE_REL_I386_DIR32NB, IMAGE_REL_I386_DIR32:
305321
rType = objabi.R_ADDR
306322

307323
// load addend from image
308-
rAdd = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rOff:])))
324+
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
309325

310326
case IMAGE_REL_AMD64_ADDR64: // R_X86_64_64
311327
rSize = 8
312328

313329
rType = objabi.R_ADDR
314330

315331
// load addend from image
316-
rAdd = int64(binary.LittleEndian.Uint64(sectdata[rsect][rOff:]))
332+
rAdd = int64(binary.LittleEndian.Uint64(state.sectdata[rsect][rOff:]))
317333
}
318334

319335
case sys.ARM:
320336
switch r.Type {
321337
default:
322-
return nil, nil, fmt.Errorf("%s: %v: unknown ARM relocation type %v", pn, sectsyms[rsect], r.Type)
338+
return nil, nil, fmt.Errorf("%s: %v: unknown ARM relocation type %v", pn, state.sectsyms[rsect], r.Type)
323339

324340
case IMAGE_REL_ARM_SECREL:
325341
rType = objabi.R_PCREL
326342

327-
rAdd = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rOff:])))
343+
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
328344

329345
case IMAGE_REL_ARM_ADDR32, IMAGE_REL_ARM_ADDR32NB:
330346
rType = objabi.R_ADDR
331347

332-
rAdd = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rOff:])))
348+
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
333349

334350
case IMAGE_REL_ARM_BRANCH24:
335351
rType = objabi.R_CALLARM
336352

337-
rAdd = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rOff:])))
353+
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
338354
}
339355

340356
case sys.ARM64:
341357
switch r.Type {
342358
default:
343-
return nil, nil, fmt.Errorf("%s: %v: unknown ARM64 relocation type %v", pn, sectsyms[rsect], r.Type)
359+
return nil, nil, fmt.Errorf("%s: %v: unknown ARM64 relocation type %v", pn, state.sectsyms[rsect], r.Type)
344360

345361
case IMAGE_REL_ARM64_ADDR32, IMAGE_REL_ARM64_ADDR32NB:
346362
rType = objabi.R_ADDR
347363

348-
rAdd = int64(int32(binary.LittleEndian.Uint32(sectdata[rsect][rOff:])))
364+
rAdd = int64(int32(binary.LittleEndian.Uint32(state.sectdata[rsect][rOff:])))
349365
}
350366
}
351367

@@ -406,12 +422,12 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
406422
var sect *pe.Section
407423
if pesym.SectionNumber > 0 {
408424
sect = f.Sections[pesym.SectionNumber-1]
409-
if _, found := sectsyms[sect]; !found {
425+
if _, found := state.sectsyms[sect]; !found {
410426
continue
411427
}
412428
}
413429

414-
bld, s, err := readpesym(l, arch, lookup, f, pesym, sectsyms, localSymVersion)
430+
bld, s, err := state.readpesym(pesym)
415431
if err != nil {
416432
return nil, nil, err
417433
}
@@ -430,7 +446,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
430446
continue
431447
} else if pesym.SectionNumber > 0 && int(pesym.SectionNumber) <= len(f.Sections) {
432448
sect = f.Sections[pesym.SectionNumber-1]
433-
if _, found := sectsyms[sect]; !found {
449+
if _, found := state.sectsyms[sect]; !found {
434450
return nil, nil, fmt.Errorf("%s: %v: missing sect.sym", pn, s)
435451
}
436452
} else {
@@ -446,12 +462,12 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
446462
continue
447463
}
448464
outerName := l.SymName(l.OuterSym(s))
449-
sectName := l.SymName(sectsyms[sect])
465+
sectName := l.SymName(state.sectsyms[sect])
450466
return nil, nil, fmt.Errorf("%s: duplicate symbol reference: %s in both %s and %s", pn, l.SymName(s), outerName, sectName)
451467
}
452468

453469
bld = makeUpdater(l, bld, s)
454-
sectsym := sectsyms[sect]
470+
sectsym := state.sectsyms[sect]
455471
bld.SetType(l.SymType(sectsym))
456472
l.AddInteriorSym(sectsym, s)
457473
bld.SetValue(int64(pesym.Value))
@@ -467,7 +483,7 @@ func Load(l *loader.Loader, arch *sys.Arch, localSymVersion int, input *bio.Read
467483
// Sort outer lists by address, adding to textp.
468484
// This keeps textp in increasing address order.
469485
for _, sect := range f.Sections {
470-
s := sectsyms[sect]
486+
s := state.sectsyms[sect]
471487
if s == 0 {
472488
continue
473489
}
@@ -490,17 +506,17 @@ func issect(s *pe.COFFSymbol) bool {
490506
return s.StorageClass == IMAGE_SYM_CLASS_STATIC && s.Type == 0 && s.Name[0] == '.'
491507
}
492508

493-
func readpesym(l *loader.Loader, arch *sys.Arch, lookup func(string, int) loader.Sym, f *pe.File, pesym *pe.COFFSymbol, sectsyms map[*pe.Section]loader.Sym, localSymVersion int) (*loader.SymbolBuilder, loader.Sym, error) {
494-
symname, err := pesym.FullName(f.StringTable)
509+
func (state *peLoaderState) readpesym(pesym *pe.COFFSymbol) (*loader.SymbolBuilder, loader.Sym, error) {
510+
symname, err := pesym.FullName(state.f.StringTable)
495511
if err != nil {
496512
return nil, 0, err
497513
}
498514
var name string
499515
if issect(pesym) {
500-
name = l.SymName(sectsyms[f.Sections[pesym.SectionNumber-1]])
516+
name = state.l.SymName(state.sectsyms[state.f.Sections[pesym.SectionNumber-1]])
501517
} else {
502518
name = symname
503-
switch arch.Family {
519+
switch state.arch.Family {
504520
case sys.AMD64:
505521
if name == "__imp___acrt_iob_func" {
506522
// Do not rename __imp___acrt_iob_func into __acrt_iob_func,
@@ -537,24 +553,24 @@ func readpesym(l *loader.Loader, arch *sys.Arch, lookup func(string, int) loader
537553
case IMAGE_SYM_DTYPE_FUNCTION, IMAGE_SYM_DTYPE_NULL:
538554
switch pesym.StorageClass {
539555
case IMAGE_SYM_CLASS_EXTERNAL: //global
540-
s = lookup(name, 0)
556+
s = state.l.LookupOrCreateCgoExport(name, 0)
541557

542558
case IMAGE_SYM_CLASS_NULL, IMAGE_SYM_CLASS_STATIC, IMAGE_SYM_CLASS_LABEL:
543-
s = lookup(name, localSymVersion)
544-
bld = makeUpdater(l, bld, s)
559+
s = state.l.LookupOrCreateCgoExport(name, state.localSymVersion)
560+
bld = makeUpdater(state.l, bld, s)
545561
bld.SetDuplicateOK(true)
546562

547563
default:
548564
return nil, 0, fmt.Errorf("%s: invalid symbol binding %d", symname, pesym.StorageClass)
549565
}
550566
}
551567

552-
if s != 0 && l.SymType(s) == 0 && (pesym.StorageClass != IMAGE_SYM_CLASS_STATIC || pesym.Value != 0) {
553-
bld = makeUpdater(l, bld, s)
568+
if s != 0 && state.l.SymType(s) == 0 && (pesym.StorageClass != IMAGE_SYM_CLASS_STATIC || pesym.Value != 0) {
569+
bld = makeUpdater(state.l, bld, s)
554570
bld.SetType(sym.SXREF)
555571
}
556572
if strings.HasPrefix(symname, "__imp_") {
557-
bld = makeUpdater(l, bld, s)
573+
bld = makeUpdater(state.l, bld, s)
558574
bld.SetGot(-2) // flag for __imp_
559575
}
560576

0 commit comments

Comments
 (0)