@@ -607,8 +607,13 @@ func elfWriteMipsAbiFlags(ctxt *Link) int {
607
607
return int (sh .Size )
608
608
}
609
609
610
- func elfnote (sh * ElfShdr , startva uint64 , resoff uint64 , sz int ) int {
611
- n := 3 * 4 + uint64 (sz ) + resoff % 4
610
+ func elfnote (sh * ElfShdr , startva uint64 , resoff uint64 , sizes ... int ) int {
611
+ n := resoff % 4
612
+ // if section contains multiple notes (as is the case with FreeBSD signature),
613
+ // multiple note sizes can be specified
614
+ for _ , sz := range sizes {
615
+ n += 3 * 4 + uint64 (sz )
616
+ }
612
617
613
618
sh .Type = uint32 (elf .SHT_NOTE )
614
619
sh .Flags = uint64 (elf .SHF_ALLOC )
@@ -714,6 +719,67 @@ func elfwriteopenbsdsig(out *OutBuf) int {
714
719
return int (sh .Size )
715
720
}
716
721
722
+ // FreeBSD Signature (as per sys/elf_common.h)
723
+ const (
724
+ ELF_NOTE_FREEBSD_NAMESZ = 8
725
+ ELF_NOTE_FREEBSD_DESCSZ = 4
726
+ ELF_NOTE_FREEBSD_ABI_TAG = 1
727
+ ELF_NOTE_FREEBSD_NOINIT_TAG = 2
728
+ ELF_NOTE_FREEBSD_FEATURE_CTL_TAG = 4
729
+ ELF_NOTE_FREEBSD_VERSION = 1203000 // 12.3-RELEASE
730
+ ELF_NOTE_FREEBSD_FCTL_ASLR_DISABLE = 0x1
731
+ )
732
+
733
+ const ELF_NOTE_FREEBSD_NAME = "FreeBSD\x00 "
734
+
735
+ func elffreebsdsig (sh * ElfShdr , startva uint64 , resoff uint64 ) int {
736
+ n := ELF_NOTE_FREEBSD_NAMESZ + ELF_NOTE_FREEBSD_DESCSZ
737
+ // FreeBSD signature section contains 3 equally sized notes
738
+ return elfnote (sh , startva , resoff , n , n , n )
739
+ }
740
+
741
+ // elfwritefreebsdsig writes FreeBSD .note section.
742
+ //
743
+ // See https://www.netbsd.org/docs/kernel/elf-notes.html for the description of
744
+ // a Note element format and
745
+ // https://github.com/freebsd/freebsd-src/blob/main/sys/sys/elf_common.h#L790
746
+ // for the FreeBSD-specific values.
747
+ func elfwritefreebsdsig (out * OutBuf ) int {
748
+ sh := elfshname (".note.tag" )
749
+ if sh == nil {
750
+ return 0
751
+ }
752
+ out .SeekSet (int64 (sh .Off ))
753
+
754
+ // NT_FREEBSD_ABI_TAG
755
+ out .Write32 (ELF_NOTE_FREEBSD_NAMESZ )
756
+ out .Write32 (ELF_NOTE_FREEBSD_DESCSZ )
757
+ out .Write32 (ELF_NOTE_FREEBSD_ABI_TAG )
758
+ out .WriteString (ELF_NOTE_FREEBSD_NAME )
759
+ out .Write32 (ELF_NOTE_FREEBSD_VERSION )
760
+
761
+ // NT_FREEBSD_NOINIT_TAG
762
+ out .Write32 (ELF_NOTE_FREEBSD_NAMESZ )
763
+ out .Write32 (ELF_NOTE_FREEBSD_DESCSZ )
764
+ out .Write32 (ELF_NOTE_FREEBSD_NOINIT_TAG )
765
+ out .WriteString (ELF_NOTE_FREEBSD_NAME )
766
+ out .Write32 (0 )
767
+
768
+ // NT_FREEBSD_FEATURE_CTL
769
+ out .Write32 (ELF_NOTE_FREEBSD_NAMESZ )
770
+ out .Write32 (ELF_NOTE_FREEBSD_DESCSZ )
771
+ out .Write32 (ELF_NOTE_FREEBSD_FEATURE_CTL_TAG )
772
+ out .WriteString (ELF_NOTE_FREEBSD_NAME )
773
+ if * flagRace {
774
+ // The race detector can't handle ASLR, turn the ASLR off when compiling with -race.
775
+ out .Write32 (ELF_NOTE_FREEBSD_FCTL_ASLR_DISABLE )
776
+ } else {
777
+ out .Write32 (0 )
778
+ }
779
+
780
+ return int (sh .Size )
781
+ }
782
+
717
783
func addbuildinfo (val string ) {
718
784
if ! strings .HasPrefix (val , "0x" ) {
719
785
Exitf ("-B argument must start with 0x: %s" , val )
@@ -1327,6 +1393,9 @@ func (ctxt *Link) doelf() {
1327
1393
if ctxt .IsOpenbsd () {
1328
1394
shstrtab .Addstring (".note.openbsd.ident" )
1329
1395
}
1396
+ if ctxt .IsFreebsd () {
1397
+ shstrtab .Addstring (".note.tag" )
1398
+ }
1330
1399
if len (buildinfo ) > 0 {
1331
1400
shstrtab .Addstring (".note.gnu.build-id" )
1332
1401
}
@@ -1820,7 +1889,7 @@ func asmbElf(ctxt *Link) {
1820
1889
phsh (ph , sh )
1821
1890
}
1822
1891
1823
- if ctxt .HeadType == objabi .Hnetbsd || ctxt .HeadType == objabi .Hopenbsd {
1892
+ if ctxt .HeadType == objabi .Hnetbsd || ctxt .HeadType == objabi .Hopenbsd || ctxt . HeadType == objabi . Hfreebsd {
1824
1893
var sh * ElfShdr
1825
1894
switch ctxt .HeadType {
1826
1895
case objabi .Hnetbsd :
@@ -1830,8 +1899,12 @@ func asmbElf(ctxt *Link) {
1830
1899
case objabi .Hopenbsd :
1831
1900
sh = elfshname (".note.openbsd.ident" )
1832
1901
resoff -= int64 (elfopenbsdsig (sh , uint64 (startva ), uint64 (resoff )))
1902
+
1903
+ case objabi .Hfreebsd :
1904
+ sh = elfshname (".note.tag" )
1905
+ resoff -= int64 (elffreebsdsig (sh , uint64 (startva ), uint64 (resoff )))
1833
1906
}
1834
- // netbsd and openbsd require ident in an independent segment.
1907
+ // NetBSD, OpenBSD and FreeBSD require ident in an independent segment.
1835
1908
pnotei := newElfPhdr ()
1836
1909
pnotei .Type = elf .PT_NOTE
1837
1910
pnotei .Flags = elf .PF_R
@@ -2209,6 +2282,9 @@ elfobj:
2209
2282
if ctxt .HeadType == objabi .Hopenbsd {
2210
2283
a += int64 (elfwriteopenbsdsig (ctxt .Out ))
2211
2284
}
2285
+ if ctxt .HeadType == objabi .Hfreebsd {
2286
+ a += int64 (elfwritefreebsdsig (ctxt .Out ))
2287
+ }
2212
2288
if len (buildinfo ) > 0 {
2213
2289
a += int64 (elfwritebuildinfo (ctxt .Out ))
2214
2290
}
0 commit comments