// Inittasks finds inittask records, figures out a good // order to execute them in, and emits that order for the // runtime to use. // // An inittask represents the initialization code that needs // to be run for a package. For package p, the p..inittask // symbol contains a list of init functions to run, both // explicit user init functions and implicit compiler-generated // init functions for initializing global variables like maps. // // In addition, inittask records have dependencies between each // other, mirroring the import dependencies. So if package p // imports package q, then there will be a dependency p -> q. // We can't initialize package p until after package q has // already been initialized. // // Package dependencies are encoded with relocations. If package // p imports package q, then package p's inittask record will // have a R_INITORDER relocation pointing to package q's inittask // record. See cmd/compile/internal/pkginit/init.go. // // This function computes an ordering of all of the inittask // records so that the order respects all the dependencies, // and given that restriction, orders the inittasks in // lexicographic order. func (ctxt *Link) inittasks() { … } // inittaskSym builds a symbol containing pointers to all the inittasks // that need to be run, given a list of root inittask symbols. func (ctxt *Link) inittaskSym(rootNames []string, symName string) loader.Sym { … }