Are there any lists compiled that provide a list of linux system calls used per function in a standard glibc build?
No, because that both depends on the target the glibc gets built for, the capabilities of the kernel glibc detects at runtime, and, rarely, due to what I'd consider bugs, also whether the platform glibc was built on is the same as it is targetting¹.
For example, free() requires mmap, munmap, mprotect, prlimit64, and brk.
On your version of linux, at least.
If necessary I can figure this out by grepping the source code
nope, some of this is runtime-decided,
or some strace wizardry,
"wizardry" such as straightforward running of strace attached to your process of interest. Do note that just because libc call a(param *p) makes syscalls sa, sb and sc when *p=42, that's not true for other values, and especially not when a passed pointer is NULL. (For example, free(0) makes no syscalls; if you're mallocing memory that is already available in the allocation arena, then potentially no syscalls are made, either.)
You will also notice that even on the same machine, same program, same execution path so far, libc calls might or might not need to make syscalls – for example, depending on whether sysfs is visible for a process, or depending on the presence of a vdso allowing to query timers simply by reading userland-mapped hardware memory regions.
So,
- neither is it possible from code reading to know what actually happens in the execution context, nor
- is it static within an execution context what syscalls are involved in execution of a libc function.
but I know from practical experience that this info changes for most functions very rarely.
My experience is different here: Especially for libc function involved with handling files and paths, a lot depends on the kernel capabilities, the privileges of the executing process. Also, glibc (and any other libc) is intended as an abstraction over the underlying operating system API; so changing the usage of that API without making a fuzz about it is actually pretty sensible.
You'll notice, for example, that glibc updates on debian often lead to an update of a lot of apparmor profiles. Exactly that reason!
So, no, this is not documentable behaviour. You should not depend on implementation detail of your libc with respect to the syscalls made.
¹ for example: that can happen when you're cross-compiling glibc for Linux. The configure scripts fail to understand that even when cross-compiling, the getcwd Linux syscall is available; thus, on the right combination of build host and target, you can end up in a situation where the libc call getcwd, instead of making the eponymous linux syscall, falls back to recursivelya building of the path, by directory listing the parent directory, and looking for the entry with current directory's inode number, repeating until the root of the file system is reached. This leads to the most interesting effects when any of the directories in that chain happens to be deleted or moved around during that very-many-syscalls operation.