This is an archive of the discontinued LLVM Phabricator instance.

Implementation of R_ARM_TARGET1
ClosedPublic

Authored by lenykholodov on Mar 30 2015, 1:00 PM.

Details

Summary

This patch provides implementation of R_ARM_TARGET1 relocation with configuration of its behaviour from a command line.

The R_ARM_TARGET1 relocation is processed in platform specific manner. Depending of the libc configuration it may be implemented as R_ARM_ABS32 or R_ARM_REL32. The decision which exact relocation should be used instead of R_ARM_TARGET1 is made immediately before the lld launch according to corresponding libc configuration. For example, linaro glibc expects R_ARM_ABS32 for R_ARM_TARGET1 relocation. It is flexible to configure lld with corresponding substitution for R_ARM_TARGET1 relocation from a command line (in the same way as ld utility works).

This patch provides two command line options for GnuLd driver: --arm-target1-rel and --arm-target1-abs (similar to ld option names with extra prefix 'arm-'). So user may choose which behaviour of R_ARM_TARGET1 is preferred for his implementation of libc (by default lld is using R_ARM_ABS32 relocation for R_ARM_TARGET1).

During the work of this patch there was an issue with implementation of command line options. They couldn't be implemented only in the driver file (GnuLdDriver.cpp) because they are target specific and should be ignored (and user should be warned about wrong using) for all targets except of armelf_linux_eabi. In this patch processing of target specific command line arguments has been divided on three parts:

  1. general processing of target specific options inside the driver (GnuLdDriver.cpp): it passes all arguments from grp_targetopts group to the ELFLinkingContext::applyTargetSpecificArgument method;
  2. printing warning about unknown target specific arguments in the implementation of ELFLinkingContext::applyTargetSpecificArgument;
  3. actual processing of incoming target specific arguments in the ARMLinkingContext::applyTargetSpecificArgument method (inside the lib\ReaderWriter\ELF\ARM component).

Thus, if the ARMLinkingContext::applyTargetSpecificArgument is called with known target specific argument (arm-target1-rel or arm-target1-abs), it processes it byself; in case of unknown argument, this method passes it to ELFLinkingContext::applyTargetSpecificArgument which finally warns user about mistake in command line. This solution also may be used in future for implementation of target specific arguments for another targets.

Diff Detail

Repository
rL LLVM

Event Timeline

