Page MenuHomeFreeBSD

rtld: remove hand rolled memset and bzero
ClosedPublic

Authored by mjg on Jan 14 2020, 8:14 PM.

Details

Summary

They were introduced to take care of ifunc, but right now no architecture provides ifunc'ed variants. Since rtld uses memset extensively this results in a pessmization. Should someone want to use ifunc here they should provide a mandatory symbol (e.g., rtld_memset).

Probing with dtrace over a binary which calls fexecve in a loop shows a 4 x reduction of time spent in memset on amd64.

Sizes seen when execing the program below:

memset: size 656
memset: size 656
memset: size 944
memset: size 656
memset: size 96
memset: size 240
memset: size 240
memset: size 208
memset: size 50624
memset: size 32
memset: size 56

cpu profile with:

dtrace -w -n 'profile:::profile-4999 /execname =="a.out"/ { @[usym(arg1)] = count(); } tick-5s { system("clear"); trunc(@, 40); printa("%40A %@16d\n", @); clear(@); }'

before:

ld-elf.so.1`matched_symbol              456
 ld-elf.so.1`reloc_non_plt             1067
        ld-elf.so.1`strcmp             1068
   ld-elf.so.1`symlook_obj             1156
        ld-elf.so.1`memset             1667
   ld-elf.so.1`find_symdef             1675

after:

        ld-elf.so.1`memset              460
ld-elf.so.1`matched_symbol              504
        ld-elf.so.1`strcmp             1126
   ld-elf.so.1`symlook_obj             1271
 ld-elf.so.1`reloc_non_plt             1292
   ld-elf.so.1`find_symdef             1659
Test Plan

make tinderbox passes

#include <sys/types.h>
#include <sys/time.h>

#include <err.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

int
main(int argc, char **argv)
{
	char buf[8];
	char *cargv[3];
	int fd;

	switch (argc) {
	case 1:
		fd = open(argv[0], O_EXEC);
		if (fd == -1)
			err(1, "open");
		cargv[0] = argv[0];
		cargv[1] = buf;
		sprintf(cargv[1], "%d", fd);
		cargv[2] = NULL;
		break;
	case 2:
		fd = atoi(argv[1]);
		cargv[0] = argv[0];
		cargv[1] = argv[1];
		cargv[2] = NULL;
		break;
	default:
		printf("invalid argc %d\n", argc);
		exit(1);
	}

	fexecve(fd, cargv, NULL);
	err(1, "fexecve");
}

Diff Detail

Repository
rS FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

mjg created this revision.Jan 14 2020, 8:14 PM
mjg edited the summary of this revision. (Show Details)Jan 14 2020, 8:16 PM
mjg edited the summary of this revision. (Show Details)
kib accepted this revision.Jan 14 2020, 8:39 PM
This revision is now accepted and ready to land.Jan 14 2020, 8:39 PM
This revision was automatically updated to reflect the committed changes.