$OpenBSD: patch-src_cmd_ld_elf_c,v 1.1 2012/09/19 21:10:38 sthen Exp $
--- src/cmd/ld/elf.c.orig	Thu Jun 14 04:23:38 2012
+++ src/cmd/ld/elf.c	Mon Sep 17 11:38:32 2012
@@ -348,20 +348,16 @@ elfwriteinterp(vlong stridx)
 	return sh->size;
 }
 
-// Defined in NetBSD's sys/exec_elf.h
-#define ELF_NOTE_TYPE_NETBSD_TAG	1
-#define ELF_NOTE_NETBSD_NAMESZ		7
-#define ELF_NOTE_NETBSD_DESCSZ		4
-#define ELF_NOTE_NETBSD_NAME		"NetBSD\0\0"
-#define ELF_NOTE_NETBSD_VERSION		599000000	/* NetBSD 5.99 */
-
 int
-elfnetbsdsig(ElfShdr *sh, uint64 startva, uint64 resoff)
+elfnote(ElfShdr *sh, uint64 startva, uint64 resoff, int sz)
 {
-	int n;
+	uint64 n;
 
-	n = sizeof(Elf_Note) + ELF_NOTE_NETBSD_NAMESZ + ELF_NOTE_NETBSD_DESCSZ + 1;
-	n += resoff % 4;
+	n = sizeof(Elf_Note) + sz + resoff % 4;
+
+	sh->type = SHT_NOTE;
+	sh->flags = SHF_ALLOC;
+	sh->addralign = 4;
 	sh->addr = startva + resoff - n;
 	sh->off = resoff - n;
 	sh->size = n;
@@ -369,8 +365,9 @@ elfnetbsdsig(ElfShdr *sh, uint64 startva, uint64 resof
 	return n;
 }
 
-int
-elfwritenetbsdsig(vlong stridx) {
+ElfShdr *
+elfwritenotehdr(vlong stridx, uint32 namesz, uint32 descsz, uint32 tag)
+{
 	ElfShdr *sh = nil;
 	int i;
 
@@ -378,15 +375,79 @@ elfwritenetbsdsig(vlong stridx) {
 		if(shdr[i]->name == stridx)
 			sh = shdr[i];
 	if(sh == nil)
-		return 0;
+		return nil;
 
-	// Write Elf_Note header followed by NetBSD string.
+	// Write Elf_Note header.
 	cseek(sh->off);
-	LPUT(ELF_NOTE_NETBSD_NAMESZ);
-	LPUT(ELF_NOTE_NETBSD_DESCSZ);
-	LPUT(ELF_NOTE_TYPE_NETBSD_TAG);
-	cwrite(ELF_NOTE_NETBSD_NAME, 8);
+	LPUT(namesz);
+	LPUT(descsz);
+	LPUT(tag);
+
+	return sh;
+}
+
+// NetBSD Signature (as per sys/exec_elf.h)
+#define ELF_NOTE_NETBSD_NAMESZ		7
+#define ELF_NOTE_NETBSD_DESCSZ		4
+#define ELF_NOTE_NETBSD_TAG		1
+#define ELF_NOTE_NETBSD_NAME		"NetBSD\0\0"
+#define ELF_NOTE_NETBSD_VERSION		599000000	/* NetBSD 5.99 */
+
+int
+elfnetbsdsig(ElfShdr *sh, uint64 startva, uint64 resoff)
+{
+	int n;
+
+	n = ELF_NOTE_NETBSD_NAMESZ + ELF_NOTE_NETBSD_DESCSZ + 1;
+	return elfnote(sh, startva, resoff, n);
+}
+
+int
+elfwritenetbsdsig(vlong stridx)
+{
+	ElfShdr *sh;
+
+	// Write Elf_Note header.
+	sh = elfwritenotehdr(stridx, ELF_NOTE_NETBSD_NAMESZ, ELF_NOTE_NETBSD_DESCSZ, ELF_NOTE_NETBSD_TAG);
+	if(sh == nil)
+		return 0;
+
+	// Followed by NetBSD string and version.
+	cwrite(ELF_NOTE_NETBSD_NAME, ELF_NOTE_NETBSD_NAMESZ + 1);
 	LPUT(ELF_NOTE_NETBSD_VERSION);
+
+	return sh->size;
+}
+
+// OpenBSD Signature
+#define ELF_NOTE_OPENBSD_NAMESZ		8
+#define ELF_NOTE_OPENBSD_DESCSZ		4
+#define ELF_NOTE_OPENBSD_TAG		1
+#define ELF_NOTE_OPENBSD_NAME		"OpenBSD\0"
+#define ELF_NOTE_OPENBSD_VERSION	0
+
+int
+elfopenbsdsig(ElfShdr *sh, uint64 startva, uint64 resoff)
+{
+	int n;
+
+	n = ELF_NOTE_OPENBSD_NAMESZ + ELF_NOTE_OPENBSD_DESCSZ;
+	return elfnote(sh, startva, resoff, n);
+}
+
+int
+elfwriteopenbsdsig(vlong stridx)
+{
+	ElfShdr *sh;
+
+	// Write Elf_Note header.
+	sh = elfwritenotehdr(stridx, ELF_NOTE_OPENBSD_NAMESZ, ELF_NOTE_OPENBSD_DESCSZ, ELF_NOTE_OPENBSD_TAG);
+	if(sh == nil)
+		return 0;
+
+	// Followed by OpenBSD string and version.
+	cwrite(ELF_NOTE_OPENBSD_NAME, ELF_NOTE_OPENBSD_NAMESZ);
+	LPUT(ELF_NOTE_OPENBSD_VERSION);
 
 	return sh->size;
 }
