Jump to page: 1 2
Thread overview
[challenge] Linker surgery
May 14, 2013
Dmitry Olshansky
May 14, 2013
Nick Sabalausky
May 14, 2013
Dmitry Olshansky
May 15, 2013
IgorStepanov
May 17, 2013
Dmitry Olshansky
May 17, 2013
Rainer Schuetze
May 17, 2013
Igor Stepanov
May 18, 2013
Rainer Schuetze
May 17, 2013
Dmitry Olshansky
May 17, 2013
Igor Stepanov
May 17, 2013
Igor Stepanov
May 18, 2013
Jacob Carlborg
May 18, 2013
Rainer Schuetze
May 18, 2013
Dmitry Olshansky
May 19, 2013
Rainer Schuetze
May 19, 2013
Dmitry Olshansky
May 14, 2013
The gist of the matter is I have module with some immutable tables. Quite some I should say (Unicode stuff). This gives the outline of problem:

imutable Something tableA  = ...; //~4-8Kb
...
imutable Something tableZ  = ...; //~4-8Kb

Now I have a set of functions that make use of each of these tables:

bool funcA(dchar ch){
	//optional ... extra logic
	return tableA[ch];
}
...
bool funcZ(dchar ch){ ... }

Now is the challenge is how do I make it NOT link in tables if I don't call the corresponding functions.

First try fails:

bool funcA(dchar ch){
	//this just allocates!
	immutable tableA = [ ... ];
	//sadly this appears in the map file
	static immutable tableA = [ ... ];
}

For the moment this what I found to 'work' :
template funcA(){
	immutable tableA = [ ... ];
	bool funcA(dchar ch){
		...
	}
}

Otherwise the table is present regardless of whether or not I make use of funcA. The above is a neat hack but I think there must be a better way to avoid pulling globals into executable.

In the test sample below 'fable' is present in the map file, foo itself is correctly absent.

//module
// should be changed somehow so as not to put fable into exe when foo
// is not referenced, with no templates involved
module mod;
immutable byte[] fable = [1, 2, 3, 4, 5];

public byte foo(int ch){
    return fable[ch];
}


//driver
import mod;

immutable byte[] bable = [1, 2, 3, 4, 5];

byte boo(int ch){
    return bable[ch];
}

void main(string[] args){
    boo(0);
}

-- 
Dmitry Olshansky
May 14, 2013
On Tue, 14 May 2013 18:59:22 +0400
Dmitry Olshansky <dmitry.olsh@gmail.com> wrote:
> 
> Now is the challenge is how do I make it NOT link in tables if I don't call the corresponding functions.
> 

Don't some linkers do unreferenced symbol removal? Maybe that's all that's needed?

May 14, 2013
14-May-2013 22:27, Nick Sabalausky пишет:
> On Tue, 14 May 2013 18:59:22 +0400
> Dmitry Olshansky <dmitry.olsh@gmail.com> wrote:
>>
>> Now is the challenge is how do I make it NOT link in tables if I
>> don't call the corresponding functions.
>>
>
> Don't some linkers do unreferenced symbol removal?

Interestingly it does ... for functions.

> Maybe that's all
> that's needed?
>

Might be - if that was my personal need I might set off to search some smart linker. But the thing will end up in the standard library and surely there it's stuck with ld/optlink.

-- 
Dmitry Olshansky
May 15, 2013
Do this table linked, if you remove all functions, which use it?
It not, you can try the next method (Another hack).

extern(C) immutable int[] table_ = [1,2,3]; //table_.mangleof ==
"table_";

int foo()
{
       pragma(mangle, "table_") extern immutable int[] table;
       return table[1];
}

In this hack we "fooling" the compiler. We say, that "table_"
doesn't used in foo(). foo() use another extern array "table"
with overrided mangle (new feature)

On Tuesday, 14 May 2013 at 18:36:32 UTC, Dmitry Olshansky wrote:
> 14-May-2013 22:27, Nick Sabalausky пишет:
>> On Tue, 14 May 2013 18:59:22 +0400
>> Dmitry Olshansky <dmitry.olsh@gmail.com> wrote:
>>>
>>> Now is the challenge is how do I make it NOT link in tables if I
>>> don't call the corresponding functions.
>>>
>>
>> Don't some linkers do unreferenced symbol removal?
>
> Interestingly it does ... for functions.
>
>> Maybe that's all
>> that's needed?
>>
>
> Might be - if that was my personal need I might set off to search some smart linker. But the thing will end up in the standard library and surely there it's stuck with ld/optlink.
May 17, 2013
15-May-2013 04:17, IgorStepanov пишет:
> Do this table linked, if you remove all functions, which use it?

Thanks for this try, but they DO link in always.
And I believe this is a key problem - each function goes into a separate object but globals are always pulled in!

Anyone ever used digits, letter or similar arrays in std.ascii ?
I doubt that - yet they are almost (next to everything depends on std.uni and that depends on std.ascii) always there in the binary.

