brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · 79774db Raw
210 lines · cpp
1//===- lib/MC/MCSymbolELF.cpp ---------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "llvm/MC/MCSymbolELF.h"10#include "llvm/BinaryFormat/ELF.h"11 12namespace llvm {13 14namespace {15enum {16  // Shift value for STT_* flags. 7 possible values. 3 bits.17  ELF_STT_Shift = 0,18 19  // Shift value for STB_* flags. 4 possible values, 2 bits.20  ELF_STB_Shift = 3,21 22  // Shift value for STV_* flags. 4 possible values, 2 bits.23  ELF_STV_Shift = 5,24 25  // Shift value for STO_* flags. 3 bits. All the values are between 0x20 and26  // 0xe0, so we shift right by 5 before storing.27  ELF_STO_Shift = 7,28 29  // One bit.30  ELF_IsSignature_Shift = 10,31 32  // One bit.33  ELF_Weakref_Shift = 11,34 35  // One bit.36  ELF_BindingSet_Shift = 12,37 38  // One bit.39  ELF_IsMemoryTagged_Shift = 13,40};41}42 43void MCSymbolELF::setBinding(unsigned Binding) const {44  setIsBindingSet();45  unsigned Val;46  switch (Binding) {47  default:48    llvm_unreachable("Unsupported Binding");49  case ELF::STB_LOCAL:50    Val = 0;51    break;52  case ELF::STB_GLOBAL:53    Val = 1;54    break;55  case ELF::STB_WEAK:56    Val = 2;57    break;58  case ELF::STB_GNU_UNIQUE:59    Val = 3;60    break;61  }62  uint32_t OtherFlags = getFlags() & ~(0x3 << ELF_STB_Shift);63  setFlags(OtherFlags | (Val << ELF_STB_Shift));64}65 66unsigned MCSymbolELF::getBinding() const {67  if (isBindingSet()) {68    uint32_t Val = (Flags >> ELF_STB_Shift) & 3;69    switch (Val) {70    default:71      llvm_unreachable("Invalid value");72    case 0:73      return ELF::STB_LOCAL;74    case 1:75      return ELF::STB_GLOBAL;76    case 2:77      return ELF::STB_WEAK;78    case 3:79      return ELF::STB_GNU_UNIQUE;80    }81  }82 83  if (isDefined())84    return ELF::STB_LOCAL;85  if (isUsedInReloc())86    return ELF::STB_GLOBAL;87  if (isSignature())88    return ELF::STB_LOCAL;89  return ELF::STB_GLOBAL;90}91 92void MCSymbolELF::setType(unsigned Type) const {93  unsigned Val;94  switch (Type) {95  default:96    llvm_unreachable("Unsupported Binding");97  case ELF::STT_NOTYPE:98    Val = 0;99    break;100  case ELF::STT_OBJECT:101    Val = 1;102    break;103  case ELF::STT_FUNC:104    Val = 2;105    break;106  case ELF::STT_SECTION:107    Val = 3;108    break;109  case ELF::STT_COMMON:110    Val = 4;111    break;112  case ELF::STT_TLS:113    Val = 5;114    break;115  case ELF::STT_GNU_IFUNC:116    Val = 6;117    break;118  }119  uint32_t OtherFlags = getFlags() & ~(0x7 << ELF_STT_Shift);120  setFlags(OtherFlags | (Val << ELF_STT_Shift));121}122 123unsigned MCSymbolELF::getType() const {124  uint32_t Val = (Flags >> ELF_STT_Shift) & 7;125  switch (Val) {126  default:127    llvm_unreachable("Invalid value");128  case 0:129    return ELF::STT_NOTYPE;130  case 1:131    return ELF::STT_OBJECT;132  case 2:133    return ELF::STT_FUNC;134  case 3:135    return ELF::STT_SECTION;136  case 4:137    return ELF::STT_COMMON;138  case 5:139    return ELF::STT_TLS;140  case 6:141    return ELF::STT_GNU_IFUNC;142  }143}144 145void MCSymbolELF::setVisibility(unsigned Visibility) {146  assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||147         Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);148 149  uint32_t OtherFlags = getFlags() & ~(0x3 << ELF_STV_Shift);150  setFlags(OtherFlags | (Visibility << ELF_STV_Shift));151}152 153unsigned MCSymbolELF::getVisibility() const {154  unsigned Visibility = (Flags >> ELF_STV_Shift) & 3;155  return Visibility;156}157 158void MCSymbolELF::setOther(unsigned Other) {159  assert((Other & 0x1f) == 0);160  Other >>= 5;161  assert(Other <= 0x7);162  uint32_t OtherFlags = getFlags() & ~(0x7 << ELF_STO_Shift);163  setFlags(OtherFlags | (Other << ELF_STO_Shift));164}165 166unsigned MCSymbolELF::getOther() const {167  unsigned Other = (Flags >> ELF_STO_Shift) & 7;168  return Other << 5;169}170 171void MCSymbolELF::setIsWeakref() const {172  uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_Weakref_Shift);173  setFlags(OtherFlags | (1 << ELF_Weakref_Shift));174}175 176bool MCSymbolELF::isWeakref() const {177  return getFlags() & (0x1 << ELF_Weakref_Shift);178}179 180void MCSymbolELF::setIsSignature() const {181  uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_IsSignature_Shift);182  setFlags(OtherFlags | (1 << ELF_IsSignature_Shift));183}184 185bool MCSymbolELF::isSignature() const {186  return getFlags() & (0x1 << ELF_IsSignature_Shift);187}188 189void MCSymbolELF::setIsBindingSet() const {190  uint32_t OtherFlags = getFlags() & ~(0x1 << ELF_BindingSet_Shift);191  setFlags(OtherFlags | (1 << ELF_BindingSet_Shift));192}193 194bool MCSymbolELF::isBindingSet() const {195  return getFlags() & (0x1 << ELF_BindingSet_Shift);196}197 198bool MCSymbolELF::isMemtag() const {199  return getFlags() & (0x1 << ELF_IsMemoryTagged_Shift);200}201 202void MCSymbolELF::setMemtag(bool Tagged) {203  uint32_t OtherFlags = getFlags() & ~(1 << ELF_IsMemoryTagged_Shift);204  if (Tagged)205    setFlags(OtherFlags | (1 << ELF_IsMemoryTagged_Shift));206  else207    setFlags(OtherFlags);208}209}210