ELF symbol table field st_other support,

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
This commit is contained in:
Jack Carter 2013-02-19 21:57:35 +00:00
parent 608e355484
commit 77afbdce53
7 changed files with 40 additions and 3 deletions

View 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);
};
}

View 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,

View 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:

View 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;

View 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;
}
}

View 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");
}

View File

@ -620,3 +620,8 @@ void MCStreamer::Finish() {
FinishImpl();
}
MCSymbolData &MCStreamer::getOrCreateSymbolData(MCSymbol *Symbol) {
report_fatal_error("Not supported!");
return *(static_cast<MCSymbolData*> (NULL));
}