[tip: objtool/core] objtool: Rename rela to reloc

2020-06-17 Thread tip-bot2 for Matt Helsley
The following commit has been merged into the objtool/core branch of tip:

Commit-ID: f1974222634010486c1692e843af0ab11304dd2c
Gitweb:
https://git.kernel.org/tip/f1974222634010486c1692e843af0ab11304dd2c
Author:Matt Helsley 
AuthorDate:Fri, 29 May 2020 14:01:13 -07:00
Committer: Josh Poimboeuf 
CommitterDate: Mon, 01 Jun 2020 09:40:58 -05:00

objtool: Rename rela to reloc

Before supporting additional relocation types rename the relevant
types and functions from "rela" to "reloc". This work be done with
the following regex:

  sed -e 's/struct rela/struct reloc/g' \
  -e 's/\([_\*]\)rela\(s\{0,1\}\)/\1reloc\2/g' \
  -e 's/tmprela\(s\{0,1\}\)/tmpreloc\1/g' \
  -e 's/relasec/relocsec/g' \
  -e 's/rela_list/reloc_list/g' \
  -e 's/rela_hash/reloc_hash/g' \
  -e 's/add_rela/add_reloc/g' \
  -e 's/rela->/reloc->/g' \
  -e '/rela[,\.]/{ s/\([^\.>]\)rela\([\.,]\)/\1reloc\2/g ; }' \
  -e 's/rela =/reloc =/g' \
  -e 's/relas =/relocs =/g' \
  -e 's/relas\[/relocs[/g' \
  -e 's/relaname =/relocname =/g' \
  -e 's/= rela\;/= reloc\;/g' \
  -e 's/= relas\;/= relocs\;/g' \
  -e 's/= relaname\;/= relocname\;/g' \
  -e 's/, rela)/, reloc)/g' \
  -e 's/\([ @]\)rela\([ "]\)/\1reloc\2/g' \
  -e 's/ rela$/ reloc/g' \
  -e 's/, relaname/, relocname/g' \
  -e 's/sec->rela/sec->reloc/g' \
  -e 's/(\(!\{0,1\}\)rela/(\1reloc/g' \
  -i \
  arch.h \
  arch/x86/decode.c  \
  check.c \
  check.h \
  elf.c \
  elf.h \
  orc_gen.c \
  special.c

Notable exceptions which complicate the regex include gelf_*
library calls and standard/expected section names which still use
"rela" because they encode the type of relocation expected. Also, keep
"rela" in the struct because it encodes a specific type of relocation
we currently expect.

It will eventually turn into a member of an anonymous union when a
susequent patch adds implicit addend, or "rel", relocation support.

Signed-off-by: Matt Helsley 
Signed-off-by: Josh Poimboeuf 
---
 tools/objtool/arch.h|   2 +-
 tools/objtool/arch/x86/decode.c |   2 +-
 tools/objtool/check.c   | 196 +++
 tools/objtool/check.h   |   2 +-
 tools/objtool/elf.c | 138 +++---
 tools/objtool/elf.h |  22 +--
 tools/objtool/orc_gen.c |  46 +++
 tools/objtool/special.c |  28 ++--
 8 files changed, 218 insertions(+), 218 deletions(-)

diff --git a/tools/objtool/arch.h b/tools/objtool/arch.h
index eda15a5..d0969a9 100644
--- a/tools/objtool/arch.h
+++ b/tools/objtool/arch.h
@@ -82,6 +82,6 @@ bool arch_callee_saved_reg(unsigned char reg);
 
 unsigned long arch_jump_destination(struct instruction *insn);
 
-unsigned long arch_dest_rela_offset(int addend);
+unsigned long arch_dest_reloc_offset(int addend);
 
 #endif /* _ARCH_H */
diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
index 4b504fc..fe83d4c 100644
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -67,7 +67,7 @@ bool arch_callee_saved_reg(unsigned char reg)
}
 }
 
