Static linking in LGPL, Upgrading LGPL libs

But can you run ucLinux on those architectures?

For example, you can't generate position independent code with gcc for the AVR, but that's because there is no natural way to run PIC on that architecture, and very few practical uses of it if there were (and you certainly can't run ucLinux on it, being an 8-bit cpu).

Have you any examples of ucLinux on architectures where gcc cannot generate PIC?

Reply to
David Brown
Loading thread data ...

In the context of licensing, there is typically only a single instance of a single program.

The PIC is useful, if there are several libraries from various vendors, but when the libraries are from a single vendor, it should be easy to link each library to a fixed and publicly known start address. Typically a function start address table is loaded at that address, followed by the actual library routine codes.

When linking the main program, reserve the space required by the library and provide small stub routines to perform an indirect indexed jump through the jump table (which is in a publicly known address).

If the library needs to be used from more than one program, then it needs to be reentrant, i.e. all modified variables must be in the stack of the calling program.

For architectures that do not easily support stacks, the library code may require some program instance ID parameter, so that the library can use different data sets for each program.

Reply to
Paul Keinanen

u
"

ed

Thats great :-)

e

Interesting ! Good snapshot of the relevant section of the license .

o

Okay .

for

a
e

Karthik Balaguru

Reply to
karthikbalaguru

