[llvm-commits] Proof of concept patch for unifying the .s/ELF emission of .ARM.attributes

Gosh, this is taking a while :slight_smile:
Is there anything else I missed?

Another one I noticed. Instead of

 SmallString<32> \*FC = &currFileFragment\.getContents\(\);
 \(\*FC\) \+= static\_cast<char>\(attr\);
 \(\*FC\) \+= static\_cast<char>\(0xFF & v\);

You can do

OutStreamer\.EmitIntValue\(static\_cast<char>\(attr\), 1\);
OutStreamer\.EmitIntValue\(0xFF & v, 1\);

No? Using the streamer interface looks a lot more in line with what
the rest of the code does.

Hmm, I wish we had this discussion way earlier..

How would I emit things in different subsections? I can do a high
level switch to .ARM.attributes, and if I were emitting one blob from
begin to end, using the higher level interface would be preferable,
but it contains additional subsections - which are naturally
represented by MCDataFragments - Is there an MC equivalent of a
SubSection (which is-a Section so I can switch back and forth?)
Currently we only have stuff that go into the File subsection only,
but.. for futureproofing?

I pretty much duplicated style from MCELFObjectWriter.cpp, which does
muck with MCDataFragments -
(in function WriteRelocation() around line 910 of
MCELFObjectWriter.cpp ) I could not find an easier solution.
The code currently closely tracks the layout required in the section,
and its very simple, which itself was a win.

-jason

Hmm, I wish we had this discussion way earlier..

How would I emit things in different subsections? I can do a high
level switch to .ARM.attributes, and if I were emitting one blob from
begin to end, using the higher level interface would be preferable,
but it contains additional subsections - which are naturally
represented by MCDataFragments - Is there an MC equivalent of a
SubSection (which is-a Section so I can switch back and forth?)
Currently we only have stuff that go into the File subsection only,
but.. for futureproofing?

We cross that bridge when we get there. It might be that the best
thing to do is organize the code so that we output the subsections in
order. It might be to add some missing feature. For now using the
regular streamer API will make this code a lot easier to read.

-jason

Cheers,
Rafael

Hmm, I wish we had this discussion way earlier..

How would I emit things in different subsections? I can do a high
level switch to .ARM.attributes, and if I were emitting one blob from
begin to end, using the higher level interface would be preferable,
but it contains additional subsections - which are naturally
represented by MCDataFragments - Is there an MC equivalent of a
SubSection (which is-a Section so I can switch back and forth?)
Currently we only have stuff that go into the File subsection only,
but.. for futureproofing?

We cross that bridge when we get there. It might be that the best
thing to do is organize the code so that we output the subsections in
order. It might be to add some missing feature. For now using the
regular streamer API will make this code a lot easier to read.

Of the roughly 111 or so calls to EmitIntValue(), rouighly half are in
the Dwarf code, which is cross-architecture.
(And they have their own MCSection types to deal with back and forth
type issues)

Of the 45 remaining, there are 4 interesting uses in MCAsmStreamer.cpp
- (I suppose for emitting data constants in a cross platform manner)
The other remaining uses are in AsmPrinter, again to do cross platform things.
It seems a bit strange to use a high level hammer to do ballpeen
work..... But when in Rome.... :slight_smile:

Also what is the preferred method for MC way of setting out subsection
sizes after the fact? I am guessing I need to use an MCFixup?
How do I get an MCExpr to evaluate a method for the subsection size?
Is there an equivalent use in the places using MCFixup?
Do I need to add a new subclass to MCExpr for doing this?

JimG, can you please comment on the MachO specific parts in the
ARMAsmPrinter.cpp? Is there an example of a "subsection size" that is
"Fixed up" after all the blobs that go into that subsection are
emitted? The closest examples I could find weren't that close :frowning:
(Matter of fact, for ELF, it looks like the section sizes are actually
calculated after everything has been processed by MCAssembler, and the
headers sizes are not "fixed up" but completely rewritten from the
beginning)

Thanks!

-jason

Hi Jason,

Are you printing ELF symbols and sections with AsmPrinter? I was under
the impression that you'd create an MCPrinter to deal with the
format-independent and only use AsmPrinter/ELFPrinter for specific
calls (to AsmStreamer/ObjectStreamer).

