diff options
author | Logan Chien <tzuhsiang.chien@gmail.com> | 2011-07-02 03:13:28 +0800 |
---|---|---|
committer | Logan Chien <tzuhsiang.chien@gmail.com> | 2011-07-02 03:34:27 +0800 |
commit | 1045a1dabf49181e7cba2e37a891799ba9055d9f (patch) | |
tree | 11035cbbab96a738537a39c4e1aadddd13d8288d | |
parent | 86196e389f2616e218de17920b6fe23d24f67786 (diff) | |
download | linkloader-1045a1dabf49181e7cba2e37a891799ba9055d9f.tar.gz |
Rewrite the workaround for misalignment.
Previous workaround caused RsBenchmark crashed. This is because
the inconsistency of the symbol address and relocation address.
In the old patch, the relocation hole will be filled with new
aligned address, while the relocation process will committed on
old address.
This new workaround is based on the observation that ".lcomm"
directive bug will only affect .bss section (NOBITS). Besides,
.bss section itself needs no relocation. So it is OK to allocate
16-byte aligned memory for .bss section.
-rw-r--r-- | include/impl/ELFSymbol.hxx | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/include/impl/ELFSymbol.hxx b/include/impl/ELFSymbol.hxx index c632f8c..d7e127b 100644 --- a/include/impl/ELFSymbol.hxx +++ b/include/impl/ELFSymbol.hxx @@ -137,27 +137,37 @@ void *ELFSymbol_CRTP<Bitwidth>::getAddress(bool autoAlloc) const { switch (idx) { default: { -#ifndef NDEBUG ELFSectionHeaderTableTy const *header = owner->getSectionHeaderTable(); - rsl_assert(((*header)[idx]->getType() == SHT_PROGBITS || - (*header)[idx]->getType() == SHT_NOBITS) && - "STT_OBJECT with not BITS section."); -#endif - ELFSectionTy const *sec = owner->getSectionByIndex(idx); - rsl_assert(sec != 0 && "STT_OBJECT with null section."); - size_t align = 16; - my_addr = const_cast<ELFObjectTy *>(owner)-> - allocateSHNCommonData((size_t)getSize(), align); - if (!my_addr) { - rsl_assert(0 && "Unable to allocate memory for SHN_COMMON."); - abort(); - } + unsigned section_type = (*header)[idx]->getType(); - ELFSectionBitsTy const &st = - static_cast<ELFSectionBitsTy const &>(*sec); - memcpy(my_addr, &st[0] + (off_t)getValue(), getSize()); + rsl_assert((section_type == SHT_PROGBITS || + section_type == SHT_NOBITS) && + "STT_OBJECT with not BITS section."); + + if (section_type == SHT_NOBITS) { + // FIXME(logan): This is a workaround for .lcomm directives + // bug of LLVM ARM MC code generator. Remove this when the + // LLVM bug is fixed. + + size_t align = 16; + + my_addr = const_cast<ELFObjectTy *>(owner)-> + allocateSHNCommonData((size_t)getSize(), align); + + if (!my_addr) { + rsl_assert(0 && "Unable to allocate memory for SHN_COMMON."); + abort(); + } + } else { + ELFSectionTy const *sec = owner->getSectionByIndex(idx); + rsl_assert(sec != 0 && "STT_OBJECT with null section."); + + ELFSectionBitsTy const &st = + static_cast<ELFSectionBitsTy const &>(*sec); + my_addr =const_cast<unsigned char *>(&st[0] + (off_t)getValue()); + } #if 0 #ifdef __arm__ |