hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/scripts/recordmcount.h
....@@ -1,3 +1,4 @@
1
+/* SPDX-License-Identifier: GPL-2.0-only */
12 /*
23 * recordmcount.h
34 *
....@@ -15,8 +16,6 @@
1516 *
1617 * This conversion to macros was done by:
1718 * Copyright 2010 Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
18
- *
19
- * Licensed under the GNU General Public License, version 2 (GPLv2).
2019 */
2120 #undef append_func
2221 #undef is_fake_mcount
....@@ -193,15 +192,20 @@
193192 Elf32_Word const *symtab_shndx)
194193 {
195194 unsigned long offset;
195
+ unsigned short shndx = w2(sym->st_shndx);
196196 int index;
197197
198
- if (sym->st_shndx != SHN_XINDEX)
199
- return w2(sym->st_shndx);
198
+ if (shndx > SHN_UNDEF && shndx < SHN_LORESERVE)
199
+ return shndx;
200200
201
- offset = (unsigned long)sym - (unsigned long)symtab;
202
- index = offset / sizeof(*sym);
201
+ if (shndx == SHN_XINDEX) {
202
+ offset = (unsigned long)sym - (unsigned long)symtab;
203
+ index = offset / sizeof(*sym);
203204
204
- return w(symtab_shndx[index]);
205
+ return w(symtab_shndx[index]);
206
+ }
207
+
208
+ return 0;
205209 }
206210
207211 static unsigned int get_shnum(Elf_Ehdr const *ehdr, Elf_Shdr const *shdr0)
....@@ -251,7 +255,7 @@
251255 }
252256
253257 /* Append the new shstrtab, Elf_Shdr[], __mcount_loc and its relocations. */
254
-static void append_func(Elf_Ehdr *const ehdr,
258
+static int append_func(Elf_Ehdr *const ehdr,
255259 Elf_Shdr *const shstr,
256260 uint_t const *const mloc0,
257261 uint_t const *const mlocp,
....@@ -283,15 +287,20 @@
283287 set_shnum(ehdr, shdr0, new_shnum);
284288
285289 /* body for new shstrtab */
286
- ulseek(fd_map, sb.st_size, SEEK_SET);
287
- uwrite(fd_map, old_shstr_sh_offset + (void *)ehdr, old_shstr_sh_size);
288
- uwrite(fd_map, mc_name, 1 + strlen(mc_name));
290
+ if (ulseek(sb.st_size, SEEK_SET) < 0)
291
+ return -1;
292
+ if (uwrite(old_shstr_sh_offset + (void *)ehdr, old_shstr_sh_size) < 0)
293
+ return -1;
294
+ if (uwrite(mc_name, 1 + strlen(mc_name)) < 0)
295
+ return -1;
289296
290297 /* old(modified) Elf_Shdr table, word-byte aligned */
291
- ulseek(fd_map, t, SEEK_SET);
298
+ if (ulseek(t, SEEK_SET) < 0)
299
+ return -1;
292300 t += sizeof(Elf_Shdr) * old_shnum;
293
- uwrite(fd_map, old_shoff + (void *)ehdr,
294
- sizeof(Elf_Shdr) * old_shnum);
301
+ if (uwrite(old_shoff + (void *)ehdr,
302
+ sizeof(Elf_Shdr) * old_shnum) < 0)
303
+ return -1;
295304
296305 /* new sections __mcount_loc and .rel__mcount_loc */
297306 t += 2*sizeof(mcsec);
....@@ -306,7 +315,8 @@
306315 mcsec.sh_info = 0;
307316 mcsec.sh_addralign = _w(_size);
308317 mcsec.sh_entsize = _w(_size);
309
- uwrite(fd_map, &mcsec, sizeof(mcsec));
318
+ if (uwrite(&mcsec, sizeof(mcsec)) < 0)
319
+ return -1;
310320
311321 mcsec.sh_name = w(old_shstr_sh_size);
312322 mcsec.sh_type = (sizeof(Elf_Rela) == rel_entsize)
....@@ -320,14 +330,21 @@
320330 mcsec.sh_info = w(old_shnum);
321331 mcsec.sh_addralign = _w(_size);
322332 mcsec.sh_entsize = _w(rel_entsize);
323
- uwrite(fd_map, &mcsec, sizeof(mcsec));
324333
325
- uwrite(fd_map, mloc0, (void *)mlocp - (void *)mloc0);
326
- uwrite(fd_map, mrel0, (void *)mrelp - (void *)mrel0);
334
+ if (uwrite(&mcsec, sizeof(mcsec)) < 0)
335
+ return -1;
336
+
337
+ if (uwrite(mloc0, (void *)mlocp - (void *)mloc0) < 0)
338
+ return -1;
339
+ if (uwrite(mrel0, (void *)mrelp - (void *)mrel0) < 0)
340
+ return -1;
327341
328342 ehdr->e_shoff = _w(new_e_shoff);
329
- ulseek(fd_map, 0, SEEK_SET);
330
- uwrite(fd_map, ehdr, sizeof(*ehdr));
343
+ if (ulseek(0, SEEK_SET) < 0)
344
+ return -1;
345
+ if (uwrite(ehdr, sizeof(*ehdr)) < 0)
346
+ return -1;
347
+ return 0;
331348 }
332349
333350 static unsigned get_mcountsym(Elf_Sym const *const sym0,
....@@ -431,9 +448,9 @@
431448 * that are not going to be traced. The mcount calls here will be converted
432449 * into nops.
433450 */
434
-static void nop_mcount(Elf_Shdr const *const relhdr,
435
- Elf_Ehdr const *const ehdr,
436
- const char *const txtname)
451
+static int nop_mcount(Elf_Shdr const *const relhdr,
452
+ Elf_Ehdr const *const ehdr,
453
+ const char *const txtname)
437454 {
438455 Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
439456 + (void *)ehdr);
....@@ -464,7 +481,7 @@
464481 once = 1;
465482 /* just warn? */
466483 if (!make_nop)
467
- return;
484
+ return 0;
468485 }
469486 }
470487
....@@ -476,13 +493,15 @@
476493 Elf_Rel rel;
477494 rel = *(Elf_Rel *)relp;
478495 Elf_r_info(&rel, Elf_r_sym(relp), rel_type_nop);
479
- ulseek(fd_map, (void *)relp - (void *)ehdr, SEEK_SET);
480
- uwrite(fd_map, &rel, sizeof(rel));
496
+ if (ulseek((void *)relp - (void *)ehdr, SEEK_SET) < 0)
497
+ return -1;
498
+ if (uwrite(&rel, sizeof(rel)) < 0)
499
+ return -1;
481500 }
482501 relp = (Elf_Rel const *)(rel_entsize + (void *)relp);
483502 }
503
+ return 0;
484504 }
485
-
486505
487506 /*
488507 * Find a symbol in the given section, to be used as the base for relocating
....@@ -494,9 +513,10 @@
494513 * Num: Value Size Type Bind Vis Ndx Name
495514 * 2: 00000000 0 SECTION LOCAL DEFAULT 1
496515 */
497
-static unsigned find_secsym_ndx(unsigned const txtndx,
516
+static int find_secsym_ndx(unsigned const txtndx,
498517 char const *const txtname,
499518 uint_t *const recvalp,
519
+ unsigned int *sym_index,
500520 Elf_Shdr const *const symhdr,
501521 Elf32_Word const *symtab,
502522 Elf32_Word const *symtab_shndx,
....@@ -520,21 +540,20 @@
520540 continue;
521541
522542 *recvalp = _w(symp->st_value);
523
- return symp - sym0;
543
+ *sym_index = symp - sym0;
544
+ return 0;
524545 }
525546 }
526547 fprintf(stderr, "Cannot find symbol for section %u: %s.\n",
527548 txtndx, txtname);
528
- fail_file();
549
+ return -1;
529550 }
530551
531
-
532552 /* Evade ISO C restriction: no declaration after statement in has_rel_mcount. */
533
-static char const *
534
-__has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */
535
- Elf_Shdr const *const shdr0,
536
- char const *const shstrtab,
537
- char const *const fname)
553
+static char const * __has_rel_mcount(Elf_Shdr const *const relhdr, /* reltype */
554
+ Elf_Shdr const *const shdr0,
555
+ char const *const shstrtab,
556
+ char const *const fname)
538557 {
539558 /* .sh_info depends on .sh_type == SHT_REL[,A] */
540559 Elf_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)];
....@@ -543,7 +562,7 @@
543562 if (strcmp("__mcount_loc", txtname) == 0) {
544563 fprintf(stderr, "warning: __mcount_loc already exists: %s\n",
545564 fname);
546
- succeed_file();
565
+ return already_has_rel_mcount;
547566 }
548567 if (w(txthdr->sh_type) != SHT_PROGBITS ||
549568 !(_w(txthdr->sh_flags) & SHF_EXECINSTR))
....@@ -573,6 +592,10 @@
573592
574593 for (; nhdr; --nhdr, ++shdrp) {
575594 txtname = has_rel_mcount(shdrp, shdr0, shstrtab, fname);
595
+ if (txtname == already_has_rel_mcount) {
596
+ totrelsz = 0;
597
+ break;
598
+ }
576599 if (txtname && is_mcounted_section_name(txtname))
577600 totrelsz += _w(shdrp->sh_size);
578601 }
....@@ -580,8 +603,8 @@
580603 }
581604
582605 /* Overall supervision for Elf32 ET_REL file. */
583
-static void
584
-do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype)
606
+static int do_func(Elf_Ehdr *const ehdr, char const *const fname,
607
+ unsigned const reltype)
585608 {
586609 Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
587610 + (void *)ehdr);
....@@ -597,29 +620,57 @@
597620 Elf32_Word *symtab_shndx;
598621
599622 /* Upper bound on space: assume all relevant relocs are for mcount. */
600
- unsigned const totrelsz = tot_relsize(shdr0, nhdr, shstrtab, fname);
601
- Elf_Rel *const mrel0 = umalloc(totrelsz);
602
- Elf_Rel * mrelp = mrel0;
623
+ unsigned totrelsz;
603624
604
- /* 2*sizeof(address) <= sizeof(Elf_Rel) */
605
- uint_t *const mloc0 = umalloc(totrelsz>>1);
606
- uint_t * mlocp = mloc0;
625
+ Elf_Rel * mrel0;
626
+ Elf_Rel * mrelp;
627
+
628
+ uint_t * mloc0;
629
+ uint_t * mlocp;
607630
608631 unsigned rel_entsize = 0;
609632 unsigned symsec_sh_link = 0;
633
+
634
+ int result = 0;
635
+
636
+ totrelsz = tot_relsize(shdr0, nhdr, shstrtab, fname);
637
+ if (totrelsz == 0)
638
+ return 0;
639
+ mrel0 = umalloc(totrelsz);
640
+ mrelp = mrel0;
641
+ if (!mrel0)
642
+ return -1;
643
+
644
+ /* 2*sizeof(address) <= sizeof(Elf_Rel) */
645
+ mloc0 = umalloc(totrelsz>>1);
646
+ mlocp = mloc0;
647
+ if (!mloc0) {
648
+ free(mrel0);
649
+ return -1;
650
+ }
610651
611652 find_symtab(ehdr, shdr0, nhdr, &symtab, &symtab_shndx);
612653
613654 for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) {
614655 char const *const txtname = has_rel_mcount(relhdr, shdr0,
615656 shstrtab, fname);
657
+ if (txtname == already_has_rel_mcount) {
658
+ result = 0;
659
+ file_updated = 0;
660
+ goto out; /* Nothing to be done; don't append! */
661
+ }
616662 if (txtname && is_mcounted_section_name(txtname)) {
663
+ unsigned int recsym;
617664 uint_t recval = 0;
618
- unsigned const recsym = find_secsym_ndx(
619
- w(relhdr->sh_info), txtname, &recval,
620
- &shdr0[symsec_sh_link = w(relhdr->sh_link)],
621
- symtab, symtab_shndx,
622
- ehdr);
665
+
666
+ symsec_sh_link = w(relhdr->sh_link);
667
+ result = find_secsym_ndx(w(relhdr->sh_info), txtname,
668
+ &recval, &recsym,
669
+ &shdr0[symsec_sh_link],
670
+ symtab, symtab_shndx,
671
+ ehdr);
672
+ if (result)
673
+ goto out;
623674
624675 rel_entsize = _w(relhdr->sh_entsize);
625676 mlocp = sift_rel_mcount(mlocp,
....@@ -630,13 +681,17 @@
630681 * This section is ignored by ftrace, but still
631682 * has mcount calls. Convert them to nops now.
632683 */
633
- nop_mcount(relhdr, ehdr, txtname);
684
+ if (nop_mcount(relhdr, ehdr, txtname) < 0) {
685
+ result = -1;
686
+ goto out;
687
+ }
634688 }
635689 }
636
- if (mloc0 != mlocp) {
637
- append_func(ehdr, shstr, mloc0, mlocp, mrel0, mrelp,
638
- rel_entsize, symsec_sh_link);
639
- }
690
+ if (!result && mloc0 != mlocp)
691
+ result = append_func(ehdr, shstr, mloc0, mlocp, mrel0, mrelp,
692
+ rel_entsize, symsec_sh_link);
693
+out:
640694 free(mrel0);
641695 free(mloc0);
696
+ return result;
642697 }