These bits do add up and now with the full spectrum of Unicode...

Hm... now if we go with the shared library route I'd only do a disservice by make tables into templates. But in static linked one surely nobody wants these e.g. extra ~20K of normalization tables (and there is way more) for next to *every* program.

P.S. I'm coming to hate developing std stuff, so little space for maneuvers ;)

> It not, you can try the next method (Another hack).
>
> extern(C) immutable int[] table_ = [1,2,3]; //table_.mangleof ==
> "table_";
>
> int foo()
> {
>         pragma(mangle, "table_") extern immutable int[] table;
>         return table[1];
> }
>
> In this hack we "fooling" the compiler. We say, that "table_"
> doesn't used in foo(). foo() use another extern array "table"
> with overrided mangle (new feature)
>
> On Tuesday, 14 May 2013 at 18:36:32 UTC, Dmitry Olshansky wrote:
>> 14-May-2013 22:27, Nick Sabalausky пишет:
>>> On Tue, 14 May 2013 18:59:22 +0400
>>> Dmitry Olshansky <dmitry.olsh@gmail.com> wrote:
>>>>
>>>> Now is the challenge is how do I make it NOT link in tables if I
>>>> don't call the corresponding functions.
>>>>
>>>
>>> Don't some linkers do unreferenced symbol removal?
>>
>> Interestingly it does ... for functions.
>>
>>> Maybe that's all
>>> that's needed?
>>>
>>
>> Might be - if that was my personal need I might set off to search some
>> smart linker. But the thing will end up in the standard library and
>> surely there it's stuck with ld/optlink.


-- 
Dmitry Olshansky
May 17, 2013

On 17.05.2013 14:29, Dmitry Olshansky wrote:
> 15-May-2013 04:17, IgorStepanov пишет:
>> Do this table linked, if you remove all functions, which use it?
>
> Thanks for this try, but they DO link in always.
> And I believe this is a key problem - each function goes into a separate
> object but globals are always pulled in!
>

Yes, if you build a library the functions in a module are split into separate object files, but data is always written into the object file of the original module. The linker cannot split these afterwards if any data in the module is referenced (which might happen by just importing the module).

A workaround could be to put the data into a different module.
May 17, 2013
On Friday, 17 May 2013 at 17:57:54 UTC, Rainer Schuetze wrote:
>
>
> On 17.05.2013 14:29, Dmitry Olshansky wrote:
>> 15-May-2013 04:17, IgorStepanov пишет:
>>> Do this table linked, if you remove all functions, which use it?
>>
>> Thanks for this try, but they DO link in always.
>> And I believe this is a key problem - each function goes into a separate
>> object but globals are always pulled in!
>>
>
> Yes, if you build a library the functions in a module are split into separate object files, but data is always written into the object file of the original module. The linker cannot split these afterwards if any data in the module is referenced (which might happen by just importing the module).
>
> A workaround could be to put the data into a different module.

What happens, if you place table into separate module? This module will be compiled as independent object file and (I hope) can be not linked if symbols from it will not be used. Or my logic is broken?
May 17, 2013
17-May-2013 21:57, Rainer Schuetze пишет:
>
>
> On 17.05.2013 14:29, Dmitry Olshansky wrote:
>> 15-May-2013 04:17, IgorStepanov пишет:
>>> Do this table linked, if you remove all functions, which use it?
>>
>> Thanks for this try, but they DO link in always.
>> And I believe this is a key problem - each function goes into a separate
>> object but globals are always pulled in!
>>
>
> Yes, if you build a library the functions in a module are split into
> separate object files, but data is always written into the object file
> of the original module. The linker cannot split these afterwards if any
> data in the module is referenced (which might happen by just importing
> the module).

And how then I would use these tables if even importing these modules then pulls in the data?

Local import doesn't help too.

> A workaround could be to put the data into a different module.

Then say I go for X files with tables and import these modules.
It still doesn't work - evidently simply referencing a module pulls in the data.

If I compile and link the following 3 modules:


module fmod;

public immutable int[] fable = [1,2,3];


module mod;

import fmod;

int foo(int i)
{
       return fable[i];
}

//driver
import mod;

immutable byte[] bable = [1, 2, 3, 4, 5];

byte boo(int ch){
    return bable[ch];
}

void main(string[] args){
    boo(0);
}

I still have this symbol in map file: _D4fmod5fableyAi
That is immutable(int[]) fmod.fable after ddemangle.

-- 
Dmitry Olshansky
May 17, 2013
>And how then I would use these tables if even importing these modules
then pulls in the data?

without import with pragma(mangle) help. But this dark linker magic no much better you template solution.
May 17, 2013
module fmod;

public immutable int[] fable = [1,2,3];


module mod;

//import fmod;

int foo(int i)
{
       pragma(mangle, "_D4fmod5fableyAi") extern immutable int[] fable;
       return fable[i];
}
« First   ‹ Prev
1 2