1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2016 Joyent, Inc.
  14  */
  15 
  16 #include <sys/auxv.h>
  17 #include <sys/lx_brand.h>
  18 
  19 /*
  20  * Linux does not make the distinction between 'int' and 'long' when it comes
  21  * to the format of the aux vector.  In order to properly clear the struct
  22  * padding present in the native auxv_t in 64-bit, we employ the Linux format.
  23  */
  24 struct lx_auxv {
  25         long la_type;
  26         long la_val;
  27 };
  28 
  29 int
  30 lx_auxv_stol(const auxv_t *ap, auxv_t *oap, const lx_elf_data_t *edp)
  31 {
  32         struct lx_auxv *loap = (struct lx_auxv *)oap;
  33 
  34         switch (ap->a_type) {
  35         case AT_BASE:
  36                 loap->la_val = edp->ed_base;
  37                 break;
  38         case AT_ENTRY:
  39                 loap->la_val = edp->ed_entry;
  40                 break;
  41         case AT_PHDR:
  42                 loap->la_val = edp->ed_phdr;
  43                 break;
  44         case AT_PHENT:
  45                 loap->la_val = edp->ed_phent;
  46                 break;
  47         case AT_PHNUM:
  48                 loap->la_val = edp->ed_phnum;
  49                 break;
  50         case AT_SUN_BRAND_LX_SYSINFO_EHDR:
  51                 loap->la_type = AT_SYSINFO_EHDR;
  52                 loap->la_val = ap->a_un.a_val;
  53                 return (0);
  54         case AT_SUN_BRAND_LX_CLKTCK:
  55                 loap->la_type = AT_CLKTCK;
  56                 loap->la_val = ap->a_un.a_val;
  57                 return (0);
  58         case AT_SUN_AUXFLAGS:
  59                 if ((ap->a_un.a_val & AF_SUN_SETUGID) != 0) {
  60                         loap->la_type = AT_SECURE;
  61                         loap->la_val = 1;
  62                         return (0);
  63                 } else {
  64                         return (1);
  65                 }
  66         case AT_SUN_GID:
  67                 loap->la_type = AT_LX_EGID;
  68                 loap->la_val = ap->a_un.a_val;
  69                 return (0);
  70         case AT_SUN_RGID:
  71                 loap->la_type = AT_LX_GID;
  72                 loap->la_val = ap->a_un.a_val;
  73                 return (0);
  74         case AT_SUN_UID:
  75                 loap->la_type = AT_LX_EUID;
  76                 loap->la_val = ap->a_un.a_val;
  77                 return (0);
  78         case AT_SUN_RUID:
  79                 loap->la_type = AT_LX_UID;
  80                 loap->la_val = ap->a_un.a_val;
  81                 return (0);
  82         case AT_EXECFD:
  83         case AT_PAGESZ:
  84         case AT_FLAGS:
  85         case AT_RANDOM:
  86         case AT_NULL:
  87                 /* No translate needed */
  88                 loap->la_val = ap->a_un.a_val;
  89                 break;
  90         default:
  91                 /* All other unrecognized entries are ignored */
  92                 return (1);
  93         }
  94         loap->la_type = ap->a_type;
  95         return (0);
  96 }