From 280494cce023f3938023b9b2b1173405601e4ddf Mon Sep 17 00:00:00 2001 From: Phil Knirsch Date: Mon, 16 Apr 2012 19:02:34 +0200 Subject: [PATCH] - Add general /proc/self/auxv parsing to rpmrc for better machine detection Signed-off-by: Panu Matilainen --- lib/rpmrc.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/lib/rpmrc.c b/lib/rpmrc.c index 4b6b29a..edb9cd6 100644 --- a/lib/rpmrc.c +++ b/lib/rpmrc.c @@ -2,6 +2,12 @@ #include +#if defined(__linux__) +#include +#include +#endif + + #if HAVE_SYS_UTSNAME_H #include #endif @@ -73,6 +79,11 @@ struct rpmOption { int localize; }; +static struct rpmat_s { + const char *platform; + uint64_t hwcap; +} rpmat; + typedef struct defaultEntry_s { char * name; char * defName; @@ -897,6 +908,46 @@ static int is_geode(void) } #endif + +#if defined(__linux__) +/** + * Populate rpmat structure with parsed info from /proc/self/auxv + */ +static void parse_auxv(void) +{ + static int oneshot = 1; + + if (oneshot) { + rpmat.platform = ""; + int fd = open("/proc/self/auxv", O_RDONLY); + + if (fd == -1) { + rpmlog(RPMLOG_WARNING, + _("Failed to read auxiliary vector, /proc not mounted?\n")); + return; + } else { + ElfW(auxv_t) auxv; + while (read(fd, &auxv, sizeof(auxv)) == sizeof(auxv)) { + switch (auxv.a_type) + { + case AT_NULL: + break; + case AT_PLATFORM: + rpmat.platform = strdup((char *) auxv.a_un.a_val); + break; + case AT_HWCAP: + rpmat.hwcap = auxv.a_un.a_val; + break; + } + } + close(fd); + } + oneshot = 0; /* only try once even if it fails */ + } + return; +} +#endif + /** */ static void defaultMachine(const char ** arch, @@ -908,6 +959,11 @@ static void defaultMachine(const char ** arch, canonEntry canon; int rc; +#if defined(__linux__) + /* Populate rpmat struct with hw info */ + parse_auxv(); +#endif + while (!gotDefaults) { if (!rpmPlatform(platform)) { char * s = rpmExpand("%{_host_cpu}", NULL); -- 2.7.4