#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <assert.h>

#include <elf.h>

char *aux_to_str(int n) {
	switch (n) {
	case AT_NULL:
		return "AT_NULL";
	case AT_IGNORE:
		return "AT_IGNORE";
	case AT_EXECFD:
		return "AT_EXECFD";
	case AT_PHDR:
		return "AT_PHDR";
	case AT_PHENT:
		return "AT_PHENT";
	case AT_PHNUM:
		return "AT_PHNUM";
	case AT_PAGESZ:
		return "AT_PAGESZ";
	case AT_BASE:
		return "AT_BASE";
	case AT_FLAGS:
		return "AT_FLAGS";
	case AT_ENTRY:
		return "AT_ENTRY";
	case AT_NOTELF:
		return "AT_NOTELF";
	case AT_UID:
		return "AT_UID";
	case AT_EUID:
		return "AT_EUID";
	case AT_GID:
		return "AT_GID";
	case AT_EGID:
		return "AT_EGID";
	case AT_CLKTCK:
		return "AT_CLKTCK";
	case AT_PLATFORM:
		return "AT_PLATFORM";
	case AT_HWCAP:
		return "AT_HWCAP";
	case AT_FPUCW:
		return "AT_FPUCW";
	case AT_DCACHEBSIZE:
		return "AT_DCACHEBSIZE";
	case AT_ICACHEBSIZE:
		return "AT_ICACHEBSIZE";
	case AT_UCACHEBSIZE:
		return "AT_UCACHEBSIZE";
	case AT_IGNOREPPC:
		return "AT_IGNOREPPC";
	case AT_SECURE:
		return "AT_SECURE";
	case AT_SYSINFO:
		return "AT_SYSINFO";
	case AT_SYSINFO_EHDR:
		return "AT_SYSINFO_EHDR";
	case AT_L1I_CACHESHAPE:
		return "AT_L1I_CACHESHAPE";
	case AT_L1D_CACHESHAPE:
		return "AT_L1D_CACHESHAPE";
	case AT_L2_CACHESHAPE:
		return "AT_L2_CACHESHAPE";
	case AT_L3_CACHESHAPE:
		return "AT_L3_CACHESHAPE";
	default:
		return "UNKNOWN";
	}
}

int main(int argc, char *argv[]) {

	int fd;
	char *file;
	struct stat sb;
	Elf32_auxv_t aux;
	int count;
	asprintf(&file, "/proc/%s/auxv", argv[1]);
	assert(file);

	fd = open(file, O_RDONLY);
	assert(fd);

	while (read(fd, &aux, sizeof(Elf32_auxv_t))) {
		printf("%s : %lx\n", aux_to_str(aux.a_type), aux.a_un.a_val);
	}
}
