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