mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.link] cmd/link: support new object file format
Parse new object file format in the linker. At least we can link a hello-world program. Add a basic "loader", which handles symbol references in the object file. - mapping between local and global indices - resolve by-name references (TODO: the overwrite logic isn't implemented yet) Currently we still create sym.Symbol rather early, and, after all the object files are loaded and indexed references are resolved, add all symbols to sym.Symbols. The code here is probably not going in the final version. This is basically only for debugging purposes -- to make sure the writer and the reader work as expected. Change-Id: I895aeea68326fabdb7e5aa1371b8cac7211a09dd Reviewed-on: https://go-review.googlesource.com/c/go/+/196032 Run-TryBot: Cherry Zhang <cherryyz@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
d79380026c
commit
6051fd0ad9
7 changed files with 513 additions and 12 deletions
|
|
@ -375,15 +375,8 @@ func (ctxt *Link) findLibPath(libname string) string {
|
|||
}
|
||||
|
||||
func (ctxt *Link) loadlib() {
|
||||
switch ctxt.BuildMode {
|
||||
case BuildModeCShared, BuildModePlugin:
|
||||
s := ctxt.Syms.Lookup("runtime.islibrary", 0)
|
||||
s.Attr |= sym.AttrDuplicateOK
|
||||
s.AddUint8(1)
|
||||
case BuildModeCArchive:
|
||||
s := ctxt.Syms.Lookup("runtime.isarchive", 0)
|
||||
s.Attr |= sym.AttrDuplicateOK
|
||||
s.AddUint8(1)
|
||||
if *flagNewobj {
|
||||
ctxt.loader = objfile.NewLoader()
|
||||
}
|
||||
|
||||
loadinternal(ctxt, "runtime")
|
||||
|
|
@ -408,6 +401,11 @@ func (ctxt *Link) loadlib() {
|
|||
}
|
||||
}
|
||||
|
||||
// XXX do it here for now
|
||||
if *flagNewobj {
|
||||
ctxt.loadlibfull()
|
||||
}
|
||||
|
||||
for _, lib := range ctxt.Library {
|
||||
if lib.Shlib != "" {
|
||||
if ctxt.Debugvlog > 1 {
|
||||
|
|
@ -417,6 +415,19 @@ func (ctxt *Link) loadlib() {
|
|||
}
|
||||
}
|
||||
|
||||
switch ctxt.BuildMode {
|
||||
case BuildModeCShared, BuildModePlugin:
|
||||
s := ctxt.Syms.Lookup("runtime.islibrary", 0)
|
||||
s.Type = sym.SNOPTRDATA
|
||||
s.Attr |= sym.AttrDuplicateOK
|
||||
s.AddUint8(1)
|
||||
case BuildModeCArchive:
|
||||
s := ctxt.Syms.Lookup("runtime.isarchive", 0)
|
||||
s.Type = sym.SNOPTRDATA
|
||||
s.Attr |= sym.AttrDuplicateOK
|
||||
s.AddUint8(1)
|
||||
}
|
||||
|
||||
iscgo = ctxt.Syms.ROLookup("x_cgo_init", 0) != nil
|
||||
|
||||
// We now have enough information to determine the link mode.
|
||||
|
|
@ -843,7 +854,7 @@ func loadobjfile(ctxt *Link, lib *sym.Library) {
|
|||
if err != nil {
|
||||
Exitf("cannot open file %s: %v", lib.File, err)
|
||||
}
|
||||
defer f.Close()
|
||||
//defer f.Close()
|
||||
defer func() {
|
||||
if pkg == "main" && !lib.Main {
|
||||
Exitf("%s: not package main", lib.File)
|
||||
|
|
@ -1773,7 +1784,12 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string,
|
|||
default:
|
||||
log.Fatalf("invalid -strictdups flag value %d", *FlagStrictDups)
|
||||
}
|
||||
c := objfile.Load(ctxt.Arch, ctxt.Syms, f, lib, unit, eof-f.Offset(), pn, flags)
|
||||
var c int
|
||||
if *flagNewobj {
|
||||
objfile.LoadNew(ctxt.loader, ctxt.Arch, ctxt.Syms, f, lib, unit, eof-f.Offset(), pn, flags)
|
||||
} else {
|
||||
c = objfile.Load(ctxt.Arch, ctxt.Syms, f, lib, unit, eof-f.Offset(), pn, flags)
|
||||
}
|
||||
strictDupMsgCount += c
|
||||
addImports(ctxt, lib, pn)
|
||||
return nil
|
||||
|
|
@ -2545,3 +2561,40 @@ func dfs(lib *sym.Library, mark map[*sym.Library]markKind, order *[]*sym.Library
|
|||
mark[lib] = visited
|
||||
*order = append(*order, lib)
|
||||
}
|
||||
|
||||
func (ctxt *Link) loadlibfull() {
|
||||
// Add references of externally defined symbols.
|
||||
for _, lib := range ctxt.Library {
|
||||
for _, r := range lib.Readers {
|
||||
objfile.LoadRefs(ctxt.loader, r.Reader, lib, ctxt.Arch, ctxt.Syms, r.Version)
|
||||
}
|
||||
}
|
||||
|
||||
// Load full symbol contents, resolve indexed references.
|
||||
for _, lib := range ctxt.Library {
|
||||
for _, r := range lib.Readers {
|
||||
objfile.LoadFull(ctxt.loader, r.Reader, lib, ctxt.Syms, r.Version, ctxt.LibraryByPkg)
|
||||
}
|
||||
}
|
||||
|
||||
// For now, add all symbols to ctxt.Syms.
|
||||
for _, s := range ctxt.loader.Syms {
|
||||
if s != nil && s.Name != "" {
|
||||
ctxt.Syms.Add(s)
|
||||
}
|
||||
}
|
||||
|
||||
// Now load cgo directives.
|
||||
for _, p := range ctxt.cgodata {
|
||||
loadcgo(ctxt, p[0], p[1], p[2])
|
||||
}
|
||||
}
|
||||
|
||||
func (ctxt *Link) dumpsyms() {
|
||||
for _, s := range ctxt.Syms.Allsym {
|
||||
fmt.Printf("%s %s %p\n", s, s.Type, s)
|
||||
for i := range s.R {
|
||||
fmt.Println("\t", s.R[i].Type, s.R[i].Sym)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue