root/arch/mips/boot/tools/relocs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. regex_skip_reloc
  2. regex_init
  3. rel_type
  4. sec_name
  5. sec_lookup
  6. sym_name
  7. elf16_to_cpu
  8. elf32_to_cpu
  9. cpu_to_elf32
  10. elf64_to_cpu
  11. read_ehdr
  12. read_shdrs
  13. read_strtabs
  14. read_symtabs
  15. read_relocs
  16. remove_relocs
  17. add_reloc
  18. walk_relocs
  19. do_reloc
  20. write_reloc_as_bin
  21. write_reloc_as_text
  22. emit_relocs
  23. do_reloc_info
  24. print_reloc_info
  25. process

   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 
  14 static Elf_Ehdr ehdr;
  15 
  16 struct relocs {
  17         uint32_t        *offset;
  18         unsigned long   count;
  19         unsigned long   size;
  20 };
  21 
  22 static struct relocs relocs;
  23 
  24 struct 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 };
  32 static struct section *secs;
  33 
  34 static const char * const regex_sym_kernel = {
  35 /* Symbols matching these regex's should never be relocated */
  36         "^(__crc_)",
  37 };
  38 
  39 static regex_t sym_regex_c;
  40 
  41 static int regex_skip_reloc(const char *sym_name)
  42 {
  43         return !regexec(&sym_regex_c, sym_name, 0, NULL, 0);
  44 }
  45 
  46 static 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 
  60 static 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_MIPS_NONE),
  65                 REL_TYPE(R_MIPS_16),
  66                 REL_TYPE(R_MIPS_32),
  67                 REL_TYPE(R_MIPS_REL32),
  68                 REL_TYPE(R_MIPS_26),
  69                 REL_TYPE(R_MIPS_HI16),
  70                 REL_TYPE(R_MIPS_LO16),
  71                 REL_TYPE(R_MIPS_GPREL16),
  72                 REL_TYPE(R_MIPS_LITERAL),
  73                 REL_TYPE(R_MIPS_GOT16),
  74                 REL_TYPE(R_MIPS_PC16),
  75                 REL_TYPE(R_MIPS_CALL16),
  76                 REL_TYPE(R_MIPS_GPREL32),
  77                 REL_TYPE(R_MIPS_64),
  78                 REL_TYPE(R_MIPS_HIGHER),
  79                 REL_TYPE(R_MIPS_HIGHEST),
  80                 REL_TYPE(R_MIPS_PC21_S2),
  81                 REL_TYPE(R_MIPS_PC26_S2),
  82 #undef REL_TYPE
  83         };
  84         const char *name = "unknown type rel type name";
  85 
  86         if (type < ARRAY_SIZE(type_name) && type_name[type])
  87                 name = type_name[type];
  88         return name;
  89 }
  90 
  91 static const char *sec_name(unsigned shndx)
  92 {
  93         const char *sec_strtab;
  94         const char *name;
  95 
  96         sec_strtab = secs[ehdr.e_shstrndx].strtab;
  97         if (shndx < ehdr.e_shnum)
  98                 name = sec_strtab + secs[shndx].shdr.sh_name;
  99         else if (shndx == SHN_ABS)
 100                 name = "ABSOLUTE";
 101         else if (shndx == SHN_COMMON)
 102                 name = "COMMON";
 103         else
 104                 name = "<noname>";
 105         return name;
 106 }
 107 
 108 static struct section *sec_lookup(const char *secname)
 109 {
 110         int i;
 111 
 112         for (i = 0; i < ehdr.e_shnum; i++)
 113                 if (strcmp(secname, sec_name(i)) == 0)
 114                         return &secs[i];
 115 
 116         return NULL;
 117 }
 118 
 119 static const char *sym_name(const char *sym_strtab, Elf_Sym *sym)
 120 {
 121         const char *name;
 122 
 123         if (sym->st_name)
 124                 name = sym_strtab + sym->st_name;
 125         else
 126                 name = sec_name(sym->st_shndx);
 127         return name;
 128 }
 129 
 130 #if BYTE_ORDER == LITTLE_ENDIAN
 131 #define le16_to_cpu(val) (val)
 132 #define le32_to_cpu(val) (val)
 133 #define le64_to_cpu(val) (val)
 134 #define be16_to_cpu(val) bswap_16(val)
 135 #define be32_to_cpu(val) bswap_32(val)
 136 #define be64_to_cpu(val) bswap_64(val)
 137 
 138 #define cpu_to_le16(val) (val)
 139 #define cpu_to_le32(val) (val)
 140 #define cpu_to_le64(val) (val)
 141 #define cpu_to_be16(val) bswap_16(val)
 142 #define cpu_to_be32(val) bswap_32(val)
 143 #define cpu_to_be64(val) bswap_64(val)
 144 #endif
 145 #if BYTE_ORDER == BIG_ENDIAN
 146 #define le16_to_cpu(val) bswap_16(val)
 147 #define le32_to_cpu(val) bswap_32(val)
 148 #define le64_to_cpu(val) bswap_64(val)
 149 #define be16_to_cpu(val) (val)
 150 #define be32_to_cpu(val) (val)
 151 #define be64_to_cpu(val) (val)
 152 
 153 #define cpu_to_le16(val) bswap_16(val)
 154 #define cpu_to_le32(val) bswap_32(val)
 155 #define cpu_to_le64(val) bswap_64(val)
 156 #define cpu_to_be16(val) (val)
 157 #define cpu_to_be32(val) (val)
 158 #define cpu_to_be64(val) (val)
 159 #endif
 160 
 161 static uint16_t elf16_to_cpu(uint16_t val)
 162 {
 163         if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
 164                 return le16_to_cpu(val);
 165         else
 166                 return be16_to_cpu(val);
 167 }
 168 
 169 static uint32_t elf32_to_cpu(uint32_t val)
 170 {
 171         if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
 172                 return le32_to_cpu(val);
 173         else
 174                 return be32_to_cpu(val);
 175 }
 176 
 177 static uint32_t cpu_to_elf32(uint32_t val)
 178 {
 179         if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
 180                 return cpu_to_le32(val);
 181         else
 182                 return cpu_to_be32(val);
 183 }
 184 
 185 #define elf_half_to_cpu(x)      elf16_to_cpu(x)
 186 #define elf_word_to_cpu(x)      elf32_to_cpu(x)
 187 
 188 #if ELF_BITS == 64
 189 static uint64_t elf64_to_cpu(uint64_t val)
 190 {
 191         if (ehdr.e_ident[EI_DATA] == ELFDATA2LSB)
 192                 return le64_to_cpu(val);
 193         else
 194                 return be64_to_cpu(val);
 195 }
 196 #define elf_addr_to_cpu(x)      elf64_to_cpu(x)
 197 #define elf_off_to_cpu(x)       elf64_to_cpu(x)
 198 #define elf_xword_to_cpu(x)     elf64_to_cpu(x)
 199 #else
 200 #define elf_addr_to_cpu(x)      elf32_to_cpu(x)
 201 #define elf_off_to_cpu(x)       elf32_to_cpu(x)
 202 #define elf_xword_to_cpu(x)     elf32_to_cpu(x)
 203 #endif
 204 
 205 static void read_ehdr(FILE *fp)
 206 {
 207         if (fread(&ehdr, sizeof(ehdr), 1, fp) != 1)
 208                 die("Cannot read ELF header: %s\n", strerror(errno));
 209 
 210         if (memcmp(ehdr.e_ident, ELFMAG, SELFMAG) != 0)
 211                 die("No ELF magic\n");
 212 
 213         if (ehdr.e_ident[EI_CLASS] != ELF_CLASS)
 214                 die("Not a %d bit executable\n", ELF_BITS);
 215 
 216         if ((ehdr.e_ident[EI_DATA] != ELFDATA2LSB) &&
 217             (ehdr.e_ident[EI_DATA] != ELFDATA2MSB))
 218                 die("Unknown ELF Endianness\n");
 219 
 220         if (ehdr.e_ident[EI_VERSION] != EV_CURRENT)
 221                 die("Unknown ELF version\n");
 222 
 223         /* Convert the fields to native endian */
 224         ehdr.e_type      = elf_half_to_cpu(ehdr.e_type);
 225         ehdr.e_machine   = elf_half_to_cpu(ehdr.e_machine);
 226         ehdr.e_version   = elf_word_to_cpu(ehdr.e_version);
 227         ehdr.e_entry     = elf_addr_to_cpu(ehdr.e_entry);
 228         ehdr.e_phoff     = elf_off_to_cpu(ehdr.e_phoff);
 229         ehdr.e_shoff     = elf_off_to_cpu(ehdr.e_shoff);
 230         ehdr.e_flags     = elf_word_to_cpu(ehdr.e_flags);
 231         ehdr.e_ehsize    = elf_half_to_cpu(ehdr.e_ehsize);
 232         ehdr.e_phentsize = elf_half_to_cpu(ehdr.e_phentsize);
 233         ehdr.e_phnum     = elf_half_to_cpu(ehdr.e_phnum);
 234         ehdr.e_shentsize = elf_half_to_cpu(ehdr.e_shentsize);
 235         ehdr.e_shnum     = elf_half_to_cpu(ehdr.e_shnum);
 236         ehdr.e_shstrndx  = elf_half_to_cpu(ehdr.e_shstrndx);
 237 
 238         if ((ehdr.e_type != ET_EXEC) && (ehdr.e_type != ET_DYN))
 239                 die("Unsupported ELF header type\n");
 240 
 241         if (ehdr.e_machine != ELF_MACHINE)
 242                 die("Not for %s\n", ELF_MACHINE_NAME);
 243 
 244         if (ehdr.e_version != EV_CURRENT)
 245                 die("Unknown ELF version\n");
 246 
 247         if (ehdr.e_ehsize != sizeof(Elf_Ehdr))
 248                 die("Bad Elf header size\n");
 249 
 250         if (ehdr.e_phentsize != sizeof(Elf_Phdr))
 251                 die("Bad program header entry\n");
 252 
 253         if (ehdr.e_shentsize != sizeof(Elf_Shdr))
 254                 die("Bad section header entry\n");
 255 
 256         if (ehdr.e_shstrndx >= ehdr.e_shnum)
 257                 die("String table index out of bounds\n");
 258 }
 259 
 260 static void read_shdrs(FILE *fp)
 261 {
 262         int i;
 263         Elf_Shdr shdr;
 264 
 265         secs = calloc(ehdr.e_shnum, sizeof(struct section));
 266         if (!secs)
 267                 die("Unable to allocate %d section headers\n", ehdr.e_shnum);
 268 
 269         if (fseek(fp, ehdr.e_shoff, SEEK_SET) < 0)
 270                 die("Seek to %d failed: %s\n", ehdr.e_shoff, strerror(errno));
 271 
 272         for (i = 0; i < ehdr.e_shnum; i++) {
 273                 struct section *sec = &secs[i];
 274 
 275                 sec->shdr_offset = ftell(fp);
 276                 if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
 277                         die("Cannot read ELF section headers %d/%d: %s\n",
 278                             i, ehdr.e_shnum, strerror(errno));
 279                 sec->shdr.sh_name      = elf_word_to_cpu(shdr.sh_name);
 280                 sec->shdr.sh_type      = elf_word_to_cpu(shdr.sh_type);
 281                 sec->shdr.sh_flags     = elf_xword_to_cpu(shdr.sh_flags);
 282                 sec->shdr.sh_addr      = elf_addr_to_cpu(shdr.sh_addr);
 283                 sec->shdr.sh_offset    = elf_off_to_cpu(shdr.sh_offset);
 284                 sec->shdr.sh_size      = elf_xword_to_cpu(shdr.sh_size);
 285                 sec->shdr.sh_link      = elf_word_to_cpu(shdr.sh_link);
 286                 sec->shdr.sh_info      = elf_word_to_cpu(shdr.sh_info);
 287                 sec->shdr.sh_addralign = elf_xword_to_cpu(shdr.sh_addralign);
 288                 sec->shdr.sh_entsize   = elf_xword_to_cpu(shdr.sh_entsize);
 289                 if (sec->shdr.sh_link < ehdr.e_shnum)
 290                         sec->link = &secs[sec->shdr.sh_link];
 291         }
 292 }
 293 
 294 static void read_strtabs(FILE *fp)
 295 {
 296         int i;
 297 
 298         for (i = 0; i < ehdr.e_shnum; i++) {
 299                 struct section *sec = &secs[i];
 300 
 301                 if (sec->shdr.sh_type != SHT_STRTAB)
 302                         continue;
 303 
 304                 sec->strtab = malloc(sec->shdr.sh_size);
 305                 if (!sec->strtab)
 306                         die("malloc of %d bytes for strtab failed\n",
 307                             sec->shdr.sh_size);
 308 
 309                 if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
 310                         die("Seek to %d failed: %s\n",
 311                             sec->shdr.sh_offset, strerror(errno));
 312 
 313                 if (fread(sec->strtab, 1, sec->shdr.sh_size, fp) !=
 314                     sec->shdr.sh_size)
 315                         die("Cannot read symbol table: %s\n", strerror(errno));
 316         }
 317 }
 318 
 319 static void read_symtabs(FILE *fp)
 320 {
 321         int i, j;
 322 
 323         for (i = 0; i < ehdr.e_shnum; i++) {
 324                 struct section *sec = &secs[i];
 325                 if (sec->shdr.sh_type != SHT_SYMTAB)
 326                         continue;
 327 
 328                 sec->symtab = malloc(sec->shdr.sh_size);
 329                 if (!sec->symtab)
 330                         die("malloc of %d bytes for symtab failed\n",
 331                             sec->shdr.sh_size);
 332 
 333                 if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
 334                         die("Seek to %d failed: %s\n",
 335                             sec->shdr.sh_offset, strerror(errno));
 336 
 337                 if (fread(sec->symtab, 1, sec->shdr.sh_size, fp) !=
 338                     sec->shdr.sh_size)
 339                         die("Cannot read symbol table: %s\n", strerror(errno));
 340 
 341                 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Sym); j++) {
 342                         Elf_Sym *sym = &sec->symtab[j];
 343 
 344                         sym->st_name  = elf_word_to_cpu(sym->st_name);
 345                         sym->st_value = elf_addr_to_cpu(sym->st_value);
 346                         sym->st_size  = elf_xword_to_cpu(sym->st_size);
 347                         sym->st_shndx = elf_half_to_cpu(sym->st_shndx);
 348                 }
 349         }
 350 }
 351 
 352 static void read_relocs(FILE *fp)
 353 {
 354         static unsigned long base = 0;
 355         int i, j;
 356 
 357         if (!base) {
 358                 struct section *sec = sec_lookup(".text");
 359 
 360                 if (!sec)
 361                         die("Could not find .text section\n");
 362 
 363                 base = sec->shdr.sh_addr;
 364         }
 365 
 366         for (i = 0; i < ehdr.e_shnum; i++) {
 367                 struct section *sec = &secs[i];
 368 
 369                 if (sec->shdr.sh_type != SHT_REL_TYPE)
 370                         continue;
 371 
 372                 sec->reltab = malloc(sec->shdr.sh_size);
 373                 if (!sec->reltab)
 374                         die("malloc of %d bytes for relocs failed\n",
 375                             sec->shdr.sh_size);
 376 
 377                 if (fseek(fp, sec->shdr.sh_offset, SEEK_SET) < 0)
 378                         die("Seek to %d failed: %s\n",
 379                             sec->shdr.sh_offset, strerror(errno));
 380 
 381                 if (fread(sec->reltab, 1, sec->shdr.sh_size, fp) !=
 382                     sec->shdr.sh_size)
 383                         die("Cannot read symbol table: %s\n", strerror(errno));
 384 
 385                 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
 386                         Elf_Rel *rel = &sec->reltab[j];
 387 
 388                         rel->r_offset = elf_addr_to_cpu(rel->r_offset);
 389                         /* Set offset into kernel image */
 390                         rel->r_offset -= base;
 391 #if (ELF_BITS == 32)
 392                         rel->r_info   = elf_xword_to_cpu(rel->r_info);
 393 #else
 394                         /* Convert MIPS64 RELA format - only the symbol
 395                          * index needs converting to native endianness
 396                          */
 397                         rel->r_info   = rel->r_info;
 398                         ELF_R_SYM(rel->r_info) = elf32_to_cpu(ELF_R_SYM(rel->r_info));
 399 #endif
 400 #if (SHT_REL_TYPE == SHT_RELA)
 401                         rel->r_addend = elf_xword_to_cpu(rel->r_addend);
 402 #endif
 403                 }
 404         }
 405 }
 406 
 407 static void remove_relocs(FILE *fp)
 408 {
 409         int i;
 410         Elf_Shdr shdr;
 411 
 412         for (i = 0; i < ehdr.e_shnum; i++) {
 413                 struct section *sec = &secs[i];
 414 
 415                 if (sec->shdr.sh_type != SHT_REL_TYPE)
 416                         continue;
 417 
 418                 if (fseek(fp, sec->shdr_offset, SEEK_SET) < 0)
 419                         die("Seek to %d failed: %s\n",
 420                             sec->shdr_offset, strerror(errno));
 421 
 422                 if (fread(&shdr, sizeof(shdr), 1, fp) != 1)
 423                         die("Cannot read ELF section headers %d/%d: %s\n",
 424                             i, ehdr.e_shnum, strerror(errno));
 425 
 426                 /* Set relocation section size to 0, effectively removing it.
 427                  * This is necessary due to lack of support for relocations
 428                  * in objcopy when creating 32bit elf from 64bit elf.
 429                  */
 430                 shdr.sh_size = 0;
 431 
 432                 if (fseek(fp, sec->shdr_offset, SEEK_SET) < 0)
 433                         die("Seek to %d failed: %s\n",
 434                             sec->shdr_offset, strerror(errno));
 435 
 436                 if (fwrite(&shdr, sizeof(shdr), 1, fp) != 1)
 437                         die("Cannot write ELF section headers %d/%d: %s\n",
 438                             i, ehdr.e_shnum, strerror(errno));
 439         }
 440 }
 441 
 442 static void add_reloc(struct relocs *r, uint32_t offset, unsigned type)
 443 {
 444         /* Relocation representation in binary table:
 445          * |76543210|76543210|76543210|76543210|
 446          * |  Type  |  offset from _text >> 2  |
 447          */
 448         offset >>= 2;
 449         if (offset > 0x00FFFFFF)
 450                 die("Kernel image exceeds maximum size for relocation!\n");
 451 
 452         offset = (offset & 0x00FFFFFF) | ((type & 0xFF) << 24);
 453 
 454         if (r->count == r->size) {
 455                 unsigned long newsize = r->size + 50000;
 456                 void *mem = realloc(r->offset, newsize * sizeof(r->offset[0]));
 457 
 458                 if (!mem)
 459                         die("realloc failed\n");
 460 
 461                 r->offset = mem;
 462                 r->size = newsize;
 463         }
 464         r->offset[r->count++] = offset;
 465 }
 466 
 467 static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel,
 468                         Elf_Sym *sym, const char *symname))
 469 {
 470         int i;
 471 
 472         /* Walk through the relocations */
 473         for (i = 0; i < ehdr.e_shnum; i++) {
 474                 char *sym_strtab;
 475                 Elf_Sym *sh_symtab;
 476                 struct section *sec_applies, *sec_symtab;
 477                 int j;
 478                 struct section *sec = &secs[i];
 479 
 480                 if (sec->shdr.sh_type != SHT_REL_TYPE)
 481                         continue;
 482 
 483                 sec_symtab  = sec->link;
 484                 sec_applies = &secs[sec->shdr.sh_info];
 485                 if (!(sec_applies->shdr.sh_flags & SHF_ALLOC))
 486                         continue;
 487 
 488                 sh_symtab = sec_symtab->symtab;
 489                 sym_strtab = sec_symtab->link->strtab;
 490                 for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
 491                         Elf_Rel *rel = &sec->reltab[j];
 492                         Elf_Sym *sym = &sh_symtab[ELF_R_SYM(rel->r_info)];
 493                         const char *symname = sym_name(sym_strtab, sym);
 494 
 495                         process(sec, rel, sym, symname);
 496                 }
 497         }
 498 }
 499 
 500 static int do_reloc(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
 501                       const char *symname)
 502 {
 503         unsigned r_type = ELF_R_TYPE(rel->r_info);
 504         unsigned bind = ELF_ST_BIND(sym->st_info);
 505 
 506         if ((bind == STB_WEAK) && (sym->st_value == 0)) {
 507                 /* Don't relocate weak symbols without a target */
 508                 return 0;
 509         }
 510 
 511         if (regex_skip_reloc(symname))
 512                 return 0;
 513 
 514         switch (r_type) {
 515         case R_MIPS_NONE:
 516         case R_MIPS_REL32:
 517         case R_MIPS_PC16:
 518         case R_MIPS_PC21_S2:
 519         case R_MIPS_PC26_S2:
 520                 /*
 521                  * NONE can be ignored and PC relative relocations don't
 522                  * need to be adjusted.
 523                  */
 524         case R_MIPS_HIGHEST:
 525         case R_MIPS_HIGHER:
 526                 /* We support relocating within the same 4Gb segment only,
 527                  * thus leaving the top 32bits unchanged
 528                  */
 529         case R_MIPS_LO16:
 530                 /* We support relocating by 64k jumps only
 531                  * thus leaving the bottom 16bits unchanged
 532                  */
 533                 break;
 534 
 535         case R_MIPS_64:
 536         case R_MIPS_32:
 537         case R_MIPS_26:
 538         case R_MIPS_HI16:
 539                 add_reloc(&relocs, rel->r_offset, r_type);
 540                 break;
 541 
 542         default:
 543                 die("Unsupported relocation type: %s (%d)\n",
 544                     rel_type(r_type), r_type);
 545                 break;
 546         }
 547 
 548         return 0;
 549 }
 550 
 551 static int write_reloc_as_bin(uint32_t v, FILE *f)
 552 {
 553         unsigned char buf[4];
 554 
 555         v = cpu_to_elf32(v);
 556 
 557         memcpy(buf, &v, sizeof(uint32_t));
 558         return fwrite(buf, 1, 4, f);
 559 }
 560 
 561 static int write_reloc_as_text(uint32_t v, FILE *f)
 562 {
 563         int res;
 564 
 565         res = fprintf(f, "\t.long 0x%08"PRIx32"\n", v);
 566         if (res < 0)
 567                 return res;
 568         else
 569                 return sizeof(uint32_t);
 570 }
 571 
 572 static void emit_relocs(int as_text, int as_bin, FILE *outf)
 573 {
 574         int i;
 575         int (*write_reloc)(uint32_t, FILE *) = write_reloc_as_bin;
 576         int size = 0;
 577         int size_reserved;
 578         struct section *sec_reloc;
 579 
 580         sec_reloc = sec_lookup(".data.reloc");
 581         if (!sec_reloc)
 582                 die("Could not find relocation section\n");
 583 
 584         size_reserved = sec_reloc->shdr.sh_size;
 585 
 586         /* Collect up the relocations */
 587         walk_relocs(do_reloc);
 588 
 589         /* Print the relocations */
 590         if (as_text) {
 591                 /* Print the relocations in a form suitable that
 592                  * gas will like.
 593                  */
 594                 printf(".section \".data.reloc\",\"a\"\n");
 595                 printf(".balign 4\n");
 596                 /* Output text to stdout */
 597                 write_reloc = write_reloc_as_text;
 598                 outf = stdout;
 599         } else if (as_bin) {
 600                 /* Output raw binary to stdout */
 601                 outf = stdout;
 602         } else {
 603                 /* Seek to offset of the relocation section.
 604                 * Each relocation is then written into the
 605                 * vmlinux kernel image.
 606                 */
 607                 if (fseek(outf, sec_reloc->shdr.sh_offset, SEEK_SET) < 0) {
 608                         die("Seek to %d failed: %s\n",
 609                                 sec_reloc->shdr.sh_offset, strerror(errno));
 610                 }
 611         }
 612 
 613         for (i = 0; i < relocs.count; i++)
 614                 size += write_reloc(relocs.offset[i], outf);
 615 
 616         /* Print a stop, but only if we've actually written some relocs */
 617         if (size)
 618                 size += write_reloc(0, outf);
 619 
 620         if (size > size_reserved)
 621                 /* Die, but suggest a value for CONFIG_RELOCATION_TABLE_SIZE
 622                  * which will fix this problem and allow a bit of headroom
 623                  * if more kernel features are enabled
 624                  */
 625                 die("Relocations overflow available space!\n" \
 626                     "Please adjust CONFIG_RELOCATION_TABLE_SIZE " \
 627                     "to at least 0x%08x\n", (size + 0x1000) & ~0xFFF);
 628 }
 629 
 630 /*
 631  * As an aid to debugging problems with different linkers
 632  * print summary information about the relocs.
 633  * Since different linkers tend to emit the sections in
 634  * different orders we use the section names in the output.
 635  */
 636 static int do_reloc_info(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
 637                                 const char *symname)
 638 {
 639         printf("%16s  0x%08x  %16s  %40s  %16s\n",
 640                 sec_name(sec->shdr.sh_info),
 641                 (unsigned int)rel->r_offset,
 642                 rel_type(ELF_R_TYPE(rel->r_info)),
 643                 symname,
 644                 sec_name(sym->st_shndx));
 645         return 0;
 646 }
 647 
 648 static void print_reloc_info(void)
 649 {
 650         printf("%16s  %10s  %16s  %40s  %16s\n",
 651                 "reloc section",
 652                 "offset",
 653                 "reloc type",
 654                 "symbol",
 655                 "symbol section");
 656         walk_relocs(do_reloc_info);
 657 }
 658 
 659 #if ELF_BITS == 64
 660 # define process process_64
 661 #else
 662 # define process process_32
 663 #endif
 664 
 665 void process(FILE *fp, int as_text, int as_bin,
 666              int show_reloc_info, int keep_relocs)
 667 {
 668         regex_init();
 669         read_ehdr(fp);
 670         read_shdrs(fp);
 671         read_strtabs(fp);
 672         read_symtabs(fp);
 673         read_relocs(fp);
 674         if (show_reloc_info) {
 675                 print_reloc_info();
 676                 return;
 677         }
 678         emit_relocs(as_text, as_bin, fp);
 679         if (!keep_relocs)
 680                 remove_relocs(fp);
 681 }

/* [<][>][^][v][top][bottom][index][help] */