cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

fixdep.c (3805B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * "Optimize" a list of dependencies as spit out by gcc -MD
      4 * for the build framework.
      5 *
      6 * Original author:
      7 *   Copyright    2002 by Kai Germaschewski  <kai.germaschewski@gmx.de>
      8 *
      9 * This code has been borrowed from kbuild's fixdep (scripts/basic/fixdep.c),
     10 * Please check it for detailed explanation. This fixdep borow only the
     11 * base transformation of dependecies without the CONFIG mangle.
     12 */
     13
     14#include <sys/types.h>
     15#include <sys/stat.h>
     16#include <sys/mman.h>
     17#include <unistd.h>
     18#include <fcntl.h>
     19#include <string.h>
     20#include <stdlib.h>
     21#include <stdio.h>
     22#include <limits.h>
     23
     24char *target;
     25char *depfile;
     26char *cmdline;
     27
     28static void usage(void)
     29{
     30	fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n");
     31	exit(1);
     32}
     33
     34/*
     35 * Print out the commandline prefixed with cmd_<target filename> :=
     36 */
     37static void print_cmdline(void)
     38{
     39	printf("cmd_%s := %s\n\n", target, cmdline);
     40}
     41
     42/*
     43 * Important: The below generated source_foo.o and deps_foo.o variable
     44 * assignments are parsed not only by make, but also by the rather simple
     45 * parser in scripts/mod/sumversion.c.
     46 */
     47static void parse_dep_file(void *map, size_t len)
     48{
     49	char *m = map;
     50	char *end = m + len;
     51	char *p;
     52	char s[PATH_MAX];
     53	int is_target, has_target = 0;
     54	int saw_any_target = 0;
     55	int is_first_dep = 0;
     56
     57	while (m < end) {
     58		/* Skip any "white space" */
     59		while (m < end && (*m == ' ' || *m == '\\' || *m == '\n'))
     60			m++;
     61		/* Find next "white space" */
     62		p = m;
     63		while (p < end && *p != ' ' && *p != '\\' && *p != '\n')
     64			p++;
     65		/* Is the token we found a target name? */
     66		is_target = (*(p-1) == ':');
     67		/* Don't write any target names into the dependency file */
     68		if (is_target) {
     69			/* The /next/ file is the first dependency */
     70			is_first_dep = 1;
     71			has_target = 1;
     72		} else if (has_target) {
     73			/* Save this token/filename */
     74			memcpy(s, m, p-m);
     75			s[p - m] = 0;
     76
     77			/*
     78			 * Do not list the source file as dependency,
     79			 * so that kbuild is not confused if a .c file
     80			 * is rewritten into .S or vice versa. Storing
     81			 * it in source_* is needed for modpost to
     82			 * compute srcversions.
     83			 */
     84			if (is_first_dep) {
     85				/*
     86				 * If processing the concatenation of
     87				 * multiple dependency files, only
     88				 * process the first target name, which
     89				 * will be the original source name,
     90				 * and ignore any other target names,
     91				 * which will be intermediate temporary
     92				 * files.
     93				 */
     94				if (!saw_any_target) {
     95					saw_any_target = 1;
     96					printf("source_%s := %s\n\n",
     97						target, s);
     98					printf("deps_%s := \\\n",
     99						target);
    100				}
    101				is_first_dep = 0;
    102			} else
    103				printf("  %s \\\n", s);
    104		}
    105		/*
    106		 * Start searching for next token immediately after the first
    107		 * "whitespace" character that follows this token.
    108		 */
    109		m = p + 1;
    110	}
    111
    112	if (!saw_any_target) {
    113		fprintf(stderr, "fixdep: parse error; no targets found\n");
    114		exit(1);
    115	}
    116
    117	printf("\n%s: $(deps_%s)\n\n", target, target);
    118	printf("$(deps_%s):\n", target);
    119}
    120
    121static void print_deps(void)
    122{
    123	struct stat st;
    124	int fd;
    125	void *map;
    126
    127	fd = open(depfile, O_RDONLY);
    128	if (fd < 0) {
    129		fprintf(stderr, "fixdep: error opening depfile: ");
    130		perror(depfile);
    131		exit(2);
    132	}
    133	if (fstat(fd, &st) < 0) {
    134		fprintf(stderr, "fixdep: error fstat'ing depfile: ");
    135		perror(depfile);
    136		exit(2);
    137	}
    138	if (st.st_size == 0) {
    139		fprintf(stderr, "fixdep: %s is empty\n", depfile);
    140		close(fd);
    141		return;
    142	}
    143	map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
    144	if ((long) map == -1) {
    145		perror("fixdep: mmap");
    146		close(fd);
    147		return;
    148	}
    149
    150	parse_dep_file(map, st.st_size);
    151
    152	munmap(map, st.st_size);
    153
    154	close(fd);
    155}
    156
    157int main(int argc, char **argv)
    158{
    159	if (argc != 4)
    160		usage();
    161
    162	depfile = argv[1];
    163	target  = argv[2];
    164	cmdline = argv[3];
    165
    166	print_cmdline();
    167	print_deps();
    168
    169	return 0;
    170}