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);
|