[PATCH] D58102: Support X86 Control-flow Enforcement Technology (CET) in LLD

Xiang Zhang via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 19 01:36:54 PDT 2019


xiangzhangllvm added a comment.

I do this changes in my local:
I do the feature collection work in the GnuPropertySection's Constructor which will be called in createSyntheticSections(). 
For the SPlt, I keep its generation condition, because the GnuPropertySection's Constructor  will set the Config->SPltSectionEnable.

    1 diff --git a/ELF/Driver.cpp b/ELF/Driver.cpp
    2 index 7628df0..d5217bd 100644
    3 --- a/ELF/Driver.cpp
    4 +++ b/ELF/Driver.cpp
    5 @@ -1626,14 +1626,6 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
    6        return S->Name.startswith(".debug") || S->Name.startswith(".zdebug");
    7      });
    8
    9 -  // Merge aggregate metadata sections like .note.gnu.property that should be
   10 -  // found across all relocated files and reproduced once. But Until now, the
   11 -  // emitAggregateMetadata just deal with the X86Feature1AND info, and only X86_64, i386
   12 -  // support the X86Feature1AND.
   13 -  if ((Config->EMachine == EM_X86_64 || Config->EMachine == EM_386)
   14 -      && (Config->AutoCET || Config->ForceCET))
   15 -    mergeAggregateMetadata();
   16 -
   17    Config->EFlags = Target->calcEFlags();
   18
   19    if (Config->EMachine == EM_ARM) {
   20 diff --git a/ELF/SyntheticSections.cpp b/ELF/SyntheticSections.cpp
   21 index bb1c5d3..4ed1a72 100644
   22 --- a/ELF/SyntheticSections.cpp
   23 +++ b/ELF/SyntheticSections.cpp
   24 @@ -297,11 +297,11 @@ void GnuPropertySection::writeTo(uint8_t *Buf) {
   25    write32(Buf + 8, NT_GNU_PROPERTY_TYPE_0);  // Type
   26    memcpy(Buf + 12, "GNU", 4);                // Name string
   27
   28 -  // To Be Dnone
   29 +  // To Be Done
   30    // Now we only supported X86_FEATURE_1_AND in .note.gnu.property, so we fix
   31    // the Feature type to GNU_PROPERTY_X86_FEATURE_1_AND, it should be changed
   32    // when we try to fix other feature types in .note.gnu.property.
   33 -  DescBuf = Buf + 16;
   34 +  uint8_t *DescBuf = Buf + 16;
   35    write32(DescBuf, GNU_PROPERTY_X86_FEATURE_1_AND); // Feature type
   36    write32(DescBuf + 4, 4);                          // Feature size
   37    write32(DescBuf + 8, Feature1AND);                // Feature flags
   38 @@ -311,20 +311,17 @@ size_t GnuPropertySection::getSize() const {
   39    return 16 + DescSize;
   40  }
   41
   42 -void GnuPropertySection::setDescSize() {
   43 -  DescSize = getDescSize();
   44 +bool GnuPropertySection::empty() const {
   45 +  uint32_t Feature = getFeature();
   46 +  return Feature == 0x0;
   47  }
   48
   49 -// To Be Dnone
   50 -// Now we only supported X86_FEATURE_1_AND in .note.gnu.property, so we just
   51 -// get the feature of GNU_PROPERTY_X86_FEATURE_1_AND property, it should be
   52 -// changed when we try to support other feature types in .note.gnu.property.
   53 -uint32_t GnuPropertySection::getFeature() {
   54 -  return Config->X86Feature1AND;
   55 +void GnuPropertySection::setDescSize() {
   56 +  DescSize = getDescSize();
   57  }
   58
   59  void GnuPropertySection::setFeature() {
   60 -  Feature1AND = getFeature();
   61 +  Feature1AND = mergeAggregateMetadata();
   62  }
   63
   64  GnuPropertySection::GnuPropertySection()
   65 @@ -3054,12 +3051,11 @@ static MergeSyntheticSection *createMergeSynthetic(StringRef Name,
   66
   67  // Get the CFProtection properties from a X86F1AND section. The X86F1AND section
   68  // info can refert the comment of function findGNUPropertyX86Feature1AND.
   69 -static void readGNUPropertyX86Feature1AND(InputSectionBase *S,
   70 -                                          Configuration *Config,
   71 -                                          unsigned X86F1ANDDescLoca) {
   72 +static uint32_t readGNUPropertyX86Feature1AND(InputSectionBase *S,
   73 +                                              Configuration *Config,
   74 +                                              unsigned X86F1ANDDescLoca) {
   75    auto Data = S->getDataAs<uint32_t>();
   76    unsigned &Offset = X86F1ANDDescLoca;
   77 -
   78    unsigned pr_typeIndex = 0; // Offset of pr_type from start of 'desc'
   79    unsigned pr_dataIndex = 2; // Offset of pr_data from start of 'desc'
   80
   81 @@ -3067,14 +3063,7 @@ static void readGNUPropertyX86Feature1AND(InputSectionBase *S,
   82    if (Data[Offset + pr_typeIndex] != GNU_PROPERTY_X86_FEATURE_1_AND)
   83      error("There must be GNU_PROPERTY_X86_FEATURE_1_AND note!");
   84    uint32_t Flags = Data[Offset + pr_dataIndex];
   85 -
   86 -  // GNU_PROPERTY_X86_FEATURE_1_AND: Its pr_data field contains a 4-byte
   87 -  // integer. A bit in the output pr_data field is set only if it is set
   88 -  // in all relocatable input pr_data fields.
   89 -  Config->X86Feature1AND &= Flags;
   90 -
   91 -  Config->SPltSectionEnable = Config->X86Feature1AND
   92 -                              & GNU_PROPERTY_X86_FEATURE_1_IBT;
   93 +  return Flags;
   94  }
   95
   96  // Get the position of desc with GNU_PROPERTY_X86_FEATURE_1_AND.
   97 @@ -3219,11 +3208,11 @@ static bool findGNUPropertyX86Feature1AND(InputSectionBase *S,
   98  // other 'desc' in the .note.gnu.propery section. Here we first find all the
   99  // X86Feature1AND info section, then delete them, and finally rebuild the
  100  // X86Feature1AND section in the Writer if necessary.
  101 -void elf::mergeAggregateMetadata() {
  102 +uint32_t elf::mergeAggregateMetadata() {
  103    decltype (InputSections) X86F1ANDSections;
  104    bool IsAllFileF1AND = true;
  105 +  uint32_t X86Feature1AND = 0xFFFFFFFF;
  106    Config->SPltSectionEnable = true;
  107 -  Config->X86Feature1AND = 0xFFFFFFFF;
  108    for (InputFile *F : ObjectFiles) {
  109      unsigned X86F1ANDDescLoca = 0;
  110      auto I = llvm::find_if(InputSections, [&](InputSectionBase *S) {
  111 @@ -3242,12 +3231,16 @@ void elf::mergeAggregateMetadata() {
  112        if (Config->ForceCET)
  113          error(toString(F) + "must enable CET when using --force-cet");
  114       } else {
  115 -       readGNUPropertyX86Feature1AND(*I, Config, X86F1ANDDescLoca);
  116 +       uint32_t Feature = readGNUPropertyX86Feature1AND(*I, Config,
  117 +                                                        X86F1ANDDescLoca);
  118 +       X86Feature1AND &= Feature;
  119       }
  120    }
  121    if (!IsAllFileF1AND) {
  122      Config->SPltSectionEnable = false;
  123 -    Config->X86Feature1AND = 0x0;
  124 +    X86Feature1AND = 0x0;
  125 +  } else {
  126 +    Config->SPltSectionEnable = X86Feature1AND & GNU_PROPERTY_X86_FEATURE_1_IBT;
  127    }
  128
  129    // The resulting .note.gnu.property section will be created by the Writer
  130 @@ -3269,6 +3262,8 @@ void elf::mergeAggregateMetadata() {
  131      else
  132        return false;
  133    });
  134 +
  135 +  return X86Feature1AND;
  136  }
  137
  138  template <class ELFT> void elf::splitSections() {
  139 diff --git a/ELF/SyntheticSections.h b/ELF/SyntheticSections.h
  140 index f148281..e369ef1 100644
  141 --- a/ELF/SyntheticSections.h
  142 +++ b/ELF/SyntheticSections.h
  143 @@ -149,19 +149,19 @@ public:
  144    GnuPropertySection();
  145    void writeTo(uint8_t *Buf) override;
  146    size_t getSize() const override;
  147 +  bool empty() const override;
  148
  149 -  // To Be Dnone
  150 +  // To Be Done
  151    // Now we only supported X86_FEATURE_1_AND in .note.gnu.property, so we fix
  152 -  // the DescSize to one Desciption size, it may be mare than one Desciption
  153 +  // the DescSize to one Description size, it may be more than one Description
  154    // when we try to fix other feature types in .note.gnu.property.
  155 -  size_t getDescSize() {return 16;}
  156 +  size_t getDescSize() { return 16; }
  157    void setDescSize();
  158 -  uint32_t getFeature();
  159 +  uint32_t getFeature() const { return Feature1AND; }
  160    void setFeature();
  161
  162  private:
  163    size_t DescSize;
  164 -  uint8_t *DescBuf;
  165    uint32_t Feature1AND;
  166  };
  167
  168 @@ -1033,7 +1033,7 @@ private:
  169
  170  InputSection *createInterpSection();
  171  MergeInputSection *createCommentSection();
  172 -void mergeAggregateMetadata();
  173 +uint32_t mergeAggregateMetadata();
  174  template <class ELFT> void splitSections();
  175  void mergeSections();
  176
  177 diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
  178 index 11639e5..0deebb9 100644
  179 --- a/ELF/Writer.cpp
  180 +++ b/ELF/Writer.cpp
  181 @@ -335,6 +335,16 @@ template <class ELFT> static void createSyntheticSections() {
  182        Add(Sec);
  183    }
  184
  185 +  // Merge aggregate metadata sections like .note.gnu.property that should be
  186 +  // found across all relocated files and reproduced once. But Until now, the
  187 +  // emitAggregateMetadata just deal with the X86Feature1AND info, and only
  188 +  // X86_64, i386 support the X86Feature1AND.
  189 +  if ((Config->EMachine == EM_X86_64 || Config->EMachine == EM_386)
  190 +      && (Config->AutoCET || Config->ForceCET)) {
  191 +    In.GnuProperty = make<GnuPropertySection>();
  192 +    Add(In.GnuProperty);
  193 +  }
  194 +
  195    if (Config->HasDynSymTab) {
  196      In.DynSymTab = make<SymbolTableSection<ELFT>>(*In.DynStrTab);
  197      Add(In.DynSymTab);
  198 @@ -416,16 +426,12 @@ template <class ELFT> static void createSyntheticSections() {
  199    Add(In.Plt);
  200    In.Iplt = make<PltSection>(true);
  201    Add(In.Iplt);
  202 +
  203    if (Config->SPltSectionEnable) {
  204      In.Splt = make<SPltSection>();
  205      Add(In.Splt);
  206    }
  207
  208 -  if (Config->X86Feature1AND) {
  209 -    In.GnuProperty = make<GnuPropertySection>();
  210 -    Add(In.GnuProperty);
  211 -  }
  212 -
  213    // .note.GNU-stack is always added when we are creating a re-linkable
  214    // object file. Other linkers are using the presence of this marker
  215    // section to control the executable-ness of the stack area, but that


Repository:
  rLLD LLVM Linker

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D58102/new/

https://reviews.llvm.org/D58102





More information about the llvm-commits mailing list