Finally, I've found some time to update phpMyAdmin packages in Debian to 3.5 series. For long it was not possible due to licensing reasons, but recently this issue was resolved upstream by using jqPlot instead of Highcharts.
While packaging new version, I've also replaced all embedded libraries to use corresponding packages from Debian. I've done some testing and everything seems to work fine, but still this frightens me as some versions are slightly different than upstream.
Anyway new version is available in experimental for now. Ubuntu users can get it from phpMyAdmin PPA.
Filed under: Debian English Phpmyadmin 9 comments Flattr this!
For this prototype to be really useful, some way to automatically
install the proposed packages by pressing the "Please install
program(s)" button should to be implemented.
If this idea seem useful to you, and you want to help make it
happen, please help me update the discover-data database with mappings
from hardware to Debian packages. Check if 'discover-pkginstall -l'
list the package you would like to have installed when a given
hardware device is inserted into your computer, and report bugs using
reportbug if it isn't. Or, if you know of a better way to provide
such mapping, please let me know.
This prototype need more work, and there are several questions that
should be considered before it is ready for production use. Is dbus
the correct way to detect new hardware? At the moment I look for HAL
dbus events on the system bus, because that is the events I could see
on my Debian Squeeze KDE desktop. Are there better events to use?
How should the user be notified? Is the desktop notification
mechanism the best option, or should the background daemon raise a
popup instead? How should packages be installed? When should they
not be installed?
If you want to help getting such feature implemented in Debian,
please send me an email. :)
-d command-line option that changes the
default directory for storing status files.
You can get the latest version from the postfaq distribution page.
Earlier this morning, JJ announced what we had been working on for the last
few weeks: the Rcpp Gallery.
Now, as our luck will have it, the Rcpp-devel list received
his message
but did not transmit it for an apparent mail system outage at WU Vienna: no sign at the
Gmane archive of rcpp-devel
or in the personal mailboxen of myself or anybody I spoke to. Hence, so far,
and preceding this blog announcement, the only way word got out was via this
earlier tweet of mine
from about 12 hours ago.
The Rcpp Gallery is really the brainchild of JJ. It builds on what he
contributed over the last few months in not one but two implementations: Rcpp
Attributes. These are described in a
vignette of their own.
They provide very powerful new functions like sourceCpp
which allow the easiest-yet way to get compiled code into R---see for example these
posts from my blog about
simulating pi
in essentially five lines of R or five lines of C++, or this post about using
the GSL with ease
from R. The Rcpp Gallery also builds on Yihui's excellent
knitr package which
gained the ability to process C++ code just like R code, as well as some
Ruby /
Jekyll magic to build a website on the github
infrastructure. I helped a little on the side by (at long last) learning how
to do prettier websites thanks to Boostrap and its theming extensions.
So what does it do, and what is it for? Have a look around the Rcpp Gallery site.
Each post is based on a single C++ (or Markdown) file which gets digested by
knitr and Rcpp, with the actual output shown alongside the marked up code and
explanatory text. Raw sources are available, just pass them into the
sourceCpp() function from a current Rcpp release and you should have the
same output.
Our idea is to have this as a repository for useful code: from simple and
introductory to fancy and featureful. We already seeded it with several dozen posts
covered anything from lesser known but powerful STL idioms, to Rcpp sugar, to tieing
in Armadillo or GSL, random number generation and of course benchmarking---as
we do love performance.
The entire content is in this github repository,
and our page on
how to contribute
details how you can get involved.
We are looking forward to what is to come. In many ways, we are only just getting started.
A friend wrote me a simple question today. My response turned out to be longer than i expected, but i hope it's useful (and maybe other people will have better suggestions) so i thought i'd share it here too: Angela Starita wrote: I'd like to save my work in a location where I can access it from any computer. I'm wary of using the mechanisms provided by Google and Apple. Can you suggest another service?Here's my reply: I think you're right to be wary of the big cloud providers, who have a tendency to inspect your data to profile you, to participate in arbitrary surveillance regimes, and to try to sell your eyeballs to advertisers. Caveat: You have to trust the client machine too But it's also worth remembering that the network service provider is not the only source of risk. If you really mean "accessing your data from any computer", that means the computer you're using to access the data can do whatever it wants with it. That is, you need to trust both the operator of these "cloud" services, *and* the administrator/operating system of the client computer you're using to access your data. For example, if you log into any "secure" account from a terminal in a web caf , that leaves you vulnerable to the admins of the web caf (and, in the rather-common case of sloppily-administered web terminals, vulnerable to the previous user(s) of the terminal as well). Option 0: Portable physical storage One way to have your data so that you can access it from "any computer" is to not rely on the network at all, but rather to carry a high-capacity MicroSD card (and USB adapter) around with you (you'll probably want to format the card with a widely-understood filesystem like FAT32 instead of NTFS or HFS+ or ext4, which are only understood by some of the major operating systems, but not all). Here is some example hardware: Almost every computer these days has either a microSD slot or a USB port, while some computers are not connected to the network. This also means that you don't have to rely on someone else to manage servers that keep your data available all the time. Note that going the microSD route doesn't remove the caveat about needing to trust the client workstation you're using, and it has another consideration: You'd be responsible for your own backup in the case of hardware failure. You're responsible for your own backup in the case of online storage too, of course -- but the better online companies are probably better equipped than most of us to deal with hardware failure. OTOH, they're also susceptible to some data loss scenarios that we aren't as individual humans (e.g. the company might go bankrupt, or get bought by a competitor who wants to terminate the service, or have a malicious employee who decides to take revenge). Backup of a MicroSD card isn't particularly hard, though: just get a USB stick that's the same size, and regularly duplicate the contents of the MicroSD card to the USB stick. One last consideration is storage size -- MicroSD cards are currently limited to 32GB or 64GB. If you have significantly more data than that, this approach might not be possible, or you might need to switch to a USB hard disk, which would limit your ability to use the data on computers that don't have a USB port (such as some smartphones). Option 1: Proprietary service providers If you don't think this portable physical storage option is the right choice for you, here are a couple proprietary service providers who offer some flavor of "cloud" storage while claiming to not look at the contents of your data: I'm not particularly happy with either of those, though, in part because the local client software they want you to run is proprietary, so there's no way to verify that they are actually unable to access the contents of your data. But i'd be a lot happier with either wuala or spideroak than i would be with google drive, dropbox, or iCloud. Option 2: What i really want I'm much more excited about the network-accessible, free-software, privacy-sensitive network-based storage tool known as git-annex assistant. The project is spearheaded by Joey Hess, who is one of the most skilled and thoughtful software developers i know of. "assistant" (and git-annex, from which it derives) has the advantage of being pretty agnostic about the backend service (many plugins for many different cloud providers) and allows you to encrypt your data locally before sending it to the remote provider. This also means you can put your encrypted data in more than one provider, so that if one of the providers fails for some reason, you can be relatively sure that you have another copy available. But "assistant" won't be ready for Windows or Android for several months (builds are available for Linux and Mac OS X now), so i don't know if it meets the criterion for "accessible from any computer". And, of course, even with the encryption capabilities, the old caveat about needing to trust the local client machine still applies.
So I got an iPod Nano (6th generation) for Christmas this year, just in time since my trusty old iPod Mini started beg for retirement after almost 8 years of usage.
Since my old iPod was working like a charm all those years I expected a smooth sailing when I plugged in my new iPod Nano. Gnome recognized it correctly and mounted the device. The iPod showed up in Rhythmbox as I was used to and I started to fill it with some music. Everything worked as expected: Rhythmbox copied the music to the iPod without complaining and after unmounting the iPod and starting it it was emtpy. Whait, what? Why is it empty? Didn t I just So I tried again, and again with the same result.
Half an hour later I found out that libgpod (the iPod driver for Linux) supports all iPods except the iPod Nano 6G. Bummer. Apparently Apple changed the algorithm to calculate the checksums of the files on the device and since that algorithm is unknown you cannot successfully write on it with free software.
That means technically this device is unusable for Linux users since iTunes doesn t run on Linux. However, there seems to be a way to use the iPod Nano with libgpod if you are trusting this guy and willing to use his binary (only!) file with libgpod (which I am not). And somehow the guys over at Spotify managed to get the iPod Nano running in their Linux client but they don t provide the code either.
Being already more than two years old, I don t have much hope that the iPod Nano will work on Linux with libgpod in the foreseeable future. On the bright side I can say the device is not totally useless as it comes with FM radio
I don t care how silly it is, but the fact that I, for 62 days in a row, I pushed something, closed something or did something worth $EFFORT on GitHub is pretty great.
I m pretty happy with that.
$ echo "W: login: setuid-binary bin/su 4755 root/root" \
lintian-overrider --alternative-forms
--8<-- debian/login.lintian-overrides --8<--
# If you want to override all (present and future) variants
# of this tag, use:
# setuid-binary
setuid-binary bin/su 4755 root/root
# Alternative forms...
# login: setuid-binary bin/su 4755 root/root
# login binary: setuid-binary bin/su 4755 root/root
# For architecture specific overrides, use one of:
# login [i386-any amd64-any other-archs] binary: setuid-binary bin/su 4755 root/root
# login [!i386-any !amd64-any !other-archs] binary: setuid-binary bin/su 4755 root/root
--8<-- End of debian/login.lintian-overrides --8<--
No more fiddling with that stupid syntax. Just feed it to the Lintian-overrider 2000 and instantly you will get the overrides you want!
If you sometimes make a copy-waste mistake or just feel life is too short manually update those files, the Lintian-overrider 2000 is the tool for you! With its --source-dir command line option, your lintian overrrides are updated automatically!
The Lintian-overrider 2000 can also automatically maintain your Lintian overrides for you! It is simple, just do:
$ lintian -o <path/to/your/changes-file.changes> \
lintian-overrider --there-are-no-issues --source-dir <path/to/unpacked/source-tree>
Alioth is ready to take your git clone (or HTTP GET) request, so go order your copy now!
</tv-shop-ad>
I've just confirmed my flight and hotel bookings for FOSDEM 2013, so I'm looking to meet all great people there again.
This year my schedule is not that packed as I have no talks (Weblate lightning talk was not accepted) and also there will be no big phpMyAdmin team meeting, so get in touch if you want to discuss anything with me.
As most of the rooms still don't have a schedule, I can't give you hint where I will be present, but I definitely won't miss Friday beer event and Dieter's talk about phpMyAdmin in MySQL room. The rest pretty much depends on who I will meet :-).
Filed under: Debian English Phpmyadmin Suse Weblate 0 comments Flattr this!
Dear lazyweb.
I remember that not so long ago someone on planet.debian.org shared info about he/she s talk about packaging Debian with link to both video of the talk and sources of presentation. Since I would like to prepare similar talk for some local Polish OpenSource conference I d be thankful if someone could remind me a link in comments.
TIA.
I'm looking for a new position as a Software Developer in eastern Switzerland, southern Germany or remote. Please have a look at my CV if some of the following buzzwords sound interesting to you:
This is my monthly summary of my free software related activities. If you re among the people who made a donation to support my work (836.78 , thanks everybody!), then you can learn how I spent your money. Otherwise it s just an interesting status update on my various projects.
Debian Packaging
I uploaded Zim 0.58, WordPress 3.5 (and I had to file a ticket about the availability of sources of minified javascript files again) and another security update for python-django (696535).
Speaking of python-django, I forwarded one bug report of Anders Kaseorg concerning Django s bash completion (#695811).
I also sponsored the upload of ledgersmb 1.3.25-1.
Other Debian work
I contributed some patches to improve debian-installer support in live-build. I also added a work-around for bug #652946 in live-installer and committed a fix for this same bug in a jessie branch of partman-target.
I also prepared a bugfix for a counter-productive behavior of choose-mirror (#695261, it was not possible to override the codename of the release to install via preseed if you install from a CD with a full base system).
I discovered an oddity in the Packages.diff/Index file for the architectures armhf and s390x, I reported it to ftpmasters in #696792.
(All those issues were discovered while working for a customer)
Debian France
I spent quite some time on Debian France this month again. I started by setting up an internal gitolite to manage our accounting/administrative documents.
Then I updated galette, the web application that we are using to manage our database of members. In the process, I filed two bugs that we discovered. I immediately tested Galette by registering 4 members that joined during the former mini-Debconf in Paris.
We have plans to automate the membership renewal process so we have opened a Paypal account. This month we also cleared the last steps so that I and Sylvestre Ledru have full control on the Debian France bank account.
I also registered the new officers at the Tribunal d instance de Sarreguemines .
Salt bug reports
During the last mini-debconf, I discovered Salt (thanks to Julien Cristau!) and since I had to switch some servers of mine, I took this opportunity to upgrade to wheezy and try out salt at the same time.
It took much more time than expected but the result is pleasant. The configuration of all my servers is now well documented/specified in a central Git repository, and moving services is much easier than before.
In the process, I filed quite some bugs (#2865, #2851, #2866 and #2875), most of them have been fixed in the 0.11.1 release that just happened.
Thanks
I wish you a happy new year and all the best for 2013!
See you next month for a new summary of my activities.
4 comments Liked this article? Click here. My blog is Flattr-enabled.
-l option, which says to add a subheading
to the HTML output giving the last modified date based on the file
modification timestamp. Previously, these subheadings were only added in
some situations and based on RCS/CVS-style Id keywords in the file. Since
I'm converting my personal repositories to Git, that was going to stop
working.
You can get the current version of faq2html from my
web tools distribution page.
With this update, I was able to convert my FAQs repository from Subversion
to Git, which means that I only have one personal repository left in
Subversion (PGP::Sign, which I will probably convert to Git shortly).
That leaves a few CVS repositories, and therein lies a problem.
There are a few places where I'm still using CVS for a conventional
package or for some random files, and those can move to Git without much
trouble whenever I get around to it. But most of my remaining use of CVS
is for storing individual scripts that, if I distribute them at all, I
distribute individually. And, for that, CVS seems to have a lot of
advantages that are hard to implement with Git:
-v output
showing the version number and last modified date. This is a nice
feature; when you have a running script, you can always figure out its
vintage. Maintaining this information in the script by hand is a
pain.
I'm still working on perl-cross-debian (just uploaded 0.0.2) and there's more to do on that with upstream but part of the reason to work on perl cross-building is to do what I can to help with the ARM64 port.
aarch64-linux-gnu-gcc -Wp,-MD,usr/klibc/.__static_init.o.d -nostdinc -iwithprefix
include -I/ PKGBUILDDIR /usr/include/arch/x86_64 -Iusr/include/arch/x86_64
-I/ PKGBUILDDIR /usr/include/bits64
-Iusr/include/bits64 -I/ PKGBUILDDIR /usr/klibc/../include
-Iusr/klibc/../include -I/ PKGBUILDDIR /usr/include -Iusr/include
-I/ PKGBUILDDIR /linux/include -Ilinux/include
-I/ PKGBUILDDIR /linux/arch/x86/include -Ilinux/arch/x86/include
-D__KLIBC__=2 -D__KLIBC_MINOR__=0 -D_BITSIZE=64 -fno-stack-protector -fwrapv -m64 -Os
-fno-asynchronous-unwind-tables -fomit-frame-pointer -falign-functions=1 -falign-jumps=1 -falign-loops=1
-W -Wall -Wno-sign-compare -Wno-unused-parameter -c -o usr/klibc/__static_init.o usr/klibc/__static_init.c
aarch64-linux-gnu-gcc: error: unrecognized command line option '-m64'
make[4]: *** [usr/klibc/__static_init.o] Error 1
--- a/usr/klibc/arch/arm/MCONFIG
+++ b/usr/klibc/arch/arm/MCONFIG
@@ -30,6 +30,13 @@
ifeq ($(CONFIG_AEABI),y)
KLIBCREQFLAGS += -mabi=aapcs-linux -mno-thumb-interwork
else
+# aarch64
+ifeq ($(CONFIG_AARCH64),y)
+KLIBCREQFLAGS +=
+KLIBCOPTFLAGS += -mgeneral-regs-only
+else
KLIBCREQFLAGS += -mabi=apcs-gnu -mno-thumb-interwork
endif
endif
+endif
+
debian/rules
ifeq ($(DEB_HOST_ARCH),arm64)
DEB_MAKE_ENVVARS := ARCH=arm CONFIG_AARCH64=y CPU_ARCH=armv8-a CPU_TUNE=generic
endif
....
code/debian/cross/klibc/klibc-2.0.1/linux/arch/arm/include -Ilinux/arch/arm/include -D__KLIBC__=2
-D__KLIBC_MINOR__=0 -D_BITSIZE=32 -fno-stack-protector -fwrapv -fno-exceptions -Os
-march=armv8-a -mtune=generic -mgeneral-regs-only -W -Wall -Wno-sign-compare -Wno-unused-parameter
-c -o ../foo.o usr/klibc/arch/arm/crt0.S
usr/klibc/arch/arm/crt0.S: Assembler messages:
usr/klibc/arch/arm/crt0.S:19: Error: operand 1 should be an integer register -- mov r0,sp'
usr/klibc/arch/arm/crt0.S:20: Error: operand 1 should be an integer register -- mov r1,#0'
--- a/usr/klibc/arch/arm/crt0.S
+++ b/usr/klibc/arch/arm/crt0.S
@@ -15,9 +15,13 @@
#ifdef __thumb__
.thumb_func
#endif
-
+#ifdef __aarch64__
+_start: mov x0, sp
+ mov x1, #0
+ bl __libc_init
+#else
_start: mov r0, sp
mov r1, #0
bl __libc_init
-
+#endif
.size _start,.-_start
....
klibc-2.0.1/linux/arch/arm/include -Ilinux/arch/arm/include
-D__KLIBC__=2 -D__KLIBC_MINOR__=0 -D_BITSIZE=32 -fno-stack-protector -fwrapv -fno-exceptions -Os
-march=armv8-a -mtune=generic -mgeneral-regs-only -W -Wall -Wno-sign-compare -Wno-unused-parameter
-c -o usr/klibc/arch/arm/setjmp.o usr/klibc/arch/arm/setjmp.S
usr/klibc/arch/arm/setjmp.S: Assembler messages:
usr/klibc/arch/arm/setjmp.S:32: Error: unknown mnemonic stmia' -- stmia r0, r4,r5,r6,r7,r8,r9,r10,fp,sp,lr '
usr/klibc/arch/arm/setjmp.S:33: Error: operand 1 should be an integer register -- mov r0,#0'
usr/klibc/arch/arm/setjmp.S:34: Error: operand 1 should be an integer register -- mov pc,lr'
usr/klibc/arch/arm/setjmp.S:42: Error: unknown mnemonic ldmia' -- ldmia r0, r4,r5,r6,r7,r8,r9,r10,fp,sp,lr '
usr/klibc/arch/arm/setjmp.S:43: Error: unknown mnemonic movs' -- movs r0,r1'
usr/klibc/arch/arm/setjmp.S:44: Error: unknown mnemonic moveq' -- moveq r0,#1'
usr/klibc/arch/arm/setjmp.S:45: Error: operand 1 should be an integer register -- mov pc,lr'
make[5]: *** [usr/klibc/arch/arm/setjmp.o] Error 1
ldconfig: /usr/lib/aarch64-linux-gnu/*.so is for unknown machine 183. in every build log (success or fail) is apparently entirely normal until more packages get fixed. Really slows down scanning the build log.
The new version of the Debian Administration is almost ready now. I'm just waiting on some back-end changes to happen on the excellent BigV hosting product.
I was hoping that the migration would be a fun "Christmas Project", but I had to wait for outside help once or twice and that pushed things back a little. Still it is hard to be anything other than grateful to folk who volunteer time, energy, and enthusiasm.
Otherwise this week has largely consisted of sleeping, planting baby spider-plants, shuffling other plants around (Aloe Vera, Cacti, etc), and enjoying my new moving plant (video isn't my specific plant).
I've spent too long reworking templer such that is now written in a modular fashion and supports plugins. The documentation is overhauled.
The only feedback I received was that it should support inline perl - so I added that as a plugin this morning via a new formatter plugin:
Title: This is my page title Format: perl Name: Steve ---- This is my page. It has inline perl: The sum of 1 + 5 is 1 + 5 This page was written by $nameObQuote: "She even attacked a mime. Just found out about it. Seems the mime had been reluctant to talk. " - Hexed
=item into a
numeric list, something that I really couldn't fix with Pod::Parser.
Also fixed in this release is the bug that got me started down this path:
mishandling of URLs with anchor text.
This is the second Perl module that I've converted to my new coding style
and augmented test suite, and I'm getting a little bit faster at it, but
it still took me a full day. (Although that included the Pod::Simple
rewrite, which required touching most of the code.) I'm not entirely sure
that should have been my top priority today, but oh well, I had to do it
sometime.
You can get the latest version from my web
tools distribution page. I also uploaded a new Debian package to my
personal repository.
I also released spin 1.80, a follow-on from the previous release, that
fixes a bug in the new code to determine last modification date from Git.
int global = 100;
int function(int i)
return i + global;
$gcc -c function.c $objdump --disassemble function.o 0000000000000000 <function>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 89 7d fc mov %edi,-0x4(%rbp) 7: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # d <function+0xd> d: 03 45 fc add -0x4(%rbp),%eax 10: c9 leaveq 11: c3 retqLets just go through that for clarity:
The top portion of the image above gives some idea of how it works. We
can examine relocations in binaries with the readelf tool.
$ readelf --relocs ./function.o Relocation section '.rela.text' at offset 0x518 contains 1 entries: Offset Info Type Sym. Value Sym. Name + Addend 000000000009 000800000002 R_X86_64_PC32 0000000000000000 global + fffffffffffffffcThere are many different types of relocations for different situations; the exact rules for different relocation types are described in the ABI documentation for the architecture. The R_X86_64_PC32 relocation is defined as "the base of the section the symbol is within, plus the symbol value, plus the addend". The addend makes it look more tricky than it is; remember that when an instruction is executing the instruction pointer points to the next instruction to be executed. Therefore, to correctly find the data relative to the instruction pointer, we need to subtract the extra. This can be seen more clearly when layed out in a linear fashion (as in the bottom of the above diagram). If you try and build a shared object (dynamic library) with an object file with this type of relocation, you should get something like:
$ gcc -shared function.c /usr/bin/ld: /tmp/ccQ2ttcT.o: relocation R_X86_64_32 against a local symbol' can not be used when making a shared object; recompile with -fPIC /tmp/ccQ2ttcT.o: could not read symbols: Bad value collect2: ld returned 1 exit statusIf you look back at the disassembly, we notice that the R_X86_64_32 relocation has left only 4-bytes (32-bits) of space left for the relocation entry (the zeros in 7: 8b 15 00 00 00 00). So why does this matter when you're creating a shared library? The first thing to remember is that in a shared library situation, we can not depend on the local value of global actually being the one we want. Consider the following example, where we override the value of global with a LD_PRELOAD library.
$ cat function.c
int global = 100;
int function(int i)
return i + global;
$ gcc -fPIC -shared -o libfunction.so function.c
$ cat preload.c
int global = 200;
$ gcc -shared preload.c -o libpreload.so
$ cat program.c
#include <stdio.h>
int function(int i);
int main(void)
printf("%d\n", function(10));
$ gcc -L. -lfunction program.c -o program
$ LD_LIBRARY_PATH=. ./program
110
$ LD_PRELOAD=libpreload.so LD_LIBRARY_PATH=. ./program
210
If the code in libfunction.so were to have a fixed offset into its
own data section, it will not be able to be overridden at run-time by
the value provided by libpreload.so. Additionally, there are only
4-bytes available to patch in for the address of global -- since a
shared library could conceivably be loaded anywhere in the 64-bit
(8-byte) address space we therefore need 8-bytes of space to cover
ourselves for all possible addresses global might turn up at.
The two basic possibilities for an object file are to be either linked
into an executable or linked into a shared-library. In the executable
case, the value of global will be in the exectuable's data
section, which should definitely be reachable with a 32-bit offset of
the current instruction-pointer. The instruction-pointer relative
address can simply be patched in and the executable is finalised.
But what about the shared-library case, where we know the value of
global could essentially be anywhere within the 64-bit address
space? It is possible to leave 8-bytes of space for the address of
global, by telling gcc to use the large-code model. e.g.
$ gcc -c -mcmodel=large function.c $ objdump --disassemble ./function.o ./function.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <function>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 89 7d fc mov %edi,-0x4(%rbp) 7: 48 b8 00 00 00 00 00 movabs $0x0,%rax e: 00 00 00 11: 8b 10 mov (%rax),%edx 13: 8b 45 fc mov -0x4(%rbp),%eax 16: 01 d0 add %edx,%eax 18: 5d pop %rbp 19: c3 retqHowever, this creates a problem if you really want to share this code. By having to patch in an address of global directly, this means the run-time code above does not remain unchanged. Two separate processes therefore can't share this code -- they each need separate copies that are identical but for their own addresses of global patched into it. By enabling Position Independent Code (PIC, with the flag -fPIC) you can ensure the code remains share-able. PIC means that the output binary does not expect to be loaded at a particular base address, but is happy being put anywhere in memory (compare the output of readelf --segments on a binary such as /bin/ls to that of any shared library). This is obviously critical for implementing lazy-loading (i.e. only loaded when required) shared-libraries, where you may have many libraries loaded in essentially any order at any location. Of course, any problem in computer science can be solved with a layer of abstraction and that is essentially what is done when compiling with -fPIC. To examine this case, let's see what happens with PIC turned on.
$ gcc -fPIC -shared -c function.c $ objdump --disassemble ./function.o ./function.o: file format elf64-x86-64 Disassembly of section .text: 0000000000000000 <function>: 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 89 7d fc mov %edi,-0x4(%rbp) 7: 48 8b 05 00 00 00 00 mov 0x0(%rip),%rax # e <function+0xe> e: 8b 00 mov (%rax),%eax 10: 03 45 fc add -0x4(%rbp),%eax 13: c9 leaveq 14: c3 retqIt's almost the same! We setup the frame pointer with the first two instructions as before. We push the first argument into memory in the pre-allocated "red-zone" as before. Then, however, we do an IP relative load of an address into rax. Next we de-reference this into eax (e.g. eax = *rax in C) before adding the incoming argument to it and returning.
$ readelf --relocs ./function.o Relocation section '.rela.text' at offset 0x550 contains 1 entries: Offset Info Type Sym. Value Sym. Name + Addend 00000000000a 000800000009 R_X86_64_GOTPCREL 0000000000000000 global + fffffffffffffffcThe magic here is again in the relocations. Notice this time we have a P_X86_64_GOTPCREL relocation. This says "replace the data at offset 0xa with the global offset table (GOT) entry of global.
As shown above, the GOT ensures the abstraction required so symbols
can be diverted as expected. Each entry is essentially a pointer to
the real data (hence the extra dereference in the code above). Since
we can assume the GOT is at a fixed offset from the program code
within plus or minus 2Gib, the code can use a 32-bit IP relative
address to gain access to the table entries.
So, taking a look a the final shared-library binary we see a final
offset hard-coded
$ gcc -shared -fPIC -o libfunction.so function.c $ objdump --disassemble ./libfunction.so 00000000000006b0 <function>: 6b0: 55 push %rbp 6b1: 48 89 e5 mov %rsp,%rbp 6b4: 89 7d fc mov %edi,-0x4(%rbp) 6b7: 48 8b 05 8a 02 20 00 mov 0x20028a(%rip),%rax # 200948 <_DYNAMIC+0x1d8> 6be: 8b 10 mov (%rax),%edx 6c0: 8b 45 fc mov -0x4(%rbp),%eax 6c3: 01 d0 add %edx,%eax 6c5: 5d pop %rbp 6c6: c3 retq 6c7: 90 nopEvery process who wants to share this code just needs to make sure they have their unique address of global at 0x20028a(%rip). Since each process has a separate address-space, this means they can all have different values for global but share the same code! Thus the default of the small-code model is sensible. It is exceedingly rare for an executable to need more than 4-byte offsets for a relative access to a variable in it's data region, so using a full 8-byte value would just be a waste of space. Although leaving 8-bytes would allow access to the variable anywhere in the 64-bit address space; when building a shared library, you really want to use -fPIC to ensure the library can actually be shared, which introduces a different relocation and access to data via the GOT. This should explain why gcc -shared function.c works on x86-32, but does not work on x86-64. Inspecting the code reveals why:
$ objdump --disassemble ./function.o 00000000 <function>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: a1 00 00 00 00 mov 0x0,%eax 8: 03 45 08 add 0x8(%ebp),%eax b: 5d pop %ebp c: c3 ret $ readelf --relocs ./function.o Relocation section '.rel.text' at offset 0x2ec contains 1 entries: Offset Info Type Sym.Value Sym. Name 00000004 00000701 R_386_32 00000000 globalWe start out the same, with the first two instructions setting up the frame pointer. However, next we load a memory value into eax -- as we can see from the relocation information, the address of global. Next we add the incoming argument from the stack (0x8(%ebp)) to the value in this memory location; implicitly dereferencing it. But since we only have a 32-bit address-space, the 4-bytes allocated is enough to access any possible address. So while this can work, you're not creating position-independent code and hence not enabling code-sharing. The disadvantage of PIC code is that you require "bouncing" through the GOT, which requires more loads and reads to find an address than directly referencing it. However, if your program is at the point that this is becoming a performance issue you're probably not reading this blog! Hopefully, this helps clear up that possibly cryptic error message. Further searches around position-independent code, global-offset tables and code-sharing should also yield you more information if it remains unclear.
Next.