Start allocating space for common symbols.

llvm-svn: 246496
This commit is contained in:
Rafael Espindola 2015-08-31 22:07:18 +00:00
parent c0dc76c251
commit 0518574a73
2 changed files with 46 additions and 12 deletions

View File

@ -60,6 +60,7 @@ public:
// Returns the size of the section in the output file.
uintX_t getSize() { return Header.sh_size; }
void setSize(uintX_t Val) { Header.sh_size = Val; }
uintX_t getFlags() { return Header.sh_flags; }
uintX_t getFileOff() { return Header.sh_offset; }
uintX_t getAlign() { return Header.sh_addralign; }
@ -149,6 +150,7 @@ template <class ELFT> class Writer {
public:
typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
Writer(SymbolTable *T)
: SymTable(*T), StringTable(T->getStringBuilder()) {}
void run();
@ -397,6 +399,18 @@ template <bool Is64Bits> struct DenseMapInfo<SectionKey<Is64Bits>> {
// Create output section objects and add them to OutputSections.
template <class ELFT> void Writer<ELFT>::createSections() {
SmallDenseMap<SectionKey<ELFT::Is64Bits>, OutputSection<ELFT> *> Map;
auto getSection = [&](StringRef Name, uint32_t sh_type,
uintX_t sh_flags) -> OutputSection<ELFT> * {
SectionKey<ELFT::Is64Bits> Key{Name, sh_type, sh_flags};
OutputSection<ELFT> *&Sec = Map[Key];
if (!Sec) {
Sec = new (CAlloc.Allocate())
OutputSection<ELFT>(Key.Name, Key.sh_type, Key.sh_flags);
addOutputSection(Sec);
}
return Sec;
};
const SymbolTable &Symtab = SymTable.getSymTable();
for (const std::unique_ptr<ObjectFileBase> &FileB : Symtab.ObjectFiles) {
auto &File = cast<ObjectFile<ELFT>>(*FileB);
@ -404,17 +418,27 @@ template <class ELFT> void Writer<ELFT>::createSections() {
if (!C)
continue;
const Elf_Shdr *H = C->getSectionHdr();
SectionKey<ELFT::Is64Bits> Key{C->getSectionName(), H->sh_type,
H->sh_flags};
OutputSection<ELFT> *&Sec = Map[Key];
if (!Sec) {
Sec = new (CAlloc.Allocate())
OutputSection<ELFT>(Key.Name, Key.sh_type, Key.sh_flags);
addOutputSection(Sec);
}
OutputSection<ELFT> *Sec =
getSection(C->getSectionName(), H->sh_type, H->sh_flags);
Sec->addChunk(C);
}
}
OutputSection<ELFT> *BSSSec =
getSection(".bss", SHT_NOBITS, SHF_ALLOC | SHF_WRITE);
uintX_t Off = BSSSec->getSize();
// FIXME: Try to avoid the extra walk over all global symbols.
for (auto &P : Symtab.getSymbols()) {
SymbolBody *Body = P.second->Body;
auto *C = dyn_cast<DefinedCommon<ELFT>>(Body);
if (!C)
continue;
const Elf_Sym &Sym = C->Sym;
uintX_t Align = Sym.st_value;
Off = RoundUpToAlignment(Off, Align);
Off += Sym.st_size;
}
BSSSec->setSize(Off);
}
template <bool Is64Bits>

View File

@ -41,12 +41,22 @@ abs = 0x123
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x1000
// CHECK: Name: .bss (14)
// CHECK-NEXT: Type: SHT_NOBITS (0x8)
// CHECK-NEXT: Flags [ (0x3)
// CHECK-NEXT: SHF_ALLOC (0x2)
// CHECK-NEXT: SHF_WRITE (0x1)
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x1004
// CHECK-NEXT: Offset: 0x1004
// CHECK-NEXT: Size: 4
// CHECK: Name: foobar
// CHECK-NEXT: Type: SHT_NOBITS
// CHECK-NEXT: Flags [
// CHECK-NEXT: SHF_ALLOC
// CHECK-NEXT: ]
// CHECK-NEXT: Address: 0x1004
// CHECK-NEXT: Address: 0x1008
// CHECK: Symbols [
// CHECK-NEXT: Symbol {
@ -105,7 +115,7 @@ abs = 0x123
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: zed
// CHECK-NEXT: Value: 0x1004
// CHECK-NEXT: Value: 0x1008
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global (0x1)
// CHECK-NEXT: Type: None
@ -114,7 +124,7 @@ abs = 0x123
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: zed3
// CHECK-NEXT: Value: 0x100C
// CHECK-NEXT: Value: 0x1010
// CHECK-NEXT: Size: 4
// CHECK-NEXT: Binding: Global
// CHECK-NEXT: Type: None
@ -123,7 +133,7 @@ abs = 0x123
// CHECK-NEXT: }
// CHECK-NEXT: Symbol {
// CHECK-NEXT: Name: zed2
// CHECK-NEXT: Value: 0x1008
// CHECK-NEXT: Value: 0x100C
// CHECK-NEXT: Size: 0
// CHECK-NEXT: Binding: Global
// CHECK-NEXT: Type: None