Live data from Hacker News

32-bit x86 Position Independent Code – It's That Bad

ewontfix.com

41–50 of 104 posts

Re: 32-bit x86 Position Independent Code – It's That Bad

#41
post #40
post #36

Earlier quoted context omitted.

mincore is a system call and does not take a pid parameter. This means it has to be executed by each process individually, which would require injecting code into each running process and executing it in some way. Unless there's a tool which makes this extremely simple (maybe Intel's pin?), I believe that writing a kernel module is simpler. The module's init function tallies up the pages and writes out the result int…

You don't need to run mincore() on target pids - you just need to write a tool that opens(O_RDONLY) and mmaps(PROT_READ) each library file, then calls mincore() on each page in the mapping to find out which pages of the library are loaded shared. The results of mincore() in one process with a shared mapping of a file are enough to tell you how much of that file is loaded shared system-wide.

Ah, good point! Though I think I'll do a dlopen on each file to mimic whatever the loader usually does. I'll do it as a weekend-project :)

Re: 32-bit x86 Position Independent Code – It's That Bad

#43
post #9
post #2

The more I play around with musl (the author's C library) the more I'm convinced dynamic linking was not worth the trouble.

One of the main reasons for dynamic linking has become irrelevant, I believe: the availability of disk and memory space has grown faster than the size of the binary objects.

So I take it you're offering to buy me some more RAM, then? Unfortunately, my motherboard is already full at 4GB so this upgrade would be more expensive than you might expect at firs. What about my friends that have older 2GB laptgops? Do they get an upgrade too?

I'm joking, of course, but there IS a lot of variation in computer hardware, which makes this kind of broad generalization even more problematic.

Also, memory size is probably not that useful of a metric for modern hardware, where the penalty for overflowing the CPU caches can be huge.

edit:

Why statically link when you can prelink(8) instead?

( http://linux.die.net/man/8/prelink )

Re: 32-bit x86 Position Independent Code – It's That Bad

#44
post #12

So what's the story on 64-bit x64 or other processors?

There are some pretty pictures here which help to explain how x86_64 handles relocations in a much less cumbersome way: http://www.mindfruit.co.uk/2012/06/relocations-relocations.h...

Re: 32-bit x86 Position Independent Code – It's That Bad

#45
post #42

> Obviously what we'd like to see is: "foo: jmp bar" Shouldn't that be "foo: call bar"?

I think it's JMP due to tail-call optimization. If there's a JMP, the RET of the inner function (bar) returns from the outer one (foo) also, and one unnecessary jump is eliminated.

Re: 32-bit x86 Position Independent Code – It's That Bad

#46
post #3

I always wondered why Linux can't just use the same thing as windows for DLLs: Instead of PIC, a big tables of places to patch with the final position. It looks really terrible to lose one precious register and have all this PIC overhead. I don't use mono's ahead of time compilation because it also creates PIC. The JIT has one register more available. But I haven't measured it yet

> Instead of PIC, a big tables of places to patch with the final position. Among other things, because that means the text section has to be writeable, and can't have a shared mapping across processes unless it's mapped in the same place in every process, which breaks address-space layout randomization (ASLR).

Windows has ASLR too (since Vista) and it works with existing DLLs. Only pages which contain relocations can't be shared, which in practice means only code that accesses global data (including calls through the import table to other modules.) All the other pages can be.

The whole process image is writable when the loader is running - else how could it load the code into memory? :-) Section attributes are applied after loading.

Re: 32-bit x86 Position Independent Code – It's That Bad

#47
post #41
post #40

Earlier quoted context omitted.

You don't need to run mincore() on target pids - you just need to write a tool that opens(O_RDONLY) and mmaps(PROT_READ) each library file, then calls mincore() on each page in the mapping to find out which pages of the library are loaded shared. The results of mincore() in one process with a shared mapping of a file are enough to tell you how much of that file is loaded shared system-wide.

Ah, good point! Though I think I'll do a dlopen on each file to mimic whatever the loader usually does. I'll do it as a weekend-project :)

In case it helps, here's my little utility (which just shows how much of a file is in core):

https://github.com/keaston/fincore

Re: 32-bit x86 Position Independent Code – It's That Bad

#48

Earlier quoted context omitted.

Not quite, I think. With a .so, I can ask `lsof` which services on the machine require restart: the ones that haven't are linked to a deleted so. And you wouldn't need to restart the clients with static OpenSSL — you need to recompile them . And with static linking, I'm not sure how you would easily determine the linked version out to say, the minor or the micro. (Perhaps, if this is your OS's thing like nix, the pac…

Tip for Debian/Ubuntu users: checkrestart from the debian-goodies package is a nice wrapper around lsof that lists running binaries that rely on outdated solibs: http://manpages.debian.org/cgi-bin/man.cgi?query=checkrestar... https://gehrcke.de/2014/06/good-to-know-checkrestart-from-de... It not only shows processes that run older solibs, but in the case of services, it will also give you the commands to restart them…

It also shows programs that are still using the old binary that has been deleted (unlinked from the filesystem) but not refcount 0 freed. This can also be used to uncover some forms of hiding that hack attempts use.

Re: 32-bit x86 Position Independent Code – It's That Bad

#49
post #18

Earlier quoted context omitted.

registers are much faster than stack, assuming you immediately make use of them; to use them from the stack you have to load them into registers anyway in most cases

In theory passing args in registers is faster because you avoid one copy in simple/small routines (the ones that perform a very simple op on the reg arguments and return). In practice there are way more complex routines than simple routines and the arg from register is copied back on the stack in the local variables area of the routine because it needs that register to perform some op or simply because it needs that…

For x86 you might be right, because there arent many registers. I doubt it is as much of an issue for x86-64. It depends on a lot of stuff that I don't have the numbers for, but, from your example:

If the functions tend to perform operations that are dependent on the arguments first (I know lots of functions I see do, doing things like an immediate null pointer check and pointer dereference on an arg) then it is better to already have them in a register, you can often immediately replace the value of the pointer in the register with the value from dereferencing.

For your point about there being more complex functions than simple ones, it doesn't matter which there are more of, it matters which are called more often. If every complex function on average calls 0.5 complex functions and 5 simple functions, you still probably have more simple function calls overall.

Re: 32-bit x86 Position Independent Code – It's That Bad

#50
post #5
post #2

The more I play around with musl (the author's C library) the more I'm convinced dynamic linking was not worth the trouble.

As a programmer who unfortunately is suckered into doing devops at times, the more I get to just update the openssl library instead of the whole OS whenever a security flaw in openssl is announced, the more I'm convinced that dynamic linking was very well worth the trouble. Funny how perceptions change depending on the angle you're looking at a problem.

There are no problems with updates anymore. You don't have to download everything to update a bunch of static binaries. There are things, like bsdiff, that allow you to download and patch only tiny differences related to a security flaw.

There is no need for dynamic linking for updates. Really.

Post reply on HN