| # 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) |
| } |
| } |