Or maybe I got it all wrong...

cheers,
--renato

Of the 45 remaining, there are 4 interesting uses in MCAsmStreamer.cpp
- (I suppose for emitting data constants in a cross platform manner)
The other remaining uses are in AsmPrinter, again to do cross platform things.
It seems a bit strange to use a high level hammer to do ballpeen
work..... But when in Rome.... :slight_smile:

Hi Jason,

Are you printing ELF symbols and sections with AsmPrinter? I was under

No. the code in question is regarding the blobs in .ARM.attributes section :slight_smile:

the impression that you'd create an MCPrinter to deal with the
format-independent and only use AsmPrinter/ELFPrinter for specific
calls (to AsmStreamer/ObjectStreamer).

Uhh, something like that? :slight_smile:
AFAIK, The final assembly (ie. building the output) for file emission
is done via MCAssembler, with input from a bunch of other classes.
The misnamed AsmPrinter hierarchy is responsible for most of the
format independent emission (i.e. the stuff that gets put inside the
sections) for both .o and .s
There is a MCStreamer hierarchy which takes care of recording the
sequential output of blobs (and there are format specific streamers
for ELF etc...)
There are also format specific helpers (ELF/Macho)Objectwriter which
fill in the format specific bits..

-jason

Also what is the preferred method for MC way of setting out subsection
sizes after the fact? I am guessing I need to use an MCFixup?
How do I get an MCExpr to evaluate a method for the subsection size?
Is there an equivalent use in the places using MCFixup?
Do I need to add a new subclass to MCExpr for doing this?

JimG, can you please comment on the MachO specific parts in the
ARMAsmPrinter.cpp? Is there an example of a "subsection size" that is
"Fixed up" after all the blobs that go into that subsection are
emitted? The closest examples I could find weren't that close :frowning:
(Matter of fact, for ELF, it looks like the section sizes are actually
calculated after everything has been processed by MCAssembler, and the
headers sizes are not "fixed up" but completely rewritten from the
beginning)

I really don't follow. Please just convert the current patch to use
the existing APIs. If in the next one you really need a missing
feature it will be a lot easier to explain what it is.

Thanks!

-jason

Cheers,
Rafael

Also what is the preferred method for MC way of setting out subsection
sizes after the fact? I am guessing I need to use an MCFixup?
How do I get an MCExpr to evaluate a method for the subsection size?
Is there an equivalent use in the places using MCFixup?
Do I need to add a new subclass to MCExpr for doing this?

JimG, can you please comment on the MachO specific parts in the
ARMAsmPrinter.cpp? Is there an example of a "subsection size" that is
"Fixed up" after all the blobs that go into that subsection are
emitted? The closest examples I could find weren't that close :frowning:
(Matter of fact, for ELF, it looks like the section sizes are actually
calculated after everything has been processed by MCAssembler, and the
headers sizes are not "fixed up" but completely rewritten from the
beginning)

I really don't follow. Please just convert the current patch to use
the existing APIs. If in the next one you really need a missing
feature it will be a lot easier to explain what it is.

Hi Rafael.

That is exactly what I need - I need a nice MC way to output a at
least two different 4 byte size fields after all of the blobs in the
.ARM.attributes
are sent out. I am currently doing this manually by messing with the
MCDataFragment directly - (I cribbed from the ELFObjectwriter code)
The size field kind of acts like an ELF section header size field, but
trying to replicate the MCAssembler/MCLayout mechanics seemed a bit
much, and from the existing sources,
I could not find a relevant use of MCExpr/MCFixup that does this. I
even considered outputing a fake symbol, but that didn't work well
either. The code I have now was the simplest I could make it under the
constraints I found myself in. If there is a "better way" in MC to do
something like this, I'll be more than happy to do it, if just for my
own education.

Err... help?? :slight_smile:

Thanks!!

-jason

Hi Jason,

If I got it right, you need to write to the attributes section after
you have moved out to print the rest of the file.

I can't think of an example right now that would require that (as you
have most important information from the IR), but I believe GAS does
that when guessing the build attributes.

