[PECOFF] Emit BSS section.

llvm-svn: 187460
This commit is contained in:
Rui Ueyama 2013-07-30 22:56:46 +00:00
parent 029af15086
commit dcf09476ff
5 changed files with 97 additions and 5 deletions

View File

@ -205,14 +205,33 @@ private:
return a->Value < b->Value;
}));
ArrayRef<uint8_t> secData;
StringRef sectionName;
if (error_code ec = _obj->getSectionContents(section, secData))
return ec;
if (error_code ec = _obj->getSectionName(section, sectionName))
return ec;
uint64_t ordinal = -1;
// BSS section does not have contents. If this is the BSS section, create
// COFFBSSAtom instead of COFFDefinedAtom.
if (section->Characteristics &
llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
const coff_symbol *sym = *si;
uint32_t size = (si + 1 == se)
? section->SizeOfRawData - sym->Value
: si[1]->Value - sym->Value;
auto *atom = new (_alloc) COFFBSSAtom(
*this, _symbolName[sym], sym, section, size, sectionName,
++ordinal);
atoms.push_back(atom);
_symbolAtom[sym] = atom;
}
return error_code::success();
}
ArrayRef<uint8_t> secData;
if (error_code ec = _obj->getSectionContents(section, secData))
return ec;
// We do not support debug information yet. We could keep data in ".debug$S"
// section in the resultant binary by copying as opaque bytes, but it would
// make the binary hard to debug because of extraneous data. So we'll skip

View File

@ -432,7 +432,7 @@ public:
virtual uint32_t getVirtualAddress() { return _sectionHeader.VirtualAddress; }
const llvm::object::coff_section &getSectionHeader() {
virtual llvm::object::coff_section &getSectionHeader() {
// Fix up section size before returning it. VirtualSize should be the size
// of the actual content, and SizeOfRawData should be aligned to the section
// alignment.
@ -444,7 +444,7 @@ public:
void appendAtom(const DefinedAtom *atom) {
auto *layout = new (_alloc) AtomLayout(atom, _size, _size);
_atomLayouts.push_back(layout);
_size += atom->rawContent().size();
_size += atom->size();
}
static bool classof(const Chunk *c) { return c->getKind() == kindSection; }
@ -578,6 +578,35 @@ private:
llvm::COFF::IMAGE_SCN_MEM_WRITE;
};
// \brief A DataSectionChunk represents a .data section.
class BssSectionChunk : public SectionChunk {
public:
// BSS section does not have contents, so write should be no-op.
virtual void write(uint8_t *fileBuffer) {}
virtual llvm::object::coff_section &getSectionHeader() {
llvm::object::coff_section &sectionHeader =
SectionChunk::getSectionHeader();
sectionHeader.VirtualSize = 0;
sectionHeader.PointerToRawData = 0;
return sectionHeader;
}
BssSectionChunk(const File &linkedFile)
: SectionChunk(".bss", characteristics) {
buildContents(linkedFile, [](const DefinedAtom *atom) {
return atom->contentType() == DefinedAtom::typeZeroFill;
});
}
private:
// When loaded into memory, bss section should be readable and writable.
static const uint32_t characteristics =
llvm::COFF::IMAGE_SCN_MEM_READ |
llvm::COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
llvm::COFF::IMAGE_SCN_MEM_WRITE;
};
/// A BaseRelocAtom represents a base relocation block in ".reloc" section.
class BaseRelocAtom : public coff::COFFLinkerInternalAtom {
public:
@ -701,6 +730,7 @@ public:
auto *text = new TextSectionChunk(linkedFile);
auto *rdata = new RDataSectionChunk(linkedFile);
auto *data = new DataSectionChunk(linkedFile);
auto *bss = new BssSectionChunk(linkedFile);
BaseRelocChunk *baseReloc = nullptr;
if (_PECOFFTargetInfo.getBaseRelocationEnabled())
baseReloc = new BaseRelocChunk(linkedFile);
@ -718,6 +748,8 @@ public:
addSectionChunk(rdata, sectionTable);
if (data->size())
addSectionChunk(data, sectionTable);
if (bss->size())
addSectionChunk(bss, sectionTable);
// Now that we know the addresses of all defined atoms that needs to be
// relocated. So we can create the ".reloc" section which contains all the
@ -745,6 +777,7 @@ public:
peHeader->setBaseOfData(data->getVirtualAddress());
}
peHeader->setSizeOfInitializedData(rdata->size() + data->size());
peHeader->setSizeOfUninitializedData(bss->size());
peHeader->setNumberOfSections(_numSections);
peHeader->setSizeOfImage(_imageSizeInMemory);
}

View File

@ -0,0 +1,20 @@
.586
.model flat, c
extern ExitProcess@4 : PROC
_BSS SEGMENT
_x DD 064H DUP (?)
_y DD 064H DUP (?)
_BSS ENDS
.code
start:
mov eax, 42
mov _x, eax
mov eax, _x
push eax
call ExitProcess@4
end start
end

Binary file not shown.

View File

@ -0,0 +1,20 @@
# RUN: lld -flavor link /out:%t /subsystem:console /force -- %p/Inputs/bss.obj \
# RUN: && llvm-readobj -sections %t | FileCheck %s
CHECK: Section {
CHECK: Number: 2
CHECK-NEXT: Name: .bss
CHECK-NEXT: VirtualSize: 0x0
CHECK-NEXT: VirtualAddress: 0x2000
CHECK-NEXT: RawDataSize: 1024
CHECK-NEXT: PointerToRawData: 0x0
CHECK-NEXT: PointerToRelocations: 0x0
CHECK-NEXT: PointerToLineNumbers: 0x0
CHECK-NEXT: RelocationCount: 0
CHECK-NEXT: LineNumberCount: 0
CHECK-NEXT: Characteristics [
CHECK-NEXT: IMAGE_SCN_CNT_UNINITIALIZED_DATA
CHECK-NEXT: IMAGE_SCN_MEM_READ
CHECK-NEXT: IMAGE_SCN_MEM_WRITE
CHECK-NEXT: ]
CHECK-NEXT: }