1b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes//===- lib/MC/MCSectionELF.cpp - ELF Code Section Representation ----------===// 2b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes// 3b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes// The LLVM Compiler Infrastructure 4b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes// 5b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes// This file is distributed under the University of Illinois Open Source 6b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes// License. See LICENSE.TXT for details. 7b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes// 8b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes//===----------------------------------------------------------------------===// 9b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes 10b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes#include "llvm/MC/MCSectionELF.h" 114d2419d7519e2bc3b437d01984f9fb268dd7a3cdChris Lattner#include "llvm/MC/MCAsmInfo.h" 12b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes#include "llvm/MC/MCContext.h" 13df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne#include "llvm/MC/MCExpr.h" 144d2419d7519e2bc3b437d01984f9fb268dd7a3cdChris Lattner#include "llvm/MC/MCSymbol.h" 15c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola#include "llvm/Support/ELF.h" 16b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes#include "llvm/Support/raw_ostream.h" 17c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola 18b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopesusing namespace llvm; 19b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes 2074aae4726a66733c5872588287535a984f9a94c7Chris LattnerMCSectionELF::~MCSectionELF() {} // anchor. 21b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes 22b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes// ShouldOmitSectionDirective - Decides whether a '.section' directive 23b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes// should be printed before the section name 24a46918d2b1b63aa3db94aa10b9ea70209b84e274Benjamin Kramerbool MCSectionELF::ShouldOmitSectionDirective(StringRef Name, 254d2419d7519e2bc3b437d01984f9fb268dd7a3cdChris Lattner const MCAsmInfo &MAI) const { 262684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach 27b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes // FIXME: Does .section .bss/.data/.text work everywhere?? 28a46918d2b1b63aa3db94aa10b9ea70209b84e274Benjamin Kramer if (Name == ".text" || Name == ".data" || 29a46918d2b1b63aa3db94aa10b9ea70209b84e274Benjamin Kramer (Name == ".bss" && !MAI.usesELFSectionDirectiveForBSS())) 30b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes return true; 31b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes 32b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes return false; 33b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes} 34b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes 35de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindolastatic void printName(raw_ostream &OS, StringRef Name) { 36de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola if (Name.find_first_not_of("0123456789_." 37de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola "abcdefghijklmnopqrstuvwxyz" 38de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == Name.npos) { 39de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola OS << Name; 40de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola return; 41de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola } 42de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola OS << '"'; 43de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola for (const char *B = Name.begin(), *E = Name.end(); B < E; ++B) { 44de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola if (*B == '"') // Unquoted " 45de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola OS << "\\\""; 46de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola else if (*B != '\\') // Neither " or backslash 47de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola OS << *B; 48de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola else if (B + 1 == E) // Trailing backslash 49de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola OS << "\\\\"; 50de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola else { 51de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola OS << B[0] << B[1]; // Quoted character 52de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola ++B; 53de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola } 54de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola } 55de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola OS << '"'; 56de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola} 57de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola 5833adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattnervoid MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, 59df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne raw_ostream &OS, 60df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne const MCExpr *Subsection) const { 612684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach 62a46918d2b1b63aa3db94aa10b9ea70209b84e274Benjamin Kramer if (ShouldOmitSectionDirective(SectionName, MAI)) { 63df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne OS << '\t' << getSectionName(); 64df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne if (Subsection) 65df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne OS << '\t' << *Subsection; 66df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne OS << '\n'; 67b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes return; 68b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes } 69b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes 70de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola OS << "\t.section\t"; 71de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola printName(OS, getSectionName()); 72ea83b133503afcd6589cf317cbb54ccd9e100f57Joerg Sonnenberger 73b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes // Handle the weird solaris syntax if desired. 742684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach if (MAI.usesSunStyleELFSectionSwitchSyntax() && 751c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola !(Flags & ELF::SHF_MERGE)) { 761c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Flags & ELF::SHF_ALLOC) 77b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes OS << ",#alloc"; 781c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Flags & ELF::SHF_EXECINSTR) 79b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes OS << ",#execinstr"; 801c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Flags & ELF::SHF_WRITE) 81b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes OS << ",#write"; 82766f25306af343fb2784350cb4d8cd9ca180f0d3Benjamin Kramer if (Flags & ELF::SHF_EXCLUDE) 83766f25306af343fb2784350cb4d8cd9ca180f0d3Benjamin Kramer OS << ",#exclude"; 841c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Flags & ELF::SHF_TLS) 85b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes OS << ",#tls"; 8674aae4726a66733c5872588287535a984f9a94c7Chris Lattner OS << '\n'; 8774aae4726a66733c5872588287535a984f9a94c7Chris Lattner return; 8874aae4726a66733c5872588287535a984f9a94c7Chris Lattner } 892684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach 9074aae4726a66733c5872588287535a984f9a94c7Chris Lattner OS << ",\""; 911c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Flags & ELF::SHF_ALLOC) 9274aae4726a66733c5872588287535a984f9a94c7Chris Lattner OS << 'a'; 93766f25306af343fb2784350cb4d8cd9ca180f0d3Benjamin Kramer if (Flags & ELF::SHF_EXCLUDE) 94766f25306af343fb2784350cb4d8cd9ca180f0d3Benjamin Kramer OS << 'e'; 951c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Flags & ELF::SHF_EXECINSTR) 9674aae4726a66733c5872588287535a984f9a94c7Chris Lattner OS << 'x'; 975d618ef7f1ad005fc6912f3e9a08c044b082e47fRafael Espindola if (Flags & ELF::SHF_GROUP) 985d618ef7f1ad005fc6912f3e9a08c044b082e47fRafael Espindola OS << 'G'; 991c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Flags & ELF::SHF_WRITE) 10074aae4726a66733c5872588287535a984f9a94c7Chris Lattner OS << 'w'; 1011c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Flags & ELF::SHF_MERGE) 10274aae4726a66733c5872588287535a984f9a94c7Chris Lattner OS << 'M'; 1031c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Flags & ELF::SHF_STRINGS) 10474aae4726a66733c5872588287535a984f9a94c7Chris Lattner OS << 'S'; 1051c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Flags & ELF::SHF_TLS) 10674aae4726a66733c5872588287535a984f9a94c7Chris Lattner OS << 'T'; 1072684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach 10874aae4726a66733c5872588287535a984f9a94c7Chris Lattner // If there are target-specific flags, print them. 1091c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Flags & ELF::XCORE_SHF_CP_SECTION) 11074aae4726a66733c5872588287535a984f9a94c7Chris Lattner OS << 'c'; 1111c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Flags & ELF::XCORE_SHF_DP_SECTION) 11274aae4726a66733c5872588287535a984f9a94c7Chris Lattner OS << 'd'; 1132684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach 11474aae4726a66733c5872588287535a984f9a94c7Chris Lattner OS << '"'; 115b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes 11634be396a12b00a95a1353c356d64868798ea3098Rafael Espindola OS << ','; 11734be396a12b00a95a1353c356d64868798ea3098Rafael Espindola 11834be396a12b00a95a1353c356d64868798ea3098Rafael Espindola // If comment string is '@', e.g. as on ARM - use '%' instead 11934be396a12b00a95a1353c356d64868798ea3098Rafael Espindola if (MAI.getCommentString()[0] == '@') 12034be396a12b00a95a1353c356d64868798ea3098Rafael Espindola OS << '%'; 12134be396a12b00a95a1353c356d64868798ea3098Rafael Espindola else 12234be396a12b00a95a1353c356d64868798ea3098Rafael Espindola OS << '@'; 12334be396a12b00a95a1353c356d64868798ea3098Rafael Espindola 124c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola if (Type == ELF::SHT_INIT_ARRAY) 12534be396a12b00a95a1353c356d64868798ea3098Rafael Espindola OS << "init_array"; 126c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola else if (Type == ELF::SHT_FINI_ARRAY) 12734be396a12b00a95a1353c356d64868798ea3098Rafael Espindola OS << "fini_array"; 128c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola else if (Type == ELF::SHT_PREINIT_ARRAY) 12934be396a12b00a95a1353c356d64868798ea3098Rafael Espindola OS << "preinit_array"; 130c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola else if (Type == ELF::SHT_NOBITS) 13134be396a12b00a95a1353c356d64868798ea3098Rafael Espindola OS << "nobits"; 132c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola else if (Type == ELF::SHT_NOTE) 13398976610d2c8067efe04042f17486a4b6c746b31Rafael Espindola OS << "note"; 134c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola else if (Type == ELF::SHT_PROGBITS) 13534be396a12b00a95a1353c356d64868798ea3098Rafael Espindola OS << "progbits"; 13634be396a12b00a95a1353c356d64868798ea3098Rafael Espindola 13734be396a12b00a95a1353c356d64868798ea3098Rafael Espindola if (EntrySize) { 1381c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola assert(Flags & ELF::SHF_MERGE); 13934be396a12b00a95a1353c356d64868798ea3098Rafael Espindola OS << "," << EntrySize; 140b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes } 14134be396a12b00a95a1353c356d64868798ea3098Rafael Espindola 142de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola if (Flags & ELF::SHF_GROUP) { 143de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola OS << ","; 144de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola printName(OS, Group->getName()); 145de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola OS << ",comdat"; 146de9a1a2055851a0f0a88e459cd23a246a90efd45Rafael Espindola } 147b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes OS << '\n'; 148df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne 149df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne if (Subsection) 150df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne OS << "\t.subsection\t" << *Subsection << '\n'; 151b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes} 152b808588a3a5febe931896b3779d159ba90d836f7Bruno Cardoso Lopes 153083cf1574facc9ce468fba1735c794bd7e520108Jan Wen Voungbool MCSectionELF::UseCodeAlign() const { 1541c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola return getFlags() & ELF::SHF_EXECINSTR; 155083cf1574facc9ce468fba1735c794bd7e520108Jan Wen Voung} 156083cf1574facc9ce468fba1735c794bd7e520108Jan Wen Voung 157f2dc4aa562e2478a73fe5aeeeec16b1e496a0642Rafael Espindolabool MCSectionELF::isVirtualSection() const { 158c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return getType() == ELF::SHT_NOBITS; 159f2dc4aa562e2478a73fe5aeeeec16b1e496a0642Rafael Espindola} 160f2dc4aa562e2478a73fe5aeeeec16b1e496a0642Rafael Espindola 161186e7a0fb1b2028e4fa9c3efe29d9433c91b3f66Jan Wen Voungunsigned MCSectionELF::DetermineEntrySize(SectionKind Kind) { 162186e7a0fb1b2028e4fa9c3efe29d9433c91b3f66Jan Wen Voung if (Kind.isMergeable1ByteCString()) return 1; 163186e7a0fb1b2028e4fa9c3efe29d9433c91b3f66Jan Wen Voung if (Kind.isMergeable2ByteCString()) return 2; 164186e7a0fb1b2028e4fa9c3efe29d9433c91b3f66Jan Wen Voung if (Kind.isMergeable4ByteCString()) return 4; 165186e7a0fb1b2028e4fa9c3efe29d9433c91b3f66Jan Wen Voung if (Kind.isMergeableConst4()) return 4; 166186e7a0fb1b2028e4fa9c3efe29d9433c91b3f66Jan Wen Voung if (Kind.isMergeableConst8()) return 8; 167186e7a0fb1b2028e4fa9c3efe29d9433c91b3f66Jan Wen Voung if (Kind.isMergeableConst16()) return 16; 168186e7a0fb1b2028e4fa9c3efe29d9433c91b3f66Jan Wen Voung return 0; 169186e7a0fb1b2028e4fa9c3efe29d9433c91b3f66Jan Wen Voung} 170