What are these two word you need to write? Why can't you write them
when building the attributes section?

cheers,
--renato

That is exactly what I need - I need a nice MC way to output a at
least two different 4 byte size fields after all of the blobs in the
.ARM.attributes are sent out.

Hi Jason,

If I got it right, you need to write to the attributes section after
you have moved out to print the rest of the file.

Hi Renato, I don't think that;s it. This is solely within the
.ARM.attributes section. It requires an overall section size declared
within it, as well as individual sub section sizes.

I can't think of an example right now that would require that (as you
have most important information from the IR), but I believe GAS does
that when guessing the build attributes.

What are these two word you need to write? Why can't you write them
when building the attributes section?

I guess I wasn't being clear. I am doing this when building the
.ARM.attributes section. Its the File, Symbol and Section chunks
within that section that need the size fields - which is byte offset
wise earlier than the blobs in those chunks.
The issue is that I need to "fix up" the subsection size after the
blobs in the various subsections are streamed out.
Doing that is easy if I directly access the stream (this is what I am
doing currently on this patch under review), and it works correctly.

What Rafael is asking me to do instead is to write the .ARM.attributes
section using only the "forward stream iterator" semantics found in
the MC.
Issue here is that there currently does NOT seem to be a nice way of
doing this kind of size field fixup purely in MC.

Hope this clears things up!

-jason

Hmm, I wish we had this discussion way earlier..

How would I emit things in different subsections? I can do a high
level switch to .ARM.attributes, and if I were emitting one blob from
begin to end, using the higher level interface would be preferable,
but it contains additional subsections - which are naturally
represented by MCDataFragments - Is there an MC equivalent of a
SubSection (which is-a Section so I can switch back and forth?)
Currently we only have stuff that go into the File subsection only,
but.. for futureproofing?

We cross that bridge when we get there. It might be that the best
thing to do is organize the code so that we output the subsections in
order. It might be to add some missing feature. For now using the
regular streamer API will make this code a lot easier to read.

Of the roughly 111 or so calls to EmitIntValue(), rouighly half are in
the Dwarf code, which is cross-architecture.
(And they have their own MCSection types to deal with back and forth
type issues)

Of the 45 remaining, there are 4 interesting uses in MCAsmStreamer.cpp
- (I suppose for emitting data constants in a cross platform manner)
The other remaining uses are in AsmPrinter, again to do cross platform things.
It seems a bit strange to use a high level hammer to do ballpeen
work..... But when in Rome.... :slight_smile:

Also what is the preferred method for MC way of setting out subsection
sizes after the fact? I am guessing I need to use an MCFixup?
How do I get an MCExpr to evaluate a method for the subsection size?
Is there an equivalent use in the places using MCFixup?
Do I need to add a new subclass to MCExpr for doing this?

JimG, can you please comment on the MachO specific parts in the
ARMAsmPrinter.cpp? Is there an example of a "subsection size" that is
"Fixed up" after all the blobs that go into that subsection are
emitted? The closest examples I could find weren't that close :frowning:
(Matter of fact, for ELF, it looks like the section sizes are actually
calculated after everything has been processed by MCAssembler, and the
headers sizes are not "fixed up" but completely rewritten from the
beginning)

There's no real equivalent to that for MachO in ARMAsmPrinter that I'm aware of. The Darwin linker can do quite a bit with rearranging things, so those sorts of values at compile/assemble time don't have much meaning. The parts that deal with section/subsection sizes for the object file format are, as far as I can tell, in the object file and section writer classes.

Hi Rafael

Included are two patches. The first one s06-mod, is the original one.
The s06-brk uses the high level Streamer interface, but currently does
not pass the test I added.

Please see the comments in the second patch. Hopefully it clarifies
the issues in using the high level MCStreamer interface in emitting
the .ARM.attributes ELF section directly.
It does not seem worthwhile to use the high level Streamer interface
for this kind of work, so I'd very much like some feedback on what
the preferred solution is.

Thanks!
-jason

arm-mc-elf-s06-mod.patch3 (12.4 KB)

arm-mc-elf-s06-brk.patch (12 KB)