| glibc.txt: |
| Barret Rhoden |
| Last updated: 2010-08-22 |
| ---------------------------------------------- |
| This document is an attempt to gather knowledge about how to work with the |
| glibc port. This is based on my half-assed struggling with the port done by |
| kevin and andrew. |
| |
| When to recompile (other than when changing libc) |
| -------------------------- |
| Whenever you change a kernel header (something in kern/include/ros), |
| technically you should rebuild. It isn't critical in all places, such as for |
| files that aren't included by glibc, or for files that haven't changed |
| something that glibc relies on. |
| |
| After any recompile, don't forget to rebuild userspace apps (make userclean, |
| make install-libs) and to refresh your FS. |
| |
| How to recompile glibc |
| -------------------------- |
| Normally, make x86 (or whatever) works fairly well. However, sometimes you |
| need to rebuild all of glibc. This might be on a hunch, or to get rid of |
| things that might have compiled, but are failing to link and don't seem to |
| rebuild. This happens when you change parts of glibc. |
| |
| If you know what file(s) you changed and it doesn't seem like the changes are |
| being applied, you can copy the file from the -ros directory to the glibc-XXX |
| directory. The glibc make process doesn't apply diffs or track the changes |
| from -ros to the glibc directory, so your recompile won't notice the changes. |
| |
| If things are stil messed up, the next step is to remove the build directories |
| (i686-ros-glibc-*) and also the hidden files (.i686-ros-glibc*). If you get |
| errors from make very early on about not finding some targets (such as |
| install-headers), you forgot to delete the hidden files. |
| |
| Then next step up would be to remove the glibc-XXX folder (whatever the |
| version is). Sometimes you aren't sure if old changes are sitting around in |
| this folder that aren't getting overwritten by the real source of our changes, |
| the -ros folder. A lovely example of this is an old Makefile for the nss |
| subdir. It was altered to remove some things, notably the files service, |
| which translates into libnss_files - which is needed by other things (nis, |
| etc). To fix this, I had to notice an -ros version of the Makefile (after I |
| realized it was the problem), and that the Makefile was being included - it |
| was just faulty. |
| |
| Finally, you can always make clean, but the overall XCC Makefile will clean |
| everything - including gcc and binutils. |
| |
| Note that if you are making a trivial addition to a kernel header, you can get |
| away with just copying it to its location in the XCC install directory |
| (sys-include). |
| |
| The -ros folder |
| -------------------------- |
| All changes to glibc must be made in the glibc-XXX-ros folder. Any changes |
| here will be copied over to the real glibc folder when it is made. If you |
| want to remove a file that was originally in the -ros folder, you need to |
| manually remove it from the glibc-XXX folder as well. The updating scripts |
| will not remove a file. |
| |
| The sysdeps folder |
| -------------------------- |
| Most of your changes will go here. Every system that has a glibc port should |
| have one of these folders, with its system-specific ports. The files here are |
| normally files expected elsewhere in libc, and the glibc build system knows to |
| look in these places. |
| |
| Simply dropping a file in here will not get it built. It will for many files, |
| but some others that weren't expected will need to be manually added to a |
| Makefile. If you notice some files not getting compiled, (drop a #error in |
| there), you'll need to add it to a Makefile. In the main sysdeps/Makefile, |
| add the filename (minus .c) to the sysdeps var. Look at sa_len for an |
| example. Sometimes you'll need to be careful about adding it for some |
| subdirectories and not others (you probably only want to add a C file for one |
| subdir). Check out Linux's port for help. |
| |
| Sometimes you have files that you want to change outside of the sysdeps |
| folder. These still go in the glibc-XXX-ros folder, but not in sysdeps. The |
| main example we have right now is features.h. At one point, I wanted to |
| change sys/socket.h. Simply adding it to sysdeps/ros/sys/socket.h would not |
| change the main sys/socket.h, nor would the sysdep version get included first. |
| Putting it in the -ros/sys/ folder did it (though ultimately I didn't want the |
| change). The point is, sysdeps doesn't mirror and override the main tree for |
| all files - it is behind some others in the search/include path. |
| |
| Another situation requiring a change outside of the sysdeps directory was |
| sunrpc/netname.c. I wanted to change the functions (stub out the ones that |
| used NSS). Adding the sysdep worked, but it turns out that *both* the sysdep |
| netname.c and the original sunrpc/netname.c were being compiled. The root |
| cause seems to be compat-netname.os. There are make rules in sunrpc to |
| generate some compatibility routines. Grep for rpc-compat-routines.os. The |
| rule seems to ignore sysdeps and just use the normal C file - in this case |
| netname.c. |
| |
| Subdirs |
| -------------------------- |
| As a note, these 'subdirectories' are the "primary folders" (i.e. addons), |
| such as inet, ncsd, libio, whatever. These are the root folders in glibc, |
| representing some major functionality. They can be built with the |
| --enable-addons switch, which by default builds all of them. Sort of! |
| |
| To really get them to even be available for a port, you need to "include" them |
| in a certain manner. There are two ways. One is the Subdirs file in the |
| sysdeps/ros/ directory. Putting a subdir name in here means glibc will try to |
| build it; it is available to be an addon. Careful with these, since a lot of |
| the folders tend to need each other (like most all of the ones in unix/inet). |
| |
| If you want a massive subsystem, such as "unix/inet" or "posix", you can add |
| it to the sysdeps/ros/Implies file. You will get a bunch of these folders at |
| once, plus some other unspecified stuff (necessary for the overall system, |
| perhaps?). If you add "unix/inet", you get more than just its Subdirs. |
| |
| Also note that these subdirs can depend on each other, noted in the "Depends" |
| file. Presumably this will cause them to get made... |
| |
| Errno & TLS |
| -------------------------- |
| errno is a macro that may point to different locations depending on where you |
| are in Glibc. errno_location is simply one of the options. |
| During dynamic linking, the linker points errno to a different location, so it |
| is usable and can be referenced before TLS is fully set up in TLS_INIT_TP. |
| Because errno is valid when the linker runs, regular syscalls can be made. |
| |
| However for statically linked apps, several syscalls cannot use the ros_syscall |
| macro, because there is no valid errno set up. |
| |
| Unimplemented Stubs |
| -------------------------- |
| There are a lot of things we haven't ported, but we have the stub functions so |
| that we can at least compile things against it. When you compile (including |
| regular programs), you'll get warnings about this. |
| |
| Linux ASM bits |
| -------------------------- |
| We've included some header files from Linux's kernel. For now, we just need |
| something to keep glibc happy, even though ROS doesn't have any networking |
| syscalls. Don't rely on this stuff too much. These files, and other future |
| glibc compatibility kernel headers, are in kern/include/ros/glibc-asm. |
| |
| Weak Symbols, start.c, and ros_syscall_blockon |
| -------------------------- |
| For a long time, __ros_syscall_blockon was not getting overridden by the |
| strong symbol in parlib. This means that glibc's syscalls were not blocking |
| uthreads properly. Why did the weak symbols work for vcore_entry() and |
| vcore_event_init(), but not blockon? |
| |
| Side note: we needed to force the linker to find out about vcore_entry and |
| vcore_event_init, via the -u tricks of commit f188983. The linker is not |
| obligated to look in libraries to override a weak symbol. |
| |
| The crux of the matter is that start.c is not linked with applications in the |
| same manner as the rest of glibc (notably all the I/O syscalls). start.c will |
| get linked with the program at compile time, while libc can be linked |
| dynamically. Because of this, start.c's weak symbols would get (correctly) |
| overridden by the strong symbols of libparlib.a. But glibc would build |
| libc.so, and that would not get a chance to link against the binary (and |
| libparlib.a) until load time. The weak symbols in libc get promoted to strong |
| symbols when it is done linking libc.so, and when it later is linked against |
| the program, there is no longer an opportunity to override the weak symbol. |
| |
| Also note that rtld will never link with parlib, so any weak symbol in there |
| will never get overriden. I briefly considered linking rtld with -lparlib, |
| but it blows up in a nasty way: parlib needs lots of libc, which rtld is not |
| built with (memset for example). |
| |
| Anyway, the moral of the story is to be careful with your weak |
| symbols/aliases. Only put them in start.c, or similar files. |
| |
| Adding a Global Variable to the ABI |
| -------------------------- |
| It's not enough to simply 'extern' a variable (or declare a function, which is |
| extern by default). At some point, glibc will change those symbols from |
| GLOBAL to LOCAL. |
| |
| You need to add an entry to the Versions file (sysdeps/ros/Versions). Be sure |
| to indent with spaces, not tabs, or else glibc's scripts will not handle your |
| symbol. |
| |
| Putting them in the libc, glibc 2.0 section seems to work fine. |
| |
| Tips, Questions, and Misc Notes |
| -------------------------- |
| - Grep and find are your friend. |
| - Watch what Linux does. |
| - The kernel headers end up getting installed to the sys-include/ directory, |
| while the regular glib headers go to the include directory. |
| - atomic_swap might have issues (warnings about signedness differences) |
| - It's not always clear which files in the -ros folder actually need to be |
| there (presumably they all do), and in what manner they were modified and |
| from which original copy. Ideally, the ROS-specific changes to large files |
| will be commented. |
| - the SHARED flag is a bit of a mess - things get compiled differently for |
| shared vs static, and it can get complicated with start.c, tls.c, etc. |
| - What things in one file rely heavily on another file? Are there non-obvious |
| gotchas? (yes, and no one documented them). |
| - Is the build failing without any clear error messages? Scroll up a lot, and |
| there may be messages farther up (like a hundred+ lines up). I've had some |
| gcc stage2 builds that fail with no obvious issue in the short term console |
| output, but the real error is much higher. Some aspect of the build system |
| will continue on failures and only fail much later, after building other |
| packages. |
| - Note that libstdc++ is a subpart of gcc, built during stage2, and has its |
| own configure script and settings. |
| |
| Ghetto Things (Feel free to fix them): |
| -------------------------- |
| - ptsname: we needed to have the sysdep (was being looked for by the login |
| subdir make process), but having the actual functions in it caused a link |
| error (multiple declarations). So we have an empty file... |