36 #include <sys/types.h>
40 #include <generated/autoconf.h>
42 #define HYP_SECTION_PREFIX ".hyp"
43 #define HYP_RELOC_SECTION ".hyp.reloc"
44 #define HYP_SECTION_SYMBOL_PREFIX "__hyp_section_"
50 #ifndef R_AARCH64_ABS64
51 #define R_AARCH64_ABS64 257
53 #ifndef R_AARCH64_PREL64
54 #define R_AARCH64_PREL64 260
56 #ifndef R_AARCH64_PREL32
57 #define R_AARCH64_PREL32 261
59 #ifndef R_AARCH64_PREL16
60 #define R_AARCH64_PREL16 262
62 #ifndef R_AARCH64_PLT32
63 #define R_AARCH64_PLT32 314
65 #ifndef R_AARCH64_LD_PREL_LO19
66 #define R_AARCH64_LD_PREL_LO19 273
68 #ifndef R_AARCH64_ADR_PREL_LO21
69 #define R_AARCH64_ADR_PREL_LO21 274
71 #ifndef R_AARCH64_ADR_PREL_PG_HI21
72 #define R_AARCH64_ADR_PREL_PG_HI21 275
74 #ifndef R_AARCH64_ADR_PREL_PG_HI21_NC
75 #define R_AARCH64_ADR_PREL_PG_HI21_NC 276
77 #ifndef R_AARCH64_ADD_ABS_LO12_NC
78 #define R_AARCH64_ADD_ABS_LO12_NC 277
80 #ifndef R_AARCH64_LDST8_ABS_LO12_NC
81 #define R_AARCH64_LDST8_ABS_LO12_NC 278
83 #ifndef R_AARCH64_TSTBR14
84 #define R_AARCH64_TSTBR14 279
86 #ifndef R_AARCH64_CONDBR19
87 #define R_AARCH64_CONDBR19 280
89 #ifndef R_AARCH64_JUMP26
90 #define R_AARCH64_JUMP26 282
92 #ifndef R_AARCH64_CALL26
93 #define R_AARCH64_CALL26 283
95 #ifndef R_AARCH64_LDST16_ABS_LO12_NC
96 #define R_AARCH64_LDST16_ABS_LO12_NC 284
98 #ifndef R_AARCH64_LDST32_ABS_LO12_NC
99 #define R_AARCH64_LDST32_ABS_LO12_NC 285
101 #ifndef R_AARCH64_LDST64_ABS_LO12_NC
102 #define R_AARCH64_LDST64_ABS_LO12_NC 286
104 #ifndef R_AARCH64_MOVW_PREL_G0
105 #define R_AARCH64_MOVW_PREL_G0 287
107 #ifndef R_AARCH64_MOVW_PREL_G0_NC
108 #define R_AARCH64_MOVW_PREL_G0_NC 288
110 #ifndef R_AARCH64_MOVW_PREL_G1
111 #define R_AARCH64_MOVW_PREL_G1 289
113 #ifndef R_AARCH64_MOVW_PREL_G1_NC
114 #define R_AARCH64_MOVW_PREL_G1_NC 290
116 #ifndef R_AARCH64_MOVW_PREL_G2
117 #define R_AARCH64_MOVW_PREL_G2 291
119 #ifndef R_AARCH64_MOVW_PREL_G2_NC
120 #define R_AARCH64_MOVW_PREL_G2_NC 292
122 #ifndef R_AARCH64_MOVW_PREL_G3
123 #define R_AARCH64_MOVW_PREL_G3 293
125 #ifndef R_AARCH64_LDST128_ABS_LO12_NC
126 #define R_AARCH64_LDST128_ABS_LO12_NC 299
139 #if defined(CONFIG_CPU_LITTLE_ENDIAN)
141 #define elf16toh(x) le16toh(x)
142 #define elf32toh(x) le32toh(x)
143 #define elf64toh(x) le64toh(x)
145 #define ELFENDIAN ELFDATA2LSB
147 #elif defined(CONFIG_CPU_BIG_ENDIAN)
149 #define elf16toh(x) be16toh(x)
150 #define elf32toh(x) be32toh(x)
151 #define elf64toh(x) be64toh(x)
153 #define ELFENDIAN ELFDATA2MSB
157 #error PDP-endian sadly unsupported...
161 #define fatal_error(fmt, ...) \
163 fprintf(stderr, "error: %s: " fmt "\n", \
164 elf.path, ## __VA_ARGS__); \
165 exit(EXIT_FAILURE); \
166 __builtin_unreachable(); \
169 #define fatal_perror(msg) \
171 fprintf(stderr, "error: %s: " msg ": %s\n", \
172 elf.path, strerror(errno)); \
173 exit(EXIT_FAILURE); \
174 __builtin_unreachable(); \
177 #define assert_op(lhs, rhs, fmt, op) \
179 typeof(lhs) _lhs = (lhs); \
180 typeof(rhs) _rhs = (rhs); \
182 if (!(_lhs op _rhs)) { \
183 fatal_error("assertion " #lhs " " #op " " #rhs \
184 " failed (lhs=" fmt ", rhs=" fmt \
185 ", line=%d)", _lhs, _rhs, __LINE__); \
189 #define assert_eq(lhs, rhs, fmt) assert_op(lhs, rhs, fmt, ==)
190 #define assert_ne(lhs, rhs, fmt) assert_op(lhs, rhs, fmt, !=)
191 #define assert_lt(lhs, rhs, fmt) assert_op(lhs, rhs, fmt, <)
192 #define assert_ge(lhs, rhs, fmt) assert_op(lhs, rhs, fmt, >=)
198 #define elf_ptr(type, off) ((type *)(elf.begin + (off)))
201 #define for_each_section(var) \
202 for (var = elf.sh_table; var < elf.sh_table + elf16toh(elf.ehdr->e_shnum); ++var)
205 #define for_each_rela(shdr, var) \
206 for (var = elf_ptr(Elf64_Rela, elf64toh(shdr->sh_offset)); \
207 var < elf_ptr(Elf64_Rela, elf64toh(shdr->sh_offset) + elf64toh(shdr->sh_size)); var++)
210 static inline bool starts_with(
const char *str,
const char *prefix)
212 return memcmp(str, prefix, strlen(prefix)) == 0;
218 return elf.sh_string + elf32toh(shdr->sh_name);
224 return elf_ptr(
char, elf64toh(shdr->sh_offset));
231 return elf_ptr(Elf64_Shdr, off);
238 return &
elf.sh_table[idx];
254 fd = open(
path, O_RDONLY);
259 ret = fstat(fd, &stat);
266 elf.begin = mmap(0, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
267 if (
elf.begin == MAP_FAILED) {
286 assert_eq(
elf.ehdr->e_ident[EI_CLASS], ELFCLASS64,
"%u");
289 assert_eq(elf16toh(
elf.ehdr->e_machine), EM_AARCH64,
"%u");
329 static size_t reloc_offset;
340 printf(
".reloc %lu, R_AARCH64_PREL32, %s%s + 0x%lx\n",
342 elf64toh(rela->r_offset));
350 printf(
".popsection\n");
362 Elf64_Shdr *sh_orig = &
elf.sh_table[elf32toh(sh_rela->sh_info)];
373 uint32_t type = (uint32_t)elf64toh(rela->r_info);
376 assert_lt(elf64toh(rela->r_offset), elf64toh(sh_orig->sh_size),
"0x%lx");
431 switch (elf32toh(shdr->sh_type)) {
442 int main(
int argc,
const char **argv)
445 fprintf(stderr,
"Usage: %s <elf_input>\n", argv[0]);
#define R_AARCH64_MOVW_PREL_G3
#define R_AARCH64_LDST8_ABS_LO12_NC
static Elf64_Shdr * section_by_idx(uint16_t idx)
#define R_AARCH64_CONDBR19
static void init_elf(const char *path)
static bool starts_with(const char *str, const char *prefix)
#define R_AARCH64_LDST64_ABS_LO12_NC
int main(int argc, const char **argv)
#define elf_ptr(type, off)
static void emit_all_relocs(void)
#define HYP_SECTION_SYMBOL_PREFIX
static const char * section_begin(Elf64_Shdr *shdr)
#define assert_lt(lhs, rhs, fmt)
#define R_AARCH64_MOVW_PREL_G2
#define for_each_section(var)
#define HYP_RELOC_SECTION
#define HYP_SECTION_PREFIX
static void emit_epilogue(void)
static void emit_rela_abs64(Elf64_Rela *rela, const char *sh_orig_name)
static const char * section_name(Elf64_Shdr *shdr)
#define R_AARCH64_MOVW_PREL_G2_NC
#define assert_eq(lhs, rhs, fmt)
#define R_AARCH64_ADR_PREL_PG_HI21_NC
static void emit_rela_section(Elf64_Shdr *sh_rela)
#define R_AARCH64_MOVW_PREL_G1
#define R_AARCH64_LDST128_ABS_LO12_NC
#define R_AARCH64_MOVW_PREL_G0_NC
#define fatal_perror(msg)
#define R_AARCH64_LD_PREL_LO19
#define for_each_rela(shdr, var)
#define assert_ne(lhs, rhs, fmt)
#define fatal_error(fmt,...)
static Elf64_Shdr * section_by_off(Elf64_Off off)
#define assert_ge(lhs, rhs, fmt)
#define R_AARCH64_ADD_ABS_LO12_NC
#define R_AARCH64_ADR_PREL_LO21
static void emit_section_prologue(const char *sh_orig_name)
#define R_AARCH64_MOVW_PREL_G0
#define R_AARCH64_TSTBR14
#define R_AARCH64_LDST32_ABS_LO12_NC
#define R_AARCH64_LDST16_ABS_LO12_NC
static void emit_prologue(void)
#define R_AARCH64_ADR_PREL_PG_HI21
#define R_AARCH64_MOVW_PREL_G1_NC