mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
2c21fe4650
If a section is rw, it is irrelevant if the dynamic linker will write to it or not. It looks like llvm implemented this because gcc was doing it. It looks like gcc implemented this in the hope that it would put all the relocated items close together and speed up the dynamic linker. There are two problem with this: * It doesn't work. Both bfd and gold will map .data.rel to .data and concatenate the input sections in the order they are seen. * If we want a feature like that, it can be implemented directly in the linker since it knowns where the dynamic relocations are. llvm-svn: 253436
80 lines
3.0 KiB
C++
80 lines
3.0 KiB
C++
//===- lib/MC/MCWinEH.cpp - Windows EH implementation ---------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/MC/MCContext.h"
|
|
#include "llvm/MC/MCObjectFileInfo.h"
|
|
#include "llvm/MC/MCSectionCOFF.h"
|
|
#include "llvm/MC/MCStreamer.h"
|
|
#include "llvm/MC/MCSymbol.h"
|
|
#include "llvm/MC/MCWinEH.h"
|
|
#include "llvm/Support/COFF.h"
|
|
|
|
namespace llvm {
|
|
namespace WinEH {
|
|
|
|
/// We can't have one section for all .pdata or .xdata because the Microsoft
|
|
/// linker seems to want all code relocations to refer to the same object file
|
|
/// section. If the code described is comdat, create a new comdat section
|
|
/// associated with that comdat. If the code described is not in the main .text
|
|
/// section, make a new section for it. Otherwise use the main unwind info
|
|
/// section.
|
|
static MCSection *getUnwindInfoSection(StringRef SecName,
|
|
MCSectionCOFF *UnwindSec,
|
|
const MCSymbol *Function,
|
|
MCContext &Context) {
|
|
if (Function && Function->isInSection()) {
|
|
// If Function is in a COMDAT, get or create an unwind info section in that
|
|
// COMDAT group.
|
|
const MCSectionCOFF *FunctionSection =
|
|
cast<MCSectionCOFF>(&Function->getSection());
|
|
if (FunctionSection->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
|
|
return Context.getAssociativeCOFFSection(
|
|
UnwindSec, FunctionSection->getCOMDATSymbol());
|
|
}
|
|
|
|
// If Function is in a section other than .text, create a new .pdata section.
|
|
// Otherwise use the plain .pdata section.
|
|
if (const auto *Section = dyn_cast<MCSectionCOFF>(FunctionSection)) {
|
|
StringRef CodeSecName = Section->getSectionName();
|
|
if (CodeSecName == ".text")
|
|
return UnwindSec;
|
|
|
|
if (CodeSecName.startswith(".text$"))
|
|
CodeSecName = CodeSecName.substr(6);
|
|
|
|
return Context.getCOFFSection((SecName + Twine('$') + CodeSecName).str(),
|
|
COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
|
|
COFF::IMAGE_SCN_MEM_READ,
|
|
SectionKind::getData());
|
|
}
|
|
}
|
|
|
|
return UnwindSec;
|
|
|
|
}
|
|
|
|
MCSection *UnwindEmitter::getPDataSection(const MCSymbol *Function,
|
|
MCContext &Context) {
|
|
MCSectionCOFF *PData =
|
|
cast<MCSectionCOFF>(Context.getObjectFileInfo()->getPDataSection());
|
|
return getUnwindInfoSection(".pdata", PData, Function, Context);
|
|
}
|
|
|
|
MCSection *UnwindEmitter::getXDataSection(const MCSymbol *Function,
|
|
MCContext &Context) {
|
|
MCSectionCOFF *XData =
|
|
cast<MCSectionCOFF>(Context.getObjectFileInfo()->getXDataSection());
|
|
return getUnwindInfoSection(".xdata", XData, Function, Context);
|
|
}
|
|
|
|
}
|
|
}
|
|
|