mirror of https://github.com/crash-utility/crash
1948 lines
52 KiB
C
1948 lines
52 KiB
C
/* configure.c - core analysis suite
|
|
*
|
|
* Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc.
|
|
* Copyright (C) 2002-2013 David Anderson
|
|
* Copyright (C) 2002-2013 Red Hat, Inc. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
/*
|
|
* define, clear and undef dynamically update the top-level Makefile:
|
|
*
|
|
* -b define: TARGET, GDB, GDB_FILES, GDB_OFILES, GDB_PATCH_FILES,
|
|
* TARGET_CFLAGS, LDFLAGS, GDB_CONF_FLAGS and GPL_FILES
|
|
* create: build_data.c
|
|
*
|
|
* -d define: TARGET, GDB, GDB_FILES, GDB_OFILES, GDB_PATCH_FILES,
|
|
* TARGET_CFLAGS, LDFLAGS, GDB_CONF_FLAGS and PROGRAM (for daemon)
|
|
* create: build_data.c
|
|
*
|
|
* -u clear: TARGET, GDB, GDB_FILES, GDB_OFILES, VERSION, GDB_PATCH_FILES,
|
|
* TARGET_CFLAGS, LDFLAGS, GDB_CONF_FLAGS and GPL_FILES
|
|
* undef: WARNING_ERROR, WARNING_OPTIONS
|
|
*
|
|
* -r define: GDB_FILES, VERSION, GDB_PATCH_FILES GPL_FILES
|
|
*
|
|
* -w define: WARNING_OPTIONS
|
|
* undef: WARNING_ERROR
|
|
*
|
|
* -W define: WARNING_ERROR, WARNING_OPTIONS
|
|
*
|
|
* -n undef: WARNING_ERROR, WARNING_OPTIONS
|
|
*
|
|
* -g define: GDB
|
|
*
|
|
* -p Create or remove .rh_rpm_package file
|
|
*
|
|
* -q Don't print configuration
|
|
*
|
|
* -s Create crash.spec file
|
|
*
|
|
* -x Add extra libraries/flags to build
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#include <ctype.h>
|
|
|
|
struct supported_gdb_version;
|
|
void build_configure(struct supported_gdb_version *);
|
|
void release_configure(char *, struct supported_gdb_version *);
|
|
void make_rh_rpm_package(char *, int);
|
|
void unconfigure(void);
|
|
void set_warnings(int);
|
|
void show_configuration(void);
|
|
void target_rebuild_instructions(struct supported_gdb_version *, char *);
|
|
void arch_mismatch(struct supported_gdb_version *);
|
|
void get_current_configuration(struct supported_gdb_version *);
|
|
void makefile_setup(FILE **, FILE **);
|
|
void makefile_create(FILE **, FILE **);
|
|
char *strip_linefeeds(char *);
|
|
char *upper_case(char *, char *);
|
|
char *lower_case(char *, char *);
|
|
char *shift_string_left(char *, int);
|
|
char *shift_string_right(char *, int);
|
|
char *strip_beginning_whitespace(char *);
|
|
char *strip_ending_whitespace(char *);
|
|
char *strip_linefeeds(char *);
|
|
int file_exists(char *);
|
|
int count_chars(char *, char);
|
|
void make_build_data(char *);
|
|
void gdb_configure(struct supported_gdb_version *);
|
|
int parse_line(char *, char **);
|
|
struct supported_gdb_version *setup_gdb_defaults(void);
|
|
struct supported_gdb_version *store_gdb_defaults(struct supported_gdb_version *);
|
|
void make_spec_file(struct supported_gdb_version *);
|
|
void set_initial_target(struct supported_gdb_version *);
|
|
char *target_to_name(int);
|
|
int name_to_target(char *);
|
|
char *get_extra_flags(char *, char *);
|
|
void add_extra_lib(char *);
|
|
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
|
|
#undef X86
|
|
#undef ALPHA
|
|
#undef PPC
|
|
#undef IA64
|
|
#undef S390
|
|
#undef S390X
|
|
#undef PPC64
|
|
#undef X86_64
|
|
#undef ARM
|
|
#undef ARM64
|
|
#undef MIPS
|
|
#undef SPARC64
|
|
#undef MIPS64
|
|
#undef RISCV64
|
|
#undef LOONGARCH64
|
|
|
|
#define UNKNOWN 0
|
|
#define X86 1
|
|
#define ALPHA 2
|
|
#define PPC 3
|
|
#define IA64 4
|
|
#define S390 5
|
|
#define S390X 6
|
|
#define PPC64 7
|
|
#define X86_64 8
|
|
#define ARM 9
|
|
#define ARM64 10
|
|
#define MIPS 11
|
|
#define SPARC64 12
|
|
#define MIPS64 13
|
|
#define RISCV64 14
|
|
#define LOONGARCH64 15
|
|
|
|
#define TARGET_X86 "TARGET=X86"
|
|
#define TARGET_ALPHA "TARGET=ALPHA"
|
|
#define TARGET_PPC "TARGET=PPC"
|
|
#define TARGET_IA64 "TARGET=IA64"
|
|
#define TARGET_S390 "TARGET=S390"
|
|
#define TARGET_S390X "TARGET=S390X"
|
|
#define TARGET_PPC64 "TARGET=PPC64"
|
|
#define TARGET_X86_64 "TARGET=X86_64"
|
|
#define TARGET_ARM "TARGET=ARM"
|
|
#define TARGET_ARM64 "TARGET=ARM64"
|
|
#define TARGET_MIPS "TARGET=MIPS"
|
|
#define TARGET_MIPS64 "TARGET=MIPS64"
|
|
#define TARGET_SPARC64 "TARGET=SPARC64"
|
|
#define TARGET_RISCV64 "TARGET=RISCV64"
|
|
#define TARGET_LOONGARCH64 "TARGET=LOONGARCH64"
|
|
|
|
#define TARGET_CFLAGS_X86 "TARGET_CFLAGS=-D_FILE_OFFSET_BITS=64"
|
|
#define TARGET_CFLAGS_ALPHA "TARGET_CFLAGS="
|
|
#define TARGET_CFLAGS_PPC "TARGET_CFLAGS=-D_FILE_OFFSET_BITS=64"
|
|
#define TARGET_CFLAGS_IA64 "TARGET_CFLAGS="
|
|
#define TARGET_CFLAGS_S390 "TARGET_CFLAGS=-D_FILE_OFFSET_BITS=64"
|
|
#define TARGET_CFLAGS_S390X "TARGET_CFLAGS="
|
|
#define TARGET_CFLAGS_PPC64 "TARGET_CFLAGS=-m64"
|
|
#define TARGET_CFLAGS_X86_64 "TARGET_CFLAGS="
|
|
#define TARGET_CFLAGS_ARM "TARGET_CFLAGS=-D_FILE_OFFSET_BITS=64"
|
|
#define TARGET_CFLAGS_ARM_ON_X86 "TARGET_CFLAGS=-D_FILE_OFFSET_BITS=64"
|
|
#define TARGET_CFLAGS_ARM_ON_X86_64 "TARGET_CFLAGS=-m32 -D_FILE_OFFSET_BITS=64"
|
|
#define TARGET_CFLAGS_X86_ON_X86_64 "TARGET_CFLAGS=-m32 -D_FILE_OFFSET_BITS=64"
|
|
#define TARGET_CFLAGS_PPC_ON_PPC64 "TARGET_CFLAGS=-m32 -D_FILE_OFFSET_BITS=64 -fPIC"
|
|
#define TARGET_CFLAGS_ARM64 "TARGET_CFLAGS="
|
|
#define TARGET_CFLAGS_ARM64_ON_X86_64 "TARGET_CFLAGS="
|
|
#define TARGET_CFLAGS_PPC64_ON_X86_64 "TARGET_CFLAGS="
|
|
#define TARGET_CFLAGS_MIPS "TARGET_CFLAGS=-D_FILE_OFFSET_BITS=64"
|
|
#define TARGET_CFLAGS_MIPS_ON_X86 "TARGET_CFLAGS=-D_FILE_OFFSET_BITS=64"
|
|
#define TARGET_CFLAGS_MIPS_ON_X86_64 "TARGET_CFLAGS=-m32 -D_FILE_OFFSET_BITS=64"
|
|
#define TARGET_CFLAGS_MIPS64 "TARGET_CFLAGS="
|
|
#define TARGET_CFLAGS_SPARC64 "TARGET_CFLAGS="
|
|
#define TARGET_CFLAGS_RISCV64 "TARGET_CFLAGS="
|
|
#define TARGET_CFLAGS_RISCV64_ON_X86_64 "TARGET_CFLAGS="
|
|
#define TARGET_CFLAGS_LOONGARCH64 "TARGET_CFLAGS="
|
|
#define TARGET_CFLAGS_LOONGARCH64_ON_X86_64 "TARGET_CFLAGS="
|
|
|
|
#define GDB_TARGET_DEFAULT "GDB_CONF_FLAGS="
|
|
#define GDB_TARGET_ARM_ON_X86 "GDB_CONF_FLAGS=--target=arm-elf-linux"
|
|
#define GDB_TARGET_ARM_ON_X86_64 "GDB_CONF_FLAGS=--target=arm-elf-linux CFLAGS=-m32 CXXFLAGS=-m32"
|
|
#define GDB_TARGET_X86_ON_X86_64 "GDB_CONF_FLAGS=--target=i686-pc-linux-gnu CFLAGS=-m32 CXXFLAGS=-m32"
|
|
#define GDB_TARGET_PPC_ON_PPC64 "GDB_CONF_FLAGS=--target=ppc-elf-linux CFLAGS=-m32 CXXFLAGS=-m32"
|
|
#define GDB_TARGET_ARM64_ON_X86_64 "GDB_CONF_FLAGS=--target=aarch64-elf-linux" /* TBD */
|
|
#define GDB_TARGET_PPC64_ON_X86_64 "GDB_CONF_FLAGS=--target=powerpc64le-unknown-linux-gnu"
|
|
#define GDB_TARGET_MIPS_ON_X86 "GDB_CONF_FLAGS=--target=mipsel-elf-linux"
|
|
#define GDB_TARGET_MIPS_ON_X86_64 "GDB_CONF_FLAGS=--target=mipsel-elf-linux CFLAGS=-m32 CXXFLAGS=-m32"
|
|
#define GDB_TARGET_RISCV64_ON_X86_64 "GDB_CONF_FLAGS=--target=riscv64-unknown-linux-gnu"
|
|
#define GDB_TARGET_LOONGARCH64_ON_X86_64 "GDB_CONF_FLAGS=--target=loongarch64-unknown-linux-gnu"
|
|
|
|
/*
|
|
* The original plan was to allow the use of a particular version
|
|
* of gdb for a given architecture. But for practical purposes,
|
|
* it's a one-size-fits-all scheme, and they all use the default
|
|
* unless overridden.
|
|
*/
|
|
|
|
#define GDB_5_3 (0)
|
|
#define GDB_6_0 (1)
|
|
#define GDB_6_1 (2)
|
|
#define GDB_7_0 (3)
|
|
#define GDB_7_3_1 (4)
|
|
#define GDB_7_6 (5)
|
|
#define GDB_10_2 (6)
|
|
#define SUPPORTED_GDB_VERSIONS (GDB_10_2 + 1)
|
|
|
|
int default_gdb = GDB_10_2;
|
|
|
|
struct supported_gdb_version {
|
|
char *GDB;
|
|
char *GDB_VERSION_IN;
|
|
char *GDB_FILES;
|
|
char *GDB_OFILES;
|
|
char *GDB_PATCH_FILES;
|
|
char *GDB_FLAGS;
|
|
char *GPL;
|
|
} supported_gdb_versions[SUPPORTED_GDB_VERSIONS] = {
|
|
{
|
|
"GDB=gdb-5.3post-0.20021129.36rh",
|
|
"Red Hat Linux (5.3post-0.20021129.36rh)",
|
|
"GDB_FILES=${GDB_5.3post-0.20021129.36rh_FILES}",
|
|
"GDB_OFILES=${GDB_5.3post-0.20021129.36rh_OFILES}",
|
|
"GDB_PATCH_FILES=",
|
|
"GDB_FLAGS=-DGDB_5_3",
|
|
"GPLv2"
|
|
},
|
|
{
|
|
"GDB=gdb-6.0",
|
|
"6.0",
|
|
"GDB_FILES=${GDB_6.0_FILES}",
|
|
"GDB_OFILES=${GDB_6.0_OFILES}",
|
|
"GDB_PATCH_FILES=",
|
|
"GDB_FLAGS=-DGDB_6_0",
|
|
"GPLv2"
|
|
},
|
|
{
|
|
"GDB=gdb-6.1",
|
|
"6.1",
|
|
"GDB_FILES=${GDB_6.1_FILES}",
|
|
"GDB_OFILES=${GDB_6.1_OFILES}",
|
|
"GDB_PATCH_FILES=gdb-6.1.patch",
|
|
"GDB_FLAGS=-DGDB_6_1",
|
|
"GPLv2"
|
|
},
|
|
{
|
|
"GDB=gdb-7.0",
|
|
"7.0",
|
|
"GDB_FILES=${GDB_7.0_FILES}",
|
|
"GDB_OFILES=${GDB_7.0_OFILES}",
|
|
"GDB_PATCH_FILES=gdb-7.0.patch",
|
|
"GDB_FLAGS=-DGDB_7_0",
|
|
"GPLv3"
|
|
},
|
|
{
|
|
"GDB=gdb-7.3.1",
|
|
"7.3.1",
|
|
"GDB_FILES=${GDB_7.3.1_FILES}",
|
|
"GDB_OFILES=${GDB_7.3.1_OFILES}",
|
|
"GDB_PATCH_FILES=gdb-7.3.1.patch",
|
|
"GDB_FLAGS=-DGDB_7_3_1",
|
|
"GPLv3"
|
|
},
|
|
{
|
|
"GDB=gdb-7.6",
|
|
"7.6",
|
|
"GDB_FILES=${GDB_7.6_FILES}",
|
|
"GDB_OFILES=${GDB_7.6_OFILES}",
|
|
"GDB_PATCH_FILES=gdb-7.6.patch gdb-7.6-ppc64le-support.patch gdb-7.6-proc_service.h.patch",
|
|
"GDB_FLAGS=-DGDB_7_6",
|
|
"GPLv3"
|
|
},
|
|
{
|
|
"GDB=gdb-10.2",
|
|
"10.2",
|
|
"GDB_FILES=${GDB_10.2_FILES}",
|
|
"GDB_OFILES=${GDB_10.2_OFILES}",
|
|
"GDB_PATCH_FILES=gdb-10.2.patch",
|
|
"GDB_FLAGS=-DGDB_10_2",
|
|
"GPLv3"
|
|
},
|
|
};
|
|
|
|
#define DAEMON 0x1
|
|
#define QUIET 0x2
|
|
|
|
#define MAXSTRLEN 256
|
|
#define MIN(a,b) (((a)<(b))?(a):(b))
|
|
|
|
struct target_data {
|
|
int target;
|
|
int host;
|
|
int initial_gdb_target;
|
|
int flags;
|
|
char program[MAXSTRLEN];
|
|
char gdb_version[MAXSTRLEN];
|
|
char release[MAXSTRLEN];
|
|
struct stat statbuf;
|
|
const char *target_as_param;
|
|
} target_data = { 0 };
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
int c;
|
|
struct supported_gdb_version *sp;
|
|
|
|
sp = setup_gdb_defaults();
|
|
|
|
while ((c = getopt(argc, argv, "gsqnWwubdr:p:P:t:x:")) > 0) {
|
|
switch (c) {
|
|
case 'q':
|
|
target_data.flags |= QUIET;
|
|
break;
|
|
case 'u':
|
|
unconfigure();
|
|
break;
|
|
case 'd':
|
|
target_data.flags |= DAEMON;
|
|
case 'b':
|
|
build_configure(sp);
|
|
break;
|
|
case 'r':
|
|
release_configure(optarg, sp);
|
|
break;
|
|
case 'p':
|
|
make_rh_rpm_package(optarg, 0);
|
|
break;
|
|
case 'P':
|
|
make_rh_rpm_package(optarg, 1);
|
|
break;
|
|
case 'W':
|
|
case 'w':
|
|
case 'n':
|
|
set_warnings(c);
|
|
break;
|
|
case 's':
|
|
make_spec_file(sp);
|
|
break;
|
|
case 'g':
|
|
gdb_configure(sp);
|
|
break;
|
|
case 't':
|
|
target_data.target_as_param = optarg;
|
|
break;
|
|
case 'x':
|
|
add_extra_lib(optarg);
|
|
break;
|
|
}
|
|
}
|
|
|
|
exit(0);
|
|
}
|
|
|
|
void
|
|
target_rebuild_instructions(struct supported_gdb_version *sp, char *target)
|
|
{
|
|
fprintf(stderr,
|
|
"\nIn order to build a crash binary for the %s architecture:\n",
|
|
target);
|
|
|
|
fprintf(stderr, " 1. remove the %s subdirectory\n",
|
|
&sp->GDB[strlen("GDB=")]);
|
|
fprintf(stderr, " 2. perform a \"make clean\"\n");
|
|
fprintf(stderr, " 3. retry the build\n\n");
|
|
}
|
|
|
|
void
|
|
arch_mismatch(struct supported_gdb_version *sp)
|
|
{
|
|
fprintf(stderr,
|
|
"\nThe initial build in this source tree was for the %s architecture.\n",
|
|
target_to_name(target_data.initial_gdb_target));
|
|
|
|
target_rebuild_instructions(sp, target_to_name(target_data.target));
|
|
|
|
exit(1);
|
|
}
|
|
|
|
void
|
|
get_current_configuration(struct supported_gdb_version *sp)
|
|
{
|
|
FILE *fp;
|
|
static char buf[512];
|
|
char *p;
|
|
|
|
#ifdef __alpha__
|
|
target_data.target = ALPHA;
|
|
#endif
|
|
#ifdef __i386__
|
|
target_data.target = X86;
|
|
#endif
|
|
#ifdef __powerpc__
|
|
target_data.target = PPC;
|
|
#endif
|
|
#ifdef __ia64__
|
|
target_data.target = IA64;
|
|
#endif
|
|
#ifdef __s390__
|
|
target_data.target = S390;
|
|
#endif
|
|
#ifdef __s390x__
|
|
target_data.target = S390X;
|
|
#endif
|
|
#ifdef __powerpc64__
|
|
target_data.target = PPC64;
|
|
#endif
|
|
#ifdef __x86_64__
|
|
target_data.target = X86_64;
|
|
#endif
|
|
#ifdef __arm__
|
|
target_data.target = ARM;
|
|
#endif
|
|
#ifdef __aarch64__
|
|
target_data.target = ARM64;
|
|
#endif
|
|
#ifdef __mips__
|
|
#ifndef __mips64
|
|
target_data.target = MIPS;
|
|
#else
|
|
target_data.target = MIPS64;
|
|
#endif
|
|
#endif
|
|
#ifdef __sparc_v9__
|
|
target_data.target = SPARC64;
|
|
#endif
|
|
#if defined(__riscv) && (__riscv_xlen == 64)
|
|
target_data.target = RISCV64;
|
|
#endif
|
|
#ifdef __loongarch64
|
|
target_data.target = LOONGARCH64;
|
|
#endif
|
|
|
|
set_initial_target(sp);
|
|
|
|
/*
|
|
* Override target if specified on command line.
|
|
*/
|
|
target_data.host = target_data.target;
|
|
|
|
if (target_data.target_as_param) {
|
|
if ((target_data.target == X86 || target_data.target == X86_64) &&
|
|
(name_to_target((char *)target_data.target_as_param) == ARM)) {
|
|
/*
|
|
* Debugging of ARM core files supported on X86, and on
|
|
* X86_64 when built as a 32-bit executable.
|
|
*/
|
|
target_data.target = ARM;
|
|
} else if ((target_data.target == X86 || target_data.target == X86_64) &&
|
|
(name_to_target((char *)target_data.target_as_param) == MIPS)) {
|
|
/*
|
|
* Debugging of MIPS little-endian core files
|
|
* supported on X86, and on X86_64 when built as a
|
|
* 32-bit executable.
|
|
*/
|
|
target_data.target = MIPS;
|
|
} else if ((target_data.target == X86_64) &&
|
|
(name_to_target((char *)target_data.target_as_param) == X86)) {
|
|
/*
|
|
* Build an X86 crash binary on an X86_64 host.
|
|
*/
|
|
target_data.target = X86;
|
|
} else if ((target_data.target == X86_64) &&
|
|
(name_to_target((char *)target_data.target_as_param) == ARM64)) {
|
|
/*
|
|
* Build an ARM64 crash binary on an X86_64 host.
|
|
*/
|
|
target_data.target = ARM64;
|
|
} else if ((target_data.target == X86_64) &&
|
|
(name_to_target((char *)target_data.target_as_param) == PPC64)) {
|
|
/*
|
|
* Build a PPC64 little-endian crash binary on an X86_64 host.
|
|
*/
|
|
target_data.target = PPC64;
|
|
} else if ((target_data.target == PPC64) &&
|
|
(name_to_target((char *)target_data.target_as_param) == PPC)) {
|
|
/*
|
|
* Build an PPC crash binary on an PPC64 host.
|
|
*/
|
|
target_data.target = PPC;
|
|
} else if (name_to_target((char *)target_data.target_as_param) ==
|
|
target_data.host) {
|
|
if ((target_data.initial_gdb_target != UNKNOWN) &&
|
|
(target_data.host != target_data.initial_gdb_target))
|
|
arch_mismatch(sp);
|
|
} else if ((target_data.target == X86_64) &&
|
|
(name_to_target((char *)target_data.target_as_param) == RISCV64)) {
|
|
/*
|
|
* Build an RISCV64 crash binary on an X86_64 host.
|
|
*/
|
|
target_data.target = RISCV64;
|
|
} else if ((target_data.target == X86_64) &&
|
|
(name_to_target((char *)target_data.target_as_param) == LOONGARCH64)) {
|
|
/*
|
|
* Build an LOONGARCH64 crash binary on an X86_64 host.
|
|
*/
|
|
target_data.target = LOONGARCH64;
|
|
} else {
|
|
fprintf(stderr,
|
|
"\ntarget=%s is not supported on the %s host architecture\n\n",
|
|
target_data.target_as_param,
|
|
target_to_name(target_data.host));
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Impose implied (sticky) target if an initial build has been
|
|
* done in the source tree.
|
|
*/
|
|
if (target_data.initial_gdb_target &&
|
|
(target_data.target != target_data.initial_gdb_target)) {
|
|
if ((target_data.initial_gdb_target == ARM) &&
|
|
(target_data.target != ARM)) {
|
|
if ((target_data.target == X86) ||
|
|
(target_data.target == X86_64))
|
|
target_data.target = ARM;
|
|
else
|
|
arch_mismatch(sp);
|
|
}
|
|
if ((target_data.target == ARM) &&
|
|
(target_data.initial_gdb_target != ARM))
|
|
arch_mismatch(sp);
|
|
|
|
if ((target_data.initial_gdb_target == MIPS) &&
|
|
(target_data.target != MIPS)) {
|
|
if ((target_data.target == X86) ||
|
|
(target_data.target == X86_64))
|
|
target_data.target = MIPS;
|
|
else
|
|
arch_mismatch(sp);
|
|
}
|
|
|
|
if ((target_data.initial_gdb_target == MIPS64) &&
|
|
(target_data.target != MIPS64))
|
|
arch_mismatch(sp);
|
|
|
|
if ((target_data.initial_gdb_target == LOONGARCH64) &&
|
|
(target_data.target != LOONGARCH64)) {
|
|
if (target_data.target == X86_64)
|
|
target_data.target = LOONGARCH64;
|
|
else
|
|
arch_mismatch(sp);
|
|
}
|
|
|
|
if ((target_data.initial_gdb_target == RISCV64) &&
|
|
(target_data.target != RISCV64)) {
|
|
if (target_data.target == X86_64)
|
|
target_data.target = RISCV64;
|
|
else
|
|
arch_mismatch(sp);
|
|
}
|
|
|
|
if ((target_data.initial_gdb_target == X86) &&
|
|
(target_data.target != X86)) {
|
|
if (target_data.target == X86_64)
|
|
target_data.target = X86;
|
|
else
|
|
arch_mismatch(sp);
|
|
}
|
|
if ((target_data.target == X86) &&
|
|
(target_data.initial_gdb_target != X86))
|
|
arch_mismatch(sp);
|
|
|
|
if ((target_data.initial_gdb_target == ARM64) &&
|
|
(target_data.target != ARM64)) {
|
|
if (target_data.target == X86_64)
|
|
target_data.target = ARM64;
|
|
else
|
|
arch_mismatch(sp);
|
|
}
|
|
if ((target_data.target == ARM64) &&
|
|
(target_data.initial_gdb_target != ARM64))
|
|
arch_mismatch(sp);
|
|
|
|
if ((target_data.initial_gdb_target == PPC64) &&
|
|
(target_data.target != PPC64)) {
|
|
if (target_data.target == X86_64)
|
|
target_data.target = PPC64;
|
|
else
|
|
arch_mismatch(sp);
|
|
}
|
|
if ((target_data.target == PPC64) &&
|
|
(target_data.initial_gdb_target != PPC64))
|
|
arch_mismatch(sp);
|
|
|
|
if ((target_data.initial_gdb_target == PPC) &&
|
|
(target_data.target != PPC)) {
|
|
if (target_data.target == PPC64)
|
|
target_data.target = PPC;
|
|
else
|
|
arch_mismatch(sp);
|
|
}
|
|
if ((target_data.target == PPC) &&
|
|
(target_data.initial_gdb_target != PPC))
|
|
arch_mismatch(sp);
|
|
|
|
if ((target_data.target == SPARC64) &&
|
|
(target_data.initial_gdb_target != SPARC64))
|
|
arch_mismatch(sp);
|
|
}
|
|
|
|
if ((fp = fopen("Makefile", "r")) == NULL) {
|
|
perror("Makefile");
|
|
goto get_release;
|
|
}
|
|
|
|
while (fgets(buf, 512, fp)) {
|
|
if (strncmp(buf, "PROGRAM=", strlen("PROGRAM=")) == 0) {
|
|
p = strstr(buf, "=") + 1;
|
|
strip_linefeeds(p);
|
|
upper_case(p, target_data.program);
|
|
if (target_data.flags & DAEMON)
|
|
strcat(target_data.program, "D");
|
|
continue;
|
|
}
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
get_release:
|
|
|
|
target_data.release[0] = '\0';
|
|
|
|
if (file_exists(".rh_rpm_package")) {
|
|
if ((fp = fopen(".rh_rpm_package", "r")) == NULL) {
|
|
perror(".rh_rpm_package");
|
|
} else {
|
|
if (fgets(buf, 512, fp)) {
|
|
strip_linefeeds(buf);
|
|
if (strlen(buf)) {
|
|
buf[MAXSTRLEN-1] = '\0';
|
|
strcpy(target_data.release, buf);
|
|
} else
|
|
fprintf(stderr,
|
|
"WARNING: .rh_rpm_package file is empty!\n");
|
|
} else
|
|
fprintf(stderr,
|
|
"WARNING: .rh_rpm_package file is empty!\n");
|
|
fclose(fp);
|
|
|
|
if (strlen(target_data.release))
|
|
return;
|
|
}
|
|
} else
|
|
fprintf(stderr,
|
|
"WARNING: .rh_rpm_package file does not exist!\n");
|
|
|
|
if ((fp = fopen("defs.h", "r")) == NULL) {
|
|
perror("defs.h");
|
|
return;
|
|
}
|
|
|
|
while (fgets(buf, 512, fp)) {
|
|
if (strncmp(buf, "#define BASELEVEL_REVISION",
|
|
strlen("#define BASELEVEL_REVISION")) == 0) {
|
|
p = strstr(buf, "\"") + 1;
|
|
strip_linefeeds(p);
|
|
p[strlen(p)-1] = '\0';
|
|
strcpy(target_data.release, p);
|
|
break;
|
|
}
|
|
}
|
|
|
|
fclose(fp);
|
|
}
|
|
|
|
void
|
|
show_configuration(void)
|
|
{
|
|
int i;
|
|
|
|
if (target_data.flags & QUIET)
|
|
return;
|
|
|
|
switch (target_data.target)
|
|
{
|
|
case X86:
|
|
printf("TARGET: X86\n");
|
|
break;
|
|
case ALPHA:
|
|
printf("TARGET: ALPHA\n");
|
|
break;
|
|
case PPC:
|
|
printf("TARGET: PPC\n");
|
|
break;
|
|
case IA64:
|
|
printf("TARGET: IA64\n");
|
|
break;
|
|
case S390:
|
|
printf("TARGET: S390\n");
|
|
break;
|
|
case S390X:
|
|
printf("TARGET: S390X\n");
|
|
break;
|
|
case PPC64:
|
|
printf("TARGET: PPC64\n");
|
|
break;
|
|
case X86_64:
|
|
printf("TARGET: X86_64\n");
|
|
break;
|
|
case ARM:
|
|
printf("TARGET: ARM\n");
|
|
break;
|
|
case ARM64:
|
|
printf("TARGET: ARM64\n");
|
|
break;
|
|
case MIPS:
|
|
printf("TARGET: MIPS\n");
|
|
break;
|
|
case MIPS64:
|
|
printf("TARGET: MIPS64\n");
|
|
break;
|
|
case SPARC64:
|
|
printf("TARGET: SPARC64\n");
|
|
break;
|
|
case RISCV64:
|
|
printf("TARGET: RISCV64\n");
|
|
break;
|
|
case LOONGARCH64:
|
|
printf("TARGET: LOONGARCH64\n");
|
|
break;
|
|
}
|
|
|
|
if (strlen(target_data.program)) {
|
|
for (i = 0; i < (strlen("TARGET")-strlen(target_data.program));
|
|
i++)
|
|
printf(" ");
|
|
printf("%s: ", target_data.program);
|
|
if (strlen(target_data.release))
|
|
printf("%s\n", target_data.release);
|
|
else
|
|
printf("???\n");
|
|
}
|
|
|
|
if (strlen(target_data.gdb_version))
|
|
printf(" GDB: %s\n\n", &target_data.gdb_version[4]);
|
|
}
|
|
|
|
void
|
|
build_configure(struct supported_gdb_version *sp)
|
|
{
|
|
FILE *fp1, *fp2;
|
|
char buf[512];
|
|
char *target;
|
|
char *target_CFLAGS;
|
|
char *gdb_conf_flags;
|
|
char *ldflags;
|
|
char *cflags;
|
|
|
|
get_current_configuration(sp);
|
|
|
|
target = target_CFLAGS = NULL;
|
|
|
|
gdb_conf_flags = GDB_TARGET_DEFAULT;
|
|
switch (target_data.target)
|
|
{
|
|
case X86:
|
|
target = TARGET_X86;
|
|
if (target_data.host == X86_64) {
|
|
target_CFLAGS = TARGET_CFLAGS_X86_ON_X86_64;
|
|
gdb_conf_flags = GDB_TARGET_X86_ON_X86_64;
|
|
} else
|
|
target_CFLAGS = TARGET_CFLAGS_X86;
|
|
break;
|
|
case ALPHA:
|
|
target = TARGET_ALPHA;
|
|
target_CFLAGS = TARGET_CFLAGS_ALPHA;
|
|
break;
|
|
case PPC:
|
|
target = TARGET_PPC;
|
|
if (target_data.host == PPC64) {
|
|
target_CFLAGS = TARGET_CFLAGS_PPC_ON_PPC64;
|
|
gdb_conf_flags = GDB_TARGET_PPC_ON_PPC64;
|
|
} else
|
|
target_CFLAGS = TARGET_CFLAGS_PPC;
|
|
break;
|
|
case IA64:
|
|
target = TARGET_IA64;
|
|
target_CFLAGS = TARGET_CFLAGS_IA64;
|
|
break;
|
|
case S390:
|
|
target = TARGET_S390;
|
|
target_CFLAGS = TARGET_CFLAGS_S390;
|
|
break;
|
|
case S390X:
|
|
target = TARGET_S390X;
|
|
target_CFLAGS = TARGET_CFLAGS_S390X;
|
|
break;
|
|
case PPC64:
|
|
target = TARGET_PPC64;
|
|
if (target_data.host == X86_64) {
|
|
target_CFLAGS = TARGET_CFLAGS_PPC64_ON_X86_64;
|
|
gdb_conf_flags = GDB_TARGET_PPC64_ON_X86_64;
|
|
} else
|
|
target_CFLAGS = TARGET_CFLAGS_PPC64;
|
|
break;
|
|
case X86_64:
|
|
target = TARGET_X86_64;
|
|
target_CFLAGS = TARGET_CFLAGS_X86_64;
|
|
break;
|
|
case ARM:
|
|
target = TARGET_ARM;
|
|
if (target_data.host == X86) {
|
|
target_CFLAGS = TARGET_CFLAGS_ARM_ON_X86;
|
|
gdb_conf_flags = GDB_TARGET_ARM_ON_X86;
|
|
} else if (target_data.host == X86_64) {
|
|
target_CFLAGS = TARGET_CFLAGS_ARM_ON_X86_64;
|
|
gdb_conf_flags = GDB_TARGET_ARM_ON_X86_64;
|
|
} else
|
|
target_CFLAGS = TARGET_CFLAGS_ARM;
|
|
break;
|
|
case ARM64:
|
|
target = TARGET_ARM64;
|
|
if (target_data.host == X86_64) {
|
|
target_CFLAGS = TARGET_CFLAGS_ARM64_ON_X86_64;
|
|
gdb_conf_flags = GDB_TARGET_ARM64_ON_X86_64;
|
|
} else
|
|
target_CFLAGS = TARGET_CFLAGS_ARM64;
|
|
break;
|
|
case MIPS:
|
|
target = TARGET_MIPS;
|
|
if (target_data.host == X86) {
|
|
target_CFLAGS = TARGET_CFLAGS_MIPS_ON_X86;
|
|
gdb_conf_flags = GDB_TARGET_MIPS_ON_X86;
|
|
} else if (target_data.host == X86_64) {
|
|
target_CFLAGS = TARGET_CFLAGS_MIPS_ON_X86_64;
|
|
gdb_conf_flags = GDB_TARGET_MIPS_ON_X86_64;
|
|
} else
|
|
target_CFLAGS = TARGET_CFLAGS_MIPS;
|
|
break;
|
|
case MIPS64:
|
|
target = TARGET_MIPS64;
|
|
target_CFLAGS = TARGET_CFLAGS_MIPS64;
|
|
break;
|
|
case SPARC64:
|
|
target = TARGET_SPARC64;
|
|
target_CFLAGS = TARGET_CFLAGS_SPARC64;
|
|
break;
|
|
case RISCV64:
|
|
target = TARGET_RISCV64;
|
|
if (target_data.host == X86_64) {
|
|
target_CFLAGS = TARGET_CFLAGS_RISCV64_ON_X86_64;
|
|
gdb_conf_flags = GDB_TARGET_RISCV64_ON_X86_64;
|
|
} else
|
|
target_CFLAGS = TARGET_CFLAGS_RISCV64;
|
|
break;
|
|
case LOONGARCH64:
|
|
target = TARGET_LOONGARCH64;
|
|
if (target_data.host == X86_64) {
|
|
target_CFLAGS = TARGET_CFLAGS_LOONGARCH64_ON_X86_64;
|
|
gdb_conf_flags = GDB_TARGET_LOONGARCH64_ON_X86_64;
|
|
} else
|
|
target_CFLAGS = TARGET_CFLAGS_LOONGARCH64;
|
|
break;
|
|
}
|
|
|
|
ldflags = get_extra_flags("LDFLAGS.extra", NULL);
|
|
cflags = get_extra_flags("CFLAGS.extra", NULL);
|
|
gdb_conf_flags = get_extra_flags("GDBFLAGS.extra", gdb_conf_flags);
|
|
|
|
makefile_setup(&fp1, &fp2);
|
|
|
|
while (fgets(buf, 512, fp1)) {
|
|
if (strncmp(buf, "TARGET=", strlen("TARGET=")) == 0)
|
|
fprintf(fp2, "%s\n", target);
|
|
else if (strncmp(buf, "TARGET_CFLAGS=",
|
|
strlen("TARGET_CFLAGS=")) == 0)
|
|
fprintf(fp2, "%s%s%s\n", target_CFLAGS,
|
|
cflags ? " " : "", cflags ? cflags : "");
|
|
else if (strncmp(buf, "GDB_CONF_FLAGS=",
|
|
strlen("GDB_CONF_FLAGS=")) == 0)
|
|
fprintf(fp2, "%s\n", gdb_conf_flags);
|
|
else if (strncmp(buf, "GDB_FILES=",strlen("GDB_FILES=")) == 0)
|
|
fprintf(fp2, "%s\n", sp->GDB_FILES);
|
|
else if (strncmp(buf, "GDB_OFILES=",strlen("GDB_OFILES=")) == 0)
|
|
fprintf(fp2, "%s\n", sp->GDB_OFILES);
|
|
else if (strncmp(buf, "GDB_PATCH_FILES=",strlen("GDB_PATCH_FILES=")) == 0)
|
|
fprintf(fp2, "%s\n", sp->GDB_PATCH_FILES);
|
|
else if (strncmp(buf, "GDB_FLAGS=",strlen("GDB_FLAGS=")) == 0)
|
|
fprintf(fp2, "%s\n", sp->GDB_FLAGS);
|
|
else if (strncmp(buf, "GPL_FILES=", strlen("GPL_FILES=")) == 0)
|
|
fprintf(fp2, "GPL_FILES=%s\n", strcmp(sp->GPL, "GPLv2") == 0 ?
|
|
"COPYING" : "COPYING3");
|
|
else if (strncmp(buf, "GDB=", strlen("GDB=")) == 0) {
|
|
fprintf(fp2, "%s\n", sp->GDB);
|
|
sprintf(target_data.gdb_version, "%s", &sp->GDB[4]);
|
|
} else if (strncmp(buf, "LDFLAGS=", strlen("LDFLAGS=")) == 0) {
|
|
fprintf(fp2, "LDFLAGS=%s\n", ldflags ? ldflags : "");
|
|
} else
|
|
fprintf(fp2, "%s", buf);
|
|
|
|
}
|
|
|
|
makefile_create(&fp1, &fp2);
|
|
show_configuration();
|
|
make_build_data(&target[strlen("TARGET=")]);
|
|
}
|
|
|
|
void
|
|
release_configure(char *gdb_version, struct supported_gdb_version *sp)
|
|
{
|
|
FILE *fp1, *fp2;
|
|
int found;
|
|
char buf[512];
|
|
char gdb_files[MAXSTRLEN];
|
|
|
|
get_current_configuration(sp);
|
|
|
|
sprintf(buf, "%s/gdb", gdb_version);
|
|
if (!file_exists(buf)) {
|
|
fprintf(stderr, "make release: no such directory: %s\n", buf);
|
|
exit(1);
|
|
}
|
|
sprintf(gdb_files, "GDB_%s_FILES",
|
|
&gdb_version[strlen("gdb-")]);
|
|
|
|
makefile_setup(&fp1, &fp2);
|
|
|
|
found = 0;
|
|
while (fgets(buf, 512, fp1)) {
|
|
if (strncmp(buf, gdb_files, strlen(gdb_files)) == 0)
|
|
found++;
|
|
if (strncmp(buf, "GDB_FILES=", strlen("GDB_FILES=")) == 0)
|
|
fprintf(fp2, "GDB_FILES=${%s}\n", gdb_files);
|
|
else if (strncmp(buf, "VERSION=", strlen("VERSION=")) == 0)
|
|
fprintf(fp2, "VERSION=%s\n",
|
|
target_data.release);
|
|
else if (strncmp(buf, "GDB_PATCH_FILES=", strlen("GDB_PATCH_FILES=")) == 0)
|
|
fprintf(fp2, "%s\n", sp->GDB_PATCH_FILES);
|
|
else if (strncmp(buf, "GPL_FILES=", strlen("GPL_FILES=")) == 0)
|
|
fprintf(fp2, "GPL_FILES=%s\n", strcmp(sp->GPL, "GPLv2") == 0 ?
|
|
"COPYING" : "COPYING3");
|
|
else
|
|
fprintf(fp2, "%s", buf);
|
|
|
|
}
|
|
|
|
if (!found) {
|
|
fprintf(stderr, "make release: cannot find %s\n", gdb_files);
|
|
exit(1);
|
|
}
|
|
|
|
makefile_create(&fp1, &fp2);
|
|
}
|
|
|
|
/*
|
|
* Create an .rh_rpm_package file if the passed-in variable is set.
|
|
*/
|
|
void
|
|
make_rh_rpm_package(char *package, int release)
|
|
{
|
|
char *p, *cur;
|
|
FILE *fp;
|
|
char buf[256];
|
|
|
|
if ((strcmp(package, "remove") == 0)) {
|
|
if (file_exists(".rh_rpm_package")) {
|
|
if (unlink(".rh_rpm_package")) {
|
|
perror("unlink");
|
|
fprintf(stderr,
|
|
"cannot remove .rh_rpm_package\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (!(p = strstr(package, "=")))
|
|
return;
|
|
|
|
if (!strlen(++p))
|
|
return;
|
|
|
|
if (release) {
|
|
if (!(fp = popen("./crash -v", "r"))) {
|
|
fprintf(stderr, "cannot execute \"crash -v\"\n");
|
|
exit(1);
|
|
}
|
|
cur = NULL;
|
|
while (fgets(buf, 256, fp)) {
|
|
if (strncmp(buf, "crash ", 6) == 0) {
|
|
cur = &buf[6];
|
|
break;
|
|
}
|
|
}
|
|
pclose(fp);
|
|
|
|
if (!cur) {
|
|
fprintf(stderr, "cannot get version from \"crash -v\"\n");
|
|
exit(1);
|
|
}
|
|
strip_linefeeds(cur);
|
|
|
|
if (strcmp(cur, p) != 0) {
|
|
fprintf(stderr, "./crash version: %s\n", cur);
|
|
fprintf(stderr, "release version: %s\n", p);
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
if ((fp = fopen(".rh_rpm_package", "w")) == NULL) {
|
|
perror("fopen");
|
|
fprintf(stderr, "cannot open .rh_rpm_package\n");
|
|
exit(1);
|
|
}
|
|
|
|
fprintf(fp, "%s\n", strip_linefeeds(p));
|
|
|
|
fclose(fp);
|
|
}
|
|
|
|
void
|
|
gdb_configure(struct supported_gdb_version *sp)
|
|
{
|
|
FILE *fp1, *fp2;
|
|
char buf[512];
|
|
|
|
get_current_configuration(sp);
|
|
|
|
makefile_setup(&fp1, &fp2);
|
|
|
|
while (fgets(buf, 512, fp1)) {
|
|
if (strncmp(buf, "GDB=", strlen("GDB=")) == 0)
|
|
fprintf(fp2, "%s\n", sp->GDB);
|
|
else
|
|
fprintf(fp2, "%s", buf);
|
|
|
|
}
|
|
|
|
makefile_create(&fp1, &fp2);
|
|
}
|
|
|
|
void
|
|
unconfigure(void)
|
|
{
|
|
FILE *fp1, *fp2;
|
|
char buf[512];
|
|
|
|
makefile_setup(&fp1, &fp2);
|
|
|
|
while (fgets(buf, 512, fp1)) {
|
|
if (strncmp(buf, "TARGET=", strlen("TARGET=")) == 0)
|
|
fprintf(fp2, "TARGET=\n");
|
|
else if (strncmp(buf, "TARGET_CFLAGS=",
|
|
strlen("TARGET_CFLAGS=")) == 0)
|
|
fprintf(fp2, "TARGET_CFLAGS=\n");
|
|
else if (strncmp(buf, "GDB_CONF_FLAGS=",
|
|
strlen("GDB_CONF_FLAGS=")) == 0)
|
|
fprintf(fp2, "GDB_CONF_FLAGS=\n");
|
|
else if (strncmp(buf, "GDB_FILES=",strlen("GDB_FILES=")) == 0)
|
|
fprintf(fp2, "GDB_FILES=\n");
|
|
else if (strncmp(buf, "GDB_OFILES=",strlen("GDB_OFILES=")) == 0)
|
|
fprintf(fp2, "GDB_OFILES=\n");
|
|
else if (strncmp(buf, "GDB_PATCH_FILES=",strlen("GDB_PATCH_FILES=")) == 0)
|
|
fprintf(fp2, "GDB_PATCH_FILES=\n");
|
|
else if (strncmp(buf, "GDB_FLAGS=",strlen("GDB_FLAGS=")) == 0)
|
|
fprintf(fp2, "GDB_FLAGS=\n");
|
|
else if (strncmp(buf, "GDB=", strlen("GDB=")) == 0)
|
|
fprintf(fp2, "GDB=\n");
|
|
else if (strncmp(buf, "VERSION=", strlen("VERSION=")) == 0)
|
|
fprintf(fp2, "VERSION=\n");
|
|
else if (strncmp(buf, "GPL_FILES=", strlen("GPL_FILES=")) == 0)
|
|
fprintf(fp2, "GPL_FILES=\n");
|
|
else if (strncmp(buf, "LDFLAGS=", strlen("LDFLAGS=")) == 0)
|
|
fprintf(fp2, "LDFLAGS=\n");
|
|
else if (strncmp(buf, "WARNING_ERROR=",
|
|
strlen("WARNING_ERROR=")) == 0) {
|
|
shift_string_right(buf, 1);
|
|
buf[0] = '#';
|
|
fprintf(fp2, "%s", buf);
|
|
} else if (strncmp(buf, "WARNING_OPTIONS=",
|
|
strlen("WARNING_OPTIONS=")) == 0) {
|
|
shift_string_right(buf, 1);
|
|
buf[0] = '#';
|
|
fprintf(fp2, "%s", buf);
|
|
} else
|
|
fprintf(fp2, "%s", buf);
|
|
}
|
|
|
|
makefile_create(&fp1, &fp2);
|
|
}
|
|
|
|
void
|
|
set_warnings(int w)
|
|
{
|
|
FILE *fp1, *fp2;
|
|
char buf[512];
|
|
|
|
makefile_setup(&fp1, &fp2);
|
|
|
|
while (fgets(buf, 512, fp1)) {
|
|
if (strncmp(buf, "#WARNING_ERROR=",
|
|
strlen("#WARNING_ERROR=")) == 0) {
|
|
switch (w)
|
|
{
|
|
case 'W':
|
|
shift_string_left(buf, 1);
|
|
break;
|
|
case 'w':
|
|
case 'n':
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (strncmp(buf, "WARNING_ERROR=",
|
|
strlen("WARNING_ERROR=")) == 0) {
|
|
switch (w)
|
|
{
|
|
case 'n':
|
|
case 'w':
|
|
shift_string_right(buf, 1);
|
|
buf[0] = '#';
|
|
break;
|
|
case 'W':
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (strncmp(buf, "#WARNING_OPTIONS=",
|
|
strlen("#WARNING_OPTIONS=")) == 0) {
|
|
switch (w)
|
|
{
|
|
case 'W':
|
|
case 'w':
|
|
shift_string_left(buf, 1);
|
|
break;
|
|
case 'n':
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (strncmp(buf, "WARNING_OPTIONS=",
|
|
strlen("WARNING_OPTIONS=")) == 0) {
|
|
switch (w)
|
|
{
|
|
case 'w':
|
|
case 'W':
|
|
break;
|
|
case 'n':
|
|
shift_string_right(buf, 1);
|
|
buf[0] = '#';
|
|
break;
|
|
}
|
|
}
|
|
|
|
fprintf(fp2, "%s", buf);
|
|
}
|
|
|
|
makefile_create(&fp1, &fp2);
|
|
}
|
|
|
|
void
|
|
makefile_setup(FILE **fp1, FILE **fp2)
|
|
{
|
|
if (stat("Makefile", &target_data.statbuf) == -1) {
|
|
perror("Makefile");
|
|
exit(1);
|
|
}
|
|
|
|
if ((*fp1 = fopen("Makefile", "r")) == NULL) {
|
|
perror("fopen");
|
|
fprintf(stderr, "cannot open existing Makefile\n");
|
|
exit(1);
|
|
}
|
|
|
|
unlink("Makefile.new");
|
|
if ((*fp2 = fopen("Makefile.new", "w+")) == NULL) {
|
|
perror("fopen");
|
|
fprintf(stderr, "cannot create new Makefile\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
void
|
|
makefile_create(FILE **fp1, FILE **fp2)
|
|
{
|
|
fclose(*fp1);
|
|
fclose(*fp2);
|
|
|
|
if (system("mv Makefile.new Makefile") != 0) {
|
|
fprintf(stderr, "Makefile: cannot create new Makefile\n");
|
|
fprintf(stderr, "please copy Makefile.new to Makefile\n");
|
|
exit(1);
|
|
}
|
|
|
|
if (chown("Makefile", target_data.statbuf.st_uid,
|
|
target_data.statbuf.st_gid) == -1) {
|
|
fprintf(stderr,
|
|
"Makefile: cannot restore original owner/group\n");
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#define LASTCHAR(s) (s[strlen(s)-1])
|
|
|
|
char *
|
|
strip_linefeeds(char *line)
|
|
{
|
|
char *p;
|
|
|
|
if (line == NULL || strlen(line) == 0)
|
|
return(line);
|
|
|
|
p = &LASTCHAR(line);
|
|
|
|
while (*p == '\n')
|
|
*p = '\0';
|
|
|
|
return(line);
|
|
}
|
|
|
|
/*
|
|
* Turn a string into upper-case.
|
|
*/
|
|
char *
|
|
upper_case(char *s, char *buf)
|
|
{
|
|
char *p1, *p2;
|
|
|
|
p1 = s;
|
|
p2 = buf;
|
|
|
|
while (*p1) {
|
|
*p2 = toupper(*p1);
|
|
p1++, p2++;
|
|
}
|
|
|
|
*p2 = '\0';
|
|
|
|
return(buf);
|
|
}
|
|
|
|
/*
|
|
* Turn a string into lower-case.
|
|
*/
|
|
char *
|
|
lower_case(char *s, char *buf)
|
|
{
|
|
char *p1, *p2;
|
|
|
|
p1 = s;
|
|
p2 = buf;
|
|
|
|
while (*p1) {
|
|
*p2 = tolower(*p1);
|
|
p1++, p2++;
|
|
}
|
|
|
|
*p2 = '\0';
|
|
|
|
return(buf);
|
|
}
|
|
|
|
char *
|
|
shift_string_left(char *s, int cnt)
|
|
{
|
|
int origlen;
|
|
|
|
if (!cnt)
|
|
return(s);
|
|
|
|
origlen = strlen(s);
|
|
memmove(s, s+cnt, (origlen-cnt));
|
|
*(s+(origlen-cnt)) = '\0';
|
|
return(s);
|
|
}
|
|
|
|
char *
|
|
shift_string_right(char *s, int cnt)
|
|
{
|
|
int i;
|
|
int origlen;
|
|
|
|
if (!cnt)
|
|
return(s);
|
|
|
|
origlen = strlen(s);
|
|
memmove(s+cnt, s, origlen);
|
|
*(s+(origlen+cnt)) = '\0';
|
|
|
|
for (i = 0; i < cnt; i++)
|
|
s[i] = ' ';
|
|
|
|
return(s);
|
|
}
|
|
|
|
char *
|
|
strip_beginning_whitespace(char *line)
|
|
{
|
|
char buf[MAXSTRLEN];
|
|
char *p;
|
|
|
|
if (line == NULL || strlen(line) == 0)
|
|
return(line);
|
|
|
|
strcpy(buf, line);
|
|
p = &buf[0];
|
|
while (*p == ' ' || *p == '\t')
|
|
p++;
|
|
strcpy(line, p);
|
|
|
|
return(line);
|
|
}
|
|
|
|
char *
|
|
strip_ending_whitespace(char *line)
|
|
{
|
|
char *p;
|
|
|
|
if (line == NULL || strlen(line) == 0)
|
|
return(line);
|
|
|
|
p = &line[strlen(line)-1];
|
|
|
|
while (*p == ' ' || *p == '\t') {
|
|
*p = '\0';
|
|
if (p == line)
|
|
break;
|
|
p--;
|
|
}
|
|
|
|
return(line);
|
|
}
|
|
|
|
int
|
|
file_exists(char *file)
|
|
{
|
|
struct stat sbuf;
|
|
|
|
if (stat(file, &sbuf) == 0)
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
int
|
|
count_chars(char *s, char c)
|
|
{
|
|
char *p;
|
|
int count;
|
|
|
|
if (!s)
|
|
return 0;
|
|
|
|
count = 0;
|
|
|
|
for (p = s; *p; p++) {
|
|
if (*p == c)
|
|
count++;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
void
|
|
make_build_data(char *target)
|
|
{
|
|
char *p;
|
|
char hostname[MAXSTRLEN];
|
|
char progname[MAXSTRLEN];
|
|
char inbuf1[MAXSTRLEN];
|
|
char inbuf2[MAXSTRLEN];
|
|
char inbuf3[MAXSTRLEN];
|
|
FILE *fp1, *fp2, *fp3, *fp4;
|
|
|
|
unlink("build_data.c");
|
|
|
|
fp1 = popen("date", "r");
|
|
fp2 = popen("id", "r");
|
|
fp3 = popen("gcc --version", "r");
|
|
|
|
if ((fp4 = fopen("build_data.c", "w")) == NULL) {
|
|
perror("build_data.c");
|
|
exit(1);
|
|
}
|
|
|
|
if (gethostname(hostname, MAXSTRLEN) != 0)
|
|
hostname[0] = '\0';
|
|
|
|
p = fgets(inbuf1, 79, fp1);
|
|
|
|
p = fgets(inbuf2, 79, fp2);
|
|
p = strstr(inbuf2, " ");
|
|
*p = '\0';
|
|
|
|
p = fgets(inbuf3, 79, fp3);
|
|
|
|
lower_case(target_data.program, progname);
|
|
|
|
fprintf(fp4, "char *build_command = \"%s\";\n", progname);
|
|
if (getenv("SOURCE_DATE_EPOCH"))
|
|
fprintf(fp4, "char *build_data = \"reproducible build\";\n");
|
|
else if (strlen(hostname))
|
|
fprintf(fp4, "char *build_data = \"%s by %s on %s\";\n",
|
|
strip_linefeeds(inbuf1), inbuf2, hostname);
|
|
else
|
|
fprintf(fp4, "char *build_data = \"%s by %s\";\n",
|
|
strip_linefeeds(inbuf1), inbuf2);
|
|
|
|
bzero(inbuf1, MAXSTRLEN);
|
|
sprintf(inbuf1, "%s", target_data.release);
|
|
|
|
fprintf(fp4, "char *build_target = \"%s\";\n", target);
|
|
|
|
fprintf(fp4, "char *build_version = \"%s\";\n", inbuf1);
|
|
|
|
fprintf(fp4, "char *compiler_version = \"%s\";\n",
|
|
strip_linefeeds(inbuf3));
|
|
|
|
pclose(fp1);
|
|
pclose(fp2);
|
|
pclose(fp3);
|
|
fclose(fp4);
|
|
}
|
|
|
|
void
|
|
make_spec_file(struct supported_gdb_version *sp)
|
|
{
|
|
char *Version, *Release;
|
|
char buf[512];
|
|
|
|
get_current_configuration(sp);
|
|
|
|
Release = strstr(target_data.release, "-");
|
|
if (!Release) {
|
|
Version = target_data.release;
|
|
Release = "0";
|
|
} else {
|
|
fprintf(stderr,
|
|
"crash.spec: obsolete src.rpm build manner -- no dashes allowed: %s\n",
|
|
target_data.release);
|
|
return;
|
|
}
|
|
|
|
printf("#\n");
|
|
printf("# crash core analysis suite\n");
|
|
printf("#\n");
|
|
printf("Summary: crash utility for live systems; netdump, diskdump, kdump, LKCD or mcore dumpfiles\n");
|
|
printf("Name: %s\n", lower_case(target_data.program, buf));
|
|
printf("Version: %s\n", Version);
|
|
printf("Release: %s\n", Release);
|
|
printf("License: %s\n", sp->GPL);
|
|
printf("Group: Development/Debuggers\n");
|
|
printf("Source: %%{name}-%%{version}.tar.gz\n");
|
|
printf("URL: https://github.com/crash-utility\n");
|
|
printf("Distribution: Linux 2.2 or greater\n");
|
|
printf("Vendor: Red Hat, Inc.\n");
|
|
printf("Packager: Dave Anderson <anderson@redhat.com>\n");
|
|
printf("ExclusiveOS: Linux\n");
|
|
printf("ExclusiveArch: %%{ix86} alpha ia64 ppc ppc64 ppc64pseries ppc64iseries x86_64 s390 s390x arm aarch64 ppc64le mips mipsel mips64el sparc64 riscv64 loongarch64\n");
|
|
printf("Buildroot: %%{_tmppath}/%%{name}-root\n");
|
|
printf("BuildRequires: ncurses-devel zlib-devel bison\n");
|
|
printf("Requires: binutils\n");
|
|
printf("# Patch0: crash-3.3-20.installfix.patch (patch example)\n");
|
|
printf("\n");
|
|
printf("%%description\n");
|
|
printf("The core analysis suite is a self-contained tool that can be used to\n");
|
|
printf("investigate either live systems, kernel core dumps created from the\n");
|
|
printf("netdump, diskdump and kdump facilities from Red Hat Linux, the mcore kernel patch\n");
|
|
printf("offered by Mission Critical Linux, or the LKCD kernel patch.\n");
|
|
printf("\n");
|
|
printf("%%package devel\n");
|
|
printf("Requires: %%{name} = %%{version}, zlib-devel\n");
|
|
printf("Summary: crash utility for live systems; netdump, diskdump, kdump, LKCD or mcore dumpfiles\n");
|
|
printf("Group: Development/Debuggers\n");
|
|
printf("\n");
|
|
printf("%%description devel\n");
|
|
printf("The core analysis suite is a self-contained tool that can be used to\n");
|
|
printf("investigate either live systems, kernel core dumps created from the\n");
|
|
printf("netdump, diskdump and kdump packages from Red Hat Linux, the mcore kernel patch\n");
|
|
printf("offered by Mission Critical Linux, or the LKCD kernel patch.\n");
|
|
printf("\n");
|
|
printf("%%package extensions\n");
|
|
printf("Summary: Additional commands for the crash dump analysis tool\n");
|
|
printf("Group: Development/Debuggers\n");
|
|
printf("\n");
|
|
printf("%%description extensions\n");
|
|
printf("The extensions package contains plugins that provide additional crash\n");
|
|
printf("commands. The extensions can be loaded in crash via the \"extend\" command.\n");
|
|
printf("\n");
|
|
printf("The following extensions are provided:\n");
|
|
printf("* eppic: Provides C-like language for writing dump analysis scripts\n");
|
|
printf("* dminfo: Device-mapper target analyzer\n");
|
|
printf("* snap: Takes a snapshot of live memory and creates a kdump dumpfile\n");
|
|
printf("* trace: Displays kernel tracing data and traced events that occurred prior to a panic.\n");
|
|
printf("\n");
|
|
printf("%%prep\n");
|
|
printf("%%setup -n %%{name}-%%{version}\n");
|
|
printf("# %%patch0 -p1 -b .install (patch example)\n");
|
|
printf("\n");
|
|
printf("%%build\n");
|
|
printf("make RPMPKG=\"%%{version}\"\n");
|
|
printf("# make RPMPKG=\"%%{version}-%%{release}\"\n");
|
|
printf("make extensions\n");
|
|
/* printf("make crashd\n"); */
|
|
printf("\n");
|
|
printf("%%install\n");
|
|
printf("rm -rf %%{buildroot}\n");
|
|
printf("mkdir -p %%{buildroot}/usr/bin\n");
|
|
printf("make DESTDIR=%%{buildroot} install\n");
|
|
printf("mkdir -p %%{buildroot}%%{_mandir}/man8\n");
|
|
printf("cp crash.8 %%{buildroot}%%{_mandir}/man8/crash.8\n");
|
|
printf("mkdir -p %%{buildroot}%%{_includedir}/crash\n");
|
|
printf("cp defs.h %%{buildroot}%%{_includedir}/crash\n");
|
|
printf("mkdir -p %%{buildroot}%%{_libdir}/crash/extensions\n");
|
|
printf("if [ -f extensions/eppic.so ]\n");
|
|
printf("then\n");
|
|
printf("cp extensions/eppic.so %%{buildroot}%%{_libdir}/crash/extensions\n");
|
|
printf("fi\n");
|
|
printf("cp extensions/dminfo.so %%{buildroot}%%{_libdir}/crash/extensions\n");
|
|
printf("cp extensions/snap.so %%{buildroot}%%{_libdir}/crash/extensions\n");
|
|
printf("cp extensions/trace.so %%{buildroot}%%{_libdir}/crash/extensions\n");
|
|
printf("\n");
|
|
printf("%%clean\n");
|
|
printf("rm -rf %%{buildroot}\n");
|
|
printf("\n");
|
|
printf("%%files\n");
|
|
printf("%%defattr(-,root,root)\n");
|
|
printf("/usr/bin/crash\n");
|
|
printf("%%{_mandir}/man8/crash.8*\n");
|
|
/* printf("/usr/bin/crashd\n"); */
|
|
printf("%%doc README\n");
|
|
printf("\n");
|
|
printf("%%files devel\n");
|
|
printf("%%defattr(-,root,root)\n");
|
|
printf("%%{_includedir}/*\n");
|
|
printf("\n");
|
|
printf("%%files extensions\n");
|
|
printf("%%defattr(-,root,root)\n");
|
|
printf("%%{_libdir}/crash/extensions/*\n");
|
|
}
|
|
|
|
/*
|
|
* Use the default gdb #defines unless there's a .gdb file.
|
|
*/
|
|
struct supported_gdb_version *
|
|
setup_gdb_defaults(void)
|
|
{
|
|
FILE *fp;
|
|
char inbuf[512];
|
|
char buf[512];
|
|
struct supported_gdb_version *sp;
|
|
|
|
/*
|
|
* Use the default, allowing for an override in .gdb
|
|
*/
|
|
if (!file_exists(".gdb"))
|
|
return store_gdb_defaults(NULL);
|
|
|
|
if ((fp = fopen(".gdb", "r")) == NULL) {
|
|
perror(".gdb");
|
|
return store_gdb_defaults(NULL);
|
|
}
|
|
|
|
while (fgets(inbuf, 512, fp)) {
|
|
strip_linefeeds(inbuf);
|
|
strip_beginning_whitespace(inbuf);
|
|
|
|
strcpy(buf, inbuf);
|
|
|
|
/*
|
|
* Simple override.
|
|
*/
|
|
if (strcmp(buf, "5.3") == 0) {
|
|
fclose(fp);
|
|
sp = &supported_gdb_versions[GDB_5_3];
|
|
fprintf(stderr, ".gdb configuration: %s\n\n", sp->GDB_VERSION_IN);
|
|
return store_gdb_defaults(sp);
|
|
}
|
|
if (strcmp(buf, "6.0") == 0) {
|
|
fclose(fp);
|
|
sp = &supported_gdb_versions[GDB_6_0];
|
|
fprintf(stderr, ".gdb configuration: %s\n\n", sp->GDB_VERSION_IN);
|
|
return store_gdb_defaults(sp);
|
|
}
|
|
if (strcmp(buf, "6.1") == 0) {
|
|
fclose(fp);
|
|
sp = &supported_gdb_versions[GDB_6_1];
|
|
fprintf(stderr, ".gdb configuration: %s\n", sp->GDB_VERSION_IN);
|
|
return store_gdb_defaults(sp);
|
|
}
|
|
if (strcmp(buf, "7.0") == 0) {
|
|
fclose(fp);
|
|
sp = &supported_gdb_versions[GDB_7_0];
|
|
fprintf(stderr, ".gdb configuration: %s\n", sp->GDB_VERSION_IN);
|
|
return store_gdb_defaults(sp);
|
|
}
|
|
if (strcmp(buf, "7.3.1") == 0) {
|
|
fclose(fp);
|
|
sp = &supported_gdb_versions[GDB_7_3_1];
|
|
fprintf(stderr, ".gdb configuration: %s\n", sp->GDB_VERSION_IN);
|
|
return store_gdb_defaults(sp);
|
|
}
|
|
if (strcmp(buf, "7.6") == 0) {
|
|
fclose(fp);
|
|
sp = &supported_gdb_versions[GDB_7_6];
|
|
fprintf(stderr, ".gdb configuration: %s\n", sp->GDB_VERSION_IN);
|
|
return store_gdb_defaults(sp);
|
|
}
|
|
if (strcmp(buf, "10.2") == 0) {
|
|
fclose(fp);
|
|
sp = &supported_gdb_versions[GDB_10_2];
|
|
fprintf(stderr, ".gdb configuration: %s\n", sp->GDB_VERSION_IN);
|
|
return store_gdb_defaults(sp);
|
|
}
|
|
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
fprintf(stderr, ".gdb: rejected -- using default gdb\n\n");
|
|
return store_gdb_defaults(NULL);
|
|
}
|
|
|
|
struct supported_gdb_version *
|
|
store_gdb_defaults(struct supported_gdb_version *sp)
|
|
{
|
|
if (!sp)
|
|
sp = &supported_gdb_versions[default_gdb];
|
|
else
|
|
fprintf(stderr, "WARNING: \"make clean\" may be required before rebuilding\n\n");
|
|
|
|
return sp;
|
|
}
|
|
|
|
void
|
|
set_initial_target(struct supported_gdb_version *sp)
|
|
{
|
|
FILE *fp;
|
|
char crash_target[512];
|
|
char buf[512];
|
|
|
|
target_data.initial_gdb_target = UNKNOWN;
|
|
|
|
sprintf(crash_target, "%s/crash.target",
|
|
&sp->GDB[strlen("GDB=")]);
|
|
|
|
if (!file_exists(crash_target)) {
|
|
if (target_data.target_as_param &&
|
|
file_exists(&sp->GDB[strlen("GDB=")])) {
|
|
fprintf(stderr,
|
|
"\nThe \"%s\" file does not exist.\n",
|
|
crash_target);
|
|
target_rebuild_instructions(sp, (char *)target_data.target_as_param);
|
|
exit(1);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if ((fp = fopen(crash_target, "r")) == NULL) {
|
|
perror(crash_target);
|
|
return;
|
|
}
|
|
|
|
if (!fgets(buf, 512, fp)) {
|
|
perror(crash_target);
|
|
fclose(fp);
|
|
return;
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
if (strncmp(buf, "X86_64", strlen("X86_64")) == 0)
|
|
target_data.initial_gdb_target = X86_64;
|
|
else if (strncmp(buf, "X86", strlen("X86")) == 0)
|
|
target_data.initial_gdb_target = X86;
|
|
else if (strncmp(buf, "ALPHA", strlen("ALPHA")) == 0)
|
|
target_data.initial_gdb_target = ALPHA;
|
|
else if (strncmp(buf, "PPC64", strlen("PPC64")) == 0)
|
|
target_data.initial_gdb_target = PPC64;
|
|
else if (strncmp(buf, "PPC", strlen("PPC")) == 0)
|
|
target_data.initial_gdb_target = PPC;
|
|
else if (strncmp(buf, "IA64", strlen("IA64")) == 0)
|
|
target_data.initial_gdb_target = IA64;
|
|
else if (strncmp(buf, "S390X", strlen("S390X")) == 0)
|
|
target_data.initial_gdb_target = S390X;
|
|
else if (strncmp(buf, "S390", strlen("S390")) == 0)
|
|
target_data.initial_gdb_target = S390;
|
|
else if (strncmp(buf, "ARM64", strlen("ARM64")) == 0)
|
|
target_data.initial_gdb_target = ARM64;
|
|
else if (strncmp(buf, "ARM", strlen("ARM")) == 0)
|
|
target_data.initial_gdb_target = ARM;
|
|
else if (strncmp(buf, "MIPS64", strlen("MIPS64")) == 0)
|
|
target_data.initial_gdb_target = MIPS64;
|
|
else if (strncmp(buf, "MIPS", strlen("MIPS")) == 0)
|
|
target_data.initial_gdb_target = MIPS;
|
|
else if (strncmp(buf, "SPARC64", strlen("SPARC64")) == 0)
|
|
target_data.initial_gdb_target = SPARC64;
|
|
else if (strncmp(buf, "RISCV64", strlen("RISCV64")) == 0)
|
|
target_data.initial_gdb_target = RISCV64;
|
|
else if (strncmp(buf, "LOONGARCH64", strlen("LOONGARCH64")) == 0)
|
|
target_data.initial_gdb_target = LOONGARCH64;
|
|
}
|
|
|
|
char *
|
|
target_to_name(int target)
|
|
{
|
|
switch (target)
|
|
{
|
|
case X86: return("X86");
|
|
case ALPHA: return("ALPHA");
|
|
case PPC: return("PPC");
|
|
case IA64: return("IA64");
|
|
case S390: return("S390");
|
|
case S390X: return("S390X");
|
|
case PPC64: return("PPC64");
|
|
case X86_64: return("X86_64");
|
|
case ARM: return("ARM");
|
|
case ARM64: return("ARM64");
|
|
case MIPS: return("MIPS");
|
|
case MIPS64: return("MIPS64");
|
|
case SPARC64: return("SPARC64");
|
|
case RISCV64: return("RISCV64");
|
|
case LOONGARCH64: return("LOONGARCH64");
|
|
}
|
|
|
|
return "UNKNOWN";
|
|
}
|
|
|
|
int
|
|
name_to_target(char *name)
|
|
{
|
|
if (strncmp(name, "X86_64", strlen("X86_64")) == 0)
|
|
return X86_64;
|
|
else if (strncmp(name, "x86_64", strlen("x86_64")) == 0)
|
|
return X86_64;
|
|
else if (strncmp(name, "X86", strlen("X86")) == 0)
|
|
return X86;
|
|
else if (strncmp(name, "x86", strlen("x86")) == 0)
|
|
return X86;
|
|
else if (strncmp(name, "ALPHA", strlen("ALPHA")) == 0)
|
|
return ALPHA;
|
|
else if (strncmp(name, "alpha", strlen("alpha")) == 0)
|
|
return ALPHA;
|
|
else if (strncmp(name, "PPC64", strlen("PPC64")) == 0)
|
|
return PPC64;
|
|
else if (strncmp(name, "ppc64", strlen("ppc64")) == 0)
|
|
return PPC64;
|
|
else if (strncmp(name, "ppc64le", strlen("ppc64le")) == 0)
|
|
return PPC64;
|
|
else if (strncmp(name, "PPC64LE", strlen("PPC64LE")) == 0)
|
|
return PPC64;
|
|
else if (strncmp(name, "PPC", strlen("PPC")) == 0)
|
|
return PPC;
|
|
else if (strncmp(name, "ppc", strlen("ppc")) == 0)
|
|
return PPC;
|
|
else if (strncmp(name, "IA64", strlen("IA64")) == 0)
|
|
return IA64;
|
|
else if (strncmp(name, "ia64", strlen("ia64")) == 0)
|
|
return IA64;
|
|
else if (strncmp(name, "S390X", strlen("S390X")) == 0)
|
|
return S390X;
|
|
else if (strncmp(name, "s390x", strlen("s390x")) == 0)
|
|
return S390X;
|
|
else if (strncmp(name, "S390", strlen("S390")) == 0)
|
|
return S390;
|
|
else if (strncmp(name, "s390", strlen("s390")) == 0)
|
|
return S390;
|
|
else if (strncmp(name, "ARM64", strlen("ARM64")) == 0)
|
|
return ARM64;
|
|
else if (strncmp(name, "arm64", strlen("arm64")) == 0)
|
|
return ARM64;
|
|
else if (strncmp(name, "aarch64", strlen("aarch64")) == 0)
|
|
return ARM64;
|
|
else if (strncmp(name, "ARM", strlen("ARM")) == 0)
|
|
return ARM;
|
|
else if (strncmp(name, "arm", strlen("arm")) == 0)
|
|
return ARM;
|
|
else if (strncmp(name, "mips", strlen("mips")) == 0)
|
|
return MIPS;
|
|
else if (strncmp(name, "MIPS", strlen("MIPS")) == 0)
|
|
return MIPS;
|
|
else if (strncmp(name, "mips64", strlen("mips64")) == 0)
|
|
return MIPS64;
|
|
else if (strncmp(name, "MIPS64", strlen("MIPS64")) == 0)
|
|
return MIPS64;
|
|
else if (strncmp(name, "sparc64", strlen("sparc64")) == 0)
|
|
return SPARC64;
|
|
else if (strncmp(name, "RISCV64", strlen("RISCV64")) == 0)
|
|
return RISCV64;
|
|
else if (strncmp(name, "riscv64", strlen("riscv64")) == 0)
|
|
return RISCV64;
|
|
else if (strncmp(name, "loongarch64", strlen("loongarch64")) == 0)
|
|
return LOONGARCH64;
|
|
else if (strncmp(name, "LOONGARCH64", strlen("LOONGARCH64")) == 0)
|
|
return LOONGARCH64;
|
|
|
|
return UNKNOWN;
|
|
}
|
|
|
|
char *
|
|
get_extra_flags(char *filename, char *initial)
|
|
{
|
|
FILE *fp;
|
|
char inbuf[512];
|
|
char buf[512];
|
|
|
|
if (!file_exists(filename))
|
|
return (initial ? initial : NULL);
|
|
|
|
if ((fp = fopen(filename, "r")) == NULL) {
|
|
perror(filename);
|
|
return (initial ? initial : NULL);
|
|
}
|
|
|
|
if (initial)
|
|
strcpy(buf, initial);
|
|
else
|
|
buf[0] = '\0';
|
|
|
|
while (fgets(inbuf, 512, fp)) {
|
|
strip_linefeeds(inbuf);
|
|
strip_beginning_whitespace(inbuf);
|
|
strip_ending_whitespace(inbuf);
|
|
if (inbuf[0] == '#')
|
|
continue;
|
|
if (strlen(inbuf)) {
|
|
if (strlen(buf))
|
|
strcat(buf, " ");
|
|
strcat(buf, inbuf);
|
|
}
|
|
}
|
|
|
|
fclose(fp);
|
|
|
|
if (strlen(buf))
|
|
return strdup(buf);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* Add extra compression libraries. If not already there, create
|
|
* a CFLAGS.extra file and an LDFLAGS.extra file.
|
|
|
|
* For lzo:
|
|
* - enter -DLZO in the CFLAGS.extra file
|
|
* - enter -llzo2 in the LDFLAGS.extra file
|
|
*
|
|
* For snappy:
|
|
* - enter -DSNAPPY in the CFLAGS.extra file
|
|
* - enter -lsnappy in the LDFLAGS.extra file
|
|
*
|
|
* For zstd:
|
|
* - enter -DZSTD in the CFLAGS.extra file
|
|
* - enter -lzstd in the LDFLAGS.extra file
|
|
*
|
|
* For valgrind:
|
|
* - enter -DVALGRIND in the CFLAGS.extra file
|
|
*/
|
|
void
|
|
add_extra_lib(char *option)
|
|
{
|
|
int lzo, add_DLZO, add_llzo2;
|
|
int snappy, add_DSNAPPY, add_lsnappy;
|
|
int zstd, add_DZSTD, add_lzstd;
|
|
int valgrind, add_DVALGRIND;
|
|
char *cflags, *ldflags;
|
|
FILE *fp_cflags, *fp_ldflags;
|
|
char *mode;
|
|
char inbuf[512];
|
|
|
|
lzo = add_DLZO = add_llzo2 = 0;
|
|
snappy = add_DSNAPPY = add_lsnappy = 0;
|
|
zstd = add_DZSTD = add_lzstd = 0;
|
|
valgrind = add_DVALGRIND = 0;
|
|
|
|
ldflags = get_extra_flags("LDFLAGS.extra", NULL);
|
|
cflags = get_extra_flags("CFLAGS.extra", NULL);
|
|
|
|
if (strcmp(option, "lzo") == 0) {
|
|
lzo++;
|
|
if (!cflags || !strstr(cflags, "-DLZO"))
|
|
add_DLZO++;
|
|
if (!ldflags || !strstr(ldflags, "-llzo2"))
|
|
add_llzo2++;
|
|
}
|
|
|
|
if (strcmp(option, "snappy") == 0) {
|
|
snappy++;
|
|
if (!cflags || !strstr(cflags, "-DSNAPPY"))
|
|
add_DSNAPPY++;
|
|
if (!ldflags || !strstr(ldflags, "-lsnappy"))
|
|
add_lsnappy++;
|
|
}
|
|
|
|
if (strcmp(option, "zstd") == 0) {
|
|
zstd++;
|
|
if (!cflags || !strstr(cflags, "-DZSTD"))
|
|
add_DZSTD++;
|
|
if (!ldflags || !strstr(ldflags, "-lzstd"))
|
|
add_lzstd++;
|
|
}
|
|
|
|
if (strcmp(option, "valgrind") == 0) {
|
|
valgrind++;
|
|
if (!cflags || !strstr(cflags, "-DVALGRIND"))
|
|
add_DVALGRIND++;
|
|
}
|
|
|
|
if ((lzo || snappy || zstd) &&
|
|
file_exists("diskdump.o") && (unlink("diskdump.o") < 0)) {
|
|
perror("diskdump.o");
|
|
return;
|
|
}
|
|
|
|
if (valgrind &&
|
|
file_exists("tools.o") && (unlink("tools.o") < 0)) {
|
|
perror("tools.o");
|
|
return;
|
|
}
|
|
|
|
mode = file_exists("CFLAGS.extra") ? "r+" : "w+";
|
|
if ((fp_cflags = fopen("CFLAGS.extra", mode)) == NULL) {
|
|
perror("CFLAGS.extra");
|
|
return;
|
|
}
|
|
|
|
mode = file_exists("LDFLAGS.extra") ? "r+" : "w+";
|
|
if ((fp_ldflags = fopen("LDFLAGS.extra", mode)) == NULL) {
|
|
perror("LDFLAGS.extra");
|
|
fclose(fp_cflags);
|
|
return;
|
|
}
|
|
|
|
if (add_DLZO || add_DSNAPPY || add_DZSTD || add_DVALGRIND) {
|
|
while (fgets(inbuf, 512, fp_cflags))
|
|
;
|
|
if (add_DLZO)
|
|
fputs("-DLZO\n", fp_cflags);
|
|
if (add_DSNAPPY)
|
|
fputs("-DSNAPPY\n", fp_cflags);
|
|
if (add_DZSTD)
|
|
fputs("-DZSTD\n", fp_cflags);
|
|
if (add_DVALGRIND)
|
|
fputs("-DVALGRIND\n", fp_cflags);
|
|
}
|
|
|
|
if (add_llzo2 || add_lsnappy || add_lzstd) {
|
|
while (fgets(inbuf, 512, fp_ldflags))
|
|
;
|
|
if (add_llzo2)
|
|
fputs("-llzo2\n", fp_ldflags);
|
|
if (add_lsnappy)
|
|
fputs("-lsnappy\n", fp_ldflags);
|
|
if (add_lzstd)
|
|
fputs("-lzstd\n", fp_ldflags);
|
|
}
|
|
|
|
fclose(fp_cflags);
|
|
fclose(fp_ldflags);
|
|
}
|