lsu := d.ldr.MakeSymbolUpdater(ls)
newattr(unit.DWInfo, dwarf.DW_AT_stmt_list, dwarf.DW_CLS_PTR, lsu.Size(), dwSym(ls))
+ internalExec := d.linkctxt.BuildMode == BuildModeExe && d.linkctxt.IsInternal()
+ addAddrPlus := loader.GenAddAddrPlusFunc(internalExec)
+
// Write .debug_line Line Number Program Header (sec 6.2.4)
// Fields marked with (*) must be changed for 64-bit dwarf
unitLengthOffset := lsu.Size()
lsu.AddUint8(0)
dwarf.Uleb128put(d, lsDwsym, 1+int64(d.arch.PtrSize))
lsu.AddUint8(dwarf.DW_LNE_set_address)
- addr := lsu.AddAddrPlus(d.arch, fnSym, 0)
+ addr := addAddrPlus(lsu, d.arch, fnSym, 0)
// Make sure the units are sorted.
if addr < lastAddr {
d.linkctxt.Errorf(fnSym, "address wasn't increasing %x < %x",
Exitf("dwarf: cieReserve too small by %d bytes.", -pad)
}
+ internalExec := d.linkctxt.BuildMode == BuildModeExe && d.linkctxt.IsInternal()
+ addAddrPlus := loader.GenAddAddrPlusFunc(internalExec)
+
fsu.AddBytes(zeros[:pad])
var deltaBuf []byte
} else {
d.addDwarfAddrField(fsu, 0) // CIE offset
}
- fsu.AddAddrPlus(d.arch, s, 0)
+ addAddrPlus(fsu, d.arch, s, 0)
fsu.AddUintXX(d.arch, uint64(len(d.ldr.Data(fn))), d.arch.PtrSize) // address range
fsu.AddBytes(deltaBuf)
sb.setReachable()
return sb.addSymRef(tgt, 0, objabi.R_SIZE, arch.PtrSize)
}
+
+// GenAddAddrPlusFunc returns a function to be called when capturing
+// a function symbol's address. In later stages of the link (when
+// address assignment is done) when doing internal linking and
+// targeting an executable, we can just emit the address of a function
+// directly instead of generating a relocation. Clients can call
+// this function (setting 'internalExec' based on build mode and target)
+// and then invoke the returned function in roughly the same way that
+// loader.*SymbolBuilder.AddAddrPlus would be used.
+func GenAddAddrPlusFunc(internalExec bool) func(s *SymbolBuilder, arch *sys.Arch, tgt Sym, add int64) int64 {
+ if internalExec {
+ return func(s *SymbolBuilder, arch *sys.Arch, tgt Sym, add int64) int64 {
+ if v := s.l.SymValue(tgt); v != 0 {
+ return s.AddUint(arch, uint64(v+add))
+ }
+ return s.AddAddrPlus(arch, tgt, add)
+ }
+ } else {
+ return (*SymbolBuilder).AddAddrPlus
+ }
+}