Merge commit 'v3.0-rc1' into kbuild/kbuild
This commit is contained in:
@@ -260,14 +260,19 @@ endif
|
||||
|
||||
ifdef CONFIG_FTRACE_MCOUNT_RECORD
|
||||
ifdef BUILD_C_RECORDMCOUNT
|
||||
ifeq ("$(origin RECORDMCOUNT_WARN)", "command line")
|
||||
RECORDMCOUNT_FLAGS = -w
|
||||
endif
|
||||
# Due to recursion, we must skip empty.o.
|
||||
# The empty.o file is created in the make process in order to determine
|
||||
# the target endianness and word size. It is made before all other C
|
||||
# files, including recordmcount.
|
||||
sub_cmd_record_mcount = \
|
||||
if [ $(@) != "scripts/mod/empty.o" ]; then \
|
||||
$(objtree)/scripts/recordmcount "$(@)"; \
|
||||
$(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)"; \
|
||||
fi;
|
||||
recordmcount_source := $(srctree)/scripts/recordmcount.c \
|
||||
$(srctree)/scripts/recordmcount.h
|
||||
else
|
||||
sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
|
||||
"$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \
|
||||
@@ -275,6 +280,7 @@ sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH
|
||||
"$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CFLAGS)" \
|
||||
"$(LD)" "$(NM)" "$(RM)" "$(MV)" \
|
||||
"$(if $(part-of-module),1,0)" "$(@)";
|
||||
recordmcount_source := $(srctree)/scripts/recordmcount.pl
|
||||
endif
|
||||
cmd_record_mcount = \
|
||||
if [ "$(findstring -pg,$(_c_flags))" = "-pg" ]; then \
|
||||
@@ -295,13 +301,13 @@ define rule_cc_o_c
|
||||
endef
|
||||
|
||||
# Built-in and composite module parts
|
||||
$(obj)/%.o: $(src)/%.c FORCE
|
||||
$(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE
|
||||
$(call cmd,force_checksrc)
|
||||
$(call if_changed_rule,cc_o_c)
|
||||
|
||||
# Single-part modules are special since we need to mark them in $(MODVERDIR)
|
||||
|
||||
$(single-used-m): $(obj)/%.o: $(src)/%.c FORCE
|
||||
$(single-used-m): $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE
|
||||
$(call cmd,force_checksrc)
|
||||
$(call if_changed_rule,cc_o_c)
|
||||
@{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod)
|
||||
|
||||
@@ -35,14 +35,14 @@
|
||||
# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined
|
||||
# symbols in the final module linking stage
|
||||
# KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules.
|
||||
# This is solely usefull to speed up test compiles
|
||||
# This is solely useful to speed up test compiles
|
||||
PHONY := _modpost
|
||||
_modpost: __modpost
|
||||
|
||||
include include/config/auto.conf
|
||||
include scripts/Kbuild.include
|
||||
|
||||
# When building external modules load the Kbuild file to retreive EXTRA_SYMBOLS info
|
||||
# When building external modules load the Kbuild file to retrieve EXTRA_SYMBOLS info
|
||||
ifneq ($(KBUILD_EXTMOD),)
|
||||
|
||||
# set src + obj - they may be used when building the .mod.c file
|
||||
|
||||
@@ -210,10 +210,10 @@ our $typeTypedefs = qr{(?x:
|
||||
|
||||
our $logFunctions = qr{(?x:
|
||||
printk|
|
||||
pr_(debug|dbg|vdbg|devel|info|warning|err|notice|alert|crit|emerg|cont)|
|
||||
(dev|netdev|netif)_(printk|dbg|vdbg|info|warn|err|notice|alert|crit|emerg|WARN)|
|
||||
[a-z]+_(emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)|
|
||||
WARN|
|
||||
panic
|
||||
panic|
|
||||
MODULE_[A-Z_]+
|
||||
)};
|
||||
|
||||
our @typeList = (
|
||||
@@ -1462,7 +1462,7 @@ sub process {
|
||||
#80 column limit
|
||||
if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
|
||||
$rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
|
||||
!($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ ||
|
||||
!($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:|,|\)\s*;)\s*$/ ||
|
||||
$line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) &&
|
||||
$length > 80)
|
||||
{
|
||||
@@ -1946,13 +1946,13 @@ sub process {
|
||||
# printk should use KERN_* levels. Note that follow on printk's on the
|
||||
# same line do not need a level, so we use the current block context
|
||||
# to try and find and validate the current printk. In summary the current
|
||||
# printk includes all preceeding printk's which have no newline on the end.
|
||||
# printk includes all preceding printk's which have no newline on the end.
|
||||
# we assume the first bad printk is the one to report.
|
||||
if ($line =~ /\bprintk\((?!KERN_)\s*"/) {
|
||||
my $ok = 0;
|
||||
for (my $ln = $linenr - 1; $ln >= $first_line; $ln--) {
|
||||
#print "CHECK<$lines[$ln - 1]\n";
|
||||
# we have a preceeding printk if it ends
|
||||
# we have a preceding printk if it ends
|
||||
# with "\n" ignore it, else it is to blame
|
||||
if ($lines[$ln - 1] =~ m{\bprintk\(}) {
|
||||
if ($rawlines[$ln - 1] !~ m{\\n"}) {
|
||||
@@ -2044,7 +2044,7 @@ sub process {
|
||||
for (my $n = 0; $n < $#elements; $n += 2) {
|
||||
$off += length($elements[$n]);
|
||||
|
||||
# Pick up the preceeding and succeeding characters.
|
||||
# Pick up the preceding and succeeding characters.
|
||||
my $ca = substr($opline, 0, $off);
|
||||
my $cc = '';
|
||||
if (length($opline) >= ($off + length($elements[$n + 1]))) {
|
||||
@@ -2748,6 +2748,11 @@ sub process {
|
||||
WARN("sizeof(& should be avoided\n" . $herecurr);
|
||||
}
|
||||
|
||||
# check for line continuations in quoted strings with odd counts of "
|
||||
if ($rawline =~ /\\$/ && $rawline =~ tr/"/"/ % 2) {
|
||||
WARN("Avoid line continuations in quoted strings\n" . $herecurr);
|
||||
}
|
||||
|
||||
# check for new externs in .c files.
|
||||
if ($realfile =~ /\.c$/ && defined $stat &&
|
||||
$stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# sh64 port by Paul Mundt
|
||||
# Random bits by Matt Mackall <mpm@selenic.com>
|
||||
# M68k port by Geert Uytterhoeven and Andreas Schwab
|
||||
# AVR32 port by Haavard Skinnemoen <hskinnemoen@atmel.com>
|
||||
# AVR32 port by Haavard Skinnemoen (Atmel)
|
||||
# PARISC port by Kyle McMartin <kyle@parisc-linux.org>
|
||||
# sparc port by Martin Habets <errandir_news@mph.eclipse.co.uk>
|
||||
#
|
||||
|
||||
@@ -12,6 +12,7 @@ $| = 1;
|
||||
my $debugging;
|
||||
|
||||
foreach my $file (@ARGV) {
|
||||
next if $file =~ "include/linux/version\.h";
|
||||
# Open this file.
|
||||
open( my $f, '<', $file )
|
||||
or die "Can't open $file: $!\n";
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
#define FDT_ERR_NOTFOUND 1
|
||||
/* FDT_ERR_NOTFOUND: The requested node or property does not exist */
|
||||
#define FDT_ERR_EXISTS 2
|
||||
/* FDT_ERR_EXISTS: Attemped to create a node or property which
|
||||
/* FDT_ERR_EXISTS: Attempted to create a node or property which
|
||||
* already exists */
|
||||
#define FDT_ERR_NOSPACE 3
|
||||
/* FDT_ERR_NOSPACE: Operation needed to expand the device
|
||||
|
||||
@@ -155,7 +155,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
|
||||
}
|
||||
}
|
||||
|
||||
/* if no collision occured, add child to the old node. */
|
||||
/* if no collision occurred, add child to the old node. */
|
||||
if (new_child)
|
||||
add_child(old_node, new_child);
|
||||
}
|
||||
|
||||
@@ -25,11 +25,12 @@ sub alphabetically {
|
||||
sub print_depends_on {
|
||||
my ($href) = @_;
|
||||
print "\n";
|
||||
while (my ($mod, $list) = each %$href) {
|
||||
for my $mod (sort keys %$href) {
|
||||
my $list = $href->{$mod};
|
||||
print "\t$mod:\n";
|
||||
foreach my $sym (sort numerically @{$list}) {
|
||||
my ($symbol, $no) = split /\s+/, $sym;
|
||||
printf("\t\t%-25s\t%-25d\n", $symbol, $no);
|
||||
printf("\t\t%-25s\n", $symbol);
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
@@ -49,8 +50,14 @@ sub usage {
|
||||
}
|
||||
|
||||
sub collectcfiles {
|
||||
my @file
|
||||
= `cat .tmp_versions/*.mod | grep '.*\.ko\$' | sed s/\.ko$/.mod.c/`;
|
||||
my @file;
|
||||
while (<.tmp_versions/*.mod>) {
|
||||
open my $fh, '<', $_ or die "cannot open $_: $!\n";
|
||||
push (@file,
|
||||
grep s/\.ko/.mod.c/, # change the suffix
|
||||
grep m/.+\.ko/, # find the .ko path
|
||||
<$fh>); # lines in opened file
|
||||
}
|
||||
chomp @file;
|
||||
return @file;
|
||||
}
|
||||
@@ -95,6 +102,8 @@ close($module_symvers);
|
||||
#
|
||||
# collect the usage count of each symbol.
|
||||
#
|
||||
my $modversion_warnings = 0;
|
||||
|
||||
foreach my $thismod (@allcfiles) {
|
||||
my $module;
|
||||
|
||||
@@ -125,7 +134,8 @@ foreach my $thismod (@allcfiles) {
|
||||
}
|
||||
}
|
||||
if ($state != 2) {
|
||||
print "WARNING:$thismod is not built with CONFIG_MODVERSION enabled\n";
|
||||
warn "WARNING:$thismod is not built with CONFIG_MODVERSIONS enabled\n";
|
||||
$modversion_warnings++;
|
||||
}
|
||||
close($module);
|
||||
}
|
||||
@@ -159,8 +169,12 @@ printf("SECTION 2:\n\tThis section reports export-symbol-usage of in-kernel
|
||||
modules. Each module lists the modules, and the symbols from that module that
|
||||
it uses. Each listed symbol reports the number of modules using it\n");
|
||||
|
||||
print "\nNOTE: Got $modversion_warnings CONFIG_MODVERSIONS warnings\n\n"
|
||||
if $modversion_warnings;
|
||||
|
||||
print "~"x80 , "\n";
|
||||
while (my ($thismod, $list) = each %MODULE) {
|
||||
for my $thismod (sort keys %MODULE) {
|
||||
my $list = $MODULE{$thismod};
|
||||
my %depends;
|
||||
$thismod =~ s/\.mod\.c/.ko/;
|
||||
print "\t\t\t$thismod\n";
|
||||
|
||||
@@ -284,7 +284,7 @@ while [ $# -gt 0 ]; do
|
||||
done
|
||||
|
||||
# If output_file is set we will generate cpio archive and compress it
|
||||
# we are carefull to delete tmp files
|
||||
# we are careful to delete tmp files
|
||||
if [ ! -z ${output_file} ]; then
|
||||
if [ -z ${cpio_file} ]; then
|
||||
timestamp=
|
||||
|
||||
@@ -77,14 +77,15 @@ localyesconfig: $(obj)/streamline_config.pl $(obj)/conf
|
||||
# The symlink is used to repair a deficiency in arch/um
|
||||
update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h
|
||||
$(Q)echo " GEN config"
|
||||
$(Q)xgettext --default-domain=linux \
|
||||
--add-comments --keyword=_ --keyword=N_ \
|
||||
--from-code=UTF-8 \
|
||||
--files-from=scripts/kconfig/POTFILES.in \
|
||||
$(Q)xgettext --default-domain=linux \
|
||||
--add-comments --keyword=_ --keyword=N_ \
|
||||
--from-code=UTF-8 \
|
||||
--files-from=$(srctree)/scripts/kconfig/POTFILES.in \
|
||||
--directory=$(srctree) --directory=$(objtree) \
|
||||
--output $(obj)/config.pot
|
||||
$(Q)sed -i s/CHARSET/UTF-8/ $(obj)/config.pot
|
||||
$(Q)ln -fs Kconfig.i386 arch/um/Kconfig.arch
|
||||
$(Q)(for i in `ls arch/*/Kconfig`; \
|
||||
$(Q)ln -fs Kconfig.x86 arch/um/Kconfig
|
||||
$(Q)(for i in `ls $(srctree)/arch/*/Kconfig`; \
|
||||
do \
|
||||
echo " GEN $$i"; \
|
||||
$(obj)/kxgettext $$i \
|
||||
@@ -92,7 +93,7 @@ update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h
|
||||
done )
|
||||
$(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \
|
||||
--output $(obj)/linux.pot
|
||||
$(Q)rm -f arch/um/Kconfig.arch
|
||||
$(Q)rm -f $(srctree)/arch/um/Kconfig
|
||||
$(Q)rm -f $(obj)/config.pot
|
||||
|
||||
PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig
|
||||
@@ -168,8 +169,11 @@ conf-objs := conf.o zconf.tab.o
|
||||
mconf-objs := mconf.o zconf.tab.o $(lxdialog)
|
||||
nconf-objs := nconf.o zconf.tab.o nconf.gui.o
|
||||
kxgettext-objs := kxgettext.o zconf.tab.o
|
||||
qconf-cxxobjs := qconf.o
|
||||
qconf-objs := kconfig_load.o zconf.tab.o
|
||||
gconf-objs := gconf.o kconfig_load.o zconf.tab.o
|
||||
|
||||
hostprogs-y := conf qconf gconf kxgettext
|
||||
hostprogs-y := conf
|
||||
|
||||
ifeq ($(MAKECMDGOALS),nconfig)
|
||||
hostprogs-y += nconf
|
||||
@@ -179,6 +183,10 @@ ifeq ($(MAKECMDGOALS),menuconfig)
|
||||
hostprogs-y += mconf
|
||||
endif
|
||||
|
||||
ifeq ($(MAKECMDGOALS),update-po-config)
|
||||
hostprogs-y += kxgettext
|
||||
endif
|
||||
|
||||
ifeq ($(MAKECMDGOALS),xconfig)
|
||||
qconf-target := 1
|
||||
endif
|
||||
@@ -188,16 +196,15 @@ endif
|
||||
|
||||
|
||||
ifeq ($(qconf-target),1)
|
||||
qconf-cxxobjs := qconf.o
|
||||
qconf-objs := kconfig_load.o zconf.tab.o
|
||||
hostprogs-y += qconf
|
||||
endif
|
||||
|
||||
ifeq ($(gconf-target),1)
|
||||
gconf-objs := gconf.o kconfig_load.o zconf.tab.o
|
||||
hostprogs-y += gconf
|
||||
endif
|
||||
|
||||
clean-files := lkc_defs.h qconf.moc .tmp_qtcheck \
|
||||
.tmp_gtkcheck zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h
|
||||
clean-files := lkc_defs.h qconf.moc .tmp_qtcheck .tmp_gtkcheck
|
||||
clean-files += zconf.tab.c lex.zconf.c zconf.hash.c gconf.glade.h
|
||||
clean-files += mconf qconf gconf nconf
|
||||
clean-files += config.pot linux.pot
|
||||
|
||||
@@ -321,11 +328,12 @@ $(obj)/%.moc: $(src)/%.h
|
||||
$(KC_QT_MOC) -i $< -o $@
|
||||
|
||||
$(obj)/lkc_defs.h: $(src)/lkc_proto.h
|
||||
sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
|
||||
$(Q)sed < $< > $@ 's/P(\([^,]*\),.*/#define \1 (\*\1_p)/'
|
||||
|
||||
# Extract gconf menu items for I18N support
|
||||
$(obj)/gconf.glade.h: $(obj)/gconf.glade
|
||||
intltool-extract --type=gettext/glade $(obj)/gconf.glade
|
||||
$(Q)intltool-extract --type=gettext/glade --srcdir=$(srctree) \
|
||||
$(obj)/gconf.glade
|
||||
|
||||
###
|
||||
# The following requires flex/bison/gperf
|
||||
|
||||
@@ -332,7 +332,7 @@ static int conf_choice(struct menu *menu)
|
||||
}
|
||||
if (!child)
|
||||
continue;
|
||||
if (line[strlen(line) - 1] == '?') {
|
||||
if (line[0] && line[strlen(line) - 1] == '?') {
|
||||
print_help(child);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -560,8 +560,6 @@ int conf_write(const char *name)
|
||||
const char *basename;
|
||||
const char *str;
|
||||
char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1];
|
||||
time_t now;
|
||||
int use_timestamp = 1;
|
||||
char *env;
|
||||
|
||||
dirname[0] = 0;
|
||||
@@ -598,19 +596,11 @@ int conf_write(const char *name)
|
||||
if (!out)
|
||||
return 1;
|
||||
|
||||
time(&now);
|
||||
env = getenv("KCONFIG_NOTIMESTAMP");
|
||||
if (env && *env)
|
||||
use_timestamp = 0;
|
||||
|
||||
fprintf(out, _("#\n"
|
||||
"# Automatically generated make config: don't edit\n"
|
||||
"# %s\n"
|
||||
"%s%s"
|
||||
"#\n"),
|
||||
rootmenu.prompt->text,
|
||||
use_timestamp ? "# " : "",
|
||||
use_timestamp ? ctime(&now) : "");
|
||||
rootmenu.prompt->text);
|
||||
|
||||
if (!conf_get_changed())
|
||||
sym_clear_all_valid();
|
||||
@@ -784,7 +774,6 @@ int conf_write_autoconf(void)
|
||||
const char *str;
|
||||
const char *name;
|
||||
FILE *out, *tristate, *out_h;
|
||||
time_t now;
|
||||
int i;
|
||||
|
||||
sym_clear_all_valid();
|
||||
@@ -811,22 +800,19 @@ int conf_write_autoconf(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
time(&now);
|
||||
fprintf(out, "#\n"
|
||||
"# Automatically generated make config: don't edit\n"
|
||||
"# %s\n"
|
||||
"# %s"
|
||||
"#\n",
|
||||
rootmenu.prompt->text, ctime(&now));
|
||||
rootmenu.prompt->text);
|
||||
fprintf(tristate, "#\n"
|
||||
"# Automatically generated - do not edit\n"
|
||||
"\n");
|
||||
fprintf(out_h, "/*\n"
|
||||
" * Automatically generated C config: don't edit\n"
|
||||
" * %s\n"
|
||||
" * %s"
|
||||
" */\n",
|
||||
rootmenu.prompt->text, ctime(&now));
|
||||
rootmenu.prompt->text);
|
||||
|
||||
for_all_symbols(i, sym) {
|
||||
sym_calc_value(sym);
|
||||
|
||||
@@ -20,12 +20,8 @@ struct file {
|
||||
struct file *parent;
|
||||
const char *name;
|
||||
int lineno;
|
||||
int flags;
|
||||
};
|
||||
|
||||
#define FILE_BUSY 0x0001
|
||||
#define FILE_SCANNED 0x0002
|
||||
|
||||
typedef enum tristate {
|
||||
no, mod, yes
|
||||
} tristate;
|
||||
|
||||
@@ -253,7 +253,7 @@ void init_left_tree(void)
|
||||
|
||||
gtk_tree_view_set_model(view, model1);
|
||||
gtk_tree_view_set_headers_visible(view, TRUE);
|
||||
gtk_tree_view_set_rules_hint(view, FALSE);
|
||||
gtk_tree_view_set_rules_hint(view, TRUE);
|
||||
|
||||
column = gtk_tree_view_column_new();
|
||||
gtk_tree_view_append_column(view, column);
|
||||
@@ -298,7 +298,7 @@ void init_right_tree(void)
|
||||
|
||||
gtk_tree_view_set_model(view, model2);
|
||||
gtk_tree_view_set_headers_visible(view, TRUE);
|
||||
gtk_tree_view_set_rules_hint(view, FALSE);
|
||||
gtk_tree_view_set_rules_hint(view, TRUE);
|
||||
|
||||
column = gtk_tree_view_column_new();
|
||||
gtk_tree_view_append_column(view, column);
|
||||
@@ -756,7 +756,6 @@ void on_load_clicked(GtkButton * button, gpointer user_data)
|
||||
void on_single_clicked(GtkButton * button, gpointer user_data)
|
||||
{
|
||||
view_mode = SINGLE_VIEW;
|
||||
gtk_paned_set_position(GTK_PANED(hpaned), 0);
|
||||
gtk_widget_hide(tree1_w);
|
||||
current = &rootmenu;
|
||||
display_tree_part();
|
||||
@@ -782,7 +781,6 @@ void on_split_clicked(GtkButton * button, gpointer user_data)
|
||||
void on_full_clicked(GtkButton * button, gpointer user_data)
|
||||
{
|
||||
view_mode = FULL_VIEW;
|
||||
gtk_paned_set_position(GTK_PANED(hpaned), 0);
|
||||
gtk_widget_hide(tree1_w);
|
||||
if (tree2)
|
||||
gtk_tree_store_clear(tree2);
|
||||
@@ -1444,6 +1442,12 @@ static void display_tree(struct menu *menu)
|
||||
if (((menu != &rootmenu) && !(menu->flags & MENU_ROOT))
|
||||
|| (view_mode == FULL_VIEW)
|
||||
|| (view_mode == SPLIT_VIEW))*/
|
||||
|
||||
/* Change paned position if the view is not in 'split mode' */
|
||||
if (view_mode == SINGLE_VIEW || view_mode == FULL_VIEW) {
|
||||
gtk_paned_set_position(GTK_PANED(hpaned), 0);
|
||||
}
|
||||
|
||||
if (((view_mode == SINGLE_VIEW) && (menu->flags & MENU_ROOT))
|
||||
|| (view_mode == FULL_VIEW)
|
||||
|| (view_mode == SPLIT_VIEW)) {
|
||||
|
||||
@@ -2363,11 +2363,11 @@ void zconf_initscan(const char *name)
|
||||
|
||||
current_file = file_lookup(name);
|
||||
current_file->lineno = 1;
|
||||
current_file->flags = FILE_BUSY;
|
||||
}
|
||||
|
||||
void zconf_nextfile(const char *name)
|
||||
{
|
||||
struct file *iter;
|
||||
struct file *file = file_lookup(name);
|
||||
struct buffer *buf = malloc(sizeof(*buf));
|
||||
memset(buf, 0, sizeof(*buf));
|
||||
@@ -2383,18 +2383,25 @@ void zconf_nextfile(const char *name)
|
||||
buf->parent = current_buf;
|
||||
current_buf = buf;
|
||||
|
||||
if (file->flags & FILE_BUSY) {
|
||||
printf("%s:%d: do not source '%s' from itself\n",
|
||||
zconf_curname(), zconf_lineno(), name);
|
||||
exit(1);
|
||||
for (iter = current_file->parent; iter; iter = iter->parent ) {
|
||||
if (!strcmp(current_file->name,iter->name) ) {
|
||||
printf("%s:%d: recursive inclusion detected. "
|
||||
"Inclusion path:\n current file : '%s'\n",
|
||||
zconf_curname(), zconf_lineno(),
|
||||
zconf_curname());
|
||||
iter = current_file->parent;
|
||||
while (iter && \
|
||||
strcmp(iter->name,current_file->name)) {
|
||||
printf(" included from: '%s:%d'\n",
|
||||
iter->name, iter->lineno-1);
|
||||
iter = iter->parent;
|
||||
}
|
||||
if (iter)
|
||||
printf(" included from: '%s:%d'\n",
|
||||
iter->name, iter->lineno+1);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (file->flags & FILE_SCANNED) {
|
||||
printf("%s:%d: file '%s' is already sourced from '%s'\n",
|
||||
zconf_curname(), zconf_lineno(), name,
|
||||
file->parent->name);
|
||||
exit(1);
|
||||
}
|
||||
file->flags |= FILE_BUSY;
|
||||
file->lineno = 1;
|
||||
file->parent = current_file;
|
||||
current_file = file;
|
||||
@@ -2404,8 +2411,6 @@ static void zconf_endfile(void)
|
||||
{
|
||||
struct buffer *parent;
|
||||
|
||||
current_file->flags |= FILE_SCANNED;
|
||||
current_file->flags &= ~FILE_BUSY;
|
||||
current_file = current_file->parent;
|
||||
|
||||
parent = current_buf->parent;
|
||||
|
||||
@@ -373,18 +373,18 @@ static void print_function_line(void)
|
||||
const int skip = 1;
|
||||
|
||||
for (i = 0; i < function_keys_num; i++) {
|
||||
wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
|
||||
(void) wattrset(main_window, attributes[FUNCTION_HIGHLIGHT]);
|
||||
mvwprintw(main_window, LINES-3, offset,
|
||||
"%s",
|
||||
function_keys[i].key_str);
|
||||
wattrset(main_window, attributes[FUNCTION_TEXT]);
|
||||
(void) wattrset(main_window, attributes[FUNCTION_TEXT]);
|
||||
offset += strlen(function_keys[i].key_str);
|
||||
mvwprintw(main_window, LINES-3,
|
||||
offset, "%s",
|
||||
function_keys[i].func);
|
||||
offset += strlen(function_keys[i].func) + skip;
|
||||
}
|
||||
wattrset(main_window, attributes[NORMAL]);
|
||||
(void) wattrset(main_window, attributes[NORMAL]);
|
||||
}
|
||||
|
||||
/* help */
|
||||
@@ -953,16 +953,16 @@ static void show_menu(const char *prompt, const char *instructions,
|
||||
current_instructions = instructions;
|
||||
|
||||
clear();
|
||||
wattrset(main_window, attributes[NORMAL]);
|
||||
(void) wattrset(main_window, attributes[NORMAL]);
|
||||
print_in_middle(stdscr, 1, 0, COLS,
|
||||
menu_backtitle,
|
||||
attributes[MAIN_HEADING]);
|
||||
|
||||
wattrset(main_window, attributes[MAIN_MENU_BOX]);
|
||||
(void) wattrset(main_window, attributes[MAIN_MENU_BOX]);
|
||||
box(main_window, 0, 0);
|
||||
wattrset(main_window, attributes[MAIN_MENU_HEADING]);
|
||||
(void) wattrset(main_window, attributes[MAIN_MENU_HEADING]);
|
||||
mvwprintw(main_window, 0, 3, " %s ", prompt);
|
||||
wattrset(main_window, attributes[NORMAL]);
|
||||
(void) wattrset(main_window, attributes[NORMAL]);
|
||||
|
||||
set_menu_items(curses_menu, curses_menu_items);
|
||||
|
||||
|
||||
@@ -1489,8 +1489,7 @@ void ConfigMainWindow::saveConfigAs(void)
|
||||
QString s = Q3FileDialog::getSaveFileName(conf_get_configname(), NULL, this);
|
||||
if (s.isNull())
|
||||
return;
|
||||
if (conf_write(QFile::encodeName(s)))
|
||||
QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
|
||||
saveConfig();
|
||||
}
|
||||
|
||||
void ConfigMainWindow::searchConfig(void)
|
||||
@@ -1643,7 +1642,7 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
|
||||
mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
|
||||
switch (mb.exec()) {
|
||||
case QMessageBox::Yes:
|
||||
conf_write(NULL);
|
||||
saveConfig();
|
||||
case QMessageBox::No:
|
||||
e->accept();
|
||||
break;
|
||||
|
||||
@@ -294,11 +294,11 @@ void zconf_initscan(const char *name)
|
||||
|
||||
current_file = file_lookup(name);
|
||||
current_file->lineno = 1;
|
||||
current_file->flags = FILE_BUSY;
|
||||
}
|
||||
|
||||
void zconf_nextfile(const char *name)
|
||||
{
|
||||
struct file *iter;
|
||||
struct file *file = file_lookup(name);
|
||||
struct buffer *buf = malloc(sizeof(*buf));
|
||||
memset(buf, 0, sizeof(*buf));
|
||||
@@ -314,18 +314,25 @@ void zconf_nextfile(const char *name)
|
||||
buf->parent = current_buf;
|
||||
current_buf = buf;
|
||||
|
||||
if (file->flags & FILE_BUSY) {
|
||||
printf("%s:%d: do not source '%s' from itself\n",
|
||||
zconf_curname(), zconf_lineno(), name);
|
||||
exit(1);
|
||||
for (iter = current_file->parent; iter; iter = iter->parent ) {
|
||||
if (!strcmp(current_file->name,iter->name) ) {
|
||||
printf("%s:%d: recursive inclusion detected. "
|
||||
"Inclusion path:\n current file : '%s'\n",
|
||||
zconf_curname(), zconf_lineno(),
|
||||
zconf_curname());
|
||||
iter = current_file->parent;
|
||||
while (iter && \
|
||||
strcmp(iter->name,current_file->name)) {
|
||||
printf(" included from: '%s:%d'\n",
|
||||
iter->name, iter->lineno-1);
|
||||
iter = iter->parent;
|
||||
}
|
||||
if (iter)
|
||||
printf(" included from: '%s:%d'\n",
|
||||
iter->name, iter->lineno+1);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (file->flags & FILE_SCANNED) {
|
||||
printf("%s:%d: file '%s' is already sourced from '%s'\n",
|
||||
zconf_curname(), zconf_lineno(), name,
|
||||
file->parent->name);
|
||||
exit(1);
|
||||
}
|
||||
file->flags |= FILE_BUSY;
|
||||
file->lineno = 1;
|
||||
file->parent = current_file;
|
||||
current_file = file;
|
||||
@@ -335,8 +342,6 @@ static void zconf_endfile(void)
|
||||
{
|
||||
struct buffer *parent;
|
||||
|
||||
current_file->flags |= FILE_SCANNED;
|
||||
current_file->flags &= ~FILE_BUSY;
|
||||
current_file = current_file->parent;
|
||||
|
||||
parent = current_buf->parent;
|
||||
|
||||
@@ -1705,7 +1705,7 @@ sub push_parameter($$$) {
|
||||
|
||||
$param = xml_escape($param);
|
||||
|
||||
# strip spaces from $param so that it is one continous string
|
||||
# strip spaces from $param so that it is one continuous string
|
||||
# on @parameterlist;
|
||||
# this fixes a problem where check_sections() cannot find
|
||||
# a parameter like "addr[6 + 2]" because it actually appears
|
||||
|
||||
@@ -702,6 +702,24 @@ static int do_ssb_entry(const char *filename,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Looks like: bcma:mNidNrevNclN. */
|
||||
static int do_bcma_entry(const char *filename,
|
||||
struct bcma_device_id *id, char *alias)
|
||||
{
|
||||
id->manuf = TO_NATIVE(id->manuf);
|
||||
id->id = TO_NATIVE(id->id);
|
||||
id->rev = TO_NATIVE(id->rev);
|
||||
id->class = TO_NATIVE(id->class);
|
||||
|
||||
strcpy(alias, "bcma:");
|
||||
ADD(alias, "m", id->manuf != BCMA_ANY_MANUF, id->manuf);
|
||||
ADD(alias, "id", id->id != BCMA_ANY_ID, id->id);
|
||||
ADD(alias, "rev", id->rev != BCMA_ANY_REV, id->rev);
|
||||
ADD(alias, "cl", id->class != BCMA_ANY_CLASS, id->class);
|
||||
add_wildcard(alias);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Looks like: virtio:dNvN */
|
||||
static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
|
||||
char *alias)
|
||||
@@ -968,6 +986,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
|
||||
do_table(symval, sym->st_size,
|
||||
sizeof(struct ssb_device_id), "ssb",
|
||||
do_ssb_entry, mod);
|
||||
else if (sym_is(symname, "__mod_bcma_device_table"))
|
||||
do_table(symval, sym->st_size,
|
||||
sizeof(struct bcma_device_id), "bcma",
|
||||
do_bcma_entry, mod);
|
||||
else if (sym_is(symname, "__mod_virtio_device_table"))
|
||||
do_table(symval, sym->st_size,
|
||||
sizeof(struct virtio_device_id), "virtio",
|
||||
|
||||
@@ -420,11 +420,10 @@ static int parse_elf(struct elf_info *info, const char *filename)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (hdr->e_shnum == 0) {
|
||||
if (hdr->e_shnum == SHN_UNDEF) {
|
||||
/*
|
||||
* There are more than 64k sections,
|
||||
* read count from .sh_size.
|
||||
* note: it doesn't need shndx2secindex()
|
||||
*/
|
||||
info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
|
||||
}
|
||||
@@ -432,8 +431,7 @@ static int parse_elf(struct elf_info *info, const char *filename)
|
||||
info->num_sections = hdr->e_shnum;
|
||||
}
|
||||
if (hdr->e_shstrndx == SHN_XINDEX) {
|
||||
info->secindex_strings =
|
||||
shndx2secindex(TO_NATIVE(sechdrs[0].sh_link));
|
||||
info->secindex_strings = TO_NATIVE(sechdrs[0].sh_link);
|
||||
}
|
||||
else {
|
||||
info->secindex_strings = hdr->e_shstrndx;
|
||||
@@ -489,7 +487,7 @@ static int parse_elf(struct elf_info *info, const char *filename)
|
||||
sechdrs[i].sh_offset;
|
||||
info->symtab_stop = (void *)hdr +
|
||||
sechdrs[i].sh_offset + sechdrs[i].sh_size;
|
||||
sh_link_idx = shndx2secindex(sechdrs[i].sh_link);
|
||||
sh_link_idx = sechdrs[i].sh_link;
|
||||
info->strtab = (void *)hdr +
|
||||
sechdrs[sh_link_idx].sh_offset;
|
||||
}
|
||||
@@ -516,11 +514,9 @@ static int parse_elf(struct elf_info *info, const char *filename)
|
||||
|
||||
if (symtab_shndx_idx != ~0U) {
|
||||
Elf32_Word *p;
|
||||
if (symtab_idx !=
|
||||
shndx2secindex(sechdrs[symtab_shndx_idx].sh_link))
|
||||
if (symtab_idx != sechdrs[symtab_shndx_idx].sh_link)
|
||||
fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
|
||||
filename,
|
||||
shndx2secindex(sechdrs[symtab_shndx_idx].sh_link),
|
||||
filename, sechdrs[symtab_shndx_idx].sh_link,
|
||||
symtab_idx);
|
||||
/* Fix endianness */
|
||||
for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
|
||||
@@ -1446,7 +1442,7 @@ static unsigned int *reloc_location(struct elf_info *elf,
|
||||
Elf_Shdr *sechdr, Elf_Rela *r)
|
||||
{
|
||||
Elf_Shdr *sechdrs = elf->sechdrs;
|
||||
int section = shndx2secindex(sechdr->sh_info);
|
||||
int section = sechdr->sh_info;
|
||||
|
||||
return (void *)elf->hdr + sechdrs[section].sh_offset +
|
||||
r->r_offset;
|
||||
|
||||
@@ -145,33 +145,22 @@ static inline int is_shndx_special(unsigned int i)
|
||||
return i != SHN_XINDEX && i >= SHN_LORESERVE && i <= SHN_HIRESERVE;
|
||||
}
|
||||
|
||||
/* shndx is in [0..SHN_LORESERVE) U (SHN_HIRESERVE, 0xfffffff], thus:
|
||||
* shndx == 0 <=> sechdrs[0]
|
||||
* ......
|
||||
* shndx == SHN_LORESERVE-1 <=> sechdrs[SHN_LORESERVE-1]
|
||||
* shndx == SHN_HIRESERVE+1 <=> sechdrs[SHN_LORESERVE]
|
||||
* shndx == SHN_HIRESERVE+2 <=> sechdrs[SHN_LORESERVE+1]
|
||||
* ......
|
||||
* fyi: sym->st_shndx is uint16, SHN_LORESERVE = ff00, SHN_HIRESERVE = ffff,
|
||||
* so basically we map 0000..feff -> 0000..feff
|
||||
* ff00..ffff -> (you are a bad boy, dont do it)
|
||||
* 10000..xxxx -> ff00..(xxxx-0x100)
|
||||
/*
|
||||
* Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
|
||||
* the way to -256..-1, to avoid conflicting with real section
|
||||
* indices.
|
||||
*/
|
||||
static inline unsigned int shndx2secindex(unsigned int i)
|
||||
{
|
||||
if (i <= SHN_HIRESERVE)
|
||||
return i;
|
||||
return i - (SHN_HIRESERVE + 1 - SHN_LORESERVE);
|
||||
}
|
||||
#define SPECIAL(i) ((i) - (SHN_HIRESERVE + 1))
|
||||
|
||||
/* Accessor for sym->st_shndx, hides ugliness of "64k sections" */
|
||||
static inline unsigned int get_secindex(const struct elf_info *info,
|
||||
const Elf_Sym *sym)
|
||||
{
|
||||
if (is_shndx_special(sym->st_shndx))
|
||||
return SPECIAL(sym->st_shndx);
|
||||
if (sym->st_shndx != SHN_XINDEX)
|
||||
return sym->st_shndx;
|
||||
return shndx2secindex(info->symtab_shndx_start[sym -
|
||||
info->symtab_start]);
|
||||
return info->symtab_shndx_start[sym - info->symtab_start];
|
||||
}
|
||||
|
||||
/* file2alias.c */
|
||||
|
||||
@@ -5,4 +5,15 @@
|
||||
*/
|
||||
SECTIONS {
|
||||
/DISCARD/ : { *(.discard) }
|
||||
|
||||
__ksymtab : { *(SORT(___ksymtab+*)) }
|
||||
__ksymtab_gpl : { *(SORT(___ksymtab_gpl+*)) }
|
||||
__ksymtab_unused : { *(SORT(___ksymtab_unused+*)) }
|
||||
__ksymtab_unused_gpl : { *(SORT(___ksymtab_unused_gpl+*)) }
|
||||
__ksymtab_gpl_future : { *(SORT(___ksymtab_gpl_future+*)) }
|
||||
__kcrctab : { *(SORT(___kcrctab+*)) }
|
||||
__kcrctab_gpl : { *(SORT(___kcrctab_gpl+*)) }
|
||||
__kcrctab_unused : { *(SORT(___kcrctab_unused+*)) }
|
||||
__kcrctab_unused_gpl : { *(SORT(___kcrctab_unused_gpl+*)) }
|
||||
__kcrctab_gpl_future : { *(SORT(___kcrctab_gpl_future+*)) }
|
||||
}
|
||||
|
||||
@@ -26,9 +26,9 @@ RPM := $(shell if [ -x "/usr/bin/rpmbuild" ]; then echo rpmbuild; \
|
||||
else echo rpm; fi)
|
||||
|
||||
# Remove hyphens since they have special meaning in RPM filenames
|
||||
KERNELPATH := kernel-$(subst -,,$(KERNELRELEASE))
|
||||
KERNELPATH := kernel-$(subst -,_,$(KERNELRELEASE))
|
||||
MKSPEC := $(srctree)/scripts/package/mkspec
|
||||
PREV := set -e; cd ..;
|
||||
PREV := set -e; cd -P ..;
|
||||
|
||||
# rpm-pkg
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@@ -92,7 +92,7 @@ case "${ARCH}" in
|
||||
echo "" >&2
|
||||
echo '** ** ** WARNING ** ** **' >&2
|
||||
echo "" >&2
|
||||
echo "Your architecture did not define any architecture-dependant files" >&2
|
||||
echo "Your architecture did not define any architecture-dependent files" >&2
|
||||
echo "to be placed into the tarball. Please add those to ${0} ..." >&2
|
||||
echo "" >&2
|
||||
sleep 5
|
||||
|
||||
@@ -22,7 +22,7 @@ if [ "`grep CONFIG_DRM=y .config | cut -f2 -d\=`" = "y" ]; then
|
||||
fi
|
||||
|
||||
PROVIDES="$PROVIDES kernel-$KERNELRELEASE"
|
||||
__KERNELRELEASE=`echo $KERNELRELEASE | sed -e "s/-//g"`
|
||||
__KERNELRELEASE=`echo $KERNELRELEASE | sed -e "s/-/_/g"`
|
||||
|
||||
echo "Name: kernel"
|
||||
echo "Summary: The Linux Kernel"
|
||||
@@ -47,6 +47,18 @@ echo ""
|
||||
echo "%description"
|
||||
echo "The Linux Kernel, the operating system core itself"
|
||||
echo ""
|
||||
echo "%package headers"
|
||||
echo "Summary: Header files for the Linux kernel for use by glibc"
|
||||
echo "Group: Development/System"
|
||||
echo "Obsoletes: kernel-headers"
|
||||
echo "Provides: kernel-headers = %{version}"
|
||||
echo "%description headers"
|
||||
echo "Kernel-headers includes the C header files that specify the interface"
|
||||
echo "between the Linux kernel and userspace libraries and programs. The"
|
||||
echo "header files define structures and constants that are needed for"
|
||||
echo "building most standard programs and are also needed for rebuilding the"
|
||||
echo "glibc package."
|
||||
echo ""
|
||||
|
||||
if ! $PREBUILT; then
|
||||
echo "%prep"
|
||||
@@ -83,6 +95,7 @@ echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/vmlinuz-$KERNELRELEASE"
|
||||
echo "%endif"
|
||||
echo "%endif"
|
||||
|
||||
echo 'make %{?_smp_mflags} INSTALL_HDR_PATH=$RPM_BUILD_ROOT/usr headers_install'
|
||||
echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$KERNELRELEASE"
|
||||
|
||||
echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$KERNELRELEASE"
|
||||
@@ -105,3 +118,7 @@ echo "/lib/modules/$KERNELRELEASE"
|
||||
echo "/lib/firmware"
|
||||
echo "/boot/*"
|
||||
echo ""
|
||||
echo "%files headers"
|
||||
echo '%defattr (-, root, root)'
|
||||
echo "/usr/include"
|
||||
echo ""
|
||||
|
||||
@@ -250,7 +250,7 @@ while : # incrementing SUBLEVEL (s in v.p.s)
|
||||
do
|
||||
CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL"
|
||||
EXTRAVER=
|
||||
if [ $STOPFULLVERSION = $CURRENTFULLVERSION ]; then
|
||||
if [ x$STOPFULLVERSION = x$CURRENTFULLVERSION ]; then
|
||||
echo "Stopping at $CURRENTFULLVERSION base as requested."
|
||||
break
|
||||
fi
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <getopt.h>
|
||||
#include <elf.h>
|
||||
#include <fcntl.h>
|
||||
#include <setjmp.h>
|
||||
@@ -39,6 +40,7 @@ static char gpfx; /* prefix for global symbol name (sometimes '_') */
|
||||
static struct stat sb; /* Remember .st_size, etc. */
|
||||
static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */
|
||||
static const char *altmcount; /* alternate mcount symbol name */
|
||||
static int warn_on_notrace_sect; /* warn when section has mcount not being recorded */
|
||||
|
||||
/* setjmp() return values */
|
||||
enum {
|
||||
@@ -78,7 +80,7 @@ static off_t
|
||||
ulseek(int const fd, off_t const offset, int const whence)
|
||||
{
|
||||
off_t const w = lseek(fd, offset, whence);
|
||||
if ((off_t)-1 == w) {
|
||||
if (w == (off_t)-1) {
|
||||
perror("lseek");
|
||||
fail_file();
|
||||
}
|
||||
@@ -111,13 +113,41 @@ static void *
|
||||
umalloc(size_t size)
|
||||
{
|
||||
void *const addr = malloc(size);
|
||||
if (0 == addr) {
|
||||
if (addr == 0) {
|
||||
fprintf(stderr, "malloc failed: %zu bytes\n", size);
|
||||
fail_file();
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
||||
static unsigned char ideal_nop5_x86_64[5] = { 0x0f, 0x1f, 0x44, 0x00, 0x00 };
|
||||
static unsigned char ideal_nop5_x86_32[5] = { 0x3e, 0x8d, 0x74, 0x26, 0x00 };
|
||||
static unsigned char *ideal_nop;
|
||||
|
||||
static char rel_type_nop;
|
||||
|
||||
static int (*make_nop)(void *map, size_t const offset);
|
||||
|
||||
static int make_nop_x86(void *map, size_t const offset)
|
||||
{
|
||||
uint32_t *ptr;
|
||||
unsigned char *op;
|
||||
|
||||
/* Confirm we have 0xe8 0x0 0x0 0x0 0x0 */
|
||||
ptr = map + offset;
|
||||
if (*ptr != 0)
|
||||
return -1;
|
||||
|
||||
op = map + offset - 1;
|
||||
if (*op != 0xe8)
|
||||
return -1;
|
||||
|
||||
/* convert to nop */
|
||||
ulseek(fd_map, offset - 1, SEEK_SET);
|
||||
uwrite(fd_map, ideal_nop, 5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the whole file as a programming convenience in order to avoid
|
||||
* malloc+lseek+read+free of many pieces. If successful, then mmap
|
||||
@@ -136,7 +166,7 @@ static void *mmap_file(char const *fname)
|
||||
void *addr;
|
||||
|
||||
fd_map = open(fname, O_RDWR);
|
||||
if (0 > fd_map || 0 > fstat(fd_map, &sb)) {
|
||||
if (fd_map < 0 || fstat(fd_map, &sb) < 0) {
|
||||
perror(fname);
|
||||
fail_file();
|
||||
}
|
||||
@@ -147,7 +177,7 @@ static void *mmap_file(char const *fname)
|
||||
addr = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE,
|
||||
fd_map, 0);
|
||||
mmap_failed = 0;
|
||||
if (MAP_FAILED == addr) {
|
||||
if (addr == MAP_FAILED) {
|
||||
mmap_failed = 1;
|
||||
addr = umalloc(sb.st_size);
|
||||
uread(fd_map, addr, sb.st_size);
|
||||
@@ -206,12 +236,13 @@ static uint32_t (*w2)(uint16_t);
|
||||
static int
|
||||
is_mcounted_section_name(char const *const txtname)
|
||||
{
|
||||
return 0 == strcmp(".text", txtname) ||
|
||||
0 == strcmp(".ref.text", txtname) ||
|
||||
0 == strcmp(".sched.text", txtname) ||
|
||||
0 == strcmp(".spinlock.text", txtname) ||
|
||||
0 == strcmp(".irqentry.text", txtname) ||
|
||||
0 == strcmp(".text.unlikely", txtname);
|
||||
return strcmp(".text", txtname) == 0 ||
|
||||
strcmp(".ref.text", txtname) == 0 ||
|
||||
strcmp(".sched.text", txtname) == 0 ||
|
||||
strcmp(".spinlock.text", txtname) == 0 ||
|
||||
strcmp(".irqentry.text", txtname) == 0 ||
|
||||
strcmp(".kprobes.text", txtname) == 0 ||
|
||||
strcmp(".text.unlikely", txtname) == 0;
|
||||
}
|
||||
|
||||
/* 32 bit and 64 bit are very similar */
|
||||
@@ -264,43 +295,48 @@ do_file(char const *const fname)
|
||||
w8 = w8nat;
|
||||
switch (ehdr->e_ident[EI_DATA]) {
|
||||
static unsigned int const endian = 1;
|
||||
default: {
|
||||
default:
|
||||
fprintf(stderr, "unrecognized ELF data encoding %d: %s\n",
|
||||
ehdr->e_ident[EI_DATA], fname);
|
||||
fail_file();
|
||||
} break;
|
||||
case ELFDATA2LSB: {
|
||||
if (1 != *(unsigned char const *)&endian) {
|
||||
break;
|
||||
case ELFDATA2LSB:
|
||||
if (*(unsigned char const *)&endian != 1) {
|
||||
/* main() is big endian, file.o is little endian. */
|
||||
w = w4rev;
|
||||
w2 = w2rev;
|
||||
w8 = w8rev;
|
||||
}
|
||||
} break;
|
||||
case ELFDATA2MSB: {
|
||||
if (0 != *(unsigned char const *)&endian) {
|
||||
break;
|
||||
case ELFDATA2MSB:
|
||||
if (*(unsigned char const *)&endian != 0) {
|
||||
/* main() is little endian, file.o is big endian. */
|
||||
w = w4rev;
|
||||
w2 = w2rev;
|
||||
w8 = w8rev;
|
||||
}
|
||||
} break;
|
||||
break;
|
||||
} /* end switch */
|
||||
if (0 != memcmp(ELFMAG, ehdr->e_ident, SELFMAG)
|
||||
|| ET_REL != w2(ehdr->e_type)
|
||||
|| EV_CURRENT != ehdr->e_ident[EI_VERSION]) {
|
||||
if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0
|
||||
|| w2(ehdr->e_type) != ET_REL
|
||||
|| ehdr->e_ident[EI_VERSION] != EV_CURRENT) {
|
||||
fprintf(stderr, "unrecognized ET_REL file %s\n", fname);
|
||||
fail_file();
|
||||
}
|
||||
|
||||
gpfx = 0;
|
||||
switch (w2(ehdr->e_machine)) {
|
||||
default: {
|
||||
default:
|
||||
fprintf(stderr, "unrecognized e_machine %d %s\n",
|
||||
w2(ehdr->e_machine), fname);
|
||||
fail_file();
|
||||
} break;
|
||||
case EM_386: reltype = R_386_32; break;
|
||||
break;
|
||||
case EM_386:
|
||||
reltype = R_386_32;
|
||||
make_nop = make_nop_x86;
|
||||
ideal_nop = ideal_nop5_x86_32;
|
||||
mcount_adjust_32 = -1;
|
||||
break;
|
||||
case EM_ARM: reltype = R_ARM_ABS32;
|
||||
altmcount = "__gnu_mcount_nc";
|
||||
break;
|
||||
@@ -311,67 +347,91 @@ do_file(char const *const fname)
|
||||
case EM_S390: /* reltype: e_class */ gpfx = '_'; break;
|
||||
case EM_SH: reltype = R_SH_DIR32; break;
|
||||
case EM_SPARCV9: reltype = R_SPARC_64; gpfx = '_'; break;
|
||||
case EM_X86_64: reltype = R_X86_64_64; break;
|
||||
case EM_X86_64:
|
||||
make_nop = make_nop_x86;
|
||||
ideal_nop = ideal_nop5_x86_64;
|
||||
reltype = R_X86_64_64;
|
||||
mcount_adjust_64 = -1;
|
||||
break;
|
||||
} /* end switch */
|
||||
|
||||
switch (ehdr->e_ident[EI_CLASS]) {
|
||||
default: {
|
||||
default:
|
||||
fprintf(stderr, "unrecognized ELF class %d %s\n",
|
||||
ehdr->e_ident[EI_CLASS], fname);
|
||||
fail_file();
|
||||
} break;
|
||||
case ELFCLASS32: {
|
||||
if (sizeof(Elf32_Ehdr) != w2(ehdr->e_ehsize)
|
||||
|| sizeof(Elf32_Shdr) != w2(ehdr->e_shentsize)) {
|
||||
break;
|
||||
case ELFCLASS32:
|
||||
if (w2(ehdr->e_ehsize) != sizeof(Elf32_Ehdr)
|
||||
|| w2(ehdr->e_shentsize) != sizeof(Elf32_Shdr)) {
|
||||
fprintf(stderr,
|
||||
"unrecognized ET_REL file: %s\n", fname);
|
||||
fail_file();
|
||||
}
|
||||
if (EM_S390 == w2(ehdr->e_machine))
|
||||
if (w2(ehdr->e_machine) == EM_S390) {
|
||||
reltype = R_390_32;
|
||||
if (EM_MIPS == w2(ehdr->e_machine)) {
|
||||
mcount_adjust_32 = -4;
|
||||
}
|
||||
if (w2(ehdr->e_machine) == EM_MIPS) {
|
||||
reltype = R_MIPS_32;
|
||||
is_fake_mcount32 = MIPS32_is_fake_mcount;
|
||||
}
|
||||
do32(ehdr, fname, reltype);
|
||||
} break;
|
||||
break;
|
||||
case ELFCLASS64: {
|
||||
Elf64_Ehdr *const ghdr = (Elf64_Ehdr *)ehdr;
|
||||
if (sizeof(Elf64_Ehdr) != w2(ghdr->e_ehsize)
|
||||
|| sizeof(Elf64_Shdr) != w2(ghdr->e_shentsize)) {
|
||||
if (w2(ghdr->e_ehsize) != sizeof(Elf64_Ehdr)
|
||||
|| w2(ghdr->e_shentsize) != sizeof(Elf64_Shdr)) {
|
||||
fprintf(stderr,
|
||||
"unrecognized ET_REL file: %s\n", fname);
|
||||
fail_file();
|
||||
}
|
||||
if (EM_S390 == w2(ghdr->e_machine))
|
||||
if (w2(ghdr->e_machine) == EM_S390) {
|
||||
reltype = R_390_64;
|
||||
if (EM_MIPS == w2(ghdr->e_machine)) {
|
||||
mcount_adjust_64 = -8;
|
||||
}
|
||||
if (w2(ghdr->e_machine) == EM_MIPS) {
|
||||
reltype = R_MIPS_64;
|
||||
Elf64_r_sym = MIPS64_r_sym;
|
||||
Elf64_r_info = MIPS64_r_info;
|
||||
is_fake_mcount64 = MIPS64_is_fake_mcount;
|
||||
}
|
||||
do64(ghdr, fname, reltype);
|
||||
} break;
|
||||
break;
|
||||
}
|
||||
} /* end switch */
|
||||
|
||||
cleanup();
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char const *argv[])
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
const char ftrace[] = "/ftrace.o";
|
||||
int ftrace_size = sizeof(ftrace) - 1;
|
||||
int n_error = 0; /* gcc-4.3.0 false positive complaint */
|
||||
int c;
|
||||
int i;
|
||||
|
||||
if (argc <= 1) {
|
||||
fprintf(stderr, "usage: recordmcount file.o...\n");
|
||||
while ((c = getopt(argc, argv, "w")) >= 0) {
|
||||
switch (c) {
|
||||
case 'w':
|
||||
warn_on_notrace_sect = 1;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "usage: recordmcount [-w] file.o...\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ((argc - optind) < 1) {
|
||||
fprintf(stderr, "usage: recordmcount [-w] file.o...\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Process each file in turn, allowing deep failure. */
|
||||
for (--argc, ++argv; 0 < argc; --argc, ++argv) {
|
||||
for (i = optind; i < argc; i++) {
|
||||
char *file = argv[i];
|
||||
int const sjval = setjmp(jmpenv);
|
||||
int len;
|
||||
|
||||
@@ -380,29 +440,29 @@ main(int argc, char const *argv[])
|
||||
* function but does not call it. Since ftrace.o should
|
||||
* not be traced anyway, we just skip it.
|
||||
*/
|
||||
len = strlen(argv[0]);
|
||||
len = strlen(file);
|
||||
if (len >= ftrace_size &&
|
||||
strcmp(argv[0] + (len - ftrace_size), ftrace) == 0)
|
||||
strcmp(file + (len - ftrace_size), ftrace) == 0)
|
||||
continue;
|
||||
|
||||
switch (sjval) {
|
||||
default: {
|
||||
fprintf(stderr, "internal error: %s\n", argv[0]);
|
||||
default:
|
||||
fprintf(stderr, "internal error: %s\n", file);
|
||||
exit(1);
|
||||
} break;
|
||||
case SJ_SETJMP: { /* normal sequence */
|
||||
break;
|
||||
case SJ_SETJMP: /* normal sequence */
|
||||
/* Avoid problems if early cleanup() */
|
||||
fd_map = -1;
|
||||
ehdr_curr = NULL;
|
||||
mmap_failed = 1;
|
||||
do_file(argv[0]);
|
||||
} break;
|
||||
case SJ_FAIL: { /* error in do_file or below */
|
||||
do_file(file);
|
||||
break;
|
||||
case SJ_FAIL: /* error in do_file or below */
|
||||
++n_error;
|
||||
} break;
|
||||
case SJ_SUCCEED: { /* premature success */
|
||||
break;
|
||||
case SJ_SUCCEED: /* premature success */
|
||||
/* do nothing */
|
||||
} break;
|
||||
break;
|
||||
} /* end switch */
|
||||
}
|
||||
return !!n_error;
|
||||
|
||||
@@ -22,11 +22,15 @@
|
||||
#undef is_fake_mcount
|
||||
#undef fn_is_fake_mcount
|
||||
#undef MIPS_is_fake_mcount
|
||||
#undef mcount_adjust
|
||||
#undef sift_rel_mcount
|
||||
#undef nop_mcount
|
||||
#undef find_secsym_ndx
|
||||
#undef __has_rel_mcount
|
||||
#undef has_rel_mcount
|
||||
#undef tot_relsize
|
||||
#undef get_mcountsym
|
||||
#undef get_sym_str_and_relp
|
||||
#undef do_func
|
||||
#undef Elf_Addr
|
||||
#undef Elf_Ehdr
|
||||
@@ -39,6 +43,7 @@
|
||||
#undef ELF_R_INFO
|
||||
#undef Elf_r_info
|
||||
#undef ELF_ST_BIND
|
||||
#undef ELF_ST_TYPE
|
||||
#undef fn_ELF_R_SYM
|
||||
#undef fn_ELF_R_INFO
|
||||
#undef uint_t
|
||||
@@ -49,14 +54,18 @@
|
||||
#ifdef RECORD_MCOUNT_64
|
||||
# define append_func append64
|
||||
# define sift_rel_mcount sift64_rel_mcount
|
||||
# define nop_mcount nop_mcount_64
|
||||
# define find_secsym_ndx find64_secsym_ndx
|
||||
# define __has_rel_mcount __has64_rel_mcount
|
||||
# define has_rel_mcount has64_rel_mcount
|
||||
# define tot_relsize tot64_relsize
|
||||
# define get_sym_str_and_relp get_sym_str_and_relp_64
|
||||
# define do_func do64
|
||||
# define get_mcountsym get_mcountsym_64
|
||||
# define is_fake_mcount is_fake_mcount64
|
||||
# define fn_is_fake_mcount fn_is_fake_mcount64
|
||||
# define MIPS_is_fake_mcount MIPS64_is_fake_mcount
|
||||
# define mcount_adjust mcount_adjust_64
|
||||
# define Elf_Addr Elf64_Addr
|
||||
# define Elf_Ehdr Elf64_Ehdr
|
||||
# define Elf_Shdr Elf64_Shdr
|
||||
@@ -68,6 +77,7 @@
|
||||
# define ELF_R_INFO ELF64_R_INFO
|
||||
# define Elf_r_info Elf64_r_info
|
||||
# define ELF_ST_BIND ELF64_ST_BIND
|
||||
# define ELF_ST_TYPE ELF64_ST_TYPE
|
||||
# define fn_ELF_R_SYM fn_ELF64_R_SYM
|
||||
# define fn_ELF_R_INFO fn_ELF64_R_INFO
|
||||
# define uint_t uint64_t
|
||||
@@ -77,14 +87,18 @@
|
||||
#else
|
||||
# define append_func append32
|
||||
# define sift_rel_mcount sift32_rel_mcount
|
||||
# define nop_mcount nop_mcount_32
|
||||
# define find_secsym_ndx find32_secsym_ndx
|
||||
# define __has_rel_mcount __has32_rel_mcount
|
||||
# define has_rel_mcount has32_rel_mcount
|
||||
# define tot_relsize tot32_relsize
|
||||
# define get_sym_str_and_relp get_sym_str_and_relp_32
|
||||
# define do_func do32
|
||||
# define get_mcountsym get_mcountsym_32
|
||||
# define is_fake_mcount is_fake_mcount32
|
||||
# define fn_is_fake_mcount fn_is_fake_mcount32
|
||||
# define MIPS_is_fake_mcount MIPS32_is_fake_mcount
|
||||
# define mcount_adjust mcount_adjust_32
|
||||
# define Elf_Addr Elf32_Addr
|
||||
# define Elf_Ehdr Elf32_Ehdr
|
||||
# define Elf_Shdr Elf32_Shdr
|
||||
@@ -96,6 +110,7 @@
|
||||
# define ELF_R_INFO ELF32_R_INFO
|
||||
# define Elf_r_info Elf32_r_info
|
||||
# define ELF_ST_BIND ELF32_ST_BIND
|
||||
# define ELF_ST_TYPE ELF32_ST_TYPE
|
||||
# define fn_ELF_R_SYM fn_ELF32_R_SYM
|
||||
# define fn_ELF_R_INFO fn_ELF32_R_INFO
|
||||
# define uint_t uint32_t
|
||||
@@ -123,6 +138,8 @@ static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type)
|
||||
}
|
||||
static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO;
|
||||
|
||||
static int mcount_adjust = 0;
|
||||
|
||||
/*
|
||||
* MIPS mcount long call has 2 _mcount symbols, only the position of the 1st
|
||||
* _mcount symbol is needed for dynamic function tracer, with it, to disable
|
||||
@@ -234,6 +251,49 @@ static void append_func(Elf_Ehdr *const ehdr,
|
||||
uwrite(fd_map, ehdr, sizeof(*ehdr));
|
||||
}
|
||||
|
||||
static unsigned get_mcountsym(Elf_Sym const *const sym0,
|
||||
Elf_Rel const *relp,
|
||||
char const *const str0)
|
||||
{
|
||||
unsigned mcountsym = 0;
|
||||
|
||||
Elf_Sym const *const symp =
|
||||
&sym0[Elf_r_sym(relp)];
|
||||
char const *symname = &str0[w(symp->st_name)];
|
||||
char const *mcount = gpfx == '_' ? "_mcount" : "mcount";
|
||||
|
||||
if (symname[0] == '.')
|
||||
++symname; /* ppc64 hack */
|
||||
if (strcmp(mcount, symname) == 0 ||
|
||||
(altmcount && strcmp(altmcount, symname) == 0))
|
||||
mcountsym = Elf_r_sym(relp);
|
||||
|
||||
return mcountsym;
|
||||
}
|
||||
|
||||
static void get_sym_str_and_relp(Elf_Shdr const *const relhdr,
|
||||
Elf_Ehdr const *const ehdr,
|
||||
Elf_Sym const **sym0,
|
||||
char const **str0,
|
||||
Elf_Rel const **relp)
|
||||
{
|
||||
Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
|
||||
+ (void *)ehdr);
|
||||
unsigned const symsec_sh_link = w(relhdr->sh_link);
|
||||
Elf_Shdr const *const symsec = &shdr0[symsec_sh_link];
|
||||
Elf_Shdr const *const strsec = &shdr0[w(symsec->sh_link)];
|
||||
Elf_Rel const *const rel0 = (Elf_Rel const *)(_w(relhdr->sh_offset)
|
||||
+ (void *)ehdr);
|
||||
|
||||
*sym0 = (Elf_Sym const *)(_w(symsec->sh_offset)
|
||||
+ (void *)ehdr);
|
||||
|
||||
*str0 = (char const *)(_w(strsec->sh_offset)
|
||||
+ (void *)ehdr);
|
||||
|
||||
*relp = rel0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look at the relocations in order to find the calls to mcount.
|
||||
* Accumulate the section offsets that are found, and their relocation info,
|
||||
@@ -250,47 +310,27 @@ static uint_t *sift_rel_mcount(uint_t *mlocp,
|
||||
{
|
||||
uint_t *const mloc0 = mlocp;
|
||||
Elf_Rel *mrelp = *mrelpp;
|
||||
Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
|
||||
+ (void *)ehdr);
|
||||
unsigned const symsec_sh_link = w(relhdr->sh_link);
|
||||
Elf_Shdr const *const symsec = &shdr0[symsec_sh_link];
|
||||
Elf_Sym const *const sym0 = (Elf_Sym const *)(_w(symsec->sh_offset)
|
||||
+ (void *)ehdr);
|
||||
|
||||
Elf_Shdr const *const strsec = &shdr0[w(symsec->sh_link)];
|
||||
char const *const str0 = (char const *)(_w(strsec->sh_offset)
|
||||
+ (void *)ehdr);
|
||||
|
||||
Elf_Rel const *const rel0 = (Elf_Rel const *)(_w(relhdr->sh_offset)
|
||||
+ (void *)ehdr);
|
||||
Elf_Sym const *sym0;
|
||||
char const *str0;
|
||||
Elf_Rel const *relp;
|
||||
unsigned rel_entsize = _w(relhdr->sh_entsize);
|
||||
unsigned const nrel = _w(relhdr->sh_size) / rel_entsize;
|
||||
Elf_Rel const *relp = rel0;
|
||||
|
||||
unsigned mcountsym = 0;
|
||||
unsigned t;
|
||||
|
||||
for (t = nrel; t; --t) {
|
||||
if (!mcountsym) {
|
||||
Elf_Sym const *const symp =
|
||||
&sym0[Elf_r_sym(relp)];
|
||||
char const *symname = &str0[w(symp->st_name)];
|
||||
char const *mcount = '_' == gpfx ? "_mcount" : "mcount";
|
||||
get_sym_str_and_relp(relhdr, ehdr, &sym0, &str0, &relp);
|
||||
|
||||
if ('.' == symname[0])
|
||||
++symname; /* ppc64 hack */
|
||||
if (0 == strcmp(mcount, symname) ||
|
||||
(altmcount && 0 == strcmp(altmcount, symname)))
|
||||
mcountsym = Elf_r_sym(relp);
|
||||
}
|
||||
for (t = nrel; t; --t) {
|
||||
if (!mcountsym)
|
||||
mcountsym = get_mcountsym(sym0, relp, str0);
|
||||
|
||||
if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) {
|
||||
uint_t const addend = _w(_w(relp->r_offset) - recval);
|
||||
|
||||
uint_t const addend =
|
||||
_w(_w(relp->r_offset) - recval + mcount_adjust);
|
||||
mrelp->r_offset = _w(offbase
|
||||
+ ((void *)mlocp - (void *)mloc0));
|
||||
Elf_r_info(mrelp, recsym, reltype);
|
||||
if (sizeof(Elf_Rela) == rel_entsize) {
|
||||
if (rel_entsize == sizeof(Elf_Rela)) {
|
||||
((Elf_Rela *)mrelp)->r_addend = addend;
|
||||
*mlocp++ = 0;
|
||||
} else
|
||||
@@ -304,6 +344,63 @@ static uint_t *sift_rel_mcount(uint_t *mlocp,
|
||||
return mlocp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the relocation table again, but this time its called on sections
|
||||
* that are not going to be traced. The mcount calls here will be converted
|
||||
* into nops.
|
||||
*/
|
||||
static void nop_mcount(Elf_Shdr const *const relhdr,
|
||||
Elf_Ehdr const *const ehdr,
|
||||
const char *const txtname)
|
||||
{
|
||||
Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff)
|
||||
+ (void *)ehdr);
|
||||
Elf_Sym const *sym0;
|
||||
char const *str0;
|
||||
Elf_Rel const *relp;
|
||||
Elf_Shdr const *const shdr = &shdr0[w(relhdr->sh_info)];
|
||||
unsigned rel_entsize = _w(relhdr->sh_entsize);
|
||||
unsigned const nrel = _w(relhdr->sh_size) / rel_entsize;
|
||||
unsigned mcountsym = 0;
|
||||
unsigned t;
|
||||
int once = 0;
|
||||
|
||||
get_sym_str_and_relp(relhdr, ehdr, &sym0, &str0, &relp);
|
||||
|
||||
for (t = nrel; t; --t) {
|
||||
int ret = -1;
|
||||
|
||||
if (!mcountsym)
|
||||
mcountsym = get_mcountsym(sym0, relp, str0);
|
||||
|
||||
if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) {
|
||||
if (make_nop)
|
||||
ret = make_nop((void *)ehdr, shdr->sh_offset + relp->r_offset);
|
||||
if (warn_on_notrace_sect && !once) {
|
||||
printf("Section %s has mcount callers being ignored\n",
|
||||
txtname);
|
||||
once = 1;
|
||||
/* just warn? */
|
||||
if (!make_nop)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we successfully removed the mcount, mark the relocation
|
||||
* as a nop (don't do anything with it).
|
||||
*/
|
||||
if (!ret) {
|
||||
Elf_Rel rel;
|
||||
rel = *(Elf_Rel *)relp;
|
||||
Elf_r_info(&rel, Elf_r_sym(relp), rel_type_nop);
|
||||
ulseek(fd_map, (void *)relp - (void *)ehdr, SEEK_SET);
|
||||
uwrite(fd_map, &rel, sizeof(rel));
|
||||
}
|
||||
relp = (Elf_Rel const *)(rel_entsize + (void *)relp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find a symbol in the given section, to be used as the base for relocating
|
||||
@@ -333,6 +430,11 @@ static unsigned find_secsym_ndx(unsigned const txtndx,
|
||||
if (txtndx == w2(symp->st_shndx)
|
||||
/* avoid STB_WEAK */
|
||||
&& (STB_LOCAL == st_bind || STB_GLOBAL == st_bind)) {
|
||||
/* function symbols on ARM have quirks, avoid them */
|
||||
if (w2(ehdr->e_machine) == EM_ARM
|
||||
&& ELF_ST_TYPE(symp->st_info) == STT_FUNC)
|
||||
continue;
|
||||
|
||||
*recvalp = _w(symp->st_value);
|
||||
return symp - sym0;
|
||||
}
|
||||
@@ -354,13 +456,13 @@ __has_rel_mcount(Elf_Shdr const *const relhdr, /* is SHT_REL or SHT_RELA */
|
||||
Elf_Shdr const *const txthdr = &shdr0[w(relhdr->sh_info)];
|
||||
char const *const txtname = &shstrtab[w(txthdr->sh_name)];
|
||||
|
||||
if (0 == strcmp("__mcount_loc", txtname)) {
|
||||
if (strcmp("__mcount_loc", txtname) == 0) {
|
||||
fprintf(stderr, "warning: __mcount_loc already exists: %s\n",
|
||||
fname);
|
||||
succeed_file();
|
||||
}
|
||||
if (SHT_PROGBITS != w(txthdr->sh_type) ||
|
||||
!is_mcounted_section_name(txtname))
|
||||
if (w(txthdr->sh_type) != SHT_PROGBITS ||
|
||||
!(w(txthdr->sh_flags) & SHF_EXECINSTR))
|
||||
return NULL;
|
||||
return txtname;
|
||||
}
|
||||
@@ -370,7 +472,7 @@ static char const *has_rel_mcount(Elf_Shdr const *const relhdr,
|
||||
char const *const shstrtab,
|
||||
char const *const fname)
|
||||
{
|
||||
if (SHT_REL != w(relhdr->sh_type) && SHT_RELA != w(relhdr->sh_type))
|
||||
if (w(relhdr->sh_type) != SHT_REL && w(relhdr->sh_type) != SHT_RELA)
|
||||
return NULL;
|
||||
return __has_rel_mcount(relhdr, shdr0, shstrtab, fname);
|
||||
}
|
||||
@@ -383,9 +485,11 @@ static unsigned tot_relsize(Elf_Shdr const *const shdr0,
|
||||
{
|
||||
unsigned totrelsz = 0;
|
||||
Elf_Shdr const *shdrp = shdr0;
|
||||
char const *txtname;
|
||||
|
||||
for (; nhdr; --nhdr, ++shdrp) {
|
||||
if (has_rel_mcount(shdrp, shdr0, shstrtab, fname))
|
||||
txtname = has_rel_mcount(shdrp, shdr0, shstrtab, fname);
|
||||
if (txtname && is_mcounted_section_name(txtname))
|
||||
totrelsz += _w(shdrp->sh_size);
|
||||
}
|
||||
return totrelsz;
|
||||
@@ -421,7 +525,7 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype)
|
||||
for (relhdr = shdr0, k = nhdr; k; --k, ++relhdr) {
|
||||
char const *const txtname = has_rel_mcount(relhdr, shdr0,
|
||||
shstrtab, fname);
|
||||
if (txtname) {
|
||||
if (txtname && is_mcounted_section_name(txtname)) {
|
||||
uint_t recval = 0;
|
||||
unsigned const recsym = find_secsym_ndx(
|
||||
w(relhdr->sh_info), txtname, &recval,
|
||||
@@ -432,6 +536,12 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype)
|
||||
mlocp = sift_rel_mcount(mlocp,
|
||||
(void *)mlocp - (void *)mloc0, &mrelp,
|
||||
relhdr, ehdr, recsym, recval, reltype);
|
||||
} else if (txtname && (warn_on_notrace_sect || make_nop)) {
|
||||
/*
|
||||
* This section is ignored by ftrace, but still
|
||||
* has mcount calls. Convert them to nops now.
|
||||
*/
|
||||
nop_mcount(relhdr, ehdr, txtname);
|
||||
}
|
||||
}
|
||||
if (mloc0 != mlocp) {
|
||||
|
||||
@@ -134,6 +134,7 @@ my %text_sections = (
|
||||
".sched.text" => 1,
|
||||
".spinlock.text" => 1,
|
||||
".irqentry.text" => 1,
|
||||
".kprobes.text" => 1,
|
||||
".text.unlikely" => 1,
|
||||
);
|
||||
|
||||
@@ -222,6 +223,7 @@ if ($arch eq "x86_64") {
|
||||
$mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\smcount([+-]0x[0-9a-zA-Z]+)?\$";
|
||||
$type = ".quad";
|
||||
$alignment = 8;
|
||||
$mcount_adjust = -1;
|
||||
|
||||
# force flags for this arch
|
||||
$ld .= " -m elf_x86_64";
|
||||
@@ -231,6 +233,7 @@ if ($arch eq "x86_64") {
|
||||
|
||||
} elsif ($arch eq "i386") {
|
||||
$alignment = 4;
|
||||
$mcount_adjust = -1;
|
||||
|
||||
# force flags for this arch
|
||||
$ld .= " -m elf_i386";
|
||||
@@ -240,12 +243,14 @@ if ($arch eq "x86_64") {
|
||||
|
||||
} elsif ($arch eq "s390" && $bits == 32) {
|
||||
$mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_390_32\\s+_mcount\$";
|
||||
$mcount_adjust = -4;
|
||||
$alignment = 4;
|
||||
$ld .= " -m elf_s390";
|
||||
$cc .= " -m31";
|
||||
|
||||
} elsif ($arch eq "s390" && $bits == 64) {
|
||||
$mcount_regex = "^\\s*([0-9a-fA-F]+):\\s*R_390_(PC|PLT)32DBL\\s+_mcount\\+0x2\$";
|
||||
$mcount_adjust = -8;
|
||||
$alignment = 8;
|
||||
$type = ".quad";
|
||||
$ld .= " -m elf64_s390";
|
||||
|
||||
@@ -180,7 +180,7 @@ while 1:
|
||||
for s in stat:
|
||||
s = s.strip()
|
||||
if s.startswith(testop[0]):
|
||||
# Seperate status value
|
||||
# Separate status value
|
||||
val = s[2:].strip()
|
||||
query = analyse(val, testop, dat)
|
||||
break
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
Please see Documentation/SELinux.txt for information on
|
||||
Please see Documentation/security/SELinux.txt for information on
|
||||
installing a dummy SELinux policy.
|
||||
|
||||
@@ -132,7 +132,7 @@ exuberant()
|
||||
--regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \
|
||||
--regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \
|
||||
--regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \
|
||||
--regex-c++='/^DEFINE_EVENT\(([^,)]*).*/trace_\1/'
|
||||
--regex-c++='/^DEFINE_EVENT\([^,)]*, *([^,)]*).*/trace_\1/'
|
||||
|
||||
all_kconfigs | xargs $1 -a \
|
||||
--langdef=kconfig --language-force=kconfig \
|
||||
@@ -152,7 +152,9 @@ emacs()
|
||||
{
|
||||
all_sources | xargs $1 -a \
|
||||
--regex='/^ENTRY(\([^)]*\)).*/\1/' \
|
||||
--regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/'
|
||||
--regex='/^SYSCALL_DEFINE[0-9]?(\([^,)]*\).*/sys_\1/' \
|
||||
--regex='/^TRACE_EVENT(\([^,)]*\).*/trace_\1/' \
|
||||
--regex='/^DEFINE_EVENT([^,)]*, *\([^,)]*\).*/trace_\1/'
|
||||
|
||||
all_kconfigs | xargs $1 -a \
|
||||
--regex='/^[ \t]*\(\(menu\)*config\)[ \t]+\([a-zA-Z0-9_]+\)/\3/'
|
||||
|
||||
Reference in New Issue
Block a user