]>
git.ipfire.org Git - people/ms/u-boot.git/blob - tools/relocate-rela.c
2 * Copyright 2013 Freescale Semiconductor, Inc.
4 * SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
6 * 64-bit and little-endian target only until we need to support a different
7 * arch that needs this.
20 #ifndef R_AARCH64_RELATIVE
21 #define R_AARCH64_RELATIVE 1027
24 static const bool debug_en
;
26 static void debug(const char *fmt
, ...)
37 static bool supported_rela(Elf64_Rela
*rela
)
39 uint64_t mask
= 0xffffffffULL
; /* would be different on 32-bit */
40 uint32_t type
= rela
->r_info
& mask
;
43 #ifdef R_AARCH64_RELATIVE
44 case R_AARCH64_RELATIVE
:
48 fprintf(stderr
, "warning: unsupported relocation type %"
49 PRIu32
" at %" PRIx64
"\n",
50 type
, rela
->r_offset
);
56 static bool read_num(const char *str
, uint64_t *num
)
59 *num
= strtoull(str
, &endptr
, 16);
60 return str
[0] && !endptr
[0];
63 int main(int argc
, char **argv
)
67 uint64_t rela_start
, rela_end
, text_base
;
70 fprintf(stderr
, "Statically apply ELF rela relocations\n");
71 fprintf(stderr
, "Usage: %s <bin file> <text base> " \
72 "<rela start> <rela end>\n", argv
[0]);
73 fprintf(stderr
, "All numbers in hex.\n");
77 f
= fopen(argv
[1], "r+b");
79 fprintf(stderr
, "%s: Cannot open %s: %s\n",
80 argv
[0], argv
[1], strerror(errno
));
84 if (!read_num(argv
[2], &text_base
) ||
85 !read_num(argv
[3], &rela_start
) ||
86 !read_num(argv
[4], &rela_end
)) {
87 fprintf(stderr
, "%s: bad number\n", argv
[0]);
91 if (rela_start
> rela_end
|| rela_start
< text_base
||
92 (rela_end
- rela_start
) % sizeof(Elf64_Rela
)) {
93 fprintf(stderr
, "%s: bad rela bounds\n", argv
[0]);
97 rela_start
-= text_base
;
98 rela_end
-= text_base
;
100 num
= (rela_end
- rela_start
) / sizeof(Elf64_Rela
);
102 for (i
= 0; i
< num
; i
++) {
103 Elf64_Rela rela
, swrela
;
104 uint64_t pos
= rela_start
+ sizeof(Elf64_Rela
) * i
;
107 if (fseek(f
, pos
, SEEK_SET
) < 0) {
108 fprintf(stderr
, "%s: %s: seek to %" PRIx64
110 argv
[0], argv
[1], pos
, strerror(errno
));
113 if (fread(&rela
, sizeof(rela
), 1, f
) != 1) {
114 fprintf(stderr
, "%s: %s: read rela failed at %"
116 argv
[0], argv
[1], pos
);
120 swrela
.r_offset
= cpu_to_le64(rela
.r_offset
);
121 swrela
.r_info
= cpu_to_le64(rela
.r_info
);
122 swrela
.r_addend
= cpu_to_le64(rela
.r_addend
);
124 if (!supported_rela(&swrela
))
127 debug("Rela %" PRIx64
" %" PRIu64
" %" PRIx64
"\n",
128 swrela
.r_offset
, swrela
.r_info
, swrela
.r_addend
);
130 if (swrela
.r_offset
< text_base
) {
131 fprintf(stderr
, "%s: %s: bad rela at %" PRIx64
"\n",
132 argv
[0], argv
[1], pos
);
136 addr
= swrela
.r_offset
- text_base
;
138 if (fseek(f
, addr
, SEEK_SET
) < 0) {
139 fprintf(stderr
, "%s: %s: seek to %"
140 PRIx64
" failed: %s\n",
141 argv
[0], argv
[1], addr
, strerror(errno
));
144 if (fwrite(&rela
.r_addend
, sizeof(rela
.r_addend
), 1, f
) != 1) {
145 fprintf(stderr
, "%s: %s: write failed at %" PRIx64
"\n",
146 argv
[0], argv
[1], addr
);
152 fprintf(stderr
, "%s: %s: close failed: %s\n",
153 argv
[0], argv
[1], strerror(errno
));