Roland Mainz wrote: > Hi! > > ---- > > Why is |resolvepath()| called in the "truss" sample below: > -- snip -- > stat64("/usr/lib/libast.so.1", 0xFFBFEF80) = 0 > resolvepath("/usr/lib/libast.so.1", "/usr/lib/libast.so.1", 1023) = 20 > open("/usr/lib/libast.so.1", O_RDONLY) = 3 > mmapobj(3, 0x00020000, 0xFF3F7A48, 0xFFBFF014, 0x00000000) = 0 > close(3) > -- snip -- > > Wouldn't it be easier to just call |open()| directly ? > > ---- > > Bye, > Roland > > P.S.: Why doesn't the code just do an |open()| for each library > _directory_ and then do a |statat()| and |openat()| using the returned > file descriptor ? AFAIK this would save some directory lookup time... >
I'm just speculating here --- the deeper answer lies in the source. I think that there are there are some assumptions underlying this, that the kernel caches recently accessed inodes, that open() is notably more expensive than stat and resolvepath, and that ld.so does not end up needing to open most of the files it stats. ld.so can encounter the same file under more than one name, via symlinks in the path or file, and via relative paths vs. fully qualified ones. Since it only wants to map each such object once, and because it needs to refer to it using a single fully qualified path, resolvepath() is used to canonify the path and compare it to what's already loaded before opening it. I don't know whether openat() would be faster, I suppose it depends on level of "recently accessed inode" caching the kernel does. As the ld.so code predates openat(), I suspect that this is an experiment that simply hasn't been done, probably because this hasn't been seen as a hot spot. - Ali