Commit cba8df4b authored by Paul Mundt's avatar Paul Mundt

sh: use the new generic strnlen_user() function

This discards both the _32 and _64 versions in favour of the consolidated
generic one.
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent 0e100e11
......@@ -33,6 +33,7 @@ config SUPERH
select GENERIC_CLOCKEVENTS
select GENERIC_CMOS_UPDATE if SH_SH03 || SH_DREAMCAST
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
help
The SuperH is a RISC processor targeted for use in embedded systems
and consumer electronics; it was also used in the Sega Dreamcast
......
......@@ -104,6 +104,9 @@ struct __large_struct { unsigned long buf[100]; };
extern long strncpy_from_user(char *dest, const char __user *src, long count);
extern __must_check long strlen_user(const char __user *str);
extern __must_check long strnlen_user(const char __user *str, long n);
/* Generic arbitrary sized copy. */
/* Return the number of bytes NOT copied */
__kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n);
......@@ -165,43 +168,6 @@ copy_to_user(void __user *to, const void *from, unsigned long n)
return __copy_size;
}
/**
* strnlen_user: - Get the size of a string in user space.
* @s: The string to measure.
* @n: The maximum valid length
*
* Context: User context only. This function may sleep.
*
* Get the size of a NUL-terminated string in user space.
*
* Returns the size of the string INCLUDING the terminating NUL.
* On exception, returns 0.
* If the string is too long, returns a value greater than @n.
*/
static inline long strnlen_user(const char __user *s, long n)
{
if (!__addr_ok(s))
return 0;
else
return __strnlen_user(s, n);
}
/**
* strlen_user: - Get the size of a string in user space.
* @str: The string to measure.
*
* Context: User context only. This function may sleep.
*
* Get the size of a NUL-terminated string in user space.
*
* Returns the size of the string INCLUDING the terminating NUL.
* On exception, returns 0.
*
* If there is a limit on the length of a valid string, you may wish to
* consider using strnlen_user() instead.
*/
#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
/*
* The exception table consists of pairs of addresses: the first is the
* address of an instruction that is allowed to fault, and the second is
......
......@@ -170,40 +170,4 @@ __asm__ __volatile__( \
extern void __put_user_unknown(void);
/*
* Return the size of a string (including the ending 0 even when we have
* exceeded the maximum string length).
*/
static inline long __strnlen_user(const char __user *__s, long __n)
{
unsigned long res;
unsigned long __dummy;
__asm__ __volatile__(
"1:\t"
"mov.b @(%0,%3), %1\n\t"
"cmp/eq %4, %0\n\t"
"bt/s 2f\n\t"
" add #1, %0\n\t"
"tst %1, %1\n\t"
"bf 1b\n\t"
"2:\n"
".section .fixup,\"ax\"\n"
"3:\n\t"
"mov.l 4f, %1\n\t"
"jmp @%1\n\t"
" mov #0, %0\n"
".balign 4\n"
"4: .long 2b\n"
".previous\n"
".section __ex_table,\"a\"\n"
" .balign 4\n"
" .long 1b,3b\n"
".previous"
: "=z" (res), "=&r" (__dummy)
: "0" (0), "r" (__s), "r" (__n)
: "t");
return res;
}
#endif /* __ASM_SH_UACCESS_32_H */
......@@ -84,6 +84,4 @@ extern long __put_user_asm_l(void *, long);
extern long __put_user_asm_q(void *, long);
extern void __put_user_unknown(void);
extern long __strnlen_user(const char *__s, long __n);
#endif /* __ASM_SH_UACCESS_64_H */
#ifndef __ASM_SH_WORD_AT_A_TIME_H
#define __ASM_SH_WORD_AT_A_TIME_H
#ifdef CONFIG_CPU_BIG_ENDIAN
# include <asm-generic/word-at-a-time.h>
#else
/*
* Little-endian version cribbed from x86.
*/
struct word_at_a_time {
const unsigned long one_bits, high_bits;
};
#define WORD_AT_A_TIME_CONSTANTS { REPEAT_BYTE(0x01), REPEAT_BYTE(0x80) }
/* Carl Chatfield / Jan Achrenius G+ version for 32-bit */
static inline long count_masked_bytes(long mask)
{
/* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */
long a = (0x0ff0001+mask) >> 23;
/* Fix the 1 for 00 case */
return a & mask;
}
/* Return nonzero if it has a zero */
static inline unsigned long has_zero(unsigned long a, unsigned long *bits, const struct word_at_a_time *c)
{
unsigned long mask = ((a - c->one_bits) & ~a) & c->high_bits;
*bits = mask;
return mask;
}
static inline unsigned long prep_zero_mask(unsigned long a, unsigned long bits, const struct word_at_a_time *c)
{
return bits;
}
static inline unsigned long create_zero_mask(unsigned long bits)
{
bits = (bits - 1) & ~bits;
return bits >> 7;
}
/* The mask we created is directly usable as a bytemask */
#define zero_bytemask(mask) (mask)
static inline unsigned long find_zero(unsigned long mask)
{
return count_masked_bytes(mask);
}
#endif
#endif
......@@ -1568,46 +1568,6 @@ ___clear_user_exit:
#endif /* CONFIG_MMU */
/*
* extern long __strnlen_user(const char *__s, long __n)
*
* Inputs:
* (r2) source address
* (r3) source size in bytes
*
* Ouputs:
* (r2) -EFAULT (in case of faulting)
* string length (otherwise)
*/
.global __strnlen_user
__strnlen_user:
pta ___strnlen_user_set_reply, tr0
pta ___strnlen_user1, tr1
or ZERO, ZERO, r5 /* r5 = counter */
movi -(EFAULT), r6 /* r6 = reply, no real fixup */
or ZERO, ZERO, r7 /* r7 = data, clear top byte of data */
beq r3, ZERO, tr0
___strnlen_user1:
ldx.b r2, r5, r7 /* Fault address: only in reading */
addi r3, -1, r3 /* No real fixup */
addi r5, 1, r5
beq r3, ZERO, tr0
bne r7, ZERO, tr1
! The line below used to be active. This meant led to a junk byte lying between each pair
! of entries in the argv & envp structures in memory. Whilst the program saw the right data
! via the argv and envp arguments to main, it meant the 'flat' representation visible through
! /proc/$pid/cmdline was corrupt, causing trouble with ps, for example.
! addi r5, 1, r5 /* Include '\0' */
___strnlen_user_set_reply:
or r5, ZERO, r6 /* If done, return counter */
___strnlen_user_exit:
or r6, ZERO, r2
ptabs LINK, tr0
blink tr0, ZERO
/*
* extern long __get_user_asm_?(void *val, long addr)
*
......@@ -1942,7 +1902,6 @@ asm_uaccess_start:
.long ___copy_user2, ___copy_user_exit
.long ___clear_user1, ___clear_user_exit
#endif
.long ___strnlen_user1, ___strnlen_user_exit
.long ___get_user_asm_b1, ___get_user_asm_b_exit
.long ___get_user_asm_w1, ___get_user_asm_w_exit
.long ___get_user_asm_l1, ___get_user_asm_l_exit
......
......@@ -32,7 +32,6 @@ EXPORT_SYMBOL(__get_user_asm_b);
EXPORT_SYMBOL(__get_user_asm_w);
EXPORT_SYMBOL(__get_user_asm_l);
EXPORT_SYMBOL(__get_user_asm_q);
EXPORT_SYMBOL(__strnlen_user);
EXPORT_SYMBOL(__clear_user);
EXPORT_SYMBOL(copy_page);
EXPORT_SYMBOL(__copy_user);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment