diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2015-01-02 22:31:07 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2015-01-02 22:31:07 +0100 |
commit | 908b6e5dfdbc81322680ce939e5415161c637bb4 (patch) | |
tree | d3a5d43b353963cf0ac8faa79b5839c611e63c40 | |
parent | 1da09cfacf1c4789cc74322857a098c2ddb06e31 (diff) | |
download | busybox-w32-908b6e5dfdbc81322680ce939e5415161c637bb4.tar.gz busybox-w32-908b6e5dfdbc81322680ce939e5415161c637bb4.tar.bz2 busybox-w32-908b6e5dfdbc81322680ce939e5415161c637bb4.zip |
libpwdgrp: use FAST_FUNC to make "matching ABI" optimization more likely to succeed
See bb_internal_get*nam_r size reduction:
function old new delta
bb_internal_getpwent_r 167 176 +9
getXXnam_r 204 206 +2
sulogin_main 326 325 -1
su_main 471 470 -1
read_line_input 3832 3831 -1
print_stat 865 864 -1
prepare_socket_fd 283 282 -1
load_crontab 777 776 -1
fork_job 456 455 -1
do_shm 884 883 -1
do_sem 637 636 -1
do_msg 783 782 -1
complete_username 124 123 -1
bb_internal_getgrouplist 71 70 -1
xgetpwuid 27 25 -2
xgetpwnam 27 25 -2
xgetgrnam 27 25 -2
xgetgrgid 27 25 -2
uid2uname 18 16 -2
login_main 980 978 -2
gid2group 18 16 -2
get_shell_name 54 52 -2
change_identity 50 48 -2
bb_internal_initgroups 50 48 -2
argstr 1261 1259 -2
print_perms 177 174 -3
inetd_main 2077 2074 -3
run_applet_no_and_exit 446 442 -4
fileaction_setowngrp 89 85 -4
deluser_main 312 308 -4
bb_internal_getpwuid 19 15 -4
bb_internal_getpwnam 11 7 -4
bb_internal_getgrnam 14 10 -4
bb_internal_getgrgid 19 15 -4
adduser_main 865 861 -4
passwd_main 989 984 -5
get_passwd 97 92 -5
data_extract_all 887 882 -5
check_user_passwd 490 485 -5
get_groups 81 75 -6
ftpd_main 2178 2171 -7
bb_internal_getspnam_r 42 18 -24
bb_internal_getpwnam_r 39 15 -24
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 2/41 up/down: 11/-153) Total: -142 bytes
text data bss dec hex filename
923167 928 17676 941771 e5ecb busybox_old
923023 928 17676 941627 e5e3b busybox_unstripped
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | include/grp_.h | 11 | ||||
-rw-r--r-- | include/pwd_.h | 14 | ||||
-rw-r--r-- | include/shadow_.h | 26 | ||||
-rw-r--r-- | libpwdgrp/pwd_grp.c | 32 |
4 files changed, 41 insertions, 42 deletions
diff --git a/include/grp_.h b/include/grp_.h index f7b8d836f..db13ce3b4 100644 --- a/include/grp_.h +++ b/include/grp_.h | |||
@@ -36,31 +36,30 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN | |||
36 | #define getgrouplist bb_internal_getgrouplist | 36 | #define getgrouplist bb_internal_getgrouplist |
37 | #define initgroups bb_internal_initgroups | 37 | #define initgroups bb_internal_initgroups |
38 | 38 | ||
39 | |||
40 | /* All function names below should be remapped by #defines above | 39 | /* All function names below should be remapped by #defines above |
41 | * in order to not collide with libc names. */ | 40 | * in order to not collide with libc names. */ |
42 | 41 | ||
43 | /* Close the group-file stream. */ | 42 | /* Close the group-file stream. */ |
44 | extern void endgrent(void); | 43 | void FAST_FUNC endgrent(void); |
45 | 44 | ||
46 | /* Search for an entry with a matching group ID. */ | 45 | /* Search for an entry with a matching group ID. */ |
47 | extern struct group *getgrgid(gid_t __gid); | 46 | struct group* FAST_FUNC getgrgid(gid_t __gid); |
48 | 47 | ||
49 | /* Search for an entry with a matching group name. */ | 48 | /* Search for an entry with a matching group name. */ |
50 | extern struct group *getgrnam(const char *__name); | 49 | struct group* FAST_FUNC getgrnam(const char *__name); |
51 | 50 | ||
52 | /* Reentrant versions of some of the functions above. */ | 51 | /* Reentrant versions of some of the functions above. */ |
53 | 52 | ||
54 | /* Store at most *NGROUPS members of the group set for USER into | 53 | /* Store at most *NGROUPS members of the group set for USER into |
55 | *GROUPS. Also include GROUP. The actual number of groups found is | 54 | *GROUPS. Also include GROUP. The actual number of groups found is |
56 | returned in *NGROUPS. Return -1 if the if *NGROUPS is too small. */ | 55 | returned in *NGROUPS. Return -1 if the if *NGROUPS is too small. */ |
57 | extern int getgrouplist(const char *__user, gid_t __group, | 56 | int FAST_FUNC getgrouplist(const char *__user, gid_t __group, |
58 | gid_t *__groups, int *__ngroups); | 57 | gid_t *__groups, int *__ngroups); |
59 | 58 | ||
60 | /* Initialize the group set for the current user | 59 | /* Initialize the group set for the current user |
61 | by reading the group database and using all groups | 60 | by reading the group database and using all groups |
62 | of which USER is a member. Also include GROUP. */ | 61 | of which USER is a member. Also include GROUP. */ |
63 | extern int initgroups(const char *__user, gid_t __group); | 62 | int FAST_FUNC initgroups(const char *__user, gid_t __group); |
64 | 63 | ||
65 | POP_SAVED_FUNCTION_VISIBILITY | 64 | POP_SAVED_FUNCTION_VISIBILITY |
66 | 65 | ||
diff --git a/include/pwd_.h b/include/pwd_.h index d086f86e3..32b5b366e 100644 --- a/include/pwd_.h +++ b/include/pwd_.h | |||
@@ -43,21 +43,21 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN | |||
43 | * in order to not collide with libc names. */ | 43 | * in order to not collide with libc names. */ |
44 | 44 | ||
45 | /* Rewind the password-file stream. */ | 45 | /* Rewind the password-file stream. */ |
46 | extern void setpwent(void); | 46 | void FAST_FUNC setpwent(void); |
47 | 47 | ||
48 | /* Close the password-file stream. */ | 48 | /* Close the password-file stream. */ |
49 | extern void endpwent(void); | 49 | void FAST_FUNC endpwent(void); |
50 | 50 | ||
51 | #ifdef UNUSED_SINCE_WE_AVOID_STATIC_BUFS | 51 | #ifdef UNUSED_SINCE_WE_AVOID_STATIC_BUFS |
52 | /* Read an entry from the password-file stream, opening it if necessary. */ | 52 | /* Read an entry from the password-file stream, opening it if necessary. */ |
53 | extern struct passwd *getpwent(void); | 53 | struct passwd* FAST_FUNC getpwent(void); |
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | /* Search for an entry with a matching user ID. */ | 56 | /* Search for an entry with a matching user ID. */ |
57 | extern struct passwd *getpwuid(uid_t __uid); | 57 | struct passwd* FAST_FUNC getpwuid(uid_t __uid); |
58 | 58 | ||
59 | /* Search for an entry with a matching username. */ | 59 | /* Search for an entry with a matching username. */ |
60 | extern struct passwd *getpwnam(const char *__name); | 60 | struct passwd* FAST_FUNC getpwnam(const char *__name); |
61 | 61 | ||
62 | /* Reentrant versions of some of the functions above. | 62 | /* Reentrant versions of some of the functions above. |
63 | 63 | ||
@@ -67,11 +67,11 @@ extern struct passwd *getpwnam(const char *__name); | |||
67 | other reentrant functions so the chances are good this is what the | 67 | other reentrant functions so the chances are good this is what the |
68 | POSIX people would choose. */ | 68 | POSIX people would choose. */ |
69 | 69 | ||
70 | extern int getpwent_r(struct passwd *__restrict __resultbuf, | 70 | int FAST_FUNC getpwent_r(struct passwd *__restrict __resultbuf, |
71 | char *__restrict __buffer, size_t __buflen, | 71 | char *__restrict __buffer, size_t __buflen, |
72 | struct passwd **__restrict __result); | 72 | struct passwd **__restrict __result); |
73 | 73 | ||
74 | extern int getpwnam_r(const char *__restrict __name, | 74 | int FAST_FUNC getpwnam_r(const char *__restrict __name, |
75 | struct passwd *__restrict __resultbuf, | 75 | struct passwd *__restrict __resultbuf, |
76 | char *__restrict __buffer, size_t __buflen, | 76 | char *__restrict __buffer, size_t __buflen, |
77 | struct passwd **__restrict __result); | 77 | struct passwd **__restrict __result); |
diff --git a/include/shadow_.h b/include/shadow_.h index 7babe4f30..8e2581e7c 100644 --- a/include/shadow_.h +++ b/include/shadow_.h | |||
@@ -57,48 +57,48 @@ struct spwd { | |||
57 | 57 | ||
58 | #ifdef UNUSED_FOR_NOW | 58 | #ifdef UNUSED_FOR_NOW |
59 | /* Open database for reading */ | 59 | /* Open database for reading */ |
60 | extern void setspent(void); | 60 | void FAST_FUNC setspent(void); |
61 | 61 | ||
62 | /* Close database */ | 62 | /* Close database */ |
63 | extern void endspent(void); | 63 | void FAST_FUNC endspent(void); |
64 | 64 | ||
65 | /* Get next entry from database, perhaps after opening the file */ | 65 | /* Get next entry from database, perhaps after opening the file */ |
66 | extern struct spwd *getspent(void); | 66 | struct spwd* FAST_FUNC getspent(void); |
67 | 67 | ||
68 | /* Get shadow entry matching NAME */ | 68 | /* Get shadow entry matching NAME */ |
69 | extern struct spwd *getspnam(const char *__name); | 69 | struct spwd* FAST_FUNC getspnam(const char *__name); |
70 | 70 | ||
71 | /* Read shadow entry from STRING */ | 71 | /* Read shadow entry from STRING */ |
72 | extern struct spwd *sgetspent(const char *__string); | 72 | struct spwd* FAST_FUNC sgetspent(const char *__string); |
73 | 73 | ||
74 | /* Read next shadow entry from STREAM */ | 74 | /* Read next shadow entry from STREAM */ |
75 | extern struct spwd *fgetspent(FILE *__stream); | 75 | struct spwd* FAST_FUNC fgetspent(FILE *__stream); |
76 | 76 | ||
77 | /* Write line containing shadow password entry to stream */ | 77 | /* Write line containing shadow password entry to stream */ |
78 | extern int putspent(const struct spwd *__p, FILE *__stream); | 78 | int FAST_FUNC putspent(const struct spwd *__p, FILE *__stream); |
79 | 79 | ||
80 | /* Reentrant versions of some of the functions above */ | 80 | /* Reentrant versions of some of the functions above */ |
81 | extern int getspent_r(struct spwd *__result_buf, char *__buffer, | 81 | int FAST_FUNC getspent_r(struct spwd *__result_buf, char *__buffer, |
82 | size_t __buflen, struct spwd **__result); | 82 | size_t __buflen, struct spwd **__result); |
83 | #endif | 83 | #endif |
84 | 84 | ||
85 | extern int getspnam_r(const char *__name, struct spwd *__result_buf, | 85 | int FAST_FUNC getspnam_r(const char *__name, struct spwd *__result_buf, |
86 | char *__buffer, size_t __buflen, | 86 | char *__buffer, size_t __buflen, |
87 | struct spwd **__result); | 87 | struct spwd **__result); |
88 | 88 | ||
89 | #ifdef UNUSED_FOR_NOW | 89 | #ifdef UNUSED_FOR_NOW |
90 | extern int sgetspent_r(const char *__string, struct spwd *__result_buf, | 90 | int FAST_FUNC sgetspent_r(const char *__string, struct spwd *__result_buf, |
91 | char *__buffer, size_t __buflen, | 91 | char *__buffer, size_t __buflen, |
92 | struct spwd **__result); | 92 | struct spwd **__result); |
93 | 93 | ||
94 | extern int fgetspent_r(FILE *__stream, struct spwd *__result_buf, | 94 | int FAST_FUNC fgetspent_r(FILE *__stream, struct spwd *__result_buf, |
95 | char *__buffer, size_t __buflen, | 95 | char *__buffer, size_t __buflen, |
96 | struct spwd **__result); | 96 | struct spwd **__result); |
97 | /* Protect password file against multi writers */ | 97 | /* Protect password file against multi writers */ |
98 | extern int lckpwdf(void); | 98 | int FAST_FUNC lckpwdf(void); |
99 | 99 | ||
100 | /* Unlock password file */ | 100 | /* Unlock password file */ |
101 | extern int ulckpwdf(void); | 101 | int FAST_FUNC ulckpwdf(void); |
102 | #endif | 102 | #endif |
103 | 103 | ||
104 | POP_SAVED_FUNCTION_VISIBILITY | 104 | POP_SAVED_FUNCTION_VISIBILITY |
diff --git a/libpwdgrp/pwd_grp.c b/libpwdgrp/pwd_grp.c index ed8370124..0d8e2bb5c 100644 --- a/libpwdgrp/pwd_grp.c +++ b/libpwdgrp/pwd_grp.c | |||
@@ -288,7 +288,7 @@ static void *convert_to_struct(const char *def, const unsigned char *off, | |||
288 | 288 | ||
289 | /****** getXXnam/id_r */ | 289 | /****** getXXnam/id_r */ |
290 | 290 | ||
291 | static int getXXnam_r(const char *name, uintptr_t db_and_field_pos, char *buffer, size_t buflen, | 291 | static int FAST_FUNC getXXnam_r(const char *name, uintptr_t db_and_field_pos, char *buffer, size_t buflen, |
292 | void *result) | 292 | void *result) |
293 | { | 293 | { |
294 | void *struct_buf = *(void**)result; | 294 | void *struct_buf = *(void**)result; |
@@ -316,18 +316,18 @@ static int getXXnam_r(const char *name, uintptr_t db_and_field_pos, char *buffer | |||
316 | return errno; | 316 | return errno; |
317 | } | 317 | } |
318 | 318 | ||
319 | int getpwnam_r(const char *name, struct passwd *struct_buf, char *buffer, size_t buflen, | 319 | int FAST_FUNC getpwnam_r(const char *name, struct passwd *struct_buf, char *buffer, size_t buflen, |
320 | struct passwd **result) | 320 | struct passwd **result) |
321 | { | 321 | { |
322 | /* Why the "store buffer address in result" trick? | 322 | /* Why the "store buffer address in result" trick? |
323 | * This way, getXXnam_r has the same ABI signature as getpwnam_r, | 323 | * This way, getXXnam_r has the same ABI signature as getpwnam_r, |
324 | * hopefully compiler can optimize tall call better in this case. | 324 | * hopefully compiler can optimize tail call better in this case. |
325 | */ | 325 | */ |
326 | *result = struct_buf; | 326 | *result = struct_buf; |
327 | return getXXnam_r(name, (0 << 2) + 0, buffer, buflen, result); | 327 | return getXXnam_r(name, (0 << 2) + 0, buffer, buflen, result); |
328 | } | 328 | } |
329 | #if ENABLE_USE_BB_SHADOW | 329 | #if ENABLE_USE_BB_SHADOW |
330 | int getspnam_r(const char *name, struct spwd *struct_buf, char *buffer, size_t buflen, | 330 | int FAST_FUNC getspnam_r(const char *name, struct spwd *struct_buf, char *buffer, size_t buflen, |
331 | struct spwd **result) | 331 | struct spwd **result) |
332 | { | 332 | { |
333 | *result = struct_buf; | 333 | *result = struct_buf; |
@@ -337,7 +337,7 @@ int getspnam_r(const char *name, struct spwd *struct_buf, char *buffer, size_t b | |||
337 | 337 | ||
338 | /****** getXXent_r */ | 338 | /****** getXXent_r */ |
339 | 339 | ||
340 | static int getXXent_r(void *struct_buf, char *buffer, size_t buflen, | 340 | static int FAST_FUNC getXXent_r(void *struct_buf, char *buffer, size_t buflen, |
341 | void *result, | 341 | void *result, |
342 | unsigned db_idx) | 342 | unsigned db_idx) |
343 | { | 343 | { |
@@ -374,14 +374,14 @@ static int getXXent_r(void *struct_buf, char *buffer, size_t buflen, | |||
374 | return errno; | 374 | return errno; |
375 | } | 375 | } |
376 | 376 | ||
377 | int getpwent_r(struct passwd *struct_buf, char *buffer, size_t buflen, struct passwd **result) | 377 | int FAST_FUNC getpwent_r(struct passwd *struct_buf, char *buffer, size_t buflen, struct passwd **result) |
378 | { | 378 | { |
379 | return getXXent_r(struct_buf, buffer, buflen, result, 0); | 379 | return getXXent_r(struct_buf, buffer, buflen, result, 0); |
380 | } | 380 | } |
381 | 381 | ||
382 | /****** getXXnam/id */ | 382 | /****** getXXnam/id */ |
383 | 383 | ||
384 | static void *getXXnam(const char *name, unsigned db_and_field_pos) | 384 | static void* FAST_FUNC getXXnam(const char *name, unsigned db_and_field_pos) |
385 | { | 385 | { |
386 | char *buf; | 386 | char *buf; |
387 | void *result; | 387 | void *result; |
@@ -409,39 +409,39 @@ static void *getXXnam(const char *name, unsigned db_and_field_pos) | |||
409 | return result; | 409 | return result; |
410 | } | 410 | } |
411 | 411 | ||
412 | struct passwd *getpwnam(const char *name) | 412 | struct passwd* FAST_FUNC getpwnam(const char *name) |
413 | { | 413 | { |
414 | return getXXnam(name, (0 << 2) + 0); | 414 | return getXXnam(name, (0 << 2) + 0); |
415 | } | 415 | } |
416 | struct group *getgrnam(const char *name) | 416 | struct group* FAST_FUNC getgrnam(const char *name) |
417 | { | 417 | { |
418 | return getXXnam(name, (1 << 2) + 0); | 418 | return getXXnam(name, (1 << 2) + 0); |
419 | } | 419 | } |
420 | struct passwd *getpwuid(uid_t id) | 420 | struct passwd* FAST_FUNC getpwuid(uid_t id) |
421 | { | 421 | { |
422 | return getXXnam(utoa(id), (0 << 2) + 2); | 422 | return getXXnam(utoa(id), (0 << 2) + 2); |
423 | } | 423 | } |
424 | struct group *getgrgid(gid_t id) | 424 | struct group* FAST_FUNC getgrgid(gid_t id) |
425 | { | 425 | { |
426 | return getXXnam(utoa(id), (1 << 2) + 2); | 426 | return getXXnam(utoa(id), (1 << 2) + 2); |
427 | } | 427 | } |
428 | 428 | ||
429 | /****** end/setXXend */ | 429 | /****** end/setXXend */ |
430 | 430 | ||
431 | void endpwent(void) | 431 | void FAST_FUNC endpwent(void) |
432 | { | 432 | { |
433 | if (has_S && S.db[0].fp) { | 433 | if (has_S && S.db[0].fp) { |
434 | fclose(S.db[0].fp); | 434 | fclose(S.db[0].fp); |
435 | S.db[0].fp = NULL; | 435 | S.db[0].fp = NULL; |
436 | } | 436 | } |
437 | } | 437 | } |
438 | void setpwent(void) | 438 | void FAST_FUNC setpwent(void) |
439 | { | 439 | { |
440 | if (has_S && S.db[0].fp) { | 440 | if (has_S && S.db[0].fp) { |
441 | rewind(S.db[0].fp); | 441 | rewind(S.db[0].fp); |
442 | } | 442 | } |
443 | } | 443 | } |
444 | void endgrent(void) | 444 | void FAST_FUNC endgrent(void) |
445 | { | 445 | { |
446 | if (has_S && S.db[1].fp) { | 446 | if (has_S && S.db[1].fp) { |
447 | fclose(S.db[1].fp); | 447 | fclose(S.db[1].fp); |
@@ -491,7 +491,7 @@ static gid_t* FAST_FUNC getgrouplist_internal(int *ngroups_ptr, | |||
491 | return group_list; | 491 | return group_list; |
492 | } | 492 | } |
493 | 493 | ||
494 | int initgroups(const char *user, gid_t gid) | 494 | int FAST_FUNC initgroups(const char *user, gid_t gid) |
495 | { | 495 | { |
496 | int ngroups; | 496 | int ngroups; |
497 | gid_t *group_list = getgrouplist_internal(&ngroups, user, gid); | 497 | gid_t *group_list = getgrouplist_internal(&ngroups, user, gid); |
@@ -501,7 +501,7 @@ int initgroups(const char *user, gid_t gid) | |||
501 | return ngroups; | 501 | return ngroups; |
502 | } | 502 | } |
503 | 503 | ||
504 | int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups) | 504 | int FAST_FUNC getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups) |
505 | { | 505 | { |
506 | int ngroups_old = *ngroups; | 506 | int ngroups_old = *ngroups; |
507 | gid_t *group_list = getgrouplist_internal(ngroups, user, gid); | 507 | gid_t *group_list = getgrouplist_internal(ngroups, user, gid); |