1// SPDX-License-Identifier: GPL-2.0 2/* This is included from relocs_32/64.c */ 3 4#define ElfW(type) _ElfW(ELF_BITS, type) 5#define _ElfW(bits, type) __ElfW(bits, type) 6#define __ElfW(bits, type) Elf##bits##_##type 7 8#define Elf_Addr ElfW(Addr) 9#define Elf_Ehdr ElfW(Ehdr) 10#define Elf_Phdr ElfW(Phdr) 11#define Elf_Shdr ElfW(Shdr) 12#define Elf_Sym ElfW(Sym) 13 14static Elf_Ehdr ehdr; 15 16struct relocs { 17 uint32_t *offset; 18 unsigned long count; 19 unsigned long size; 20}; 21 22static struct relocs relocs; 23 24struct section { 25 Elf_Shdr shdr; 26 struct section *link; 27 Elf_Sym *symtab; 28 Elf_Rel *reltab; 29 char *strtab; 30 long shdr_offset; 31}; 32static struct section *secs; 33 34static const char * const regex_sym_kernel = { 35/* Symbols matching these regex's should never be relocated */ 36 "^(__crc_)", 37}; 38 39static regex_t sym_regex_c; 40 41static int regex_skip_reloc(const char *sym_name) 42{ 43 return !regexec(&sym_regex_c, sym_name, 0, NULL, 0); 44} 45 46static void regex_init(void) 47{ 48 char errbuf[128]; 49 int err; 50 51 err = regcomp(&sym_regex_c, regex_sym_kernel, 52 REG_EXTENDED|REG_NOSUB); 53 54 if (err) { 55 regerror(err, &sym_regex_c, errbuf, sizeof(errbuf)); 56 die("%s", errbuf); 57 } 58} 59 60static const char *rel_type(unsigned type) 61{ 62 static const char * const type_name[] = { 63#define REL_TYPE(X)[X] = #X 64 REL_TYPE(R_LARCH_NONE), 65 REL_TYPE(R_LARCH_32), 66 REL_TYPE(R_LARCH_64), 67 REL_TYPE(R_LARCH_MARK_LA), 68 REL_TYPE(R_LARCH_MARK_PCREL), 69 REL_TYPE(R_LARCH_SOP_PUSH_PCREL), 70 REL_TYPE(R_LARCH_SOP_PUSH_ABSOLUTE), 71 REL_TYPE(R_LARCH_SOP_PUSH_DUP), 72 REL_TYPE(R_LARCH_SOP_PUSH_PLT_PCREL), 73 REL_TYPE(R_LARCH_SOP_SUB), 74 REL_TYPE(R_LARCH_SOP_SL), 75 REL_TYPE(R_LARCH_SOP_SR), 76 REL_TYPE(R_LARCH_SOP_ADD), 77 REL_TYPE(R_LARCH_SOP_AND), 78 REL_TYPE(R_LARCH_SOP_IF_ELSE), 79 REL_TYPE(R_LARCH_SOP_POP_32_S_10_5), 80 REL_TYPE(R_LARCH_SOP_POP_32_U_10_12), 81 REL_TYPE(R_LARCH_SOP_POP_32_S_10_12), 82 REL_TYPE(R_LARCH_SOP_POP_32_S_10_16), 83 REL_TYPE(R_LARCH_SOP_POP_32_S_10_16_S2), 84 REL_TYPE(R_LARCH_SOP_POP_32_S_5_20), 85 REL_TYPE(R_LARCH_SOP_POP_32_S_0_5_10_16_S2), 86 REL_TYPE(R_LARCH_SOP_POP_32_S_0_10_10_16_S2), 87 REL_TYPE(R_LARCH_SOP_POP_32_U), 88 REL_TYPE(R_LARCH_ADD32), 89 REL_TYPE(R_LARCH_ADD64), 90 REL_TYPE(R_LARCH_SUB32), 91 REL_TYPE(R_LARCH_SUB64), 92#undef REL_TYPE 93 }; 94 const char *name = "unknown type rel type name"; 95 96 if (type < ARRAY_SIZE(type_name) && type_name[type]) 97 name = type_name[type]; 98 return name; 99} 100 101static const char *sec_name(unsigned shndx) 102{ 103 const char *sec_strtab; 104 const char *name; 105 106 sec_strtab = secs[ehdr.e_shstrndx].strtab; 107 if (shndx < ehdr.e_shnum) 108 name = sec_strtab + secs[shndx].shdr.sh_name; 109 else if (shndx == SHN_ABS) 110 name = "ABSOLUTE"; 111 else if (shndx == SHN_COMMON) 112 name = "COMMON"; 113 else 114 name = "<noname>"; 115 return name; 116} 117 118static struct section *sec_lookup(const char *secname) 119{ 120 int i; 121 122 for (i = 0; i < ehdr.e_shnum; i++) 123 if (strcmp(secname, sec_name(i)) == 0) 124 return &secs[i]; 125 126 return NULL; 127} 128 129static const char *sym_name(const char *sym_strtab, Elf_Sym *sym) 130{ 131 const char *name; 132 133 if (sym->st_name) 134 name = sym_strtab + sym->st_name; 135 else 136 name = sec_name(sym->st_shndx); 137 return name; 138} 139 140static void read_ehdr(FILE *fp) 141{ 142 if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1) 143 die("Cannot read ELF header: %s\n", strerror(errno)); 144 145 if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0) 146 die("No ELF magic\n"); 147 148 if (ehdr.e_ident[EI_CLASS] != ELF_CLASS) 149 die("Not a %d bit executable\n", ELF_BITS); 150 151 if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) 152 die("Unsupported ELF Endianness\n"); 153 154 if (ehdr.e_ident[EI_VERSION] != EV_CURRENT) 155 die("Unknown ELF version\n"); 156 157 if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN)) 158 die("Unsupported ELF header type\n"); 159 160 if (ehdr.e_machine != ELF_MACHINE) 161 die("Not for %s\n", ELF_MACHINE_NAME); 162 163 if (ehdr.e_version != EV_CURRENT) 164 die("Unknown ELF version\n"); 165 166 if (ehdr.e_ehsize != sizeof(Elf_Ehdr)) 167 die("Bad Elf header size\n"); 168 169 if (ehdr.e_phentsize != sizeof(Elf_Phdr)) 170 die("Bad program header entry\n"); 171 172 if (ehdr.e_shentsize != sizeof(Elf_Shdr)) 173 die("Bad section header entry\n"); 174 175 if (ehdr.e_shstrndx >= ehdr.e_shnum) 176 die("String table index out of bounds\n"); 177} 178 179static void read_shdrs(FILE *fp) 180{ 181 int i; 182 183 secs = calloc(ehdr.e_shnum, sizeof(struct section)); 184 if (!secs) 185 die("Unable to allocate %d section headers\n", ehdr.e_shnum); 186 187 if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0) 188 die("Seek to %d failed: %s\n", ehdr.e_shoff, strerror(errno)); 189 190 for (i = 0; i < ehdr.e_shnum; i++) { 191 struct section *sec = &secs[i]; 192 193 sec->shdr_offset = ftell(fp); 194 if (fread(&sec->shdr, sizeof(Elf_Shdr), 1, fp) != 1) 195 die("Cannot read ELF section headers %d/%d: %s\n", 196 i, ehdr.e_shnum, strerror(errno)); 197 198 if (sec->shdr.sh_link < ehdr.e_shnum) 199 sec->link = &secs[sec->shdr.sh_link]; 200 } 201} 202 203static void read_strtabs(FILE *fp) 204{ 205 int i; 206 207 for (i = 0; i < ehdr.e_shnum; i++) { 208 struct section *sec = &secs[i]; 209 210 if (sec->shdr.sh_type != SHT_STRTAB) 211 continue; 212 213 sec->strtab = malloc(sec->shdr.sh_size); 214 if (!sec->strtab) 215 die("malloc of %d bytes for strtab failed\n", 216 sec->shdr.sh_size); 217 218 if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) 219 die("Seek to %d failed: %s\n", 220 sec->shdr.sh_offset, strerror(errno)); 221 222 if (fread(sec->strtab, 1, sec->shdr.sh_size, fp) != 223 sec->shdr.sh_size) 224 die("Cannot read symbol table: %s\n", strerror(errno)); 225 } 226} 227 228static void read_symtabs(FILE *fp) 229{ 230 int i; 231 232 for (i = 0; i < ehdr.e_shnum; i++) { 233 struct section *sec = &secs[i]; 234 if (sec->shdr.sh_type != SHT_SYMTAB) 235 continue; 236 237 sec->symtab = malloc(sec->shdr.sh_size); 238 if (!sec->symtab) 239 die("malloc of %d bytes for symtab failed\n", 240 sec->shdr.sh_size); 241 242 if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) 243 die("Seek to %d failed: %s\n", 244 sec->shdr.sh_offset, strerror(errno)); 245 246 if (fread(sec->symtab, 1, sec->shdr.sh_size, fp) != 247 sec->shdr.sh_size) 248 die("Cannot read symbol table: %s\n", strerror(errno)); 249 } 250} 251 252static void read_relocs(FILE *fp) 253{ 254 static unsigned long base = 0; 255 int i, j; 256 257 if (!base) { 258 struct section *sec = sec_lookup(".text"); 259 260 if (!sec) 261 die("Could not find .text section\n"); 262 263 base = sec->shdr.sh_addr; 264 } 265 266 for (i = 0; i < ehdr.e_shnum; i++) { 267 struct section *sec = &secs[i]; 268 269 if (sec->shdr.sh_type != SHT_REL_TYPE) 270 continue; 271 272 sec->reltab = malloc(sec->shdr.sh_size); 273 if (!sec->reltab) 274 die("malloc of %d bytes for relocs failed\n", 275 sec->shdr.sh_size); 276 277 if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0) 278 die("Seek to %d failed: %s\n", 279 sec->shdr.sh_offset, strerror(errno)); 280 281 if (fread(sec->reltab, 1, sec->shdr.sh_size, fp) != 282 sec->shdr.sh_size) 283 die("Cannot read symbol table: %s\n", strerror(errno)); 284 285 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) { 286 Elf_Rel *rel = &sec->reltab[j]; 287 288 /* Set offset into kernel image */ 289 rel->r_offset -= base; 290 } 291 } 292} 293 294static void remove_relocs(FILE *fp) 295{ 296 int i; 297 Elf_Shdr shdr; 298 299 for (i = 0; i < ehdr.e_shnum; i++) { 300 struct section *sec = &secs[i]; 301 302 if (sec->shdr.sh_type != SHT_REL_TYPE) 303 continue; 304 305 if (fseek(fp, sec->shdr_offset, SEEK_SET) < 0) 306 die("Seek to %d failed: %s\n", 307 sec->shdr_offset, strerror(errno)); 308 309 if (fread(&shdr, sizeof(shdr), 1, fp) != 1) 310 die("Cannot read ELF section headers %d/%d: %s\n", 311 i, ehdr.e_shnum, strerror(errno)); 312 313 /* Set relocation section size to 0, effectively removing it. 314 * This is necessary due to lack of support for relocations 315 * in objcopy when creating 32bit elf from 64bit elf. 316 */ 317 shdr.sh_size = 0; 318 319 if (fseek(fp, sec->shdr_offset, SEEK_SET) < 0) 320 die("Seek to %d failed: %s\n", 321 sec->shdr_offset, strerror(errno)); 322 323 if (fwrite(&shdr, sizeof(shdr), 1, fp) != 1) 324 die("Cannot write ELF section headers %d/%d: %s\n", 325 i, ehdr.e_shnum, strerror(errno)); 326 } 327} 328 329static void add_reloc(struct relocs *r, uint32_t offset, unsigned type) 330{ 331 /* Relocation representation in binary table: 332 * |76543210|76543210|76543210|76543210| 333 * | Type | offset from _text >> 2 | 334 */ 335 offset >>= 2; 336 if (offset > 0x00FFFFFF) 337 die("Kernel image exceeds maximum size for relocation!\n"); 338 339 offset = (offset & 0x00FFFFFF) | ((type & 0xFF) << 24); 340 341 if (r->count == r->size) { 342 unsigned long newsize = r->size + 50000; 343 void *mem = realloc(r->offset, newsize * sizeof(r->offset[0])); 344 345 if (!mem) 346 die("realloc failed\n"); 347 348 r->offset = mem; 349 r->size = newsize; 350 } 351 r->offset[r->count++] = offset; 352} 353 354static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel, 355 Elf_Sym *sym, const char *symname)) 356{ 357 int i; 358 359 /* Walk through the relocations */ 360 for (i = 0; i < ehdr.e_shnum; i++) { 361 char *sym_strtab; 362 Elf_Sym *sh_symtab; 363 struct section *sec_applies, *sec_symtab; 364 int j; 365 struct section *sec = &secs[i]; 366 367 if (sec->shdr.sh_type != SHT_REL_TYPE) 368 continue; 369 370 sec_symtab = sec->link; 371 sec_applies = &secs[sec->shdr.sh_info]; 372 if (!(sec_applies->shdr.sh_flags & SHF_ALLOC)) 373 continue; 374 375 sh_symtab = sec_symtab->symtab; 376 sym_strtab = sec_symtab->link->strtab; 377 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) { 378 Elf_Rel *rel = &sec->reltab[j]; 379 Elf_Sym *sym = &sh_symtab[ELF_R_SYM(rel->r_info)]; 380 const char *symname = sym_name(sym_strtab, sym); 381 382 process(sec, rel, sym, symname); 383 } 384 } 385} 386 387static int do_reloc(struct section *sec, Elf_Rel *rel, Elf_Sym *sym, 388 const char *symname) 389{ 390 unsigned r_type = ELF_R_TYPE(rel->r_info); 391 unsigned bind = ELF_ST_BIND(sym->st_info); 392 393 if ((bind == STB_WEAK) && (sym->st_value == 0)) { 394 /* Don't relocate weak symbols without a target */ 395 return 0; 396 } 397 398 if (regex_skip_reloc(symname)) 399 return 0; 400 401 switch (r_type) { 402 case R_LARCH_NONE: 403 case R_LARCH_MARK_PCREL: 404 case R_LARCH_SOP_PUSH_PCREL: 405 case R_LARCH_SOP_PUSH_ABSOLUTE: 406 case R_LARCH_SOP_PUSH_DUP: 407 case R_LARCH_SOP_PUSH_PLT_PCREL: 408 case R_LARCH_SOP_SUB: 409 case R_LARCH_SOP_SL: 410 case R_LARCH_SOP_SR: 411 case R_LARCH_SOP_ADD: 412 case R_LARCH_SOP_AND: 413 case R_LARCH_SOP_IF_ELSE: 414 case R_LARCH_SOP_POP_32_S_10_5: 415 case R_LARCH_SOP_POP_32_U_10_12: 416 case R_LARCH_SOP_POP_32_S_10_12: 417 case R_LARCH_SOP_POP_32_S_10_16: 418 case R_LARCH_SOP_POP_32_S_10_16_S2: 419 case R_LARCH_SOP_POP_32_S_5_20: 420 case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: 421 case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: 422 case R_LARCH_SOP_POP_32_U: 423 case R_LARCH_ADD32: 424 case R_LARCH_ADD64: 425 case R_LARCH_SUB32: 426 case R_LARCH_SUB64: 427 break; 428 429 case R_LARCH_32: 430 case R_LARCH_64: 431 case R_LARCH_MARK_LA: 432 add_reloc(&relocs, rel->r_offset, r_type); 433 break; 434 435 default: 436 die("Unsupported relocation type: %s (%d)\n", rel_type(r_type), r_type); 437 break; 438 } 439 440 return 0; 441} 442 443static int write_reloc_as_bin(uint32_t v, FILE *f) 444{ 445 return fwrite(&v, 4, 1, f); 446} 447 448static int write_reloc_as_text(uint32_t v, FILE *f) 449{ 450 int res; 451 452 res = fprintf(f, "\t.long 0x%08"PRIx32"\n", v); 453 if (res < 0) 454 return res; 455 else 456 return sizeof(uint32_t); 457} 458 459static void emit_relocs(int as_text, int as_bin, FILE *outf) 460{ 461 int i; 462 int (*write_reloc)(uint32_t, FILE *) = write_reloc_as_bin; 463 int size = 0; 464 int size_reserved; 465 struct section *sec_reloc; 466 467 sec_reloc = sec_lookup(".data.reloc"); 468 if (!sec_reloc) 469 die("Could not find relocation section\n"); 470 471 size_reserved = sec_reloc->shdr.sh_size; 472 473 /* Collect up the relocations */ 474 walk_relocs(do_reloc); 475 476 /* Print the relocations */ 477 if (as_text) { 478 /* Print the relocations in a form suitable that 479 * gas will like. 480 */ 481 printf(".section \".data.reloc\",\"a\"\n"); 482 printf(".balign 4\n"); 483 /* Output text to stdout */ 484 write_reloc = write_reloc_as_text; 485 outf = stdout; 486 } else if (as_bin) { 487 /* Output raw binary to stdout */ 488 outf = stdout; 489 } else { 490 /* Seek to offset of the relocation section. 491 * Each relocation is then written into the 492 * vmlinux kernel image. 493 */ 494 if (fseek(outf, sec_reloc->shdr.sh_offset, SEEK_SET) < 0) { 495 die("Seek to %d failed: %s\n", 496 sec_reloc->shdr.sh_offset, strerror(errno)); 497 } 498 } 499 500 for (i = 0; i < relocs.count; i++) 501 size += write_reloc(relocs.offset[i], outf); 502 503 /* Print a stop, but only if we've actually written some relocs */ 504 if (size) 505 size += write_reloc(0, outf); 506 507 if (size > size_reserved) 508 /* Die, but suggest a value for CONFIG_RELOCATION_TABLE_SIZE 509 * which will fix this problem and allow a bit of headroom 510 * if more kernel features are enabled 511 */ 512 die("Relocations overflow available space!\n" \ 513 "Please adjust CONFIG_RELOCATION_TABLE_SIZE " \ 514 "to at least 0x%08x\n", (size + 0x1000) & ~0xFFF); 515} 516 517/* 518 * As an aid to debugging problems with different linkers 519 * print summary information about the relocs. 520 * Since different linkers tend to emit the sections in 521 * different orders we use the section names in the output. 522 */ 523static int do_reloc_info(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym, 524 const char *symname) 525{ 526 printf("%-16s 0x%08x %-35s %-40s %-16s\n", 527 sec_name(sec->shdr.sh_info), 528 (unsigned int)rel->r_offset, 529 rel_type(ELF_R_TYPE(rel->r_info)), 530 symname, 531 sec_name(sym->st_shndx)); 532 return 0; 533} 534 535static void print_reloc_info(void) 536{ 537 printf("%-16s %-10s %-35s %-40s %-16s\n", 538 "reloc section", 539 "offset", 540 "reloc type", 541 "symbol", 542 "symbol section"); 543 walk_relocs(do_reloc_info); 544} 545 546#if ELF_BITS == 64 547# define process process_64 548#else 549# define process process_32 550#endif 551 552void process(FILE *fp, int as_text, int as_bin, 553 int show_reloc_info, int keep_relocs) 554{ 555 regex_init(); 556 read_ehdr(fp); 557 read_shdrs(fp); 558 read_strtabs(fp); 559 read_symtabs(fp); 560 read_relocs(fp); 561 if (show_reloc_info) { 562 print_reloc_info(); 563 return; 564 } 565 emit_relocs(as_text, as_bin, fp); 566 if (!keep_relocs) 567 remove_relocs(fp); 568} 569