This is an archive of the discontinued LLVM Phabricator instance.

Implement .reloc (constant offset only) with support for R_MIPS_NONE and R_MIPS_32.
ClosedPublic

Authored by dsanders on Oct 12 2015, 8:49 AM.

Details

Summary

Support for R_MIPS_NONE allows us to parse MIPS16's usage of .reloc.
R_MIPS_32 was included to be able to better test the directive.

Targets can add their relocations by overriding MCAsmBackend::getFixupKind().

Diff Detail

Repository
rL LLVM

Event Timeline

dsanders updated this revision to Diff 37121.Oct 12 2015, 8:49 AM
dsanders retitled this revision from to Implement .reloc (constant offset only) with support for R_MIPS_NONE and R_MIPS_32..
dsanders updated this object.
dsanders added a subscriber: llvm-commits.
majnemer added inline comments.
include/llvm/MC/MCObjectStreamer.h
127–128 ↗(On Diff #37121)

Will there be any direct calls of this? If not, I'd just drop the default argument.

include/llvm/MC/MCStreamer.h
692 ↗(On Diff #37121)

Shouldn't this return true because nothing was emitted?

lib/MC/MCAsmStreamer.cpp
242–243 ↗(On Diff #37121)

Will there be any direct calls of this? If not, I'd just drop the default argument.

lib/MC/MCParser/AsmParser.cpp
4528–4531 ↗(On Diff #37121)

Not all targets support an addend, this should be predicated on a hook.

Thanks

include/llvm/MC/MCObjectStreamer.h
127–128 ↗(On Diff #37121)

Probably not, I'll drop the default part. MIPS16 might use it at some point in the future but I can always bring it back later if it's required.

include/llvm/MC/MCStreamer.h
692 ↗(On Diff #37121)

I think false makes the most sense. Returning true would cause all targets to silently accept and ignore any relocation name. By returning false, we emit an error message about the unknown/unsupported name.

lib/MC/MCParser/AsmParser.cpp
4528–4531 ↗(On Diff #37121)

This isn't the addend, it's the section offset the relocation is applied to. I believe you're thinking of the expression that's parsed on line 4547. If that's the case, I agree. I'll also make that expression optional like it should be.

majnemer added inline comments.Oct 26 2015, 4:10 PM
include/llvm/MC/MCStreamer.h
692 ↗(On Diff #37121)

Your comment says:

Returns true if the relocation could not be emitted because Name is not known.

All relocations cannot be emitted by this implementation because Name will never be known, hence the function should return true.

If you'd be happier with it returning false, that's fine but please change the comment to be consistent. Also, this case needs a test.

dsanders added inline comments.Oct 26 2015, 6:32 PM
include/llvm/MC/MCStreamer.h
692 ↗(On Diff #37121)

That'll teach me to use true to indicate failure. Sorry, you're absolutely right that I'm returning success instead of failure in this implementation. I'll fix this.

dsanders updated this revision to Diff 38584.Oct 27 2015, 1:02 PM

Fix all review comments except for the addend hook which I'm still thinking
about:

  • Loc argument no longer optional.
  • Fixed accidental success/fail inversion in MCStreamer::EmitRelocDirective. I've retained true==failure despite my misgivings about it since it's consistent with the other Emit*() functions.
  • .reloc expression is now optional.
dsanders added inline comments.Oct 27 2015, 7:01 PM
lib/MC/MCParser/AsmParser.cpp
4611–4614 ↗(On Diff #38584)

Do you know any cases where the addend isn't supported? The GAS documentation says that ELF REL targets such as 386 don't support addends but I'm finding they work. Similarly, addends are also working for MIPS O32 which is also a REL target.

What happens when you do:

.text
.long .text+2
.reloc 0, R_MIPS_32, .text+3
lib/MC/MCParser/AsmParser.cpp
368 ↗(On Diff #38584)

It'd be nicer if this could be closer to DK_VALUE. I'd just leave it on it's own line.

488–489 ↗(On Diff #38584)

Could this be moved near the handler for .value ?

4611–4614 ↗(On Diff #38584)

NT targets use REL relocations and they work with mingw assemblers. Perhaps the comment is out of date.

lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h
27 ↗(On Diff #38584)

Would it be more consistent to name this fixup_Mips_NONE ?

What happens when you do:

.text
.long .text+2
.reloc 0, R_MIPS_32, .text+3

I get:

Disassembly of section .text:

00000000 <.text>:
   0:	00000005 	lsa	zero,zero,zero,0x1
			0: R_MIPS_32	.text
			0: R_MIPS_32	.text
	...

The two addends are summed and stored in the section while two R_MIPS_32 relocs for .text are emitted.

lib/MC/MCParser/AsmParser.cpp
368 ↗(On Diff #38584)

Ok

488–489 ↗(On Diff #38584)

Ok

4611–4614 ↗(On Diff #38584)

Seems like it. Shall we leave this patch as always accepting addends and follow-up later if we find a case that doesn't work?

lib/Target/Mips/MCTargetDesc/MipsFixupKinds.h
27 ↗(On Diff #38584)

I agree. There's a couple inconsistencies below but there's no need to add more

majnemer added inline comments.Oct 27 2015, 10:41 PM
lib/MC/MCObjectStreamer.cpp
447–448 ↗(On Diff #38584)

I don't believe you have a test case which exercises this case. I'm a little confused as to why we need to create a symbol here. GNU as doesn't seem to do this:

$ cat t.s
.text
.long 0
.reloc .text, R_X86_64_32
$ as t.s -o t.o
$ objdump -r t.o
t.o:     file format elf64-x86-64

RELOCATION RECORDS FOR [.text]:
OFFSET           TYPE              VALUE                                                                                                                                                   
0000000000000000 R_X86_64_32       *ABS*
lib/MC/MCParser/AsmParser.cpp
4603 ↗(On Diff #38584)

It might be nice to have a comment here describing the syntax using pseudo-EBNF. We do this for some directives like parseDirectiveRept and it makes it a little easier to see the "big idea".

4628–4629 ↗(On Diff #38584)

I think we should evaluateAsRelocatable the Expr to sanity check the expression. Stuff like .text + .text should fail with a nice message.

dsanders added inline comments.Oct 27 2015, 11:05 PM
lib/MC/MCObjectStreamer.cpp
447–448 ↗(On Diff #38584)

It's the:

.reloc 12, R_MIPS_NONE # ASM: .reloc 12, R_MIPS_NONE{{$}}

The temporary symbol arose from experimentation. Leaving Expr as nullptr leads to a crash and using '0' causes the reloc to be omitted in the output. Using a temporary symbol like this causes both 'objdump -dr' and 'llvm-readobj -sections -section-data -r'* output to match between the integrated assembler and gas.

*llvm-readobj does show differences compared to gas but they aren't related to the reloc or the text section.

lib/MC/MCParser/AsmParser.cpp
4603 ↗(On Diff #38584)

I noticed this when I moved the implementation near parseDirectiveValue. I've already added one in my working copy.

4628–4629 ↗(On Diff #38584)

Ok, that makes sense.

dsanders updated this revision to Diff 38629.Oct 27 2015, 11:41 PM

Moved .reloc related things near to .value related things.
s/fixup_Mips_None/fixup_Mips_NONE/g
Check that the expression is relocatable.

Thanks for quickly working through the feedback :)

This LGTM but I'd be more comfortable with somebody else concurring, perhaps @grosbach or @rafael.

lib/MC/MCObjectStreamer.cpp
446 ↗(On Diff #38629)

You could reduce indentation by returning true if getFixupKind fails.

This revision was automatically updated to reflect the committed changes.

I committed this in r252888 since I have an LGTM from David and there have been no further comments in the last two weeks.

lib/MC/MCObjectStreamer.cpp
446 ↗(On Diff #38629)

I made this change in the commit.

@majnemer: Nearly forgot to say: Thanks for the reviews.