diff --git a/lib/rpmrc.c b/lib/rpmrc.c index 4ebefa7..920ceed 100644 --- a/lib/rpmrc.c +++ b/lib/rpmrc.c @@ -737,6 +737,80 @@ static int is_sun4v() } #endif +#if defined(__linux__) && defined(__arm__) +static int has_neon() +{ + char buffer[4096], *p; + int fd = open("/proc/cpuinfo", O_RDONLY); + if (read(fd, &buffer, sizeof(buffer) - 1) == -1) { + rpmlog(RPMLOG_WARNING, _("read(/proc/cpuinfo) failed\n")); + close(fd); + return 0; + } + close(fd); + + p = strstr(buffer, "Features"); + p = strtok(p, "\n"); + p = strstr(p, "neon"); + p = strtok(p, " "); + if (p == NULL) { + rpmlog(RPMLOG_WARNING, _("/proc/cpuinfo has no 'Features' line\n")); + return 0; + } else if (strcmp(p, "neon") == 0) { + return 1; + } + return 0; +} + +static int has_vfpv3() +{ + char buffer[4096], *p; + int fd = open("/proc/cpuinfo", O_RDONLY); + if (read(fd, &buffer, sizeof(buffer) - 1) == -1) { + rpmlog(RPMLOG_WARNING, _("read(/proc/cpuinfo) failed\n")); + close(fd); + return 0; + } + close(fd); + + p = strstr(buffer, "Features"); + p = strtok(p, "\n"); + p = strstr(p, "vfpv3"); + p = strtok(p, " "); + if (p == NULL) { + rpmlog(RPMLOG_WARNING, _("/proc/cpuinfo has no 'Features' line\n")); + return 0; + } else if (strcmp(p, "vfpv3") == 0) { + return 1; + } + return 0; +} + +static int has_vfp() +{ + char buffer[4096], *p; + int fd = open("/proc/cpuinfo", O_RDONLY); + if (read(fd, &buffer, sizeof(buffer) - 1) == -1) { + rpmlog(RPMLOG_WARNING, _("read(/proc/cpuinfo) failed\n")); + close(fd); + return 0; + } + close(fd); + + p = strstr(buffer, "Features"); + p = strtok(p, "\n"); + p = strstr(p, "vfp"); + p = strtok(p, " "); + if (p == NULL) { + rpmlog(RPMLOG_WARNING, _("/proc/cpuinfo has no 'Features' line\n")); + return 0; + } else if (strcmp(p, "vfp") == 0) { + return 1; + } + return 0; +} +#endif + # if defined(__linux__) && defined(__i386__) #include @@ -1147,6 +1221,20 @@ static void defaultMachine(const char ** arch, # endif /* __ORDER_BIG_ENDIAN__ */ # endif /* ppc64*-linux */ +# if defined(__linux__) && defined(__arm__) + { + if (strcmp(un.machine, "armv7l") == 0 ) { + if (has_neon() && has_vfpv3()) + strcpy(un.machine, "armv7hnl"); + else if (has_vfpv3()) + strcpy(un.machine, "armv7hl"); + } else if (strcmp(un.machine, "armv6l") == 0 ) { + if (has_vfp()) + strcpy(un.machine, "armv6hl"); + } + } +# endif /* arm*-linux */ + # if defined(__GNUC__) && defined(__alpha__) { unsigned long amask, implver;