Print this page
3451 archive libraries with no symbols shouldn't require a string table


  88 #else
  89 #define get8(p) (((((((uint64_t)p[4]<<8)+p[5])<<8)+p[6])<<8)+p[7])
  90 #endif
  91 
  92 
  93 static Elf_Void *
  94 arsym(Byte *off, size_t sz, size_t *e, int is64)
  95 {
  96         char            *endstr = (char *)off + sz;
  97         register char   *str;
  98         Byte            *endoff;
  99         Elf_Void        *oas;
 100         size_t          eltsize = is64 ? 8 : 4;
 101 
 102         {
 103                 register size_t n;
 104 
 105                 if (is64) {
 106                         if (sz < 8 || (sz - 8) / 8 < (n = get8(off))) {
 107                                 _elf_seterr(EFMT_ARSYMSZ, 0);
 108                                 return (0);
 109                         }
 110                 } else {
 111                         if (sz < 4 || (sz - 4) / 4 < (n = get4(off))) {
 112                                 _elf_seterr(EFMT_ARSYMSZ, 0);
 113                                 return (0);
 114                         }
 115                 }
 116                 off += eltsize;
 117                 endoff = off + n * eltsize;
 118 
 119                 /*
 120                  * string table must be present, null terminated






 121                  */
 122 
 123                 if (((str = (char *)endoff) >= endstr) ||
 124                     (*(endstr - 1) != '\0')) {
 125                         _elf_seterr(EFMT_ARSYM, 0);
 126                         return (0);
 127                 }
 128 
 129                 /*




 130                  * overflow can occur here, but not likely
 131                  */
 132 
 133                 *e = n + 1;
 134                 n = sizeof (Elf_Arsym) * (n + 1);
 135                 if ((oas = malloc(n)) == 0) {
 136                         _elf_seterr(EMEM_ARSYM, errno);
 137                         return (0);
 138                 }
 139         }
 140         {
 141                 register Elf_Arsym      *as = (Elf_Arsym *)oas;
 142 
 143                 while (off < endoff) {
 144                         if (str >= endstr) {
 145                                 _elf_seterr(EFMT_ARSYMSTR, 0);
 146                                 free(oas);
 147                                 return (0);
 148                         }
 149                         if (is64)
 150                                 as->as_off = get8(off);
 151                         else
 152                                 as->as_off = get4(off);
 153                         as->as_name = str;
 154                         as->as_hash = elf_hash(str);
 155                         ++as;
 156                         off += eltsize;
 157                         while (*str++ != '\0')
 158                                 /* LINTED */
 159                                 ;
 160                 }
 161                 as->as_name = 0;
 162                 as->as_off = 0;
 163                 as->as_hash = ~(unsigned long)0L;
 164         }
 165         return (oas);
 166 }
 167 
 168 
 169 Elf_Arsym *
 170 elf_getarsym(Elf *elf, size_t *ptr)
 171 {
 172         Byte            *as;
 173         size_t          sz;
 174         Elf_Arsym       *rc;
 175         int             is64;
 176 
 177         if (ptr != 0)
 178                 *ptr = 0;
 179         if (elf == NULL)
 180                 return (0);
 181         ELFRLOCK(elf);




  88 #else
  89 #define get8(p) (((((((uint64_t)p[4]<<8)+p[5])<<8)+p[6])<<8)+p[7])
  90 #endif
  91 
  92 
  93 static Elf_Void *
  94 arsym(Byte *off, size_t sz, size_t *e, int is64)
  95 {
  96         char            *endstr = (char *)off + sz;
  97         register char   *str;
  98         Byte            *endoff;
  99         Elf_Void        *oas;
 100         size_t          eltsize = is64 ? 8 : 4;
 101 
 102         {
 103                 register size_t n;
 104 
 105                 if (is64) {
 106                         if (sz < 8 || (sz - 8) / 8 < (n = get8(off))) {
 107                                 _elf_seterr(EFMT_ARSYMSZ, 0);
 108                                 return (NULL);
 109                         }
 110                 } else {
 111                         if (sz < 4 || (sz - 4) / 4 < (n = get4(off))) {
 112                                 _elf_seterr(EFMT_ARSYMSZ, 0);
 113                                 return (NULL);
 114                         }
 115                 }
 116                 off += eltsize;
 117                 endoff = off + n * eltsize;
 118 
 119                 /*
 120                  * If there are symbols in the symbol table, a
 121                  * string table must be present and NULL terminated.
 122                  *
 123                  * The format dictates that the string table must always be
 124                  * present, however in the case of an archive containing no
 125                  * symbols GNU ar will not create one.  We are permissive for
 126                  * the sake of compatibility.
 127                  */
 128                 if ((n > 0) && (((str = (char *)endoff) >= endstr) ||
 129                     (*(endstr - 1) != '\0'))) {

 130                         _elf_seterr(EFMT_ARSYM, 0);
 131                         return (NULL);
 132                 }
 133 
 134                 /*
 135                  * There is always at least one entry returned if a symtab
 136                  * exists since the table's last entry is an artificial one
 137                  * with a NULL as_name, but is included in the count.
 138                  *
 139                  * overflow can occur here, but not likely
 140                  */

 141                 *e = n + 1;
 142                 if ((oas = calloc(n + 1, sizeof (Elf_Arsym))) == NULL) {

 143                         _elf_seterr(EMEM_ARSYM, errno);
 144                         return (NULL);
 145                 }
 146         }
 147         {
 148                 register Elf_Arsym      *as = (Elf_Arsym *)oas;
 149 
 150                 while (off < endoff) {
 151                         if (str >= endstr) {
 152                                 _elf_seterr(EFMT_ARSYMSTR, 0);
 153                                 free(oas);
 154                                 return (NULL);
 155                         }
 156                         if (is64)
 157                                 as->as_off = get8(off);
 158                         else
 159                                 as->as_off = get4(off);
 160                         as->as_name = str;
 161                         as->as_hash = elf_hash(str);
 162                         ++as;
 163                         off += eltsize;
 164                         while (*str++ != '\0')
 165                                 /* LINTED */
 166                                 ;
 167                 }
 168                 as->as_name = NULL;
 169                 as->as_off = 0;
 170                 as->as_hash = ~(unsigned long)0L;
 171         }
 172         return (oas);
 173 }
 174 
 175 
 176 Elf_Arsym *
 177 elf_getarsym(Elf *elf, size_t *ptr)
 178 {
 179         Byte            *as;
 180         size_t          sz;
 181         Elf_Arsym       *rc;
 182         int             is64;
 183 
 184         if (ptr != 0)
 185                 *ptr = 0;
 186         if (elf == NULL)
 187                 return (0);
 188         ELFRLOCK(elf);