aboutsummaryrefslogtreecommitdiffstats
path: root/lib/MC/WinCOFFObjectWriter.cpp
diff options
context:
space:
mode:
authorNico Rieck <nico.rieck@gmail.com>2013-07-06 12:13:10 +0000
committerNico Rieck <nico.rieck@gmail.com>2013-07-06 12:13:10 +0000
commit80646283796b20c6a1b7d8eb69ce6f0478d54383 (patch)
tree83b9be6b71faffa6cd481cea7736a172d36609ea /lib/MC/WinCOFFObjectWriter.cpp
parent2be430d251a781e76634e945d56224a7a0ef5a39 (diff)
downloadexternal_llvm-80646283796b20c6a1b7d8eb69ce6f0478d54383.tar.gz
external_llvm-80646283796b20c6a1b7d8eb69ce6f0478d54383.tar.bz2
external_llvm-80646283796b20c6a1b7d8eb69ce6f0478d54383.zip
MC: Implement COFF .linkonce directive
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185753 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/WinCOFFObjectWriter.cpp')
-rw-r--r--lib/MC/WinCOFFObjectWriter.cpp31
1 files changed, 30 insertions, 1 deletions
diff --git a/lib/MC/WinCOFFObjectWriter.cpp b/lib/MC/WinCOFFObjectWriter.cpp
index 518b59ee24..cf73396088 100644
--- a/lib/MC/WinCOFFObjectWriter.cpp
+++ b/lib/MC/WinCOFFObjectWriter.cpp
@@ -18,6 +18,7 @@
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAsmLayout.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
@@ -707,10 +708,13 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
// Assign symbol and section indexes and offsets.
Header.NumberOfSections = 0;
+ DenseMap<COFFSection *, uint16_t> SectionIndices;
for (sections::iterator i = Sections.begin(),
e = Sections.end(); i != e; i++) {
if (Layout.getSectionAddressSize((*i)->MCData) > 0) {
- MakeSectionReal(**i, ++Header.NumberOfSections);
+ size_t Number = ++Header.NumberOfSections;
+ SectionIndices[*i] = Number;
+ MakeSectionReal(**i, Number);
} else {
(*i)->Number = -1;
}
@@ -754,6 +758,31 @@ void WinCOFFObjectWriter::WriteObject(MCAssembler &Asm,
}
}
+ // Fixup associative COMDAT sections.
+ for (sections::iterator i = Sections.begin(),
+ e = Sections.end(); i != e; i++) {
+ if ((*i)->Symbol->Aux[0].Aux.SectionDefinition.Selection !=
+ COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
+ continue;
+
+ const MCSectionCOFF &MCSec = static_cast<const MCSectionCOFF &>(
+ (*i)->MCData->getSection());
+
+ COFFSection *Assoc = SectionMap.lookup(MCSec.getAssocSection());
+ if (!Assoc) {
+ report_fatal_error(Twine("Missing associated COMDAT section ") +
+ MCSec.getAssocSection()->getSectionName() +
+ " for section " + MCSec.getSectionName());
+ }
+
+ // Skip this section if the associated section is unused.
+ if (Assoc->Number == -1)
+ continue;
+
+ (*i)->Symbol->Aux[0].Aux.SectionDefinition.Number = SectionIndices[Assoc];
+ }
+
+
// Assign file offsets to COFF object file structures.
unsigned offset = 0;