objtool: Enable compilation of objtool for all architectures
[linux-2.6-microblaze.git] / tools / objtool / orc_gen.c
index 41e4a27..c954998 100644 (file)
@@ -6,7 +6,6 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "orc.h"
 #include "check.h"
 #include "warn.h"
 
@@ -16,10 +15,10 @@ int create_orc(struct objtool_file *file)
 
        for_each_insn(file, insn) {
                struct orc_entry *orc = &insn->orc;
-               struct cfi_reg *cfa = &insn->state.cfa;
-               struct cfi_reg *bp = &insn->state.regs[CFI_BP];
+               struct cfi_reg *cfa = &insn->cfi.cfa;
+               struct cfi_reg *bp = &insn->cfi.regs[CFI_BP];
 
-               orc->end = insn->state.end;
+               orc->end = insn->cfi.end;
 
                if (cfa->base == CFI_UNDEFINED) {
                        orc->sp_reg = ORC_REG_UNDEFINED;
@@ -75,7 +74,7 @@ int create_orc(struct objtool_file *file)
 
                orc->sp_offset = cfa->offset;
                orc->bp_offset = bp->offset;
-               orc->type = insn->state.type;
+               orc->type = insn->cfi.type;
        }
 
        return 0;
@@ -88,11 +87,6 @@ static int create_orc_entry(struct elf *elf, struct section *u_sec, struct secti
        struct orc_entry *orc;
        struct rela *rela;
 
-       if (!insn_sec->sym) {
-               WARN("missing symbol for section %s", insn_sec->name);
-               return -1;
-       }
-
        /* populate ORC data */
        orc = (struct orc_entry *)u_sec->data->d_buf + idx;
        memcpy(orc, o, sizeof(*orc));
@@ -105,14 +99,37 @@ static int create_orc_entry(struct elf *elf, struct section *u_sec, struct secti
        }
        memset(rela, 0, sizeof(*rela));
 
-       rela->sym = insn_sec->sym;
-       rela->addend = insn_off;
+       if (insn_sec->sym) {
+               rela->sym = insn_sec->sym;
+               rela->addend = insn_off;
+       } else {
+               /*
+                * The Clang assembler doesn't produce section symbols, so we
+                * have to reference the function symbol instead:
+                */
+               rela->sym = find_symbol_containing(insn_sec, insn_off);
+               if (!rela->sym) {
+                       /*
+                        * Hack alert.  This happens when we need to reference
+                        * the NOP pad insn immediately after the function.
+                        */
+                       rela->sym = find_symbol_containing(insn_sec,
+                                                          insn_off - 1);
+               }
+               if (!rela->sym) {
+                       WARN("missing symbol for insn at offset 0x%lx\n",
+                            insn_off);
+                       return -1;
+               }
+
+               rela->addend = insn_off - rela->sym->offset;
+       }
+
        rela->type = R_X86_64_PC32;
        rela->offset = idx * sizeof(int);
        rela->sec = ip_relasec;
 
-       list_add_tail(&rela->list, &ip_relasec->rela_list);
-       hash_add(elf->rela_hash, &rela->hash, rela_hash(rela));
+       elf_add_rela(elf, rela);
 
        return 0;
 }