[PATCH 09/35] objtool: Introduce special_type
From: Peter Zijlstra
Date: Thu Jan 18 2018 - 09:58:12 EST
Use an enum for the special_alt entries instead of a collection of
booleans.
Signed-off-by: Peter Zijlstra (Intel) <peterz@xxxxxxxxxxxxx>
---
tools/objtool/check.c | 14 +++++++++++---
tools/objtool/special.c | 14 +++++++-------
tools/objtool/special.h | 10 ++++++++--
3 files changed, 26 insertions(+), 12 deletions(-)
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -773,7 +773,7 @@ static int add_special_section_alts(stru
continue;
new_insn = NULL;
- if (!special_alt->group || special_alt->new_len) {
+ if (special_alt->type != alternative || special_alt->new_len) {
new_insn = find_insn(file, special_alt->new_sec,
special_alt->new_off);
if (!new_insn) {
@@ -785,16 +785,24 @@ static int add_special_section_alts(stru
}
}
- if (special_alt->group) {
+ switch (special_alt->type) {
+ case alternative:
ret = handle_group_alt(file, special_alt, orig_insn,
&new_insn);
if (ret)
goto out;
- } else if (special_alt->jump_or_nop) {
+ break;
+
+ case jump_label:
ret = handle_jump_alt(file, special_alt, orig_insn,
&new_insn);
if (ret)
goto out;
+
+ break;
+
+ default:
+ break;
}
alt = malloc(sizeof(*alt));
--- a/tools/objtool/special.c
+++ b/tools/objtool/special.c
@@ -49,7 +49,7 @@
struct special_entry {
const char *sec;
- bool group, jump_or_nop;
+ enum special_type type;
unsigned char size, orig, new;
unsigned char orig_len, new_len; /* group only */
};
@@ -57,7 +57,7 @@ struct special_entry {
struct special_entry entries[] = {
{
.sec = ".altinstructions",
- .group = true,
+ .type = alternative,
.size = ALT_ENTRY_SIZE,
.orig = ALT_ORIG_OFFSET,
.orig_len = ALT_ORIG_LEN_OFFSET,
@@ -66,13 +66,14 @@ struct special_entry entries[] = {
},
{
.sec = "__jump_table",
- .jump_or_nop = true,
+ .type = jump_label,
.size = JUMP_ENTRY_SIZE,
.orig = JUMP_ORIG_OFFSET,
.new = JUMP_NEW_OFFSET,
},
{
.sec = "__ex_table",
+ .type = exception,
.size = EX_ENTRY_SIZE,
.orig = EX_ORIG_OFFSET,
.new = EX_NEW_OFFSET,
@@ -91,10 +92,9 @@ static int get_alt_entry(struct elf *elf
offset = idx * entry->size;
data = sec->data->d_buf + offset;
- alt->group = entry->group;
- alt->jump_or_nop = entry->jump_or_nop;
+ alt->type = entry->type;
- if (alt->group) {
+ if (alt->type == alternative) {
unsigned short feature;
unsigned char type;
@@ -130,7 +130,7 @@ static int get_alt_entry(struct elf *elf
alt->orig_sec = orig_rela->sym->sec;
alt->orig_off = orig_rela->addend;
- if (!entry->group || alt->new_len) {
+ if (entry->type != alternative || alt->new_len) {
new_rela = find_rela_by_dest(sec, offset + entry->new);
if (!new_rela) {
WARN_FUNC("can't find new rela",
--- a/tools/objtool/special.h
+++ b/tools/objtool/special.h
@@ -21,12 +21,18 @@
#include <stdbool.h>
#include "elf.h"
+enum special_type {
+ alternative,
+ jump_label,
+ exception,
+};
+
struct special_alt {
struct list_head list;
- bool group;
+ enum special_type type;
+
bool skip_orig;
- bool jump_or_nop;
bool static_cpu_has;
struct section *orig_sec;