mirror of https://github.com/golang/go.git
cmd/link: define ELF .note section on FreeBSD
Write .note signature section when targeting FreeBSD, similar to NetBSD and OpenBSD. This allows binaries to declare the ABI version they were compiled for and opt out of ASLR when compiled with -race. Fixes #48164 Change-Id: Ie54dd5c70697a3f42a75fd640540350fd8a4dc71 Reviewed-on: https://go-review.googlesource.com/c/go/+/412494 Reviewed-by: Meng Zhuo <mzh@golangcn.org> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: Than McIntosh <thanm@google.com> Reviewed-by: Yuval Pavel Zholkover <paulzhol@gmail.com>
This commit is contained in:
parent
005c78d8bb
commit
c79b2009ef
|
|
@ -204,8 +204,8 @@ func TestMergeNoteSections(t *testing.T) {
|
|||
expected := 1
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "linux", "freebsd", "dragonfly":
|
||||
case "openbsd", "netbsd":
|
||||
case "linux", "dragonfly":
|
||||
case "openbsd", "netbsd", "freebsd":
|
||||
// These OSes require independent segment
|
||||
expected = 2
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -607,8 +607,13 @@ func elfWriteMipsAbiFlags(ctxt *Link) int {
|
|||
return int(sh.Size)
|
||||
}
|
||||
|
||||
func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sz int) int {
|
||||
n := 3*4 + uint64(sz) + resoff%4
|
||||
func elfnote(sh *ElfShdr, startva uint64, resoff uint64, sizes ...int) int {
|
||||
n := resoff % 4
|
||||
// if section contains multiple notes (as is the case with FreeBSD signature),
|
||||
// multiple note sizes can be specified
|
||||
for _, sz := range sizes {
|
||||
n += 3*4 + uint64(sz)
|
||||
}
|
||||
|
||||
sh.Type = uint32(elf.SHT_NOTE)
|
||||
sh.Flags = uint64(elf.SHF_ALLOC)
|
||||
|
|
@ -714,6 +719,67 @@ func elfwriteopenbsdsig(out *OutBuf) int {
|
|||
return int(sh.Size)
|
||||
}
|
||||
|
||||
// FreeBSD Signature (as per sys/elf_common.h)
|
||||
const (
|
||||
ELF_NOTE_FREEBSD_NAMESZ = 8
|
||||
ELF_NOTE_FREEBSD_DESCSZ = 4
|
||||
ELF_NOTE_FREEBSD_ABI_TAG = 1
|
||||
ELF_NOTE_FREEBSD_NOINIT_TAG = 2
|
||||
ELF_NOTE_FREEBSD_FEATURE_CTL_TAG = 4
|
||||
ELF_NOTE_FREEBSD_VERSION = 1203000 // 12.3-RELEASE
|
||||
ELF_NOTE_FREEBSD_FCTL_ASLR_DISABLE = 0x1
|
||||
)
|
||||
|
||||
const ELF_NOTE_FREEBSD_NAME = "FreeBSD\x00"
|
||||
|
||||
func elffreebsdsig(sh *ElfShdr, startva uint64, resoff uint64) int {
|
||||
n := ELF_NOTE_FREEBSD_NAMESZ + ELF_NOTE_FREEBSD_DESCSZ
|
||||
// FreeBSD signature section contains 3 equally sized notes
|
||||
return elfnote(sh, startva, resoff, n, n, n)
|
||||
}
|
||||
|
||||
// elfwritefreebsdsig writes FreeBSD .note section.
|
||||
//
|
||||
// See https://www.netbsd.org/docs/kernel/elf-notes.html for the description of
|
||||
// a Note element format and
|
||||
// https://github.com/freebsd/freebsd-src/blob/main/sys/sys/elf_common.h#L790
|
||||
// for the FreeBSD-specific values.
|
||||
func elfwritefreebsdsig(out *OutBuf) int {
|
||||
sh := elfshname(".note.tag")
|
||||
if sh == nil {
|
||||
return 0
|
||||
}
|
||||
out.SeekSet(int64(sh.Off))
|
||||
|
||||
// NT_FREEBSD_ABI_TAG
|
||||
out.Write32(ELF_NOTE_FREEBSD_NAMESZ)
|
||||
out.Write32(ELF_NOTE_FREEBSD_DESCSZ)
|
||||
out.Write32(ELF_NOTE_FREEBSD_ABI_TAG)
|
||||
out.WriteString(ELF_NOTE_FREEBSD_NAME)
|
||||
out.Write32(ELF_NOTE_FREEBSD_VERSION)
|
||||
|
||||
// NT_FREEBSD_NOINIT_TAG
|
||||
out.Write32(ELF_NOTE_FREEBSD_NAMESZ)
|
||||
out.Write32(ELF_NOTE_FREEBSD_DESCSZ)
|
||||
out.Write32(ELF_NOTE_FREEBSD_NOINIT_TAG)
|
||||
out.WriteString(ELF_NOTE_FREEBSD_NAME)
|
||||
out.Write32(0)
|
||||
|
||||
// NT_FREEBSD_FEATURE_CTL
|
||||
out.Write32(ELF_NOTE_FREEBSD_NAMESZ)
|
||||
out.Write32(ELF_NOTE_FREEBSD_DESCSZ)
|
||||
out.Write32(ELF_NOTE_FREEBSD_FEATURE_CTL_TAG)
|
||||
out.WriteString(ELF_NOTE_FREEBSD_NAME)
|
||||
if *flagRace {
|
||||
// The race detector can't handle ASLR, turn the ASLR off when compiling with -race.
|
||||
out.Write32(ELF_NOTE_FREEBSD_FCTL_ASLR_DISABLE)
|
||||
} else {
|
||||
out.Write32(0)
|
||||
}
|
||||
|
||||
return int(sh.Size)
|
||||
}
|
||||
|
||||
func addbuildinfo(val string) {
|
||||
if !strings.HasPrefix(val, "0x") {
|
||||
Exitf("-B argument must start with 0x: %s", val)
|
||||
|
|
@ -1327,6 +1393,9 @@ func (ctxt *Link) doelf() {
|
|||
if ctxt.IsOpenbsd() {
|
||||
shstrtab.Addstring(".note.openbsd.ident")
|
||||
}
|
||||
if ctxt.IsFreebsd() {
|
||||
shstrtab.Addstring(".note.tag")
|
||||
}
|
||||
if len(buildinfo) > 0 {
|
||||
shstrtab.Addstring(".note.gnu.build-id")
|
||||
}
|
||||
|
|
@ -1820,7 +1889,7 @@ func asmbElf(ctxt *Link) {
|
|||
phsh(ph, sh)
|
||||
}
|
||||
|
||||
if ctxt.HeadType == objabi.Hnetbsd || ctxt.HeadType == objabi.Hopenbsd {
|
||||
if ctxt.HeadType == objabi.Hnetbsd || ctxt.HeadType == objabi.Hopenbsd || ctxt.HeadType == objabi.Hfreebsd {
|
||||
var sh *ElfShdr
|
||||
switch ctxt.HeadType {
|
||||
case objabi.Hnetbsd:
|
||||
|
|
@ -1830,8 +1899,12 @@ func asmbElf(ctxt *Link) {
|
|||
case objabi.Hopenbsd:
|
||||
sh = elfshname(".note.openbsd.ident")
|
||||
resoff -= int64(elfopenbsdsig(sh, uint64(startva), uint64(resoff)))
|
||||
|
||||
case objabi.Hfreebsd:
|
||||
sh = elfshname(".note.tag")
|
||||
resoff -= int64(elffreebsdsig(sh, uint64(startva), uint64(resoff)))
|
||||
}
|
||||
// netbsd and openbsd require ident in an independent segment.
|
||||
// NetBSD, OpenBSD and FreeBSD require ident in an independent segment.
|
||||
pnotei := newElfPhdr()
|
||||
pnotei.Type = elf.PT_NOTE
|
||||
pnotei.Flags = elf.PF_R
|
||||
|
|
@ -2209,6 +2282,9 @@ elfobj:
|
|||
if ctxt.HeadType == objabi.Hopenbsd {
|
||||
a += int64(elfwriteopenbsdsig(ctxt.Out))
|
||||
}
|
||||
if ctxt.HeadType == objabi.Hfreebsd {
|
||||
a += int64(elfwritefreebsdsig(ctxt.Out))
|
||||
}
|
||||
if len(buildinfo) > 0 {
|
||||
a += int64(elfwritebuildinfo(ctxt.Out))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,6 +176,11 @@ func (t *Target) IsOpenbsd() bool {
|
|||
return t.HeadType == objabi.Hopenbsd
|
||||
}
|
||||
|
||||
func (t *Target) IsFreebsd() bool {
|
||||
t.mustSetHeadType()
|
||||
return t.HeadType == objabi.Hfreebsd
|
||||
}
|
||||
|
||||
func (t *Target) mustSetHeadType() {
|
||||
if t.HeadType == objabi.Hunknown {
|
||||
panic("HeadType is not set")
|
||||
|
|
|
|||
Loading…
Reference in New Issue