Bug 1880634 - annobin creates symbols outside (empty) sections on ppc64le
Summary: annobin creates symbols outside (empty) sections on ppc64le
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: annobin
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Nick Clifton
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
: 1908863 (view as bug list)
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2020-09-18 20:27 UTC by Mark Wielaard
Modified: 2021-01-14 17:09 UTC (History)
5 users (show)

Fixed In Version: annobin-9.57-1.fc34
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2021-01-14 17:09:49 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Mark Wielaard 2020-09-18 20:27:05 UTC
While trying to build elfutils eu-elflint complains about various annobin generated symbols in ET_REL files:

section [61] '.symtab': symbol 9: st_value out of bounds
section [61] '.symtab': symbol 13: st_value out of bounds
section [61] '.symtab': symbol 17: st_value out of bounds
section [61] '.symtab': symbol 21: st_value out of bounds

Symbol table [61] '.symtab' contains 126 entries:
 85 local symbols  String table: [62] '.strtab'
  Num:            Value   Size Type    Bind   Vis          Ndx Name
    0: 0000000000000000      0 NOTYPE  LOCAL  DEFAULT    UNDEF 
    1: 0000000000000000      0 FILE    LOCAL  DEFAULT      ABS size.c
    2: 0000000000000000      0 SECTION LOCAL  DEFAULT        5 
    3: 0000000000000000      0 SECTION LOCAL  DEFAULT        7 
    4: 0000000000000000      0 SECTION LOCAL  DEFAULT        8 
    5: 0000000000000004      0 NOTYPE  LOCAL  HIDDEN         5 .annobin_size.c
    6: 0000000000000000      0 SECTION LOCAL  DEFAULT        9 
    7: 0000000000001c5c      0 NOTYPE  LOCAL  HIDDEN         5 .annobin_size.c_end
    8: 0000000000000000      0 SECTION LOCAL  DEFAULT       11 
    9: 0000000000000004      0 NOTYPE  LOCAL  HIDDEN        11 .annobin_size.c.hot
   10: 0000000000000000      0 SECTION LOCAL  DEFAULT       12 
   11: 0000000000000000      0 NOTYPE  LOCAL  HIDDEN        11 .annobin_size.c_end.hot
   12: 0000000000000000      0 SECTION LOCAL  DEFAULT       14 
   13: 0000000000000004      0 NOTYPE  LOCAL  HIDDEN        14 .annobin_size.c.unlikely
   14: 0000000000000000      0 SECTION LOCAL  DEFAULT       15 
   15: 0000000000000000      0 NOTYPE  LOCAL  HIDDEN        14 .annobin_size.c_end.unlikely
   16: 0000000000000000      0 SECTION LOCAL  DEFAULT       17 
   17: 0000000000000004      0 NOTYPE  LOCAL  HIDDEN        17 .annobin_size.c.startup
   18: 0000000000000000      0 SECTION LOCAL  DEFAULT       18 
   19: 0000000000000000      0 NOTYPE  LOCAL  HIDDEN        17 .annobin_size.c_end.startup
   20: 0000000000000000      0 SECTION LOCAL  DEFAULT       20 
   21: 0000000000000004      0 NOTYPE  LOCAL  HIDDEN        20 .annobin_size.c.exit
   22: 0000000000000000      0 SECTION LOCAL  DEFAULT       21 
   23: 0000000000000000      0 NOTYPE  LOCAL  HIDDEN        20 .annobin_size.c_end.exit
   24: 0000000000000000      0 NOTYPE  LOCAL  HIDDEN         5 .annobin_parse_opt.start
   25: 0000000000000000      0 SECTION LOCAL  DEFAULT       23 

Symbol 9 is against section 11, symbol 13 is against section 14, symbol 17 is against section 17 and symbol 21 is against section 20.

  [11] .text.hot         PROGBITS         0000000000000000  00001f88
       0000000000000000  0000000000000000 AXG       0     0     1
  [14] .text.unlikely    PROGBITS         0000000000000000  00001fb0
       0000000000000000  0000000000000000 AXG       0     0     1
  [17] .text.startup     PROGBITS         0000000000000000  00001fd8
       0000000000000000  0000000000000000 AXG       0     0     1
  [20] .text.exit        PROGBITS         0000000000000000  00002000
       0000000000000000  0000000000000000 AXG       0     0     1

Note how all those sections are empty (have a zero size). All the symbols claim to be at position 4, which is impossible for an empty section.

