Bug Summary

File:src/libexec/ld.so/amd64/rtld_machine.c
Warning:line 273, column 32
Access to field 'st_size' results in a dereference of a null pointer (loaded from variable 'dstsym')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name rtld_machine.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -target-feature -sse2 -target-feature -sse -target-feature -3dnow -target-feature -mmx -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/libexec/ld.so/obj -resource-dir /usr/local/lib/clang/13.0.0 -D DO_CLEAN_BOOT -I /usr/src/libexec/ld.so -I /usr/src/libexec/ld.so/amd64 -D DEF_WEAK(x)=asm("") -D DEF_STRONG(x)=asm("") -D strsep=_dl_strsep -D strlcat=_dl_strlcat -D strlen=_dl_strlen -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/libexec/ld.so/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fno-builtin -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/libexec/ld.so/amd64/rtld_machine.c
1/* $OpenBSD: rtld_machine.c,v 1.40 2022/01/08 06:49:41 guenther Exp $ */
2
3/*
4 * Copyright (c) 2002,2004 Dale Rahn
5 * Copyright (c) 2001 Niklas Hallqvist
6 * Copyright (c) 2001 Artur Grabowski
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29/*-
30 * Copyright (c) 2000 Eduardo Horvath.
31 * Copyright (c) 1999 The NetBSD Foundation, Inc.
32 * All rights reserved.
33 *
34 * This code is derived from software contributed to The NetBSD Foundation
35 * by Paul Kranenburg.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 * 3. All advertising materials mentioning features or use of this software
46 * must display the following acknowledgement:
47 * This product includes software developed by the NetBSD
48 * Foundation, Inc. and its contributors.
49 * 4. Neither the name of The NetBSD Foundation nor the names of its
50 * contributors may be used to endorse or promote products derived
51 * from this software without specific prior written permission.
52 *
53 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
54 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
55 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
57 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
58 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
59 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
60 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
61 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
62 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
63 * POSSIBILITY OF SUCH DAMAGE.
64 */
65
66#define _DYN_LOADER
67
68#include <sys/types.h>
69#include <sys/exec_elf.h>
70#include <sys/syscall.h>
71#include <sys/unistd.h>
72
73#include <machine/reloc.h>
74
75#include "util.h"
76#include "resolve.h"
77
78int64_t pcookie __attribute__((section(".openbsd.randomdata"))) __dso_hidden__attribute__((__visibility__("hidden")));
79
80/*
81 * The following table holds for each relocation type:
82 * - the width in bits of the memory location the relocation
83 * applies to
84 * - the number of bits the relocation value must be shifted to the
85 * right (i.e. discard least significant bits) to fit into
86 * the appropriate field in the instruction word.
87 * - flags indicating whether
88 * * the relocation involves a symbol
89 * * the relocation is relative to the current position
90 * * the relocation is for a GOT entry
91 * * the relocation is relative to the load address
92 *
93 */
94#define _RF_S0x80000000 0x80000000 /* Resolve symbol */
95#define _RF_A0x40000000 0x40000000 /* Use addend */
96#define _RF_P0x20000000 0x20000000 /* Location relative */
97#define _RF_G0x10000000 0x10000000 /* GOT offset */
98#define _RF_B0x08000000 0x08000000 /* Load address relative */
99#define _RF_E0x02000000 0x02000000 /* ERROR */
100#define _RF_SZ(s)(((s) & 0xff) << 8) (((s) & 0xff) << 8) /* memory target size */
101#define _RF_RS(s)((s) & 0xff) ((s) & 0xff) /* right shift */
102static const int reloc_target_flags[] = {
103 0, /* 0 NONE */
104 _RF_S0x80000000|_RF_A0x40000000| _RF_SZ(64)(((64) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 1 _64*/
105 _RF_S0x80000000|_RF_A0x40000000|_RF_P0x20000000| _RF_SZ(32)(((32) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 2 PC32 */
106 _RF_G0x10000000|_RF_A0x40000000| _RF_SZ(32)(((32) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 3 GOT32 */
107 _RF_E0x02000000|_RF_A0x40000000| _RF_SZ(32)(((32) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 4 PLT32 */
108 _RF_S0x80000000| _RF_SZ(32)(((32) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 5 COPY */
109 _RF_S0x80000000| _RF_SZ(64)(((64) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 6 GLOB_DAT*/
110 _RF_S0x80000000| _RF_SZ(64)(((64) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 7 JUMP_SLOT*/
111 _RF_A0x40000000| _RF_B0x08000000| _RF_SZ(64)(((64) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 8 RELATIVE*/
112 _RF_E0x02000000, /* 9 GOTPCREL*/
113 _RF_S0x80000000|_RF_A0x40000000| _RF_SZ(32)(((32) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 10 32 */
114 _RF_S0x80000000|_RF_A0x40000000| _RF_SZ(32)(((32) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 11 32S */
115 _RF_S0x80000000|_RF_A0x40000000| _RF_SZ(16)(((16) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 12 16 */
116 _RF_S0x80000000|_RF_A0x40000000|_RF_P0x20000000| _RF_SZ(16)(((16) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 13 PC16 */
117 _RF_S0x80000000|_RF_A0x40000000| _RF_SZ(8)(((8) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 14 8 */
118 _RF_S0x80000000|_RF_A0x40000000|_RF_P0x20000000| _RF_SZ(8)(((8) & 0xff) << 8) | _RF_RS(0)((0) & 0xff), /* 15 PC8 */
119 _RF_E0x02000000, /* 16 DTPMOD64*/
120 _RF_E0x02000000, /* 17 DTPOFF64*/
121 _RF_E0x02000000, /* 18 TPOFF64 */
122 _RF_E0x02000000, /* 19 TLSGD */
123 _RF_E0x02000000, /* 20 TLSLD */
124 _RF_E0x02000000, /* 21 DTPOFF32*/
125 _RF_E0x02000000, /* 22 GOTTPOFF*/
126 _RF_E0x02000000 /* 23 TPOFF32*/
127};
128
129#define RELOC_RESOLVE_SYMBOL(t)((reloc_target_flags[t] & 0x80000000) != 0) ((reloc_target_flags[t] & _RF_S0x80000000) != 0)
130#define RELOC_PC_RELATIVE(t)((reloc_target_flags[t] & 0x20000000) != 0) ((reloc_target_flags[t] & _RF_P0x20000000) != 0)
131#define RELOC_BASE_RELATIVE(t)((reloc_target_flags[t] & 0x08000000) != 0) ((reloc_target_flags[t] & _RF_B0x08000000) != 0)
132#define RELOC_USE_ADDEND(t)((reloc_target_flags[t] & 0x40000000) != 0) ((reloc_target_flags[t] & _RF_A0x40000000) != 0)
133#define RELOC_TARGET_SIZE(t)((reloc_target_flags[t] >> 8) & 0xff) ((reloc_target_flags[t] >> 8) & 0xff)
134#define RELOC_VALUE_RIGHTSHIFT(t)(reloc_target_flags[t] & 0xff) (reloc_target_flags[t] & 0xff)
135#define RELOC_ERROR(t)(reloc_target_flags[t] & 0x02000000) (reloc_target_flags[t] & _RF_E0x02000000)
136
137static const Elf_AddrElf64_Addr reloc_target_bitmask[] = {
138#define _BM(x) (~(Elf_AddrElf64_Addr)0 >> ((8*sizeof(reloc_target_bitmask[0])) - (x)))
139 0, /* 0 NONE */
140 _BM(64), /* 1 _64*/
141 _BM(32), /* 2 PC32 */
142 _BM(32), /* 3 GOT32 */
143 _BM(32), /* 4 PLT32 */
144 0, /* 5 COPY */
145 _BM(64), /* 6 GLOB_DAT*/
146 _BM(64), /* 7 JUMP_SLOT*/
147 _BM(64), /* 8 RELATIVE*/
148 _BM(32), /* 9 GOTPCREL*/
149 _BM(32), /* 10 32 */
150 _BM(32), /* 11 32S */
151 _BM(16), /* 12 16 */
152 _BM(16), /* 13 PC16 */
153 _BM(8), /* 14 8 */
154 _BM(8), /* 15 PC8 */
155 0, /* 16 DTPMOD64*/
156 0, /* 17 DTPOFF64*/
157 0, /* 18 TPOFF64 */
158 0, /* 19 TLSGD */
159 0, /* 20 TLSLD */
160 0, /* 21 DTPOFF32*/
161 0, /* 22 GOTTPOFF*/
162 0 /* 23 TPOFF32*/
163#undef _BM
164};
165#define RELOC_VALUE_BITMASK(t)(reloc_target_bitmask[t]) (reloc_target_bitmask[t])
166
167void _dl_reloc_plt(Elf_AddrElf64_Addr *where, Elf_AddrElf64_Addr value);
168
169int
170_dl_md_reloc(elf_object_t *object, int rel, int relsz)
171{
172 long i;
173 long numrel;
174 long relrel;
175 int fails = 0;
176 Elf_AddrElf64_Addr loff;
177 Elf_AddrElf64_Addr prev_value = 0;
178 const Elf_SymElf64_Sym *prev_sym = NULL((void*)0);
179 Elf_RelAElf64_Rela *rels;
180
181 loff = object->obj_base;
182 numrel = object->Dyn.info[relsz] / sizeof(Elf_RelAElf64_Rela);
183 relrel = rel
7.1
'rel' is not equal to DT_RELA
== DT_RELA7 ? object->relacount : 0;
8
'?' condition is false
184 rels = (Elf_RelAElf64_Rela *)(object->Dyn.info[rel]);
185 if (rels == NULL((void*)0))
9
Assuming 'rels' is not equal to NULL
10
Taking false branch
186 return 0;
187
188 if (relrel
10.1
'relrel' is <= 'numrel'
> numrel)
11
Taking false branch
189 _dl_die("relacount > numrel: %ld > %ld", relrel, numrel);
190
191 /* tight loop for leading RELATIVE relocs */
192 for (i = 0; i < relrel; i++, rels++) {
12
Loop condition is false. Execution continues on line 198
193 Elf_AddrElf64_Addr *where;
194
195 where = (Elf_AddrElf64_Addr *)(rels->r_offset + loff);
196 *where = rels->r_addend + loff;
197 }
198 for (; i < numrel; i++, rels++) {
13
Assuming 'i' is < 'numrel'
14
Loop condition is true. Entering loop body
199 Elf_AddrElf64_Addr *where, value, mask;
200 Elf_WordElf64_Word type;
201 const Elf_SymElf64_Sym *sym;
202 const char *symn;
203
204 type = ELF_R_TYPE(rels->r_info)((rels->r_info) & 0xFFFFFFFF);
205
206 if (RELOC_ERROR(type)(reloc_target_flags[type] & 0x02000000))
15
Assuming the condition is false
16
Taking false branch
207 _dl_die("relocation error %d idx %ld", type, i);
208
209 if (type == R_TYPE(NONE)0)
17
Assuming 'type' is not equal to R_TYPE(NONE)
18
Taking false branch
210 continue;
211
212 if (type == R_TYPE(JUMP_SLOT)7 && rel != DT_JMPREL23)
19
Assuming 'type' is not equal to R_TYPE(JUMP_SLOT)
213 continue;
214
215 where = (Elf_AddrElf64_Addr *)(rels->r_offset + loff);
216
217 if (RELOC_USE_ADDEND(type)((reloc_target_flags[type] & 0x40000000) != 0))
20
Assuming the condition is false
21
Taking false branch
218 value = rels->r_addend;
219 else
220 value = 0;
221
222 sym = NULL((void*)0);
22
Null pointer value stored to 'sym'
223 symn = NULL((void*)0);
224 if (RELOC_RESOLVE_SYMBOL(type)((reloc_target_flags[type] & 0x80000000) != 0)) {
23
Assuming the condition is false
24
Taking false branch
225 sym = object->dynDyn.u.symtab;
226 sym += ELF_R_SYM(rels->r_info)((rels->r_info) >> 32);
227 symn = object->dynDyn.u.strtab + sym->st_name;
228
229 if (sym->st_shndx != SHN_UNDEF0 &&
230 ELF_ST_BIND(sym->st_info)((sym->st_info) >> 4) == STB_LOCAL0) {
231 value += loff;
232 } else if (sym == prev_sym) {
233 value += prev_value;
234 } else {
235 struct sym_res sr;
236
237 sr = _dl_find_symbol(symn,
238 SYM_SEARCH_ALL0x00|SYM_WARNNOTFOUND0x10|
239 ((type == R_TYPE(JUMP_SLOT)7)?
240 SYM_PLT0x20:SYM_NOTPLT0x00), sym, object);
241 if (sr.sym == NULL((void*)0)) {
242resolve_failed:
243 if (ELF_ST_BIND(sym->st_info)((sym->st_info) >> 4) !=
244 STB_WEAK2)
245 fails++;
246 continue;
247 }
248 prev_sym = sym;
249 prev_value = (Elf_AddrElf64_Addr)(sr.obj->obj_base +
250 sr.sym->st_value);
251 value += prev_value;
252 }
253 }
254
255 if (type
24.1
'type' is not equal to R_TYPE(JUMP_SLOT)
== R_TYPE(JUMP_SLOT)7) {
25
Taking false branch
256 _dl_reloc_plt(where, value);
257 continue;
258 }
259
260 if (type == R_TYPE(COPY)5) {
26
Assuming 'type' is equal to R_TYPE(COPY)
27
Taking true branch
261 void *dstaddr = where;
262 const void *srcaddr;
263 const Elf_SymElf64_Sym *dstsym = sym;
28
'dstsym' initialized to a null pointer value
264 struct sym_res sr;
265
266 sr = _dl_find_symbol(symn,
267 SYM_SEARCH_OTHER0x02|SYM_WARNNOTFOUND0x10|SYM_NOTPLT0x00,
268 dstsym, object);
269 if (sr.sym == NULL((void*)0))
29
Assuming field 'sym' is not equal to NULL
30
Taking false branch
270 goto resolve_failed;
271
272 srcaddr = (void *)(sr.obj->obj_base + sr.sym->st_value);
273 _dl_bcopy(srcaddr, dstaddr, dstsym->st_size);
31
Access to field 'st_size' results in a dereference of a null pointer (loaded from variable 'dstsym')
274 continue;
275 }
276
277 if (RELOC_PC_RELATIVE(type)((reloc_target_flags[type] & 0x20000000) != 0))
278 value -= (Elf_AddrElf64_Addr)where;
279 if (RELOC_BASE_RELATIVE(type)((reloc_target_flags[type] & 0x08000000) != 0))
280 value += loff;
281
282 mask = RELOC_VALUE_BITMASK(type)(reloc_target_bitmask[type]);
283 value >>= RELOC_VALUE_RIGHTSHIFT(type)(reloc_target_flags[type] & 0xff);
284 value &= mask;
285
286 if (RELOC_TARGET_SIZE(type)((reloc_target_flags[type] >> 8) & 0xff) > 32) {
287 *where &= ~mask;
288 *where |= value;
289 } else {
290 Elf32_Addr *where32 = (Elf32_Addr *)where;
291
292 *where32 &= ~mask;
293 *where32 |= value;
294 }
295 }
296
297 return fails;
298}
299
300void
301_dl_reloc_plt(Elf_AddrElf64_Addr *where, Elf_AddrElf64_Addr value)
302{
303 *where = value;
304}
305
306/*
307 * Resolve a symbol at run-time.
308 */
309Elf_AddrElf64_Addr
310_dl_bind(elf_object_t *object, int index)
311{
312 Elf_RelAElf64_Rela *rel;
313 const Elf_SymElf64_Sym *sym;
314 const char *symn;
315 struct sym_res sr;
316 int64_t cookie = pcookie;
317 struct {
318 struct __kbind param;
319 Elf_AddrElf64_Addr newval;
320 } buf;
321
322 rel = (Elf_RelAElf64_Rela *)(object->Dyn.info[DT_JMPREL23]) + index;
323
324 sym = object->dynDyn.u.symtab;
325 sym += ELF_R_SYM(rel->r_info)((rel->r_info) >> 32);
326 symn = object->dynDyn.u.strtab + sym->st_name;
327
328 sr = _dl_find_symbol(symn, SYM_SEARCH_ALL0x00|SYM_WARNNOTFOUND0x10|SYM_PLT0x20,
329 sym, object);
330 if (sr.sym == NULL((void*)0))
331 _dl_die("lazy binding failed!");
332
333 buf.newval = sr.obj->obj_base + sr.sym->st_value;
334
335 if (__predict_false(sr.obj->traced)__builtin_expect(((sr.obj->traced) != 0), 0) && _dl_trace_plt(sr.obj, symn))
336 return buf.newval;
337
338 buf.param.kb_addr = (Elf_WordElf64_Word *)(object->obj_base + rel->r_offset);
339 buf.param.kb_size = sizeof(Elf_AddrElf64_Addr);
340
341 /* directly code the syscall, so that it's actually inline here */
342 {
343 register long syscall_num __asm("rax") = SYS_kbind86;
344 register void *arg1 __asm("rdi") = &buf;
345 register long arg2 __asm("rsi") = sizeof(buf);
346 register long arg3 __asm("rdx") = cookie;
347
348 __asm volatile("syscall" : "+r" (syscall_num), "+r" (arg3) :
349 "r" (arg1), "r" (arg2) : "cc", "rcx", "r11", "memory");
350 }
351 return buf.newval;
352}
353
354int
355_dl_md_reloc_got(elf_object_t *object, int lazy)
356{
357 extern void _dl_bind_start(void); /* XXX */
358 int fails = 0;
359 Elf_AddrElf64_Addr *pltgot = (Elf_AddrElf64_Addr *)object->Dyn.info[DT_PLTGOT3];
360 int i, num;
361 Elf_RelAElf64_Rela *rel;
362
363 if (pltgot == NULL((void*)0))
1
Assuming 'pltgot' is not equal to NULL
2
Taking false branch
364 return 0; /* it is possible to have no PLT/GOT relocations */
365
366 if (object->Dyn.info[DT_PLTREL20] != DT_RELA7)
3
Assuming the condition is false
4
Taking false branch
367 return 0;
368
369 if (__predict_false(!lazy)__builtin_expect(((!lazy) != 0), 0)) {
5
Assuming 'lazy' is 0
6
Taking true branch
370 fails = _dl_md_reloc(object, DT_JMPREL23, DT_PLTRELSZ2);
7
Calling '_dl_md_reloc'
371 } else {
372 pltgot[1] = (Elf_AddrElf64_Addr)object;
373 pltgot[2] = (Elf_AddrElf64_Addr)&_dl_bind_start;
374
375 rel = (Elf_RelAElf64_Rela *)(object->Dyn.info[DT_JMPREL23]);
376 num = (object->Dyn.info[DT_PLTRELSZ2]);
377 for (i = 0; i < num/sizeof(Elf_RelAElf64_Rela); i++, rel++) {
378 Elf_AddrElf64_Addr *where;
379 where = (Elf_AddrElf64_Addr *)(rel->r_offset + object->obj_base);
380 *where += object->obj_base;
381 }
382 }
383
384 return fails;
385}