]> Git Repo - linux.git/commitdiff
Merge branch 'x86-asmlinkage-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <[email protected]>
Mon, 31 Mar 2014 21:13:25 +0000 (14:13 -0700)
committerLinus Torvalds <[email protected]>
Mon, 31 Mar 2014 21:13:25 +0000 (14:13 -0700)
Pull x86 LTO changes from Peter Anvin:
 "More infrastructure work in preparation for link-time optimization
  (LTO).  Most of these changes is to make sure symbols accessed from
  assembly code are properly marked as visible so the linker doesn't
  remove them.

  My understanding is that the changes to support LTO are still not
  upstream in binutils, but are on the way there.  This patchset should
  conclude the x86-specific changes, and remaining patches to actually
  enable LTO will be fed through the Kbuild tree (other than keeping up
  with changes to the x86 code base, of course), although not
  necessarily in this merge window"

* 'x86-asmlinkage-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (25 commits)
  Kbuild, lto: Handle basic LTO in modpost
  Kbuild, lto: Disable LTO for asm-offsets.c
  Kbuild, lto: Add a gcc-ld script to let run gcc as ld
  Kbuild, lto: add ld-version and ld-ifversion macros
  Kbuild, lto: Drop .number postfixes in modpost
  Kbuild, lto, workaround: Don't warn for initcall_reference in modpost
  lto: Disable LTO for sys_ni
  lto: Handle LTO common symbols in module loader
  lto, workaround: Add workaround for initcall reordering
  lto: Make asmlinkage __visible
  x86, lto: Disable LTO for the x86 VDSO
  initconst, x86: Fix initconst mistake in ts5500 code
  initconst: Fix initconst mistake in dcdbas
  asmlinkage: Make trace_hardirqs_on/off_caller visible
  asmlinkage, x86: Fix 32bit memcpy for LTO
  asmlinkage Make __stack_chk_failed and memcmp visible
  asmlinkage: Mark rwsem functions that can be called from assembler asmlinkage
  asmlinkage: Make main_extable_sort_needed visible
  asmlinkage, mutex: Mark __visible
  asmlinkage: Make trace_hardirq visible
  ...

1  2 
include/linux/lockdep.h
kernel/Makefile
kernel/locking/lockdep.c
kernel/locking/mutex.c
kernel/module.c
kernel/panic.c
scripts/mod/modpost.c

diff --combined include/linux/lockdep.h
index 060e5137fd80d877894b5e5b65cfde4bfc4cb2a7,7df9aa6902c06f61caed6350fab20e9c235d8082..008388f920d7e93e32ba388dd4b497f33d7bd49d
@@@ -252,9 -252,9 +252,9 @@@ struct held_lock 
        unsigned int trylock:1;                                         /* 16 bits */
  
        unsigned int read:2;        /* see lock_acquire() comment */
 -      unsigned int check:2;       /* see lock_acquire() comment */
 +      unsigned int check:1;       /* see lock_acquire() comment */
        unsigned int hardirqs_off:1;
 -      unsigned int references:11;                                     /* 32 bits */
 +      unsigned int references:12;                                     /* 32 bits */
  };
  
  /*
@@@ -265,7 -265,7 +265,7 @@@ extern void lockdep_info(void)
  extern void lockdep_reset(void);
  extern void lockdep_reset_lock(struct lockdep_map *lock);
  extern void lockdep_free_key_range(void *start, unsigned long size);
- extern void lockdep_sys_exit(void);
+ extern asmlinkage void lockdep_sys_exit(void);
  
  extern void lockdep_off(void);
  extern void lockdep_on(void);
@@@ -303,7 -303,7 +303,7 @@@ extern void lockdep_init_map(struct loc
                                 (lock)->dep_map.key, sub)
  
  #define lockdep_set_novalidate_class(lock) \
 -      lockdep_set_class(lock, &__lockdep_no_validate__)
 +      lockdep_set_class_and_name(lock, &__lockdep_no_validate__, #lock)
  /*
   * Compare locking classes
   */
