funny llvm bug

I'm going to file this bug but it's kind of a blocker for me so maybe someone has time
to look at it. Should be nearly trivial to fix.

It's a bug in the way the "section" attribute of functions is processed.

Consider the following code:

void x(int i) __attribute((section(".mySection,\"aw\",@progbits#")));

void x(int i) {
}

If you compile this with gcc you get:

     .file "sectbug.c"
     .section .mySection,"aw",@progbits#,"ax",@progbits
.globl x

  With Clang you get

     .file "sectbug.c"
     .section ".mySection,\"aw\",@progbits#","ax",@progbits
     .globl x

It needs to unquote the string.

reed kotler <rkotler@mips.com> writes:

I'm going to file this bug but it's kind of a blocker for me so maybe
someone has time
to look at it. Should be nearly trivial to fix.

Bugs should be reported to http://www.llvm.org/bugs/

Reports sent to the mailing list are very likely to be forgotten.

I don't think this is a bug, but a misfeature in GCC due to the way it
does (non-)escaping.

Joerg

This is a feature (or bug) of MCSectionELF::PrintSwitchToSection. For
ELF target this function tries to escape string if it founds
'suspicious' character, see implementation in MCSectionELF.cpp:

  StringRef name = getSectionName();
  if (name.find_first_not_of("0123456789_."
                             "abcdefghijklmnopqrstuvwxyz"
                             "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == name.npos) {
    OS << "\t.section\t" << name;
  } else {
    OS << "\t.section\t\"";

As section "name" is something like .mySection,\"aw\",@progbits# ,
this method puts all the string in quotes.
Other targets (COFF and MachO) doesn't have such treatment.

If looks like the code that transforms section names should be
removed. Does anybody know what this transformation is for?

It is exactly intended to handle section names as what they are --
section names. The only reason it works with GCC is because it writes an
assembler stream.

reed: correct use is to declare the section with inline asm first with
the desired attributes, followed by .previous to reset the old section.

Joerg

Yes, I see, the test MC/ELF/section-quoting.s checks that. Description
of this attbitute in GCC manual also implies names only, not
attributes.
Thank you for clarification!

It is exactly intended to handle section names as what they are --
section names. The only reason it works with GCC is because it writes an
assembler stream.

+1

Reed, this fails in gcc if you do LTO, no?

Joerg

Cheers,
Rafael

This came about in trying to implement some stubs used by gcc mips16 for allowing floating point interoperability with mips32.

You get the following looking code from gcc -mips16:

  # Stub function for foovf (float)
  .section .mips16.fn.foovf,"ax",@progbits
  .align 2
  .set nomips16
  .set nomicromips
  .ent __fn_stub_foovf
  .type __fn_stub_foovf, @function
__fn_stub_foovf:
  la $25,foovf
  mfc1 $4,$f12
  jr $25
  .end __fn_stub_foovf
  .text
  $__fn_local_foovf = foovf

Not being sure about the restriction of section to just "name", well docs can be wrong and not match the code, I Googled for this:

http://stackoverflow.com/questions/6252812/what-does-the-aw-flag-in-the-section-attribute-mean

This implied that it was okay to do what I tried.

I have not looked at how gcc implements this internally but in LLVM I'm creating real IR for a function (the stub being in mips32 mode; even though the rest of the compilation unit is being compiled in mips16 mode). This is one (not the only) reason why I implemented the ability to switch processor modes on a per function basis.

As Joerg pointed out, I could create the section change myself with inline assembly.I'm not really comfortable emitting inline assembly from the compiler that has anything other than instructions or something in direct support of an instruction stream and not things that could interfere with the global sequencing of things like sections by the compiler. While users can do this; they are then more responsible for making sure that they have not shot themselves in the foot. On the other side, since these are "naked" functions, one could argue that changing sections is safe to do inside the function itself.
We do have some ability in MIPS16 to do inline assembly in the presence of the direct object emitter but I'm not sure if it could do something like this right now.

The clean solution is probably to add two additional function attributes to cover these additional pieces, namely "ax" and @progbits.

Thoughts?

Reed

Extend the section attribute to allow additional parameters?

Joerg

The idea would be to create additional function attributes.
I have not spent time thinking this through yet.

section_flags("flags")
section_type("type")
others....

so then

void x(int i) __attributes__((section("mysection"), section_flags("aw"), section_type("@progbits")) ;

or maybe extend the syntax of section

section(<name> [<section_flags>] [,<type>])

The clean solution is probably to add two additional function
attributes to cover these additional pieces, namely "ax" and
@progbits.

Extend the section attribute to allow additional parameters?

Joerg

The idea would be to create additional function attributes.
I have not spent time thinking this through yet.

section_flags("flags")
section_type("type")
others....

This sounds awful.

so then

void x(int i) __attributes__((section("mysection"), section_flags("aw"),
section_type("@progbits")) ;

or maybe extend the syntax of section

section(<name> [<section_flags>] [,<type>])

This not so much.

-eric

The idea would be to create additional function attributes.
I have not spent time thinking this through yet.

section_flags("flags")
section_type("type")
others....

What would the semantic be of having section_flags but no section name?

so then

void x(int i) __attributes__((section("mysection"), section_flags("aw"),
section_type("@progbits")) ;

or maybe extend the syntax of section

section(<name> [<section_flags>] [,<type>])

This avoids the above mentioned problem, so it is probably better.

Cheers,
Rafael

>>The clean solution is probably to add two additional function
>>attributes to cover these additional pieces, namely "ax" and
>>@progbits.
>
>Extend the section attribute to allow additional parameters?
>
>Joerg
>
The idea would be to create additional function attributes.
I have not spent time thinking this through yet.

section_flags("flags")
section_type("type")
others....

Awful :slight_smile:

so then

void x(int i) __attributes__((section("mysection"),
section_flags("aw"), section_type("@progbits")) ;

This too.

or maybe extend the syntax of section

section(<name> [<section_flags>] [,<type>])

Better and what I meant.

Joerg

would if be acceptable if this was in quotes:
"<name> [<section_flags>] [,<type>]"

???

So basically parsing this gas code.

I have not looked at how gcc implements this internally but in LLVM I'm
creating real IR for a function (the stub being in mips32 mode; even though
the rest of the compilation unit is being compiled in mips16 mode). This is
one (not the only) reason why I implemented the ability to switch processor
modes on a per function basis.

Now that I see where this is from, why don't you add an attribute
(calling convention?) to the function saying it is a thunk and then
the mips backend can print the correct assembly to put it in a
separate section with the correct flags.

This looks somewhat similar to some functions being printed to
different comdat sections. Follow the compilation of

define weak_odr void @bar() {
  ret void
}

noticed how the IL has no explicit section, but the assembly has

.section .text.bar,"axG",@progbits,bar,comdat

Cheers,
Rafael

weak_odr is predefined in llvm AsmPrinter

that will get handled in AsmPrint::EmitLinkage

EmitFunctionHeader is not a virtual function and that is where the segment gets switched.

It's possible that we can emit another .section directive in EmitFunctionEntryLabel

I'll have to play around with this.

Thanks for the ideas (from you and others).

Reed

I think that Rafaels suggestion of adding a new mips attribute can solve my short term needs. It can be an llvm only string type attribute.

Long term, what about just allowing the full gas syntax for .section and extending the meaning of section() to be not just name but the full gas syntax. So that should work the same as it does for gas/gcc and will also work for direct object emitter.

We just have to parse that string and extract flags, type information ,etc.

???

Reed