diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2018-08-02 17:33:42 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2018-08-02 17:33:42 +0000 | 
| commit | 84c4061b34e048f47e5eb4fbabc1558495e8157c (patch) | |
| tree | 83f9a0fbaadd2f5e3adac8f066cc8160781b385d /ELF/InputFiles.cpp | |
| parent | 20d35e67e67f106f617c939725101223211659f0 (diff) | |
Diffstat (limited to 'ELF/InputFiles.cpp')
| -rw-r--r-- | ELF/InputFiles.cpp | 42 | 
1 files changed, 42 insertions, 0 deletions
| diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp index 6da722f6f30e..0eb605a556ae 100644 --- a/ELF/InputFiles.cpp +++ b/ELF/InputFiles.cpp @@ -494,6 +494,46 @@ void ObjFile<ELFT>::initializeSections(    }  } +// For ARM only, to set the EF_ARM_ABI_FLOAT_SOFT or EF_ARM_ABI_FLOAT_HARD +// flag in the ELF Header we need to look at Tag_ABI_VFP_args to find out how +// the input objects have been compiled. +static void updateARMVFPArgs(const ARMAttributeParser &Attributes, +                             const InputFile *F) { +  if (!Attributes.hasAttribute(ARMBuildAttrs::ABI_VFP_args)) +    // If an ABI tag isn't present then it is implicitly given the value of 0 +    // which maps to ARMBuildAttrs::BaseAAPCS. However many assembler files, +    // including some in glibc that don't use FP args (and should have value 3) +    // don't have the attribute so we do not consider an implicit value of 0 +    // as a clash. +    return; + +  unsigned VFPArgs = Attributes.getAttributeValue(ARMBuildAttrs::ABI_VFP_args); +  ARMVFPArgKind Arg; +  switch (VFPArgs) { +  case ARMBuildAttrs::BaseAAPCS: +    Arg = ARMVFPArgKind::Base; +    break; +  case ARMBuildAttrs::HardFPAAPCS: +    Arg = ARMVFPArgKind::VFP; +    break; +  case ARMBuildAttrs::ToolChainFPPCS: +    // Tool chain specific convention that conforms to neither AAPCS variant. +    Arg = ARMVFPArgKind::ToolChain; +    break; +  case ARMBuildAttrs::CompatibleFPAAPCS: +    // Object compatible with all conventions. +    return; +  default: +    error(toString(F) + ": unknown Tag_ABI_VFP_args value: " + Twine(VFPArgs)); +    return; +  } +  // Follow ld.bfd and error if there is a mix of calling conventions. +  if (Config->ARMVFPArgs != Arg && Config->ARMVFPArgs != ARMVFPArgKind::Default) +    error(toString(F) + ": incompatible Tag_ABI_VFP_args"); +  else +    Config->ARMVFPArgs = Arg; +} +  // The ARM support in lld makes some use of instructions that are not available  // on all ARM architectures. Namely:  // - Use of BLX instruction for interworking between ARM and Thumb state. @@ -573,6 +613,8 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {      ArrayRef<uint8_t> Contents = check(this->getObj().getSectionContents(&Sec));      Attributes.Parse(Contents, /*isLittle*/ Config->EKind == ELF32LEKind);      updateSupportedARMFeatures(Attributes); +    updateARMVFPArgs(Attributes, this); +      // FIXME: Retain the first attribute section we see. The eglibc ARM      // dynamic loaders require the presence of an attribute section for dlopen      // to work. In a full implementation we would merge all attribute sections. | 
