mklinknames.awk 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. # Copyright 2020 The Go Authors. All rights reserved.
  2. # Use of this source code is governed by a BSD-style
  3. # license that can be found in the LICENSE file.
  4. # This AWK script reads a Go file with special //extern-sysinfo
  5. # comments annotating functions which should be linked to libc
  6. # functions. It generates a Go file containing the appropriate
  7. # //go:linkname directives.
  8. #
  9. # For each annotated function, the script searches gen-sysinfo.go
  10. # to see if a different assembly name is known for the function.
  11. # For example, on NetBSD, the timegm symbol is renamed to
  12. # __timegm50 by an __asm__ annotation on its declaration in time.h.
  13. BEGIN {
  14. print "// Code generated by mklinknames.awk. DO NOT EDIT."
  15. print ""
  16. print "package", package
  17. print ""
  18. print "import _ \"unsafe\""
  19. print ""
  20. }
  21. /^\/\/extern-sysinfo/ {
  22. cfnname = $2
  23. getline
  24. if ($1 != "func") {
  25. printf("mklinknames.awk: error: %s:%d: unattached extern-sysinfo directive\n", FILENAME, FNR) | "cat 1>&2"
  26. exit 1
  27. }
  28. split($2, a, "(")
  29. gofnname = a[1]
  30. def = sprintf("grep '^func _%s[ (]' gen-sysinfo.go", cfnname)
  31. # def looks like one of the following:
  32. # func _timegm (*_tm) int64 __asm__("__timegm50")
  33. # func _timegm (*_tm) int64 __asm__("*__timegm50")
  34. # The goal is to extract "__timegm50".
  35. if ((def | getline fndef) > 0 && match(fndef, "__asm__\\(\"\\*?")) {
  36. asmname = substr(fndef, RSTART + RLENGTH)
  37. asmname = substr(asmname, 0, length(asmname) - 2)
  38. printf("//go:linkname %s %s\n", gofnname, asmname)
  39. } else {
  40. # Assume the asm name is the same as the declared C name.
  41. printf("//go:linkname %s %s\n", gofnname, cfnname)
  42. }
  43. }