]>
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
, ...)
35 static bool supported_rela(Elf64_Rela
*rela
)
37 uint64_t mask
= 0xffffffffULL
; /* would be different on 32-bit */
38 uint32_t type
= rela
->r_info
& mask
;
41 #ifdef R_AARCH64_RELATIVE
42 case R_AARCH64_RELATIVE
:
46 fprintf(stderr
, "warning: unsupported relocation type %"
47 PRIu32
" at %" PRIx64
"\n",
48 type
, rela
->r_offset
);
54 static bool read_num(const char *str
, uint64_t *num
)
57 *num
= strtoull(str
, &endptr
, 16);
58 return str
[0] && !endptr
[0];
61 int main(int argc
, char **argv
)
65 uint64_t rela_start
, rela_end
, text_base
;
68 fprintf(stderr
, "Statically apply ELF rela relocations\n");
69 fprintf(stderr
, "Usage: %s <bin file> <text base> " \
70 "<rela start> <rela end>\n", argv
[0]);
71 fprintf(stderr
, "All numbers in hex.\n");
75 f
= fopen(argv
[1], "r+b");
77 fprintf(stderr
, "%s: Cannot open %s: %s\n",
78 argv
[0], argv
[1], strerror(errno
));
82 if (!read_num(argv
[2], &text_base
) ||
83 !read_num(argv
[3], &rela_start
) ||
84 !read_num(argv
[4], &rela_end
)) {
85 fprintf(stderr
, "%s: bad number\n", argv
[0]);
89 if (rela_start
> rela_end
|| rela_start
< text_base
||
90 (rela_end
- rela_start
) % sizeof(Elf64_Rela
)) {
91 fprintf(stderr
, "%s: bad rela bounds\n", argv
[0]);
95 rela_start
-= text_base
;
96 rela_end
-= text_base
;
98 num
= (rela_end
- rela_start
) / sizeof(Elf64_Rela
);
100 for (i
= 0; i
< num
; i
++) {
101 Elf64_Rela rela
, swrela
;
102 uint64_t pos
= rela_start
+ sizeof(Elf64_Rela
) * i
;
105 if (fseek(f
, pos
, SEEK_SET
) < 0) {
106 fprintf(stderr
, "%s: %s: seek to %" PRIx64
108 argv
[0], argv
[1], pos
, strerror(errno
));
111 if (fread(&rela
, sizeof(rela
), 1, f
) != 1) {
112 fprintf(stderr
, "%s: %s: read rela failed at %"
114 argv
[0], argv
[1], pos
);
118 swrela
.r_offset
= cpu_to_le64(rela
.r_offset
);
119 swrela
.r_info
= cpu_to_le64(rela
.r_info
);
120 swrela
.r_addend
= cpu_to_le64(rela
.r_addend
);
122 if (!supported_rela(&swrela
))
125 debug("Rela %" PRIx64
" %" PRIu64
" %" PRIx64
"\n",
126 swrela
.r_offset
, swrela
.r_info
, swrela
.r_addend
);
128 if (swrela
.r_offset
< text_base
) {
129 fprintf(stderr
, "%s: %s: bad rela at %" PRIx64
"\n",
130 argv
[0], argv
[1], pos
);
134 addr
= swrela
.r_offset
- text_base
;
136 if (fseek(f
, addr
, SEEK_SET
) < 0) {
137 fprintf(stderr
, "%s: %s: seek to %"
138 PRIx64
" failed: %s\n",
139 argv
[0], argv
[1], addr
, strerror(errno
));
142 if (fwrite(&rela
.r_addend
, sizeof(rela
.r_addend
), 1, f
) != 1) {
143 fprintf(stderr
, "%s: %s: write failed at %" PRIx64
"\n",
144 argv
[0], argv
[1], addr
);
150 fprintf(stderr
, "%s: %s: close failed: %s\n",
151 argv
[0], argv
[1], strerror(errno
));