Comment 1 Nick Clifton 2020-09-21 10:19:25 UTC
Hi Mark,

  This is actually expected behaviour for the annobin plugin.  It has to bias the symbol positions because if it did not they would coincide with the start of functions.  (Well for sections that actually contain code that is).  This is a bad thing, because the PPC linker creates special entry symbols for functions which are needed by the ABI.  But it only does this if there are no symbols already at the function entry point.  (It assumes that if a symbol is there, then it has been created by hand crafted assembler code, and so it does not need synthesise its own).  Basically if the +4 bias was not used, PPC linking would break in the presence of annobin symbols.

  As far as I know there is no requirement that a section relative symbol actually lie inside its section.  So the symbols are legal, if unconventional.

  Could eu-elflint ignore these symbols ?

Cheers
  Nick

Comment 2 Mark Wielaard 2020-09-21 10:31:40 UTC
(In reply to Nick Clifton from comment #1)
>   This is actually expected behaviour for the annobin plugin.  It has to
> bias the symbol positions because if it did not they would coincide with the
> start of functions.  (Well for sections that actually contain code that is).
> This is a bad thing, because the PPC linker creates special entry symbols
> for functions which are needed by the ABI.  But it only does this if there
> are no symbols already at the function entry point.  (It assumes that if a
> symbol is there, then it has been created by hand crafted assembler code,
> and so it does not need synthesise its own).  Basically if the +4 bias was
> not used, PPC linking would break in the presence of annobin symbols.

OK, but there is no code (or function) there, so why add the symbol in the first place?

>   As far as I know there is no requirement that a section relative symbol
> actually lie inside its section.  So the symbols are legal, if
> unconventional.

The spec says: "In relocatable files, st_value holds a section offset for a defined symbol. st_value is an offset from the beginning of the section that st_shndx identifies." I don't think an offset outside the section is valid, what would that even mean?

>   Could eu-elflint ignore these symbols ?

It is not clear to me how to identify them (except by matching on name, but that would be really messy). How are they different from normal symbols in an ET_REL file that do have invalid section offset st_values?

Comment 3 Nick Clifton 2020-09-21 11:33:05 UTC
(In reply to Mark Wielaard from comment #2)
Hi Mark,

> OK, but there is no code (or function) there, so why add the symbol in the
> first place?

Because at the time that the symbols are created, the plugin does not know
if there will be any code in the section.


> >   As far as I know there is no requirement that a section relative symbol
> > actually lie inside its section.  So the symbols are legal, if
> > unconventional.
> 
> The spec says: "In relocatable files, st_value holds a section offset for a
> defined symbol. st_value is an offset from the beginning of the section that
> st_shndx identifies." I don't think an offset outside the section is valid,
> what would that even mean?

I don't see why it would not be valid.  It is just an offset.  The standard does
not mandate any semantics for symbol offsets.  It is up to the consumer to decide
what interpretation to put on the symbol's offset.  

In the case of the annobin symbols that are causing the problems, the offset 
means "the place where section FOO begins plus four".


> >   Could eu-elflint ignore these symbols ?
> 
> It is not clear to me how to identify them (except by matching on name, but
> that would be really messy). How are they different from normal symbols in
> an ET_REL file that do have invalid section offset st_values?

The symbols are a little special.  They are HIDDEN, LOCAL and have NOTYPE.
They do also contain the "annobin" string, but I agree that checking for this
would be a little bit hackish.

I will try some experiments with the plugin and see if I can detect empty
sections or change the offset of the start symbols to be no more than the 
offset of the end symbols.

Cheers
  Nick

Comment 4 Nick Clifton 2020-09-21 11:57:24 UTC
Ha!  It turns out that there already was some code in the annobin plugin that was supposed to fix this problem, but it broke when I changed the PowerPC symbol bias from 2 to 4.  I am testing a local fix now...

Comment 5 Nick Clifton 2020-09-21 12:25:28 UTC
Right - this should now be fixed in annobin-9.33-1.fc34.

Comment 6 Mark Wielaard 2020-09-21 12:42:50 UTC
Thanks, confirmed by a new elfutils-0.181-2.fc34 ppc64le build.

Comment 7 Jeff Law 2020-12-15 20:37:20 UTC
Sadly, this bug has returned:

https://koji.fedoraproject.org/koji/taskinfo?taskID=57523377

Comment 8 Nick Clifton 2020-12-16 11:43:47 UTC
(In reply to Jeff Law from comment #7)
> Sadly, this bug has returned:
> 
> https://koji.fedoraproject.org/koji/taskinfo?taskID=57523377

*sigh* Yes - but I am not sure what to do about it this time.

The cause is that annobin needs to create start and end symbols for any given code 
section.  But for the hot and cold text sections gcc can create multiple instances 
of the same section, so there is no way to ensure that annobin's end symbol will be 
placed after all the others.  Instead annobin places the end symbol into sections 
called .text.hot.zzz or .text.cold.zzz and it relies upon the linker's alphabetic 
sorting of sections to make sure that the symbol is at the end.

For the PowerPC however there is an additional problem - the start symbol cannot appear
at the start of the code section.  This is because the ppc linker creates special 
ABI-mandated entry symbols for functions, but only if there are no symbols present 
already present at the function's start address.  (Crazy but true).  So - in order to
work around this, annobin adds 4 to the address of any (powerpc) start symbol that it 
creates.

Which is fine, except for empty PowerPC sections.  Because now they have a start symbol
that is placed beyond the end of the section.  Annobin used to fix this by adding extra
code into the generated assembler that effectively performs: "if start > end then start = end"
But - this only works if the start and end symbol are in the same section.  If they are
in different sections then the assembler cannot evaluate the expression and so it errors
out.  Hence the fix works for some sections, but not the hot and cold sections.

Again this used to work because gcc would not generate hot and cold text sections for
the powerpc.  But as of gcc 10 and LTO compilation it does.  And so we are back to where
this BZ came in.

Now I still maintain that there is nothing intrinsicly wrong with a section relative
symbol having an address that it outside of the section.  There can be perfectly
legitimate reasons for doing this.  But the elfutils do not like them and annobin wants
to play nice, so I need to think up another solution.  Maybe I could force empty 
sections to be non-empty ?

Any-who I am on PTO now, so I will look at this once I get back.

Comment 9 Mark Wielaard 2020-12-17 12:50:06 UTC
So it seems this really is a linker problem on ppc64le. There must be a way to create normal symbols at a function start.

Having symbols with offsets beyond the section they are associated with is a problem in general since it is unclear how to handle them when merging sections, where should that symbol point to? It seems wrong to just make it point at some arbitrary data added.

If the issue is multiple .text sections with the same name, and you already create a new section with a name lexically at the end to place the end symbol in, can't you then not also create an (empty) start section with a name lexically before the others to place the start symbol in? Then you don't need any extra offset.

Comment 10 Mark Wielaard 2020-12-17 18:14:29 UTC
*** Bug 1908863 has been marked as a duplicate of this bug. ***

Comment 11 Nick Clifton 2021-01-13 12:07:01 UTC
Hi Mark,

  Do you have a small testcase that will reproduce this problem ?

  I know that I could try rebuilding all of elfutils and running its testsuite, but I am looking for just a small program that I can compile on its own, but which still triggers errors from eu-elflint.

Cheers
  Nick

Comment 12 Mark Wielaard 2021-01-13 13:19:08 UTC
Not having access to a rawhide ppc64le setup right now I cannot easily try to reduce something.

But the src/size.c program in elfutils shows the issue and is fairly small itself.
$ wc src/size.c 
  667  2499 17557 src/size.c

Comment 13 Mark Wielaard 2021-01-13 15:05:22 UTC
I still haven't replicated, but if you just want to build size.c then the following patch should help:

diff --git a/src/size.c b/src/size.c
index e49b64b8..3506f1ff 100644
--- a/src/size.c
+++ b/src/size.c
@@ -16,9 +16,14 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
+#include "eu-config.h"
+
+#define HAVE_DECL_POWEROF2 1
+#define PACKAGE_BUGREPORT "foobar" 
+#define PACKAGE_TARNAME "foobar"
+#define LOCALEDIR "foobar"
+#define PACKAGE_VERSION 0
+#define fputs_unlocked fputs
 
 #include <argp.h>
 #include <fcntl.h>

Then build with something like:

gcc -I ../lib -fstack-clash-protection -fstack-protector-strong -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -g -O2 -c size.c

But I'll try to get hold of a ppc64le machine where this fails to make sure.

Comment 14 Nick Clifton 2021-01-14 12:38:07 UTC
OK I have created a new annobin (annobin-9.57-1.fc34) which should solve this problem.

Note - the new annobin needs to be in the buildroot as I have updated the gcc plugin.

Local testing confirms that the elfutils source rpm can be built on a ppc64le machine, so I am hoping that this time everyone will be happy.

Comment 16 Mark Wielaard 2021-01-14 17:09:49 UTC
Confirmed. elfutils-0.182-2.fc34 build fine with annobin-9.57-1.fc34 installed, including a full green testsuite.
https://koji.fedoraproject.org/koji/taskinfo?taskID=59709103


Note You need to log in before you can comment on or make changes to this bug.