-unsigned long arch_dest_rela_offset(int addend)
+unsigned long arch_dest_reloc_offset(int addend)
 {
return addend + 4;
 }
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 63d65a7..28ce311 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -352,7 +352,7 @@ static struct instruction *find_last_insn(struct 
objtool_file *file,
 static int add_dead_ends(struct objtool_file *file)
 {
struct section *sec;
-   struct rela *rela;
+   struct reloc *reloc;
struct instruction *insn;
 
/*
@@ -370,24 +370,24 @@ static int add_dead_ends(struct objtool_file *file)
if (!sec)
goto reachable;
 
-   list_for_each_entry(rela, &sec->rela_list, list) {
-   if (rela->sym->type != STT_SECTION) {
+   list_for_each_entry(reloc, &sec->reloc_list, list) {
+   if (reloc->sym->type != STT_SECTION) {
WARN("unexpected relocation symbol type in %s", 
sec->name);
return -1;
}
-   insn = find_insn(file, rela->sym->sec, rela->addend);
+   insn = find_insn(file, reloc->sym->sec, reloc->addend);
if (insn)
insn = list_prev_entry(insn, list);
-   else if (rela->addend == rela->sym->sec->len) {
-   insn = find_last_insn(file, rela->sym->sec);
+   else if (reloc->addend == reloc->sym->sec->len) {
+   insn = find_last_insn(file, reloc->sym->sec);
if (!insn) {
WARN("can't find unreachable insn at %s+0x%x",
-rela->sym->sec->name, rela->addend);
+reloc->sym->sec->name, reloc->addend);

[tip: objtool/core] objtool: Add support for relocations without addends

2020-06-17 Thread tip-bot2 for Matt Helsley
The following commit has been merged into the objtool/core branch of tip:

Commit-ID: fb414783b65c880606fbc1463e6849f017e60d46
Gitweb:
https://git.kernel.org/tip/fb414783b65c880606fbc1463e6849f017e60d46
Author:Matt Helsley 
AuthorDate:Fri, 29 May 2020 14:01:14 -07:00
Committer: Josh Poimboeuf 
CommitterDate: Tue, 02 Jun 2020 15:37:04 -05:00

objtool: Add support for relocations without addends

Currently objtool only collects information about relocations with
addends. In recordmcount, which we are about to merge into objtool,
some supported architectures do not use rela relocations.

Signed-off-by: Matt Helsley 
Reviewed-by: Julien Thierry 
Reviewed-by: Kamalesh Babulal 
Signed-off-by: Josh Poimboeuf 
---
 tools/objtool/elf.c | 145 ++-
 tools/objtool/elf.h |   7 +-
 tools/objtool/orc_gen.c |   2 +-
 3 files changed, 134 insertions(+), 20 deletions(-)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 3160931..95d86bc 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -496,6 +496,32 @@ void elf_add_reloc(struct elf *elf, struct reloc *reloc)
elf_hash_add(elf->reloc_hash, &reloc->hash, reloc_hash(reloc));
 }
 
+static int read_rel_reloc(struct section *sec, int i, struct reloc *reloc, 
unsigned int *symndx)
+{
+   if (!gelf_getrel(sec->data, i, &reloc->rel)) {
+   WARN_ELF("gelf_getrel");
+   return -1;
+   }
+   reloc->type = GELF_R_TYPE(reloc->rel.r_info);
+   reloc->addend = 0;
+   reloc->offset = reloc->rel.r_offset;
+   *symndx = GELF_R_SYM(reloc->rel.r_info);
+   return 0;
+}
+
+static int read_rela_reloc(struct section *sec, int i, struct reloc *reloc, 
unsigned int *symndx)
+{
+   if (!gelf_getrela(sec->data, i, &reloc->rela)) {
+   WARN_ELF("gelf_getrela");
+   return -1;
+   }
+   reloc->type = GELF_R_TYPE(reloc->rela.r_info);
+   reloc->addend = reloc->rela.r_addend;
+   reloc->offset = reloc->rela.r_offset;
+   *symndx = GELF_R_SYM(reloc->rela.r_info);
+   return 0;
+}
+
 static int read_relocs(struct elf *elf)
 {
struct section *sec;
@@ -505,7 +531,8 @@ static int read_relocs(struct elf *elf)
unsigned long nr_reloc, max_reloc = 0, tot_reloc = 0;
 
list_for_each_entry(sec, &elf->sections, list) {
-   if (sec->sh.sh_type != SHT_RELA)
+   if ((sec->sh.sh_type != SHT_RELA) &&
+   (sec->sh.sh_type != SHT_REL))
continue;
 
sec->base = find_section_by_index(elf, sec->sh.sh_info);
@@ -525,16 +552,17 @@ static int read_relocs(struct elf *elf)
return -1;
}
memset(reloc, 0, sizeof(*reloc));
-
-   if (!gelf_getrela(sec->data, i, &reloc->rela)) {
-   WARN_ELF("gelf_getrela");
-   return -1;
+   switch (sec->sh.sh_type) {
+   case SHT_REL:
+   if (read_rel_reloc(sec, i, reloc, &symndx))
+   return -1;
+   break;
+   case SHT_RELA:
+   if (read_rela_reloc(sec, i, reloc, &symndx))
+   return -1;
+   break;
+   default: return -1;
}
-
-   reloc->type = GELF_R_TYPE(reloc->rela.r_info);
-   reloc->addend = reloc->rela.r_addend;
-   reloc->offset = reloc->rela.r_offset;
-   symndx = GELF_R_SYM(reloc->rela.r_info);
reloc->sym = find_symbol_by_index(elf, symndx);
reloc->sec = sec;
if (!reloc->sym) {
@@ -722,7 +750,37 @@ struct section *elf_create_section(struct elf *elf, const 
char *name,
return sec;
 }
 
-struct section *elf_create_reloc_section(struct elf *elf, struct section *base)
+static struct section *elf_create_rel_reloc_section(struct elf *elf, struct 
section *base)
+{
+   char *relocname;
+   struct section *sec;
+
+   relocname = malloc(strlen(base->name) + strlen(".rel") + 1);
+   if (!relocname) {
+   perror("malloc");
+   return NULL;
+   }
+   strcpy(relocname, ".rel");
+   strcat(relocname, base->name);
+
+   sec = elf_create_section(elf, relocname, sizeof(GElf_Rel), 0);
+   free(relocname);
+   if (!sec)
+   return NULL;
+
+   base->reloc = sec;
+   sec->base = base;
+
+   sec->sh.sh_type = SHT_REL;
+   sec->sh.sh_addralign = 8;
+   sec->sh.sh_link = find_section_by_name(elf, ".symtab")->idx;
+   sec->sh.sh_info = base->idx;
+   sec->sh.sh_flags = SHF_INFO_LINK;
+
+   return sec;
+}
+
+static st

[tip: objtool/core] objtool: Move struct objtool_file into arch-independent header

2020-05-27 Thread tip-bot2 for Matt Helsley
The following commit has been merged into the objtool/core branch of tip:

Commit-ID: d37c90d47fc4657423d2ff1c3ed3fd70612a9b43
Gitweb:
https://git.kernel.org/tip/d37c90d47fc4657423d2ff1c3ed3fd70612a9b43
Author:Matt Helsley 
AuthorDate:Tue, 19 May 2020 13:55:32 -07:00
Committer: Josh Poimboeuf 
CommitterDate: Wed, 20 May 2020 08:35:20 -05:00

objtool: Move struct objtool_file into arch-independent header

The objtool_file structure describes the files objtool works on,
is used by the check subcommand, and the check.h header is included
by the orc subcommands so it's presently used by all subcommands.

Since the structure will be useful in all subcommands besides check,
and some subcommands may not want to include check.h to get the
definition, split the structure out into a new header meant for use
by all objtool subcommands.

Signed-off-by: Matt Helsley 
Reviewed-by: Julien Thierry 
Signed-off-by: Josh Poimboeuf 
---
 tools/objtool/check.h   | 10 +-
 tools/objtool/objtool.h | 22 ++
 2 files changed, 23 insertions(+), 9 deletions(-)
 create mode 100644 tools/objtool/objtool.h

diff --git a/tools/objtool/check.h b/tools/objtool/check.h
index 2428022..3b59a1c 100644
--- a/tools/objtool/check.h
+++ b/tools/objtool/check.h
@@ -7,11 +7,10 @@
 #define _CHECK_H
 
 #include 
-#include "elf.h"
+#include "objtool.h"
 #include "cfi.h"
 #include "arch.h"
 #include "orc.h"
-#include 
 
 struct insn_state {
struct cfi_state cfi;
@@ -48,13 +47,6 @@ struct instruction {
struct orc_entry orc;
 };
 
-struct objtool_file {
-   struct elf *elf;
-   struct list_head insn_list;
-   DECLARE_HASHTABLE(insn_hash, 20);
-   bool ignore_unreachables, c_file, hints, rodata;
-};
-
 int check(const char *objname, bool orc);
 
 struct instruction *find_insn(struct objtool_file *file,
diff --git a/tools/objtool/objtool.h b/tools/objtool/objtool.h
new file mode 100644
index 000..d89616b
--- /dev/null
+++ b/tools/objtool/objtool.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2020 Matt Helsley 
+ */
+
+#ifndef _OBJTOOL_H
+#define _OBJTOOL_H
+
+#include 
+#include 
+#include 
+
+#include "elf.h"
+
+struct objtool_file {
+   struct elf *elf;
+   struct list_head insn_list;
+   DECLARE_HASHTABLE(insn_hash, 20);
+   bool ignore_unreachables, c_file, hints, rodata;
+};
+
+#endif /* _OBJTOOL_H */


[tip: objtool/core] objtool: Enable compilation of objtool for all architectures

2020-05-27 Thread tip-bot2 for Matt Helsley
The following commit has been merged into the objtool/core branch of tip:

Commit-ID: 0decf1f8de919782b152daf9c991967a2bac54f0
Gitweb:
https://git.kernel.org/tip/0decf1f8de919782b152daf9c991967a2bac54f0
Author:Matt Helsley 
AuthorDate:Tue, 19 May 2020 13:55:33 -07:00
Committer: Josh Poimboeuf 
CommitterDate: Wed, 20 May 2020 09:17:28 -05:00

objtool: Enable compilation of objtool for all architectures

Objtool currently only compiles for x86 architectures. This is
fine as it presently does not support tooling for other
architectures. However, we would like to be able to convert other
kernel tools to run as objtool sub commands because they too
process ELF object files. This will allow us to convert tools
such as recordmcount to use objtool's ELF code.

Since much of recordmcount's ELF code is copy-paste code to/from
a variety of other kernel tools (look at modpost for example) this
means that if we can convert recordmcount we can convert more.

We define weak definitions for subcommand entry functions and other weak
definitions for shared functions critical to building existing
subcommands. These return 127 when the command is missing which signify
tools that do not exist on all architectures.  In this case the "check"
and "orc" tools do not exist on all architectures so we only add them
for x86. Future changes adding support for "check", to arm64 for
example, can then modify the SUBCMD_CHECK variable when building for
arm64.

Objtool is not currently wired in to KConfig to be built for other
architectures because it's not needed for those architectures and
there are no commands it supports other than those for x86. As more
command support is enabled on various architectures the necessary
KConfig changes can be made (e.g. adding "STACK_VALIDATION") to
trigger building objtool.

[ jpoimboe: remove aliases, add __weak macro, add error messages ]

Cc: Julien Thierry 
Signed-off-by: Matt Helsley 
Signed-off-by: Josh Poimboeuf 
---
 tools/objtool/Build   | 13 +++
 tools/objtool/Makefile| 10 +-
 tools/objtool/arch.h  |  4 ++-
 tools/objtool/builtin-check.c |  2 +-
 tools/objtool/builtin-orc.c   |  3 +--
 tools/objtool/check.c |  4 +--
 tools/objtool/check.h |  4 +---
 tools/objtool/objtool.h   |  5 -
 tools/objtool/orc.h   | 18 +---
 tools/objtool/orc_dump.c  |  3 ++-
 tools/objtool/orc_gen.c   |  1 +-
 tools/objtool/weak.c  | 40 ++-
 12 files changed, 73 insertions(+), 34 deletions(-)
 delete mode 100644 tools/objtool/orc.h
 create mode 100644 tools/objtool/weak.c

diff --git a/tools/objtool/Build b/tools/objtool/Build
index 66f44f5..b7222d5 100644
--- a/tools/objtool/Build
+++ b/tools/objtool/Build
@@ -1,11 +1,16 @@
 objtool-y += arch/$(SRCARCH)/
+
+objtool-y += weak.o
+
+objtool-$(SUBCMD_CHECK) += check.o
+objtool-$(SUBCMD_CHECK) += special.o
+objtool-$(SUBCMD_ORC) += check.o
+objtool-$(SUBCMD_ORC) += orc_gen.o
+objtool-$(SUBCMD_ORC) += orc_dump.o
+
 objtool-y += builtin-check.o
 objtool-y += builtin-orc.o
-objtool-y += check.o
-objtool-y += orc_gen.o
-objtool-y += orc_dump.o
 objtool-y += elf.o
-objtool-y += special.o
 objtool-y += objtool.o
 
 objtool-y += libstring.o
diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index 6b91388..7770edc 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -46,6 +46,16 @@ elfshdr := $(shell echo '$(pound)include ' | $(CC) 
$(CFLAGS) -x c -E -
 CFLAGS += $(if $(elfshdr),,-DLIBELF_USE_DEPRECATED)
 
 AWK = awk
+
+SUBCMD_CHECK := n
+SUBCMD_ORC := n
+
+ifeq ($(SRCARCH),x86)
+   SUBCMD_CHECK := y
+   SUBCMD_ORC := y
+endif
+
+export SUBCMD_CHECK SUBCMD_ORC
 export srctree OUTPUT CFLAGS SRCARCH AWK
 include $(srctree)/tools/build/Makefile.include
 
diff --git a/tools/objtool/arch.h b/tools/objtool/arch.h
index cd118eb..eda15a5 100644
--- a/tools/objtool/arch.h
+++ b/tools/objtool/arch.h
@@ -8,9 +8,11 @@
 
 #include 
 #include 
-#include "elf.h"
+#include "objtool.h"
 #include "cfi.h"
 
+#include 
+
 enum insn_type {
INSN_JUMP_CONDITIONAL,
INSN_JUMP_UNCONDITIONAL,
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index be42b71..7a44174 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -16,7 +16,7 @@
 #include 
 #include 
 #include "builtin.h"
-#include "check.h"
+#include "objtool.h"
 
 bool no_fp, no_unreachable, retpoline, module, backtrace, uaccess, stats, 
validate_dup, vmlinux;
 
diff --git a/tools/objtool/builtin-orc.c b/tools/objtool/builtin-orc.c
index 5f7cc61..b1dfe20 100644
--- a/tools/objtool/builtin-orc.c
+++ b/tools/objtool/builtin-orc.c
@@ -14,8 +14,7 @@
 
 #include 
 #include "builtin.h"
-#include "check.h"
-
+#include "objtool.h"
 
 static const char *orc_usage[] = {
"objtool orc generate [] file.o",
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 7a47ff9..63d65a7 100644
--- a/

[tip: objtool/core] objtool: Exit successfully when requesting help

2020-05-27 Thread tip-bot2 for Matt Helsley
The following commit has been merged into the objtool/core branch of tip:

Commit-ID: f15c648f202cd0232d4a9c98627bc08bcd6d11ee
Gitweb:
https://git.kernel.org/tip/f15c648f202cd0232d4a9c98627bc08bcd6d11ee
Author:Matt Helsley 
AuthorDate:Tue, 19 May 2020 13:55:31 -07:00
Committer: Josh Poimboeuf 
CommitterDate: Wed, 20 May 2020 08:32:52 -05:00

objtool: Exit successfully when requesting help

When the user requests help it's not an error so do not exit with
a non-zero exit code. This is not especially useful for a user but
any script that might wish to check that objtool --help is at least
available can't rely on the exit code to crudely check that, for
example, building an objtool executable succeeds.

Signed-off-by: Matt Helsley 
Signed-off-by: Josh Poimboeuf 
---
 tools/objtool/objtool.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/objtool/objtool.c b/tools/objtool/objtool.c
index 0b3528f..58fdda5 100644
--- a/tools/objtool/objtool.c
+++ b/tools/objtool/objtool.c
@@ -58,7 +58,9 @@ static void cmd_usage(void)
 
printf("\n");
 
-   exit(129);
+   if (!help)
+   exit(129);
+   exit(0);
 }
 
 static void handle_options(int *argc, const char ***argv)