diff --git a/blink/cpuid.c b/blink/cpuid.c index 597c7c6e..d9cd320d 100644 --- a/blink/cpuid.c +++ b/blink/cpuid.c @@ -20,17 +20,18 @@ #include "blink/endian.h" #include "blink/machine.h" -#define INTEL "GenuineIntel" -#define BLINK "GenuineBlink" -#define LINUX_ "Linux\0\0\0\0\0\0\0" -#define FREEBSD_ "FreeBSD\0\0\0\0\0\0" -#define NETBSD_ "NetBSD\0\0\0\0\0\0" -#define OPENBSD_ "OpenBSD\0\0\0\0\0" -#define XNU_ "XNU\0\0\0\0\0\0\0\0\0" -#define WINDOWS_ "Windows\0\0\0\0\0" -#define CYGWIN_ "Cygwin\0\0\0\0\0\0" -#define HAIKU_ "Haiku\0\0\0\0\0\0\0" -#define UNKNOWN_ "Unknown\0\0\0\0\0\0" +#define INTEL "GenuineIntel" +#define BLINK "GenuineBlink" +#define LINUX_ "Linux\0\0\0\0\0\0\0" +#define FREEBSD_ "FreeBSD\0\0\0\0\0\0" +#define NETBSD_ "NetBSD\0\0\0\0\0\0" +#define OPENBSD_ "OpenBSD\0\0\0\0\0" +#define DRAGONFLYBSD_ "DragonFlyBSD" +#define XNU_ "XNU\0\0\0\0\0\0\0\0\0" +#define WINDOWS_ "Windows\0\0\0\0\0" +#define CYGWIN_ "Cygwin\0\0\0\0\0\0" +#define HAIKU_ "Haiku\0\0\0\0\0\0\0" +#define UNKNOWN_ "Unknown\0\0\0\0\0\0" #ifdef __COSMOPOLITAN__ #define OS \ @@ -49,6 +50,8 @@ #define OS NETBSD_ #elif defined(__OpenBSD__) #define OS OPENBSD_ +#elif defined(__DragonFly__) +#define OS DRAGONFLYBSD_ #elif defined(__APPLE__) #define OS XNU_ #elif defined(__CYGWIN__) diff --git a/blink/elf.c b/blink/elf.c index 702370b9..7608479a 100644 --- a/blink/elf.c +++ b/blink/elf.c @@ -178,3 +178,47 @@ Elf64_Sym_ *GetElfSymbolTable(const Elf64_Ehdr_ *elf, // } return res; } + +const char *GetElfOsNameInNoteTag(const Elf64_Ehdr_ *elf, size_t mapsize) { + int i; + Elf64_Shdr_ *shdr; + const char *sect_name; + const char *note, *note_end; + uint32_t namesz, descsz, type; + const char *os_name; + + for (i = 0; i < Read16(elf->shnum); ++i) { + shdr = GetElfSectionHeaderAddress(elf, mapsize, i); + if (!shdr) continue; + if (Read32(shdr->type) != SHT_NOTE_) continue; + + sect_name = GetElfSectionName(elf, mapsize, shdr); + if (!sect_name) continue; + if (strcmp(sect_name, ".note.ABI-tag") != 0 && + strcmp(sect_name, ".note.tag") != 0 && + strcmp(sect_name, ".note.gnu") != 0) + continue; + + note = (const char *)GetElfSectionAddress(elf, mapsize, shdr); + if (!note) continue; + note_end = note + Read64(shdr->size); + + while (note + 12 <= note_end) { + namesz = *(const uint32_t *)(note + 0); + descsz = *(const uint32_t *)(note + 4); + type = *(const uint32_t *)(note + 8); + + const char *name_field = note + 12; + const char *desc_field = name_field + ((namesz + 3) & ~3); + if (desc_field + ((descsz + 3) & ~3) > note_end) break; + + if (namesz && name_field[namesz-1] == '\0') { + return name_field; + } + + // Advance to next note + note = desc_field + ((descsz + 3) & ~3); + } + } + return NULL; +} \ No newline at end of file diff --git a/blink/elf.h b/blink/elf.h index 8a4a76bc..34910a9f 100644 --- a/blink/elf.h +++ b/blink/elf.h @@ -629,5 +629,6 @@ char *GetElfSectionNameStringTable(const Elf64_Ehdr_ *, size_t); void *GetElfSectionAddress(const Elf64_Ehdr_ *, size_t, const Elf64_Shdr_ *); Elf64_Sym_ *GetElfSymbolTable(const Elf64_Ehdr_ *, size_t, int *); i64 GetElfMemorySize(const Elf64_Ehdr_ *, size_t, i64 *); +const char *GetElfOsNameInNoteTag(const Elf64_Ehdr_ *, size_t); #endif /* BLINK_ELF_H_ */ diff --git a/blink/loader.c b/blink/loader.c index fb244be3..03eebda3 100644 --- a/blink/loader.c +++ b/blink/loader.c @@ -293,6 +293,16 @@ static bool IsHaikuExecutable(Elf64_Ehdr_ *ehdr, size_t size) { #endif } +static bool IsDragonflybsdExecutable(Elf64_Ehdr_ *ehdr, size_t size) { +#ifdef __DragonFly__ + const char *name = GetElfOsNameInNoteTag(ehdr, size); + if (name && !strcmp(name, "DragonFly")) { + return true; + } +#endif + return false; +} + static bool IsShebangExecutable(void *image, size_t size) { return size >= 2 && ((char *)image)[0] == '#' && ((char *)image)[1] == '!'; } @@ -342,6 +352,10 @@ bool IsSupportedExecutable(const char *path, void *image, size_t size) { ExplainWhyItCantBeEmulated(path, "ELF is Haiku executable"); return false; } + if (IsDragonflybsdExecutable(ehdr, size)) { + ExplainWhyItCantBeEmulated(path, "ELF is DragonFlyBSD executable"); + return false; + } #if defined(__ELF__) && !defined(__linux) LOGF("blink believes %s is an x86_64-linux executable", path); #endif