Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/mips/boot/tools/relocs.c
26481 views
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;
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
struct section *extab_sec = sec_lookup("__ex_table");
472
int extab_index = extab_sec ? extab_sec - secs : -1;
473
474
/* Walk through the relocations */
475
for (i = 0; i < ehdr.e_shnum; i++) {
476
char *sym_strtab;
477
Elf_Sym *sh_symtab;
478
struct section *sec_applies, *sec_symtab;
479
int j;
480
struct section *sec = &secs[i];
481
482
if (sec->shdr.sh_type != SHT_REL_TYPE)
483
continue;
484
485
if (sec->shdr.sh_info == extab_index)
486
continue;
487
488
sec_symtab = sec->link;
489
sec_applies = &secs[sec->shdr.sh_info];
490
if (!(sec_applies->shdr.sh_flags & SHF_ALLOC))
491
continue;
492
493
sh_symtab = sec_symtab->symtab;
494
sym_strtab = sec_symtab->link->strtab;
495
for (j = 0; j < sec->shdr.sh_size/sizeof(Elf_Rel); j++) {
496
Elf_Rel *rel = &sec->reltab[j];
497
Elf_Sym *sym = &sh_symtab[ELF_R_SYM(rel->r_info)];
498
const char *symname = sym_name(sym_strtab, sym);
499
500
process(sec, rel, sym, symname);
501
}
502
}
503
}
504
505
static int do_reloc(struct section *sec, Elf_Rel *rel, Elf_Sym *sym,
506
const char *symname)
507
{
508
unsigned r_type = ELF_R_TYPE(rel->r_info);
509
unsigned bind = ELF_ST_BIND(sym->st_info);
510
511
if ((bind == STB_WEAK) && (sym->st_value == 0)) {
512
/* Don't relocate weak symbols without a target */
513
return 0;
514
}
515
516
if (regex_skip_reloc(symname))
517
return 0;
518
519
switch (r_type) {
520
case R_MIPS_NONE:
521
case R_MIPS_REL32:
522
case R_MIPS_PC16:
523
case R_MIPS_PC21_S2:
524
case R_MIPS_PC26_S2:
525
/*
526
* NONE can be ignored and PC relative relocations don't
527
* need to be adjusted.
528
*/
529
case R_MIPS_HIGHEST:
530
case R_MIPS_HIGHER:
531
/* We support relocating within the same 4Gb segment only,
532
* thus leaving the top 32bits unchanged
533
*/
534
case R_MIPS_LO16:
535
/* We support relocating by 64k jumps only
536
* thus leaving the bottom 16bits unchanged
537
*/
538
break;
539
540
case R_MIPS_64:
541
case R_MIPS_32:
542
case R_MIPS_26:
543
case R_MIPS_HI16:
544
add_reloc(&relocs, rel->r_offset, r_type);
545
break;
546
547
default:
548
die("Unsupported relocation type: %s (%d)\n",
549
rel_type(r_type), r_type);
550
break;
551
}
552
553
return 0;
554
}
555
556
static int write_reloc_as_bin(uint32_t v, FILE *f)
557
{
558
unsigned char buf[4];
559
560
v = cpu_to_elf32(v);
561
562
memcpy(buf, &v, sizeof(uint32_t));
563
return fwrite(buf, 1, 4, f);
564
}
565
566
static int write_reloc_as_text(uint32_t v, FILE *f)
567
{
568
int res;
569
570
res = fprintf(f, "\t.long 0x%08"PRIx32"\n", v);
571
if (res < 0)
572
return res;
573
else
574
return sizeof(uint32_t);
575
}
576
577
static void emit_relocs(int as_text, int as_bin, FILE *outf)
578
{
579
int i;
580
int (*write_reloc)(uint32_t, FILE *) = write_reloc_as_bin;
581
int size = 0;
582
int size_reserved;
583
struct section *sec_reloc;
584
585
sec_reloc = sec_lookup(".data.reloc");
586
if (!sec_reloc)
587
die("Could not find relocation section\n");
588
589
size_reserved = sec_reloc->shdr.sh_size;
590
591
/* Collect up the relocations */
592
walk_relocs(do_reloc);
593
594
/* Print the relocations */
595
if (as_text) {
596
/* Print the relocations in a form suitable that
597
* gas will like.
598
*/
599
printf(".section \".data.reloc\",\"a\"\n");
600
printf(".balign 4\n");
601
/* Output text to stdout */
602
write_reloc = write_reloc_as_text;
603
outf = stdout;
604
} else if (as_bin) {
605
/* Output raw binary to stdout */
606
outf = stdout;
607
} else {
608
/* Seek to offset of the relocation section.
609
* Each relocation is then written into the
610
* vmlinux kernel image.
611
*/
612
if (fseek(outf, sec_reloc->shdr.sh_offset, SEEK_SET) < 0) {
613
die("Seek to %d failed: %s\n",
614
sec_reloc->shdr.sh_offset, strerror(errno));
615
}
616
}
617
618
for (i = 0; i < relocs.count; i++)
619
size += write_reloc(relocs.offset[i], outf);
620
621
/* Print a stop, but only if we've actually written some relocs */
622
if (size)
623
size += write_reloc(0, outf);
624
625
if (size > size_reserved)
626
/* Die, but suggest a value for CONFIG_RELOCATION_TABLE_SIZE
627
* which will fix this problem and allow a bit of headroom
628
* if more kernel features are enabled
629
*/
630
die("Relocations overflow available space!\n" \
631
"Please adjust CONFIG_RELOCATION_TABLE_SIZE " \
632
"to at least 0x%08x\n", (size + 0x1000) & ~0xFFF);
633
}
634
635
/*
636
* As an aid to debugging problems with different linkers
637
* print summary information about the relocs.
638
* Since different linkers tend to emit the sections in
639
* different orders we use the section names in the output.
640
*/
641
static int do_reloc_info(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
642
const char *symname)
643
{
644
printf("%16s 0x%08x %16s %40s %16s\n",
645
sec_name(sec->shdr.sh_info),
646
(unsigned int)rel->r_offset,
647
rel_type(ELF_R_TYPE(rel->r_info)),
648
symname,
649
sec_name(sym->st_shndx));
650
return 0;
651
}
652
653
static void print_reloc_info(void)
654
{
655
printf("%16s %10s %16s %40s %16s\n",
656
"reloc section",
657
"offset",
658
"reloc type",
659
"symbol",
660
"symbol section");
661
walk_relocs(do_reloc_info);
662
}
663
664
#if ELF_BITS == 64
665
# define process process_64
666
#else
667
# define process process_32
668
#endif
669
670
void process(FILE *fp, int as_text, int as_bin,
671
int show_reloc_info, int keep_relocs)
672
{
673
regex_init();
674
read_ehdr(fp);
675
read_shdrs(fp);
676
read_strtabs(fp);
677
read_symtabs(fp);
678
read_relocs(fp);
679
if (show_reloc_info) {
680
print_reloc_info();
681
return;
682
}
683
emit_relocs(as_text, as_bin, fp);
684
if (!keep_relocs)
685
remove_relocs(fp);
686
}
687
688