<?xml version="1.0" encoding="UTF-8"?><!-- generator="wordpress/1.5.2" -->
<rss version="2.0" 
	xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
	<title>Comments on: Linkers part 5</title>
	<link>http://www.airs.com/blog/archives/42</link>
	<description>Ian Lance Taylor</description>
	<pubDate>Tue, 18 Nov 2008 21:40:55 +0000</pubDate>
	<generator>http://wordpress.org/?v=1.5.2</generator>

	<item>
 		<title>Comment on Linkers part 5 by: lev</title>
		<link>http://www.airs.com/blog/archives/42#comment-4724</link>
		<pubDate>Wed, 26 Sep 2007 13:26:57 +0000</pubDate>
		<guid>http://www.airs.com/blog/archives/42#comment-4724</guid>
					<description>Thanks for responding.

I think the GNU linker's restriction on using GOTOFF for a protected function symbol is because it would be impossible for the dynamic linker to get it right in all possible cases. When the executable references a function of the same name as the protected symbol, there are possibilities the dynamic linker has to distinguish between: 1) the executable's reference will resolve to the protected function (in which case the reference in the DSO has to be resolved to the executable's PLT address, just as in the default visibility case); 2) the executable's reference will resolve to a different function (in which case the reference can be resolved, for example, to the protected function's load address). Unfortunately at the time of resolving the GOTOFF reference in the DSO, the dynamic linker has no way of choosing between these two possibilities (in particular, it might change in the future, in the presence of dlopen(...,RTLD_DEEPBIND) and so on). So, it seems necessary to disallow references to protected symbols.

As for changing the semantics and preventing the symbol from being overridden, this is desirable in the case that Ulrich describes -- he's trying to minimize the number of dynamic relocations needed, in order to speed startup of large applications with many libraries. His suggested solution using an internal hidden version of the symbol has the same semantics and also cannot be overridden. I guess I'll ask Ulrich what his concern was with protected symbols.</description>
		<content:encoded><![CDATA[	<p>Thanks for responding.</p>
	<p>I think the GNU linker&#8217;s restriction on using GOTOFF for a protected function symbol is because it would be impossible for the dynamic linker to get it right in all possible cases. When the executable references a function of the same name as the protected symbol, there are possibilities the dynamic linker has to distinguish between: 1) the executable&#8217;s reference will resolve to the protected function (in which case the reference in the DSO has to be resolved to the executable&#8217;s PLT address, just as in the default visibility case); 2) the executable&#8217;s reference will resolve to a different function (in which case the reference can be resolved, for example, to the protected function&#8217;s load address). Unfortunately at the time of resolving the GOTOFF reference in the DSO, the dynamic linker has no way of choosing between these two possibilities (in particular, it might change in the future, in the presence of dlopen(&#8230;,RTLD_DEEPBIND) and so on). So, it seems necessary to disallow references to protected symbols.</p>
	<p>As for changing the semantics and preventing the symbol from being overridden, this is desirable in the case that Ulrich describes &#8212; he&#8217;s trying to minimize the number of dynamic relocations needed, in order to speed startup of large applications with many libraries. His suggested solution using an internal hidden version of the symbol has the same semantics and also cannot be overridden. I guess I&#8217;ll ask Ulrich what his concern was with protected symbols.
</p>
]]></content:encoded>
				</item>
	<item>
 		<title>Comment on Linkers part 5 by: Ian Lance Taylor</title>
		<link>http://www.airs.com/blog/archives/42#comment-4718</link>
		<pubDate>Wed, 26 Sep 2007 07:43:01 +0000</pubDate>
		<guid>http://www.airs.com/blog/archives/42#comment-4718</guid>
					<description>Thanks for the comment.

Ulrich is saying that a protected function symbol is expensive because if a shared library references it without calling it, and if the application also references it without calling it, then both references have to return the same address.  I personally don't think this is worth worrying about, as the dynamic linker can tell, based on the relocation, whether the function is being called or referenced.  This means that a reference rather than a call in a shared library is not optimally efficient.  But I don't immediately see why it has to be any more expensive than an ordinary reference to a function in a shared library.  In any case, references to functions are not the normal case.

The GNU linker's restriction on using a GOTOFF reloc for a protected function symbol seems to be an attempt to avoid a bug in getting the address of the function.  But it seems to be the wrong approach.  It should really be marking the GOT entry with an appropriate reloc so that the dynamic linker can resolve it.  I don't see any reason that that can not work.

So, yes, I think protected function symbols should work fine, and I don't see any reason to avoid them (modulo toolchain bugs).  But I also don't see them as an optimal solution in general.  Making a symbol protected changes the semantics: the symbol can no longer be overriden from outside the shared library.  If that is what you want, then fine.  But if you want the default semantics, then protected visibility is not helpful.</description>
		<content:encoded><![CDATA[	<p>Thanks for the comment.</p>
	<p>Ulrich is saying that a protected function symbol is expensive because if a shared library references it without calling it, and if the application also references it without calling it, then both references have to return the same address.  I personally don&#8217;t think this is worth worrying about, as the dynamic linker can tell, based on the relocation, whether the function is being called or referenced.  This means that a reference rather than a call in a shared library is not optimally efficient.  But I don&#8217;t immediately see why it has to be any more expensive than an ordinary reference to a function in a shared library.  In any case, references to functions are not the normal case.</p>
	<p>The GNU linker&#8217;s restriction on using a GOTOFF reloc for a protected function symbol seems to be an attempt to avoid a bug in getting the address of the function.  But it seems to be the wrong approach.  It should really be marking the GOT entry with an appropriate reloc so that the dynamic linker can resolve it.  I don&#8217;t see any reason that that can not work.</p>
	<p>So, yes, I think protected function symbols should work fine, and I don&#8217;t see any reason to avoid them (modulo toolchain bugs).  But I also don&#8217;t see them as an optimal solution in general.  Making a symbol protected changes the semantics: the symbol can no longer be overriden from outside the shared library.  If that is what you want, then fine.  But if you want the default semantics, then protected visibility is not helpful.
</p>
]]></content:encoded>
				</item>
	<item>
 		<title>Comment on Linkers part 5 by: lev</title>
		<link>http://www.airs.com/blog/archives/42#comment-4696</link>
		<pubDate>Tue, 25 Sep 2007 15:53:16 +0000</pubDate>
		<guid>http://www.airs.com/blog/archives/42#comment-4696</guid>
					<description>Thanks for the further explanation. That was the clue I needed. It took me a while looking at the assembler that gets generated, but I figured it out. I had the wrong idea about how the relocations worked for the main executable.
This stuff is certainly confusing, at least if you're not used to the proper way of thinking.

As for the difference between internal and hidden, I found this discussion:
http://groups.google.com/group/generic-abi/browse_thread/thread/1a84adc15666164
where Jim Dehnert, apparently the SGI representative who originally requested the addition of  STV_INTERNAL to the gABI, posts here:
http://groups.google.com/group/generic-abi/browse_thread/thread/2c3c04f556d9b84d
He can't remember exactly why they needed it, but thinks it was only relevant to link-time (interprocedural) optimization. Everyone else in that discussion (8 authors) says that they treat STV_HIDDEN and STV_INTERNAL identically.

Finally, if you're not fed up with answering questions about visibility.... In Ulrich Drepper's DSO how-to:
http://people.redhat.com/drepper/dsohowto.pdf
Drepper says that protected visibility sounds nice but is even more expensive than default visibility. I can't see why this would be. I see that it would be very tricky if you were allowed use protected function addresses in a non-call way in the DSO. But the gnu toolchain specifically forbids this. Eg:

cmt:~/dso&amp;#62; cat w.c
void prot(void) __attribute__ (( visibility (&quot;protected&quot;) ));
int f(void (*p)(void) )
{
  return p==prot;
}

void prot(void)
{
  /*nothing*/
}

cmt:~/dso&amp;#62; gcc -fpic -o w.so -shared w.c
/usr/lib/gcc/i586-suse-linux/4.1.0/../../../../i586-suse-linux/bin/ld: /tmp/ccsNpSI0.o: relocation R_386_GOTOFF against protected function `prot' can not be used when making a shared object
/usr/lib/gcc/i586-suse-linux/4.1.0/../../../../i586-suse-linux/bin/ld: final link failed: Bad value
collect2: ld returned 1 exit status

As long as one can deal with this restriction, shouldn't protected visibility be an optimal solution for both intra-DSO calls (bypassing the dynamic linker and the PLT) and calls and non-call references from outside the DSO (which just use the same mechanisms as they would with default visibility)? Seems like it has just the same effect as Drepper's suggested:

void __attribute__(( visibility(&quot;default&quot;) )) prot(void)
{
}
extern __typeof(prot) prot_int __attributes__ (( alias(&quot;prot&quot;), visibility(&quot;hidden&quot;) ));

...where you then have to remember to use prot_int when referring to the function from within the DSO. The toolchain does allow to take the address of prot_int for this method, but you do have to be careful since it won't be same as the address of prot.

On the other hand, I'm reluctant to assume that I know any better than Ulrich Drepper about this stuff -- he generally seems to know what he's talking about :-) so... any thoughts? (I spotted some tricky-looking code in glibc's elf/dl-lookup.c maybe relating to this, but I don't really follow it).

I'm done reading up to part 17 of your series, and none of the other sections have puzzled me as much as this whole thing about the meaning of symbol visibilities.</description>
		<content:encoded><![CDATA[	<p>Thanks for the further explanation. That was the clue I needed. It took me a while looking at the assembler that gets generated, but I figured it out. I had the wrong idea about how the relocations worked for the main executable.<br />
This stuff is certainly confusing, at least if you&#8217;re not used to the proper way of thinking.</p>
	<p>As for the difference between internal and hidden, I found this discussion:<br />
<a href='http://groups.google.com/group/generic-abi/browse_thread/thread/1a84adc15666164' rel='nofollow'>http://groups.google.com/group/generic-abi/browse_thread/thread/1a84adc15666164</a><br />
where Jim Dehnert, apparently the SGI representative who originally requested the addition of  STV_INTERNAL to the gABI, posts here:<br />
<a href='http://groups.google.com/group/generic-abi/browse_thread/thread/2c3c04f556d9b84d' rel='nofollow'>http://groups.google.com/group/generic-abi/browse_thread/thread/2c3c04f556d9b84d</a><br />
He can&#8217;t remember exactly why they needed it, but thinks it was only relevant to link-time (interprocedural) optimization. Everyone else in that discussion (8 authors) says that they treat STV_HIDDEN and STV_INTERNAL identically.</p>
	<p>Finally, if you&#8217;re not fed up with answering questions about visibility&#8230;. In Ulrich Drepper&#8217;s DSO how-to:<br />
<a href='http://people.redhat.com/drepper/dsohowto.pdf' rel='nofollow'>http://people.redhat.com/drepper/dsohowto.pdf</a><br />
Drepper says that protected visibility sounds nice but is even more expensive than default visibility. I can&#8217;t see why this would be. I see that it would be very tricky if you were allowed use protected function addresses in a non-call way in the DSO. But the gnu toolchain specifically forbids this. Eg:</p>
	<p>cmt:~/dso&gt; cat w.c<br />
void prot(void) __attribute__ (( visibility (&#8221;protected&#8221;) ));<br />
int f(void (*p)(void) )<br />
{<br />
  return p==prot;<br />
}</p>
	<p>void prot(void)<br />
{<br />
  /*nothing*/<br />
}</p>
	<p>cmt:~/dso&gt; gcc -fpic -o w.so -shared w.c<br />
/usr/lib/gcc/i586-suse-linux/4.1.0/../../../../i586-suse-linux/bin/ld: /tmp/ccsNpSI0.o: relocation R_386_GOTOFF against protected function `prot&#8217; can not be used when making a shared object<br />
/usr/lib/gcc/i586-suse-linux/4.1.0/../../../../i586-suse-linux/bin/ld: final link failed: Bad value<br />
collect2: ld returned 1 exit status</p>
	<p>As long as one can deal with this restriction, shouldn&#8217;t protected visibility be an optimal solution for both intra-DSO calls (bypassing the dynamic linker and the PLT) and calls and non-call references from outside the DSO (which just use the same mechanisms as they would with default visibility)? Seems like it has just the same effect as Drepper&#8217;s suggested:</p>
	<p>void __attribute__(( visibility(&#8221;default&#8221;) )) prot(void)<br />
{<br />
}<br />
extern __typeof(prot) prot_int __attributes__ (( alias(&#8221;prot&#8221;), visibility(&#8221;hidden&#8221;) ));</p>
	<p>&#8230;where you then have to remember to use prot_int when referring to the function from within the DSO. The toolchain does allow to take the address of prot_int for this method, but you do have to be careful since it won&#8217;t be same as the address of prot.</p>
	<p>On the other hand, I&#8217;m reluctant to assume that I know any better than Ulrich Drepper about this stuff &#8212; he generally seems to know what he&#8217;s talking about <img src='http://www.airs.com/blog/wp-images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  so&#8230; any thoughts? (I spotted some tricky-looking code in glibc&#8217;s elf/dl-lookup.c maybe relating to this, but I don&#8217;t really follow it).</p>
	<p>I&#8217;m done reading up to part 17 of your series, and none of the other sections have puzzled me as much as this whole thing about the meaning of symbol visibilities.
</p>
]]></content:encoded>
				</item>
	<item>
 		<title>Comment on Linkers part 5 by: Ian Lance Taylor</title>
		<link>http://www.airs.com/blog/archives/42#comment-4533</link>
		<pubDate>Thu, 20 Sep 2007 07:15:09 +0000</pubDate>
		<guid>http://www.airs.com/blog/archives/42#comment-4533</guid>
					<description>Thanks for the note.

It's OK to make the address of the function be the address of the PLT entry, what matters is that every reference to the function, no matter where it occurs, get that same address.  So there is a two-step process.  First, the program linker marks the dynamic symbol in a special way by giving it a non-zero value A, and it also uses A for any relocations which reference the function.  The dynamic linker then makes sure to use A for any reference to the function other than actually calling it.  That is, in the main executable, A is used for any reloc other than a PLT reloc.  And likewise in a shared library (typically the only other reloc would be a GOT reloc).  This ensures that every reference to the function, other than calling it, gets the value A.  Thus comparisons of the function address for equality will work.

Note that this is not an issue for a function defined in the executable.  In that case the dynamic linker will always use the address in the executable for all references to the function.  This is also not an issue for a function reference from a shared library.  The shared library will naturally have dynamic relocations for the function, and the usual dynamic linker algorithm will ensure that all those relocations refer to the same value.

The problem only arises for a function reference from the main executable.  In this case there may not be a dynamic relocation for all references to the function, since the program linker will be able to resolve those relocations to the PLT address.  So the special non-zero value in the dynamic symbol table records that there was a reference to the function other than calling it, and it tells the dynamic linker that it must use that address when resolving dynamic relocations in shared libraries other than calling the function.

I hope that makes some sense.

Finally, you're right, both the program linker and the dynamic linker should treat internal and hidden symbols exactly the same.  Explicitly recording both types in the ELF symbol visibility field is just for information.  Actually I don't know of any systems which actually treat internal symbols differently from hidden symbols in any way, though no doubt there are some.</description>
		<content:encoded><![CDATA[	<p>Thanks for the note.</p>
	<p>It&#8217;s OK to make the address of the function be the address of the PLT entry, what matters is that every reference to the function, no matter where it occurs, get that same address.  So there is a two-step process.  First, the program linker marks the dynamic symbol in a special way by giving it a non-zero value A, and it also uses A for any relocations which reference the function.  The dynamic linker then makes sure to use A for any reference to the function other than actually calling it.  That is, in the main executable, A is used for any reloc other than a PLT reloc.  And likewise in a shared library (typically the only other reloc would be a GOT reloc).  This ensures that every reference to the function, other than calling it, gets the value A.  Thus comparisons of the function address for equality will work.</p>
	<p>Note that this is not an issue for a function defined in the executable.  In that case the dynamic linker will always use the address in the executable for all references to the function.  This is also not an issue for a function reference from a shared library.  The shared library will naturally have dynamic relocations for the function, and the usual dynamic linker algorithm will ensure that all those relocations refer to the same value.</p>
	<p>The problem only arises for a function reference from the main executable.  In this case there may not be a dynamic relocation for all references to the function, since the program linker will be able to resolve those relocations to the PLT address.  So the special non-zero value in the dynamic symbol table records that there was a reference to the function other than calling it, and it tells the dynamic linker that it must use that address when resolving dynamic relocations in shared libraries other than calling the function.</p>
	<p>I hope that makes some sense.</p>
	<p>Finally, you&#8217;re right, both the program linker and the dynamic linker should treat internal and hidden symbols exactly the same.  Explicitly recording both types in the ELF symbol visibility field is just for information.  Actually I don&#8217;t know of any systems which actually treat internal symbols differently from hidden symbols in any way, though no doubt there are some.
</p>
]]></content:encoded>
				</item>
	<item>
 		<title>Comment on Linkers part 5 by: lev</title>
		<link>http://www.airs.com/blog/archives/42#comment-4531</link>
		<pubDate>Thu, 20 Sep 2007 05:48:19 +0000</pubDate>
		<guid>http://www.airs.com/blog/archives/42#comment-4531</guid>
					<description>I'm finding this series of posts on linkers very interesting, and mostly very clear. I have a couple of questions regarding this one, though.

1) I understand why it's wrong giving the address of the PLT entry when C code takes the address of a function. But you say that the way around this is to specially mark such uses of a function, with a special symbol that has the value of the address of the PLT entry. Isn't this the same thing? I'm obviously not following that paragraph properly.

2) What possible difference can it make to the linker whether a symbol is marked STV_INTERNAL vs STV_HIDDEN? I can understand that the compiler might be able to do some optimizations if it knows that the function will never be called from outside the executable/shared lib -- maybe can avoid loading the PIC register since you know it's already done by the caller. But that's the compiler: why would the linker need to know the difference between internal and hidden?

Thanks for some interesting articles.</description>
		<content:encoded><![CDATA[	<p>I&#8217;m finding this series of posts on linkers very interesting, and mostly very clear. I have a couple of questions regarding this one, though.</p>
	<p>1) I understand why it&#8217;s wrong giving the address of the PLT entry when C code takes the address of a function. But you say that the way around this is to specially mark such uses of a function, with a special symbol that has the value of the address of the PLT entry. Isn&#8217;t this the same thing? I&#8217;m obviously not following that paragraph properly.</p>
	<p>2) What possible difference can it make to the linker whether a symbol is marked STV_INTERNAL vs STV_HIDDEN? I can understand that the compiler might be able to do some optimizations if it knows that the function will never be called from outside the executable/shared lib &#8212; maybe can avoid loading the PIC register since you know it&#8217;s already done by the caller. But that&#8217;s the compiler: why would the linker need to know the difference between internal and hidden?</p>
	<p>Thanks for some interesting articles.
</p>
]]></content:encoded>
				</item>
	<item>
 		<title>Comment on Linkers part 5 by: christian schorn &#187; Blog Archive &#187; links for 2007-08-30</title>
		<link>http://www.airs.com/blog/archives/42#comment-4009</link>
		<pubDate>Thu, 30 Aug 2007 21:22:54 +0000</pubDate>
		<guid>http://www.airs.com/blog/archives/42#comment-4009</guid>
					<description>[...] Airs - Ian Lance Taylor » Linkers part 5 (tags: programming basics) [...]</description>
		<content:encoded><![CDATA[	<p>[&#8230;] Airs - Ian Lance Taylor » Linkers part 5 (tags: programming basics) [&#8230;]
</p>
]]></content:encoded>
				</item>
</channel>
</rss>
