ELF symbol table field st_other support,
authorJack Carter <jcarter@mips.com>
Tue, 19 Feb 2013 21:57:35 +0000 (21:57 +0000)
committerJack Carter <jcarter@mips.com>
Tue, 19 Feb 2013 21:57:35 +0000 (21:57 +0000)
excluding visibility bits.

Generic STO handling at the Target level.

The st_other field of the ELF symbol table is one
byte in size. The first 2 bytes are used for generic
visibility and are currently handled by llvm.

The other six bits are processor specific and need
to be set at the target level.

A couple of notes:

The new static methods for accessing and setting the "other"
flags in include/llvm/MC/MCELF.h match the style guide
and not the other methods in the file. I don't like the
inconsistency, but feel I should follow the prescribed
lowerUpper() convention.

STO_ value definitions are not specified in gnu land as
consistently as the STT_ and STB_ fields. Probably because
the latter were defined in a standards doc and the former
defined partially in code. I have stuck with the full byte
definition of the flags.

Contributer: Zoran Jovanovic

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@175561 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCELF.h
include/llvm/MC/MCELFStreamer.h
include/llvm/MC/MCStreamer.h
lib/MC/ELFObjectWriter.cpp
lib/MC/MCELF.cpp
lib/MC/MCELFStreamer.cpp
lib/MC/MCStreamer.cpp

index e08f1e65429a316efbb9ed35c7e8eeb4c936d967..7e59911a89c39002bc309eb68ed404585b80ee04 100644 (file)
@@ -28,6 +28,8 @@ class MCELF {
   static unsigned GetType(const MCSymbolData &SD);
   static void SetVisibility(MCSymbolData &SD, unsigned Visibility);
   static unsigned GetVisibility(MCSymbolData &SD);
+  static void setOther(MCSymbolData &SD, unsigned Other);
+  static unsigned getOther(MCSymbolData &SD);
 };
 
 }
index f78de157013809e126368f1a6b6c99e19a7a6003..6fb2d22be2e7090de43191af906ca2c726e48583 100644 (file)
@@ -65,6 +65,8 @@ public:
   virtual void EmitCOFFSymbolType(int Type);
   virtual void EndCOFFSymbolDef();
 
+  virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol);
+
   virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value);
 
   virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
index 9bc4a8bbb51fa4c6456fecc6d233416795d9fbc4..d247066cd9f7b9d2408819a8c7a446471c20ede2 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/MC/MCAssembler.h"
 #include "llvm/MC/MCDirectives.h"
 #include "llvm/MC/MCDwarf.h"
 #include "llvm/MC/MCWin64EH.h"
@@ -286,6 +287,9 @@ namespace llvm {
     /// a Thumb mode function (ARM target only).
     virtual void EmitThumbFunc(MCSymbol *Func) = 0;
 
+    /// getOrCreateSymbolData - Get symbol data for given symbol.
+    virtual MCSymbolData &getOrCreateSymbolData(MCSymbol *Symbol);
+
     /// EmitAssignment - Emit an assignment of @p Value to @p Symbol.
     ///
     /// This corresponds to an assembler statement such as:
index fb14dc96b390ee7fc71b92cd71c9822e681875e2..0b97f2700bef0028374744645cb8d41a8aa7ef68 100644 (file)
@@ -546,12 +546,17 @@ void ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF,
   bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() ||
     Data.getSymbol().isVariable();
 
+  // Binding and Type share the same byte as upper and lower nibbles
   uint8_t Binding = MCELF::GetBinding(OrigData);
-  uint8_t Visibility = MCELF::GetVisibility(OrigData);
   uint8_t Type = MCELF::GetType(Data);
-
   uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift);
-  uint8_t Other = Visibility;
+
+  // Other and Visibility share the same byte with Visability using the lower
+  // 2 bits
+  uint8_t Visibility = MCELF::GetVisibility(OrigData);
+  uint8_t Other = MCELF::getOther(OrigData) <<
+    (ELF_Other_Shift - ELF_STV_Shift);
+  Other |= Visibility;
 
   uint64_t Value = SymbolValue(Data, Layout);
   uint64_t Size = 0;
index 4db2846bc3d0739c53c3fb7baf9404cf76019e4e..560cdbc6abae750a5279173b84472a1981805014 100644 (file)
@@ -52,6 +52,8 @@ unsigned MCELF::GetType(const MCSymbolData &SD) {
   return Type;
 }
 
+// Visibility is stored in the first two bits of st_other
+// st_other values are stored in the second byte of get/setFlags
 void MCELF::SetVisibility(MCSymbolData &SD, unsigned Visibility) {
   assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL ||
          Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED);
@@ -68,4 +70,17 @@ unsigned MCELF::GetVisibility(MCSymbolData &SD) {
   return Visibility;
 }
 
+// Other is stored in the last six bits of st_other
+// st_other values are stored in the second byte of get/setFlags
+void MCELF::setOther(MCSymbolData &SD, unsigned Other) {
+  uint32_t OtherFlags = SD.getFlags() & ~(0x3f << ELF_Other_Shift);
+  SD.setFlags(OtherFlags | (Other << ELF_Other_Shift));
+}
+
+unsigned MCELF::getOther(MCSymbolData &SD) {
+  unsigned Other =
+    (SD.getFlags() & (0x3f << ELF_Other_Shift)) >> ELF_Other_Shift;
+  return Other;
+}
+
 }
index 8ddbfbbe8a44a1d557d9769df868610211c7f962..a9c35ccdf356928a76cd79fab3f363416bf47294 100644 (file)
@@ -504,6 +504,10 @@ void MCELFStreamer::EmitThumbFunc(MCSymbol *Func) {
   llvm_unreachable("Generic ELF doesn't support this directive");
 }
 
+MCSymbolData &MCELFStreamer::getOrCreateSymbolData(MCSymbol *Symbol) {
+  return getAssembler().getOrCreateSymbolData(*Symbol);
+}
+
 void MCELFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {
   llvm_unreachable("ELF doesn't support this directive");
 }
index 7d79d62830ff8773b8250aa3833b5c8ef2c9d429..9857f7bb08de4516997ff71d1a812ebc1a5f2ec8 100644 (file)
@@ -620,3 +620,8 @@ void MCStreamer::Finish() {
 
   FinishImpl();
 }
+
+MCSymbolData &MCStreamer::getOrCreateSymbolData(MCSymbol *Symbol) {
+  report_fatal_error("Not supported!");
+  return *(static_cast<MCSymbolData*> (NULL));
+}