@@@ -326,8 -326,9 +326,8 @@@ static inline int lockdep_match_key(str
   *
   * Values for check:
   *
 - *   0: disabled
 - *   1: simple checks (freeing, held-at-exit-time, etc.)
 - *   2: full validation
 + *   0: simple checks (freeing, held-at-exit-time, etc.)
 + *   1: full validation
   */
  extern void lock_acquire(struct lockdep_map *lock, unsigned int subclass,
                         int trylock, int read, int check,
@@@ -478,9 -479,15 +478,9 @@@ static inline void print_irqtrace_event
   * on the per lock-class debug mode:
   */
  
 -#ifdef CONFIG_PROVE_LOCKING
 - #define lock_acquire_exclusive(l, s, t, n, i)                lock_acquire(l, s, t, 0, 2, n, i)
 - #define lock_acquire_shared(l, s, t, n, i)           lock_acquire(l, s, t, 1, 2, n, i)
 - #define lock_acquire_shared_recursive(l, s, t, n, i) lock_acquire(l, s, t, 2, 2, n, i)
 -#else
 - #define lock_acquire_exclusive(l, s, t, n, i)                lock_acquire(l, s, t, 0, 1, n, i)
 - #define lock_acquire_shared(l, s, t, n, i)           lock_acquire(l, s, t, 1, 1, n, i)
 - #define lock_acquire_shared_recursive(l, s, t, n, i) lock_acquire(l, s, t, 2, 1, n, i)
 -#endif
 +#define lock_acquire_exclusive(l, s, t, n, i)         lock_acquire(l, s, t, 0, 1, n, i)
 +#define lock_acquire_shared(l, s, t, n, i)            lock_acquire(l, s, t, 1, 1, n, i)
 +#define lock_acquire_shared_recursive(l, s, t, n, i)  lock_acquire(l, s, t, 2, 1, n, i)
  
  #define spin_acquire(l, s, t, i)              lock_acquire_exclusive(l, s, t, NULL, i)
  #define spin_acquire_nest(l, s, t, n, i)      lock_acquire_exclusive(l, s, t, n, i)
  # define might_lock(lock)                                             \
  do {                                                                  \
        typecheck(struct lockdep_map *, &(lock)->dep_map);              \
 -      lock_acquire(&(lock)->dep_map, 0, 0, 0, 2, NULL, _THIS_IP_);    \
 +      lock_acquire(&(lock)->dep_map, 0, 0, 0, 1, NULL, _THIS_IP_);    \
        lock_release(&(lock)->dep_map, 0, _THIS_IP_);                   \
  } while (0)
  # define might_lock_read(lock)                                                \
  do {                                                                  \
        typecheck(struct lockdep_map *, &(lock)->dep_map);              \
 -      lock_acquire(&(lock)->dep_map, 0, 0, 1, 2, NULL, _THIS_IP_);    \
 +      lock_acquire(&(lock)->dep_map, 0, 0, 1, 1, NULL, _THIS_IP_);    \
        lock_release(&(lock)->dep_map, 0, _THIS_IP_);                   \
  } while (0)
  #else
diff --combined kernel/Makefile
index 4fd847488b7630f903245cae0d2c45cfcf3840e7,31c26c61aaecb05bc6bc380cdc97b9503b90d2cf..f2a8b6246ce935e9d4ae5aeddc314e3d281c8539
@@@ -18,10 -18,14 +18,13 @@@ CFLAGS_REMOVE_cgroup-debug.o = -p
  CFLAGS_REMOVE_irq_work.o = -pg
  endif
  
+ # cond_syscall is currently not LTO compatible
+ CFLAGS_sys_ni.o = $(DISABLE_LTO)
  obj-y += sched/
  obj-y += locking/
  obj-y += power/
  obj-y += printk/
 -obj-y += cpu/
  obj-y += irq/
  obj-y += rcu/
  
@@@ -92,7 -96,6 +95,7 @@@ obj-$(CONFIG_PADATA) += padata.
  obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
  obj-$(CONFIG_JUMP_LABEL) += jump_label.o
  obj-$(CONFIG_CONTEXT_TRACKING) += context_tracking.o
 +obj-$(CONFIG_TORTURE_TEST) += torture.o
  
  $(obj)/configs.o: $(obj)/config_data.h
  
diff --combined kernel/locking/lockdep.c
index bf0c6b0dd9c59cd04a3ee00ef1f7c83cf38c49d0,aa3bf153b718fa215f9c0b4d6c0915481f9f0e1f..b0e9467922e1a476bfe1d4d8503ac7623affcaea
@@@ -1936,12 -1936,12 +1936,12 @@@ check_prevs_add(struct task_struct *cur
  
        for (;;) {
                int distance = curr->lockdep_depth - depth + 1;
 -              hlock = curr->held_locks + depth-1;
 +              hlock = curr->held_locks + depth - 1;
                /*
                 * Only non-recursive-read entries get new dependencies
                 * added:
                 */
 -              if (hlock->read != 2) {
 +              if (hlock->read != 2 && hlock->check) {
                        if (!check_prev_add(curr, hlock, next,
                                                distance, trylock_loop))
                                return 0;
@@@ -2098,7 -2098,7 +2098,7 @@@ static int validate_chain(struct task_s
         * (If lookup_chain_cache() returns with 1 it acquires
         * graph_lock for us)
         */
 -      if (!hlock->trylock && (hlock->check == 2) &&
 +      if (!hlock->trylock && hlock->check &&
            lookup_chain_cache(curr, hlock, chain_key)) {
                /*
                 * Check whether last held lock:
@@@ -2517,7 -2517,7 +2517,7 @@@ mark_held_locks(struct task_struct *cur
  
                BUG_ON(usage_bit >= LOCK_USAGE_STATES);
  
 -              if (hlock_class(hlock)->key == __lockdep_no_validate__.subkeys)
 +              if (!hlock->check)
                        continue;
  
                if (!mark_lock(curr, hlock, usage_bit))
@@@ -2557,7 -2557,7 +2557,7 @@@ static void __trace_hardirqs_on_caller(
        debug_atomic_inc(hardirqs_on_events);
  }
  
- void trace_hardirqs_on_caller(unsigned long ip)
__visible void trace_hardirqs_on_caller(unsigned long ip)
  {
        time_hardirqs_on(CALLER_ADDR0, ip);
  
@@@ -2610,7 -2610,7 +2610,7 @@@ EXPORT_SYMBOL(trace_hardirqs_on)
  /*
   * Hardirqs were disabled:
   */
- void trace_hardirqs_off_caller(unsigned long ip)
__visible void trace_hardirqs_off_caller(unsigned long ip)
  {
        struct task_struct *curr = current;
  
@@@ -3055,6 -3055,9 +3055,6 @@@ static int __lock_acquire(struct lockde
        int class_idx;
        u64 chain_key;
  
 -      if (!prove_locking)
 -              check = 1;
 -
        if (unlikely(!debug_locks))
                return 0;
  
        if (DEBUG_LOCKS_WARN_ON(!irqs_disabled()))
                return 0;
  
 -      if (lock->key == &__lockdep_no_validate__)
 -              check = 1;
 +      if (!prove_locking || lock->key == &__lockdep_no_validate__)
 +              check = 0;
  
        if (subclass < NR_LOCKDEP_CACHING_CLASSES)
                class = lock->class_cache[subclass];
        hlock->holdtime_stamp = lockstat_clock();
  #endif
  
 -      if (check == 2 && !mark_irqflags(curr, hlock))
 +      if (check && !mark_irqflags(curr, hlock))
                return 0;
  
        /* mark it as used: */
@@@ -4188,7 -4191,7 +4188,7 @@@ void debug_show_held_locks(struct task_
  }
  EXPORT_SYMBOL_GPL(debug_show_held_locks);
  
- void lockdep_sys_exit(void)
asmlinkage void lockdep_sys_exit(void)
  {
        struct task_struct *curr = current;
  
diff --combined kernel/locking/mutex.c
index 14fe72cc8ce7f038a11e7e860c4f323bca496908,adbc0d0f314b0049540d0eaf97afc4387513b4a3..bc73d33c6760e174fd1bb2c8319c0faf5abc221f
@@@ -25,7 -25,6 +25,7 @@@
  #include <linux/spinlock.h>
  #include <linux/interrupt.h>
  #include <linux/debug_locks.h>
 +#include "mcs_spinlock.h"
  
  /*
   * In the DEBUG case we are using the "NULL fastpath" for mutexes,
  #ifdef CONFIG_DEBUG_MUTEXES
  # include "mutex-debug.h"
  # include <asm-generic/mutex-null.h>
 +/*
 + * Must be 0 for the debug case so we do not do the unlock outside of the
 + * wait_lock region. debug_mutex_unlock() will do the actual unlock in this
 + * case.
 + */
 +# undef __mutex_slowpath_needs_to_unlock
 +# define  __mutex_slowpath_needs_to_unlock()  0
  #else
  # include "mutex.h"
  # include <asm/mutex.h>
@@@ -60,7 -52,7 +60,7 @@@ __mutex_init(struct mutex *lock, const 
        INIT_LIST_HEAD(&lock->wait_list);
        mutex_clear_owner(lock);
  #ifdef CONFIG_MUTEX_SPIN_ON_OWNER
 -      lock->spin_mlock = NULL;
 +      lock->osq = NULL;
  #endif
  
        debug_mutex_init(lock, name, key);
@@@ -75,8 -67,7 +75,7 @@@ EXPORT_SYMBOL(__mutex_init)
   * We also put the fastpath first in the kernel image, to make sure the
   * branch is predicted by the CPU as default-untaken.
   */
- static __used noinline void __sched
- __mutex_lock_slowpath(atomic_t *lock_count);
+ __visible void __sched __mutex_lock_slowpath(atomic_t *lock_count);
  
  /**
   * mutex_lock - acquire the mutex
@@@ -119,7 -110,54 +118,7 @@@ EXPORT_SYMBOL(mutex_lock)
   * more or less simultaneously, the spinners need to acquire a MCS lock
   * first before spinning on the owner field.
   *
 - * We don't inline mspin_lock() so that perf can correctly account for the
 - * time spent in this lock function.
   */
 -struct mspin_node {
 -      struct mspin_node *next ;
 -      int               locked;       /* 1 if lock acquired */
 -};
 -#define       MLOCK(mutex)    ((struct mspin_node **)&((mutex)->spin_mlock))
 -
 -static noinline
 -void mspin_lock(struct mspin_node **lock, struct mspin_node *node)
 -{
 -      struct mspin_node *prev;
 -
 -      /* Init node */
 -      node->locked = 0;
 -      node->next   = NULL;
 -
 -      prev = xchg(lock, node);
 -      if (likely(prev == NULL)) {
 -              /* Lock acquired */
 -              node->locked = 1;
 -              return;
 -      }
 -      ACCESS_ONCE(prev->next) = node;
 -      smp_wmb();
 -      /* Wait until the lock holder passes the lock down */
 -      while (!ACCESS_ONCE(node->locked))
 -              arch_mutex_cpu_relax();
 -}
 -
 -static void mspin_unlock(struct mspin_node **lock, struct mspin_node *node)
 -{
 -      struct mspin_node *next = ACCESS_ONCE(node->next);
 -
 -      if (likely(!next)) {
 -              /*
 -               * Release the lock by setting it to NULL
 -               */
 -              if (cmpxchg(lock, node, NULL) == node)
 -                      return;
 -              /* Wait until the next pointer is set */
 -              while (!(next = ACCESS_ONCE(node->next)))
 -                      arch_mutex_cpu_relax();
 -      }
 -      ACCESS_ONCE(next->locked) = 1;
 -      smp_wmb();
 -}
  
  /*
   * Mutex spinning code migrated from kernel/sched/core.c
@@@ -173,9 -211,6 +172,9 @@@ static inline int mutex_can_spin_on_own
        struct task_struct *owner;
        int retval = 1;
  
 +      if (need_resched())
 +              return 0;
 +
        rcu_read_lock();
        owner = ACCESS_ONCE(lock->owner);
        if (owner)
  }
  #endif
  
- static __used noinline void __sched __mutex_unlock_slowpath(atomic_t *lock_count);
+ __visible __used noinline
+ void __sched __mutex_unlock_slowpath(atomic_t *lock_count);
  
  /**
   * mutex_unlock - release the mutex
@@@ -410,11 -446,9 +410,11 @@@ __mutex_lock_common(struct mutex *lock
        if (!mutex_can_spin_on_owner(lock))
                goto slowpath;
  
 +      if (!osq_lock(&lock->osq))
 +              goto slowpath;
 +
        for (;;) {
                struct task_struct *owner;
 -              struct mspin_node  node;
  
                if (use_ww_ctx && ww_ctx->acquired > 0) {
                        struct ww_mutex *ww;
                         * performed the optimistic spinning cannot be done.
                         */
                        if (ACCESS_ONCE(ww->ctx))
 -                              goto slowpath;
 +                              break;
                }
  
                /*
                 * If there's an owner, wait for it to either
                 * release the lock or go to sleep.
                 */
 -              mspin_lock(MLOCK(lock), &node);
                owner = ACCESS_ONCE(lock->owner);
 -              if (owner && !mutex_spin_on_owner(lock, owner)) {
 -                      mspin_unlock(MLOCK(lock), &node);
 -                      goto slowpath;
 -              }
 +              if (owner && !mutex_spin_on_owner(lock, owner))
 +                      break;
  
                if ((atomic_read(&lock->count) == 1) &&
                    (atomic_cmpxchg(&lock->count, 1, 0) == 1)) {
                        }
  
                        mutex_set_owner(lock);
 -                      mspin_unlock(MLOCK(lock), &node);
 +                      osq_unlock(&lock->osq);
                        preempt_enable();
                        return 0;
                }
 -              mspin_unlock(MLOCK(lock), &node);
  
                /*
                 * When there's no owner, we might have preempted between the
                 * the owner complete.
                 */
                if (!owner && (need_resched() || rt_task(task)))
 -                      goto slowpath;
 +                      break;
  
                /*
                 * The cpu_relax() call is a compiler barrier which forces
                 */
                arch_mutex_cpu_relax();
        }
 +      osq_unlock(&lock->osq);
  slowpath:
 +      /*
 +       * If we fell out of the spin path because of need_resched(),
 +       * reschedule now, before we try-lock the mutex. This avoids getting
 +       * scheduled out right after we obtained the mutex.
 +       */
 +      if (need_resched())
 +              schedule_preempt_disabled();
  #endif
        spin_lock_mutex(&lock->wait_lock, flags);
  
@@@ -687,6 -717,10 +687,6 @@@ __mutex_unlock_common_slowpath(atomic_
        struct mutex *lock = container_of(lock_count, struct mutex, count);
        unsigned long flags;
  
 -      spin_lock_mutex(&lock->wait_lock, flags);
 -      mutex_release(&lock->dep_map, nested, _RET_IP_);
 -      debug_mutex_unlock(lock);
 -
        /*
         * some architectures leave the lock unlocked in the fastpath failure
         * case, others need to leave it locked. In the later case we have to
        if (__mutex_slowpath_needs_to_unlock())
                atomic_set(&lock->count, 1);
  
 +      spin_lock_mutex(&lock->wait_lock, flags);
 +      mutex_release(&lock->dep_map, nested, _RET_IP_);
 +      debug_mutex_unlock(lock);
 +
        if (!list_empty(&lock->wait_list)) {
                /* get the first entry from the wait-list: */
                struct mutex_waiter *waiter =
  /*
   * Release the lock, slowpath:
   */
static __used noinline void
__visible void
  __mutex_unlock_slowpath(atomic_t *lock_count)
  {
        __mutex_unlock_common_slowpath(lock_count, 1);
@@@ -773,7 -803,7 +773,7 @@@ int __sched mutex_lock_killable(struct 
  }
  EXPORT_SYMBOL(mutex_lock_killable);
  
static __used noinline void __sched
__visible void __sched
  __mutex_lock_slowpath(atomic_t *lock_count)
  {
        struct mutex *lock = container_of(lock_count, struct mutex, count);
diff --combined kernel/module.c
index ca2c1aded7eecba13a634d4a429975ad33236d61,b99e80119eef85469cf666cfa063f83ad9053280..8dc7f5e80dd8f75273ef15df03a14615de1579d4
@@@ -1015,7 -1015,7 +1015,7 @@@ static size_t module_flags_taint(struc
                buf[l++] = 'C';
        /*
         * TAINT_FORCED_RMMOD: could be added.
 -       * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
 +       * TAINT_CPU_OUT_OF_SPEC, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
         * apply to modules.
         */
        return l;
@@@ -1948,6 -1948,10 +1948,10 @@@ static int simplify_symbols(struct modu
  
                switch (sym[i].st_shndx) {
                case SHN_COMMON:
+                       /* Ignore common symbols */
+                       if (!strncmp(name, "__gnu_lto", 9))
+                               break;
                        /* We compiled with -fno-common.  These are not
                           supposed to happen.  */
                        pr_debug("Common symbol: %s\n", name);
diff --combined kernel/panic.c
index 2270cfd1d6becdd392366051beb94ba9d7af9692,3eb0ffb2596019077c7a46484e97f034e01d9cac..cca8a913ae7c8d6314fda34a1f3853a364e32cfd
@@@ -199,7 -199,7 +199,7 @@@ struct tnt 
  static const struct tnt tnts[] = {
        { TAINT_PROPRIETARY_MODULE,     'P', 'G' },
        { TAINT_FORCED_MODULE,          'F', ' ' },
 -      { TAINT_UNSAFE_SMP,             'S', ' ' },
 +      { TAINT_CPU_OUT_OF_SPEC,        'S', ' ' },
        { TAINT_FORCED_RMMOD,           'R', ' ' },
        { TAINT_MACHINE_CHECK,          'M', ' ' },
        { TAINT_BAD_PAGE,               'B', ' ' },
@@@ -459,7 -459,7 +459,7 @@@ EXPORT_SYMBOL(warn_slowpath_null)
   * Called when gcc's -fstack-protector feature is used, and
   * gcc detects corruption of the on-stack canary value
   */
- void __stack_chk_fail(void)
__visible void __stack_chk_fail(void)
  {
        panic("stack-protector: Kernel stack is corrupted in: %p\n",
                __builtin_return_address(0));
diff --combined scripts/mod/modpost.c
index 99a45fdc1bbfa9a15e7bbd6e4f9ec14a8a8c2357,63804a16ba9feeb843d4eeb7bef371a53a0b24ed..066355673930342a1b5e839950cbd1186ed6c24b
@@@ -623,7 -623,10 +623,10 @@@ static void handle_modversions(struct m
  
        switch (sym->st_shndx) {
        case SHN_COMMON:
-               warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
+               if (!strncmp(symname, "__gnu_lto_", sizeof("__gnu_lto_")-1)) {
+                       /* Should warn here, but modpost runs before the linker */
+               } else
+                       warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
                break;
        case SHN_UNDEF:
                /* undefined symbol */
@@@ -849,6 -852,7 +852,7 @@@ static const char *section_white_list[
        ".xt.lit",         /* xtensa */
        ".arcextmap*",                  /* arc */
        ".gnu.linkonce.arcext*",        /* arc : modules */
+       ".gnu.lto*",
        NULL
  };
  
@@@ -1455,6 -1459,10 +1459,10 @@@ static void check_section_mismatch(cons
                to = find_elf_symbol(elf, r->r_addend, sym);
                tosym = sym_name(elf, to);
  
+               if (!strncmp(fromsym, "reference___initcall",
+                               sizeof("reference___initcall")-1))
+                       return;
                /* check whitelist - we may ignore it */
                if (secref_whitelist(mismatch,
                                        fromsec, fromsym, tosec, tosym)) {
@@@ -1502,16 -1510,6 +1510,16 @@@ static int addend_386_rel(struct elf_in
  #define R_ARM_JUMP24  29
  #endif
  
 +#ifndef       R_ARM_THM_CALL
 +#define       R_ARM_THM_CALL          10
 +#endif
 +#ifndef       R_ARM_THM_JUMP24
 +#define       R_ARM_THM_JUMP24        30
 +#endif
 +#ifndef       R_ARM_THM_JUMP19
 +#define       R_ARM_THM_JUMP19        51
 +#endif
 +
  static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
  {
        unsigned int r_typ = ELF_R_TYPE(r->r_info);
        case R_ARM_PC24:
        case R_ARM_CALL:
        case R_ARM_JUMP24:
 +      case R_ARM_THM_CALL:
 +      case R_ARM_THM_JUMP24:
 +      case R_ARM_THM_JUMP19:
                /* From ARM ABI: ((S + A) | T) - P */
                r->r_addend = (int)(long)(elf->hdr +
                              sechdr->sh_offset +
@@@ -1693,6 -1688,19 +1701,19 @@@ static void check_sec_ref(struct modul
        }
  }
  
+ static char *remove_dot(char *s)
+ {
+       char *end;
+       int n = strcspn(s, ".");
+       if (n > 0 && s[n] != 0) {
+               strtoul(s + n + 1, &end, 10);
+               if  (end > s + n + 1 && (*end == '.' || *end == 0))
+                       s[n] = 0;
+       }
+       return s;
+ }
  static void read_symbols(char *modname)
  {
        const char *symname;
        }
  
        for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
-               symname = info.strtab + sym->st_name;
+               symname = remove_dot(info.strtab + sym->st_name);
  
                handle_modversions(mod, &info, sym, symname);
                handle_moddevtable(mod, &info, sym, symname);
This page took 0.137229 seconds and 4 git commands to generate.