# Copyright 2020 The Go Authors. All rights reserved. # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. # This AWK script reads a Go file with special //extern-sysinfo # comments annotating functions which should be linked to libc # functions. It generates a Go file containing the appropriate # //go:linkname directives. # # For each annotated function, the script searches gen-sysinfo.go # to see if a different assembly name is known for the function. # For example, on NetBSD, the timegm symbol is renamed to # __timegm50 by an __asm__ annotation on its declaration in time.h. BEGIN { print "// Code generated by mklinknames.awk. DO NOT EDIT." print "" print "package", package print "" print "import _ \"unsafe\"" print "" } /^\/\/extern-sysinfo/ { cfnname = $2 getline if ($1 != "func") { printf("mklinknames.awk: error: %s:%d: unattached extern-sysinfo directive\n", FILENAME, FNR) | "cat 1>&2" exit 1 } split($2, a, "(") gofnname = a[1] def = sprintf("grep '^func _%s[ (]' gen-sysinfo.go", cfnname) # def looks like one of the following: # func _timegm (*_tm) int64 __asm__("__timegm50") # func _timegm (*_tm) int64 __asm__("*__timegm50") # The goal is to extract "__timegm50". if ((def | getline fndef) > 0 && match(fndef, "__asm__\\(\"\\*?")) { asmname = substr(fndef, RSTART + RLENGTH) asmname = substr(asmname, 0, length(asmname) - 2) printf("//go:linkname %s %s\n", gofnname, asmname) } else { # Assume the asm name is the same as the declared C name. printf("//go:linkname %s %s\n", gofnname, cfnname) } }