Of course. Same mostly use "Flat" binaries. (AFAIK, you can do linked libraries with flat binaries, but I don't have an example).

NIOS2

-Michael

Reply to
Michael Schnell

on

e
.

nd

u
"

ed

Great !

Okay.

e
o

It appears to be a lot of work !

Strange that LGPL is bad for embedded systems. I think, embedded systems is one of the domains that might be ever-green !

Any clause/licenses to help embedded systems ?

But, as others pointed out, i think this is not allowed by LGPL.

This is interesting ! I wonder why it was not revised after the evolution of embedded systems . Strange ?

Any embedded specific clauses in LGPL to help embedded systems ?

Thx in advans, Karthik Balaguru

Reply to
karthikbalaguru

It does not make much sense to do dynamic linking if the library can't be shared. /

Shared (thus reentrant) libraries (theoretically) can use static variables if any dynamic linkage creates a new address space for same. This can be done by means of the MMU or by means of a pointer. I seem to remember that normal PC so's do this.

-Michael

Reply to
Michael Schnell

The GNU Compiler Collection is intended to be widely used. A c-compiler without its library is worthless. That is the reason for LGPL: that you can release commercial programs without revealing your source code.

It would be a rare c-program that nowhere uses e.g. a malloc or strcpy. So the malloc going with gcc is not GPL-ed.

One more note: If you're using the resulting program internally, the GPL imposes no restrictions on you.

From my personal experience: I saved a company's cash cow by replacing the compiler by gcc. I even modified gcc! But the company didn't distribute that gcc, so that is neither here nor there. Then we used gcc including its libraries to make embedded software for industrial machines worth millions of Euro's. The competition would be interested to see the source code *of the machines* but of course we didn't distribute that, and we were in no obligation to do so. And no: this is 68000 code in EPROM. No dynamic libraries.

You shouldn't rely on others. You should just read the LGPL.

A good legal system works this way: you as an expert interpret LGPL you give expert witness and a judge follows your opinion lawyers base action and advice on previous judges rulings

This is how it works now in the US: the party with the shallow pockets give in there comes a settlement this servers as jurisprudence to force judgements in the same way lawyers are now the only ones who can figure out what to do because judgements are no longer effectively based on law

This also undermines the democracy. A parliament makes written laws that are objective and should apply to everybody. But those laws are no longer followed.

--

--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst
Reply to
Albert van der Horst

The final linking is done by the link-loader when you start a program or load a shared library into memory, so with ucLinux's flat binaries you don't need PIC to run software or to use shared libraries. You will need PID if the shared library has to keep track of application-specific data, however.

Where PIC is important is for XIP binaries - execute in place - which run from flash. These are not loaded into ram, and thus the link-loader can't patch in addresses.

Fair enough. The Nios2 gcc port is out-of-tree, and won't support features that Altera don't see as important, making it a little more limited than mainline targets. But I accept your point here.

Reply to
David Brown

It is also a lot of work to develop the code yourself, or to earn enough money to be able to buy commercially licensed code for the same purpose. Just because something costs zero dollars, does not mean it is zero cost :-( When you choose your software components, you have to take these things into account and find a balance that suits your needs and your project.

"Obfusticated" code is not considered "source code", nor is any intermediary code (for example, if you are using something that generates C code from a higher level language, the C code does not count as "source code"). Thus it does not satisfy the requirements of the GPL. But it is, as far as I can tell, good enough as the equivalent of linkable object code.

See below for your answer.

Reply to
David Brown

Ah, I now do see your point. This would mean dynamic linking but not shared object-code. I did not suppose that this is possible (as other than to void the license-issue discussed there is no big practical reason to do this.)

OTOH I suppose that this Arch will get quite low interest, as now the new NIOS2 can have an MMU and the full Linux port is available (commercially supported by WindRiver, the community distribution close to usability.)

-Michael

Reply to
Michael Schnell

IMHO the even more interesting way is to use a file system in DRAM and when booting load it from a (serial) flash. Here XIP is executing as fast as "normal" and loading is much faster.

-Michael

Reply to
Michael Schnell

Yes, that's another use of XIP. And even though you can write to RAM, the link-loader can't start writing address patches to the file on the "disk".

Reply to
David Brown

Yes, you /do/ get shared object code in this way. Suppose you have a library libfoo.so that contains a function "bar". The library's header contains a record indicating the offset of the function "bar" inside its object code section. When the link-loader loads libfoo.so somewhere in memory, it can then calculate the absolute address of "bar". Suppose you then have a program "test" that calls "bar" at some point. Within the object code section of "test", the address of "bar" is simply a placeholder (typically 0), and the header of the "test" file contains a link table with a record saying "bar" and the offset of the placeholder within the object code. When the link-loader loads "test", it copies the object code section into memory. It then runs through the link table from the file's header, and patches in the absolute address of "bar" (within the in-memory shared library) into the copy of test's object code. That's why programs are loaded by a "link-loader", not just a "loader" - the final stage of linking is carried out at load time.

When you see how this process works, it's easy to see that a second program can use the same in-memory copy of the shared library in the same way.

True enough. And while the MMU adds some overhead (both in space and speed for the NIOS2), it is almost certainly worth it if you get to run full Linux rather than ucLinux.

Reply to
David Brown

I see. rather complicated but workable.

That is what I am going to do :)

-Michael

Reply to
Michael Schnell

Yep. Updates would be done writing into the flash and be activated with the next boot.

I'll even provide a dual flash image (with CRC check) and have the boot process load a default one if the CRC fails on the current, thus upgrading via line is quite safe.

-Michael

Reply to
Michael Schnell

It's not that complicated, really, and it's the way modern Linux systems work (not just ucLinux). The alternative to load-time relocation patching of some sort is to have extra layers of indirection in all shared library calls, or to use something like software interrupts.

Reply to
David Brown

This isn't quite how it works for normal ELF executables on Linux. The details are architecture dependent, but on x86, calls among shared libraries and executables indirect through a PLT (procedure linkage table).

There is a .plt section containing little stub routines for every function that is dynamically resolved. The first time such a stub is called, it branches to a function which computes the reference, and patches the stub.

The executable code of shared libraries and executables is mapped shared and read-only (when not under a debugger).

Here is an example, from an actual executable:

Disassembly of section .plt: ...

08048418 : 8048418: ff 25 f0 98 04 08 jmp *0x80498f0 804841e: 68 00 00 00 00 push $0x0 8048423: e9 e0 ff ff ff jmp 8048408

The address 0x80498f0 is in another section which is called .got.plt.

The contents of *80498f0 are 804841e! I.e. it just points one instruction down.

So initially, when the program calls getchar, this stub jumps through the entry in the .got.plt, which brings it right back. It pushes $0x0 on the stack ($0x0 is the offset of the function in the PLT) and calls a routine which will resolve the symbol and patch the table to go to the right location.

We can see this live:

$ gdb ./a.out [ ... GDB messages ... ] (gdb) b main Breakpoint 1 at 0x8048556 (gdb) b getchar Function "getchar" not defined. Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 2 (getchar) pending. (gdb) r 0 Starting program: /home/kaz/a.out 0 (no debugging symbols found) (no debugging symbols found) Breakpoint 3 at 0x2adc86 Pending breakpoint "getchar" resolved

Breakpoint 1, 0x08048556 in main () (gdb) p *(void **) 0x80498f0 $1 = (void *) 0x804841e

At this point, getchar has not been called yet, and so the PLT entry still points to the next instruction in the stub. Now we hit the breakpoint in getchar:

(gdb) c Continuing.

Breakpoint 3, 0x002adc86 in getchar () from /lib/tls/libc.so.6 (gdb) p *(void **) 0x80498f0 $2 = (void *) 0x2adc80 (gdb) p getchar $3 = {} 0x2adc80

This time when we print the contents of that PLT location, it points to the actual address of getchar. The call has been lazily resolved, but still goes through the indirect jump.

Reply to
Kaz Kylheku

l

u/

e:

Hide quoted text -

'GPL with exception clause' is interesting. True that without applying the linking exception, code linked with GPL code becomes automatically GPL. Reer -

formatting link

LGPL's linking exception appears to be more customer friendly.

Thx, Karthik Balaguru

Reply to
Karthik Balaguru

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.