Commit d55571c0 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'kbuild-v6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild

Pull Kbuild updates from Masahiro Yamada:

 - Refactor scripts/kallsyms to make it faster and easier to maintain

 - Clean up menuconfig

 - Provide Clang with hard-coded target triple instead of CROSS_COMPILE

 - Use -z pack-relative-relocs flags instead of --use-android-relr-tags
   for arm64 CONFIG_RELR

 - Add srcdeb-pkg target to build only a Debian source package

 - Add KDEB_SOURCE_COMPRESS option to specify the compression for a
   Debian source package

 - Misc cleanups and fixes

* tag 'kbuild-v6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild:
  kbuild: deb-pkg: specify targets in debian/rules as .PHONY
  sparc: unify sparc32/sparc64 archhelp
  kbuild: rpm-pkg: remove kernel-drm PROVIDES
  kbuild: deb-pkg: add KDEB_SOURCE_COMPRESS to specify source compression
  kbuild: add srcdeb-pkg target
  Makefile: use -z pack-relative-relocs
  kbuild: clang: do not use CROSS_COMPILE for target triple
  kconfig: menuconfig: reorder functions to remove forward declarations
  kconfig: menuconfig: remove unused M_EVENT macro
  kconfig: menuconfig: remove OLD_NCURSES macro
  kbuild: builddeb: Eliminate debian/arch use
  scripts/kallsyms: update the usage in the comment block
  scripts/kallsyms: decrease expand_symbol() / cleanup_symbol_name() calls
  scripts/kallsyms: change the output order
  scripts/kallsyms: move compiler-generated symbol patterns to mksysmap
  scripts/kallsyms: exclude symbols generated by itself dynamically
  scripts/mksysmap: use sed with in-line comments
  scripts/mksysmap: remove comments described in nm(1)
  scripts/kallsyms: remove redundant code for omitting U and N
  kallsyms: expand symbol name into comment for debugging
