ElfStrGnuVersion,
ElfStrGnuVersionR,
ElfStrNoteNetbsdIdent,
+ ElfStrNoteOpenbsdIdent,
ElfStrNoPtrData,
ElfStrNoPtrBss,
NElfStr
elfstr[ElfStrNoPtrBss] = addstring(shstrtab, ".noptrbss");
if(HEADTYPE == Hnetbsd)
elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
+ if(HEADTYPE == Hopenbsd)
+ elfstr[ElfStrNoteOpenbsdIdent] = addstring(shstrtab, ".note.openbsd.ident");
addstring(shstrtab, ".rodata");
addstring(shstrtab, ".gcdata");
addstring(shstrtab, ".gcbss");
if(elfverneed)
elftextsh += 2;
}
- if(HEADTYPE == Hnetbsd)
+ if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd)
elftextsh += 1;
}
phsh(ph, sh);
}
- if(HEADTYPE == Hnetbsd) {
- sh = newElfShdr(elfstr[ElfStrNoteNetbsdIdent]);
- sh->type = SHT_NOTE;
- sh->flags = SHF_ALLOC;
- sh->addralign = 4;
- resoff -= elfnetbsdsig(sh, startva, resoff);
+ if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd) {
+ sh = nil;
+ switch(HEADTYPE) {
+ case Hnetbsd:
+ sh = newElfShdr(elfstr[ElfStrNoteNetbsdIdent]);
+ resoff -= elfnetbsdsig(sh, startva, resoff);
+ break;
+ case Hopenbsd:
+ sh = newElfShdr(elfstr[ElfStrNoteOpenbsdIdent]);
+ resoff -= elfopenbsdsig(sh, startva, resoff);
+ break;
+ }
ph = newElfPhdr();
ph->type = PT_NOTE;
a += elfwriteinterp(elfstr[ElfStrInterp]);
if(HEADTYPE == Hnetbsd)
a += elfwritenetbsdsig(elfstr[ElfStrNoteNetbsdIdent]);
+ if(HEADTYPE == Hopenbsd)
+ a += elfwriteopenbsdsig(elfstr[ElfStrNoteOpenbsdIdent]);
if(a > ELFRESERVE)
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break;
ElfStrGnuVersion,
ElfStrGnuVersionR,
ElfStrNoteNetbsdIdent,
+ ElfStrNoteOpenbsdIdent,
ElfStrNoPtrData,
ElfStrNoPtrBss,
NElfStr
elfstr[ElfStrNoPtrBss] = addstring(shstrtab, ".noptrbss");
if(HEADTYPE == Hnetbsd)
elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
+ if(HEADTYPE == Hopenbsd)
+ elfstr[ElfStrNoteOpenbsdIdent] = addstring(shstrtab, ".note.openbsd.ident");
addstring(shstrtab, ".elfdata");
addstring(shstrtab, ".rodata");
addstring(shstrtab, ".gcdata");
if(elfverneed)
elftextsh += 2;
}
- if(HEADTYPE == Hnetbsd)
+ if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd)
elftextsh += 1;
break;
case Hwindows:
phsh(ph, sh);
}
- if(HEADTYPE == Hnetbsd) {
- sh = newElfShdr(elfstr[ElfStrNoteNetbsdIdent]);
- sh->type = SHT_NOTE;
- sh->flags = SHF_ALLOC;
- sh->addralign = 4;
- resoff -= elfnetbsdsig(sh, startva, resoff);
+ if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd) {
+ sh = nil;
+ switch(HEADTYPE) {
+ case Hnetbsd:
+ sh = newElfShdr(elfstr[ElfStrNoteNetbsdIdent]);
+ resoff -= elfnetbsdsig(sh, startva, resoff);
+ break;
+ case Hopenbsd:
+ sh = newElfShdr(elfstr[ElfStrNoteOpenbsdIdent]);
+ resoff -= elfopenbsdsig(sh, startva, resoff);
+ break;
+ }
ph = newElfPhdr();
ph->type = PT_NOTE;
a += elfwriteinterp(elfstr[ElfStrInterp]);
if(HEADTYPE == Hnetbsd)
a += elfwritenetbsdsig(elfstr[ElfStrNoteNetbsdIdent]);
+ if(HEADTYPE == Hopenbsd)
+ a += elfwriteopenbsdsig(elfstr[ElfStrNoteOpenbsdIdent]);
if(a > ELFRESERVE)
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break;
ElfStrGnuVersion,
ElfStrGnuVersionR,
ElfStrNoteNetbsdIdent,
+ ElfStrNoteOpenbsdIdent,
ElfStrNoPtrData,
ElfStrNoPtrBss,
NElfStr
elfstr[ElfStrNoPtrBss] = addstring(shstrtab, ".noptrbss");
if(HEADTYPE == Hnetbsd)
elfstr[ElfStrNoteNetbsdIdent] = addstring(shstrtab, ".note.netbsd.ident");
+ if(HEADTYPE == Hopenbsd)
+ elfstr[ElfStrNoteOpenbsdIdent] = addstring(shstrtab, ".note.openbsd.ident");
addstring(shstrtab, ".elfdata");
addstring(shstrtab, ".rodata");
addstring(shstrtab, ".gcdata");
if(elfverneed)
elftextsh += 2;
}
- if(HEADTYPE == Hnetbsd)
+ if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd)
elftextsh += 1;
}
phsh(ph, sh);
}
- if(HEADTYPE == Hnetbsd) {
- sh = newElfShdr(elfstr[ElfStrNoteNetbsdIdent]);
- sh->type = SHT_NOTE;
- sh->flags = SHF_ALLOC;
- sh->addralign = 4;
- resoff -= elfnetbsdsig(sh, startva, resoff);
+ if(HEADTYPE == Hnetbsd || HEADTYPE == Hopenbsd) {
+ sh = nil;
+ switch(HEADTYPE) {
+ case Hnetbsd:
+ sh = newElfShdr(elfstr[ElfStrNoteNetbsdIdent]);
+ resoff -= elfnetbsdsig(sh, startva, resoff);
+ break;
+ case Hopenbsd:
+ sh = newElfShdr(elfstr[ElfStrNoteOpenbsdIdent]);
+ resoff -= elfopenbsdsig(sh, startva, resoff);
+ break;
+ }
ph = newElfPhdr();
ph->type = PT_NOTE;
a += elfwriteinterp(elfstr[ElfStrInterp]);
if(HEADTYPE == Hnetbsd)
a += elfwritenetbsdsig(elfstr[ElfStrNoteNetbsdIdent]);
+ if(HEADTYPE == Hopenbsd)
+ a += elfwriteopenbsdsig(elfstr[ElfStrNoteOpenbsdIdent]);
if(a > ELFRESERVE)
diag("ELFRESERVE too small: %d > %d", a, ELFRESERVE);
break;
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;
return n;
}
-int
-elfwritenetbsdsig(vlong stridx) {
+ElfShdr *
+elfwritenotehdr(vlong stridx, uint32 namesz, uint32 descsz, uint32 tag)
+{
ElfShdr *sh = nil;
int i;
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;
+}
+
extern int nelfsym;
int elfverneed;
int elfwriteinterp(vlong);
int elfnetbsdsig(ElfShdr*, uint64, uint64);
int elfwritenetbsdsig(vlong);
+int elfopenbsdsig(ElfShdr*, uint64, uint64);
+int elfwriteopenbsdsig(vlong);
void elfdynhash(void);
ElfPhdr* elfphload(Segment*);
ElfShdr* elfshbits(Section*);