lenykholodov retitled this revision from to Implementation of R_ARM_TARGET1.
lenykholodov updated this object.
lenykholodov edited the test plan for this revision. (Show Details)
lenykholodov set the repository for this revision to rL LLVM.
lenykholodov added a project: lld.
lenykholodov added a subscriber: Unknown Object (MLST).
ruiu added inline comments.Mar 30 2015, 2:39 PM
lib/Driver/GnuLdDriver.cpp
430 ↗(On Diff #22897)

There's no ambiguity on command line option meaning (--arm-target1-rel and --arm-target1-abs clearly for ARM only). Also in this context we already know what the target architecture is. So I don't think we need to abstract the thing away from the driver.

You can just check value of "triple" to see if it's ARM, and if it's ARM, call setTargetRel1(true or false) directly here. If it's not ARM, print out a warning message.

lib/ReaderWriter/ELF/ARM/ARMLinkingContext.cpp
40 ↗(On Diff #22897)

This parenthesis position style doesn't follow the LLVM coding style.

lib/ReaderWriter/ELF/ARM/ARMLinkingContext.h
56 ↗(On Diff #22897)

Let's use C++11 initializer.

bool _target1Rel = false;
lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.h
26 ↗(On Diff #22897)

Remove newline after comma.

Maybe you want to pass a boolean value instead of a context object itself? That makes it clear that you only need the boolean flag.

lenykholodov added inline comments.Mar 31 2015, 6:05 AM
lib/Driver/GnuLdDriver.cpp
430 ↗(On Diff #22897)

Ok. I'll move all command line processing stuff to driver class. Also, I'll remove applyTargetSpecificArg polymorphism.

lib/ReaderWriter/ELF/ARM/ARMLinkingContext.cpp
40 ↗(On Diff #22897)

Will be fixed.

lib/ReaderWriter/ELF/ARM/ARMLinkingContext.h
56 ↗(On Diff #22897)

WIll be fixed.

lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.h
26 ↗(On Diff #22897)

You are right. Will be fixed.

ruiu edited edge metadata.Mar 31 2015, 8:38 AM

Please upload a new patch when you are done. Thanks.

lenykholodov edited edge metadata.

Updates in the patch:

  • all command line options processing logic has been moved to GnuLdDriver class;
  • fixes in formatting and style.
ruiu added inline comments.Mar 31 2015, 11:27 AM
lib/Driver/GnuLdDriver.cpp
547 ↗(On Diff #22987)

Instead of defining two local variables in one statement, split them into two statements. It's what we usually do in LLVM.

551 ↗(On Diff #22987)

In this file we can safely assume that we are handling ELF, so you can remove this line.

559 ↗(On Diff #22987)

Use hasArmTarget1Rel instead.

562 ↗(On Diff #22987)

Use hasArmTarget1Abs instead.

lenykholodov added inline comments.Mar 31 2015, 11:31 AM
lib/ReaderWriter/ELF/ARM/ARMRelocationHandler.h
26 ↗(On Diff #22897)

Unfortunately, the ARMRelocationHandler class initializes before the command line arguments parsing. So when I'm passing bool variable to the ARMRelocationHandler construtor, this variable contains only a default value. I've rewritten the code. Now it retrieves ELFLinkingContext through _armLayout field which has been already added to the class ARMRelocationHandler before my patch and has access to the ELFLinkingContext.

shankarke added inline comments.
lib/Driver/GnuLdOptions.td
306–312 ↗(On Diff #22987)

I dont see these options in the bfd or the gold linker. Do we need to really have these options ?

<snip>

$ ld.bfd --help | grep arm
$ ld.gold --help | grep arm

--fix-arm1176               (ARM only) Fix binaries for ARM1176 erratum.
--no-fix-arm1176            (ARM only) Do not fix binaries for ARM1176 erratum.

</snip>

lenykholodov added inline comments.Mar 31 2015, 11:38 AM
lib/Driver/GnuLdOptions.td
306–312 ↗(On Diff #22987)

It uses them without 'arm-' prefix. I've added it to emphasize their architecture specific nature.

lenykholodov added inline comments.Mar 31 2015, 11:41 AM
lib/Driver/GnuLdOptions.td
306–312 ↗(On Diff #22987)

You can find them in the file ld\emultempl\armelf.em:

fprintf (file, _("  --target1-rel               Interpret R_ARM_TARGET1 as R_ARM_REL32\n"));
fprintf (file, _("  --target1-abs               Interpret R_ARM_TARGET1 as R_ARM_ABS32\n"));

Small changes in command line options processing logic according to the review comments.

ruiu accepted this revision.Mar 31 2015, 12:43 PM
ruiu edited edge metadata.

LGTM. Please update the commit message before committing.

lib/Driver/GnuLdDriver.cpp
563 ↗(On Diff #22996)

nit: can you make these two "if"s into two "else if"s in order to reduce nesting level?

This revision is now accepted and ready to land.Mar 31 2015, 12:43 PM
denis-protivensky added inline comments.
lib/Driver/GnuLdDriver.cpp
549 ↗(On Diff #22996)

You can remove this outermost if (hasArmTarget1Rel || hasArmTarget1Abs) check completely because it doesn't introduce any logic. All the cases are double-checked inside it.

lenykholodov edited edge metadata.
  • rebase with master;
  • small updates for decreasing nesting level.
ruiu added a comment.Apr 2 2015, 1:32 PM

Please submit.

This revision was automatically updated to reflect the committed changes.