parents 31089765 9892bd72
......@@ -1113,7 +1113,8 @@ LDFLAGS_vmlinux += -X
endif
ifeq ($(CONFIG_RELR),y)
LDFLAGS_vmlinux += --pack-dyn-relocs=relr --use-android-relr-tags
# ld.lld before 15 did not support -z pack-relative-relocs.
LDFLAGS_vmlinux += $(call ld-option,--pack-dyn-relocs=relr,-z pack-relative-relocs)
endif
# We never want expected sections to be placed heuristically by the
......
......@@ -83,18 +83,11 @@ vdso_install:
KBUILD_IMAGE := $(boot)/zImage
# Don't use tabs in echo arguments.
ifeq ($(ARCH),sparc)
define archhelp
echo '* image - kernel image ($(boot)/image)'
echo '* zImage - stripped kernel image ($(boot)/zImage)'
echo '* vmlinux - standard SPARC kernel'
echo ' image - kernel image ($(boot)/image)'
echo '* zImage - stripped/compressed kernel image ($(boot)/zImage)'
echo ' uImage - U-Boot SPARC32 Image (only for LEON)'
echo ' vmlinux.aout - a.out kernel for SPARC64'
echo ' tftpboot.img - image prepared for tftp'
endef
else
define archhelp
echo '* vmlinux - standard sparc64 kernel'
echo '* zImage - stripped and compressed sparc64 kernel ($(boot)/zImage)'
echo ' vmlinux.aout - a.out kernel for sparc64'
echo ' tftpboot.img - image prepared for tftp'
endef
endif
......@@ -13,15 +13,11 @@ CLANG_TARGET_FLAGS_x86 := x86_64-linux-gnu
CLANG_TARGET_FLAGS_um := $(CLANG_TARGET_FLAGS_$(SUBARCH))
CLANG_TARGET_FLAGS := $(CLANG_TARGET_FLAGS_$(SRCARCH))
ifeq ($(CROSS_COMPILE),)
ifeq ($(CLANG_TARGET_FLAGS),)
$(error Specify CROSS_COMPILE or add '--target=' option to scripts/Makefile.clang)
$(error add '--target=' option to scripts/Makefile.clang)
else
CLANG_FLAGS += --target=$(CLANG_TARGET_FLAGS)
endif # CLANG_TARGET_FLAGS
else
CLANG_FLAGS += --target=$(notdir $(CROSS_COMPILE:%-=%))
endif # CROSS_COMPILE
endif
ifeq ($(LLVM_IAS),0)
CLANG_FLAGS += -fno-integrated-as
......
......@@ -5,7 +5,6 @@ include $(srctree)/scripts/Kbuild.include
include $(srctree)/scripts/Makefile.lib
KERNELPATH := kernel-$(subst -,_,$(KERNELRELEASE))
KBUILD_PKG_ROOTCMD ?="fakeroot -u"
# Include only those top-level files that are needed by make, plus the GPL copy
TAR_CONTENT := Documentation LICENSES arch block certs crypto drivers fs \
include init io_uring ipc kernel lib mm net rust \
......@@ -42,19 +41,25 @@ check-git:
false; \
fi
git-config-tar.gz = -c tar.tar.gz.command="$(KGZIP)"
git-config-tar.bz2 = -c tar.tar.bz2.command="$(KBZIP2)"
git-config-tar.xz = -c tar.tar.xz.command="$(XZ)"
git-config-tar.zst = -c tar.tar.zst.command="$(ZSTD)"
git-config-tar.gz = -c tar.tar.gz.command="$(KGZIP)"
git-config-tar.bz2 = -c tar.tar.bz2.command="$(KBZIP2)"
git-config-tar.lzma = -c tar.tar.lzma.command="$(LZMA)"
git-config-tar.xz = -c tar.tar.xz.command="$(XZ)"
git-config-tar.zst = -c tar.tar.zst.command="$(ZSTD)"
quiet_cmd_archive = ARCHIVE $@
cmd_archive = git -C $(srctree) $(git-config-tar$(suffix $@)) archive \
--output=$$(realpath $@) $(archive-args)
suffix-gzip := .gz
suffix-bzip2 := .bz2
suffix-lzma := .lzma
suffix-xz := .xz
# Linux source tarball
# ---------------------------------------------------------------------------
linux-tarballs := $(addprefix linux, .tar.gz)
linux-tarballs := $(addprefix linux, .tar.gz .tar.bz2 .tar.lzma .tar.xz)
targets += $(linux-tarballs)
$(linux-tarballs): archive-args = --prefix=linux/ $$(cat $<)
......@@ -86,6 +91,22 @@ binrpm-pkg:
+rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \
$(UTS_MACHINE)-linux -bb $(objtree)/binkernel.spec
# deb-pkg srcdeb-pkg bindeb-pkg
# ---------------------------------------------------------------------------
KDEB_SOURCE_COMPRESS ?= gzip
supported-deb-source-compress := gzip bzip2 lzma xz
PHONY += linux.tar.unsupported-deb-src-compress
linux.tar.unsupported-deb-src-compress:
@echo "error: KDEB_SOURCE_COMPRESS=$(KDEB_SOURCE_COMPRESS) is not supported. The supported values are: $(supported-deb-source-compress)" >&2
@false
debian-orig-suffix := \
$(strip $(if $(filter $(supported-deb-source-compress), $(KDEB_SOURCE_COMPRESS)), \
$(suffix-$(KDEB_SOURCE_COMPRESS)),.unsupported-deb-src-compress))
quiet_cmd_debianize = GEN $@
cmd_debianize = $(srctree)/scripts/package/mkdebian $(mkdebian-opts)
......@@ -95,23 +116,34 @@ debian: FORCE
PHONY += debian-orig
debian-orig: private source = $(shell dpkg-parsechangelog -S Source)
debian-orig: private version = $(shell dpkg-parsechangelog -S Version | sed 's/-[^-]*$$//')
debian-orig: private orig-name = $(source)_$(version).orig.tar.gz
debian-orig: private orig-name = $(source)_$(version).orig.tar$(debian-orig-suffix)
debian-orig: mkdebian-opts = --need-source
debian-orig: linux.tar.gz debian
debian-orig: linux.tar$(debian-orig-suffix) debian
$(Q)if [ "$(df --output=target .. 2>/dev/null)" = "$(df --output=target $< 2>/dev/null)" ]; then \
ln -f $< ../$(orig-name); \
else \
cp $< ../$(orig-name); \
fi
PHONY += deb-pkg
deb-pkg: debian-orig
+dpkg-buildpackage -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch) $(DPKG_FLAGS) \
--build=source,binary -nc -us -uc
KBUILD_PKG_ROOTCMD ?= 'fakeroot -u'
PHONY += deb-pkg srcdeb-pkg bindeb-pkg
deb-pkg: private build-type := source,binary
srcdeb-pkg: private build-type := source
bindeb-pkg: private build-type := binary
PHONY += bindeb-pkg
deb-pkg srcdeb-pkg: debian-orig
bindeb-pkg: debian
+dpkg-buildpackage -r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch) $(DPKG_FLAGS) -b -nc -uc
deb-pkg srcdeb-pkg bindeb-pkg:
+$(strip dpkg-buildpackage \
--build=$(build-type) --no-pre-clean --unsigned-changes \
$(if $(findstring source, $(build-type)), \
--unsigned-source --compression=$(KDEB_SOURCE_COMPRESS)) \
$(if $(findstring binary, $(build-type)), \
-r$(KBUILD_PKG_ROOTCMD) -a$$(cat debian/arch), \
--no-check-builddeps) \
$(DPKG_FLAGS))
PHONY += intdeb-pkg
intdeb-pkg:
......@@ -208,6 +240,7 @@ help:
@echo ' srcrpm-pkg - Build only the source kernel RPM package'
@echo ' binrpm-pkg - Build only the binary kernel RPM package'
@echo ' deb-pkg - Build both source and binary deb kernel packages'
@echo ' srcdeb-pkg - Build only the source kernel deb package'
@echo ' bindeb-pkg - Build only the binary kernel deb package'
@echo ' snap-pkg - Build only the binary kernel snap package'
@echo ' (will connect to external hosts)'
......
......@@ -6,7 +6,7 @@
* of the GNU General Public License, incorporated herein by reference.
*
* Usage: kallsyms [--all-symbols] [--absolute-percpu]
* [--base-relative] in.map > out.S
* [--base-relative] [--lto-clang] in.map > out.S
*
* Table compression uses all the unused char codes on the symbols and
* maps these to the most used substrings (tokens). For instance, it might
......@@ -102,86 +102,7 @@ static char *sym_name(const struct sym_entry *s)
static bool is_ignored_symbol(const char *name, char type)
{
/* Symbol names that exactly match to the following are ignored.*/
static const char * const ignored_symbols[] = {
/*
* Symbols which vary between passes. Passes 1 and 2 must have
* identical symbol lists. The kallsyms_* symbols below are
* only added after pass 1, they would be included in pass 2
* when --all-symbols is specified so exclude them to get a
* stable symbol list.
*/
"kallsyms_addresses",
"kallsyms_offsets",
"kallsyms_relative_base",
"kallsyms_num_syms",
"kallsyms_names",
"kallsyms_markers",
"kallsyms_token_table",
"kallsyms_token_index",
"kallsyms_seqs_of_names",
/* Exclude linker generated symbols which vary between passes */
"_SDA_BASE_", /* ppc */
"_SDA2_BASE_", /* ppc */
NULL
};
/* Symbol names that begin with the following are ignored.*/
static const char * const ignored_prefixes[] = {
"__efistub_", /* arm64 EFI stub namespace */
"__kvm_nvhe_$", /* arm64 local symbols in non-VHE KVM namespace */
"__kvm_nvhe_.L", /* arm64 local symbols in non-VHE KVM namespace */
"__AArch64ADRPThunk_", /* arm64 lld */
"__ARMV5PILongThunk_", /* arm lld */
"__ARMV7PILongThunk_",
"__ThumbV7PILongThunk_",
"__LA25Thunk_", /* mips lld */
"__microLA25Thunk_",
"__kcfi_typeid_", /* CFI type identifiers */
NULL
};
/* Symbol names that end with the following are ignored.*/
static const char * const ignored_suffixes[] = {
"_from_arm", /* arm */
"_from_thumb", /* arm */
"_veneer", /* arm */
NULL
};
/* Symbol names that contain the following are ignored.*/
static const char * const ignored_matches[] = {
".long_branch.", /* ppc stub */
".plt_branch.", /* ppc stub */
NULL
};
const char * const *p;
for (p = ignored_symbols; *p; p++)
if (!strcmp(name, *p))
return true;
for (p = ignored_prefixes; *p; p++)
if (!strncmp(name, *p, strlen(*p)))
return true;
for (p = ignored_suffixes; *p; p++) {
int l = strlen(name) - strlen(*p);
if (l >= 0 && !strcmp(name + l, *p))
return true;
}
for (p = ignored_matches; *p; p++) {
if (strstr(name, *p))
return true;
}
if (type == 'U' || type == 'u')
return true;
/* exclude debugging symbols */
if (type == 'N' || type == 'n')
if (type == 'u' || type == 'n')
return true;
if (toupper(type) == 'A') {
......@@ -414,19 +335,10 @@ static int symbol_absolute(const struct sym_entry *s)
return s->percpu_absolute;
}
static char * s_name(char *buf)
{
/* Skip the symbol type */
return buf + 1;
}
static void cleanup_symbol_name(char *s)
{
char *p;
if (!lto_clang)
return;
/*
* ASCII[.] = 2e
* ASCII[0-9] = 30,39
......@@ -445,16 +357,10 @@ static void cleanup_symbol_name(char *s)
static int compare_names(const void *a, const void *b)
{
int ret;
char sa_namebuf[KSYM_NAME_LEN];
char sb_namebuf[KSYM_NAME_LEN];
const struct sym_entry *sa = *(const struct sym_entry **)a;
const struct sym_entry *sb = *(const struct sym_entry **)b;
expand_symbol(sa->sym, sa->len, sa_namebuf);
expand_symbol(sb->sym, sb->len, sb_namebuf);
cleanup_symbol_name(s_name(sa_namebuf));
cleanup_symbol_name(s_name(sb_namebuf));
ret = strcmp(s_name(sa_namebuf), s_name(sb_namebuf));
ret = strcmp(sym_name(sa), sym_name(sb));
if (!ret) {
if (sa->addr > sb->addr)
return 1;
......@@ -491,55 +397,6 @@ static void write_src(void)
printf("\t.section .rodata, \"a\"\n");
if (!base_relative)
output_label("kallsyms_addresses");
else
output_label("kallsyms_offsets");
for (i = 0; i < table_cnt; i++) {
if (base_relative) {
/*
* Use the offset relative to the lowest value
* encountered of all relative symbols, and emit
* non-relocatable fixed offsets that will be fixed
* up at runtime.
*/
long long offset;
int overflow;
if (!absolute_percpu) {
offset = table[i]->addr - relative_base;
overflow = (offset < 0 || offset > UINT_MAX);
} else if (symbol_absolute(table[i])) {
offset = table[i]->addr;
overflow = (offset < 0 || offset > INT_MAX);
} else {
offset = relative_base - table[i]->addr - 1;
overflow = (offset < INT_MIN || offset >= 0);
}
if (overflow) {
fprintf(stderr, "kallsyms failure: "
"%s symbol value %#llx out of range in relative mode\n",
symbol_absolute(table[i]) ? "absolute" : "relative",
table[i]->addr);
exit(EXIT_FAILURE);
}
printf("\t.long\t%#x\n", (int)offset);
} else if (!symbol_absolute(table[i])) {
output_address(table[i]->addr);
} else {
printf("\tPTR\t%#llx\n", table[i]->addr);
}
}
printf("\n");
if (base_relative) {
output_label("kallsyms_relative_base");
output_address(relative_base);
printf("\n");
}
output_label("kallsyms_num_syms");
printf("\t.long\t%u\n", table_cnt);
printf("\n");
......@@ -592,6 +449,15 @@ static void write_src(void)
}
printf("\n");
/*
* Now that we wrote out the compressed symbol names, restore the
* original names, which are needed in some of the later steps.
*/
for (i = 0; i < table_cnt; i++) {
expand_symbol(table[i]->sym, table[i]->len, buf);
strcpy((char *)table[i]->sym, buf);
}
output_label("kallsyms_markers");
for (i = 0; i < ((table_cnt + 255) >> 8); i++)
printf("\t.long\t%u\n", markers[i]);
......@@ -599,15 +465,6 @@ static void write_src(void)
free(markers);
sort_symbols_by_name();
output_label("kallsyms_seqs_of_names");
for (i = 0; i < table_cnt; i++)
printf("\t.byte 0x%02x, 0x%02x, 0x%02x\n",
(unsigned char)(table[i]->seq >> 16),
(unsigned char)(table[i]->seq >> 8),
(unsigned char)(table[i]->seq >> 0));
printf("\n");
output_label("kallsyms_token_table");
off = 0;
for (i = 0; i < 256; i++) {
......@@ -622,6 +479,68 @@ static void write_src(void)
for (i = 0; i < 256; i++)
printf("\t.short\t%d\n", best_idx[i]);
printf("\n");
if (!base_relative)
output_label("kallsyms_addresses");
else
output_label("kallsyms_offsets");
for (i = 0; i < table_cnt; i++) {
if (base_relative) {
/*
* Use the offset relative to the lowest value
* encountered of all relative symbols, and emit
* non-relocatable fixed offsets that will be fixed
* up at runtime.
*/
long long offset;
int overflow;
if (!absolute_percpu) {
offset = table[i]->addr - relative_base;
overflow = (offset < 0 || offset > UINT_MAX);
} else if (symbol_absolute(table[i])) {
offset = table[i]->addr;
overflow = (offset < 0 || offset > INT_MAX);
} else {
offset = relative_base - table[i]->addr - 1;
overflow = (offset < INT_MIN || offset >= 0);
}
if (overflow) {
fprintf(stderr, "kallsyms failure: "
"%s symbol value %#llx out of range in relative mode\n",
symbol_absolute(table[i]) ? "absolute" : "relative",
table[i]->addr);
exit(EXIT_FAILURE);
}
printf("\t.long\t%#x /* %s */\n", (int)offset, table[i]->sym);
} else if (!symbol_absolute(table[i])) {
output_address(table[i]->addr);
} else {
printf("\tPTR\t%#llx\n", table[i]->addr);
}
}
printf("\n");
if (base_relative) {
output_label("kallsyms_relative_base");
output_address(relative_base);
printf("\n");
}
if (lto_clang)
for (i = 0; i < table_cnt; i++)
cleanup_symbol_name((char *)table[i]->sym);
sort_symbols_by_name();
output_label("kallsyms_seqs_of_names");
for (i = 0; i < table_cnt; i++)
printf("\t.byte 0x%02x, 0x%02x, 0x%02x\n",
(unsigned char)(table[i]->seq >> 16),
(unsigned char)(table[i]->seq >> 8),
(unsigned char)(table[i]->seq >> 0));
printf("\n");
}
......
......@@ -18,22 +18,6 @@
#endif
#include <ncurses.h>
/*
* Colors in ncurses 1.9.9e do not work properly since foreground and
* background colors are OR'd rather than separately masked. This version
* of dialog was hacked to work with ncurses 1.9.9e, making it incompatible
* with standard curses. The simplest fix (to make this work with standard
* curses) uses the wbkgdset() function, not used in the original hack.
* Turn it off if we're building with 1.9.9e, since it just confuses things.
*/
#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
#define OLD_NCURSES 1
#undef wbkgdset
#define wbkgdset(w,p) /*nothing */
#else
#define OLD_NCURSES 0
#endif
#define TR(params) _tracef params
#define KEY_ESC 27
......@@ -225,14 +209,3 @@ int dialog_checklist(const char *title, const char *prompt, int height,
int width, int list_height);
int dialog_inputbox(const char *title, const char *prompt, int height,
int width, const char *init);
/*
* This is the base for fictitious keys, which activate
* the buttons.
*
* Mouse-generated keys are the following:
* -- the first 32 are used as numbers, in addition to '0'-'9'
* -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o')
* -- uppercase chars are used to invoke the button (M_EVENT + 'O')
*/
#define M_EVENT (KEY_MAX+1)
......@@ -63,15 +63,7 @@ static void do_print_item(WINDOW * win, const char *item, int line_y,
/* Clear 'residue' of last item */
wattrset(win, dlg.menubox.atr);
wmove(win, line_y, 0);
#if OLD_NCURSES
{
int i;
for (i = 0; i < menu_width; i++)
waddch(win, ' ');
}
#else
wclrtoeol(win);
#endif
wattrset(win, selected ? dlg.item_selected.atr : dlg.item.atr);
mvwaddstr(win, line_y, item_x, menu_item);
if (hotkey) {
......
......@@ -8,18 +8,136 @@
#include "dialog.h"
static void back_lines(int n);
static void print_page(WINDOW *win, int height, int width, update_text_fn
update_text, void *data);
static void print_line(WINDOW *win, int row, int width);
static char *get_line(void);
static void print_position(WINDOW * win);
static int hscroll;
static int begin_reached, end_reached, page_length;
static char *buf;
static char *page;
/*
* Go back 'n' lines in text. Called by dialog_textbox().
* 'page' will be updated to point to the desired line in 'buf'.
*/
static void back_lines(int n)
{
int i;
begin_reached = 0;
/* Go back 'n' lines */
for (i = 0; i < n; i++) {
if (*page == '\0') {
if (end_reached) {
end_reached = 0;
continue;
}
}
if (page == buf) {
begin_reached = 1;
return;
}
page--;
do {
if (page == buf) {
begin_reached = 1;
return;
}
page--;
} while (*page != '\n');
page++;
}
}
/*
* Return current line of text. Called by dialog_textbox() and print_line().
* 'page' should point to start of current line before calling, and will be
* updated to point to start of next line.
*/
static char *get_line(void)
{
int i = 0;
static char line[MAX_LEN + 1];
end_reached = 0;
while (*page != '\n') {
if (*page == '\0') {
end_reached = 1;
break;
} else if (i < MAX_LEN)
line[i++] = *(page++);
else {
/* Truncate lines longer than MAX_LEN characters */
if (i == MAX_LEN)
line[i++] = '\0';
page++;
}
}
if (i <= MAX_LEN)
line[i] = '\0';
if (!end_reached)
page++; /* move past '\n' */
return line;
}
/*
* Print a new line of text.
*/
static void print_line(WINDOW *win, int row, int width)
{
char *line;
line = get_line();
line += MIN(strlen(line), hscroll); /* Scroll horizontally */
wmove(win, row, 0); /* move cursor to correct line */
waddch(win, ' ');
waddnstr(win, line, MIN(strlen(line), width - 2));
/* Clear 'residue' of previous line */
wclrtoeol(win);
}
/*
* Print a new page of text.
*/
static void print_page(WINDOW *win, int height, int width, update_text_fn
update_text, void *data)
{
int i, passed_end = 0;
if (update_text) {
char *end;
for (i = 0; i < height; i++)
get_line();
end = page;
back_lines(height);
update_text(buf, page - buf, end - buf, data);
}
page_length = 0;
for (i = 0; i < height; i++) {
print_line(win, i, width);
if (!passed_end)
page_length++;
if (end_reached && !passed_end)
passed_end = 1;
}
wnoutrefresh(win);
}
/*
* Print current position
*/
static void print_position(WINDOW *win)
{
int percent;
wattrset(win, dlg.position_indicator.atr);
wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
percent = (page - buf) * 100 / strlen(buf);
wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
wprintw(win, "(%3d%%)", percent);
}
/*
* refresh window content
*/
......@@ -33,7 +151,6 @@ static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
wrefresh(dialog);
}
/*
* Display text from a file in a dialog box.
*
......@@ -259,137 +376,3 @@ int dialog_textbox(const char *title, char *tbuf, int initial_height,
*_hscroll = hscroll;
return key;
}
/*
* Go back 'n' lines in text. Called by dialog_textbox().
* 'page' will be updated to point to the desired line in 'buf'.
*/
static void back_lines(int n)
{
int i;
begin_reached = 0;
/* Go back 'n' lines */
for (i = 0; i < n; i++) {
if (*page == '\0') {
if (end_reached) {
end_reached = 0;
continue;
}
}
if (page == buf) {
begin_reached = 1;
return;
}
page--;
do {
if (page == buf) {
begin_reached = 1;
return;
}
page--;
} while (*page != '\n');
page++;
}
}
/*
* Print a new page of text.
*/
static void print_page(WINDOW *win, int height, int width, update_text_fn
update_text, void *data)
{
int i, passed_end = 0;
if (update_text) {
char *end;
for (i = 0; i < height; i++)
get_line();
end = page;
back_lines(height);
update_text(buf, page - buf, end - buf, data);
}
page_length = 0;
for (i = 0; i < height; i++) {
print_line(win, i, width);
if (!passed_end)
page_length++;
if (end_reached && !passed_end)
passed_end = 1;
}
wnoutrefresh(win);
}
/*
* Print a new line of text.
*/
static void print_line(WINDOW * win, int row, int width)
{
char *line;
line = get_line();
line += MIN(strlen(line), hscroll); /* Scroll horizontally */
wmove(win, row, 0); /* move cursor to correct line */
waddch(win, ' ');
waddnstr(win, line, MIN(strlen(line), width - 2));
/* Clear 'residue' of previous line */
#if OLD_NCURSES
{
int x = getcurx(win);
int i;
for (i = 0; i < width - x; i++)
waddch(win, ' ');
}
#else
wclrtoeol(win);
#endif
}
/*
* Return current line of text. Called by dialog_textbox() and print_line().
* 'page' should point to start of current line before calling, and will be
* updated to point to start of next line.
*/
static char *get_line(void)
{
int i = 0;
static char line[MAX_LEN + 1];
end_reached = 0;
while (*page != '\n') {
if (*page == '\0') {
end_reached = 1;
break;
} else if (i < MAX_LEN)
line[i++] = *(page++);
else {
/* Truncate lines longer than MAX_LEN characters */
if (i == MAX_LEN)
line[i++] = '\0';
page++;
}
}
if (i <= MAX_LEN)
line[i] = '\0';
if (!end_reached)
page++; /* move past '\n' */
return line;
}
/*
* Print current position
*/
static void print_position(WINDOW * win)
{
int percent;
wattrset(win, dlg.position_indicator.atr);
wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
percent = (page - buf) * 100 / strlen(buf);
wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
wprintw(win, "(%3d%%)", percent);
}
......@@ -290,16 +290,6 @@ static int save_and_exit;
static int silent;
static void conf(struct menu *menu, struct menu *active_menu);
static void conf_choice(struct menu *menu);
static void conf_string(struct menu *menu);
static void conf_load(void);
static void conf_save(void);
static int show_textbox_ext(const char *title, char *text, int r, int c,
int *keys, int *vscroll, int *hscroll,
update_text_fn update_text, void *data);
static void show_textbox(const char *title, const char *text, int r, int c);
static void show_helptext(const char *title, const char *text);
static void show_help(struct menu *menu);
static char filename[PATH_MAX+1];
static void set_config_filename(const char *config_filename)
......@@ -358,6 +348,37 @@ static void reset_subtitle(void)
set_dialog_subtitles(subtitles);
}
static int show_textbox_ext(const char *title, char *text, int r, int c, int
*keys, int *vscroll, int *hscroll, update_text_fn
update_text, void *data)
{
dialog_clear();
return dialog_textbox(title, text, r, c, keys, vscroll, hscroll,
update_text, data);
}
static void show_textbox(const char *title, const char *text, int r, int c)
{
show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL,
NULL, NULL);
}
static void show_helptext(const char *title, const char *text)
{
show_textbox(title, text, 0, 0);
}
static void show_help(struct menu *menu)
{
struct gstr help = str_new();
help.max_width = getmaxx(stdscr) - 10;
menu_get_ext_help(menu, &help);
show_helptext(menu_get_prompt(menu), str_get(&help));
str_free(&help);
}
struct search_data {
struct list_head *head;
struct menu **targets;
......@@ -643,158 +664,6 @@ static void build_conf(struct menu *menu)
indent -= doint;
}
static void conf(struct menu *menu, struct menu *active_menu)
{
struct menu *submenu;
const char *prompt = menu_get_prompt(menu);
struct subtitle_part stpart;
struct symbol *sym;
int res;
int s_scroll = 0;
if (menu != &rootmenu)
stpart.text = menu_get_prompt(menu);
else
stpart.text = NULL;
list_add_tail(&stpart.entries, &trail);
while (1) {
item_reset();
current_menu = menu;
build_conf(menu);
if (!child_count)
break;
set_subtitle();
dialog_clear();
res = dialog_menu(prompt ? prompt : "Main Menu",
menu_instructions,
active_menu, &s_scroll);
if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
break;
if (item_count() != 0) {
if (!item_activate_selected())
continue;
if (!item_tag())
continue;
}
submenu = item_data();
active_menu = item_data();
if (submenu)
sym = submenu->sym;
else
sym = NULL;
switch (res) {
case 0:
switch (item_tag()) {
case 'm':
if (single_menu_mode)
submenu->data = (void *) (long) !submenu->data;
else
conf(submenu, NULL);
break;
case 't':
if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
conf_choice(submenu);
else if (submenu->prompt->type == P_MENU)
conf(submenu, NULL);
break;
case 's':
conf_string(submenu);
break;
}
break;
case 2:
if (sym)
show_help(submenu);
else {
reset_subtitle();
show_helptext("README", mconf_readme);
}
break;
case 3:
reset_subtitle();
conf_save();
break;
case 4:
reset_subtitle();
conf_load();
break;
case 5:
if (item_is_tag('t')) {
if (sym_set_tristate_value(sym, yes))
break;
if (sym_set_tristate_value(sym, mod))
show_textbox(NULL, setmod_text, 6, 74);
}
break;
case 6:
if (item_is_tag('t'))
sym_set_tristate_value(sym, no);
break;
case 7:
if (item_is_tag('t'))
sym_set_tristate_value(sym, mod);
break;
case 8:
if (item_is_tag('t'))
sym_toggle_tristate_value(sym);
else if (item_is_tag('m'))
conf(submenu, NULL);
break;
case 9:
search_conf();
break;
case 10:
show_all_options = !show_all_options;
break;
}
}
list_del(trail.prev);
}
static int show_textbox_ext(const char *title, char *text, int r, int c, int
*keys, int *vscroll, int *hscroll, update_text_fn
update_text, void *data)
{
dialog_clear();
return dialog_textbox(title, text, r, c, keys, vscroll, hscroll,
update_text, data);
}
static void show_textbox(const char *title, const char *text, int r, int c)
{
show_textbox_ext(title, (char *) text, r, c, (int []) {0}, NULL, NULL,
NULL, NULL);
}
static void show_helptext(const char *title, const char *text)
{
show_textbox(title, text, 0, 0);
}
static void conf_message_callback(const char *s)
{
if (save_and_exit) {
if (!silent)
printf("%s", s);
} else {
show_textbox(NULL, s, 6, 60);
}
}
static void show_help(struct menu *menu)
{
struct gstr help = str_new();
help.max_width = getmaxx(stdscr) - 10;
menu_get_ext_help(menu, &help);
show_helptext(menu_get_prompt(menu), str_get(&help));
str_free(&help);
}
static void conf_choice(struct menu *menu)
{
const char *prompt = menu_get_prompt(menu);
......@@ -950,6 +819,127 @@ static void conf_save(void)
}
}
static void conf(struct menu *menu, struct menu *active_menu)
{
struct menu *submenu;
const char *prompt = menu_get_prompt(menu);
struct subtitle_part stpart;
struct symbol *sym;
int res;
int s_scroll = 0;
if (menu != &rootmenu)
stpart.text = menu_get_prompt(menu);
else
stpart.text = NULL;
list_add_tail(&stpart.entries, &trail);
while (1) {
item_reset();
current_menu = menu;
build_conf(menu);
if (!child_count)
break;
set_subtitle();
dialog_clear();
res = dialog_menu(prompt ? prompt : "Main Menu",
menu_instructions,
active_menu, &s_scroll);
if (res == 1 || res == KEY_ESC || res == -ERRDISPLAYTOOSMALL)
break;
if (item_count() != 0) {
if (!item_activate_selected())
continue;
if (!item_tag())
continue;
}
submenu = item_data();
active_menu = item_data();
if (submenu)
sym = submenu->sym;
else
sym = NULL;
switch (res) {
case 0:
switch (item_tag()) {
case 'm':
if (single_menu_mode)
submenu->data = (void *) (long) !submenu->data;
else
conf(submenu, NULL);
break;
case 't':
if (sym_is_choice(sym) && sym_get_tristate_value(sym) == yes)
conf_choice(submenu);
else if (submenu->prompt->type == P_MENU)
conf(submenu, NULL);
break;
case 's':
conf_string(submenu);
break;
}
break;
case 2:
if (sym)
show_help(submenu);
else {
reset_subtitle();
show_helptext("README", mconf_readme);
}
break;
case 3:
reset_subtitle();
conf_save();
break;
case 4:
reset_subtitle();
conf_load();
break;
case 5:
if (item_is_tag('t')) {
if (sym_set_tristate_value(sym, yes))
break;
if (sym_set_tristate_value(sym, mod))
show_textbox(NULL, setmod_text, 6, 74);
}
break;
case 6:
if (item_is_tag('t'))
sym_set_tristate_value(sym, no);
break;
case 7:
if (item_is_tag('t'))
sym_set_tristate_value(sym, mod);
break;
case 8:
if (item_is_tag('t'))
sym_toggle_tristate_value(sym);
else if (item_is_tag('m'))
conf(submenu, NULL);
break;
case 9:
search_conf();
break;
case 10:
show_all_options = !show_all_options;
break;
}
}
list_del(trail.prev);
}
static void conf_message_callback(const char *s)
{
if (save_and_exit) {
if (!silent)
printf("%s", s);
} else {
show_textbox(NULL, s, 6, 60);
}
}
static int handle_exit(void)
{
int res;
......
......@@ -174,7 +174,7 @@ kallsyms_step()
kallsyms_S=${kallsyms_vmlinux}.S
vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o}
mksysmap ${kallsyms_vmlinux} ${kallsyms_vmlinux}.syms
mksysmap ${kallsyms_vmlinux} ${kallsyms_vmlinux}.syms ${kallsymso_prev}
kallsyms ${kallsyms_vmlinux}.syms ${kallsyms_S}
info AS ${kallsyms_S}
......@@ -188,7 +188,7 @@ kallsyms_step()
mksysmap()
{
info NM ${2}
${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2}
${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2} ${3}
}
sorttable()
......@@ -277,7 +277,7 @@ if is_enabled CONFIG_DEBUG_INFO_BTF && is_enabled CONFIG_BPF; then
${RESOLVE_BTFIDS} vmlinux
fi
mksysmap vmlinux System.map
mksysmap vmlinux System.map ${kallsymso}
if is_enabled CONFIG_BUILDTIME_TABLE_SORT; then
info SORTTAB vmlinux
......
......@@ -4,57 +4,104 @@
# tools to retrieve the actual addresses of symbols in the kernel.
#
# Usage
# mksysmap vmlinux System.map
# mksysmap vmlinux System.map [exclude]
#####
# Generate System.map (actual filename passed as second argument)
# $NM produces the following output:
# f0081e80 T alloc_vfsmnt
# The second row specify the type of the symbol:
# A = Absolute
# B = Uninitialised data (.bss)
# C = Common symbol
# D = Initialised data
# G = Initialised data for small objects
# I = Indirect reference to another symbol
# N = Debugging symbol
# R = Read only
# S = Uninitialised data for small objects
# T = Text code symbol
# U = Undefined symbol
# V = Weak symbol
# W = Weak symbol
# Corresponding small letters are local symbols
# For System.map filter away:
# a - local absolute symbols
# U - undefined global symbols
# N - debugging symbols
# w - local weak symbols
# The following refers to the symbol type as per nm(1).
# readprofile starts reading symbols when _stext is found, and
# continue until it finds a symbol which is not either of 'T', 't',
# 'W' or 'w'.
#
# Ignored prefixes:
# $ - local symbols for ARM, MIPS, etc.
# .L - local labels, .LBB,.Ltmpxxx,.L__unnamed_xx,.LASANPC, etc.
# __crc_ - modversions
# __kstrtab_ - EXPORT_SYMBOL (symbol name)
# __kstrtabns_ - EXPORT_SYMBOL (namespace)
${NM} -n ${1} | sed >${2} -e "
# ---------------------------------------------------------------------------
# Ignored symbol types
#
# a: local absolute symbols
# N: debugging symbols
# U: undefined global symbols
# w: local weak symbols
/ [aNUw] /d
# ---------------------------------------------------------------------------
# Ignored prefixes
# (do not forget a space before each pattern)
# local symbols for ARM, MIPS, etc.
/ \$/d
# local labels, .LBB, .Ltmpxxx, .L__unnamed_xx, .LASANPC, etc.
/ \.L/d
# arm64 EFI stub namespace
/ __efistub_/d
# arm64 local symbols in non-VHE KVM namespace
/ __kvm_nvhe_\$/d
/ __kvm_nvhe_\.L/d
# arm64 lld
/ __AArch64ADRPThunk_/d
# arm lld
/ __ARMV5PILongThunk_/d
/ __ARMV7PILongThunk_/d
/ __ThumbV7PILongThunk_/d
# mips lld
/ __LA25Thunk_/d
/ __microLA25Thunk_/d
# CFI type identifiers
/ __kcfi_typeid_/d
# CRC from modversions
/ __crc_/d
# EXPORT_SYMBOL (symbol name)
/ __kstrtab_/d
# EXPORT_SYMBOL (namespace)
/ __kstrtabns_/d
# ---------------------------------------------------------------------------
# Ignored suffixes
# (do not forget '$' after each pattern)
# arm
/_from_arm$/d
/_from_thumb$/d
/_veneer$/d
# ---------------------------------------------------------------------------
# Ignored symbols (exact match)
# (do not forget a space before and '$' after each pattern)
# for LoongArch?
/ L0$/d
# ppc
/ _SDA_BASE_$/d
/ _SDA2_BASE_$/d
# ---------------------------------------------------------------------------
# Ignored patterns
# (symbols that contain the pattern are ignored)
# ppc stub
/\.long_branch\./d
/\.plt_branch\./d
# ---------------------------------------------------------------------------
# Ignored kallsyms symbols
#
# Ignored symbols:
# L0 - for LoongArch?
$NM -n $1 | grep -v \
-e ' [aNUw] ' \
-e ' \$' \
-e ' \.L' \
-e ' __crc_' \
-e ' __kstrtab_' \
-e ' __kstrtabns_' \
-e ' L0$' \
> $2
# If the 3rd parameter exists, symbols from it will be omitted from the output.
# This makes kallsyms have the identical symbol lists in the step 1 and 2.
# Without this, the step2 would get new symbols generated by scripts/kallsyms.c
# when CONFIG_KALLSYMS_ALL is enabled. That might require one more pass.
$(if [ $# -ge 3 ]; then ${NM} ${3} | sed -n '/ U /!s:.* \([^ ]*\)$:/ \1$/d:p'; fi)
"
......@@ -209,7 +209,7 @@ install_libc_headers () {
# move asm headers to /usr/include/<libc-machine>/asm to match the structure
# used by Debian-based distros (to support multi-arch)
host_arch=$(dpkg-architecture -a$(cat debian/arch) -qDEB_HOST_MULTIARCH)
host_arch=$(dpkg-architecture -a$DEB_HOST_ARCH -qDEB_HOST_MULTIARCH)
mkdir $pdir/usr/include/$host_arch
mv $pdir/usr/include/asm $pdir/usr/include/$host_arch/
}
......
......@@ -269,6 +269,8 @@ cat <<EOF > debian/rules
srctree ?= .
KERNELRELEASE = ${KERNELRELEASE}
.PHONY: clean build build-arch build-indep binary binary-arch binary-indep
build-indep:
build-arch:
\$(MAKE) -f \$(srctree)/Makefile ARCH=${ARCH} \
......
......@@ -28,11 +28,6 @@ else
M=DEL
fi
if grep -q CONFIG_DRM=y include/config/auto.conf; then
PROVIDES=kernel-drm
fi
PROVIDES="$PROVIDES kernel-$KERNELRELEASE"
__KERNELRELEASE=$(echo $KERNELRELEASE | sed -e "s/-/_/g")
EXCLUDES="$RCS_TAR_IGNORE --exclude=*vmlinux* --exclude=*.mod \
--exclude=*.o --exclude=*.ko --exclude=*.cmd --exclude=Documentation \
......@@ -55,7 +50,7 @@ sed -e '/^DEL/d' -e 's/^\t*//' <<EOF
$S Source0: linux.tar.gz
$S Source1: config
$S Source2: diff.patch
Provides: $PROVIDES
Provides: kernel-$KERNELRELEASE
$S BuildRequires: bc binutils bison dwarves
$S BuildRequires: (elfutils-libelf-devel or libelf-devel) flex
$S BuildRequires: gcc make openssl openssl-devel perl python3 rsync
......
......@@ -7,8 +7,12 @@ trap "rm -f $tmp_file.o $tmp_file $tmp_file.bin" EXIT
cat << "END" | $CC -c -x c - -o $tmp_file.o >/dev/null 2>&1
void *p = &p;
END
$LD $tmp_file.o -shared -Bsymbolic --pack-dyn-relocs=relr \
--use-android-relr-tags -o $tmp_file
# ld.lld before 15 did not support -z pack-relative-relocs.
if ! $LD $tmp_file.o -shared -Bsymbolic --pack-dyn-relocs=relr -o $tmp_file 2>/dev/null; then
$LD $tmp_file.o -shared -Bsymbolic -z pack-relative-relocs -o $tmp_file 2>&1 |
grep -q pack-relative-relocs && exit 1
fi
# Despite printing an error message, GNU nm still exits with exit code 0 if it
# sees a relr section. So we need to check that nothing is printed to stderr.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment