diff options
Diffstat (limited to 'lib/vsprintf.c')
| -rw-r--r-- | lib/vsprintf.c | 164 |
1 files changed, 12 insertions, 152 deletions
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index d3023df8477f..bc0ac6b333dc 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
| @@ -120,147 +120,6 @@ long long simple_strtoll(const char *cp, char **endp, unsigned int base) | |||
| 120 | } | 120 | } |
| 121 | EXPORT_SYMBOL(simple_strtoll); | 121 | EXPORT_SYMBOL(simple_strtoll); |
| 122 | 122 | ||
| 123 | /** | ||
| 124 | * strict_strtoul - convert a string to an unsigned long strictly | ||
| 125 | * @cp: The string to be converted | ||
| 126 | * @base: The number base to use | ||
| 127 | * @res: The converted result value | ||
| 128 | * | ||
| 129 | * strict_strtoul converts a string to an unsigned long only if the | ||
| 130 | * string is really an unsigned long string, any string containing | ||
| 131 | * any invalid char at the tail will be rejected and -EINVAL is returned, | ||
| 132 | * only a newline char at the tail is acceptible because people generally | ||
| 133 | * change a module parameter in the following way: | ||
| 134 | * | ||
| 135 | * echo 1024 > /sys/module/e1000/parameters/copybreak | ||
| 136 | * | ||
| 137 | * echo will append a newline to the tail. | ||
| 138 | * | ||
| 139 | * It returns 0 if conversion is successful and *res is set to the converted | ||
| 140 | * value, otherwise it returns -EINVAL and *res is set to 0. | ||
| 141 | * | ||
| 142 | * simple_strtoul just ignores the successive invalid characters and | ||
| 143 | * return the converted value of prefix part of the string. | ||
| 144 | */ | ||
| 145 | int strict_strtoul(const char *cp, unsigned int base, unsigned long *res) | ||
| 146 | { | ||
| 147 | char *tail; | ||
| 148 | unsigned long val; | ||
| 149 | |||
| 150 | *res = 0; | ||
| 151 | if (!*cp) | ||
| 152 | return -EINVAL; | ||
| 153 | |||
| 154 | val = simple_strtoul(cp, &tail, base); | ||
| 155 | if (tail == cp) | ||
| 156 | return -EINVAL; | ||
| 157 | |||
| 158 | if ((tail[0] == '\0') || (tail[0] == '\n' && tail[1] == '\0')) { | ||
| 159 | *res = val; | ||
| 160 | return 0; | ||
| 161 | } | ||
| 162 | |||
| 163 | return -EINVAL; | ||
| 164 | } | ||
| 165 | EXPORT_SYMBOL(strict_strtoul); | ||
| 166 | |||
| 167 | /** | ||
| 168 | * strict_strtol - convert a string to a long strictly | ||
| 169 | * @cp: The string to be converted | ||
| 170 | * @base: The number base to use | ||
| 171 | * @res: The converted result value | ||
| 172 | * | ||
| 173 | * strict_strtol is similiar to strict_strtoul, but it allows the first | ||
| 174 | * character of a string is '-'. | ||
| 175 | * | ||
| 176 | * It returns 0 if conversion is successful and *res is set to the converted | ||
| 177 | * value, otherwise it returns -EINVAL and *res is set to 0. | ||
| 178 | */ | ||
| 179 | int strict_strtol(const char *cp, unsigned int base, long *res) | ||
| 180 | { | ||
| 181 | int ret; | ||
| 182 | if (*cp == '-') { | ||
| 183 | ret = strict_strtoul(cp + 1, base, (unsigned long *)res); | ||
| 184 | if (!ret) | ||
| 185 | *res = -(*res); | ||
| 186 | } else { | ||
| 187 | ret = strict_strtoul(cp, base, (unsigned long *)res); | ||
| 188 | } | ||
| 189 | |||
| 190 | return ret; | ||
| 191 | } | ||
| 192 | EXPORT_SYMBOL(strict_strtol); | ||
| 193 | |||
| 194 | /** | ||
| 195 | * strict_strtoull - convert a string to an unsigned long long strictly | ||
| 196 | * @cp: The string to be converted | ||
| 197 | * @base: The number base to use | ||
| 198 | * @res: The converted result value | ||
| 199 | * | ||
| 200 | * strict_strtoull converts a string to an unsigned long long only if the | ||
| 201 | * string is really an unsigned long long string, any string containing | ||
| 202 | * any invalid char at the tail will be rejected and -EINVAL is returned, | ||
| 203 | * only a newline char at the tail is acceptible because people generally | ||
| 204 | * change a module parameter in the following way: | ||
| 205 | * | ||
| 206 | * echo 1024 > /sys/module/e1000/parameters/copybreak | ||
| 207 | * | ||
| 208 | * echo will append a newline to the tail of the string. | ||
| 209 | * | ||
| 210 | * It returns 0 if conversion is successful and *res is set to the converted | ||
| 211 | * value, otherwise it returns -EINVAL and *res is set to 0. | ||
| 212 | * | ||
| 213 | * simple_strtoull just ignores the successive invalid characters and | ||
| 214 | * return the converted value of prefix part of the string. | ||
| 215 | */ | ||
| 216 | int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res) | ||
| 217 | { | ||
| 218 | char *tail; | ||
| 219 | unsigned long long val; | ||
| 220 | |||
| 221 | *res = 0; | ||
| 222 | if (!*cp) | ||
| 223 | return -EINVAL; | ||
| 224 | |||
| 225 | val = simple_strtoull(cp, &tail, base); | ||
| 226 | if (tail == cp) | ||
| 227 | return -EINVAL; | ||
| 228 | if ((tail[0] == '\0') || (tail[0] == '\n' && tail[1] == '\0')) { | ||
| 229 | *res = val; | ||
| 230 | return 0; | ||
| 231 | } | ||
| 232 | |||
| 233 | return -EINVAL; | ||
| 234 | } | ||
| 235 | EXPORT_SYMBOL(strict_strtoull); | ||
| 236 | |||
| 237 | /** | ||
| 238 | * strict_strtoll - convert a string to a long long strictly | ||
| 239 | * @cp: The string to be converted | ||
| 240 | * @base: The number base to use | ||
| 241 | * @res: The converted result value | ||
| 242 | * | ||
| 243 | * strict_strtoll is similiar to strict_strtoull, but it allows the first | ||
| 244 | * character of a string is '-'. | ||
| 245 | * | ||
| 246 | * It returns 0 if conversion is successful and *res is set to the converted | ||
| 247 | * value, otherwise it returns -EINVAL and *res is set to 0. | ||
| 248 | */ | ||
| 249 | int strict_strtoll(const char *cp, unsigned int base, long long *res) | ||
| 250 | { | ||
| 251 | int ret; | ||
| 252 | if (*cp == '-') { | ||
| 253 | ret = strict_strtoull(cp + 1, base, (unsigned long long *)res); | ||
| 254 | if (!ret) | ||
| 255 | *res = -(*res); | ||
| 256 | } else { | ||
| 257 | ret = strict_strtoull(cp, base, (unsigned long long *)res); | ||
| 258 | } | ||
| 259 | |||
| 260 | return ret; | ||
| 261 | } | ||
| 262 | EXPORT_SYMBOL(strict_strtoll); | ||
| 263 | |||
| 264 | static noinline_for_stack | 123 | static noinline_for_stack |
| 265 | int skip_atoi(const char **s) | 124 | int skip_atoi(const char **s) |
| 266 | { | 125 | { |
| @@ -574,7 +433,9 @@ char *symbol_string(char *buf, char *end, void *ptr, | |||
| 574 | unsigned long value = (unsigned long) ptr; | 433 | unsigned long value = (unsigned long) ptr; |
| 575 | #ifdef CONFIG_KALLSYMS | 434 | #ifdef CONFIG_KALLSYMS |
| 576 | char sym[KSYM_SYMBOL_LEN]; | 435 | char sym[KSYM_SYMBOL_LEN]; |
| 577 | if (ext != 'f' && ext != 's') | 436 | if (ext == 'B') |
| 437 | sprint_backtrace(sym, value); | ||
| 438 | else if (ext != 'f' && ext != 's') | ||
| 578 | sprint_symbol(sym, value); | 439 | sprint_symbol(sym, value); |
| 579 | else | 440 | else |
| 580 | kallsyms_lookup(value, NULL, NULL, NULL, sym); | 441 | kallsyms_lookup(value, NULL, NULL, NULL, sym); |
| @@ -949,6 +810,7 @@ int kptr_restrict = 1; | |||
| 949 | * - 'f' For simple symbolic function names without offset | 810 | * - 'f' For simple symbolic function names without offset |
| 950 | * - 'S' For symbolic direct pointers with offset | 811 | * - 'S' For symbolic direct pointers with offset |
| 951 | * - 's' For symbolic direct pointers without offset | 812 | * - 's' For symbolic direct pointers without offset |
| 813 | * - 'B' For backtraced symbolic direct pointers with offset | ||
| 952 | * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] | 814 | * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] |
| 953 | * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201] | 815 | * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201] |
| 954 | * - 'M' For a 6-byte MAC address, it prints the address in the | 816 | * - 'M' For a 6-byte MAC address, it prints the address in the |
| @@ -991,7 +853,7 @@ static noinline_for_stack | |||
| 991 | char *pointer(const char *fmt, char *buf, char *end, void *ptr, | 853 | char *pointer(const char *fmt, char *buf, char *end, void *ptr, |
| 992 | struct printf_spec spec) | 854 | struct printf_spec spec) |
| 993 | { | 855 | { |
| 994 | if (!ptr) { | 856 | if (!ptr && *fmt != 'K') { |
| 995 | /* | 857 | /* |
| 996 | * Print (null) with the same width as a pointer so it makes | 858 | * Print (null) with the same width as a pointer so it makes |
| 997 | * tabular output look nice. | 859 | * tabular output look nice. |
| @@ -1008,6 +870,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
| 1008 | /* Fallthrough */ | 870 | /* Fallthrough */ |
| 1009 | case 'S': | 871 | case 'S': |
| 1010 | case 's': | 872 | case 's': |
| 873 | case 'B': | ||
| 1011 | return symbol_string(buf, end, ptr, spec, *fmt); | 874 | return symbol_string(buf, end, ptr, spec, *fmt); |
| 1012 | case 'R': | 875 | case 'R': |
| 1013 | case 'r': | 876 | case 'r': |
| @@ -1047,16 +910,12 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, | |||
| 1047 | if (spec.field_width == -1) | 910 | if (spec.field_width == -1) |
| 1048 | spec.field_width = 2 * sizeof(void *); | 911 | spec.field_width = 2 * sizeof(void *); |
| 1049 | return string(buf, end, "pK-error", spec); | 912 | return string(buf, end, "pK-error", spec); |
| 1050 | } else if ((kptr_restrict == 0) || | ||
| 1051 | (kptr_restrict == 1 && | ||
| 1052 | has_capability_noaudit(current, CAP_SYSLOG))) | ||
| 1053 | break; | ||
| 1054 | |||
| 1055 | if (spec.field_width == -1) { | ||
| 1056 | spec.field_width = 2 * sizeof(void *); | ||
| 1057 | spec.flags |= ZEROPAD; | ||
| 1058 | } | 913 | } |
| 1059 | return number(buf, end, 0, spec); | 914 | if (!((kptr_restrict == 0) || |
| 915 | (kptr_restrict == 1 && | ||
| 916 | has_capability_noaudit(current, CAP_SYSLOG)))) | ||
| 917 | ptr = NULL; | ||
| 918 | break; | ||
| 1060 | } | 919 | } |
| 1061 | spec.flags |= SMALL; | 920 | spec.flags |= SMALL; |
| 1062 | if (spec.field_width == -1) { | 921 | if (spec.field_width == -1) { |
| @@ -1279,6 +1138,7 @@ qualifier: | |||
| 1279 | * %ps output the name of a text symbol without offset | 1138 | * %ps output the name of a text symbol without offset |
| 1280 | * %pF output the name of a function pointer with its offset | 1139 | * %pF output the name of a function pointer with its offset |
| 1281 | * %pf output the name of a function pointer without its offset | 1140 | * %pf output the name of a function pointer without its offset |
| 1141 | * %pB output the name of a backtrace symbol with its offset | ||
| 1282 | * %pR output the address range in a struct resource with decoded flags | 1142 | * %pR output the address range in a struct resource with decoded flags |
| 1283 | * %pr output the address range in a struct resource with raw flags | 1143 | * %pr output the address range in a struct resource with raw flags |
| 1284 | * %pM output a 6-byte MAC address with colons | 1144 | * %pM output a 6-byte MAC address with colons |
