// files read from the package directory or subdirectories at compile time.
//
// For example, here are three ways to embed a file named hello.txt
- // and then print its contents at run time:
+ // and then print its contents at run time.
//
- // import "embed"
+ // Embedding one file into a string:
+ //
+ // import _ "embed"
//
// //go:embed hello.txt
// var s string
// print(s)
//
+ // Embedding one file into a slice of bytes:
+ //
+ // import _ "embed"
+ //
// //go:embed hello.txt
// var b []byte
// print(string(b))
//
+ // Embedded one or more files into a file system:
+ //
+ // import "embed"
+ //
// //go:embed hello.txt
// var f embed.FS
// data, _ := f.ReadFile("hello.txt")
// The directive must immediately precede a line containing the declaration of a single variable.
// Only blank lines and ‘//’ line comments are permitted between the directive and the declaration.
//
- // The variable must be of type string, []byte, or FS exactly. Named types or type aliases
- // derived from those types are not allowed.
+ // The type of the variable must be a string type, or a slice of a byte type,
+ // or FS (or an alias of FS).
//
// For example:
//
//
// The //go:embed directive can be used with both exported and unexported variables,
// depending on whether the package wants to make the data available to other packages.
- // Similarly, it can be used with both global and function-local variables,
- // depending on what is more convenient in context.
+ // It can only be used with global variables at package scope,
+ // not with local variables.
//
// Patterns must not match files outside the package's module, such as ‘.git/*’ or symbolic links.
// Matches for empty directories are ignored. After that, each pattern in a //go:embed line
// See the package documentation for more details about initializing an FS.
type FS struct {
// The compiler knows the layout of this struct.
- // See cmd/compile/internal/gc's initEmbed.
+ // See cmd/compile/internal/staticdata's WriteEmbed.
//
// The files list is sorted by name but not by simple string comparison.
// Instead, each file's name takes the form "dir/elem" or "dir/elem/".
// It implements fs.FileInfo and fs.DirEntry.
type file struct {
// The compiler knows the layout of this struct.
- // See cmd/compile/internal/gc's initEmbed.
+ // See cmd/compile/internal/staticdata's WriteEmbed.
name string
data string
hash [16]byte // truncated SHA256 hash
my $netbsd = 0;
my $dragonfly = 0;
my $arm = 0; # 64-bit value should use (even, odd)-pair
+ my $libc = 0;
my $tags = ""; # build tags
if($ARGV[0] eq "-b32") {
}
if($ARGV[0] eq "-darwin") {
$darwin = 1;
+ $libc = 1;
shift;
}
if($ARGV[0] eq "-openbsd") {
$arm = 1;
shift;
}
+ if($ARGV[0] eq "-libc") {
+ $libc = 1;
+ shift;
+ }
if($ARGV[0] eq "-tags") {
shift;
$tags = $ARGV[0];
# without reading the header.
$text .= "// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT\n\n";
- if ($darwin && $func eq "ptrace1") {
+ if (($darwin || ($openbsd && $libc)) && $func eq "ptrace") {
# The ptrace function is called from forkAndExecInChild where stack
# growth is forbidden.
$text .= "//go:nosplit\n"
push @args, "uintptr(_p$n)", "uintptr(len($name))";
$n++;
} elsif($type eq "int64" && ($openbsd || $netbsd)) {
- push @args, "0";
+ if (!$libc) {
+ push @args, "0";
+ }
if($_32bit eq "big-endian") {
push @args, "uintptr($name>>32)", "uintptr($name)";
} elsif($_32bit eq "little-endian") {
$asm = "RawSyscall";
}
}
- if ($darwin) {
+ if ($libc) {
# Call unexported syscall functions (which take
# libc functions instead of syscall numbers).
$asm = lcfirst($asm);
print STDERR "$ARGV:$.: too many arguments to system call\n";
}
- if ($darwin) {
+ if ($darwin || ($openbsd && $libc)) {
# Use extended versions for calls that generate a 64-bit result.
my ($name, $type) = parseparam($out[0]);
if ($type eq "int64" || ($type eq "uintptr" && $_32bit eq "")) {
$sysname = "SYS_$func";
$sysname =~ s/([a-z])([A-Z])/${1}_$2/g; # turn FooBar into Foo_Bar
$sysname =~ y/a-z/A-Z/;
- if($darwin) {
+ if($libc) {
$sysname =~ y/A-Z/a-z/;
$sysname = substr $sysname, 4;
$funcname = "libc_$sysname";
}
}
- if($darwin) {
+ if($libc) {
if($funcname eq "") {
$sysname = substr $sysname, 4;
$funcname = "libc_$sysname";
}
$text .= "\treturn\n";
$text .= "}\n\n";
- if($darwin) {
+ if($libc) {
if (not exists $trampolines{$funcname}) {
$trampolines{$funcname} = 1;
# The assembly trampoline that jumps to the libc routine.
$text .= "func ${funcname}_trampoline()\n";
- # Map syscall.funcname to just plain funcname.
- # (The jump to this function is in the assembly trampoline, generated by mkasm.go.)
- $text .= "//go:linkname $funcname $funcname\n";
# Tell the linker that funcname can be found in libSystem using varname without the libc_ prefix.
my $basename = substr $funcname, 5;
- $text .= "//go:cgo_import_dynamic $funcname $basename \"/usr/lib/libSystem.B.dylib\"\n\n";
+ my $libc = "libc.so";
+ if ($darwin) {
+ $libc = "/usr/lib/libSystem.B.dylib";
+ }
+ $text .= "//go:cgo_import_dynamic $funcname $basename \"$libc\"\n\n";
}
}
}