Merge tag 'mips_4.21' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
[linux-2.6-microblaze.git] / tools / objtool / check.c
index 2928939..0414a0d 100644 (file)
@@ -836,7 +836,7 @@ static int add_switch_table(struct objtool_file *file, struct instruction *insn,
        struct symbol *pfunc = insn->func->pfunc;
        unsigned int prev_offset = 0;
 
-       list_for_each_entry_from(rela, &file->rodata->rela->rela_list, list) {
+       list_for_each_entry_from(rela, &table->rela_sec->rela_list, list) {
                if (rela == next_table)
                        break;
 
@@ -926,6 +926,7 @@ static struct rela *find_switch_table(struct objtool_file *file,
 {
        struct rela *text_rela, *rodata_rela;
        struct instruction *orig_insn = insn;
+       struct section *rodata_sec;
        unsigned long table_offset;
 
        /*
@@ -953,10 +954,13 @@ static struct rela *find_switch_table(struct objtool_file *file,
                /* look for a relocation which references .rodata */
                text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
                                                    insn->len);
-               if (!text_rela || text_rela->sym != file->rodata->sym)
+               if (!text_rela || text_rela->sym->type != STT_SECTION ||
+                   !text_rela->sym->sec->rodata)
                        continue;
 
                table_offset = text_rela->addend;
+               rodata_sec = text_rela->sym->sec;
+
                if (text_rela->type == R_X86_64_PC32)
                        table_offset += 4;
 
@@ -964,10 +968,10 @@ static struct rela *find_switch_table(struct objtool_file *file,
                 * Make sure the .rodata address isn't associated with a
                 * symbol.  gcc jump tables are anonymous data.
                 */
-               if (find_symbol_containing(file->rodata, table_offset))
+               if (find_symbol_containing(rodata_sec, table_offset))
                        continue;
 
-               rodata_rela = find_rela_by_dest(file->rodata, table_offset);
+               rodata_rela = find_rela_by_dest(rodata_sec, table_offset);
                if (rodata_rela) {
                        /*
                         * Use of RIP-relative switch jumps is quite rare, and
@@ -1052,7 +1056,7 @@ static int add_switch_table_alts(struct objtool_file *file)
        struct symbol *func;
        int ret;
 
-       if (!file->rodata || !file->rodata->rela)
+       if (!file->rodata)
                return 0;
 
        for_each_sec(file, sec) {
@@ -1198,10 +1202,33 @@ static int read_retpoline_hints(struct objtool_file *file)
        return 0;
 }
 
+static void mark_rodata(struct objtool_file *file)
+{
+       struct section *sec;
+       bool found = false;
+
+       /*
+        * This searches for the .rodata section or multiple .rodata.func_name
+        * sections if -fdata-sections is being used. The .str.1.1 and .str.1.8
+        * rodata sections are ignored as they don't contain jump tables.
+        */
+       for_each_sec(file, sec) {
+               if (!strncmp(sec->name, ".rodata", 7) &&
+                   !strstr(sec->name, ".str1.")) {
+                       sec->rodata = true;
+                       found = true;
+               }
+       }
+
+       file->rodata = found;
+}
+
 static int decode_sections(struct objtool_file *file)
 {
        int ret;
 
+       mark_rodata(file);
+
        ret = decode_instructions(file);
        if (ret)
                return ret;
@@ -2171,7 +2198,6 @@ int check(const char *_objname, bool orc)
        INIT_LIST_HEAD(&file.insn_list);
        hash_init(file.insn_hash);
        file.whitelist = find_section_by_name(file.elf, ".discard.func_stack_frame_non_standard");
-       file.rodata = find_section_by_name(file.elf, ".rodata");
        file.c_file = find_section_by_name(file.elf, ".comment");
        file.ignore_unreachables = no_unreachable;
        file.hints = false;